Version 2.1.0-dev.8.0

Merge commit 'cf0a99a' into dev
diff --git a/.gitattributes b/.gitattributes
index 7501c16..b9cadf0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -18,36 +18,18 @@
 tests/compiler/dart2js_extra/string_interpolation_test.dart -text
 tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart -text
 tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart -text
-tests/language/raw_string_test.dart -text
-tests/language/multiline_strings_test.dart -text
-tests/language/multiline_newline_cr.dart -text
-tests/language/multiline_newline_crlf.dart -text
-tests/language/multiline_newline_lf.dart -text
 tests/language_2/raw_string_test.dart -text
 tests/language_2/multiline_strings_test.dart -text
 tests/language_2/multiline_newline_cr.dart -text
 tests/language_2/multiline_newline_crlf.dart -text
 tests/language_2/multiline_newline_lf.dart -text
-tests/lib/convert/json_pretty_test.dart -text
 tests/lib_2/convert/json_pretty_test.dart -text
-tests/lib/mirrors/method_mirror_source_line_ending_test.dart -text
-tests/lib/mirrors/method_mirror_source_line_ending_cr.dart -text
-tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart -text
-tests/lib/mirrors/method_mirror_source_line_ending_lf.dart -text
-tests/lib/mirrors/method_mirror_source_test.dart -text
-tests/lib/mirrors/method_mirror_source_other.dart -text
-tests/lib_2/mirrors/method_mirror_source_line_ending_test.dart -text
 tests/lib_2/mirrors/method_mirror_source_line_ending_cr.dart -text
 tests/lib_2/mirrors/method_mirror_source_line_ending_crlf.dart -text
 tests/lib_2/mirrors/method_mirror_source_line_ending_lf.dart -text
-tests/lib_2/mirrors/method_mirror_source_test.dart -text
-tests/lib_2/mirrors/method_mirror_source_other.dart -text
 tests/lib_2/mirrors/method_mirror_source_line_ending_test.dart -text
-tests/lib_2/mirrors/method_mirror_source_line_ending_cr.dart -text
-tests/lib_2/mirrors/method_mirror_source_line_ending_crlf.dart -text
-tests/lib_2/mirrors/method_mirror_source_line_ending_lf.dart -text
-tests/lib_2/mirrors/method_mirror_source_test.dart -text
 tests/lib_2/mirrors/method_mirror_source_other.dart -text
+tests/lib_2/mirrors/method_mirror_source_test.dart -text
 
 # Files to leave alone and not diff.
 *.png binary
diff --git a/.packages b/.packages
index 0b9c7ed..f9f0641 100644
--- a/.packages
+++ b/.packages
@@ -32,6 +32,7 @@
 dart_internal:pkg/dart_internal/lib
 dart_style:third_party/pkg_tested/dart_style/lib
 dartdoc:third_party/pkg/dartdoc/lib
+dartfix:pkg/dartfix/lib
 dev_compiler:pkg/dev_compiler/lib
 diagnostic:pkg/diagnostic/lib
 expect:pkg/expect/lib
diff --git a/.vpython b/.vpython
new file mode 100644
index 0000000..4e38fa5
--- /dev/null
+++ b/.vpython
@@ -0,0 +1,36 @@
+# This is a vpython "spec" file.
+#
+# It describes patterns for python wheel dependencies of the python scripts in
+# the chromium repo, particularly for dependencies that have compiled components
+# (since pure-python dependencies can be easily vendored into third_party).
+#
+# When vpython is invoked, it finds this file and builds a python VirtualEnv,
+# containing all of the dependencies described in this file, fetching them from
+# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`,
+# this never requires the end-user machine to have a working python extension
+# compilation environment. All of these packages are built using:
+#   https://chromium.googlesource.com/infra/infra/+/master/infra/tools/dockerbuild/
+#
+# All python scripts in the repo share this same spec, to avoid dependency
+# fragmentation.
+#
+# If you have depot_tools installed in your $PATH, you can invoke python scripts
+# in this repo by running them as you normally would run them, except
+# substituting `vpython` instead of `python` on the command line, e.g.:
+#   vpython path/to/script.py some --arguments
+#
+# Read more about `vpython` and how to modify this file here:
+#   https://chromium.googlesource.com/infra/infra/+/master/doc/users/vpython.md
+
+python_version: "2.7"
+
+# Used by:
+#   tools/third_party/gsutil
+wheel: <
+  name: "infra/python/wheels/google_compute_engine-py2_py3"
+  version: "version:2.6.2"
+>
+wheel: <
+  name: "infra/python/wheels/boto-py2_py3"
+  version: "version:2.48.0"
+>
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d3eaa12..5a55218 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,193 @@
+## 2.1.0-dev.8.0
+
+#### `dart:html`
+Fixed Service Workers and any Promise/Future API with a Dictionary parameter.
+
+APIs in dart:html (that take a Dictionary) will receive a Dart Map parameter.
+The Map parameter must be converted to a Dictionary before passing to the
+browser's API.  Before this change, any Promise/Future API with a
+Map/Dictionary parameter never called the Promise and didn't return a Dart
+Future - now it does.
+
+This caused a number of breaks especially in Service Workers (register, etc.).
+Here is a complete list of the fixed APIs:
+
+* BackgroundFetchManager
+  * `Future<BackgroundFetchRegistration> fetch(String id, Object requests, [Map options])`
+
+* CacheStorage
+  * `Future match(/*RequestInfo*/ request, [Map options])`
+
+* CanMakePayment
+  * `Future<List<Client>> matchAll([Map options])`
+
+* CookieStore
+  * `Future getAll([Map options])`
+  * `Future set(String name, String value, [Map options])`
+
+* CredentialsContainer
+  * `Future get([Map options])`
+  * `Future create([Map options])`
+
+* ImageCapture
+  * `Future setOptions(Map photoSettings)`
+
+* MediaCapabilities
+  * `Future<MediaCapabilitiesInfo> decodingInfo(Map configuration)`
+  * `Future<MediaCapabilitiesInfo> encodingInfo(Map configuration)`
+
+* MediaStreamTrack
+  * `Future applyConstraints([Map constraints])`
+
+* Navigator
+  * `Future requestKeyboardLock([List<String> keyCodes])`
+  * `Future requestMidiAccess([Map options])`
+  * `Future share([Map data])`
+
+* OffscreenCanvas
+  * `Future<Blob> convertToBlob([Map options])`
+
+* PaymentInstruments
+  * `Future set(String instrumentKey, Map details)`
+
+* Permissions
+  * `Future<PermissionStatus> query(Map permission)`
+  * `Future<PermissionStatus> request(Map permissions)`
+  * `Future<PermissionStatus> revoke(Map permission)`
+
+* PushManager
+  * `Future permissionState([Map options])`
+  * `Future<PushSubscription> subscribe([Map options])`
+
+* RtcPeerConnection
+  * **CHANGED**
+
+    ```dart
+    Future createAnswer([options_OR_successCallback,
+                         RtcPeerConnectionErrorCallback failureCallback,
+                         Map mediaConstraints])
+    ```
+
+    to
+
+    `Future<RtcSessionDescription> createAnswer([Map options])`
+
+  * **CHANGED**
+
+    ```dart
+    Future createOffer([options_OR_successCallback,
+                        RtcPeerConnectionErrorCallback failureCallback,
+                        Map rtcOfferOptions])
+    ```
+
+    to
+
+    `Future<RtcSessionDescription> createOffer([Map options])`
+
+  * **CHANGED**
+
+    ```dart
+    Future setLocalDescription(Map description, VoidCallback successCallback,
+                               [RtcPeerConnectionErrorCallback failureCallback])
+    ```
+
+    to
+
+    `Future setLocalDescription(Map description)`
+  * **CHANGED**
+
+    ```dart
+    Future setLocalDescription(Map description, VoidCallback successCallback,
+                               [RtcPeerConnectionErrorCallback failureCallback])
+    ```
+
+    to
+
+    `Future setRemoteDescription(Map description)`
+
+* ServiceWorkerContainer
+  * `Future<ServiceWorkerRegistration> register(String url, [Map options])`
+
+* ServiceWorkerRegistration
+  * `Future<List<Notification>> getNotifications([Map filter])`
+  * `Future showNotification(String title, [Map options])`
+
+* VRDevice
+  * `Future requestSession([Map options])`
+  * `Future supportsSession([Map options])`
+
+* VRSession
+  * `Future requestFrameOfReference(String type, [Map options])`
+
+* Window
+  * `Future fetch(/*RequestInfo*/ input, [Map init])`
+
+* WorkerGlobalScope
+  * `Future fetch(/*RequestInfo*/ input, [Map init])`
+
+In addition, exposed Service Worker "self" as a static getter named "instance".
+The instance is exposed on four different Service Worker classes and can throw
+a InstanceTypeError if the instance isn't of the class expected
+(WorkerGlobalScope.instance will always work and not throw):
+
+*   SharedWorkerGlobalScope.instance
+*   DedicatedWorkerGlobalScope.instance
+*   ServiceWorkerGlobalScope.instance
+*   WorkerGlobalScope.instance
+
+### Language
+
+*   Allow integer literals to be used in double contexts.
+    An integer literal used in a place where a double is required is now
+    interpreted as a double value. The numerical value of the literal needs
+    to be precisely representable as a double value.
+
+*   Integer literals compiled to JavaScript are now allowed to have any
+    value that can be exactly represented as a JavaScript `Number`.
+    They were previously limited to such numbers that were also representable
+    as signed 64-bit integers.
+
+### Core library changes
+
+*   Add `HashMap.fromEntries` and `LinkedHashmap.fromEntries` constructors.
+
+### Tool Changes
+
+#### Linter
+
+Bumped the linter to `0.1.70` which includes the following new lints:
+
+* `avoid_returning_null_for_void`
+* `sort_pub_dependencies`
+* `prefer_mixin`
+* `avoid_implementing_value_types`
+* `flutter_style_todos`
+* `avoid_void_async`
+* `prefer_void_to_null`
+
+and improvements:
+
+* fix NPE in `prefer_iterable_whereType`
+* improved message display for `await_only_futures`
+* performance improvements for `null_closures`
+* mixin support
+* update to `sort_constructors_first` to apply to all members
+* update `unnecessary_this` to work on field initializers
+* updated `unawaited_futures` to ignore assignments within cascades
+* improved handling of constant expressions with generic type params
+* NPE fix for `invariant_booleans`
+* improved docs for `unawaited_futures`
+* `unawaited_futures` updated to check cascades
+* relaxed `void_checks` (allowing `T Function()` to be assigned to `void Function()`)
+* fixed false positives in `lines_longer_than_80_chars`
+
+#### dart2js
+
+*   Breaking change: duplicate keys in a const map are not allowed and produce a
+    compile-time error.  Dart2js used to report this as a warning before. Note
+    this is already an error in dartanalyzer and DDC and will be an error in
+    other tools in the future as well.
+
 ## 2.1.0-dev.7.1
 
 * Cherry-pick 6b67cd784bbd13d5b6127cba44281a879fa7275c to dev
@@ -59,6 +249,8 @@
 
 ## 2.1.0-dev.5.0
 
+### Core library changes
+
 #### `dart:core`
 
 *   Exported `Future` and `Stream` from `dart:core`.
diff --git a/DEPS b/DEPS
index 06ad967..d3af193 100644
--- a/DEPS
+++ b/DEPS
@@ -36,8 +36,7 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
-  "co19_rev": "9858ee7d79cf09b50d6b5bc13fb950ae5f357954",
-  "co19_2_rev": "9484b81650d8c5bedf72abc541960dd1c90b2329",
+  "co19_2_rev": "77825446f59893bb2b20f2e9517a4567e0371193",
 
   # As Flutter does, we pull buildtools, including the clang toolchain, from
   # Fuchsia. This revision should be kept up to date with the revision pulled
@@ -64,7 +63,7 @@
   "convert_tag": "2.0.2",
   "crypto_tag" : "2.0.6",
   "csslib_tag" : "0.14.4+1",
-  "dart2js_info_tag" : "0.5.6+4",
+  "dart2js_info_tag" : "0.5.13",
 
   # Note: updates to dart_style have to be coordinated carefully with
   # the infrastructure-team so that the internal formatter in
@@ -80,7 +79,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "1.2.0",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "v0.23.0",
+  "dartdoc_tag" : "v0.24.1",
   "file_rev": "515ed1dd48740ab14b625de1be464cb2bca4fefd",  # 5.0.6
   "fixnum_tag": "0.10.8",
   "func_rev": "25eec48146a58967d75330075ab376b3838b18a8",
@@ -96,7 +95,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.68",
+  "linter_tag": "0.1.70",
   "logging_tag": "0.11.3+2",
   "markdown_tag": "2.0.2",
   "matcher_tag": "0.12.3",
@@ -134,7 +133,7 @@
   "test_process_tag": "1.0.3",
   "term_glyph_tag": "1.0.1",
   "test_reflective_loader_tag": "0.1.8",
-  "test_tag": "1.0.0",
+  "test_tag": "1.3.4",
   "tuple_tag": "v1.0.1",
   "typed_data_tag": "1.1.6",
   "unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
@@ -165,9 +164,15 @@
       ],
       "dep_type": "cipd",
   },
-
-  Var("dart_root") + "/tests/co19/src":
-      Var("dart_git") + "co19.git" + "@" + Var("co19_rev"),
+  Var("dart_root") + "/third_party/d8": {
+      "packages": [
+          {
+              "package": "dart/d8",
+              "version": "version:6.9.427.23+1",
+          },
+      ],
+      "dep_type": "cipd",
+  },
 
   Var("dart_root") + "/tests/co19_2/src":
       Var("chromium_git") + "/external/github.com/dart-lang/co19.git" +
@@ -382,20 +387,6 @@
 # without the runtime being available.
 hooks = [
   {
-    'name': 'd8_testing_binaries',
-    'pattern': '.',
-    'action': [
-      'download_from_google_storage',
-      '--no_auth',
-      '--no_resume',
-      '--bucket',
-      'dart-dependencies',
-      '--recursive',
-      '--directory',
-      Var('dart_root') + '/third_party/d8',
-    ],
-  },
-  {
     "name": "firefox_jsshell",
     "pattern": ".",
     "action": [
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 4d83619..57b7bfa 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -107,78 +107,6 @@
   return []
 
 
-def _CheckNewTests(input_api, output_api):
-  testsDirectories = [
-      #    Dart 1 tests              Dart 2.0 tests
-      # =================       ==========================
-      ("tests/language/",       "tests/language_2/"),
-      ("tests/corelib/",        "tests/corelib_2/"),
-      ("tests/lib/",            "tests/lib_2/"),
-      ("tests/html/",           "tests/lib_2/html/"),
-      ("tests/isolate/",        "tests/lib_2/isolate/")
-  ]
-
-  result = []
-  # Tuples of (new Dart 1 test path, expected Dart 2.0 test path)
-  dart1TestsAdded = []
-  # Tuples of (original Dart test path, expected Dart 2.0 test path)
-  dart2TestsExists = []
-  for f in input_api.AffectedTextFiles():
-    localpath = f.LocalPath()
-    if not(localpath.endswith('.status')):
-      for oldPath, newPath in testsDirectories:
-        if localpath.startswith(oldPath):
-          if f.Action() == 'A':
-            # Compute where the new test should live.
-            dart2TestPath = localpath.replace(oldPath, newPath)
-            dart1TestsAdded.append((localpath, dart2TestPath))
-          elif f.Action() == 'M':
-            # Find all modified tests in Dart 1.0
-            for oldPath, newPath in testsDirectories:
-              if localpath.find(oldPath) == 0:
-                dart2TestFilePathAbs = "%s" % \
-                    f.AbsoluteLocalPath().replace(oldPath, newPath)
-                if os.path.isfile(dart2TestFilePathAbs):
-                  #originalDart1Test.append(localpath)
-                  dart2TestsExists.append((localpath,
-                      localpath.replace(oldPath, newPath)))
-
-  # Does a Dart 2.0 test exist if so it must be changed too.
-  missingDart2TestsChange = []
-  for (dartTest, dart2Test) in dart2TestsExists:
-    foundDart2TestModified = False
-    for f in input_api.AffectedFiles():
-      if f.LocalPath() == dart2Test:
-        # Found corresponding Dart 2 test - great.
-        foundDart2TestModified = True
-        break
-    if not foundDart2TestModified:
-      # Add the tuple (dart 1 test path, Dart 2.0 test path)
-      missingDart2TestsChange.append((dartTest, dart2Test))
-
-  if missingDart2TestsChange:
-    errorList = []
-    for idx, (orginalTest, dart2Test) in enumerate(missingDart2TestsChange):
-      errorList.append(
-          '%s. Dart 1.0 test changed: %s\n%s. Only the Dart 2.0 test can '\
-          'change: %s\n' % (idx + 1, orginalTest, idx + 1, dart2Test))
-    result.append(output_api.PresubmitError(
-        'Error: Changed Dart 1.0 test detected - only 1.0 status files can '\
-        'change. Migrate test to Dart 2.0 tests:\n%s' % ''.join(errorList)))
-
-  if dart1TestsAdded:
-    errorList = []
-    for idx, (oldTestPath, newTestPath) in enumerate(dart1TestsAdded):
-      errorList.append('%s. New Dart 1.0  test: %s\n'
-          '%s. Should be Dart 2.0 test: %s\n' % \
-          (idx + 1, oldTestPath, idx + 1, newTestPath))
-    result.append(output_api.PresubmitError(
-        'Error: New Dart 1.0 test can not be added the test must be added '\
-        'as a Dart 2.0 test:\nFix tests:\n%s' % ''.join(errorList)))
-
-  return result
-
-
 def _CheckStatusFiles(input_api, output_api):
   local_root = input_api.change.RepositoryRoot()
   upstream = input_api.change._upstream
@@ -244,13 +172,11 @@
 def CheckChangeOnCommit(input_api, output_api):
   return (_CheckValidHostsInDEPS(input_api, output_api) +
           _CheckBuildStatus(input_api, output_api) +
-          _CheckNewTests(input_api, output_api) +
           _CheckDartFormat(input_api, output_api) +
           _CheckStatusFiles(input_api, output_api))
 
 
 def CheckChangeOnUpload(input_api, output_api):
   return (_CheckValidHostsInDEPS(input_api, output_api) +
-          _CheckNewTests(input_api, output_api) +
           _CheckDartFormat(input_api, output_api) +
           _CheckStatusFiles(input_api, output_api))
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 3b8f01e..7e381b9 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -1,4 +1,5 @@
 \documentclass{article}
+\usepackage{xspace}
 \usepackage{epsfig}
 \usepackage{color}
 \usepackage{syntax}
@@ -61,6 +62,7 @@
 %   program such that it takes exports into account.
 % - Eliminate all references to checked and production mode, Dart 2 does
 %   not have modes.
+% - Integrate feature specification on noSuchMethod forwarders.
 %
 % 2.0
 % - Don't allow functions as assert test values.
@@ -604,8 +606,8 @@
 Isolates are created by spawning (\ref{spawningAnIsolate}).
 
 
-\section{Errors}
-\LMLabel{errors}
+\section{Errors and Warnings}
+\LMLabel{errorsAndWarnings}
 
 \LMHash{}
 This specification distinguishes between several kinds of errors.
@@ -647,6 +649,12 @@
 }
 
 \LMHash{}
+{\em Compile-time warnings} are situations that do not preclude execution,
+but which are unlikely to be intended,
+and likely to cause bugs or inconveniences.
+A compile-time warning must be reported by a Dart compiler before the associated code is executed.
+
+\LMHash{}
 When this specification says that a {\em run-time error} occurs,
 it means that a corresponding error object is thrown.
 When it says that a {\em dynamic type error} occurs,
@@ -697,11 +705,11 @@
 with the same type and modifiers.
 
 \LMHash{}
-An initialized variable declaration that contains one or more terms of the form
+An \syntax{<initializedVariableDeclaration>} that contains one or more terms of the form
 \syntax{<initializedIdentifier>}
-(\commentary{a declaration that declares two or more initialized variables})
+(\commentary{that is, a declaration that declares two or more initialized variables})
 is equivalent to multiple variable declarations declaring
-the same set of variable names in the same order,
+the same set of variable names, in the same order,
 with the same initialization, type, and modifiers.
 
 \commentary{
@@ -735,7 +743,8 @@
 }
 
 \LMHash{}
-An {\em initialized variable} is a variable whose declaring identifier is
+An {\em initializing variable declaration}
+is a variable declaration whose declaring identifier is
 immediately followed by `\code{=}' and an {\em initializing expression}.
 
 \LMHash{}
@@ -830,7 +839,8 @@
 A mutable instance variable introduces an instance setter into the immediately enclosing class.
 
 \LMHash{}
-Let $v$ be an initialized variable and let $e$ be the associated initializing expression.
+Let $v$ be variable declared in an initializing variable declaration,
+and let $e$ be the associated initializing expression.
 It is a compile-time error if the static type of $e$ is not assignable to the declared type of $v$.
 It is a compile-time error if a final instance variable whose declaration has an initializer expression
 is also initialized by a constructor, either by an initializing formal or an initializer list entry.
@@ -1497,7 +1507,7 @@
 \LMHash{}
 %% TODO(eernst): We need to use the concept of 'correctly overrides' rather than 'is a subtype of', e.g., to treat `void` correctly.
 It is a compile-time error if an instance method $m_1$ overrides an instance member $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$.
-It is a compile-time error if an instance method $m_1$ overrides an instance member $m_2$, the signature of $m_2$ explicitly specifies a default value for a formal parameter $p$, and the signature of $m_1$ implies a different default value for $p$.
+It is a compile-time warning if an instance method $m_1$ overrides an instance member $m_2$, the signature of $m_2$ explicitly specifies a default value for a formal parameter $p$, and the signature of $m_1$ implies a different default value for $p$.
 
 \commentary{
 A method declaration may conflict with other declarations
@@ -1603,7 +1613,7 @@
 It is a compile-time error to declare an optional parameter in an operator.
 
 \LMHash{}
-It is a compile-time error if the return type of a user-declared operator
+It is a compile-time warning if the return type of a user-declared operator
 \syntax{`[]='}
 is explicitly declared and not \VOID{}.
 
@@ -1629,6 +1639,298 @@
 }
 
 
+\subsubsection{The Method \code{noSuchMethod}}
+\LMLabel{theMethodNoSuchMethod}
+
+\LMHash{}
+The method \code{noSuchMethod} is invoked implicitly during execution
+in situations where one or more member lookups fail
+(\ref{ordinaryInvocation},
+\ref{getterAccessAndMethodExtraction},
+\ref{assignment}).
+
+\commentary{
+We may think of \code{noSuchMethod} as a backup
+which kicks in when an invocation of a member $m$ is attempted,
+but there is no member named $m$,
+or it exists,
+but the given invocation has an argument list shape
+that does not fit the declaration of $m$
+(passing fewer positional arguments than required or more than supported,
+or passing named arguments with names not declared by $m$).
+% The next sentence covers both function objects and instances of
+% a class with a method named \code{call}, because we would have a
+% compile-time error invoking \code{call} with a wrongly shaped argument
+% list unless the type is \DYNAMIC{} or \FUNCTION.
+This can only occur for an ordinary method invocation
+when the receiver has static type \DYNAMIC,
+or for a function invocation when
+the invoked function has static type \FUNCTION{} or \DYNAMIC.
+%
+The method \code{noSuchMethod} can also be invoked in other ways, e.g.,
+it can be called explicitly like any other method,
+and it can be invoked from a \code{noSuchMethod} forwarder,
+as explained below.
+}
+
+\LMHash{}
+We say that a class $C$ {\em has a non-trivial \code{noSuchMethod}}
+if $C$ has a concrete member named \code{noSuchMethod}
+which is distinct from the one declared in the built-in class \code{Object}.
+
+\commentary{
+Note that it must be a method that accepts one positional argument,
+in order to correctly override \code{noSuchMethod} in \code{Object}.
+For instance, it can have signature
+\code{noSuchMethod(Invocation i)} or
+\code{noSuchMethod(Object i, [String s])},
+but not
+\code{noSuchMethod(Invocation i, String s)}.
+This implies that the situation where \code{noSuchMethod} is invoked
+(explicitly or implicitly)
+with one actual argument cannot fail for the reason that
+``there is no such method'',
+such that we would enter an infinite loop trying to invoke \code{noSuchMethod}.
+It \emph{is} possible, however, to encounter a dynamic error
+during an invocation of \code{noSuchMethod}
+because the actual argument fails to satisfy a type check,
+but that situation will give rise to a dynamic type error
+rather than a repeated attempt to invoke \code{noSuchMethod}
+(\ref{bindingActualsToFormals}).
+Here is an example where a dynamic type error occurs because
+an attempt is made to pass an \code{Invocation}
+where only the null object is accepted:
+}
+
+\begin{dartCode}
+\CLASS{} A \{
+  noSuchMethod(\COVARIANT{} Null n) => n;
+\}
+\\
+\VOID{} main() \{
+  \DYNAMIC{} d = A();
+  d.foo(42); // Dynamic type error when invoking noSuchMethod.
+\}
+\end{dartCode}
+
+\LMHash{}
+Let $C$ be a concrete class and
+let $L$ be the library that contains the declaration of $C$.
+The member $m$ is {\em noSuchMethod forwarded in} $C$ if{}f
+one of the following is true:
+
+\begin{itemize}
+\item $C$ has a non-trivial \code{noSuchMethod},
+  the interface of $C$ contains $m$,
+  and $C$ has no concrete declaration of $m$
+  (\commentary{that is, no member $m$ is declared or inherited by $C$}).
+\item
+  % Inaccessible private methods are not present in the interface of a class,
+  % so we need to find a class that can access $m$.
+  There exists a direct or indirect superinterface
+  $D$ of $C$ which is declared in the library $L_2$,
+  the interface of $D$ contains $m$
+  (\commentary{which implies that $m$ is accessible to $L_2$}),
+  $m$ is inaccessible to $L$,
+  and no superclass of $C$ has
+  a concrete declaration of $m$ accessible to $L_2$.
+\end{itemize}
+
+\LMHash{}
+For a concrete class $C$, a {\em \code{noSuchMethod} forwarder}
+is implicitly induced for each member $m$
+which is \code{noSuchMethod} forwarded.
+This is a concrete member of $C$
+with the signature taken from the interface of $C$ respectively $D$ above,
+and with the same default value for each optional parameter.
+It can be invoked in an ordinary invocation and in a superinvocation,
+and when $m$ is a method it can be closurized
+(\ref{ordinaryMemberClosurization})
+using a property extraction
+(\ref{propertyExtraction}).
+
+\commentary{
+This implies that a \code{noSuchMethod} forwarder has the same
+properties as an explicitly declared concrete member,
+except of course that a \code{noSuchMethod} forwarder
+does not prevent itself from being induced.
+We do not specify the body of a \code{noSuchMethod} forwarder,
+but it will invoke \code{noSuchMethod},
+and we specify the dynamic semantics of executing it below.
+}
+
+\commentary{
+At the beginning of this section we mentioned that implicit invocations
+of \code{noSuchMethod} can only occur
+with a receiver of static type \DYNAMIC{}
+or a function of static type \DYNAMIC{} or \FUNCTION{}.
+With a \code{noSuchMethod} forwarder,
+\code{noSuchMethod} can also be invoked
+on a receiver whose static type is not \DYNAMIC{}.
+No similar situation exists for functions,
+because it is impossible to induce a \code{noSuchMethod} forwarder
+into the class of a function object.
+}
+
+\commentary{
+For a concrete class $C$,
+we may think of a non-trivial \code{noSuchMethod}
+(declared in or inherited by $C$)
+as a request for ``automatic implementation'' of all unimplemented members
+in the interface of $C$ as \code{noSuchMethod} forwarders.
+Similarly, there is an implicit request for
+automatic implementation of all unimplemented
+inaccessible members of any concrete class,
+whether or not there is a non-trivial \code{noSuchMethod}.
+Note that the latter cannot be written explicitly in Dart,
+because their names are inaccessible;
+but the language can still specify that they are induced implicitly,
+because compilers control the treatment of private names.
+}
+
+\LMHash{}
+It is a compile-time error if a concrete class $C$ has
+a \code{noSuchMethod} forwarded method signature $S$
+for a method named $m$,
+and a superclass of $C$ has a concrete declaration of $m$
+which is not a \code{noSuchMethod} forwarder.
+
+\commentary{
+This can only happen if that concrete declaration does not
+correctly override $S$. Consider the following example:
+}
+
+\begin{dartCode}
+\CLASS{} A \{
+  foo(int i) => \NULL;
+\}
+
+\ABSTRACT{} \CLASS{} B \{
+  foo([int i]);
+\}
+
+\CLASS{} C \EXTENDS{} A \IMPLEMENTS{} B \{
+  noSuchMethod(Invocation i) => ...;
+  // Error: Forwarder would override `A.foo`.
+\}
+\end{dartCode}
+
+\commentary{
+In this example,
+an implementation with signature \code{foo(int i)} is inherited by \code{C},
+and the superinterface \code{B} declares
+the signature \code{foo([int i])}.
+This is a compile-time error because \code{C} does not have
+a method implementation with signature \code{foo([int])}.
+We do not wish to implicitly induce
+a \code{noSuchMethod} forwarder with signature \code{foo([int])}
+because it would override \code{A.foo},
+and that is likely to be highly confusing for developers.
+%
+In particular, it would cause an invocation like \code{C().foo(42)}
+to invoke \code{noSuchMethod},
+even though that is an invocation which is correct for
+the declaration of \code{foo} in \code{A}.
+%
+Hence, we require developers to explicitly resolve the conflict
+whenever an implicitly induced \code{noSuchMethod} forwarder
+would override an explicitly declared inherited implementation.
+%
+It is no problem, however,
+to let a \code{noSuchMethod} forwarder override
+another \code{noSuchMethod} forwarder,
+and hence there is no error in that situation.
+}
+
+\LMHash{}
+For the dynamic semantics,
+assume that a class $C$ has an implicitly induced
+\code{noSuchMethod} forwarder named $m$,
+with formal type parameters
+\code{$X_1,\ \ldots,\ X_r$},
+positional formal parameters
+\code{$a1,\ \ldots,\ a_k$}
+(\commentary{some of which may be optional when $m = 0$}),
+and named formal parameters with names
+\code{$x_1,\ \ldots,\ x_m$}
+(\commentary{with default values as mentioned above}).
+
+\commentary{
+For this purpose we need not distinguish between
+a signature that has optional positional parameters and
+a signature that has named parameters,
+because the former is covered by $m = 0$.
+}
+
+\LMHash{}
+The execution of the body of $m$ creates
+an instance $im$ of the predefined class \code{Invocation}
+such that:
+
+\begin{itemize}
+\item \code{$im$.isMethod} evaluates to \code{\TRUE{}} if{}f $m$ is a method.
+\item \code{$im$.isGetter} evaluates to \code{\TRUE{}} if{}f $m$ is a getter.
+\item \code{$im$.isSetter} evaluates to \code{\TRUE{}} if{}f $m$ is a setter.
+\item \code{$im$.memberName} evaluates to the symbol \code{m}.
+\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
+  with the same values as the list resulting from evaluation of
+  \code{<Object>[$a_1, \ldots,\ a_k$]}.
+\item \code{$im$.namedArguments} evaluates to an unmodifiable map
+  with the same keys and values as the map resulting from evaluation of
+
+  \code{<Symbol, Object>\{$\#x_1$: $x_1, \ldots,\ \#x_m$: $x_m$\}}.
+\item \code{$im$.typeArguments} evaluates to an unmodifiable list
+  with the same values as the list resulting from evaluation of
+  \code{<Type>[$X_1, \ldots,\ X_r$]}.
+\end{itemize}
+
+\LMHash{}
+Next, \code{noSuchMethod} is invoked with $i$ as the actual argument,
+and the result obtained from there is returned by the execution of $m$.
+
+\commentary{
+This is an ordinary method invocation of \code{noSuchMethod}
+(\ref{ordinaryInvocation}).
+That is, a \code{noSuchMethod} forwarder in a class $C$ can invoke
+an implementation of \code{noSuchMethod} that is declared in
+a subclass of $C$.
+
+Dynamic type checks on the actual arguments passed to $m$
+are performed in the same way as for an invocation of an
+explicitly declared method.
+In particular, an actual argument passed to a covariant parameter
+will be checked dynamically.
+
+Also, like other ordinary method invocations,
+it is a dynamic type error if the result returned by
+a \code{noSuchMethod} forwarder has a type which is not a subtype
+of the return type of the forwarder.
+
+One special case to be aware of is where a forwarder is torn off
+and then invoked with an actual argument list which does not match
+the formal parameter list.
+In that situation we will get an invocation of
+\code{Object.noSuchMethod}
+rather than the \code{noSuchMethod} in the original receiver,
+because this is an invocation of a function object
+(and they do not override \code{noSuchMethod}):
+}
+
+\begin{dartCode}
+\CLASS{} A \{
+  noSuchMethod(Invocation i) => \NULL;
+  \VOID{} foo();
+\}
+\\
+\VOID{} main() \{
+  A a = A();
+  \FUNCTION{} f = a.foo;
+  // Invokes `Object.noSuchMethod`, which throws.
+  f(42);
+\}
+\end{dartCode}
+
+
 \subsection{Getters}
 \LMLabel{getters}
 
@@ -1699,10 +2001,12 @@
 }
 
 \LMHash{}
-It is a compile-time error if a setter declares a return type other than \VOID{}.
+It is a compile-time warning if a setter declares a return type other than \VOID{}.
 It is a compile-time error if a setter $m_1$ overrides (\ref{inheritanceAndOverriding}) a setter $m_2$
 and the parameter type of $m_1$ is not a supertype of the parameter type of $m_2$.
-It is a compile-time error if a class has a setter named $v=$ with argument type $T$ and a getter named $v$ with return type $S$,
+It is a compile-time warning if a class has
+a setter named $v=$ with argument type $T$ and
+a getter named $v$ with return type $S$,
 and $S$ may not be assigned to $T$.
 
 \commentary{
@@ -1747,7 +2051,11 @@
 }
 
 \LMHash{}
-%% TODO(eernst): Revise this to use the concepts of interfaces, and do not say that an abstract member is inherited by a class.
+%% TODO(eernst): This is semi-redundant: We should define what it means for
+%% a class to be 'fully implemented' and require once and for all that it is
+%% a compile-time error if a concrete class is not fully implemented. That
+%% is very nearly what line 2706++ already says. This will then be commentary,
+%% just focusing on the case where a concrete $C$ _declares_ an abstract $m$.
 It is a compile-time error if an abstract member $m$ is declared or inherited in a concrete class $C$ unless:
 \begin{itemize}
 \item $m$ overrides a concrete member, or
@@ -2060,13 +2368,17 @@
 It is a compile-time error if $k$ includes an initializing formal for a final variable $f$ whose declaration includes an initialization expression.
 
 \LMHash{}
-Each final instance variable $f$ declared in the immediately enclosing class must have an initializer in $k$'s initializer list unless it has already been initialized by one of the following means:
+Let $f$ be a final instance variable declared in
+the immediately enclosing class.
+A compile-time error occurs unless $f$ is initialized
+by one of the following means:
 \begin{itemize}
-\item Initialization at the declaration of $f$.
-\item Initialization by means of an initializing formal of $k$.
+\item $f$ is declared by an initializing variable declaration.
+\item $f$ is initialized by means of an initializing formal of $k$.
+\item $f$ has an initializer in $k$'s initializer list.
 \end{itemize}
 
-or a compile-time error occurs.
+\LMHash{}
 It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declared in the immediately surrounding class.
 
 \commentary{
@@ -2787,7 +3099,7 @@
 \item Rule \ref{typeSigAssignable} applies to interfaces as well as classes
   (\ref{interfaceInheritanceAndOverriding}).
 \item It is an error if a concrete class does not have an implementation
-  for a method in any of its superinterfaces
+  for a method in its interface
   unless it has a concrete \code{noSuchMethod} method
   (\ref{superinterfaces})
   distinct from the one in class \code{Object}.
@@ -2867,11 +3179,6 @@
 However, if a class does explicitly declare a member that conflicts with its superinterface, this always yields an error.
 }
 
-% TODO(eernst): When integrating nosuchmethod-forwarders.md, delete this and make sure that we mention the
-% case where there is no `noSuchMethod` and we still generate forwarders.
-% Consider: It is a compile-time error if an imported superinterface of a class $C$ declares private members.
-% Should we ignore unimplemented private members?
-
 
 \subsection{Class Member Conflicts}
 \LMLabel{classMemberConflicts}
@@ -3681,6 +3988,13 @@
 \end{itemize}
 
 \commentary{
+It is \emph{not} an error if a super-bounded type occurs
+as an immediate subterm of an \EXTENDS{} clause
+that specifies the bound of a type variable
+(\ref{generics}).
+}
+
+\commentary{
 Types of members from super-bounded class types are computed using the same
 rules as types of members from other types. Types of function applications
 involving super-bounded types are computed using the same rules as types of
@@ -4185,6 +4499,8 @@
 Attempting to instantiate \code{Null} causes a run-time error.
 It is a compile-time error for a class to extend, mix in or implement \code{Null}.
 The \code{Null} class extends the \code{Object} class and declares no methods except those also declared by \code{Object}.
+\commentary{As such, it does not override the \code{==} operator inherited
+from the \code{Object} class.}
 
 \LMHash{}
 The static type of \NULL{} is the \code{Null} type.
@@ -4294,6 +4610,8 @@
 It is a compile-time error for a class to extend, mix in or implement \code{double}.
 It is a compile-time error for any class other than \code{int} and \code{double} to extend, mix in or implement \code{num}.
 
+\LMHash{}
+The instances of \code{int} and \code{double} all override the \code{==} operator inherited from the \code{Object} class.
 
 \subsection{Booleans}
 \LMLabel{booleans}
@@ -4313,6 +4631,10 @@
 It is a compile-time error for a class to extend, mix in or implement \code{bool}.
 
 \LMHash{}
+The \code{bool} class does not override the \code{==} operator inherited from
+the \code{Object} class.
+
+\LMHash{}
 Invoking the getter \code{runtimeType} on a boolean value returns the \code{Type} object that is the value of the expression \code{bool}.
 The static type of a boolean literal is \code{bool}.
 
@@ -4500,6 +4822,8 @@
 \LMHash{}
 All string literals evaluate to instances of the built-in class \code{String}.
 It is a compile-time error for a class to extend, mix in or implement \code{String}.
+The \code{String} class overrides the \code{==} operator inherited from
+the \code{Object} class.
 The static type of a string literal is \code{String}.
 
 
@@ -4587,6 +4911,10 @@
 and no other symbol literals evaluate to that \code{Symbol} instance
 or to a \code{Symbol} instance that is \code{==} to that instance.
 
+\LMHash{}
+The objects created by symbol literals all override
+the \code{==} operator inherited from the \code{Object} class.
+
 \rationale{
 One may well ask what is the motivation for introducing literal symbols? In some languages, symbols are canonicalized whereas strings are not.
 However literal strings are already canonicalized in Dart.
@@ -4679,6 +5007,10 @@
 The result of the evaluation is $a$.
 \end{itemize}
 
+\LMHash{}
+The objects created by list literals do not override
+the \code{==} operator inherited from the \code{Object} class.
+
 \commentary{
 Note that this document does not specify an order in which the elements are set.
 This allows for parallel assignments into the list if an implementation so desires.
@@ -4743,8 +5075,10 @@
 It is a compile-time error if the key of an entry in a constant map literal is an instance of
 a class that has a concrete operator \syntax{`=='} declaration different from the one in \code{Object},
 unless the key is a string or an integer,
-or the key expression is a literal symbol or
-an invocation of a constant constructor of class \code{Symbol}.
+or the key expression evaluates to an instance of the built-in
+class \code{Symbol} which was originally obtained by evaluation of a
+literal symbol or
+a constant invocation of a constructor of the \code{Symbol} class.
 % Needs 'free': `const <int, Function(Function<X>(X))>{}` is OK, but
 % `X` is not free.
 It is a compile-time error if a type argument of a constant map literal
@@ -4793,6 +5127,10 @@
 \end{itemize}
 
 \LMHash{}
+The objects created by map literals do not override
+the \code{==} operator inherited from the \code{Object} class.
+
+\LMHash{}
 A run-time map literal
 \code{\{$k_1:e_1, \ldots, k_n:e_n$\}}
 is evaluated as
@@ -5532,7 +5870,7 @@
 It is possible for a running isolate to exhaust its memory or stack, resulting in a run-time error that cannot be effectively caught, which will force the isolate to be suspended.
 
 \commentary{
-As discussed in section \ref{errors}, the handling of a suspended isolate is the responsibility of the embedder.
+As discussed in section \ref{errorsAndWarnings}, the handling of a suspended isolate is the responsibility of the embedder.
 }
 
 
@@ -6177,6 +6515,8 @@
 and its result is then the result of evaluating $i$.
 
 \commentary{
+The situation where \code{noSuchMethod} is invoked can only arise
+when the static type of $e_f$ is \DYNAMIC{}.
 The run-time semantics ensures that
 a function invocation may amount to an invocation of the instance method \CALL{}.
 However, an interface type with a method named \CALL{} is not itself a subtype of any function type.
@@ -6211,6 +6551,9 @@
 (\ref{actualTypeOfADeclaration})
 corresponding to the signature in the function declaration $f$,
 using the current bindings of type variables, if any.
+If $f$ denotes a static method or top-level function,
+the corresponding class does not override the \code{==} operator
+inherited from the \code{Object} class.
 %
 An invocation of $o$ with a given argument list will bind actuals to formals
 in the same way as an invocation of $f$
@@ -6496,16 +6839,9 @@
 and the result of this invocation is the result of evaluating $i$.
 
 \commentary{
+The situation where \code{noSuchMethod} is invoked can only arise
+when the static type of $e$ is \DYNAMIC{}.
 Notice that the wording avoids re-evaluating the receiver $o$ and the arguments $a_i$.
-Also note that there is no need to specify how to handle an invocation of \code{noSuchMethod}
-that fails because ``there is no such method'':
-It is not possible to override the \code{noSuchMethod} of class \code{Object}
-in such a way that it cannot be invoked with one argument of type \code{Invocation}.
-It can fail with a dynamic type error if the parameter type is overridden with a
-proper subtype of \code{Invocation},
-but that does not give rise to yet another invocation of \code{noSuchMethod}.
-% We might want to mention `noSuchMethod(covariant Null n) => n;`, but
-% `covariant` is not yet specified, and it is not a big problem to omit it.
 }
 
 
@@ -6739,14 +7075,10 @@
 Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argument $im$,
 and the result of this invocation is the result of evaluating $i$.
 
-% TODO(eernst): We have removed the description of how to invoke noSuchMethod
-% in Object if the overriding noSuchMethod does not accept one argument of
-% type Invocation, because that will be a compile-time error soon. At this
-% point we just keep a commentary ready to say that:
-%
-%% \commentary {
-%% It is a compile-time error to override the \code{noSuchMethod} of class \code{Object} in such a way that it cannot be invoked with one positional argument of type \code{Invocation}.
-%% }
+\commentary {
+The situation where \code{noSuchMethod} is invoked can only arise
+when the static type of $e$ is \DYNAMIC{}.
+}
 
 \LMHash{}
 It is a compile-time error if $m$ is a member of class \code{Object} and $e$ is either a prefix object (\ref{imports}) or a constant type literal.
@@ -6800,32 +7132,11 @@
 The body of $f$ is executed with \THIS{} bound to the current value of \THIS{}.
 The value of $i$ is the result returned by the call to the getter function.
 
-\LMHash{}
-If the getter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
-\begin{itemize}
-\item \code{$im$.isGetter} evaluates to \code{\TRUE{}}.
-\item \code{$im$.memberName} evaluates to the symbol \code{m}.
-\item \code{$im$.positionalArguments} evaluates to an empty, unmodifiable instance of
-\code{List<Object>}.
-\item \code{$im$.namedArguments} evaluates to an empty, unmodifiable instance of
-
-\code{Map<Symbol, Object>}.
-\item \code{$im$.typeArguments} evaluates to an empty, unmodifiable instance of
-
-\code{List<Type>}.
-\end{itemize}
-
-\LMHash{}
-Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$.
-
-% TODO(eernst): We have removed the description of how to invoke noSuchMethod
-% in Object if the overriding noSuchMethod does not accept one argument of
-% type Invocation, because that will be a compile-time error soon. At this
-% point we just keep a commentary ready to say that:
-%
-%% \commentary {
-%% It is a compile-time error to override the \code{noSuchMethod} of class \code{Object} in such a way that it cannot be invoked with one positional argument of type \code{Invocation}.
-%% }
+\commentary{
+The getter lookup will not fail, because it is a compile-time error to have
+a super property extraction of a member $m$ when the superclass $S_{dynamic}$
+does not have a concrete member named $m$.
+}
 
 \LMHash{}
 Let $S_{static}$ be the superclass of the immediately enclosing class.
@@ -7080,6 +7391,11 @@
 
 \LMHash{}
 \Case{\code{$v$ = $e$}}
+%% TODO(eernst): This _only_ works if we assume that `v = e` has already
+%% been expanded to `this.v = e` "when that's the right thing to do".
+%% Otherwise `denotes` below cannot be interpreted as the result of a lookup,
+%% and we have no precise alternative which would work. We might be able
+%% to repair this by giving a definition of `denotes` somewhere.
 Consider an assignment $a$ of the form \code{$v$ = $e$},
 where $v$ is an identifier or an identifier qualified by an import prefix,
 and $v$ denotes a variable (\ref{variables}) or \code{$v$=} denotes a setter
@@ -7109,8 +7425,8 @@
 If no error occurs, the value of the assignment expression is $o$.
 
 \commentary{
-If $v$ is a final variable, a compile-time error has occurred,
-but a type check may cause a dynamic error.
+If $v$ is a final variable, a compile-time error has occurred and execution is unspecified.
+But a program with no compile-time errors may incur a dynamic type error.
 }
 
 % add local functions per bug 23218
@@ -7147,8 +7463,8 @@
 \LMHash{}
 \Case{\code{$e_1$?.$v$ = $e_2$}}
 Consider an assignment $a$ of the form \code{$e_1$?.$v$ = $e_2$}.
-Let $S$ be the static type of the formal parameter of the setter \code{$v$=}.
-It is a compile-time error if the static type of $e_2$ may not be assigned to $S$.
+Exactly the same compile-time errors that would be caused by
+\code{$e_1$.$v$ = $e_2$} are also generated in the case of $a$.
 The static type of $a$ is the static type of $e_2$.
 
 \LMHash{}
@@ -7164,9 +7480,14 @@
 \LMHash{}
 \Case{\code{$e_1$.$v$ = $e_2$}}
 Consider an assignment $a$ of the form \code{$e_1$.$v$ = $e_2$}.
-Let $S$ be the static type of the formal parameter of the setter \code{$v$=}.
-It is a compile-time error if the static type of $e_2$ may not be assigned to $S$.
-The static type of $a$ is the static type of $e_2$.
+Let $T$ be the static type of $e_1$.
+If $T$ is \DYNAMIC{}, no further checks are performed.
+Otherwise, it is a compile-time error unless
+$T$ has an accessible instance setter named \code{$v$=}.
+It is a compile-time error unless the static type of $e_2$
+may be assigned to the declared type of the formal parameter of said setter.
+Whether or not $T$ is \DYNAMIC{},
+the static type of $a$ is the static type of $e_2$.
 
 \LMHash{}
 Evaluation of an assignment of the form \code{$e_1$.$v$ = $e_2$}
@@ -7174,10 +7495,10 @@
 The expression $e_1$ is evaluated to an object $o_1$.
 Then, the expression $e_2$ is evaluated to an object $o_2$.
 Then, the setter \code{$v$=} is looked up (\ref{lookup}) in $o_1$ with respect to the current library.
-%% TODO(eernst): This is metaclass stuff, should be deleted.
-If $o_1$ is an instance of \code{Type} but $e_1$ is not a constant type literal,
-then if \code{$v$=} is a setter that forwards (\ref{functionDeclarations}) to a static setter, setter lookup fails.
-Otherwise, the body of \code{$v$=} is executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$.
+It is a dynamic type error if the dynamic type of $o_2$
+is not a subtype of the actual parameter type of said setter
+(\ref{actualTypeOfADeclaration}).
+Otherwise, the body of the setter is executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$.
 
 \LMHash{}
 If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
@@ -7197,36 +7518,21 @@
 \LMHash{}
 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with argument $im$.
 
-% TODO(eernst): We have removed the description of how to invoke noSuchMethod
-% in Object if the overriding noSuchMethod does not accept one argument of
-% type Invocation, because that will be a compile-time error soon. At this
-% point we just keep a commentary ready to say that:
-%
-%% \commentary {
-%% It is a compile-time error to override the \code{noSuchMethod} of class \code{Object} in such a way that it cannot be invoked with one positional argument of type \code{Invocation}.
-%% }
+\commentary{
+The situation where \code{noSuchMethod} is invoked can only arise
+when the static type of $e_1$ is \DYNAMIC{}.
+}
 
 \LMHash{}
 The value of the assignment expression is $o_2$ irrespective of whether setter lookup has failed or succeeded.
 
 \LMHash{}
-It is a dynamic type error if $o_2$ is not the null object (\ref{null})
-and the dynamic type of $o_2$ is
-not a subtype of the actual type of $e_1.v$
-(\ref{actualTypeOfADeclaration}).
-
-\LMHash{}
-Let $T$ be the static type of $e_1$.
-It is a compile-time error if $T$ does not have an accessible instance setter named \code{$v$=}
-%% TODO(eernst): This is metaclass stuff, should be deleted.
-unless $T$ is \code{Type}, $e_1$ is a constant type literal and the class corresponding to $e_1$ has a static setter named \code{$v$=}.
-
-\LMHash{}
 \Case{\code{\SUPER.$v$ = $e$}}
 Consider an assignment $a$ of the form \code{\SUPER.$v$ = $e$}.
 Let $S_{static}$ be the superclass of the immediately enclosing class.
-It is a compile-time error if $S_{static}$ does not have an accessible instance setter named \code{$v$=}.
-Otherwise, it is a compile-time error if the static type of $e$ may not be assigned to the static type of the formal parameter of the setter \code{$v$=}.
+It is a compile-time error if $S_{static}$ does not have a concrete accessible instance setter named \code{$v$=}.
+Otherwise, it is a compile-time error if the static type of $e$
+may not be assigned to the static type of the formal parameter of said setter.
 The static type of $a$ is the static type of $e$.
 
 \LMHash{}
@@ -7239,42 +7545,34 @@
 The body of \code{$v$=} is executed with its formal parameter bound to $o$
 and \THIS{} bound to the current value of \THIS{}.
 
-\LMHash{}
-If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
-\begin{itemize}
-\item \code{$im$.isSetter} evaluates to \code{\TRUE{}}.
-\item \code{$im$.memberName} evaluates to the symbol \code{v=}.
-\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
-with the same values as \code{<Object>[$o$]}.
-\item \code{$im$.namedArguments} evaluates to an empty unmodifiable instance of
-
-\code{Map<Symbol, Object>}.
-\item \code{$im$.typeArguments} evaluates to an empty, unmodifiable instance of
-
-\code{List<Type>}.
-\end{itemize}
+\commentary{
+The setter lookup will not fail, because it is a compile-time error
+when no concrete setter named \code{$v$=} exists in $S_{static}$.
+}
 
 \LMHash{}
-Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$.
-
-\LMHash{}
-The value of the assignment expression is $o$ irrespective of whether setter lookup has failed or succeeded.
+The value of the assignment expression is $o$.
 
 \LMHash{}
 It is a dynamic type error if $o$ is not the null object (\ref{null})
 and the dynamic type of $o$ is
-not a subtype of the actual type of \code{$S$.$v$}
-(\ref{actualTypeOfADeclaration}).
+not a subtype of the actual type of the formal parameter of \code{$v$=}
+(\ref{actualTypeOfADeclaration}) in $S_{static}$.
 
 \LMHash{}
 \Case{\code{$e_1$[$e_2$] = $e_3$}}
 Consider an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}.
-It is a compile-time error if the static type of $e_1$ does not have a method named \code{[]=}.
-Otherwise, let $S_2$ be the static type of the first formal parameter of the method \code{[]=}
+Let $T$ be the static type of $e_1$.
+If $T$ is \DYNAMIC{}, no further checks are performed.
+Otherwise, it is a compile-time error unless
+$T$ has a method named \code{[]=}.
+Let $S_2$ be the static type of the
+first formal parameter of the method \code{[]=},
 and $S_3$ the static type of the second.
-It is a compile-time error if the static type of $e_2$ may not be assigned to $S_2$,
-and if the static type of $e_3$ may not be assigned to $S_3$.
-The static type of $a$ is the static type of $e_3$.
+It is a compile-time error unless the static type of $e_2$ respectively $e_3$
+may be assigned to $S_2$ respectively $S_3$.
+Whether or not $T$ is \DYNAMIC{},
+the static type of $a$ is the static type of $e_3$.
 
 \LMHash{}
 Evaluation of an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}
@@ -7289,10 +7587,11 @@
 Consider an assignment $a$ of the form \code{\SUPER[$e_1$] = $e_2$}.
 Let $S_{static}$ be the superclass of the immediately enclosing class.
 It is a compile-time error if $S_{static}$ does not have a method \code{[]=}.
-Otherwise, let $S_1$ be the static type of the first formal parameter of the method \code{[]=}
+Otherwise, let $S_1$ be the static type of the
+first formal parameter of the method \code{[]=},
 and $S_2$ the static type of the second.
-It is a compile-time error if the static type of $e_1$ may not be assigned to $S_1$,
-and if the static type of $e_2$ may not be assigned to $S_2$.
+It is a compile-time error if the static type of $e_1$ respectively $e_2$
+may not be assigned to $S_1$ respectively $S_2$.
 The static type of $a$ is the static type of $e_2$.
 
 \LMHash{}
@@ -7521,16 +7820,17 @@
 Otherwise the value of $c$ is the result of evaluating the expression $e_3$.
 
 \LMHash{}
-If all of the following hold:
+If $e_1$ shows that a local variable $v$ has type $T$,
+then the type of $v$ is known to be $T$ in $e_2$,
+unless any of the following are true:
 \begin{itemize}
-\item $e_1$ shows that a local variable $v$ has type $T$.
-\item $v$ is not potentially mutated in $e_2$ or within a function.
-\item If the variable $v$ is accessed by a function in $e_2$ then
-$v$ is not potentially mutated anywhere in the scope of $v$.
+\item $v$ is potentially mutated in $e_2$,
+\item $v$ is potentially mutated within a function other
+than the one where $v$ is declared, or
+\item $v$ is accessed by a function defined in $e_2$ and
+$v$ is potentially mutated anywhere in the scope of $v$.
 \end{itemize}
 
-then the type of $v$ is known to be $T$ in $e_2$.
-
 \LMHash{}
 It is a compile-time error if the static type of $e_1$ may not be assigned to \code{bool}.
 The static type of $c$ is the least upper bound (\ref{leastUpperBounds}) of the static type of $e_2$ and the static type of $e_3$.
@@ -7595,18 +7895,30 @@
 if both of the following conditions hold:
 \begin{itemize}
 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type $T$.
-\item $v$ is not mutated in $e_2$ or within a function.
+\item $v$ is not mutated in $e_2$ or within a function other than the one where $v$ is declared.
 \end{itemize}
 
 \LMHash{}
-Furthermore, if all of the following hold:
+If $e_1$ shows that a local variable $v$ has type $T$,
+then the type of $v$ is known to be $T$ in $e_2$,
+unless any of the following are true:
 \begin{itemize}
-\item $e_1$ shows that $v$ has type $T$.
-\item $v$ is not mutated in either $e_1$, $e_2$ or within a function.
-\item If $v$ is accessed by a function in $e_2$ then
-$v$ is not potentially mutated anywhere in the scope of $v$.
+%% The first item here is unnecessary for soundness,
+%% and is retained mainly for backwards compatibility.
+%% If $e_1$ shows that $v$ has type $T$, then any assignment
+%% in $e_1$ does not invalidate that.
+%% Removing the line is visible in the semantics, though, because:
+%%  num x;
+%%  (x ??= 42) != null && x is int & x.toRadixString(16) != ""
+%% is allowed without the line, and disallowed with.
+%% At time of writing, the analyzer disallows the code.
+\item $v$ is potentially mutated in $e_1$,
+\item $v$ is potentially mutated in $e_2$,
+\item $v$ is potentially mutated within a function other
+than the one where $v$ is declared, or
+\item $v$ is accessed by a function defined in $e_2$ and
+$v$ is potentially mutated anywhere in the scope of $v$.
 \end{itemize}
-then the type of $v$ is known to be $T$ in $e_2$.
 
 \LMHash{}
 It is a compile-time error if the static type of $e_1$ may not be assigned to \code{bool} or if the static type of $e_2$ may not be assigned to \code{bool}.
@@ -7851,9 +8163,9 @@
 Evaluation of an expression of the form \code{-{}-$e$} is equivalent to \code{$e$\,-=\,1}.
 
 \LMHash{}
-If $e$ is an expression of the form \code{-$l$}
+Let $e$ be an expression of the form \code{-$l$}
 where $l$ is an integer literal (\ref{numbers}) with numeric integer value $i$,
-and with static contex type $T$.
+and with static context type $T$.
 If \code{double} is assignable to $T$ and \code{int} is not assignable to $T$,
 then the static type of $e$ is \code{double};
 otherwise the static type of $e$ is \code{int}.
@@ -7861,12 +8173,16 @@
 \LMHash{}
 If the static type of $e$ is \code{int} then $e$ evaluates to
 to an instance of the \code{int} class representing the numeric value $-i$.
+If $i$ is zero and the \code{int} class can represent a negative zero value,
+then the resulting instance instead represents that negative zero value.
 It is a compile-time error if the integer $-i$ cannot be represented
 exactly by an instance of \code{int}.
 
 \LMHash{}
 If the static type of $e$ is \code{double} then $e$ evaluates to
 to an instance of the \code{double} class representing the numeric value $-i$.
+If $i$ is zero, the resulting instance instead represents the
+\emph{negative} zero double value, \code{-0.0}.
 It is a compile-time error if the integer $-i$ cannot be represented
 exactly by an instance of \code{double}.
 \commentary{
@@ -8540,9 +8856,11 @@
 is \DYNAMIC{}.
 
 \LMHash{}
-Let $v$ be an initialized local variable and let $e$ be the associated initializing expression.
+Let $v$ be a local variable declared by an initializing variable declaration,
+and let $e$ be the associated initializing expression.
 It is a compile-time error if the static type of $e$ is not assignable to the type of $v$.
-It is a compile-time error if a local variable $v$ is final and $v$ is not an initialized variable.
+It is a compile-time error if a local variable $v$ is final,
+and the declaration of $v$ is not an initializing variable declaration.
 
 \commentary{
 It is also a compile-time error to assign to a final local variable
@@ -8761,14 +9079,16 @@
 It is a compile-time error if the type of the expression $b$ may not be assigned to \code{bool}.
 
 \LMHash{}
-If:
+If $b$ shows that a local variable $v$ has type $T$,
+then the type of $v$ is known to be $T$ in $s_2$,
+unless any of the following are true
 \begin{itemize}
-\item $b$ shows that a local variable $v$ has type $T$.
-\item $v$ is not potentially mutated in $s_1$ or within a function.
-\item If $v$ is accessed by a function in $s_1$ then
-$v$ is not potentially mutated anywhere in the scope of $v$.
+\item $v$ is potentially mutated in $s_1$,
+\item $v$ is potentially mutated within a function other
+than the one where $v$ is declared, or
+\item $v$ is accessed by a function defined in $s_1$ and
+$v$ is potentially mutated anywhere in the scope of $v$.
 \end{itemize}
-then the type of $v$ is known to be $T$ in $s_1$.
 
 \LMHash{}
 An if statement of the form \code{\IF{} ($e$) $s$} is equivalent to the if statement \code{\IF{} ($e$) $s$ \ELSE{} \{\}}.
@@ -9089,8 +9409,10 @@
 It is a compile-time error if the class $C$ has an implementation of
 the operator \code{==} other than the one inherited from \code{Object},
 unless the expression evaluates to a string or an integer,
-or the expression is a literal symbol or
-an invocation of a constant constructor of class \code{Symbol}.
+or the expression evaluates to an instance of the built-in
+class \code{Symbol} which was initially obtained by evaluation of a
+literal symbol or
+a constant invocation of a constructor of the \code{Symbol} class.
 
 \rationale{
 The prohibition on user defined equality allows us to implement the switch efficiently for user defined types.
@@ -9216,7 +9538,7 @@
 }
 
 \LMHash{}
-It is a compile-time error if all of the following conditions hold:
+It is a compile-time warning if all of the following conditions hold:
 \begin{itemize}
 \item The switch statement does not have a default clause.
 \item The static type of $e$ is an enumerated type with elements $\id_1, \ldots, \id_n$.
@@ -9224,7 +9546,7 @@
 \end{itemize}
 
 \commentary{
-In other words, an error will be raised if a switch statement over an enum is not exhaustive.
+In other words, a warning will be emitted if a switch statement over an enum is not exhaustive.
 }
 
 
@@ -9459,8 +9781,8 @@
 }
 
 \LMHash{}
-Let $f$ be the function immediately enclosing a return statement of the form \RETURN{};.
-It is a compile-time error if $f$ is neither a generator nor a generative constructor and either:
+Let $f$ be the function immediately enclosing a return statement of the form \code{\RETURN{};}.
+It is a compile-time warning if $f$ is neither a generator nor a generative constructor and either:
 \begin{itemize}
 %% TODO(eernst): Integrating generalized-void.md, "may not be assigned
 %% to void" is useless. Update, also considering invalid_returns.md.
@@ -9470,7 +9792,8 @@
 \end{itemize}
 
 \commentary{
-Hence, a compile-time error will not be raised if $f$ has no declared return type,
+Hence, a compile-time warning will not be raised if $f$ has no declared return type,
+%% TODO(eernst): Update when integrating generalized-void.md!
 since the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VOID{} and to \code{Future<Null>}.
 However, any synchronous non-generator function that declares a return type must return an expression explicitly.
 }
@@ -10159,7 +10482,7 @@
 }
 
 \LMHash{}
-It is a compile-time error to import two different libraries with the same name unless their name is the empty string.
+It is a compile-time warning to import two different libraries with the same name unless their name is the empty string.
 
 \commentary{
 A widely disseminated library should be given a name that will not conflict with other such libraries.
@@ -10626,6 +10949,8 @@
 
 \LMHash{}
 When types are reified as instances of the built-in class \code{Type},
+those objects override the \code{==} operator
+inherited from the \code{Object} class, so that
 two \code{Type} objects are equal according to operator \syntax{`=='}
 if{}f the corresponding types are subtypes of each other.
 
@@ -11433,7 +11758,7 @@
 Unary postfix & \code{$e$.}, \code{$e$?.}, \code{$e$++}, \code{$e$-{}-}, \code{$e1$[$e2$]},
 \code{$e$()} & None & 16 \\
 \hline
-Unary prefix & \code{-$e$}, \code{!$e$}, \code{\~{}$e$}, \code{++$e$}, \code{-{}-$e$} & None & 15\\
+Unary prefix & \code{-$e$}, \code{!$e$}, \code{\~{}$e$}, \code{++$e$}, \code{-{}-$e$}, \code{\AWAIT{} $e$} & None & 15\\
 \hline
 Multiplicative & \code{*}, \code{/}, \code{\~{}/}, \code{\%} & Left & 14\\
 \hline
diff --git a/docs/language/informal/instantiate-to-bound.md b/docs/language/informal/instantiate-to-bound.md
index 4bed76e..dfe36bc 100644
--- a/docs/language/informal/instantiate-to-bound.md
+++ b/docs/language/informal/instantiate-to-bound.md
@@ -99,9 +99,42 @@
 
 ## Static analysis
 
-Let _G_ be a generic class or parameterized type alias with formal type
-parameter declarations
-_F<sub>1</sub> .. F<sub>k</sub>_ containing formal type parameters
+We will define simple bounds, but at first we need an auxiliary concept.
+Let _T_ be a type of the form `typeName`. A type _S_ then _contains_ _T_
+if one of the following conditions hold:
+
+- _S_ is of the form `typeName`, and _S_ is _T_.
+- _S_ is of the form `typeName typeArguments`, and one of the type
+  arguments contains _T_.
+- _S_ is of the form `typeName typeArguments?` where `typeName` denotes a
+  type alias _F_, and the body of _F_ contains _T_.
+- _S_ is of the form
+  `returnType? 'Function' typeParameters? parameterTypeList` and
+  `returnType?` contains _T_, or a bound in `typeParameters?` contains _T_,
+  or the type of a parameter in `parameterTypeList` contains _T_.
+
+*Multiple cases may be applicable, e.g., when a type alias is applied to a
+list of actual type arguments, and the type alias body as well as some type
+arguments may contain _T_.*
+
+*In the rule about type aliases, _F_ may or may not be parameterized, and
+it may or may not receive type arguments. However, there is no need to
+consider the result of substituting actual type arguments for formal type
+parameters in the body of the type alias, because we only need to inspect
+all types of the form `typeName` contained in its body, and they are not
+affected by such a substitution.*
+
+*It is understood that name capture is avoided, that is, a type _S_ does
+not contain `p.C` even if _S_ contains `F` which denotes a type alias whose
+body contains the syntax `p.C`, say, as a return type, if `p` has different
+meanings in _S_ and in the body of _F_. This could occur because _S_ and
+_F_ are declared in different libraries. Similarly, when a type parameter
+bound _B_ contains a type variable `X` from the enclosing class, it is
+never because `X` is contained in the body of a type alias, it will always
+be as a syntactic subterm of _B_.*
+
+Let _G_ be a generic class or parameterized type alias with _k_ formal type
+parameter declarations containing formal type parameters
 _X<sub>1</sub> .. X<sub>k</sub>_ and bounds
 _B<sub>1</sub> .. B<sub>k</sub>_. We say that the formal type parameter
 _X<sub>j</sub>_ has a _simple bound_ when one of the following requirements
@@ -110,8 +143,8 @@
 1. _B<sub>j</sub>_ is omitted.
 
 2. _B<sub>j</sub>_ is included, but does not contain any of _X<sub>1</sub>
-   .. X<sub>k</sub>_. If _B<sub>j</sub>_ contains a type _T_ on the form
-   `qualified` (*for instance, `C` or `p.D`*) which denotes a generic class
+   .. X<sub>k</sub>_. If _B<sub>j</sub>_ contains a type _T_ of the form
+   `typeName` (*for instance, `C` or `p.D`*) which denotes a generic class
    or parameterized type alias _G<sub>1</sub>_ (*that is, _T_ is a raw type*),
    every type argument of _G<sub>1</sub>_ has a simple bound.
 
@@ -130,7 +163,7 @@
 all bounds because any generic type may be used as a raw type.*
 
 It is a compile-time error if a formal parameter bound _B_ contains a type
-_T_ on the form `qualified` and _T_ denotes a generic class or parameterized
+_T_ on the form `typeName` and _T_ denotes a generic class or parameterized
 type alias _G_ (*that is, _T_ is a raw type*), unless every formal type
 parameter of _G_ has a simple bound.
 
@@ -140,7 +173,7 @@
 parameter `X` that corresponds to the omitted type argument does not have a
 simple bound.*
 
-When a type annotation _T_ on the form `qualified` denotes a generic class
+When a type annotation _T_ on the form `typeName` denotes a generic class
 or parameterized type alias (*so _T_ is raw*), instantiate to bound is used
 to provide the missing type argument list. It is a compile-time error if
 the instantiate to bound process fails.
@@ -157,7 +190,7 @@
 infer the omitted type arguments, e.g., for `List xs = [];`.*
 
 *When type inference is providing actual type arguments for a term _G_ on
-the form `qualified` which denotes a generic class or a parameterized type
+the form `typeName` which denotes a generic class or a parameterized type
 alias, instantiate to bound may be used to provide the value for type
 arguments where no information is available for inferring such an actual
 type argument. This document does not specify how inference interacts with
@@ -166,7 +199,7 @@
 applies to a type argument list which is omitted, such that a value for all
 the actual type arguments must be computed.*
 
-Let _T_ be a `qualified` term which denotes a generic class or
+Let _T_ be a `typeName` term which denotes a generic class or
 parameterized type alias _G_ (*so _T_ is a raw type*), let
 _F<sub>1</sub> .. F<sub>k</sub>_ be the formal type
 parameter declarations in the declaration of _G_, with type parameters
diff --git a/docs/language/informal/interface-conflicts.md b/docs/language/informal/interface-conflicts.md
new file mode 100644
index 0000000..cd1d7f3
--- /dev/null
+++ b/docs/language/informal/interface-conflicts.md
@@ -0,0 +1,275 @@
+# Feature Specification: Interface Conflict Management
+
+**Owner**: eernst@
+
+**Status**: Under discussion.
+
+**Version**: 0.3 (2018-04-24)
+
+
+This document is a Dart 2 feature specification which specifies how to
+handle conflicts among certain program elements associated with the
+interface of a class. In particular, it specifies that multiple occurrences
+of the same generic class in the superinterface hierarchy must receive the
+same type arguments, and that no attempts are made at synthesizing a
+suitable method signature if multiple distinct signatures are provided by
+the superinterfaces, and none of them resolves the conflict.
+
+
+## Motivation
+
+In Dart 1, the management of conflicts during the computation of the
+interface of a class is rather forgiving. On page 42 of
+[ECMA-408](https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf),
+we have the following:
+
+> However, if the above rules would cause multiple members
+> _m<sub>1</sub>, ..., m<sub>k</sub>_
+> with the same name _n_ to be inherited (because identically named
+> members existed in several superinterfaces) then at most one member
+> is inherited.
+>
+> ...
+>
+> Then _I_ has a method named _n_, with _r_ required parameters of type
+> `dynamic`, _h_ positional parameters of type `dynamic`, named parameters
+> _s_ of type `dynamic` and return type `dynamic`.
+
+In particular, the resulting class interface may then contain a method
+signature which has been synthesized during static analysis, and which
+differs from all declarations of the given method in the source code.
+In the case where some superintenfaces specify some optional positional
+parameters and others specify some named parameters, any attempt to
+implement the synthesized method signature other than via a user-defined
+`noSuchMethod` would fail (it would be a syntax error to declare both
+kinds of parameters in the same method declaration).
+
+For Dart 2 we modify this approach such that more emphasis is given to
+predictability, and less emphasis is given to convenience: No class
+interface will ever contain a method signature which has been
+synthesized during static analysis, it will always be one of the method
+interfaces that occur in the source code. In case of a conflict, the
+developer must explicitly specify how to resolve the conflict.
+
+To reinforce the same emphasis on predictability, we also specify that
+it is a compile-time error for a class to have two superinterfaces which
+are instantiations of the same generic class with different type arguments.
+
+
+## Syntax
+
+The grammar remains unchanged.
+
+
+## Static Analysis
+
+We introduce a new relation among types, _more interface-specific than_,
+which is similar to the subtype relation, but which treats top types
+differently.
+
+- The built-in class `Object` is more interface-specific than `void`.
+- The built-in type `dynamic` is more interface-specific than `void`.
+- None of `Object` and `dynamic` is more interface-specific than the other.
+- All other subtype rules are also valid rules about being more
+  interface-specific.
+
+This means that we will express the complete rules for being 'more
+interface-specific than' as a slight modification of
+[subtyping.md](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/subtyping.md)
+and in particular, the rule 'Right Top' will need to be split in cases
+such that `Object` and `dynamic` are more interface-specific than `void` and
+mutually unrelated, and all other types are more interface-specific than
+both `Object` and `dynamic`.
+
+*For example, `List<Object>` is more interface-specific than `List<void>`
+and incomparable to `List<dynamic>`; similarly, `int Function(void)` is
+more interface-specific than `void Function(Object)`, but the latter is
+incomparable to `void Function(dynamic)`.*
+
+It is a compile-time error if a class _C_ has two superinterfaces of the
+form _D<T<sub>1</sub> .. T<sub>k</sub>>_ respectively
+_D<S<sub>1</sub> .. S<sub>k</sub>>_ such that there is a _j_ in _1 .. k_
+where _T<sub>j</sub>_ and _S<sub>j</sub>_ denote types that are not
+mutually more interface-specific than each other.
+
+*This means that the (direct and indirect) superinterfaces must agree on
+the type arguments passed to any given generic class. Note that the case
+where the number of type arguments differ is unimportant because at least
+one of them is already a compile-time error for other reasons. Also note
+that it is not sufficient that the type arguments to a given superinterface
+are mutual subtypes (say, if `C` implements both `I<dynamic>` and
+`I<Object>`), because that gives rise to ambiguities which are considered
+to be compile-time errors if they had been created in a different way.*
+
+This compile-time error also arises if the type arguments are not given
+explicitly.
+
+*They might be obtained via
+[instantiate-to-bound](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/instantiate-to-bound.md)
+or, in case such a mechanism is introduced, they might be inferred.*
+
+*The language specification already contains verbiage to this effect, but we
+mention it here for two reasons: First, it is a recent change which has been
+discussed in the language team together with the rest of the topics in this
+document because of their similar nature and motivation. Second, we note
+that this restriction may be lifted in the future. It was a change in the
+specification which did not break many existing programs because `dart2js`
+always enforced that restriction (even though it was not specified in the
+language specification), so in that sense it just made the actual situation
+explicit. However, it may be possible to lift the restriction: Given that an
+instance of a class that has `List<int>` among its superinterfaces can be
+accessed via a variable of type `List<num>`, it seems unlikely that it would
+violate any language invariants to allow the class of that instance to have
+both `List<int>` and `List<num>` among its superinterfaces. We may then
+relax the rule to specify that for each generic class _G_ which occurs among
+superinterfaces, there must be a unique superinterface which is the most
+specific instantiation of _G_.*
+
+During computation of the interface of a class _C_, it may be the case that
+multiple direct superinterfaces have a declaration of a member of the same
+name _n_, and class _C_ does not declare member named _n_.
+Let _D<sub>1</sub> .. D<sub>n</sub>_ denote this set of declarations.
+
+It is a compile-time error if some declarations among
+_D<sub>1</sub> .. D<sub>n</sub>_ are getters and others are non-getters.
+
+Otherwise, if all of _D<sub>1</sub> .. D<sub>n</sub>_ are getter
+declarations, the interface of _C_ inherits one, _D<sub>j</sub>_, whose
+return type is more interface-specific than that of every declaration in
+_D<sub>1</sub> .. D<sub>n</sub>_. It is a compile-time error if no such
+_D<sub>j</sub>_ exists.
+
+*For example, it is an error to have two declarations with the signatures
+`Object get foo` and `dynamic get foo`, and no others, because none of
+these is more interface-specific than the other. This example illustrates
+why it is unsatisfactory to rely on subtyping alone: If we had accepted
+this kind of ambiguity then it would be difficult to justify the treatment
+of `o.foo.bar` during static analysis where `o` has type _C_: If it is
+considered to be a compile-time error then `dynamic get foo` is being
+ignored, and if it is not an error then `Object get foo` is being ignored,
+and each of these behaviors may be surprising and/or error-prone. Hence, we
+require such a conflict to be resolved explicitly, which may be done by
+writing a signature in the class which overrides both method signatures
+from the superinterfaces and explicitly chooses `Object` or `dynamic`.*
+
+Otherwise, (*when all declarations are non-getter declarations*), the
+interface of _C_ inherits one, _D<sub>j</sub>_, where its function type is
+more interface-specific than that of all declarations in
+_D<sub>1</sub> .. D<sub>n</sub>_. It is a compile-time error if no such
+declaration _D<sub>j</sub>_ exists.
+
+*In the case where more than one such declaration exists, it is known that
+their parameter list shapes are identical, and their return types and
+parameter types are pairwise mutually more interface-specific than each
+other (i.e., for any two such declarations _D<sub>i</sub>_ and _D<sub>j</sub>_,
+if _U<sub>i</sub>_ is the return type from _D<sub>i</sub>_ and
+_U<sub>j</sub>_ is the return type from _D<sub>j</sub>_ then
+_U<sub>i</sub>_ is more interface-specific than _U<sub>j</sub>_ and
+vice versa, and similarly for each parameter type). This still allows for
+some differences. We ignore differences in metadata on formal parameters
+(we do not consider method signatures in interfaces to have metadata). But
+we need to consider one more thing:*
+
+In this decision about which declaration among
+_D<sub>1</sub> .. D<sub>n</sub>_
+the interface of the class _C_ will inherit, if we have multiple possible
+choices, let _D<sub>i</sub>_ and _D<sub>j</sub>_ be such a pair of possible
+choices. It is a compile-time error if _D<sub>i</sub>_ and _D<sub>j</sub>_
+declare two optional formal parameters _p<sub>1</sub>_ and _p<sub>2</sub>_
+such that they correspond to each other (*same name if named, or else same
+position*) and they specify different default values.
+
+
+## Discussion
+
+Conflicts among distinct top types may be considered to be spurious in the
+case where said type occurs in a contravariant position in the method
+signature. Consider the following example:
+
+```dart
+abstract class I1 {
+  void foo(dynamic d);
+}
+
+abstract class I2 {
+  void foo(Object o);
+}
+
+abstract class C implements I1, I2 {}
+```
+
+In both situations&mdash;when `foo` accepts an argument of type `dynamic`
+and when it accepts an `Object`&mdash;the acceptable actual arguments are
+exactly the same: _Every_ object can be passed. Moreover, the formal
+parameters `d` and `o` are not in scope anywhere, so there will never be
+an expression like `d.bar` or `o.bar` which is allowed respectively
+rejected because the receiver is or is not `dynamic`. In other words,
+_it does not matter_ for clients of `C` whether that argument type is
+`dynamic` or `Object`.
+
+During inference, the type-from-context for an actual argument to `foo`
+will depend on the choice: It will be `dynamic` respectively `Object`.
+However, this choice will not affect the treatment of the actual
+argument.
+
+One case worth considering is the following:
+
+```dart
+abstract class I1 {
+  void foo(dynamic f());
+}
+
+abstract class I2 {
+  void foo(Object f());
+}
+```
+
+If a function literal is passed in at a call site, it may have its return
+type inferred to `dynamic` respectively `Object`. This will change the
+type-from-context for any returned expressions, but just like the case
+for the actual parameter, that will not change the treatment of such
+expressions. Again, it does not matter for clients calling `foo` whether
+that type is `dynamic` or `Object`.
+
+Conversely, the choice of top type matters when it is placed in a
+contravariant location in the parameter type:
+
+```dart
+abstract class I1 {
+  void foo(int f(dynamic d));
+}
+
+abstract class I2 {
+  void foo(int f(Object o));
+}
+```
+
+In this situation, a function literal used as an actual argument at a call
+site for `foo` would receive an inferred type annotation for its formal
+parameter of `dynamic` respectively `Object`, and the usage of that parameter
+in the body of the function literal would then differ. In other words, the
+developer who declares `foo` may decide whether the code in the body of the
+function literal at the call sites should use strict or relaxed type
+checking&mdash;and it would be highly error-prone if this decision were
+to be made in a way which is unspecified.
+
+All in all, it may be useful to "erase" all top types to `Object` when they
+occur in contravariant positions in method signatures, such that the
+differences that may exist do not create conflicts; in contrast, the top
+types that occur in covariant positions are significant, and hence the fact
+that we require such conflicts to be resolved explicitly is unlikely to be
+relaxed.
+
+## Updates
+
+*   Apr 24th 2018, version 0.3: Renamed 'override-specific' to
+    'interface-specific', to avoid giving the impression that it can be
+    used to determine whether a given signature can override another one
+    (the override check must use different rules, e.g., it must allow
+    `dynamic foo();` to override `Object foo();` _and_ vice versa).
+
+*   Apr 16th 2018, version 0.2: Introduced the relation 'more
+    override-specific than' in order to handle top types more consistently
+    and concisely.
+
+*   Feb 8th 2018, version 0.1: Initial version.
diff --git a/docs/language/informal/nosuchmethod-forwarding.md b/docs/language/informal/nosuchmethod-forwarding.md
index 68d1153..6fca335 100644
--- a/docs/language/informal/nosuchmethod-forwarding.md
+++ b/docs/language/informal/nosuchmethod-forwarding.md
@@ -2,7 +2,7 @@
 
 Author: eernst@
 
-**Status**: Implemented.
+**Status**: Background material, normative language now in dartLangSpec.tex.
 
 **Version**: 0.7 (2018-07-10)
 
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
new file mode 100644
index 0000000..e1e4b90
--- /dev/null
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -0,0 +1,6214 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
+
+import 'dart:core' hide deprecated;
+import 'dart:core' as core show deprecated;
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+
+class ApplyWorkspaceEditParams implements ToJsonable {
+  ApplyWorkspaceEditParams(this.label, this.edit) {
+    if (edit == null) {
+      throw 'edit is required but was not provided';
+    }
+  }
+  factory ApplyWorkspaceEditParams.fromJson(Map<String, dynamic> json) {
+    final label = json['label'];
+    final edit =
+        json['edit'] != null ? new WorkspaceEdit.fromJson(json['edit']) : null;
+    return new ApplyWorkspaceEditParams(label, edit);
+  }
+
+  /// The edits to apply.
+  final WorkspaceEdit edit;
+
+  /// An optional label of the workspace edit. This label is presented in the
+  /// user interface for example on an undo stack to undo the workspace edit.
+  final String label;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (label != null) {
+      __result['label'] = label;
+    }
+    __result['edit'] = edit ?? (throw 'edit is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('edit') &&
+        WorkspaceEdit.canParse(obj['edit']);
+  }
+}
+
+class ApplyWorkspaceEditResponse implements ToJsonable {
+  ApplyWorkspaceEditResponse(this.applied) {
+    if (applied == null) {
+      throw 'applied is required but was not provided';
+    }
+  }
+  factory ApplyWorkspaceEditResponse.fromJson(Map<String, dynamic> json) {
+    final applied = json['applied'];
+    return new ApplyWorkspaceEditResponse(applied);
+  }
+
+  /// Indicates whether the edit was applied or not.
+  final bool applied;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['applied'] =
+        applied ?? (throw 'applied is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('applied') &&
+        obj['applied'] is bool;
+  }
+}
+
+class CancelParams implements ToJsonable {
+  CancelParams(this.id) {
+    if (id == null) {
+      throw 'id is required but was not provided';
+    }
+  }
+  factory CancelParams.fromJson(Map<String, dynamic> json) {
+    final id = json['id'] is num
+        ? new Either2<num, String>.t1(json['id'])
+        : (json['id'] is String
+            ? new Either2<num, String>.t2(json['id'])
+            : (throw '''${json['id']} was not one of (number, string)'''));
+    return new CancelParams(id);
+  }
+
+  /// The request id to cancel.
+  final Either2<num, String> id;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['id'] = id ?? (throw 'id is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('id') &&
+        (obj['id'] is num || obj['id'] is String);
+  }
+}
+
+class ClientCapabilities implements ToJsonable {
+  ClientCapabilities(this.workspace, this.textDocument, this.experimental);
+  factory ClientCapabilities.fromJson(Map<String, dynamic> json) {
+    final workspace = json['workspace'] != null
+        ? new WorkspaceClientCapabilities.fromJson(json['workspace'])
+        : null;
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentClientCapabilities.fromJson(json['textDocument'])
+        : null;
+    final experimental = json['experimental'];
+    return new ClientCapabilities(workspace, textDocument, experimental);
+  }
+
+  /// Experimental client capabilities.
+  final dynamic experimental;
+
+  /// Text document specific client capabilities.
+  final TextDocumentClientCapabilities textDocument;
+
+  /// Workspace specific client capabilities.
+  final WorkspaceClientCapabilities workspace;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (workspace != null) {
+      __result['workspace'] = workspace;
+    }
+    if (textDocument != null) {
+      __result['textDocument'] = textDocument;
+    }
+    if (experimental != null) {
+      __result['experimental'] = experimental;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// A code action represents a change that can be performed in code, e.g. to fix
+/// a problem or to refactor code.
+///
+/// A CodeAction must set either `edit` and/or a `command`. If both are
+/// supplied, the `edit` is applied first, then the `command` is executed.
+class CodeAction implements ToJsonable {
+  CodeAction(this.title, this.kind, this.diagnostics, this.edit, this.command) {
+    if (title == null) {
+      throw 'title is required but was not provided';
+    }
+  }
+  factory CodeAction.fromJson(Map<String, dynamic> json) {
+    final title = json['title'];
+    final kind = json['kind'];
+    final diagnostics = json['diagnostics']
+        ?.map((item) => item != null ? new Diagnostic.fromJson(item) : null)
+        ?.cast<Diagnostic>()
+        ?.toList();
+    final edit =
+        json['edit'] != null ? new WorkspaceEdit.fromJson(json['edit']) : null;
+    final command =
+        json['command'] != null ? new Command.fromJson(json['command']) : null;
+    return new CodeAction(title, kind, diagnostics, edit, command);
+  }
+
+  /// A command this code action executes. If a code action provides an edit and
+  /// a command, first the edit is executed and then the command.
+  final Command command;
+
+  /// The diagnostics that this code action resolves.
+  final List<Diagnostic> diagnostics;
+
+  /// The workspace edit this code action performs.
+  final WorkspaceEdit edit;
+
+  /// The kind of the code action.
+  ///
+  /// Used to filter code actions.
+  final String kind;
+
+  /// A short, human-readable, title for this code action.
+  final String title;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['title'] = title ?? (throw 'title is required but was not set');
+    if (kind != null) {
+      __result['kind'] = kind;
+    }
+    if (diagnostics != null) {
+      __result['diagnostics'] = diagnostics;
+    }
+    if (edit != null) {
+      __result['edit'] = edit;
+    }
+    if (command != null) {
+      __result['command'] = command;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('title') &&
+        obj['title'] is String;
+  }
+}
+
+/// Contains additional diagnostic information about the context in which a code
+/// action is run.
+class CodeActionContext implements ToJsonable {
+  CodeActionContext(this.diagnostics, this.only) {
+    if (diagnostics == null) {
+      throw 'diagnostics is required but was not provided';
+    }
+  }
+  factory CodeActionContext.fromJson(Map<String, dynamic> json) {
+    final diagnostics = json['diagnostics']
+        ?.map((item) => item != null ? new Diagnostic.fromJson(item) : null)
+        ?.cast<Diagnostic>()
+        ?.toList();
+    final only = json['only']?.map((item) => item)?.cast<String>()?.toList();
+    return new CodeActionContext(diagnostics, only);
+  }
+
+  /// An array of diagnostics.
+  final List<Diagnostic> diagnostics;
+
+  /// Requested kind of actions to return.
+  ///
+  /// Actions not of this kind are filtered out by the client before being
+  /// shown. So servers can omit computing them.
+  final List<String> only;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['diagnostics'] =
+        diagnostics ?? (throw 'diagnostics is required but was not set');
+    if (only != null) {
+      __result['only'] = only;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('diagnostics') &&
+        (obj['diagnostics'] is List &&
+            (obj['diagnostics'].length == 0 ||
+                obj['diagnostics'].every((item) => Diagnostic.canParse(item))));
+  }
+}
+
+/// A set of predefined code action kinds
+abstract class CodeActionKind {
+  /// Base kind for quickfix actions: 'quickfix'
+  static const QuickFix = 'quickfix';
+
+  /// Base kind for refactoring actions: 'refactor'
+  static const Refactor = 'refactor';
+
+  /// Base kind for refactoring extraction actions: 'refactor.extract'
+  ///
+  /// Example extract actions:
+  ///
+  /// - Extract method
+  /// - Extract function
+  /// - Extract variable
+  /// - Extract interface from class
+  /// - ...
+  static const RefactorExtract = 'refactor.extract';
+
+  /// Base kind for refactoring inline actions: 'refactor.inline'
+  ///
+  /// Example inline actions:
+  ///
+  /// - Inline function
+  /// - Inline variable
+  /// - Inline constant
+  /// - ...
+  static const RefactorInline = 'refactor.inline';
+
+  /// Base kind for refactoring rewrite actions: 'refactor.rewrite'
+  ///
+  /// Example rewrite actions:
+  ///
+  /// - Convert JavaScript function to class
+  /// - Add or remove parameter
+  /// - Encapsulate field
+  /// - Make method static
+  /// - Move method to base class
+  /// - ...
+  static const RefactorRewrite = 'refactor.rewrite';
+
+  /// Base kind for source actions: `source`
+  ///
+  /// Source code actions apply to the entire file.
+  static const Source = 'source';
+
+  /// Base kind for an organize imports source action: `source.organizeImports`
+  static const SourceOrganizeImports = 'source.organizeImports';
+}
+
+/// Code Action options.
+class CodeActionOptions implements ToJsonable {
+  CodeActionOptions(this.codeActionKinds);
+  factory CodeActionOptions.fromJson(Map<String, dynamic> json) {
+    final codeActionKinds =
+        json['codeActionKinds']?.map((item) => item)?.cast<String>()?.toList();
+    return new CodeActionOptions(codeActionKinds);
+  }
+
+  /// CodeActionKinds that this server may return.
+  ///
+  /// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or
+  /// the server may list out every specific kind they provide.
+  final List<String> codeActionKinds;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (codeActionKinds != null) {
+      __result['codeActionKinds'] = codeActionKinds;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// Params for the CodeActionRequest
+class CodeActionParams implements ToJsonable {
+  CodeActionParams(this.textDocument, this.range, this.context) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (context == null) {
+      throw 'context is required but was not provided';
+    }
+  }
+  factory CodeActionParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final context = json['context'] != null
+        ? new CodeActionContext.fromJson(json['context'])
+        : null;
+    return new CodeActionParams(textDocument, range, context);
+  }
+
+  /// Context carrying additional information.
+  final CodeActionContext context;
+
+  /// The range for which the command was invoked.
+  final Range range;
+
+  /// The document in which the command was invoked.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    __result['context'] =
+        context ?? (throw 'context is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']) &&
+        obj.containsKey('context') &&
+        CodeActionContext.canParse(obj['context']);
+  }
+}
+
+class CodeActionRegistrationOptions
+    implements TextDocumentRegistrationOptions, CodeActionOptions, ToJsonable {
+  CodeActionRegistrationOptions(this.documentSelector, this.codeActionKinds);
+  factory CodeActionRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    final codeActionKinds =
+        json['codeActionKinds']?.map((item) => item)?.cast<String>()?.toList();
+    return new CodeActionRegistrationOptions(documentSelector, codeActionKinds);
+  }
+
+  /// CodeActionKinds that this server may return.
+  ///
+  /// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or
+  /// the server may list out every specific kind they provide.
+  final List<String> codeActionKinds;
+
+  /// A document selector to identify the scope of the registration. If set to
+  /// null the document selector provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['documentSelector'] = documentSelector;
+    if (codeActionKinds != null) {
+      __result['codeActionKinds'] = codeActionKinds;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// A code lens represents a command that should be shown along with source
+/// text, like the number of references, a way to run tests, etc.
+///
+/// A code lens is _unresolved_ when no command is associated to it. For
+/// performance reasons the creation of a code lens and resolving should be done
+/// in two stages.
+class CodeLens implements ToJsonable {
+  CodeLens(this.range, this.command, this.data) {
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+  }
+  factory CodeLens.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final command =
+        json['command'] != null ? new Command.fromJson(json['command']) : null;
+    final data = json['data'];
+    return new CodeLens(range, command, data);
+  }
+
+  /// The command this code lens represents.
+  final Command command;
+
+  /// A data entry field that is preserved on a code lens item between a code
+  /// lens and a code lens resolve request.
+  final dynamic data;
+
+  /// The range in which this code lens is valid. Should only span a single
+  /// line.
+  final Range range;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    if (command != null) {
+      __result['command'] = command;
+    }
+    if (data != null) {
+      __result['data'] = data;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']);
+  }
+}
+
+/// Code Lens options.
+class CodeLensOptions implements ToJsonable {
+  CodeLensOptions(this.resolveProvider);
+  factory CodeLensOptions.fromJson(Map<String, dynamic> json) {
+    final resolveProvider = json['resolveProvider'];
+    return new CodeLensOptions(resolveProvider);
+  }
+
+  /// Code lens has a resolve provider as well.
+  final bool resolveProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (resolveProvider != null) {
+      __result['resolveProvider'] = resolveProvider;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class CodeLensParams implements ToJsonable {
+  CodeLensParams(this.textDocument) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory CodeLensParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    return new CodeLensParams(textDocument);
+  }
+
+  /// The document to request code lens for.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']);
+  }
+}
+
+class CodeLensRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  CodeLensRegistrationOptions(this.resolveProvider, this.documentSelector);
+  factory CodeLensRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final resolveProvider = json['resolveProvider'];
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new CodeLensRegistrationOptions(resolveProvider, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the registration. If set to
+  /// null the document selector provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// Code lens has a resolve provider as well.
+  final bool resolveProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (resolveProvider != null) {
+      __result['resolveProvider'] = resolveProvider;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// Represents a color in RGBA space.
+class Color implements ToJsonable {
+  Color(this.red, this.green, this.blue, this.alpha) {
+    if (red == null) {
+      throw 'red is required but was not provided';
+    }
+    if (green == null) {
+      throw 'green is required but was not provided';
+    }
+    if (blue == null) {
+      throw 'blue is required but was not provided';
+    }
+    if (alpha == null) {
+      throw 'alpha is required but was not provided';
+    }
+  }
+  factory Color.fromJson(Map<String, dynamic> json) {
+    final red = json['red'];
+    final green = json['green'];
+    final blue = json['blue'];
+    final alpha = json['alpha'];
+    return new Color(red, green, blue, alpha);
+  }
+
+  final num alpha;
+  final num blue;
+  final num green;
+  final num red;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['red'] = red ?? (throw 'red is required but was not set');
+    __result['green'] = green ?? (throw 'green is required but was not set');
+    __result['blue'] = blue ?? (throw 'blue is required but was not set');
+    __result['alpha'] = alpha ?? (throw 'alpha is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('red') &&
+        obj['red'] is num &&
+        obj.containsKey('green') &&
+        obj['green'] is num &&
+        obj.containsKey('blue') &&
+        obj['blue'] is num &&
+        obj.containsKey('alpha') &&
+        obj['alpha'] is num;
+  }
+}
+
+class ColorInformation implements ToJsonable {
+  ColorInformation(this.range, this.color) {
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (color == null) {
+      throw 'color is required but was not provided';
+    }
+  }
+  factory ColorInformation.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final color =
+        json['color'] != null ? new Color.fromJson(json['color']) : null;
+    return new ColorInformation(range, color);
+  }
+
+  /// The actual color value for this color range.
+  final Color color;
+
+  /// The range in the document where this color appears.
+  final Range range;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    __result['color'] = color ?? (throw 'color is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']) &&
+        obj.containsKey('color') &&
+        Color.canParse(obj['color']);
+  }
+}
+
+class ColorPresentation implements ToJsonable {
+  ColorPresentation(this.label, this.textEdit, this.additionalTextEdits) {
+    if (label == null) {
+      throw 'label is required but was not provided';
+    }
+  }
+  factory ColorPresentation.fromJson(Map<String, dynamic> json) {
+    final label = json['label'];
+    final textEdit = json['textEdit'] != null
+        ? new TextEdit.fromJson(json['textEdit'])
+        : null;
+    final additionalTextEdits = json['additionalTextEdits']
+        ?.map((item) => item != null ? new TextEdit.fromJson(item) : null)
+        ?.cast<TextEdit>()
+        ?.toList();
+    return new ColorPresentation(label, textEdit, additionalTextEdits);
+  }
+
+  /// An optional array of additional text edits ([TextEdit]) that are applied
+  /// when selecting this color presentation. Edits must not overlap with the
+  /// main [edit](#ColorPresentation.textEdit) nor with themselves.
+  final List<TextEdit> additionalTextEdits;
+
+  /// The label of this color presentation. It will be shown on the color picker
+  /// header. By default this is also the text that is inserted when selecting
+  /// this color presentation.
+  final String label;
+
+  /// An edit ([TextEdit]) which is applied to a document when selecting this
+  /// presentation for the color.  When `falsy` the
+  /// [label](#ColorPresentation.label) is used.
+  final TextEdit textEdit;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['label'] = label ?? (throw 'label is required but was not set');
+    if (textEdit != null) {
+      __result['textEdit'] = textEdit;
+    }
+    if (additionalTextEdits != null) {
+      __result['additionalTextEdits'] = additionalTextEdits;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('label') &&
+        obj['label'] is String;
+  }
+}
+
+class ColorPresentationParams implements ToJsonable {
+  ColorPresentationParams(this.textDocument, this.color, this.range) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (color == null) {
+      throw 'color is required but was not provided';
+    }
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+  }
+  factory ColorPresentationParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final color =
+        json['color'] != null ? new Color.fromJson(json['color']) : null;
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    return new ColorPresentationParams(textDocument, color, range);
+  }
+
+  /// The color information to request presentations for.
+  final Color color;
+
+  /// The range where the color would be inserted. Serves as a context.
+  final Range range;
+
+  /// The text document.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['color'] = color ?? (throw 'color is required but was not set');
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('color') &&
+        Color.canParse(obj['color']) &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']);
+  }
+}
+
+/// Color provider options.
+class ColorProviderOptions implements ToJsonable {
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class Command implements ToJsonable {
+  Command(this.title, this.command, this.arguments) {
+    if (title == null) {
+      throw 'title is required but was not provided';
+    }
+    if (command == null) {
+      throw 'command is required but was not provided';
+    }
+  }
+  factory Command.fromJson(Map<String, dynamic> json) {
+    final title = json['title'];
+    final command = json['command'];
+    final arguments =
+        json['arguments']?.map((item) => item)?.cast<dynamic>()?.toList();
+    return new Command(title, command, arguments);
+  }
+
+  /// Arguments that the command handler should be invoked with.
+  final List<dynamic> arguments;
+
+  /// The identifier of the actual command handler.
+  final String command;
+
+  /// Title of the command, like `save`.
+  final String title;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['title'] = title ?? (throw 'title is required but was not set');
+    __result['command'] =
+        command ?? (throw 'command is required but was not set');
+    if (arguments != null) {
+      __result['arguments'] = arguments;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('title') &&
+        obj['title'] is String &&
+        obj.containsKey('command') &&
+        obj['command'] is String;
+  }
+}
+
+/// Contains additional information about the context in which a completion
+/// request is triggered.
+class CompletionContext implements ToJsonable {
+  CompletionContext(this.triggerKind, this.triggerCharacter) {
+    if (triggerKind == null) {
+      throw 'triggerKind is required but was not provided';
+    }
+  }
+  factory CompletionContext.fromJson(Map<String, dynamic> json) {
+    final triggerKind = json['triggerKind'] != null
+        ? new CompletionTriggerKind.fromJson(json['triggerKind'])
+        : null;
+    final triggerCharacter = json['triggerCharacter'];
+    return new CompletionContext(triggerKind, triggerCharacter);
+  }
+
+  /// The trigger character (a single character) that has trigger code complete.
+  /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
+  final String triggerCharacter;
+
+  /// How the completion was triggered.
+  final CompletionTriggerKind triggerKind;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['triggerKind'] =
+        triggerKind ?? (throw 'triggerKind is required but was not set');
+    if (triggerCharacter != null) {
+      __result['triggerCharacter'] = triggerCharacter;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('triggerKind') &&
+        CompletionTriggerKind.canParse(obj['triggerKind']);
+  }
+}
+
+class CompletionItem implements ToJsonable {
+  CompletionItem(
+      this.label,
+      this.kind,
+      this.detail,
+      this.documentation,
+      this.deprecated,
+      this.preselect,
+      this.sortText,
+      this.filterText,
+      this.insertText,
+      this.insertTextFormat,
+      this.textEdit,
+      this.additionalTextEdits,
+      this.commitCharacters,
+      this.command,
+      this.data) {
+    if (label == null) {
+      throw 'label is required but was not provided';
+    }
+  }
+  factory CompletionItem.fromJson(Map<String, dynamic> json) {
+    final label = json['label'];
+    final kind = json['kind'] != null
+        ? new CompletionItemKind.fromJson(json['kind'])
+        : null;
+    final detail = json['detail'];
+    final documentation = json['documentation'] is String
+        ? new Either2<String, MarkupContent>.t1(json['documentation'])
+        : (MarkupContent.canParse(json['documentation'])
+            ? new Either2<String, MarkupContent>.t2(
+                json['documentation'] != null
+                    ? new MarkupContent.fromJson(json['documentation'])
+                    : null)
+            : (throw '''${json['documentation']} was not one of (string, MarkupContent)'''));
+    final deprecated = json['deprecated'];
+    final preselect = json['preselect'];
+    final sortText = json['sortText'];
+    final filterText = json['filterText'];
+    final insertText = json['insertText'];
+    final insertTextFormat = json['insertTextFormat'] != null
+        ? new InsertTextFormat.fromJson(json['insertTextFormat'])
+        : null;
+    final textEdit = json['textEdit'] != null
+        ? new TextEdit.fromJson(json['textEdit'])
+        : null;
+    final additionalTextEdits = json['additionalTextEdits']
+        ?.map((item) => item != null ? new TextEdit.fromJson(item) : null)
+        ?.cast<TextEdit>()
+        ?.toList();
+    final commitCharacters =
+        json['commitCharacters']?.map((item) => item)?.cast<String>()?.toList();
+    final command =
+        json['command'] != null ? new Command.fromJson(json['command']) : null;
+    final data = json['data'];
+    return new CompletionItem(
+        label,
+        kind,
+        detail,
+        documentation,
+        deprecated,
+        preselect,
+        sortText,
+        filterText,
+        insertText,
+        insertTextFormat,
+        textEdit,
+        additionalTextEdits,
+        commitCharacters,
+        command,
+        data);
+  }
+
+  /// An optional array of additional text edits that are applied when selecting
+  /// this completion. Edits must not overlap (including the same insert
+  /// position) with the main edit nor with themselves.
+  ///
+  /// Additional text edits should be used to change text unrelated to the
+  /// current cursor position (for example adding an import statement at the top
+  /// of the file if the completion item will insert an unqualified type).
+  final List<TextEdit> additionalTextEdits;
+
+  /// An optional command that is executed *after* inserting this completion.
+  /// *Note* that additional modifications to the current document should be
+  /// described with the additionalTextEdits-property.
+  final Command command;
+
+  /// An optional set of characters that when pressed while this completion is
+  /// active will accept it first and then type that character. *Note* that all
+  /// commit characters should have `length=1` and that superfluous characters
+  /// will be ignored.
+  final List<String> commitCharacters;
+
+  /// An data entry field that is preserved on a completion item between a
+  /// completion and a completion resolve request.
+  final dynamic data;
+
+  /// Indicates if this item is deprecated.
+  final bool deprecated;
+
+  /// A human-readable string with additional information about this item, like
+  /// type or symbol information.
+  final String detail;
+
+  /// A human-readable string that represents a doc-comment.
+  final Either2<String, MarkupContent> documentation;
+
+  /// A string that should be used when filtering a set of completion items.
+  /// When `falsy` the label is used.
+  final String filterText;
+
+  /// A string that should be inserted into a document when selecting this
+  /// completion. When `falsy` the label is used.
+  ///
+  /// The `insertText` is subject to interpretation by the client side. Some
+  /// tools might not take the string literally. For example VS Code when code
+  /// complete is requested in this example `con<cursor position>` and a
+  /// completion item with an `insertText` of `console` is provided it will only
+  /// insert `sole`. Therefore it is recommended to use `textEdit` instead since
+  /// it avoids additional client side interpretation.
+  ///  @deprecated Use textEdit instead.
+  @core.deprecated
+  final String insertText;
+
+  /// The format of the insert text. The format applies to both the `insertText`
+  /// property and the `newText` property of a provided `textEdit`.
+  final InsertTextFormat insertTextFormat;
+
+  /// The kind of this completion item. Based of the kind an icon is chosen by
+  /// the editor.
+  final CompletionItemKind kind;
+
+  /// The label of this completion item. By default also the text that is
+  /// inserted when selecting this completion.
+  final String label;
+
+  /// Select this item when showing.
+  ///
+  /// *Note* that only one completion item can be selected and that the tool /
+  /// client decides which item that is. The rule is that the *first* item of
+  /// those that match best is selected.
+  final bool preselect;
+
+  /// A string that should be used when comparing this item with other items.
+  /// When `falsy` the label is used.
+  final String sortText;
+
+  /// An edit which is applied to a document when selecting this completion.
+  /// When an edit is provided the value of `insertText` is ignored.
+  ///
+  /// *Note:* The range of the edit must be a single line range and it must
+  /// contain the position at which completion has been requested.
+  final TextEdit textEdit;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['label'] = label ?? (throw 'label is required but was not set');
+    if (kind != null) {
+      __result['kind'] = kind;
+    }
+    if (detail != null) {
+      __result['detail'] = detail;
+    }
+    if (documentation != null) {
+      __result['documentation'] = documentation;
+    }
+    if (deprecated != null) {
+      __result['deprecated'] = deprecated;
+    }
+    if (preselect != null) {
+      __result['preselect'] = preselect;
+    }
+    if (sortText != null) {
+      __result['sortText'] = sortText;
+    }
+    if (filterText != null) {
+      __result['filterText'] = filterText;
+    }
+    // ignore: deprecated_member_use
+    if (insertText != null) {
+      // ignore: deprecated_member_use
+      __result['insertText'] = insertText;
+    }
+    if (insertTextFormat != null) {
+      __result['insertTextFormat'] = insertTextFormat;
+    }
+    if (textEdit != null) {
+      __result['textEdit'] = textEdit;
+    }
+    if (additionalTextEdits != null) {
+      __result['additionalTextEdits'] = additionalTextEdits;
+    }
+    if (commitCharacters != null) {
+      __result['commitCharacters'] = commitCharacters;
+    }
+    if (command != null) {
+      __result['command'] = command;
+    }
+    if (data != null) {
+      __result['data'] = data;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('label') &&
+        obj['label'] is String;
+  }
+}
+
+/// The kind of a completion entry.
+class CompletionItemKind {
+  const CompletionItemKind._(this._value);
+  const CompletionItemKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+      case 9:
+      case 10:
+      case 11:
+      case 12:
+      case 13:
+      case 14:
+      case 15:
+      case 16:
+      case 17:
+      case 18:
+      case 19:
+      case 20:
+      case 21:
+      case 22:
+      case 23:
+      case 24:
+      case 25:
+        return true;
+    }
+    return false;
+  }
+
+  static const Text = const CompletionItemKind._(1);
+  static const Method = const CompletionItemKind._(2);
+  static const Function = const CompletionItemKind._(3);
+  static const Constructor = const CompletionItemKind._(4);
+  static const Field = const CompletionItemKind._(5);
+  static const Variable = const CompletionItemKind._(6);
+  static const Class = const CompletionItemKind._(7);
+  static const Interface = const CompletionItemKind._(8);
+  static const Module = const CompletionItemKind._(9);
+  static const Property = const CompletionItemKind._(10);
+  static const Unit = const CompletionItemKind._(11);
+  static const Value = const CompletionItemKind._(12);
+  static const Enum = const CompletionItemKind._(13);
+  static const Keyword = const CompletionItemKind._(14);
+  static const Snippet = const CompletionItemKind._(15);
+  static const Color = const CompletionItemKind._(16);
+  static const File = const CompletionItemKind._(17);
+  static const Reference = const CompletionItemKind._(18);
+  static const Folder = const CompletionItemKind._(19);
+  static const EnumMember = const CompletionItemKind._(20);
+  static const Constant = const CompletionItemKind._(21);
+  static const Struct = const CompletionItemKind._(22);
+  static const Event = const CompletionItemKind._(23);
+  static const Operator = const CompletionItemKind._(24);
+  static const TypeParameter = const CompletionItemKind._(25);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is CompletionItemKind && o._value == _value;
+}
+
+/// Represents a collection of completion items ([CompletionItem]) to be
+/// presented in the editor.
+class CompletionList implements ToJsonable {
+  CompletionList(this.isIncomplete, this.items) {
+    if (isIncomplete == null) {
+      throw 'isIncomplete is required but was not provided';
+    }
+    if (items == null) {
+      throw 'items is required but was not provided';
+    }
+  }
+  factory CompletionList.fromJson(Map<String, dynamic> json) {
+    final isIncomplete = json['isIncomplete'];
+    final items = json['items']
+        ?.map((item) => item != null ? new CompletionItem.fromJson(item) : null)
+        ?.cast<CompletionItem>()
+        ?.toList();
+    return new CompletionList(isIncomplete, items);
+  }
+
+  /// This list it not complete. Further typing should result in recomputing
+  /// this list.
+  final bool isIncomplete;
+
+  /// The completion items.
+  final List<CompletionItem> items;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['isIncomplete'] =
+        isIncomplete ?? (throw 'isIncomplete is required but was not set');
+    __result['items'] = items ?? (throw 'items is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('isIncomplete') &&
+        obj['isIncomplete'] is bool &&
+        obj.containsKey('items') &&
+        (obj['items'] is List &&
+            (obj['items'].length == 0 ||
+                obj['items'].every((item) => CompletionItem.canParse(item))));
+  }
+}
+
+/// Completion options.
+class CompletionOptions implements ToJsonable {
+  CompletionOptions(this.resolveProvider, this.triggerCharacters);
+  factory CompletionOptions.fromJson(Map<String, dynamic> json) {
+    final resolveProvider = json['resolveProvider'];
+    final triggerCharacters = json['triggerCharacters']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
+    return new CompletionOptions(resolveProvider, triggerCharacters);
+  }
+
+  /// The server provides support to resolve additional information for a
+  /// completion item.
+  final bool resolveProvider;
+
+  /// The characters that trigger completion automatically.
+  final List<String> triggerCharacters;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (resolveProvider != null) {
+      __result['resolveProvider'] = resolveProvider;
+    }
+    if (triggerCharacters != null) {
+      __result['triggerCharacters'] = triggerCharacters;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class CompletionParams implements TextDocumentPositionParams, ToJsonable {
+  CompletionParams(this.context, this.textDocument, this.position) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (position == null) {
+      throw 'position is required but was not provided';
+    }
+  }
+  factory CompletionParams.fromJson(Map<String, dynamic> json) {
+    final context = json['context'] != null
+        ? new CompletionContext.fromJson(json['context'])
+        : null;
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final position = json['position'] != null
+        ? new Position.fromJson(json['position'])
+        : null;
+    return new CompletionParams(context, textDocument, position);
+  }
+
+  /// The completion context. This is only available if the client specifies
+  /// to send this using
+  /// `ClientCapabilities.textDocument.completion.contextSupport === true`
+  final CompletionContext context;
+
+  /// The position inside the text document.
+  final Position position;
+
+  /// The text document.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (context != null) {
+      __result['context'] = context;
+    }
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['position'] =
+        position ?? (throw 'position is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('position') &&
+        Position.canParse(obj['position']);
+  }
+}
+
+class CompletionRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  CompletionRegistrationOptions(
+      this.triggerCharacters, this.resolveProvider, this.documentSelector);
+  factory CompletionRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final triggerCharacters = json['triggerCharacters']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
+    final resolveProvider = json['resolveProvider'];
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new CompletionRegistrationOptions(
+        triggerCharacters, resolveProvider, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the registration. If set to
+  /// null the document selector provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// The server provides support to resolve additional information for a
+  /// completion item.
+  final bool resolveProvider;
+
+  /// Most tools trigger completion request automatically without explicitly
+  /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically
+  /// they do so when the user starts to type an identifier. For example if
+  /// the user types `c` in a JavaScript file code complete will automatically
+  /// pop up present `console` besides others as a completion item. Characters
+  /// that make up identifiers don't need to be listed here.
+  ///
+  /// If code complete should automatically be trigger on characters not being
+  /// valid inside an identifier (for example `.` in JavaScript) list them in
+  /// `triggerCharacters`.
+  final List<String> triggerCharacters;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (triggerCharacters != null) {
+      __result['triggerCharacters'] = triggerCharacters;
+    }
+    if (resolveProvider != null) {
+      __result['resolveProvider'] = resolveProvider;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// How a completion was triggered
+class CompletionTriggerKind {
+  const CompletionTriggerKind._(this._value);
+  const CompletionTriggerKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+        return true;
+    }
+    return false;
+  }
+
+  /// Completion was triggered by typing an identifier (24x7 code complete),
+  /// manual invocation (e.g Ctrl+Space) or via API.
+  static const Invoked = const CompletionTriggerKind._(1);
+
+  /// Completion was triggered by a trigger character specified by the
+  /// `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+  static const TriggerCharacter = const CompletionTriggerKind._(2);
+
+  /// Completion was re-triggered as the current completion list is
+  /// incomplete.
+  static const TriggerForIncompleteCompletions =
+      const CompletionTriggerKind._(3);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is CompletionTriggerKind && o._value == _value;
+}
+
+class ConfigurationItem implements ToJsonable {
+  ConfigurationItem(this.scopeUri, this.section);
+  factory ConfigurationItem.fromJson(Map<String, dynamic> json) {
+    final scopeUri = json['scopeUri'];
+    final section = json['section'];
+    return new ConfigurationItem(scopeUri, section);
+  }
+
+  /// The scope to get the configuration section for.
+  final String scopeUri;
+
+  /// The configuration section asked for.
+  final String section;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (scopeUri != null) {
+      __result['scopeUri'] = scopeUri;
+    }
+    if (section != null) {
+      __result['section'] = section;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class ConfigurationParams implements ToJsonable {
+  ConfigurationParams(this.items) {
+    if (items == null) {
+      throw 'items is required but was not provided';
+    }
+  }
+  factory ConfigurationParams.fromJson(Map<String, dynamic> json) {
+    final items = json['items']
+        ?.map((item) =>
+            item != null ? new ConfigurationItem.fromJson(item) : null)
+        ?.cast<ConfigurationItem>()
+        ?.toList();
+    return new ConfigurationParams(items);
+  }
+
+  final List<ConfigurationItem> items;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['items'] = items ?? (throw 'items is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('items') &&
+        (obj['items'] is List &&
+            (obj['items'].length == 0 ||
+                obj['items']
+                    .every((item) => ConfigurationItem.canParse(item))));
+  }
+}
+
+/// Create file operation
+class CreateFile implements FileOperation, ToJsonable {
+  CreateFile(this.uri, this.options) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+  }
+  factory CreateFile.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final options = json['options'] != null
+        ? new CreateFileOptions.fromJson(json['options'])
+        : null;
+    return new CreateFile(uri, options);
+  }
+
+  /// Additional options
+  final CreateFileOptions options;
+
+  /// The resource to create.
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    if (options != null) {
+      __result['options'] = options;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String;
+  }
+}
+
+/// Options to create a file.
+class CreateFileOptions implements ToJsonable {
+  CreateFileOptions(this.overwrite, this.ignoreIfExists);
+  factory CreateFileOptions.fromJson(Map<String, dynamic> json) {
+    final overwrite = json['overwrite'];
+    final ignoreIfExists = json['ignoreIfExists'];
+    return new CreateFileOptions(overwrite, ignoreIfExists);
+  }
+
+  /// Ignore if exists.
+  final bool ignoreIfExists;
+
+  /// Overwrite existing file. Overwrite wins over `ignoreIfExists`
+  final bool overwrite;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (overwrite != null) {
+      __result['overwrite'] = overwrite;
+    }
+    if (ignoreIfExists != null) {
+      __result['ignoreIfExists'] = ignoreIfExists;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// Delete file operation
+class DeleteFile implements FileOperation, ToJsonable {
+  DeleteFile(this.uri, this.options) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+  }
+  factory DeleteFile.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final options = json['options'] != null
+        ? new DeleteFileOptions.fromJson(json['options'])
+        : null;
+    return new DeleteFile(uri, options);
+  }
+
+  /// Delete options.
+  final DeleteFileOptions options;
+
+  /// The file to delete.
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    if (options != null) {
+      __result['options'] = options;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String;
+  }
+}
+
+/// Delete file options
+class DeleteFileOptions implements ToJsonable {
+  DeleteFileOptions(this.recursive, this.ignoreIfNotExists);
+  factory DeleteFileOptions.fromJson(Map<String, dynamic> json) {
+    final recursive = json['recursive'];
+    final ignoreIfNotExists = json['ignoreIfNotExists'];
+    return new DeleteFileOptions(recursive, ignoreIfNotExists);
+  }
+
+  /// Ignore the operation if the file doesn't exist.
+  final bool ignoreIfNotExists;
+
+  /// Delete the content recursively if a folder is denoted.
+  final bool recursive;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (recursive != null) {
+      __result['recursive'] = recursive;
+    }
+    if (ignoreIfNotExists != null) {
+      __result['ignoreIfNotExists'] = ignoreIfNotExists;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class Diagnostic implements ToJsonable {
+  Diagnostic(this.range, this.severity, this.code, this.source, this.message,
+      this.relatedInformation) {
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (message == null) {
+      throw 'message is required but was not provided';
+    }
+  }
+  factory Diagnostic.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final severity = json['severity'] != null
+        ? new DiagnosticSeverity.fromJson(json['severity'])
+        : null;
+    final code = json['code'] is num
+        ? new Either2<num, String>.t1(json['code'])
+        : (json['code'] is String
+            ? new Either2<num, String>.t2(json['code'])
+            : (throw '''${json['code']} was not one of (number, string)'''));
+    final source = json['source'];
+    final message = json['message'];
+    final relatedInformation = json['relatedInformation']
+        ?.map((item) => item != null
+            ? new DiagnosticRelatedInformation.fromJson(item)
+            : null)
+        ?.cast<DiagnosticRelatedInformation>()
+        ?.toList();
+    return new Diagnostic(
+        range, severity, code, source, message, relatedInformation);
+  }
+
+  /// The diagnostic's code, which might appear in the user interface.
+  final Either2<num, String> code;
+
+  /// The diagnostic's message.
+  final String message;
+
+  /// The range at which the message applies.
+  final Range range;
+
+  /// An array of related diagnostic information, e.g. when symbol-names
+  /// within a scope collide all definitions can be marked via this
+  /// property.
+  final List<DiagnosticRelatedInformation> relatedInformation;
+
+  /// The diagnostic's severity. Can be omitted. If omitted it is up to the
+  /// client to interpret diagnostics as error, warning, info or hint.
+  final DiagnosticSeverity severity;
+
+  /// A human-readable string describing the source of this diagnostic, e.g.
+  /// 'typescript' or 'super lint'.
+  final String source;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    if (severity != null) {
+      __result['severity'] = severity;
+    }
+    if (code != null) {
+      __result['code'] = code;
+    }
+    if (source != null) {
+      __result['source'] = source;
+    }
+    __result['message'] =
+        message ?? (throw 'message is required but was not set');
+    if (relatedInformation != null) {
+      __result['relatedInformation'] = relatedInformation;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']) &&
+        obj.containsKey('message') &&
+        obj['message'] is String;
+  }
+}
+
+/// Represents a related message and source code location for a diagnostic.
+/// This should be used to point to code locations that cause or related to
+/// a diagnostics, e.g when duplicating a symbol in a scope.
+class DiagnosticRelatedInformation implements ToJsonable {
+  DiagnosticRelatedInformation(this.location, this.message) {
+    if (location == null) {
+      throw 'location is required but was not provided';
+    }
+    if (message == null) {
+      throw 'message is required but was not provided';
+    }
+  }
+  factory DiagnosticRelatedInformation.fromJson(Map<String, dynamic> json) {
+    final location = json['location'] != null
+        ? new Location.fromJson(json['location'])
+        : null;
+    final message = json['message'];
+    return new DiagnosticRelatedInformation(location, message);
+  }
+
+  /// The location of this related diagnostic information.
+  final Location location;
+
+  /// The message of this related diagnostic information.
+  final String message;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['location'] =
+        location ?? (throw 'location is required but was not set');
+    __result['message'] =
+        message ?? (throw 'message is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('location') &&
+        Location.canParse(obj['location']) &&
+        obj.containsKey('message') &&
+        obj['message'] is String;
+  }
+}
+
+class DiagnosticSeverity {
+  const DiagnosticSeverity._(this._value);
+  const DiagnosticSeverity.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+        return true;
+    }
+    return false;
+  }
+
+  /// Reports an error.
+  static const Error = const DiagnosticSeverity._(1);
+
+  /// Reports a warning.
+  static const Warning = const DiagnosticSeverity._(2);
+
+  /// Reports an information.
+  static const Information = const DiagnosticSeverity._(3);
+
+  /// Reports a hint.
+  static const Hint = const DiagnosticSeverity._(4);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is DiagnosticSeverity && o._value == _value;
+}
+
+class DidChangeConfigurationParams implements ToJsonable {
+  DidChangeConfigurationParams(this.settings) {
+    if (settings == null) {
+      throw 'settings is required but was not provided';
+    }
+  }
+  factory DidChangeConfigurationParams.fromJson(Map<String, dynamic> json) {
+    final settings = json['settings'];
+    return new DidChangeConfigurationParams(settings);
+  }
+
+  /// The actual changed settings
+  final dynamic settings;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['settings'] =
+        settings ?? (throw 'settings is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> && obj.containsKey('settings') && true;
+  }
+}
+
+class DidChangeTextDocumentParams implements ToJsonable {
+  DidChangeTextDocumentParams(this.textDocument, this.contentChanges) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (contentChanges == null) {
+      throw 'contentChanges is required but was not provided';
+    }
+  }
+  factory DidChangeTextDocumentParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new VersionedTextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final contentChanges = json['contentChanges']
+        ?.map((item) => item != null
+            ? new TextDocumentContentChangeEvent.fromJson(item)
+            : null)
+        ?.cast<TextDocumentContentChangeEvent>()
+        ?.toList();
+    return new DidChangeTextDocumentParams(textDocument, contentChanges);
+  }
+
+  /// The actual content changes. The content changes describe single
+  /// state changes to the document. So if there are two content changes
+  /// c1 and c2 for a document in state S then c1 move the document to S'
+  /// and c2 to S''.
+  final List<TextDocumentContentChangeEvent> contentChanges;
+
+  /// The document that did change. The version number points to the
+  /// version after all provided content changes have been applied.
+  final VersionedTextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['contentChanges'] =
+        contentChanges ?? (throw 'contentChanges is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        VersionedTextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('contentChanges') &&
+        (obj['contentChanges'] is List &&
+            (obj['contentChanges'].length == 0 ||
+                obj['contentChanges'].every(
+                    (item) => TextDocumentContentChangeEvent.canParse(item))));
+  }
+}
+
+class DidChangeWatchedFilesParams implements ToJsonable {
+  DidChangeWatchedFilesParams(this.changes) {
+    if (changes == null) {
+      throw 'changes is required but was not provided';
+    }
+  }
+  factory DidChangeWatchedFilesParams.fromJson(Map<String, dynamic> json) {
+    final changes = json['changes']
+        ?.map((item) => item != null ? new FileEvent.fromJson(item) : null)
+        ?.cast<FileEvent>()
+        ?.toList();
+    return new DidChangeWatchedFilesParams(changes);
+  }
+
+  /// The actual file events.
+  final List<FileEvent> changes;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['changes'] =
+        changes ?? (throw 'changes is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('changes') &&
+        (obj['changes'] is List &&
+            (obj['changes'].length == 0 ||
+                obj['changes'].every((item) => FileEvent.canParse(item))));
+  }
+}
+
+/// Describe options to be used when registering for text document change
+/// events.
+class DidChangeWatchedFilesRegistrationOptions implements ToJsonable {
+  DidChangeWatchedFilesRegistrationOptions(this.watchers) {
+    if (watchers == null) {
+      throw 'watchers is required but was not provided';
+    }
+  }
+  factory DidChangeWatchedFilesRegistrationOptions.fromJson(
+      Map<String, dynamic> json) {
+    final watchers = json['watchers']
+        ?.map((item) =>
+            item != null ? new FileSystemWatcher.fromJson(item) : null)
+        ?.cast<FileSystemWatcher>()
+        ?.toList();
+    return new DidChangeWatchedFilesRegistrationOptions(watchers);
+  }
+
+  /// The watchers to register.
+  final List<FileSystemWatcher> watchers;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['watchers'] =
+        watchers ?? (throw 'watchers is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('watchers') &&
+        (obj['watchers'] is List &&
+            (obj['watchers'].length == 0 ||
+                obj['watchers']
+                    .every((item) => FileSystemWatcher.canParse(item))));
+  }
+}
+
+class DidChangeWorkspaceFoldersParams implements ToJsonable {
+  DidChangeWorkspaceFoldersParams(this.event) {
+    if (event == null) {
+      throw 'event is required but was not provided';
+    }
+  }
+  factory DidChangeWorkspaceFoldersParams.fromJson(Map<String, dynamic> json) {
+    final event = json['event'] != null
+        ? new WorkspaceFoldersChangeEvent.fromJson(json['event'])
+        : null;
+    return new DidChangeWorkspaceFoldersParams(event);
+  }
+
+  /// The actual workspace folder change event.
+  final WorkspaceFoldersChangeEvent event;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['event'] = event ?? (throw 'event is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('event') &&
+        WorkspaceFoldersChangeEvent.canParse(obj['event']);
+  }
+}
+
+class DidCloseTextDocumentParams implements ToJsonable {
+  DidCloseTextDocumentParams(this.textDocument) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory DidCloseTextDocumentParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    return new DidCloseTextDocumentParams(textDocument);
+  }
+
+  /// The document that was closed.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']);
+  }
+}
+
+class DidOpenTextDocumentParams implements ToJsonable {
+  DidOpenTextDocumentParams(this.textDocument) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory DidOpenTextDocumentParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentItem.fromJson(json['textDocument'])
+        : null;
+    return new DidOpenTextDocumentParams(textDocument);
+  }
+
+  /// The document that was opened.
+  final TextDocumentItem textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentItem.canParse(obj['textDocument']);
+  }
+}
+
+class DidSaveTextDocumentParams implements ToJsonable {
+  DidSaveTextDocumentParams(this.textDocument, this.text) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory DidSaveTextDocumentParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final text = json['text'];
+    return new DidSaveTextDocumentParams(textDocument, text);
+  }
+
+  /// Optional the content when saved. Depends on the includeText value
+  /// when the save notification was requested.
+  final String text;
+
+  /// The document that was saved.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    if (text != null) {
+      __result['text'] = text;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']);
+  }
+}
+
+class DocumentFilter implements ToJsonable {
+  DocumentFilter(this.language, this.scheme, this.pattern);
+  factory DocumentFilter.fromJson(Map<String, dynamic> json) {
+    final language = json['language'];
+    final scheme = json['scheme'];
+    final pattern = json['pattern'];
+    return new DocumentFilter(language, scheme, pattern);
+  }
+
+  /// A language id, like `typescript`.
+  final String language;
+
+  /// A glob pattern, like `*.{ts,js}`.
+  final String pattern;
+
+  /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+  final String scheme;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (language != null) {
+      __result['language'] = language;
+    }
+    if (scheme != null) {
+      __result['scheme'] = scheme;
+    }
+    if (pattern != null) {
+      __result['pattern'] = pattern;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class DocumentFormattingParams implements ToJsonable {
+  DocumentFormattingParams(this.textDocument, this.options) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (options == null) {
+      throw 'options is required but was not provided';
+    }
+  }
+  factory DocumentFormattingParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final options = json['options'] != null
+        ? new FormattingOptions.fromJson(json['options'])
+        : null;
+    return new DocumentFormattingParams(textDocument, options);
+  }
+
+  /// The format options.
+  final FormattingOptions options;
+
+  /// The document to format.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['options'] =
+        options ?? (throw 'options is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('options') &&
+        FormattingOptions.canParse(obj['options']);
+  }
+}
+
+/// A document highlight is a range inside a text document which deserves
+/// special attention. Usually a document highlight is visualized by
+/// changing the background color of its range.
+class DocumentHighlight implements ToJsonable {
+  DocumentHighlight(this.range, this.kind) {
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+  }
+  factory DocumentHighlight.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final kind = json['kind'] != null
+        ? new DocumentHighlightKind.fromJson(json['kind'])
+        : null;
+    return new DocumentHighlight(range, kind);
+  }
+
+  /// The highlight kind, default is DocumentHighlightKind.Text.
+  final DocumentHighlightKind kind;
+
+  /// The range this highlight applies to.
+  final Range range;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    if (kind != null) {
+      __result['kind'] = kind;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']);
+  }
+}
+
+/// A document highlight kind.
+class DocumentHighlightKind {
+  const DocumentHighlightKind._(this._value);
+  const DocumentHighlightKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+        return true;
+    }
+    return false;
+  }
+
+  /// A textual occurrence.
+  static const Text = const DocumentHighlightKind._(1);
+
+  /// Read-access of a symbol, like reading a variable.
+  static const Read = const DocumentHighlightKind._(2);
+
+  /// Write-access of a symbol, like writing to a variable.
+  static const Write = const DocumentHighlightKind._(3);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is DocumentHighlightKind && o._value == _value;
+}
+
+/// A document link is a range in a text document that links to an
+/// internal or external resource, like another text document or a web
+/// site.
+class DocumentLink implements ToJsonable {
+  DocumentLink(this.range, this.target, this.data) {
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+  }
+  factory DocumentLink.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final target = json['target'];
+    final data = json['data'];
+    return new DocumentLink(range, target, data);
+  }
+
+  /// A data entry field that is preserved on a document link between a
+  /// DocumentLinkRequest and a DocumentLinkResolveRequest.
+  final dynamic data;
+
+  /// The range this link applies to.
+  final Range range;
+
+  /// The uri this link points to. If missing a resolve request is sent
+  /// later.
+  final String target;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    if (target != null) {
+      __result['target'] = target;
+    }
+    if (data != null) {
+      __result['data'] = data;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']);
+  }
+}
+
+/// Document link options.
+class DocumentLinkOptions implements ToJsonable {
+  DocumentLinkOptions(this.resolveProvider);
+  factory DocumentLinkOptions.fromJson(Map<String, dynamic> json) {
+    final resolveProvider = json['resolveProvider'];
+    return new DocumentLinkOptions(resolveProvider);
+  }
+
+  /// Document links have a resolve provider as well.
+  final bool resolveProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (resolveProvider != null) {
+      __result['resolveProvider'] = resolveProvider;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class DocumentLinkParams implements ToJsonable {
+  DocumentLinkParams(this.textDocument) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory DocumentLinkParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    return new DocumentLinkParams(textDocument);
+  }
+
+  /// The document to provide document links for.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']);
+  }
+}
+
+class DocumentLinkRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  DocumentLinkRegistrationOptions(this.resolveProvider, this.documentSelector);
+  factory DocumentLinkRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final resolveProvider = json['resolveProvider'];
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new DocumentLinkRegistrationOptions(
+        resolveProvider, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the registration. If
+  /// set to null the document selector provided on the client side will
+  /// be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// Document links have a resolve provider as well.
+  final bool resolveProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (resolveProvider != null) {
+      __result['resolveProvider'] = resolveProvider;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// Format document on type options.
+class DocumentOnTypeFormattingOptions implements ToJsonable {
+  DocumentOnTypeFormattingOptions(
+      this.firstTriggerCharacter, this.moreTriggerCharacter) {
+    if (firstTriggerCharacter == null) {
+      throw 'firstTriggerCharacter is required but was not provided';
+    }
+  }
+  factory DocumentOnTypeFormattingOptions.fromJson(Map<String, dynamic> json) {
+    final firstTriggerCharacter = json['firstTriggerCharacter'];
+    final moreTriggerCharacter = json['moreTriggerCharacter']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
+    return new DocumentOnTypeFormattingOptions(
+        firstTriggerCharacter, moreTriggerCharacter);
+  }
+
+  /// A character on which formatting should be triggered, like `}`.
+  final String firstTriggerCharacter;
+
+  /// More trigger characters.
+  final List<String> moreTriggerCharacter;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['firstTriggerCharacter'] = firstTriggerCharacter ??
+        (throw 'firstTriggerCharacter is required but was not set');
+    if (moreTriggerCharacter != null) {
+      __result['moreTriggerCharacter'] = moreTriggerCharacter;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('firstTriggerCharacter') &&
+        obj['firstTriggerCharacter'] is String;
+  }
+}
+
+class DocumentOnTypeFormattingParams implements ToJsonable {
+  DocumentOnTypeFormattingParams(
+      this.textDocument, this.position, this.ch, this.options) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (position == null) {
+      throw 'position is required but was not provided';
+    }
+    if (ch == null) {
+      throw 'ch is required but was not provided';
+    }
+    if (options == null) {
+      throw 'options is required but was not provided';
+    }
+  }
+  factory DocumentOnTypeFormattingParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final position = json['position'] != null
+        ? new Position.fromJson(json['position'])
+        : null;
+    final ch = json['ch'];
+    final options = json['options'] != null
+        ? new FormattingOptions.fromJson(json['options'])
+        : null;
+    return new DocumentOnTypeFormattingParams(
+        textDocument, position, ch, options);
+  }
+
+  /// The character that has been typed.
+  final String ch;
+
+  /// The format options.
+  final FormattingOptions options;
+
+  /// The position at which this request was sent.
+  final Position position;
+
+  /// The document to format.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['position'] =
+        position ?? (throw 'position is required but was not set');
+    __result['ch'] = ch ?? (throw 'ch is required but was not set');
+    __result['options'] =
+        options ?? (throw 'options is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('position') &&
+        Position.canParse(obj['position']) &&
+        obj.containsKey('ch') &&
+        obj['ch'] is String &&
+        obj.containsKey('options') &&
+        FormattingOptions.canParse(obj['options']);
+  }
+}
+
+class DocumentOnTypeFormattingRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  DocumentOnTypeFormattingRegistrationOptions(this.firstTriggerCharacter,
+      this.moreTriggerCharacter, this.documentSelector) {
+    if (firstTriggerCharacter == null) {
+      throw 'firstTriggerCharacter is required but was not provided';
+    }
+  }
+  factory DocumentOnTypeFormattingRegistrationOptions.fromJson(
+      Map<String, dynamic> json) {
+    final firstTriggerCharacter = json['firstTriggerCharacter'];
+    final moreTriggerCharacter = json['moreTriggerCharacter']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new DocumentOnTypeFormattingRegistrationOptions(
+        firstTriggerCharacter, moreTriggerCharacter, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the registration. If
+  /// set to null the document selector provided on the client side will
+  /// be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// A character on which formatting should be triggered, like `}`.
+  final String firstTriggerCharacter;
+
+  /// More trigger characters.
+  final List<String> moreTriggerCharacter;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['firstTriggerCharacter'] = firstTriggerCharacter ??
+        (throw 'firstTriggerCharacter is required but was not set');
+    if (moreTriggerCharacter != null) {
+      __result['moreTriggerCharacter'] = moreTriggerCharacter;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('firstTriggerCharacter') &&
+        obj['firstTriggerCharacter'] is String &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+class DocumentRangeFormattingParams implements ToJsonable {
+  DocumentRangeFormattingParams(this.textDocument, this.range, this.options) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (options == null) {
+      throw 'options is required but was not provided';
+    }
+  }
+  factory DocumentRangeFormattingParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final options = json['options'] != null
+        ? new FormattingOptions.fromJson(json['options'])
+        : null;
+    return new DocumentRangeFormattingParams(textDocument, range, options);
+  }
+
+  /// The format options
+  final FormattingOptions options;
+
+  /// The range to format
+  final Range range;
+
+  /// The document to format.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    __result['options'] =
+        options ?? (throw 'options is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']) &&
+        obj.containsKey('options') &&
+        FormattingOptions.canParse(obj['options']);
+  }
+}
+
+/// Represents programming constructs like variables, classes,
+/// interfaces etc. that appear in a document. Document symbols can be
+/// hierarchical and they have two ranges: one that encloses its
+/// definition and one that points to its most interesting range, e.g.
+/// the range of an identifier.
+class DocumentSymbol implements ToJsonable {
+  DocumentSymbol(this.name, this.detail, this.kind, this.deprecated, this.range,
+      this.selectionRange, this.children) {
+    if (name == null) {
+      throw 'name is required but was not provided';
+    }
+    if (kind == null) {
+      throw 'kind is required but was not provided';
+    }
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (selectionRange == null) {
+      throw 'selectionRange is required but was not provided';
+    }
+  }
+  factory DocumentSymbol.fromJson(Map<String, dynamic> json) {
+    final name = json['name'];
+    final detail = json['detail'];
+    final kind =
+        json['kind'] != null ? new SymbolKind.fromJson(json['kind']) : null;
+    final deprecated = json['deprecated'];
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final selectionRange = json['selectionRange'] != null
+        ? new Range.fromJson(json['selectionRange'])
+        : null;
+    final children = json['children']
+        ?.map((item) => item != null ? new DocumentSymbol.fromJson(item) : null)
+        ?.cast<DocumentSymbol>()
+        ?.toList();
+    return new DocumentSymbol(
+        name, detail, kind, deprecated, range, selectionRange, children);
+  }
+
+  /// Children of this symbol, e.g. properties of a class.
+  final List<DocumentSymbol> children;
+
+  /// Indicates if this symbol is deprecated.
+  final bool deprecated;
+
+  /// More detail for this symbol, e.g the signature of a function.
+  final String detail;
+
+  /// The kind of this symbol.
+  final SymbolKind kind;
+
+  /// The name of this symbol.
+  final String name;
+
+  /// The range enclosing this symbol not including leading/trailing
+  /// whitespace but everything else like comments. This information is
+  /// typically used to determine if the clients cursor is inside the
+  /// symbol to reveal in the symbol in the UI.
+  final Range range;
+
+  /// The range that should be selected and revealed when this symbol is
+  /// being picked, e.g the name of a function. Must be contained by the
+  /// `range`.
+  final Range selectionRange;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['name'] = name ?? (throw 'name is required but was not set');
+    if (detail != null) {
+      __result['detail'] = detail;
+    }
+    __result['kind'] = kind ?? (throw 'kind is required but was not set');
+    if (deprecated != null) {
+      __result['deprecated'] = deprecated;
+    }
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    __result['selectionRange'] =
+        selectionRange ?? (throw 'selectionRange is required but was not set');
+    if (children != null) {
+      __result['children'] = children;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('name') &&
+        obj['name'] is String &&
+        obj.containsKey('kind') &&
+        SymbolKind.canParse(obj['kind']) &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']) &&
+        obj.containsKey('selectionRange') &&
+        Range.canParse(obj['selectionRange']);
+  }
+}
+
+class DocumentSymbolParams implements ToJsonable {
+  DocumentSymbolParams(this.textDocument) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory DocumentSymbolParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    return new DocumentSymbolParams(textDocument);
+  }
+
+  /// The text document.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']);
+  }
+}
+
+abstract class ErrorCodes {
+  static const InternalError = -32603;
+  static const InvalidParams = -32602;
+  static const InvalidRequest = -32600;
+  static const MethodNotFound = -32601;
+  static const ParseError = -32700;
+  static const RequestCancelled = -32800;
+  static const ServerNotInitialized = -32002;
+  static const UnknownErrorCode = -32001;
+  static const serverErrorEnd = -32000;
+  static const serverErrorStart = -32099;
+}
+
+/// Execute command options.
+class ExecuteCommandOptions implements ToJsonable {
+  ExecuteCommandOptions(this.commands) {
+    if (commands == null) {
+      throw 'commands is required but was not provided';
+    }
+  }
+  factory ExecuteCommandOptions.fromJson(Map<String, dynamic> json) {
+    final commands =
+        json['commands']?.map((item) => item)?.cast<String>()?.toList();
+    return new ExecuteCommandOptions(commands);
+  }
+
+  /// The commands to be executed on the server
+  final List<String> commands;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['commands'] =
+        commands ?? (throw 'commands is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('commands') &&
+        (obj['commands'] is List &&
+            (obj['commands'].length == 0 ||
+                obj['commands'].every((item) => item is String)));
+  }
+}
+
+class ExecuteCommandParams implements ToJsonable {
+  ExecuteCommandParams(this.command, this.arguments) {
+    if (command == null) {
+      throw 'command is required but was not provided';
+    }
+  }
+  factory ExecuteCommandParams.fromJson(Map<String, dynamic> json) {
+    final command = json['command'];
+    final arguments =
+        json['arguments']?.map((item) => item)?.cast<dynamic>()?.toList();
+    return new ExecuteCommandParams(command, arguments);
+  }
+
+  /// Arguments that the command should be invoked with.
+  final List<dynamic> arguments;
+
+  /// The identifier of the actual command handler.
+  final String command;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['command'] =
+        command ?? (throw 'command is required but was not set');
+    if (arguments != null) {
+      __result['arguments'] = arguments;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('command') &&
+        obj['command'] is String;
+  }
+}
+
+/// Execute command registration options.
+class ExecuteCommandRegistrationOptions implements ToJsonable {
+  ExecuteCommandRegistrationOptions(this.commands) {
+    if (commands == null) {
+      throw 'commands is required but was not provided';
+    }
+  }
+  factory ExecuteCommandRegistrationOptions.fromJson(
+      Map<String, dynamic> json) {
+    final commands =
+        json['commands']?.map((item) => item)?.cast<String>()?.toList();
+    return new ExecuteCommandRegistrationOptions(commands);
+  }
+
+  /// The commands to be executed on the server
+  final List<String> commands;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['commands'] =
+        commands ?? (throw 'commands is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('commands') &&
+        (obj['commands'] is List &&
+            (obj['commands'].length == 0 ||
+                obj['commands'].every((item) => item is String)));
+  }
+}
+
+class FailureHandlingKind {
+  const FailureHandlingKind._(this._value);
+  const FailureHandlingKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 'abort':
+      case 'transactional':
+      case 'textOnlyTransactional':
+      case 'undo':
+        return true;
+    }
+    return false;
+  }
+
+  /// Applying the workspace change is simply aborted if one of the
+  /// changes provided fails. All operations executed before the
+  /// failing operation stay executed.
+  static const Abort = const FailureHandlingKind._('abort');
+
+  /// All operations are executed transactional. That means they
+  /// either all succeed or no changes at all are applied to the
+  /// workspace.
+  static const Transactional = const FailureHandlingKind._('transactional');
+
+  /// If the workspace edit contains only textual file changes they
+  /// are executed transactional. If resource changes (create, rename
+  /// or delete file) are part of the change the failure handling
+  /// startegy is abort.
+  static const TextOnlyTransactional =
+      const FailureHandlingKind._('textOnlyTransactional');
+
+  /// The client tries to undo the operations already executed. But
+  /// there is no guaruntee that this is succeeding.
+  static const Undo = const FailureHandlingKind._('undo');
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is FailureHandlingKind && o._value == _value;
+}
+
+/// The file event type.
+class FileChangeType {
+  const FileChangeType._(this._value);
+  const FileChangeType.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+        return true;
+    }
+    return false;
+  }
+
+  /// The file got created.
+  static const Created = const FileChangeType._(1);
+
+  /// The file got changed.
+  static const Changed = const FileChangeType._(2);
+
+  /// The file got deleted.
+  static const Deleted = const FileChangeType._(3);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is FileChangeType && o._value == _value;
+}
+
+/// An event describing a file change.
+class FileEvent implements ToJsonable {
+  FileEvent(this.uri, this.type) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+    if (type == null) {
+      throw 'type is required but was not provided';
+    }
+  }
+  factory FileEvent.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final type = json['type'];
+    return new FileEvent(uri, type);
+  }
+
+  /// The change type.
+  final num type;
+
+  /// The file's URI.
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    __result['type'] = type ?? (throw 'type is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String &&
+        obj.containsKey('type') &&
+        obj['type'] is num;
+  }
+}
+
+class FileSystemWatcher implements ToJsonable {
+  FileSystemWatcher(this.globPattern, this.kind) {
+    if (globPattern == null) {
+      throw 'globPattern is required but was not provided';
+    }
+  }
+  factory FileSystemWatcher.fromJson(Map<String, dynamic> json) {
+    final globPattern = json['globPattern'];
+    final kind =
+        json['kind'] != null ? new WatchKind.fromJson(json['kind']) : null;
+    return new FileSystemWatcher(globPattern, kind);
+  }
+
+  /// The  glob pattern to watch
+  final String globPattern;
+
+  /// The kind of events of interest. If omitted it defaults to
+  /// WatchKind.Create | WatchKind.Change | WatchKind.Delete which
+  /// is 7.
+  final WatchKind kind;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['globPattern'] =
+        globPattern ?? (throw 'globPattern is required but was not set');
+    if (kind != null) {
+      __result['kind'] = kind;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('globPattern') &&
+        obj['globPattern'] is String;
+  }
+}
+
+/// Represents a folding range.
+class FoldingRange implements ToJsonable {
+  FoldingRange(this.startLine, this.startCharacter, this.endLine,
+      this.endCharacter, this.kind) {
+    if (startLine == null) {
+      throw 'startLine is required but was not provided';
+    }
+    if (endLine == null) {
+      throw 'endLine is required but was not provided';
+    }
+  }
+  factory FoldingRange.fromJson(Map<String, dynamic> json) {
+    final startLine = json['startLine'];
+    final startCharacter = json['startCharacter'];
+    final endLine = json['endLine'];
+    final endCharacter = json['endCharacter'];
+    final kind = json['kind'] != null
+        ? new FoldingRangeKind.fromJson(json['kind'])
+        : null;
+    return new FoldingRange(
+        startLine, startCharacter, endLine, endCharacter, kind);
+  }
+
+  /// The zero-based character offset before the folded range ends.
+  /// If not defined, defaults to the length of the end line.
+  final num endCharacter;
+
+  /// The zero-based line number where the folded range ends.
+  final num endLine;
+
+  /// Describes the kind of the folding range such as `comment' or
+  /// 'region'. The kind is used to categorize folding ranges and
+  /// used by commands like 'Fold all comments'. See
+  /// [FoldingRangeKind] for an enumeration of standardized kinds.
+  final FoldingRangeKind kind;
+
+  /// The zero-based character offset from where the folded range
+  /// starts. If not defined, defaults to the length of the start
+  /// line.
+  final num startCharacter;
+
+  /// The zero-based line number from where the folded range starts.
+  final num startLine;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['startLine'] =
+        startLine ?? (throw 'startLine is required but was not set');
+    if (startCharacter != null) {
+      __result['startCharacter'] = startCharacter;
+    }
+    __result['endLine'] =
+        endLine ?? (throw 'endLine is required but was not set');
+    if (endCharacter != null) {
+      __result['endCharacter'] = endCharacter;
+    }
+    if (kind != null) {
+      __result['kind'] = kind;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('startLine') &&
+        obj['startLine'] is num &&
+        obj.containsKey('endLine') &&
+        obj['endLine'] is num;
+  }
+}
+
+/// Enum of known range kinds
+class FoldingRangeKind {
+  const FoldingRangeKind._(this._value);
+  const FoldingRangeKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 'comment':
+      case 'imports':
+      case 'region':
+        return true;
+    }
+    return false;
+  }
+
+  /// Folding range for a comment
+  static const Comment = const FoldingRangeKind._('comment');
+
+  /// Folding range for a imports or includes
+  static const Imports = const FoldingRangeKind._('imports');
+
+  /// Folding range for a region (e.g. `#region`)
+  static const Region = const FoldingRangeKind._('region');
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is FoldingRangeKind && o._value == _value;
+}
+
+class FoldingRangeParams implements ToJsonable {
+  FoldingRangeParams(this.textDocument) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+  }
+  factory FoldingRangeParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    return new FoldingRangeParams(textDocument);
+  }
+
+  /// The text document.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']);
+  }
+}
+
+/// Folding range provider options.
+class FoldingRangeProviderOptions implements ToJsonable {
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// Value-object describing what options formatting should use.
+class FormattingOptions implements ToJsonable {
+  FormattingOptions(this.tabSize, this.insertSpaces) {
+    if (tabSize == null) {
+      throw 'tabSize is required but was not provided';
+    }
+    if (insertSpaces == null) {
+      throw 'insertSpaces is required but was not provided';
+    }
+  }
+  factory FormattingOptions.fromJson(Map<String, dynamic> json) {
+    final tabSize = json['tabSize'];
+    final insertSpaces = json['insertSpaces'];
+    return new FormattingOptions(tabSize, insertSpaces);
+  }
+
+  /// Prefer spaces over tabs.
+  final bool insertSpaces;
+
+  /// Size of a tab in spaces.
+  final num tabSize;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['tabSize'] =
+        tabSize ?? (throw 'tabSize is required but was not set');
+    __result['insertSpaces'] =
+        insertSpaces ?? (throw 'insertSpaces is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('tabSize') &&
+        obj['tabSize'] is num &&
+        obj.containsKey('insertSpaces') &&
+        obj['insertSpaces'] is bool;
+  }
+}
+
+/// The result of a hover request.
+class Hover implements ToJsonable {
+  Hover(this.contents, this.range) {
+    if (contents == null) {
+      throw 'contents is required but was not provided';
+    }
+  }
+  factory Hover.fromJson(Map<String, dynamic> json) {
+    final contents = MarkedString.canParse(json['contents'])
+        ? new Either3<MarkedString, List<MarkedString>, MarkupContent>.t1(
+            json['contents'] != null
+                ? new MarkedString.fromJson(json['contents'])
+                : null)
+        : ((json['contents'] is List &&
+                (json['contents'].length == 0 ||
+                    json['contents']
+                        .every((item) => MarkedString.canParse(item))))
+            ? new Either3<MarkedString, List<MarkedString>, MarkupContent>.t2(json['contents']
+                ?.map((item) =>
+                    item != null ? new MarkedString.fromJson(item) : null)
+                ?.cast<MarkedString>()
+                ?.toList())
+            : (MarkupContent.canParse(json['contents'])
+                ? new Either3<MarkedString, List<MarkedString>, MarkupContent>.t3(
+                    json['contents'] != null
+                        ? new MarkupContent.fromJson(json['contents'])
+                        : null)
+                : (throw '''${json['contents']} was not one of (MarkedString, MarkedString[], MarkupContent)''')));
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    return new Hover(contents, range);
+  }
+
+  /// The hover's content
+  final Either3<MarkedString, List<MarkedString>, MarkupContent> contents;
+
+  /// An optional range is a range inside a text document that is
+  /// used to visualize a hover, e.g. by changing the background
+  /// color.
+  final Range range;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['contents'] =
+        contents ?? (throw 'contents is required but was not set');
+    if (range != null) {
+      __result['range'] = range;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('contents') &&
+        (MarkedString.canParse(obj['contents']) ||
+            (obj['contents'] is List &&
+                (obj['contents'].length == 0 ||
+                    obj['contents']
+                        .every((item) => MarkedString.canParse(item)))) ||
+            MarkupContent.canParse(obj['contents']));
+  }
+}
+
+class InitializeParams implements ToJsonable {
+  InitializeParams(this.processId, this.rootPath, this.rootUri,
+      this.initializationOptions, this.capabilities, this.workspaceFolders) {
+    if (capabilities == null) {
+      throw 'capabilities is required but was not provided';
+    }
+  }
+  factory InitializeParams.fromJson(Map<String, dynamic> json) {
+    final processId = json['processId'];
+    final rootPath = json['rootPath'];
+    final rootUri = json['rootUri'];
+    final initializationOptions = json['initializationOptions'];
+    final capabilities = json['capabilities'] != null
+        ? new ClientCapabilities.fromJson(json['capabilities'])
+        : null;
+    final workspaceFolders = json['workspaceFolders']
+        ?.map(
+            (item) => item != null ? new WorkspaceFolder.fromJson(item) : null)
+        ?.cast<WorkspaceFolder>()
+        ?.toList();
+    return new InitializeParams(processId, rootPath, rootUri,
+        initializationOptions, capabilities, workspaceFolders);
+  }
+
+  /// The capabilities provided by the client (editor or tool)
+  final ClientCapabilities capabilities;
+
+  /// User provided initialization options.
+  final dynamic initializationOptions;
+
+  /// The process Id of the parent process that started the
+  /// server. Is null if the process has not been started by
+  /// another process. If the parent process is not alive then the
+  /// server should exit (see exit notification) its process.
+  final num processId;
+
+  /// The rootPath of the workspace. Is null if no folder is open.
+  ///  @deprecated in favour of rootUri.
+  @core.deprecated
+  final String rootPath;
+
+  /// The rootUri of the workspace. Is null if no folder is open.
+  /// If both `rootPath` and `rootUri` are set `rootUri` wins.
+  final String rootUri;
+
+  /// The workspace folders configured in the client when the
+  /// server starts. This property is only available if the client
+  /// supports workspace folders. It can be `null` if the client
+  /// supports workspace folders but none are configured.
+  ///
+  /// Since 3.6.0
+  final List<WorkspaceFolder> workspaceFolders;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['processId'] = processId;
+    // ignore: deprecated_member_use
+    if (rootPath != null) {
+      // ignore: deprecated_member_use
+      __result['rootPath'] = rootPath;
+    }
+    __result['rootUri'] = rootUri;
+    if (initializationOptions != null) {
+      __result['initializationOptions'] = initializationOptions;
+    }
+    __result['capabilities'] =
+        capabilities ?? (throw 'capabilities is required but was not set');
+    if (workspaceFolders != null) {
+      __result['workspaceFolders'] = workspaceFolders;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('processId') &&
+        obj['processId'] is num &&
+        obj.containsKey('rootUri') &&
+        obj['rootUri'] is String &&
+        obj.containsKey('capabilities') &&
+        ClientCapabilities.canParse(obj['capabilities']);
+  }
+}
+
+class InitializeResult implements ToJsonable {
+  InitializeResult(this.capabilities) {
+    if (capabilities == null) {
+      throw 'capabilities is required but was not provided';
+    }
+  }
+  factory InitializeResult.fromJson(Map<String, dynamic> json) {
+    final capabilities = json['capabilities'] != null
+        ? new ServerCapabilities.fromJson(json['capabilities'])
+        : null;
+    return new InitializeResult(capabilities);
+  }
+
+  /// The capabilities the language server provides.
+  final ServerCapabilities capabilities;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['capabilities'] =
+        capabilities ?? (throw 'capabilities is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('capabilities') &&
+        ServerCapabilities.canParse(obj['capabilities']);
+  }
+}
+
+class InitializedParams implements ToJsonable {
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// Defines whether the insert text in a completion item should be
+/// interpreted as plain text or a snippet.
+class InsertTextFormat {
+  const InsertTextFormat._(this._value);
+  const InsertTextFormat.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+        return true;
+    }
+    return false;
+  }
+
+  /// The primary text to be inserted is treated as a plain
+  /// string.
+  static const PlainText = const InsertTextFormat._(1);
+
+  /// The primary text to be inserted is treated as a snippet.
+  ///
+  /// A snippet can define tab stops and placeholders with `$1`,
+  /// `$2` and `${3:foo}`. `$0` defines the final tab stop, it
+  /// defaults to the end of the snippet. Placeholders with
+  /// equal identifiers are linked, that is typing in one will
+  /// update others too.
+  static const Snippet = const InsertTextFormat._(2);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is InsertTextFormat && o._value == _value;
+}
+
+class Location implements ToJsonable {
+  Location(this.uri, this.range) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+  }
+  factory Location.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    return new Location(uri, range);
+  }
+
+  final Range range;
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']);
+  }
+}
+
+class LogMessageParams implements ToJsonable {
+  LogMessageParams(this.type, this.message) {
+    if (type == null) {
+      throw 'type is required but was not provided';
+    }
+    if (message == null) {
+      throw 'message is required but was not provided';
+    }
+  }
+  factory LogMessageParams.fromJson(Map<String, dynamic> json) {
+    final type =
+        json['type'] != null ? new MessageType.fromJson(json['type']) : null;
+    final message = json['message'];
+    return new LogMessageParams(type, message);
+  }
+
+  /// The actual message
+  final String message;
+
+  /// The message type.
+  final MessageType type;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['type'] = type ?? (throw 'type is required but was not set');
+    __result['message'] =
+        message ?? (throw 'message is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('type') &&
+        MessageType.canParse(obj['type']) &&
+        obj.containsKey('message') &&
+        obj['message'] is String;
+  }
+}
+
+class MarkedString implements ToJsonable {
+  MarkedString(this.language, this.value) {
+    if (language == null) {
+      throw 'language is required but was not provided';
+    }
+    if (value == null) {
+      throw 'value is required but was not provided';
+    }
+  }
+  factory MarkedString.fromJson(Map<String, dynamic> json) {
+    final language = json['language'];
+    final value = json['value'];
+    return new MarkedString(language, value);
+  }
+
+  final String language;
+  final String value;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['language'] =
+        language ?? (throw 'language is required but was not set');
+    __result['value'] = value ?? (throw 'value is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('language') &&
+        obj['language'] is String &&
+        obj.containsKey('value') &&
+        obj['value'] is String;
+  }
+}
+
+/// A `MarkupContent` literal represents a string value which
+/// content is interpreted base on its kind flag. Currently the
+/// protocol supports `plaintext` and `markdown` as markup
+/// kinds.
+///
+/// If the kind is `markdown` then the value can contain fenced
+/// code blocks like in GitHub issues. See
+/// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+///
+/// Here is an example how such a string can be constructed
+/// using JavaScript / TypeScript: ```ts let markdown:
+/// MarkdownContent = {
+///
+/// kind: MarkupKind.Markdown,
+/// 	value: [
+/// 		'# Header',
+/// 		'Some text',
+/// 		'```typescript',
+/// 		'someCode();',
+/// 		'```'
+/// 	].join('\n') }; ```
+///
+/// *Please Note* that clients might sanitize the return
+/// markdown. A client could decide to remove HTML from the
+/// markdown to avoid script execution.
+class MarkupContent implements ToJsonable {
+  MarkupContent(this.kind, this.value) {
+    if (kind == null) {
+      throw 'kind is required but was not provided';
+    }
+    if (value == null) {
+      throw 'value is required but was not provided';
+    }
+  }
+  factory MarkupContent.fromJson(Map<String, dynamic> json) {
+    final kind =
+        json['kind'] != null ? new MarkupKind.fromJson(json['kind']) : null;
+    final value = json['value'];
+    return new MarkupContent(kind, value);
+  }
+
+  /// The type of the Markup
+  final MarkupKind kind;
+
+  /// The content itself
+  final String value;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['kind'] = kind ?? (throw 'kind is required but was not set');
+    __result['value'] = value ?? (throw 'value is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('kind') &&
+        MarkupKind.canParse(obj['kind']) &&
+        obj.containsKey('value') &&
+        obj['value'] is String;
+  }
+}
+
+/// Describes the content type that a client supports in various
+/// result literals like `Hover`, `ParameterInfo` or
+/// `CompletionItem`.
+///
+/// Please note that `MarkupKinds` must not start with a `$`.
+/// This kinds are reserved for internal usage.
+class MarkupKind {
+  const MarkupKind._(this._value);
+  const MarkupKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 'plaintext':
+      case 'markdown':
+        return true;
+    }
+    return false;
+  }
+
+  /// Plain text is supported as a content format
+  static const PlainText = const MarkupKind._('plaintext');
+
+  /// Markdown is supported as a content format
+  static const Markdown = const MarkupKind._('markdown');
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is MarkupKind && o._value == _value;
+}
+
+class Message implements ToJsonable {
+  Message(this.jsonrpc) {
+    if (jsonrpc == null) {
+      throw 'jsonrpc is required but was not provided';
+    }
+  }
+  factory Message.fromJson(Map<String, dynamic> json) {
+    final jsonrpc = json['jsonrpc'];
+    return new Message(jsonrpc);
+  }
+
+  final String jsonrpc;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['jsonrpc'] =
+        jsonrpc ?? (throw 'jsonrpc is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('jsonrpc') &&
+        obj['jsonrpc'] is String;
+  }
+}
+
+class MessageActionItem implements ToJsonable {
+  MessageActionItem(this.title) {
+    if (title == null) {
+      throw 'title is required but was not provided';
+    }
+  }
+  factory MessageActionItem.fromJson(Map<String, dynamic> json) {
+    final title = json['title'];
+    return new MessageActionItem(title);
+  }
+
+  /// A short title like 'Retry', 'Open Log' etc.
+  final String title;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['title'] = title ?? (throw 'title is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('title') &&
+        obj['title'] is String;
+  }
+}
+
+class MessageType {
+  const MessageType._(this._value);
+  const MessageType.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+        return true;
+    }
+    return false;
+  }
+
+  /// An error message.
+  static const Error = const MessageType._(1);
+
+  /// A warning message.
+  static const Warning = const MessageType._(2);
+
+  /// An information message.
+  static const Info = const MessageType._(3);
+
+  /// A log message.
+  static const Log = const MessageType._(4);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is MessageType && o._value == _value;
+}
+
+class NotificationMessage implements Message, ToJsonable {
+  NotificationMessage(this.method, this.params, this.jsonrpc) {
+    if (method == null) {
+      throw 'method is required but was not provided';
+    }
+    if (jsonrpc == null) {
+      throw 'jsonrpc is required but was not provided';
+    }
+  }
+  factory NotificationMessage.fromJson(Map<String, dynamic> json) {
+    final method = json['method'];
+    final params = (json['params'] is List &&
+            (json['params'].length == 0 ||
+                json['params'].every((item) => true)))
+        ? new Either2<List<dynamic>, dynamic>.t1(
+            json['params']?.map((item) => item)?.cast<dynamic>()?.toList())
+        : (new Either2<List<dynamic>, dynamic>.t2(json['params']));
+    final jsonrpc = json['jsonrpc'];
+    return new NotificationMessage(method, params, jsonrpc);
+  }
+
+  final String jsonrpc;
+
+  /// The method to be invoked.
+  final String method;
+
+  /// The notification's params.
+  final Either2<List<dynamic>, dynamic> params;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['method'] = method ?? (throw 'method is required but was not set');
+    if (params != null) {
+      __result['params'] = params;
+    }
+    __result['jsonrpc'] =
+        jsonrpc ?? (throw 'jsonrpc is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('method') &&
+        obj['method'] is String &&
+        obj.containsKey('jsonrpc') &&
+        obj['jsonrpc'] is String;
+  }
+}
+
+/// Represents a parameter of a callable-signature. A
+/// parameter can have a label and a doc-comment.
+class ParameterInformation implements ToJsonable {
+  ParameterInformation(this.label, this.documentation) {
+    if (label == null) {
+      throw 'label is required but was not provided';
+    }
+  }
+  factory ParameterInformation.fromJson(Map<String, dynamic> json) {
+    final label = json['label'];
+    final documentation = json['documentation'] is String
+        ? new Either2<String, MarkupContent>.t1(json['documentation'])
+        : (MarkupContent.canParse(json['documentation'])
+            ? new Either2<String, MarkupContent>.t2(
+                json['documentation'] != null
+                    ? new MarkupContent.fromJson(json['documentation'])
+                    : null)
+            : (throw '''${json['documentation']} was not one of (string, MarkupContent)'''));
+    return new ParameterInformation(label, documentation);
+  }
+
+  /// The human-readable doc-comment of this parameter. Will
+  /// be shown in the UI but can be omitted.
+  final Either2<String, MarkupContent> documentation;
+
+  /// The label of this parameter. Will be shown in the UI.
+  final String label;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['label'] = label ?? (throw 'label is required but was not set');
+    if (documentation != null) {
+      __result['documentation'] = documentation;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('label') &&
+        obj['label'] is String;
+  }
+}
+
+class Position implements ToJsonable {
+  Position(this.line, this.character) {
+    if (line == null) {
+      throw 'line is required but was not provided';
+    }
+    if (character == null) {
+      throw 'character is required but was not provided';
+    }
+  }
+  factory Position.fromJson(Map<String, dynamic> json) {
+    final line = json['line'];
+    final character = json['character'];
+    return new Position(line, character);
+  }
+
+  /// Character offset on a line in a document (zero-based).
+  /// Assuming that the line is represented as a string, the
+  /// `character` value represents the gap between the
+  /// `character` and `character + 1`.
+  ///
+  /// If the character value is greater than the line length
+  /// it defaults back to the line length.
+  final num character;
+
+  /// Line position in a document (zero-based).
+  final num line;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['line'] = line ?? (throw 'line is required but was not set');
+    __result['character'] =
+        character ?? (throw 'character is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('line') &&
+        obj['line'] is num &&
+        obj.containsKey('character') &&
+        obj['character'] is num;
+  }
+}
+
+class PublishDiagnosticsParams implements ToJsonable {
+  PublishDiagnosticsParams(this.uri, this.diagnostics) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+    if (diagnostics == null) {
+      throw 'diagnostics is required but was not provided';
+    }
+  }
+  factory PublishDiagnosticsParams.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final diagnostics = json['diagnostics']
+        ?.map((item) => item != null ? new Diagnostic.fromJson(item) : null)
+        ?.cast<Diagnostic>()
+        ?.toList();
+    return new PublishDiagnosticsParams(uri, diagnostics);
+  }
+
+  /// An array of diagnostic information items.
+  final List<Diagnostic> diagnostics;
+
+  /// The URI for which diagnostic information is reported.
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    __result['diagnostics'] =
+        diagnostics ?? (throw 'diagnostics is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String &&
+        obj.containsKey('diagnostics') &&
+        (obj['diagnostics'] is List &&
+            (obj['diagnostics'].length == 0 ||
+                obj['diagnostics'].every((item) => Diagnostic.canParse(item))));
+  }
+}
+
+class Range implements ToJsonable {
+  Range(this.start, this.end) {
+    if (start == null) {
+      throw 'start is required but was not provided';
+    }
+    if (end == null) {
+      throw 'end is required but was not provided';
+    }
+  }
+  factory Range.fromJson(Map<String, dynamic> json) {
+    final start =
+        json['start'] != null ? new Position.fromJson(json['start']) : null;
+    final end = json['end'] != null ? new Position.fromJson(json['end']) : null;
+    return new Range(start, end);
+  }
+
+  /// The range's end position.
+  final Position end;
+
+  /// The range's start position.
+  final Position start;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['start'] = start ?? (throw 'start is required but was not set');
+    __result['end'] = end ?? (throw 'end is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('start') &&
+        Position.canParse(obj['start']) &&
+        obj.containsKey('end') &&
+        Position.canParse(obj['end']);
+  }
+}
+
+class ReferenceContext implements ToJsonable {
+  ReferenceContext(this.includeDeclaration) {
+    if (includeDeclaration == null) {
+      throw 'includeDeclaration is required but was not provided';
+    }
+  }
+  factory ReferenceContext.fromJson(Map<String, dynamic> json) {
+    final includeDeclaration = json['includeDeclaration'];
+    return new ReferenceContext(includeDeclaration);
+  }
+
+  /// Include the declaration of the current symbol.
+  final bool includeDeclaration;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['includeDeclaration'] = includeDeclaration ??
+        (throw 'includeDeclaration is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('includeDeclaration') &&
+        obj['includeDeclaration'] is bool;
+  }
+}
+
+class ReferenceParams implements TextDocumentPositionParams, ToJsonable {
+  ReferenceParams(this.context, this.textDocument, this.position) {
+    if (context == null) {
+      throw 'context is required but was not provided';
+    }
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (position == null) {
+      throw 'position is required but was not provided';
+    }
+  }
+  factory ReferenceParams.fromJson(Map<String, dynamic> json) {
+    final context = json['context'] != null
+        ? new ReferenceContext.fromJson(json['context'])
+        : null;
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final position = json['position'] != null
+        ? new Position.fromJson(json['position'])
+        : null;
+    return new ReferenceParams(context, textDocument, position);
+  }
+
+  final ReferenceContext context;
+
+  /// The position inside the text document.
+  final Position position;
+
+  /// The text document.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['context'] =
+        context ?? (throw 'context is required but was not set');
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['position'] =
+        position ?? (throw 'position is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('context') &&
+        ReferenceContext.canParse(obj['context']) &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('position') &&
+        Position.canParse(obj['position']);
+  }
+}
+
+/// General parameters to register for a capability.
+class Registration implements ToJsonable {
+  Registration(this.id, this.method, this.registerOptions) {
+    if (id == null) {
+      throw 'id is required but was not provided';
+    }
+    if (method == null) {
+      throw 'method is required but was not provided';
+    }
+  }
+  factory Registration.fromJson(Map<String, dynamic> json) {
+    final id = json['id'];
+    final method = json['method'];
+    final registerOptions = json['registerOptions'];
+    return new Registration(id, method, registerOptions);
+  }
+
+  /// The id used to register the request. The id can be
+  /// used to deregister the request again.
+  final String id;
+
+  /// The method / capability to register for.
+  final String method;
+
+  /// Options necessary for the registration.
+  final dynamic registerOptions;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['id'] = id ?? (throw 'id is required but was not set');
+    __result['method'] = method ?? (throw 'method is required but was not set');
+    if (registerOptions != null) {
+      __result['registerOptions'] = registerOptions;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('id') &&
+        obj['id'] is String &&
+        obj.containsKey('method') &&
+        obj['method'] is String;
+  }
+}
+
+class RegistrationParams implements ToJsonable {
+  RegistrationParams(this.registrations) {
+    if (registrations == null) {
+      throw 'registrations is required but was not provided';
+    }
+  }
+  factory RegistrationParams.fromJson(Map<String, dynamic> json) {
+    final registrations = json['registrations']
+        ?.map((item) => item != null ? new Registration.fromJson(item) : null)
+        ?.cast<Registration>()
+        ?.toList();
+    return new RegistrationParams(registrations);
+  }
+
+  final List<Registration> registrations;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['registrations'] =
+        registrations ?? (throw 'registrations is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('registrations') &&
+        (obj['registrations'] is List &&
+            (obj['registrations'].length == 0 ||
+                obj['registrations']
+                    .every((item) => Registration.canParse(item))));
+  }
+}
+
+/// Rename file operation
+class RenameFile implements FileOperation, ToJsonable {
+  RenameFile(this.oldUri, this.newUri, this.options) {
+    if (oldUri == null) {
+      throw 'oldUri is required but was not provided';
+    }
+    if (newUri == null) {
+      throw 'newUri is required but was not provided';
+    }
+  }
+  factory RenameFile.fromJson(Map<String, dynamic> json) {
+    final oldUri = json['oldUri'];
+    final newUri = json['newUri'];
+    final options = json['options'] != null
+        ? new RenameFileOptions.fromJson(json['options'])
+        : null;
+    return new RenameFile(oldUri, newUri, options);
+  }
+
+  /// The new location.
+  final String newUri;
+
+  /// The old (existing) location.
+  final String oldUri;
+
+  /// Rename options.
+  final RenameFileOptions options;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['oldUri'] = oldUri ?? (throw 'oldUri is required but was not set');
+    __result['newUri'] = newUri ?? (throw 'newUri is required but was not set');
+    if (options != null) {
+      __result['options'] = options;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('oldUri') &&
+        obj['oldUri'] is String &&
+        obj.containsKey('newUri') &&
+        obj['newUri'] is String;
+  }
+}
+
+/// Rename file options
+class RenameFileOptions implements ToJsonable {
+  RenameFileOptions(this.overwrite, this.ignoreIfExists);
+  factory RenameFileOptions.fromJson(Map<String, dynamic> json) {
+    final overwrite = json['overwrite'];
+    final ignoreIfExists = json['ignoreIfExists'];
+    return new RenameFileOptions(overwrite, ignoreIfExists);
+  }
+
+  /// Ignores if target exists.
+  final bool ignoreIfExists;
+
+  /// Overwrite target if existing. Overwrite wins over
+  /// `ignoreIfExists`
+  final bool overwrite;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (overwrite != null) {
+      __result['overwrite'] = overwrite;
+    }
+    if (ignoreIfExists != null) {
+      __result['ignoreIfExists'] = ignoreIfExists;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// Rename options
+class RenameOptions implements ToJsonable {
+  RenameOptions(this.prepareProvider);
+  factory RenameOptions.fromJson(Map<String, dynamic> json) {
+    final prepareProvider = json['prepareProvider'];
+    return new RenameOptions(prepareProvider);
+  }
+
+  /// Renames should be checked and tested before being
+  /// executed.
+  final bool prepareProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (prepareProvider != null) {
+      __result['prepareProvider'] = prepareProvider;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class RenameParams implements ToJsonable {
+  RenameParams(this.textDocument, this.position, this.newName) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (position == null) {
+      throw 'position is required but was not provided';
+    }
+    if (newName == null) {
+      throw 'newName is required but was not provided';
+    }
+  }
+  factory RenameParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final position = json['position'] != null
+        ? new Position.fromJson(json['position'])
+        : null;
+    final newName = json['newName'];
+    return new RenameParams(textDocument, position, newName);
+  }
+
+  /// The new name of the symbol. If the given name is not
+  /// valid the request must return a [ResponseError] with
+  /// an appropriate message set.
+  final String newName;
+
+  /// The position at which this request was sent.
+  final Position position;
+
+  /// The document to rename.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['position'] =
+        position ?? (throw 'position is required but was not set');
+    __result['newName'] =
+        newName ?? (throw 'newName is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('position') &&
+        Position.canParse(obj['position']) &&
+        obj.containsKey('newName') &&
+        obj['newName'] is String;
+  }
+}
+
+class RenameRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  RenameRegistrationOptions(this.prepareProvider, this.documentSelector);
+  factory RenameRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final prepareProvider = json['prepareProvider'];
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new RenameRegistrationOptions(prepareProvider, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the
+  /// registration. If set to null the document selector
+  /// provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// Renames should be checked and tested for validity
+  /// before being executed.
+  final bool prepareProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (prepareProvider != null) {
+      __result['prepareProvider'] = prepareProvider;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+class RequestMessage implements Message, ToJsonable {
+  RequestMessage(this.id, this.method, this.params, this.jsonrpc) {
+    if (id == null) {
+      throw 'id is required but was not provided';
+    }
+    if (method == null) {
+      throw 'method is required but was not provided';
+    }
+    if (jsonrpc == null) {
+      throw 'jsonrpc is required but was not provided';
+    }
+  }
+  factory RequestMessage.fromJson(Map<String, dynamic> json) {
+    final id = json['id'] is num
+        ? new Either2<num, String>.t1(json['id'])
+        : (json['id'] is String
+            ? new Either2<num, String>.t2(json['id'])
+            : (throw '''${json['id']} was not one of (number, string)'''));
+    final method = json['method'];
+    final params = (json['params'] is List &&
+            (json['params'].length == 0 ||
+                json['params'].every((item) => true)))
+        ? new Either2<List<dynamic>, dynamic>.t1(
+            json['params']?.map((item) => item)?.cast<dynamic>()?.toList())
+        : (new Either2<List<dynamic>, dynamic>.t2(json['params']));
+    final jsonrpc = json['jsonrpc'];
+    return new RequestMessage(id, method, params, jsonrpc);
+  }
+
+  /// The request id.
+  final Either2<num, String> id;
+  final String jsonrpc;
+
+  /// The method to be invoked.
+  final String method;
+
+  /// The method's params.
+  final Either2<List<dynamic>, dynamic> params;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['id'] = id ?? (throw 'id is required but was not set');
+    __result['method'] = method ?? (throw 'method is required but was not set');
+    if (params != null) {
+      __result['params'] = params;
+    }
+    __result['jsonrpc'] =
+        jsonrpc ?? (throw 'jsonrpc is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('id') &&
+        (obj['id'] is num || obj['id'] is String) &&
+        obj.containsKey('method') &&
+        obj['method'] is String &&
+        obj.containsKey('jsonrpc') &&
+        obj['jsonrpc'] is String;
+  }
+}
+
+class ResourceOperationKind {
+  const ResourceOperationKind._(this._value);
+  const ResourceOperationKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 'create':
+      case 'rename':
+      case 'delete':
+        return true;
+    }
+    return false;
+  }
+
+  /// Supports creating new files and folders.
+  static const Create = const ResourceOperationKind._('create');
+
+  /// Supports renaming existing files and folders.
+  static const Rename = const ResourceOperationKind._('rename');
+
+  /// Supports deleting existing files and folders.
+  static const Delete = const ResourceOperationKind._('delete');
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is ResourceOperationKind && o._value == _value;
+}
+
+class ResponseError<D> implements ToJsonable {
+  ResponseError(this.code, this.message, this.data) {
+    if (code == null) {
+      throw 'code is required but was not provided';
+    }
+    if (message == null) {
+      throw 'message is required but was not provided';
+    }
+  }
+  factory ResponseError.fromJson(Map<String, dynamic> json) {
+    final code = json['code'];
+    final message = json['message'];
+    final data = json['data'];
+    return new ResponseError<D>(code, message, data);
+  }
+
+  /// A number indicating the error type that occurred.
+  final num code;
+
+  /// A Primitive or Structured value that contains
+  /// additional information about the error. Can be
+  /// omitted.
+  final D data;
+
+  /// A string providing a short description of the error.
+  final String message;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['code'] = code ?? (throw 'code is required but was not set');
+    __result['message'] =
+        message ?? (throw 'message is required but was not set');
+    if (data != null) {
+      __result['data'] = data;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('code') &&
+        obj['code'] is num &&
+        obj.containsKey('message') &&
+        obj['message'] is String;
+  }
+}
+
+class ResponseMessage implements Message, ToJsonable {
+  ResponseMessage(this.id, this.result, this.error, this.jsonrpc) {
+    if (jsonrpc == null) {
+      throw 'jsonrpc is required but was not provided';
+    }
+  }
+  factory ResponseMessage.fromJson(Map<String, dynamic> json) {
+    final id = json['id'] is num
+        ? new Either2<num, String>.t1(json['id'])
+        : (json['id'] is String
+            ? new Either2<num, String>.t2(json['id'])
+            : (throw '''${json['id']} was not one of (number, string)'''));
+    final result = json['result'];
+    final error = json['error'];
+    final jsonrpc = json['jsonrpc'];
+    return new ResponseMessage(id, result, error, jsonrpc);
+  }
+
+  /// The error object in case a request fails.
+  final ResponseError<dynamic> error;
+
+  /// The request id.
+  final Either2<num, String> id;
+  final String jsonrpc;
+
+  /// The result of a request. This can be omitted in the
+  /// case of an error.
+  final dynamic result;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['id'] = id;
+    if (result != null) {
+      __result['result'] = result;
+    }
+    if (error != null) {
+      __result['error'] = error;
+    }
+    __result['jsonrpc'] =
+        jsonrpc ?? (throw 'jsonrpc is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('id') &&
+        (obj['id'] is num || obj['id'] is String) &&
+        obj.containsKey('jsonrpc') &&
+        obj['jsonrpc'] is String;
+  }
+}
+
+/// Save options.
+class SaveOptions implements ToJsonable {
+  SaveOptions(this.includeText);
+  factory SaveOptions.fromJson(Map<String, dynamic> json) {
+    final includeText = json['includeText'];
+    return new SaveOptions(includeText);
+  }
+
+  /// The client is supposed to include the content on
+  /// save.
+  final bool includeText;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (includeText != null) {
+      __result['includeText'] = includeText;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class ServerCapabilities implements ToJsonable {
+  ServerCapabilities(
+      this.textDocumentSync,
+      this.hoverProvider,
+      this.completionProvider,
+      this.signatureHelpProvider,
+      this.definitionProvider,
+      this.referencesProvider,
+      this.documentHighlightProvider,
+      this.documentSymbolProvider,
+      this.workspaceSymbolProvider,
+      this.codeActionProvider,
+      this.codeLensProvider,
+      this.documentFormattingProvider,
+      this.documentRangeFormattingProvider,
+      this.documentOnTypeFormattingProvider,
+      this.renameProvider,
+      this.documentLinkProvider,
+      this.executeCommandProvider,
+      this.supported,
+      this.changeNotifications);
+  factory ServerCapabilities.fromJson(Map<String, dynamic> json) {
+    final textDocumentSync = TextDocumentSyncOptions.canParse(
+            json['textDocumentSync'])
+        ? new Either2<TextDocumentSyncOptions, num>.t1(
+            json['textDocumentSync'] != null
+                ? new TextDocumentSyncOptions.fromJson(json['textDocumentSync'])
+                : null)
+        : (json['textDocumentSync'] is num
+            ? new Either2<TextDocumentSyncOptions, num>.t2(
+                json['textDocumentSync'])
+            : (throw '''${json['textDocumentSync']} was not one of (TextDocumentSyncOptions, number)'''));
+    final hoverProvider = json['hoverProvider'];
+    final completionProvider = json['completionProvider'] != null
+        ? new CompletionOptions.fromJson(json['completionProvider'])
+        : null;
+    final signatureHelpProvider = json['signatureHelpProvider'] != null
+        ? new SignatureHelpOptions.fromJson(json['signatureHelpProvider'])
+        : null;
+    final definitionProvider = json['definitionProvider'];
+    final referencesProvider = json['referencesProvider'];
+    final documentHighlightProvider = json['documentHighlightProvider'];
+    final documentSymbolProvider = json['documentSymbolProvider'];
+    final workspaceSymbolProvider = json['workspaceSymbolProvider'];
+    final codeActionProvider = json['codeActionProvider'] is bool
+        ? new Either2<bool, CodeActionOptions>.t1(json['codeActionProvider'])
+        : (CodeActionOptions.canParse(json['codeActionProvider'])
+            ? new Either2<bool, CodeActionOptions>.t2(
+                json['codeActionProvider'] != null
+                    ? new CodeActionOptions.fromJson(json['codeActionProvider'])
+                    : null)
+            : (throw '''${json['codeActionProvider']} was not one of (boolean, CodeActionOptions)'''));
+    final codeLensProvider = json['codeLensProvider'] != null
+        ? new CodeLensOptions.fromJson(json['codeLensProvider'])
+        : null;
+    final documentFormattingProvider = json['documentFormattingProvider'];
+    final documentRangeFormattingProvider =
+        json['documentRangeFormattingProvider'];
+    final documentOnTypeFormattingProvider =
+        json['documentOnTypeFormattingProvider'] != null
+            ? new DocumentOnTypeFormattingOptions.fromJson(
+                json['documentOnTypeFormattingProvider'])
+            : null;
+    final renameProvider = json['renameProvider'] is bool
+        ? new Either2<bool, RenameOptions>.t1(json['renameProvider'])
+        : (RenameOptions.canParse(json['renameProvider'])
+            ? new Either2<bool, RenameOptions>.t2(json['renameProvider'] != null
+                ? new RenameOptions.fromJson(json['renameProvider'])
+                : null)
+            : (throw '''${json['renameProvider']} was not one of (boolean, RenameOptions)'''));
+    final documentLinkProvider = json['documentLinkProvider'] != null
+        ? new DocumentLinkOptions.fromJson(json['documentLinkProvider'])
+        : null;
+    final executeCommandProvider = json['executeCommandProvider'] != null
+        ? new ExecuteCommandOptions.fromJson(json['executeCommandProvider'])
+        : null;
+    final supported = json['supported'];
+    final changeNotifications = json['changeNotifications'] is String
+        ? new Either2<String, bool>.t1(json['changeNotifications'])
+        : (json['changeNotifications'] is bool
+            ? new Either2<String, bool>.t2(json['changeNotifications'])
+            : (throw '''${json['changeNotifications']} was not one of (string, boolean)'''));
+    return new ServerCapabilities(
+        textDocumentSync,
+        hoverProvider,
+        completionProvider,
+        signatureHelpProvider,
+        definitionProvider,
+        referencesProvider,
+        documentHighlightProvider,
+        documentSymbolProvider,
+        workspaceSymbolProvider,
+        codeActionProvider,
+        codeLensProvider,
+        documentFormattingProvider,
+        documentRangeFormattingProvider,
+        documentOnTypeFormattingProvider,
+        renameProvider,
+        documentLinkProvider,
+        executeCommandProvider,
+        supported,
+        changeNotifications);
+  }
+
+  /// Whether the server wants to receive workspace folder
+  /// change notifications.
+  ///
+  /// If a strings is provided the string is treated as a
+  /// ID under which the notification is registered on the
+  /// client side. The ID can be used to unregister for
+  /// these events using the `client/unregisterCapability`
+  /// request.
+  final Either2<String, bool> changeNotifications;
+
+  /// The server provides code actions. The
+  /// `CodeActionOptions` return type is only valid if the
+  /// client signals code action literal support via the
+  /// property
+  /// `textDocument.codeAction.codeActionLiteralSupport`.
+  final Either2<bool, CodeActionOptions> codeActionProvider;
+
+  /// The server provides code lens.
+  final CodeLensOptions codeLensProvider;
+
+  /// The server provides completion support.
+  final CompletionOptions completionProvider;
+
+  /// The server provides goto definition support.
+  final bool definitionProvider;
+
+  /// The server provides document formatting.
+  final bool documentFormattingProvider;
+
+  /// The server provides document highlight support.
+  final bool documentHighlightProvider;
+
+  /// The server provides document link support.
+  final DocumentLinkOptions documentLinkProvider;
+
+  /// The server provides document formatting on typing.
+  final DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
+
+  /// The server provides document range formatting.
+  final bool documentRangeFormattingProvider;
+
+  /// The server provides document symbol support.
+  final bool documentSymbolProvider;
+
+  /// The server provides execute command support.
+  final ExecuteCommandOptions executeCommandProvider;
+
+  /// The server provides hover support.
+  final bool hoverProvider;
+
+  /// The server provides find references support.
+  final bool referencesProvider;
+
+  /// The server provides rename support. RenameOptions
+  /// may only be specified if the client states that it
+  /// supports `prepareSupport` in its initial
+  /// `initialize` request.
+  final Either2<bool, RenameOptions> renameProvider;
+
+  /// The server provides signature help support.
+  final SignatureHelpOptions signatureHelpProvider;
+
+  /// The server has support for workspace folders
+  final bool supported;
+
+  /// Defines how text documents are synced. Is either a
+  /// detailed structure defining each notification or for
+  /// backwards compatibility the TextDocumentSyncKind
+  /// number. If omitted it defaults to
+  /// `TextDocumentSyncKind.None`.
+  final Either2<TextDocumentSyncOptions, num> textDocumentSync;
+
+  /// The server provides workspace symbol support.
+  final bool workspaceSymbolProvider;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (textDocumentSync != null) {
+      __result['textDocumentSync'] = textDocumentSync;
+    }
+    if (hoverProvider != null) {
+      __result['hoverProvider'] = hoverProvider;
+    }
+    if (completionProvider != null) {
+      __result['completionProvider'] = completionProvider;
+    }
+    if (signatureHelpProvider != null) {
+      __result['signatureHelpProvider'] = signatureHelpProvider;
+    }
+    if (definitionProvider != null) {
+      __result['definitionProvider'] = definitionProvider;
+    }
+    if (referencesProvider != null) {
+      __result['referencesProvider'] = referencesProvider;
+    }
+    if (documentHighlightProvider != null) {
+      __result['documentHighlightProvider'] = documentHighlightProvider;
+    }
+    if (documentSymbolProvider != null) {
+      __result['documentSymbolProvider'] = documentSymbolProvider;
+    }
+    if (workspaceSymbolProvider != null) {
+      __result['workspaceSymbolProvider'] = workspaceSymbolProvider;
+    }
+    if (codeActionProvider != null) {
+      __result['codeActionProvider'] = codeActionProvider;
+    }
+    if (codeLensProvider != null) {
+      __result['codeLensProvider'] = codeLensProvider;
+    }
+    if (documentFormattingProvider != null) {
+      __result['documentFormattingProvider'] = documentFormattingProvider;
+    }
+    if (documentRangeFormattingProvider != null) {
+      __result['documentRangeFormattingProvider'] =
+          documentRangeFormattingProvider;
+    }
+    if (documentOnTypeFormattingProvider != null) {
+      __result['documentOnTypeFormattingProvider'] =
+          documentOnTypeFormattingProvider;
+    }
+    if (renameProvider != null) {
+      __result['renameProvider'] = renameProvider;
+    }
+    if (documentLinkProvider != null) {
+      __result['documentLinkProvider'] = documentLinkProvider;
+    }
+    if (executeCommandProvider != null) {
+      __result['executeCommandProvider'] = executeCommandProvider;
+    }
+    if (supported != null) {
+      __result['supported'] = supported;
+    }
+    if (changeNotifications != null) {
+      __result['changeNotifications'] = changeNotifications;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class ShowMessageParams implements ToJsonable {
+  ShowMessageParams(this.type, this.message) {
+    if (type == null) {
+      throw 'type is required but was not provided';
+    }
+    if (message == null) {
+      throw 'message is required but was not provided';
+    }
+  }
+  factory ShowMessageParams.fromJson(Map<String, dynamic> json) {
+    final type =
+        json['type'] != null ? new MessageType.fromJson(json['type']) : null;
+    final message = json['message'];
+    return new ShowMessageParams(type, message);
+  }
+
+  /// The actual message.
+  final String message;
+
+  /// The message type.
+  final MessageType type;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['type'] = type ?? (throw 'type is required but was not set');
+    __result['message'] =
+        message ?? (throw 'message is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('type') &&
+        MessageType.canParse(obj['type']) &&
+        obj.containsKey('message') &&
+        obj['message'] is String;
+  }
+}
+
+class ShowMessageRequestParams implements ToJsonable {
+  ShowMessageRequestParams(this.type, this.message, this.actions) {
+    if (type == null) {
+      throw 'type is required but was not provided';
+    }
+    if (message == null) {
+      throw 'message is required but was not provided';
+    }
+  }
+  factory ShowMessageRequestParams.fromJson(Map<String, dynamic> json) {
+    final type =
+        json['type'] != null ? new MessageType.fromJson(json['type']) : null;
+    final message = json['message'];
+    final actions = json['actions']
+        ?.map((item) =>
+            item != null ? new MessageActionItem.fromJson(item) : null)
+        ?.cast<MessageActionItem>()
+        ?.toList();
+    return new ShowMessageRequestParams(type, message, actions);
+  }
+
+  /// The message action items to present.
+  final List<MessageActionItem> actions;
+
+  /// The actual message
+  final String message;
+
+  /// The message type.
+  final MessageType type;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['type'] = type ?? (throw 'type is required but was not set');
+    __result['message'] =
+        message ?? (throw 'message is required but was not set');
+    if (actions != null) {
+      __result['actions'] = actions;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('type') &&
+        MessageType.canParse(obj['type']) &&
+        obj.containsKey('message') &&
+        obj['message'] is String;
+  }
+}
+
+/// Signature help represents the signature of something
+/// callable. There can be multiple signature but only one
+/// active and only one active parameter.
+class SignatureHelp implements ToJsonable {
+  SignatureHelp(this.signatures, this.activeSignature, this.activeParameter) {
+    if (signatures == null) {
+      throw 'signatures is required but was not provided';
+    }
+  }
+  factory SignatureHelp.fromJson(Map<String, dynamic> json) {
+    final signatures = json['signatures']
+        ?.map((item) =>
+            item != null ? new SignatureInformation.fromJson(item) : null)
+        ?.cast<SignatureInformation>()
+        ?.toList();
+    final activeSignature = json['activeSignature'];
+    final activeParameter = json['activeParameter'];
+    return new SignatureHelp(signatures, activeSignature, activeParameter);
+  }
+
+  /// The active parameter of the active signature. If
+  /// omitted or the value lies outside the range of
+  /// `signatures[activeSignature].parameters` defaults to
+  /// 0 if the active signature has parameters. If the
+  /// active signature has no parameters it is ignored. In
+  /// future version of the protocol this property might
+  /// become mandatory to better express the active
+  /// parameter if the active signature does have any.
+  final num activeParameter;
+
+  /// The active signature. If omitted or the value lies
+  /// outside the range of `signatures` the value defaults
+  /// to zero or is ignored if `signatures.length === 0`.
+  /// Whenever possible implementors should make an active
+  /// decision about the active signature and shouldn't
+  /// rely on a default value. In future version of the
+  /// protocol this property might become mandatory to
+  /// better express this.
+  final num activeSignature;
+
+  /// One or more signatures.
+  final List<SignatureInformation> signatures;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['signatures'] =
+        signatures ?? (throw 'signatures is required but was not set');
+    if (activeSignature != null) {
+      __result['activeSignature'] = activeSignature;
+    }
+    if (activeParameter != null) {
+      __result['activeParameter'] = activeParameter;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('signatures') &&
+        (obj['signatures'] is List &&
+            (obj['signatures'].length == 0 ||
+                obj['signatures']
+                    .every((item) => SignatureInformation.canParse(item))));
+  }
+}
+
+/// Signature help options.
+class SignatureHelpOptions implements ToJsonable {
+  SignatureHelpOptions(this.triggerCharacters);
+  factory SignatureHelpOptions.fromJson(Map<String, dynamic> json) {
+    final triggerCharacters = json['triggerCharacters']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
+    return new SignatureHelpOptions(triggerCharacters);
+  }
+
+  /// The characters that trigger signature help
+  /// automatically.
+  final List<String> triggerCharacters;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (triggerCharacters != null) {
+      __result['triggerCharacters'] = triggerCharacters;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class SignatureHelpRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  SignatureHelpRegistrationOptions(
+      this.triggerCharacters, this.documentSelector);
+  factory SignatureHelpRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final triggerCharacters = json['triggerCharacters']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new SignatureHelpRegistrationOptions(
+        triggerCharacters, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the
+  /// registration. If set to null the document selector
+  /// provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// The characters that trigger signature help
+  /// automatically.
+  final List<String> triggerCharacters;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (triggerCharacters != null) {
+      __result['triggerCharacters'] = triggerCharacters;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// Represents the signature of something callable. A
+/// signature can have a label, like a function-name, a
+/// doc-comment, and a set of parameters.
+class SignatureInformation implements ToJsonable {
+  SignatureInformation(this.label, this.documentation, this.parameters) {
+    if (label == null) {
+      throw 'label is required but was not provided';
+    }
+  }
+  factory SignatureInformation.fromJson(Map<String, dynamic> json) {
+    final label = json['label'];
+    final documentation = json['documentation'] is String
+        ? new Either2<String, MarkupContent>.t1(json['documentation'])
+        : (MarkupContent.canParse(json['documentation'])
+            ? new Either2<String, MarkupContent>.t2(
+                json['documentation'] != null
+                    ? new MarkupContent.fromJson(json['documentation'])
+                    : null)
+            : (throw '''${json['documentation']} was not one of (string, MarkupContent)'''));
+    final parameters = json['parameters']
+        ?.map((item) =>
+            item != null ? new ParameterInformation.fromJson(item) : null)
+        ?.cast<ParameterInformation>()
+        ?.toList();
+    return new SignatureInformation(label, documentation, parameters);
+  }
+
+  /// The human-readable doc-comment of this signature.
+  /// Will be shown in the UI but can be omitted.
+  final Either2<String, MarkupContent> documentation;
+
+  /// The label of this signature. Will be shown in the
+  /// UI.
+  final String label;
+
+  /// The parameters of this signature.
+  final List<ParameterInformation> parameters;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['label'] = label ?? (throw 'label is required but was not set');
+    if (documentation != null) {
+      __result['documentation'] = documentation;
+    }
+    if (parameters != null) {
+      __result['parameters'] = parameters;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('label') &&
+        obj['label'] is String;
+  }
+}
+
+/// Static registration options to be returned in the
+/// initialize request.
+class StaticRegistrationOptions implements ToJsonable {
+  StaticRegistrationOptions(this.id);
+  factory StaticRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final id = json['id'];
+    return new StaticRegistrationOptions(id);
+  }
+
+  /// The id used to register the request. The id can be
+  /// used to deregister the request again. See also
+  /// Registration#id.
+  final String id;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (id != null) {
+      __result['id'] = id;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// Represents information about programming constructs
+/// like variables, classes, interfaces etc.
+class SymbolInformation implements ToJsonable {
+  SymbolInformation(this.name, this.kind, this.deprecated, this.location,
+      this.containerName) {
+    if (name == null) {
+      throw 'name is required but was not provided';
+    }
+    if (kind == null) {
+      throw 'kind is required but was not provided';
+    }
+    if (location == null) {
+      throw 'location is required but was not provided';
+    }
+  }
+  factory SymbolInformation.fromJson(Map<String, dynamic> json) {
+    final name = json['name'];
+    final kind = json['kind'];
+    final deprecated = json['deprecated'];
+    final location = json['location'] != null
+        ? new Location.fromJson(json['location'])
+        : null;
+    final containerName = json['containerName'];
+    return new SymbolInformation(
+        name, kind, deprecated, location, containerName);
+  }
+
+  /// The name of the symbol containing this symbol. This
+  /// information is for user interface purposes (e.g. to
+  /// render a qualifier in the user interface if
+  /// necessary). It can't be used to re-infer a hierarchy
+  /// for the document symbols.
+  final String containerName;
+
+  /// Indicates if this symbol is deprecated.
+  final bool deprecated;
+
+  /// The kind of this symbol.
+  final num kind;
+
+  /// The location of this symbol. The location's range is
+  /// used by a tool to reveal the location in the editor.
+  /// If the symbol is selected in the tool the range's
+  /// start information is used to position the cursor. So
+  /// the range usually spans more then the actual
+  /// symbol's name and does normally include things like
+  /// visibility modifiers.
+  ///
+  /// The range doesn't have to denote a node range in the
+  /// sense of a abstract syntax tree. It can therefore
+  /// not be used to re-construct a hierarchy of the
+  /// symbols.
+  final Location location;
+
+  /// The name of this symbol.
+  final String name;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['name'] = name ?? (throw 'name is required but was not set');
+    __result['kind'] = kind ?? (throw 'kind is required but was not set');
+    if (deprecated != null) {
+      __result['deprecated'] = deprecated;
+    }
+    __result['location'] =
+        location ?? (throw 'location is required but was not set');
+    if (containerName != null) {
+      __result['containerName'] = containerName;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('name') &&
+        obj['name'] is String &&
+        obj.containsKey('kind') &&
+        obj['kind'] is num &&
+        obj.containsKey('location') &&
+        Location.canParse(obj['location']);
+  }
+}
+
+/// A symbol kind.
+class SymbolKind {
+  const SymbolKind._(this._value);
+  const SymbolKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+      case 9:
+      case 10:
+      case 11:
+      case 12:
+      case 13:
+      case 14:
+      case 15:
+      case 16:
+      case 17:
+      case 18:
+      case 19:
+      case 20:
+      case 21:
+      case 22:
+      case 23:
+      case 24:
+      case 25:
+      case 26:
+        return true;
+    }
+    return false;
+  }
+
+  static const File = const SymbolKind._(1);
+  static const Module = const SymbolKind._(2);
+  static const Namespace = const SymbolKind._(3);
+  static const Package = const SymbolKind._(4);
+  static const Class = const SymbolKind._(5);
+  static const Method = const SymbolKind._(6);
+  static const Property = const SymbolKind._(7);
+  static const Field = const SymbolKind._(8);
+  static const Constructor = const SymbolKind._(9);
+  static const Enum = const SymbolKind._(10);
+  static const Interface = const SymbolKind._(11);
+  static const Function = const SymbolKind._(12);
+  static const Variable = const SymbolKind._(13);
+  static const Constant = const SymbolKind._(14);
+  static const Str = const SymbolKind._(15);
+  static const Number = const SymbolKind._(16);
+  static const Boolean = const SymbolKind._(17);
+  static const Array = const SymbolKind._(18);
+  static const Obj = const SymbolKind._(19);
+  static const Key = const SymbolKind._(20);
+  static const Null = const SymbolKind._(21);
+  static const EnumMember = const SymbolKind._(22);
+  static const Struct = const SymbolKind._(23);
+  static const Event = const SymbolKind._(24);
+  static const Operator = const SymbolKind._(25);
+  static const TypeParameter = const SymbolKind._(26);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is SymbolKind && o._value == _value;
+}
+
+/// Describe options to be used when registering for
+/// text document change events.
+class TextDocumentChangeRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  TextDocumentChangeRegistrationOptions(this.syncKind, this.documentSelector) {
+    if (syncKind == null) {
+      throw 'syncKind is required but was not provided';
+    }
+  }
+  factory TextDocumentChangeRegistrationOptions.fromJson(
+      Map<String, dynamic> json) {
+    final syncKind = json['syncKind'];
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new TextDocumentChangeRegistrationOptions(
+        syncKind, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the
+  /// registration. If set to null the document selector
+  /// provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  /// How documents are synced to the server. See
+  /// TextDocumentSyncKind.Full and
+  /// TextDocumentSyncKind.Incremental.
+  final num syncKind;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['syncKind'] =
+        syncKind ?? (throw 'syncKind is required but was not set');
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('syncKind') &&
+        obj['syncKind'] is num &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// Text document specific client capabilities.
+class TextDocumentClientCapabilities implements ToJsonable {
+  TextDocumentClientCapabilities(this.dynamicRegistration, this.willSave,
+      this.willSaveWaitUntil, this.didSave);
+  factory TextDocumentClientCapabilities.fromJson(Map<String, dynamic> json) {
+    final dynamicRegistration = json['dynamicRegistration'];
+    final willSave = json['willSave'];
+    final willSaveWaitUntil = json['willSaveWaitUntil'];
+    final didSave = json['didSave'];
+    return new TextDocumentClientCapabilities(
+        dynamicRegistration, willSave, willSaveWaitUntil, didSave);
+  }
+
+  /// The client supports did save notifications.
+  final bool didSave;
+
+  /// Whether text document synchronization supports
+  /// dynamic registration.
+  final bool dynamicRegistration;
+
+  /// The client supports sending will save
+  /// notifications.
+  final bool willSave;
+
+  /// The client supports sending a will save request
+  /// and waits for a response providing text edits
+  /// which will be applied to the document before it is
+  /// saved.
+  final bool willSaveWaitUntil;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (dynamicRegistration != null) {
+      __result['dynamicRegistration'] = dynamicRegistration;
+    }
+    if (willSave != null) {
+      __result['willSave'] = willSave;
+    }
+    if (willSaveWaitUntil != null) {
+      __result['willSaveWaitUntil'] = willSaveWaitUntil;
+    }
+    if (didSave != null) {
+      __result['didSave'] = didSave;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+/// An event describing a change to a text document. If
+/// range and rangeLength are omitted the new text is
+/// considered to be the full content of the document.
+class TextDocumentContentChangeEvent implements ToJsonable {
+  TextDocumentContentChangeEvent(this.range, this.rangeLength, this.text) {
+    if (text == null) {
+      throw 'text is required but was not provided';
+    }
+  }
+  factory TextDocumentContentChangeEvent.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final rangeLength = json['rangeLength'];
+    final text = json['text'];
+    return new TextDocumentContentChangeEvent(range, rangeLength, text);
+  }
+
+  /// The range of the document that changed.
+  final Range range;
+
+  /// The length of the range that got replaced.
+  final num rangeLength;
+
+  /// The new text of the range/document.
+  final String text;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (range != null) {
+      __result['range'] = range;
+    }
+    if (rangeLength != null) {
+      __result['rangeLength'] = rangeLength;
+    }
+    __result['text'] = text ?? (throw 'text is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('text') &&
+        obj['text'] is String;
+  }
+}
+
+class TextDocumentEdit implements FileOperation, ToJsonable {
+  TextDocumentEdit(this.textDocument, this.edits) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (edits == null) {
+      throw 'edits is required but was not provided';
+    }
+  }
+  factory TextDocumentEdit.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new VersionedTextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final edits = json['edits']
+        ?.map((item) => item != null ? new TextEdit.fromJson(item) : null)
+        ?.cast<TextEdit>()
+        ?.toList();
+    return new TextDocumentEdit(textDocument, edits);
+  }
+
+  /// The edits to be applied.
+  final List<TextEdit> edits;
+
+  /// The text document to change.
+  final VersionedTextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['edits'] = edits ?? (throw 'edits is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        VersionedTextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('edits') &&
+        (obj['edits'] is List &&
+            (obj['edits'].length == 0 ||
+                obj['edits'].every((item) => TextEdit.canParse(item))));
+  }
+}
+
+class TextDocumentIdentifier implements ToJsonable {
+  TextDocumentIdentifier(this.uri) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+  }
+  factory TextDocumentIdentifier.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    return new TextDocumentIdentifier(uri);
+  }
+
+  /// The text document's URI.
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String;
+  }
+}
+
+class TextDocumentItem implements ToJsonable {
+  TextDocumentItem(this.uri, this.languageId, this.version, this.text) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+    if (languageId == null) {
+      throw 'languageId is required but was not provided';
+    }
+    if (version == null) {
+      throw 'version is required but was not provided';
+    }
+    if (text == null) {
+      throw 'text is required but was not provided';
+    }
+  }
+  factory TextDocumentItem.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final languageId = json['languageId'];
+    final version = json['version'];
+    final text = json['text'];
+    return new TextDocumentItem(uri, languageId, version, text);
+  }
+
+  /// The text document's language identifier.
+  final String languageId;
+
+  /// The content of the opened text document.
+  final String text;
+
+  /// The text document's URI.
+  final String uri;
+
+  /// The version number of this document (it will
+  /// increase after each change, including undo/redo).
+  final num version;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    __result['languageId'] =
+        languageId ?? (throw 'languageId is required but was not set');
+    __result['version'] =
+        version ?? (throw 'version is required but was not set');
+    __result['text'] = text ?? (throw 'text is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String &&
+        obj.containsKey('languageId') &&
+        obj['languageId'] is String &&
+        obj.containsKey('version') &&
+        obj['version'] is num &&
+        obj.containsKey('text') &&
+        obj['text'] is String;
+  }
+}
+
+class TextDocumentPositionParams implements ToJsonable {
+  TextDocumentPositionParams(this.textDocument, this.position) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (position == null) {
+      throw 'position is required but was not provided';
+    }
+  }
+  factory TextDocumentPositionParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final position = json['position'] != null
+        ? new Position.fromJson(json['position'])
+        : null;
+    return new TextDocumentPositionParams(textDocument, position);
+  }
+
+  /// The position inside the text document.
+  final Position position;
+
+  /// The text document.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['position'] =
+        position ?? (throw 'position is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('position') &&
+        Position.canParse(obj['position']);
+  }
+}
+
+class TextDocumentRegistrationOptions implements ToJsonable {
+  TextDocumentRegistrationOptions(this.documentSelector);
+  factory TextDocumentRegistrationOptions.fromJson(Map<String, dynamic> json) {
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new TextDocumentRegistrationOptions(documentSelector);
+  }
+
+  /// A document selector to identify the scope of the
+  /// registration. If set to null the document selector
+  /// provided on the client side will be used.
+  final List<DocumentFilter> documentSelector;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// Represents reasons why a text document is saved.
+class TextDocumentSaveReason {
+  const TextDocumentSaveReason._(this._value);
+  const TextDocumentSaveReason.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 3:
+        return true;
+    }
+    return false;
+  }
+
+  /// Manually triggered, e.g. by the user pressing
+  /// save, by starting debugging, or by an API call.
+  static const Manual = const TextDocumentSaveReason._(1);
+
+  /// Automatic after a delay.
+  static const AfterDelay = const TextDocumentSaveReason._(2);
+
+  /// When the editor lost focus.
+  static const FocusOut = const TextDocumentSaveReason._(3);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is TextDocumentSaveReason && o._value == _value;
+}
+
+class TextDocumentSaveRegistrationOptions
+    implements TextDocumentRegistrationOptions, ToJsonable {
+  TextDocumentSaveRegistrationOptions(this.includeText, this.documentSelector);
+  factory TextDocumentSaveRegistrationOptions.fromJson(
+      Map<String, dynamic> json) {
+    final includeText = json['includeText'];
+    final documentSelector = json['documentSelector']
+        ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+        ?.cast<DocumentFilter>()
+        ?.toList();
+    return new TextDocumentSaveRegistrationOptions(
+        includeText, documentSelector);
+  }
+
+  /// A document selector to identify the scope of the
+  /// registration. If set to null the document
+  /// selector provided on the client side will be
+  /// used.
+  final List<DocumentFilter> documentSelector;
+
+  /// The client is supposed to include the content on
+  /// save.
+  final bool includeText;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (includeText != null) {
+      __result['includeText'] = includeText;
+    }
+    __result['documentSelector'] = documentSelector;
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('documentSelector') &&
+        (obj['documentSelector'] is List &&
+            (obj['documentSelector'].length == 0 ||
+                obj['documentSelector']
+                    .every((item) => DocumentFilter.canParse(item))));
+  }
+}
+
+/// Defines how the host (editor) should sync document
+/// changes to the language server.
+class TextDocumentSyncKind {
+  const TextDocumentSyncKind._(this._value);
+  const TextDocumentSyncKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 0:
+      case 1:
+      case 2:
+        return true;
+    }
+    return false;
+  }
+
+  /// Documents should not be synced at all.
+  static const None = const TextDocumentSyncKind._(0);
+
+  /// Documents are synced by always sending the
+  /// full content of the document.
+  static const Full = const TextDocumentSyncKind._(1);
+
+  /// Documents are synced by sending the full
+  /// content on open. After that only incremental
+  /// updates to the document are send.
+  static const Incremental = const TextDocumentSyncKind._(2);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is TextDocumentSyncKind && o._value == _value;
+}
+
+class TextDocumentSyncOptions implements ToJsonable {
+  TextDocumentSyncOptions(this.openClose, this.change, this.willSave,
+      this.willSaveWaitUntil, this.save);
+  factory TextDocumentSyncOptions.fromJson(Map<String, dynamic> json) {
+    final openClose = json['openClose'];
+    final change = json['change'] != null
+        ? new TextDocumentSyncKind.fromJson(json['change'])
+        : null;
+    final willSave = json['willSave'];
+    final willSaveWaitUntil = json['willSaveWaitUntil'];
+    final save =
+        json['save'] != null ? new SaveOptions.fromJson(json['save']) : null;
+    return new TextDocumentSyncOptions(
+        openClose, change, willSave, willSaveWaitUntil, save);
+  }
+
+  /// Change notifications are sent to the server.
+  /// See TextDocumentSyncKind.None,
+  /// TextDocumentSyncKind.Full and
+  /// TextDocumentSyncKind.Incremental. If omitted
+  /// it defaults to TextDocumentSyncKind.None.
+  final TextDocumentSyncKind change;
+
+  /// Open and close notifications are sent to the
+  /// server.
+  final bool openClose;
+
+  /// Save notifications are sent to the server.
+  final SaveOptions save;
+
+  /// Will save notifications are sent to the
+  /// server.
+  final bool willSave;
+
+  /// Will save wait until requests are sent to the
+  /// server.
+  final bool willSaveWaitUntil;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (openClose != null) {
+      __result['openClose'] = openClose;
+    }
+    if (change != null) {
+      __result['change'] = change;
+    }
+    if (willSave != null) {
+      __result['willSave'] = willSave;
+    }
+    if (willSaveWaitUntil != null) {
+      __result['willSaveWaitUntil'] = willSaveWaitUntil;
+    }
+    if (save != null) {
+      __result['save'] = save;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class TextEdit implements ToJsonable {
+  TextEdit(this.range, this.newText) {
+    if (range == null) {
+      throw 'range is required but was not provided';
+    }
+    if (newText == null) {
+      throw 'newText is required but was not provided';
+    }
+  }
+  factory TextEdit.fromJson(Map<String, dynamic> json) {
+    final range =
+        json['range'] != null ? new Range.fromJson(json['range']) : null;
+    final newText = json['newText'];
+    return new TextEdit(range, newText);
+  }
+
+  /// The string to be inserted. For delete
+  /// operations use an empty string.
+  final String newText;
+
+  /// The range of the text document to be
+  /// manipulated. To insert text into a document
+  /// create a range where start === end.
+  final Range range;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['range'] = range ?? (throw 'range is required but was not set');
+    __result['newText'] =
+        newText ?? (throw 'newText is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('range') &&
+        Range.canParse(obj['range']) &&
+        obj.containsKey('newText') &&
+        obj['newText'] is String;
+  }
+}
+
+/// General parameters to unregister a capability.
+class Unregistration implements ToJsonable {
+  Unregistration(this.id, this.method) {
+    if (id == null) {
+      throw 'id is required but was not provided';
+    }
+    if (method == null) {
+      throw 'method is required but was not provided';
+    }
+  }
+  factory Unregistration.fromJson(Map<String, dynamic> json) {
+    final id = json['id'];
+    final method = json['method'];
+    return new Unregistration(id, method);
+  }
+
+  /// The id used to unregister the request or
+  /// notification. Usually an id provided during
+  /// the register request.
+  final String id;
+
+  /// The method / capability to unregister for.
+  final String method;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['id'] = id ?? (throw 'id is required but was not set');
+    __result['method'] = method ?? (throw 'method is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('id') &&
+        obj['id'] is String &&
+        obj.containsKey('method') &&
+        obj['method'] is String;
+  }
+}
+
+class UnregistrationParams implements ToJsonable {
+  UnregistrationParams(this.unregisterations) {
+    if (unregisterations == null) {
+      throw 'unregisterations is required but was not provided';
+    }
+  }
+  factory UnregistrationParams.fromJson(Map<String, dynamic> json) {
+    final unregisterations = json['unregisterations']
+        ?.map((item) => item != null ? new Unregistration.fromJson(item) : null)
+        ?.cast<Unregistration>()
+        ?.toList();
+    return new UnregistrationParams(unregisterations);
+  }
+
+  final List<Unregistration> unregisterations;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['unregisterations'] = unregisterations ??
+        (throw 'unregisterations is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('unregisterations') &&
+        (obj['unregisterations'] is List &&
+            (obj['unregisterations'].length == 0 ||
+                obj['unregisterations']
+                    .every((item) => Unregistration.canParse(item))));
+  }
+}
+
+class VersionedTextDocumentIdentifier
+    implements TextDocumentIdentifier, ToJsonable {
+  VersionedTextDocumentIdentifier(this.version, this.uri) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+  }
+  factory VersionedTextDocumentIdentifier.fromJson(Map<String, dynamic> json) {
+    final version = json['version'];
+    final uri = json['uri'];
+    return new VersionedTextDocumentIdentifier(version, uri);
+  }
+
+  /// The text document's URI.
+  final String uri;
+
+  /// The version number of this document. If a
+  /// versioned text document identifier is sent
+  /// from the server to the client and the file is
+  /// not open in the editor (the server has not
+  /// received an open notification before) the
+  /// server can send `null` to indicate that the
+  /// version is known and the content on disk is
+  /// the truth (as speced with document content
+  /// ownership).
+  ///
+  /// The version number of a document will increase
+  /// after each change, including undo/redo. The
+  /// number doesn't need to be consecutive.
+  final num version;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['version'] = version;
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('version') &&
+        obj['version'] is num &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String;
+  }
+}
+
+class WatchKind {
+  const WatchKind._(this._value);
+  const WatchKind.fromJson(this._value);
+
+  final Object _value;
+
+  static bool canParse(Object obj) {
+    switch (obj) {
+      case 1:
+      case 2:
+      case 4:
+        return true;
+    }
+    return false;
+  }
+
+  /// Interested in create events.
+  static const Create = const WatchKind._(1);
+
+  /// Interested in change events
+  static const Change = const WatchKind._(2);
+
+  /// Interested in delete events
+  static const Delete = const WatchKind._(4);
+
+  Object toJson() => _value;
+
+  @override
+  String toString() => _value.toString();
+
+  @override
+  get hashCode => _value.hashCode;
+
+  bool operator ==(o) => o is WatchKind && o._value == _value;
+}
+
+/// The parameters send in a will save text
+/// document notification.
+class WillSaveTextDocumentParams implements ToJsonable {
+  WillSaveTextDocumentParams(this.textDocument, this.reason) {
+    if (textDocument == null) {
+      throw 'textDocument is required but was not provided';
+    }
+    if (reason == null) {
+      throw 'reason is required but was not provided';
+    }
+  }
+  factory WillSaveTextDocumentParams.fromJson(Map<String, dynamic> json) {
+    final textDocument = json['textDocument'] != null
+        ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+        : null;
+    final reason = json['reason'];
+    return new WillSaveTextDocumentParams(textDocument, reason);
+  }
+
+  /// The 'TextDocumentSaveReason'.
+  final num reason;
+
+  /// The document that will be saved.
+  final TextDocumentIdentifier textDocument;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['textDocument'] =
+        textDocument ?? (throw 'textDocument is required but was not set');
+    __result['reason'] = reason ?? (throw 'reason is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('textDocument') &&
+        TextDocumentIdentifier.canParse(obj['textDocument']) &&
+        obj.containsKey('reason') &&
+        obj['reason'] is num;
+  }
+}
+
+/// Workspace specific client capabilities.
+class WorkspaceClientCapabilities implements ToJsonable {
+  WorkspaceClientCapabilities(this.applyEdit, this.documentChanges,
+      this.resourceOperations, this.failureHandling);
+  factory WorkspaceClientCapabilities.fromJson(Map<String, dynamic> json) {
+    final applyEdit = json['applyEdit'];
+    final documentChanges = json['documentChanges'];
+    final resourceOperations = json['resourceOperations']
+        ?.map((item) =>
+            item != null ? new ResourceOperationKind.fromJson(item) : null)
+        ?.cast<ResourceOperationKind>()
+        ?.toList();
+    final failureHandling = json['failureHandling'] != null
+        ? new FailureHandlingKind.fromJson(json['failureHandling'])
+        : null;
+    return new WorkspaceClientCapabilities(
+        applyEdit, documentChanges, resourceOperations, failureHandling);
+  }
+
+  /// The client supports applying batch edits to
+  /// the workspace by supporting the request
+  /// 'workspace/applyEdit'
+  final bool applyEdit;
+
+  /// The client supports versioned document
+  /// changes in `WorkspaceEdit`s
+  final bool documentChanges;
+
+  /// The failure handling strategy of a client if
+  /// applying the workspace edit failes.
+  final FailureHandlingKind failureHandling;
+
+  /// The resource operations the client supports.
+  /// Clients should at least support 'create',
+  /// 'rename' and 'delete' files and folders.
+  final List<ResourceOperationKind> resourceOperations;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (applyEdit != null) {
+      __result['applyEdit'] = applyEdit;
+    }
+    if (documentChanges != null) {
+      __result['documentChanges'] = documentChanges;
+    }
+    if (resourceOperations != null) {
+      __result['resourceOperations'] = resourceOperations;
+    }
+    if (failureHandling != null) {
+      __result['failureHandling'] = failureHandling;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class WorkspaceEdit implements ToJsonable {
+  WorkspaceEdit(this.changes, this.documentChanges);
+  factory WorkspaceEdit.fromJson(Map<String, dynamic> json) {
+    final changes = json['changes'];
+    final documentChanges = json['documentChanges']
+        ?.map((item) => item)
+        ?.cast<FileOperation>()
+        ?.toList();
+    return new WorkspaceEdit(changes, documentChanges);
+  }
+
+  /// Holds changes to existing resources.
+  final Map<String, List<TextEdit>> changes;
+
+  /// Depending on the client capability
+  /// `workspace.workspaceEdit.resourceOperations`
+  /// document changes are either an array of
+  /// `TextDocumentEdit`s to express changes to n
+  /// different text documents where each text
+  /// document edit addresses a specific version
+  /// of a text document. Or it can contain above
+  /// `TextDocumentEdit`s mixed with create,
+  /// rename and delete file / folder operations.
+  ///
+  /// Whether a client supports versioned document
+  /// edits is expressed via
+  /// `workspace.workspaceEdit.documentChanges`
+  /// client capability.
+  ///
+  /// If a client neither supports
+  /// `documentChanges` nor
+  /// `workspace.workspaceEdit.resourceOperations`
+  /// then only plain `TextEdit`s using the
+  /// `changes` property are supported.
+  final List<FileOperation> documentChanges;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    if (changes != null) {
+      __result['changes'] = changes;
+    }
+    if (documentChanges != null) {
+      __result['documentChanges'] = documentChanges;
+    }
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic>;
+  }
+}
+
+class WorkspaceFolder implements ToJsonable {
+  WorkspaceFolder(this.uri, this.name) {
+    if (uri == null) {
+      throw 'uri is required but was not provided';
+    }
+    if (name == null) {
+      throw 'name is required but was not provided';
+    }
+  }
+  factory WorkspaceFolder.fromJson(Map<String, dynamic> json) {
+    final uri = json['uri'];
+    final name = json['name'];
+    return new WorkspaceFolder(uri, name);
+  }
+
+  /// The name of the workspace folder. Defaults
+  /// to the uri's basename.
+  final String name;
+
+  /// The associated URI for this workspace
+  /// folder.
+  final String uri;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['uri'] = uri ?? (throw 'uri is required but was not set');
+    __result['name'] = name ?? (throw 'name is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('uri') &&
+        obj['uri'] is String &&
+        obj.containsKey('name') &&
+        obj['name'] is String;
+  }
+}
+
+/// The workspace folder change event.
+class WorkspaceFoldersChangeEvent implements ToJsonable {
+  WorkspaceFoldersChangeEvent(this.added, this.removed) {
+    if (added == null) {
+      throw 'added is required but was not provided';
+    }
+    if (removed == null) {
+      throw 'removed is required but was not provided';
+    }
+  }
+  factory WorkspaceFoldersChangeEvent.fromJson(Map<String, dynamic> json) {
+    final added = json['added']
+        ?.map(
+            (item) => item != null ? new WorkspaceFolder.fromJson(item) : null)
+        ?.cast<WorkspaceFolder>()
+        ?.toList();
+    final removed = json['removed']
+        ?.map(
+            (item) => item != null ? new WorkspaceFolder.fromJson(item) : null)
+        ?.cast<WorkspaceFolder>()
+        ?.toList();
+    return new WorkspaceFoldersChangeEvent(added, removed);
+  }
+
+  /// The array of added workspace folders
+  final List<WorkspaceFolder> added;
+
+  /// The array of the removed workspace folders
+  final List<WorkspaceFolder> removed;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['added'] = added ?? (throw 'added is required but was not set');
+    __result['removed'] =
+        removed ?? (throw 'removed is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('added') &&
+        (obj['added'] is List &&
+            (obj['added'].length == 0 ||
+                obj['added']
+                    .every((item) => WorkspaceFolder.canParse(item)))) &&
+        obj.containsKey('removed') &&
+        (obj['removed'] is List &&
+            (obj['removed'].length == 0 ||
+                obj['removed']
+                    .every((item) => WorkspaceFolder.canParse(item))));
+  }
+}
+
+/// The parameters of a Workspace Symbol Request.
+class WorkspaceSymbolParams implements ToJsonable {
+  WorkspaceSymbolParams(this.query) {
+    if (query == null) {
+      throw 'query is required but was not provided';
+    }
+  }
+  factory WorkspaceSymbolParams.fromJson(Map<String, dynamic> json) {
+    final query = json['query'];
+    return new WorkspaceSymbolParams(query);
+  }
+
+  /// A non-empty query string
+  final String query;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['query'] = query ?? (throw 'query is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('query') &&
+        obj['query'] is String;
+  }
+}
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
new file mode 100644
index 0000000..35ae774
--- /dev/null
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+Object id(Object obj) => obj;
+
+Object specToJson(Object obj) {
+  if (obj is ToJsonable) {
+    return obj.toJson();
+  } else {
+    return obj;
+  }
+}
+
+class Either2<T1, T2> {
+  final int _which;
+  final T1 _t1;
+  final T2 _t2;
+
+  Either2.t1(this._t1)
+      : _t2 = null,
+        _which = 1;
+  Either2.t2(this._t2)
+      : _t1 = null,
+        _which = 2;
+
+  @override
+  get hashCode => map((t) => t.hashCode, (t) => t.hashCode);
+
+  bool operator ==(o) => o is Either2<T1, T2> && o._t1 == _t1 && o._t2 == _t2;
+
+  T map<T>(T Function(T1) f1, T Function(T2) f2) {
+    return _which == 1 ? f1(_t1) : f2(_t2);
+  }
+
+  Object toJson() => map(specToJson, specToJson);
+
+  /// Checks whether the value of the union equals the supplied value.
+  bool valueEquals(o) => map((t) => t == o, (t) => t == o);
+}
+
+class Either3<T1, T2, T3> {
+  final int _which;
+  final T1 _t1;
+  final T2 _t2;
+  final T3 _t3;
+
+  Either3.t1(this._t1)
+      : _t2 = null,
+        _t3 = null,
+        _which = 1;
+  Either3.t2(this._t2)
+      : _t1 = null,
+        _t3 = null,
+        _which = 2;
+  Either3.t3(this._t3)
+      : _t1 = null,
+        _t2 = null,
+        _which = 3;
+
+  @override
+  get hashCode => map((t) => t.hashCode, (t) => t.hashCode, (t) => t.hashCode);
+
+  bool operator ==(o) =>
+      o is Either3<T1, T2, T3> && o._t1 == _t1 && o._t2 == _t2 && o._t3 == _t3;
+
+  T map<T>(T Function(T1) f1, T Function(T2) f2, T Function(T3) f3) {
+    switch (_which) {
+      case 1:
+        return f1(_t1);
+      case 2:
+        return f2(_t2);
+      case 3:
+        return f3(_t3);
+      default:
+        throw 'Invalid state.';
+    }
+  }
+
+  Object toJson() => map(specToJson, specToJson, specToJson);
+
+  /// Checks whether the value of the union equals the supplied value.
+  bool valueEquals(o) => map((t) => t == o, (t) => t == o, (t) => t == o);
+}
+
+class Either4<T1, T2, T3, T4> {
+  final int _which;
+  final T1 _t1;
+  final T2 _t2;
+  final T3 _t3;
+  final T4 _t4;
+
+  Either4.t1(this._t1)
+      : _t2 = null,
+        _t3 = null,
+        _t4 = null,
+        _which = 1;
+  Either4.t2(this._t2)
+      : _t1 = null,
+        _t3 = null,
+        _t4 = null,
+        _which = 2;
+  Either4.t3(this._t3)
+      : _t1 = null,
+        _t2 = null,
+        _t4 = null,
+        _which = 3;
+  Either4.t4(this._t4)
+      : _t1 = null,
+        _t2 = null,
+        _t3 = null,
+        _which = 4;
+
+  @override
+  get hashCode => map((t) => t.hashCode, (t) => t.hashCode, (t) => t.hashCode,
+      (t) => t.hashCode);
+
+  bool operator ==(o) =>
+      o is Either4<T1, T2, T3, T4> &&
+      o._t1 == _t1 &&
+      o._t2 == _t2 &&
+      o._t3 == _t3 &&
+      o._t4 == _t4;
+
+  T map<T>(T Function(T1) f1, T Function(T2) f2, T Function(T3) f3,
+      T Function(T4) f4) {
+    switch (_which) {
+      case 1:
+        return f1(_t1);
+      case 2:
+        return f2(_t2);
+      case 3:
+        return f3(_t3);
+      case 4:
+        return f4(_t4);
+      default:
+        throw 'Invalid state.';
+    }
+  }
+
+  Object toJson() => map(specToJson, specToJson, specToJson, specToJson);
+
+  /// Checks whether the value of the union equals the supplied value.
+  bool valueEquals(o) =>
+      map((t) => t == o, (t) => t == o, (t) => t == o, (t) => t == o);
+}
+
+class FileOperation {}
+
+abstract class ToJsonable {
+  Object toJson();
+}
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
index e203b4a..af303ec 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
@@ -24,7 +24,9 @@
    */
   static final Comparator<Fix> SORT_BY_RELEVANCE = (Fix a, Fix b) {
     if (a.kind.priority != b.kind.priority) {
-      return a.kind.priority - b.kind.priority;
+      // A higher priority indicates a higher relevance
+      // and should be sorted before a lower priority.
+      return b.kind.priority - a.kind.priority;
     }
     return a.change.message.compareTo(b.change.message);
   };
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 51eeee6..9d85d08 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
-// This file has been automatically generated.  Please do not edit it manually.
+// This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 5930a94..cb7d946 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
-// This file has been automatically generated.  Please do not edit it manually.
+// This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
@@ -2017,8 +2017,8 @@
  *
  * {
  *   "name": String
- *   "dartdoc": optional String
  *   "parameters": List<ParameterInfo>
+ *   "dartdoc": optional String
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -2026,10 +2026,10 @@
 class AnalysisGetSignatureResult implements ResponseResult {
   String _name;
 
-  String _dartdoc;
-
   List<ParameterInfo> _parameters;
 
+  String _dartdoc;
+
   /**
    * The name of the function being invoked at the given offset.
    */
@@ -2044,6 +2044,21 @@
   }
 
   /**
+   * A list of information about each of the parameters of the function being
+   * invoked.
+   */
+  List<ParameterInfo> get parameters => _parameters;
+
+  /**
+   * A list of information about each of the parameters of the function being
+   * invoked.
+   */
+  void set parameters(List<ParameterInfo> value) {
+    assert(value != null);
+    this._parameters = value;
+  }
+
+  /**
    * The dartdoc associated with the function being invoked. Other than the
    * removal of the comment delimiters, including leading asterisks in the case
    * of a block comment, the dartdoc is unprocessed markdown. This data is
@@ -2063,26 +2078,11 @@
     this._dartdoc = value;
   }
 
-  /**
-   * A list of information about each of the parameters of the function being
-   * invoked.
-   */
-  List<ParameterInfo> get parameters => _parameters;
-
-  /**
-   * A list of information about each of the parameters of the function being
-   * invoked.
-   */
-  void set parameters(List<ParameterInfo> value) {
-    assert(value != null);
-    this._parameters = value;
-  }
-
   AnalysisGetSignatureResult(String name, List<ParameterInfo> parameters,
       {String dartdoc}) {
     this.name = name;
-    this.dartdoc = dartdoc;
     this.parameters = parameters;
+    this.dartdoc = dartdoc;
   }
 
   factory AnalysisGetSignatureResult.fromJson(
@@ -2097,11 +2097,6 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "name");
       }
-      String dartdoc;
-      if (json.containsKey("dartdoc")) {
-        dartdoc =
-            jsonDecoder.decodeString(jsonPath + ".dartdoc", json["dartdoc"]);
-      }
       List<ParameterInfo> parameters;
       if (json.containsKey("parameters")) {
         parameters = jsonDecoder.decodeList(
@@ -2112,6 +2107,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "parameters");
       }
+      String dartdoc;
+      if (json.containsKey("dartdoc")) {
+        dartdoc =
+            jsonDecoder.decodeString(jsonPath + ".dartdoc", json["dartdoc"]);
+      }
       return new AnalysisGetSignatureResult(name, parameters, dartdoc: dartdoc);
     } else {
       throw jsonDecoder.mismatch(
@@ -2130,11 +2130,11 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["name"] = name;
+    result["parameters"] =
+        parameters.map((ParameterInfo value) => value.toJson()).toList();
     if (dartdoc != null) {
       result["dartdoc"] = dartdoc;
     }
-    result["parameters"] =
-        parameters.map((ParameterInfo value) => value.toJson()).toList();
     return result;
   }
 
@@ -2150,9 +2150,9 @@
   bool operator ==(other) {
     if (other is AnalysisGetSignatureResult) {
       return name == other.name &&
-          dartdoc == other.dartdoc &&
           listEqual(parameters, other.parameters,
-              (ParameterInfo a, ParameterInfo b) => a == b);
+              (ParameterInfo a, ParameterInfo b) => a == b) &&
+          dartdoc == other.dartdoc;
     }
     return false;
   }
@@ -2161,8 +2161,8 @@
   int get hashCode {
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
-    hash = JenkinsSmiHash.combine(hash, dartdoc.hashCode);
     hash = JenkinsSmiHash.combine(hash, parameters.hashCode);
+    hash = JenkinsSmiHash.combine(hash, dartdoc.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index bdd5194..715570c 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -54,8 +54,12 @@
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
+import 'package:analyzer/src/dart/analysis/file_byte_store.dart'
+    show EvictingFileByteStore;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/ast_provider.dart';
@@ -68,10 +72,6 @@
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/file_byte_store.dart'
-    show EvictingFileByteStore;
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:telemetry/crash_reporting.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
 import 'package:watcher/watcher.dart';
@@ -560,7 +560,7 @@
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     if (!priorityFiles.contains(file)) {
-      var driver = await getAnalysisDriver(file);
+      var driver = getAnalysisDriver(file);
       if (driver == null) {
         return null;
       }
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index ae19037..a3e3257 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -518,11 +518,6 @@
         options.lint = newOptions.generateLints;
       });
     }
-    if (newOptions.enableSuperMixins != null) {
-      updaters.add((engine.AnalysisOptionsImpl options) {
-        options.enableSuperMixins = newOptions.enableSuperMixins;
-      });
-    }
     server.updateOptions(updaters);
     return new AnalysisUpdateOptionsResult().toResponse(request.id);
   }
diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart
index 4b7447d..c4fceb6 100644
--- a/pkg/analysis_server/lib/src/domain_kythe.dart
+++ b/pkg/analysis_server/lib/src/domain_kythe.dart
@@ -15,7 +15,8 @@
 import 'package:analysis_server/src/services/kythe/kythe_visitors.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
@@ -57,6 +58,7 @@
           <KytheGetKytheEntriesResult>[];
       AnalysisResult result = await server.getAnalysisResult(file);
       CompilationUnit unit = result?.unit;
+      TypeSystem typeSystem = result.libraryElement.context.typeSystem;
       if (unit != null && result.exists) {
         List<KytheEntry> entries = <KytheEntry>[];
         // TODO(brianwilkerson) Figure out how to get the list of files.
@@ -65,7 +67,7 @@
             server.resourceProvider,
             entries,
             file,
-            new InheritanceManager(result.libraryElement),
+            new InheritanceManager2(typeSystem),
             result.content));
         allResults.add(new KytheGetKytheEntriesResult(entries, files));
       }
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index fc1139a..3a8e344 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -2,25 +2,29 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
 import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/services/correction/assist.dart';
-import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analysis_server/src/edit/fix/prefer_int_literals_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/linter_visitor.dart';
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show SourceChange, SourceEdit, SourceFileEdit;
-import 'package:analyzer/src/generated/source.dart';
+import 'package:front_end/src/fasta/fasta_codes.dart';
 import 'package:front_end/src/scanner/token.dart';
 import 'package:source_span/src/span.dart';
 
@@ -55,15 +59,15 @@
     // Validate each included file and directory.
     final resourceProvider = server.resourceProvider;
     final contextManager = server.contextManager;
-    for (String path in params.included) {
-      if (!server.isValidFilePath(path)) {
-        return new Response.invalidFilePathFormat(request, path);
+    for (String filePath in params.included) {
+      if (!server.isValidFilePath(filePath)) {
+        return new Response.invalidFilePathFormat(request, filePath);
       }
-      Resource res = resourceProvider.getResource(path);
+      Resource res = resourceProvider.getResource(filePath);
       if (!res.exists ||
-          !(contextManager.includedPaths.contains(path) ||
-              contextManager.isInAnalysisRoot(path))) {
-        return new Response.fileNotAnalyzed(request, path);
+          !(contextManager.includedPaths.contains(filePath) ||
+              contextManager.isInAnalysisRoot(filePath))) {
+        return new Response.fileNotAnalyzed(request, filePath);
       }
       if (res is Folder) {
         fixFolders.add(res);
@@ -73,30 +77,36 @@
     }
 
     // Get the desired lints
-    final LintRule preferMixin = Registry.ruleRegistry['prefer_mixin'];
-    if (preferMixin == null) {
-      return new Response.serverError(
-          request, 'Missing prefer_mixin lint', null);
-    }
+    final lintRules = Registry.ruleRegistry;
+
+    final preferMixin = lintRules['prefer_mixin'];
     final preferMixinFix = new PreferMixinFix(this);
     preferMixin.reporter = preferMixinFix;
 
+    final preferIntLiterals = lintRules['prefer_int_literals'];
+    final preferIntLiteralsFix = new PreferIntLiteralsFix(this);
+    preferIntLiterals?.reporter = preferIntLiteralsFix;
+
     // Setup
     final linters = <Linter>[
       preferMixin,
+      preferIntLiterals,
     ];
     final fixes = <LinterFix>[
       preferMixinFix,
+      preferIntLiteralsFix,
     ];
     final visitors = <AstVisitor>[];
     final registry = new NodeLintRegistry(false);
     for (Linter linter in linters) {
-      final visitor = linter.getVisitor();
-      if (visitor != null) {
-        visitors.add(visitor);
-      }
-      if (linter is NodeLintRule) {
-        (linter as NodeLintRule).registerNodeProcessors(registry);
+      if (linter != null) {
+        final visitor = linter.getVisitor();
+        if (visitor != null) {
+          visitors.add(visitor);
+        }
+        if (linter is NodeLintRule) {
+          (linter as NodeLintRule).registerNodeProcessors(registry);
+        }
       }
     }
     final AstVisitor astVisitor = visitors.isNotEmpty
@@ -115,6 +125,9 @@
     for (String rootPath in contextManager.includedPaths) {
       resources.add(resourceProvider.getResource(rootPath));
     }
+    descriptionOfFixes = <String>[];
+    otherRecommendations = <String>[];
+    sourceChange = new SourceChange('dartfix');
     bool hasErrors = false;
     while (resources.isNotEmpty) {
       Resource res = resources.removeLast();
@@ -132,57 +145,125 @@
       if (unit != null) {
         if (!hasErrors) {
           for (AnalysisError error in result.errors) {
-            if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
-              hasErrors = true;
-              break;
+            if (!(await fixError(result, error))) {
+              if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
+                hasErrors = true;
+              }
             }
           }
         }
         Source source = result.sourceFactory.forUri2(result.uri);
         for (Linter linter in linters) {
-          linter.reporter.source = source;
+          if (linter != null) {
+            linter.reporter.source = source;
+          }
         }
         if (astVisitor != null) {
           unit.accept(astVisitor);
         }
         unit.accept(linterVisitor);
+        for (LinterFix fix in fixes) {
+          await fix.applyLocalFixes(result);
+        }
       }
     }
 
     // Cleanup
     for (Linter linter in linters) {
-      linter.reporter = null;
+      if (linter != null) {
+        linter.reporter.source = null;
+        linter.reporter = null;
+      }
     }
 
-    // Reporting
-    descriptionOfFixes = <String>[];
-    otherRecommendations = <String>[];
-    sourceChange = new SourceChange('dartfix');
-    for (LinterFix fix in fixes) {
-      await fix.applyFix();
+    // Apply distributed fixes
+    if (preferIntLiterals == null) {
+      // TODO(danrubel): Remove this once linter rolled into sdk/third_party.
+      addRecommendation('*** Convert double literal not available'
+          ' because prefer_int_literal not found. May need to roll linter');
     }
+    for (LinterFix fix in fixes) {
+      await fix.applyRemainingFixes();
+    }
+
     return new EditDartfixResult(descriptionOfFixes, otherRecommendations,
             hasErrors, sourceChange.edits)
         .toResponse(request.id);
   }
 
+  Future<bool> fixError(AnalysisResult result, AnalysisError error) async {
+    if (error.errorCode ==
+        StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR) {
+      // TODO(danrubel): Rather than comparing the error codes individually,
+      // it would be better if each error code could specify
+      // whether or not it could be fixed automatically.
+
+      // Fall through to calculate and apply the fix
+    } else {
+      // This error cannot be automatically fixed
+      return false;
+    }
+
+    final location = '${locationDescription(result, error.offset)}';
+    final dartContext = new DartFixContextImpl(
+        new FixContextImpl(
+            server.resourceProvider, result.driver, error, result.errors),
+        new AstProviderForDriver(result.driver),
+        result.unit);
+    final processor = new FixProcessor(dartContext);
+    Fix fix = await processor.computeFix();
+    if (fix != null) {
+      addFix('${fix.change.message} in $location', fix.change);
+    } else {
+      // TODO(danrubel): Determine why the fix could not be applied
+      // and report that in the description.
+      addRecommendation('Could not fix "${error.message}" in $location');
+    }
+    return true;
+  }
+
   /// Return `true` if the path in within the set of `included` files
   /// or is within an `included` directory.
-  bool isIncluded(String path) {
-    if (path != null) {
+  bool isIncluded(String filePath) {
+    if (filePath != null) {
       for (File file in fixFiles) {
-        if (file.path == path) {
+        if (file.path == filePath) {
           return true;
         }
       }
       for (Folder folder in fixFolders) {
-        if (folder.contains(path)) {
+        if (folder.contains(filePath)) {
           return true;
         }
       }
     }
     return false;
   }
+
+  /// Return a human readable description of the specified offset and file.
+  String locationDescription(AnalysisResult result, int offset) {
+    // TODO(danrubel): Pass the location back to the client along with the
+    // message indicating what was or was not automatically fixed
+    // rather than interpreting and integrating the location into the message.
+    final description = new StringBuffer();
+    // Determine the relative path
+    for (Folder folder in fixFolders) {
+      if (folder.contains(result.path)) {
+        description.write(server.resourceProvider.pathContext
+            .relative(result.path, from: folder.path));
+        break;
+      }
+    }
+    if (description.isEmpty) {
+      description.write(result.path);
+    }
+    // Determine the line and column number
+    if (offset >= 0) {
+      final loc = result.unit.lineInfo.getLocation(offset);
+      description.write(':${loc.lineNumber}');
+    }
+    return description.toString();
+  }
 }
 
 class EditDartFixAssistContext implements DartAssistContext {
@@ -216,6 +297,12 @@
 
   LinterFix(this.dartFix);
 
+  /// Apply fixes for the current compilation unit.
+  Future<void> applyLocalFixes(AnalysisResult result);
+
+  /// Apply any fixes remaining after analysis is complete.
+  Future<void> applyRemainingFixes();
+
   @override
   void reportError(AnalysisError error) {
     // ignored
@@ -252,63 +339,14 @@
   }
 
   @override
-  void reportTypeErrorForNode(
-      ErrorCode errorCode, AstNode node, List<Object> arguments) {
+  void reportErrorMessage(
+      ErrorCode errorCode, int offset, int length, Message message) {
     // ignored
   }
 
-  void applyFix();
-}
-
-class PreferMixinFix extends LinterFix {
-  final classesToConvert = new Set<Element>();
-
-  PreferMixinFix(EditDartFix dartFix) : super(dartFix);
-
   @override
-  void reportErrorForNode(ErrorCode errorCode, AstNode node,
-      [List<Object> arguments]) {
-    TypeName type = node;
-    Element element = type.name.staticElement;
-    String path = element.source?.fullName;
-    if (path != null && dartFix.isIncluded(path)) {
-      classesToConvert.add(element);
-    }
-  }
-
-  @override
-  void applyFix() async {
-    for (Element elem in classesToConvert) {
-      await convertClassToMixin(elem);
-    }
-  }
-
-  void convertClassToMixin(Element elem) async {
-    String path = elem.source?.fullName;
-    AnalysisResult result = await dartFix.server.getAnalysisResult(path);
-
-    // TODO(danrubel): Verify that class can be converted
-    for (CompilationUnitMember declaration in result.unit.declarations) {
-      if (declaration is ClassOrMixinDeclaration &&
-          declaration.name.name == elem.name) {
-        AssistProcessor processor = new AssistProcessor(
-            new EditDartFixAssistContext(
-                dartFix, elem.source, result.unit, declaration.name));
-        List<Assist> assists = await processor
-            .computeAssist(DartAssistKind.CONVERT_CLASS_TO_MIXIN);
-        if (assists.isNotEmpty) {
-          for (Assist assist in assists) {
-            dartFix.addFix(
-                'Convert class to mixin: ${elem.name}', assist.change);
-          }
-        } else {
-          // TODO(danrubel): If assists is empty, then determine why
-          // assist could not be performed and report that in the description.
-          dartFix.addRecommendation(
-              'Could not automatically convert ${elem.name} to a mixin'
-              ' because the class contains a constructor.');
-        }
-      }
-    }
+  void reportTypeErrorForNode(
+      ErrorCode errorCode, AstNode node, List<Object> arguments) {
+    // ignored
   }
 }
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
new file mode 100644
index 0000000..81758f9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+
+class PreferIntLiteralsFix extends LinterFix {
+  final literalsToConvert = <DoubleLiteral>[];
+
+  PreferIntLiteralsFix(EditDartFix dartFix) : super(dartFix);
+
+  @override
+  Future<void> applyLocalFixes(AnalysisResult result) async {
+    while (literalsToConvert.isNotEmpty) {
+      DoubleLiteral literal = literalsToConvert.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+          new EditDartFixAssistContext(dartFix, source, result.unit, literal));
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_INT_LITERAL);
+      final location = dartFix.locationDescription(result, literal.offset);
+      if (assists.isNotEmpty) {
+        for (Assist assist in assists) {
+          dartFix.addFix(
+              'Replace a double literal with an int literal in $location',
+              assist.change);
+        }
+      } else {
+        // TODO(danrubel): If assists is empty, then determine why
+        // assist could not be performed and report that in the description.
+        dartFix.addRecommendation('Could not replace'
+            ' a double literal with an int literal in $location');
+      }
+    }
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    // All fixes applied in [applyLocalFixes]
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    String filePath = source.fullName;
+    if (filePath != null && dartFix.isIncluded(filePath)) {
+      literalsToConvert.add(node);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
new file mode 100644
index 0000000..5e2aad1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+
+class PreferMixinFix extends LinterFix {
+  final classesToConvert = new Set<Element>();
+
+  PreferMixinFix(EditDartFix dartFix) : super(dartFix);
+
+  @override
+  Future<void> applyLocalFixes(AnalysisResult result) {
+    // All fixes applied in [applyRemainingFixes]
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() async {
+    for (Element elem in classesToConvert) {
+      await convertClassToMixin(elem);
+    }
+  }
+
+  Future<void> convertClassToMixin(Element elem) async {
+    AnalysisResult result =
+        await dartFix.server.getAnalysisResult(elem.source?.fullName);
+
+    for (CompilationUnitMember declaration in result.unit.declarations) {
+      if (declaration is ClassOrMixinDeclaration &&
+          declaration.name.name == elem.name) {
+        AssistProcessor processor = new AssistProcessor(
+            new EditDartFixAssistContext(
+                dartFix, elem.source, result.unit, declaration.name));
+        List<Assist> assists = await processor
+            .computeAssist(DartAssistKind.CONVERT_CLASS_TO_MIXIN);
+        final location = dartFix.locationDescription(result, elem.nameOffset);
+        if (assists.isNotEmpty) {
+          for (Assist assist in assists) {
+            dartFix.addFix(
+                'Convert ${elem.displayName} to a mixin in $location',
+                assist.change);
+          }
+        } else {
+          // TODO(danrubel): If assists is empty, then determine why
+          // assist could not be performed and report that in the description.
+          dartFix.addRecommendation(
+              'Could not convert ${elem.displayName} to a mixin'
+              ' because the class contains a constructor in $location');
+        }
+      }
+    }
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    TypeName type = node;
+    Element element = type.name.staticElement;
+    String filePath = element.source?.fullName;
+    if (filePath != null && dartFix.isIncluded(filePath)) {
+      classesToConvert.add(element);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 7c86874..34d1ffb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -11,6 +11,7 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -49,11 +50,11 @@
     // Build suggestions
     List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
     for (Name name in namesToOverride) {
-      ExecutableElement element = interface[name].element;
+      FunctionType signature = interface[name];
       // Gracefully degrade if the overridden element has not been resolved.
-      if (element.returnType != null) {
+      if (signature.returnType != null) {
         CompletionSuggestion suggestion =
-            await _buildSuggestion(request, targetId, element);
+            await _buildSuggestion(request, targetId, signature);
         if (suggestion != null) {
           suggestions.add(suggestion);
         }
@@ -63,13 +64,13 @@
   }
 
   /**
-   * Return a template for an override of the given [element]. If selected, the
-   * template will replace [targetId].
+   * Return a template for an override of the given [signature]. If selected,
+   * the template will replace [targetId].
    */
   Future<DartChangeBuilder> _buildReplacementText(
       AnalysisResult result,
       SimpleIdentifier targetId,
-      ExecutableElement element,
+      FunctionType signature,
       StringBuffer displayTextBuffer) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -77,8 +78,12 @@
         new DartChangeBuilder(result.driver.currentSession);
     await builder.addFileEdit(result.path, (DartFileEditBuilder builder) {
       builder.addReplacement(range.node(targetId), (DartEditBuilder builder) {
-        builder.writeOverrideOfInheritedMember(element,
-            displayTextBuffer: displayTextBuffer);
+        ExecutableElement element = signature.element;
+        builder.writeOverride(
+          signature,
+          displayTextBuffer: displayTextBuffer,
+          invokeSuper: !element.isAbstract,
+        );
       });
     });
     return builder;
@@ -86,15 +91,15 @@
 
   /**
    * Build a suggestion to replace [targetId] in the given [unit]
-   * with an override of the given [element].
+   * with an override of the given [signature].
    */
   Future<CompletionSuggestion> _buildSuggestion(DartCompletionRequest request,
-      SimpleIdentifier targetId, ExecutableElement element) async {
+      SimpleIdentifier targetId, FunctionType signature) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     StringBuffer displayTextBuffer = new StringBuffer();
     DartChangeBuilder builder = await _buildReplacementText(
-        request.result, targetId, element, displayTextBuffer);
+        request.result, targetId, signature, displayTextBuffer);
     String replacement = builder.sourceChange.edits[0].edits[0].replacement;
     String completion = replacement.trim();
     String overrideAnnotation = '@override';
@@ -119,10 +124,10 @@
         completion,
         selectionRange.offset - offsetDelta,
         selectionRange.length,
-        element.hasDeprecated,
+        signature.element.hasDeprecated,
         false,
         displayText: displayText);
-    suggestion.element = protocol.convertElement(element);
+    suggestion.element = protocol.convertElement(signature.element);
     return suggestion;
   }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
index eda5336..af2d9e3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
@@ -13,6 +13,12 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 
+/**
+ * Given some [String] name "foo", return a [CompletionSuggestion] with the
+ * [String].
+ *
+ * If the passed [String] is null or empty, null is returned.
+ */
 CompletionSuggestion _createNameSuggestion(String name) {
   if (name == null || name.isEmpty) {
     return null;
@@ -21,6 +27,9 @@
       DART_RELEVANCE_DEFAULT, name, name.length, 0, false, false);
 }
 
+/**
+ * Convert some [Identifier] to its [String] name.
+ */
 String _getStringName(Identifier id) {
   if (id == null) {
     return null;
@@ -50,6 +59,7 @@
       // Resolution not needed for this completion
 
       AstNode node = request.target.containingNode;
+
       String strName = null;
       if (node is ExpressionStatement) {
         if (node.expression is Identifier) {
@@ -85,6 +95,10 @@
         return const <CompletionSuggestion>[];
       }
 
+      var doIncludePrivateVersion = !optype.inMethodBody &&
+          !optype.inFunctionBody &&
+          !optype.inConstructorBody;
+
       List<String> variableNameSuggestions = getCamelWordCombinations(strName);
       variableNameSuggestions.remove(strName);
       List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
@@ -93,6 +107,13 @@
         if (suggestion != null) {
           suggestions.add(suggestion);
         }
+        if (doIncludePrivateVersion) {
+          CompletionSuggestion privateSuggestion =
+              _createNameSuggestion('_' + varName);
+          if (privateSuggestion != null) {
+            suggestions.add(privateSuggestion);
+          }
+        }
       }
       return suggestions;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 1b98a13..772299c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -52,6 +52,8 @@
       'dart.assist.convert.toConstructorFieldParameter',
       30,
       "Convert to field formal parameter");
+  static const CONVERT_TO_INT_LITERAL = const AssistKind(
+      'dart.assist.convert.toIntLiteral', 30, "Convert to an int literal");
   static const CONVERT_TO_NORMAL_PARAMETER = const AssistKind(
       'dart.assist.convert.toConstructorNormalParameter',
       30,
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index d0f2695..dffd207 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -132,6 +132,7 @@
     await _addProposal_convertPartOfToUri();
     await _addProposal_convertToForIndexLoop();
     await _addProposal_convertToGenericFunctionSyntax();
+    await _addProposal_convertToIntLiteral();
     await _addProposal_convertToIsNot_onIs();
     await _addProposal_convertToIsNot_onNot();
     await _addProposal_convertToIsNotEmpty();
@@ -176,6 +177,8 @@
     // Calculate only specific assists for edit.dartFix
     if (assistKind == DartAssistKind.CONVERT_CLASS_TO_MIXIN) {
       await _addProposal_convertClassToMixin();
+    } else if (assistKind == DartAssistKind.CONVERT_TO_INT_LITERAL) {
+      await _addProposal_convertToIntLiteral();
     }
     return assists;
   }
@@ -382,6 +385,33 @@
     }
   }
 
+  Future<void> _addProposal_convertToIntLiteral() async {
+    if (node is! DoubleLiteral) {
+      _coverageMarker();
+      return;
+    }
+    DoubleLiteral literal = node;
+    int intValue;
+    try {
+      intValue = literal.value?.truncate();
+    } catch (e) {
+      // Double cannot be converted to int
+    }
+    if (intValue == null || intValue != literal.value) {
+      _coverageMarker();
+      return;
+    }
+
+    DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(new SourceRange(literal.offset, literal.length),
+          (DartEditBuilder builder) {
+        builder.write('${intValue}');
+      });
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_INT_LITERAL);
+  }
+
   Future<void> _addProposal_assignToLocalVariable() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index dca6f25..3f595bf 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -95,17 +95,17 @@
       'ADD_EXPLICIT_CAST', 50, "Add cast",
       appliedTogetherMessage: "Add all casts in file");
   static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
-      'ADD_FIELD_FORMAL_PARAMETERS', 30, "Add final field formal parameters");
+      'ADD_FIELD_FORMAL_PARAMETERS', 70, "Add final field formal parameters");
   static const ADD_MISSING_PARAMETER_POSITIONAL = const FixKind(
       'ADD_MISSING_PARAMETER_POSITIONAL',
-      31,
+      69,
       "Add optional positional parameter");
   static const ADD_MISSING_PARAMETER_NAMED = const FixKind(
-      'ADD_MISSING_PARAMETER_NAMED', 30, "Add named parameter '{0}'");
+      'ADD_MISSING_PARAMETER_NAMED', 70, "Add named parameter '{0}'");
   static const ADD_MISSING_PARAMETER_REQUIRED = const FixKind(
-      'ADD_MISSING_PARAMETER_REQUIRED', 30, "Add required parameter");
+      'ADD_MISSING_PARAMETER_REQUIRED', 70, "Add required parameter");
   static const ADD_MISSING_REQUIRED_ARGUMENT = const FixKind(
-      'ADD_MISSING_REQUIRED_ARGUMENT', 30, "Add required argument '{0}'");
+      'ADD_MISSING_REQUIRED_ARGUMENT', 70, "Add required argument '{0}'");
   static const ADD_NE_NULL = const FixKind('ADD_NE_NULL', 50, "Add != null",
       appliedTogetherMessage: "Add != null everywhere in file");
   static const ADD_PACKAGE_DEPENDENCY = const FixKind(
@@ -116,11 +116,11 @@
       'ADD_SUPER_CONSTRUCTOR_INVOCATION',
       50,
       "Add super constructor {0} invocation");
-  static const CHANGE_TO = const FixKind('CHANGE_TO', 49, "Change to '{0}'");
+  static const CHANGE_TO = const FixKind('CHANGE_TO', 51, "Change to '{0}'");
   static const CHANGE_TO_NEAREST_PRECISE_VALUE = const FixKind(
       'CHANGE_TO_NEAREST_PRECISE_VALUE',
       50,
-      'Change to nearest precise int-as-double value: {0}');
+      "Change to nearest precise int-as-double value: {0}");
   static const CHANGE_TO_STATIC_ACCESS = const FixKind(
       'CHANGE_TO_STATIC_ACCESS', 50, "Change access to static using '{0}'");
   static const CHANGE_TYPE_ANNOTATION = const FixKind(
@@ -140,11 +140,11 @@
   static const CREATE_CONSTRUCTOR_SUPER = const FixKind(
       'CREATE_CONSTRUCTOR_SUPER', 50, "Create constructor to call {0}");
   static const CREATE_FIELD =
-      const FixKind('CREATE_FIELD', 51, "Create field '{0}'");
+      const FixKind('CREATE_FIELD', 49, "Create field '{0}'");
   static const CREATE_FILE =
       const FixKind('CREATE_FILE', 50, "Create file '{0}'");
   static const CREATE_FUNCTION =
-      const FixKind('CREATE_FUNCTION', 51, "Create function '{0}'");
+      const FixKind('CREATE_FUNCTION', 49, "Create function '{0}'");
   static const CREATE_GETTER =
       const FixKind('CREATE_GETTER', 50, "Create getter '{0}'");
   static const CREATE_LOCAL_VARIABLE =
@@ -152,25 +152,25 @@
   static const CREATE_METHOD =
       const FixKind('CREATE_METHOD', 50, "Create method '{0}'");
   static const CREATE_MISSING_OVERRIDES = const FixKind(
-      'CREATE_MISSING_OVERRIDES', 49, "Create {0} missing override(s)");
+      'CREATE_MISSING_OVERRIDES', 51, "Create {0} missing override(s)");
   static const CREATE_MIXIN =
       const FixKind('CREATE_MIXIN', 50, "Create mixin '{0}'");
   static const CREATE_NO_SUCH_METHOD = const FixKind(
-      'CREATE_NO_SUCH_METHOD', 51, "Create 'noSuchMethod' method");
+      'CREATE_NO_SUCH_METHOD', 49, "Create 'noSuchMethod' method");
   static const CONVERT_TO_NAMED_ARGUMENTS = const FixKind(
       'CONVERT_TO_NAMED_ARGUMENTS', 50, "Convert to named arguments");
   static const IMPORT_LIBRARY_PREFIX = const FixKind('IMPORT_LIBRARY_PREFIX',
-      51, "Use imported library '{0}' with prefix '{1}'");
+      49, "Use imported library '{0}' with prefix '{1}'");
   static const IMPORT_LIBRARY_PROJECT1 =
-      const FixKind('IMPORT_LIBRARY_PROJECT1', 47, "Import library '{0}'");
+      const FixKind('IMPORT_LIBRARY_PROJECT1', 53, "Import library '{0}'");
   static const IMPORT_LIBRARY_PROJECT2 =
-      const FixKind('IMPORT_LIBRARY_PROJECT2', 48, "Import library '{0}'");
+      const FixKind('IMPORT_LIBRARY_PROJECT2', 52, "Import library '{0}'");
   static const IMPORT_LIBRARY_PROJECT3 =
-      const FixKind('IMPORT_LIBRARY_PROJECT3', 49, "Import library '{0}'");
+      const FixKind('IMPORT_LIBRARY_PROJECT3', 51, "Import library '{0}'");
   static const IMPORT_LIBRARY_SDK =
-      const FixKind('IMPORT_LIBRARY_SDK', 46, "Import library '{0}'");
+      const FixKind('IMPORT_LIBRARY_SDK', 54, "Import library '{0}'");
   static const IMPORT_LIBRARY_SHOW =
-      const FixKind('IMPORT_LIBRARY_SHOW', 45, "Update library '{0}' import");
+      const FixKind('IMPORT_LIBRARY_SHOW', 55, "Update library '{0}' import");
   static const INSERT_SEMICOLON =
       const FixKind('INSERT_SEMICOLON', 50, "Insert ';'");
   static const INVOKE_CONSTRUCTOR_USING_NEW = const FixKind(
@@ -182,9 +182,13 @@
   static const LINT_REMOVE_INTERPOLATION_BRACES = const FixKind(
       'LINT_REMOVE_INTERPOLATION_BRACES',
       50,
-      'Remove unnecessary interpolation braces');
+      "Remove unnecessary interpolation braces");
   static const MAKE_CLASS_ABSTRACT =
       const FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract");
+  static const MOVE_TYPE_ARGUMENTS_TO_CLASS = const FixKind(
+      'MOVE_TYPE_ARGUMENTS_TO_CLASS',
+      50,
+      "Move type arguments to after class name");
   static const REMOVE_DEAD_CODE =
       const FixKind('REMOVE_DEAD_CODE', 50, "Remove dead code");
   static const MAKE_FIELD_NOT_FINAL =
@@ -202,7 +206,7 @@
   static const REMOVE_INITIALIZER =
       const FixKind('REMOVE_INITIALIZER', 50, "Remove initializer");
   static const REMOVE_METHOD_DECLARATION = const FixKind(
-      'REMOVE_METHOD_DECLARATION', 50, 'Remove method declaration');
+      'REMOVE_METHOD_DECLARATION', 50, "Remove method declaration");
   static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = const FixKind(
       'REMOVE_PARAMETERS_IN_GETTER_DECLARATION',
       50,
@@ -213,13 +217,15 @@
       "Remove parentheses in getter invocation");
   static const REMOVE_THIS_EXPRESSION =
       const FixKind('REMOVE_THIS_EXPRESSION', 50, "Remove this expression");
+  static const REMOVE_TYPE_ARGUMENTS =
+      const FixKind('REMOVE_TYPE_ARGUMENTS', 51, "Remove type arguments");
   static const REMOVE_TYPE_NAME =
       const FixKind('REMOVE_TYPE_NAME', 50, "Remove type name");
   static const REMOVE_UNNECESSARY_CAST = const FixKind(
       'REMOVE_UNNECESSARY_CAST', 50, "Remove unnecessary cast",
       appliedTogetherMessage: "Remove all unnecessary casts in file");
-  static const REMOVE_UNUSED_CATCH_CLAUSE =
-      const FixKind('REMOVE_UNUSED_CATCH', 50, "Remove unused 'catch' clause");
+  static const REMOVE_UNUSED_CATCH_CLAUSE = const FixKind(
+      'REMOVE_UNUSED_CATCH_CLAUSE', 50, "Remove unused 'catch' clause");
   static const REMOVE_UNUSED_CATCH_STACK = const FixKind(
       'REMOVE_UNUSED_CATCH_STACK', 50, "Remove unused stack trace variable");
   static const REMOVE_UNUSED_IMPORT = const FixKind(
@@ -241,11 +247,11 @@
   static const REPLACE_WITH_BRACKETS =
       const FixKind('REPLACE_WITH_BRACKETS', 50, "Replace with { }");
   static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = const FixKind(
-      'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, 'Replace with ??=');
+      'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??=");
   static const REPLACE_WITH_IDENTIFIER =
       const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier");
   static const REPLACE_WITH_LITERAL =
-      const FixKind('REPLACE_WITH_LITERAL', 50, 'Replace with literal');
+      const FixKind('REPLACE_WITH_LITERAL', 50, "Replace with literal");
   static const REPLACE_WITH_NULL_AWARE = const FixKind(
       'REPLACE_WITH_NULL_AWARE',
       50,
@@ -262,7 +268,7 @@
       appliedTogetherMessage:
           "Use == null instead of 'is Null' everywhere in file");
   static const USE_IS_NOT_EMPTY = const FixKind(
-      'USE_NOT_EMPTY', 50, "Use x.isNotEmpty instead of '!x.isEmpty'");
+      'USE_IS_NOT_EMPTY', 50, "Use x.isNotEmpty instead of '!x.isEmpty'");
   static const USE_NOT_EQ_NULL = const FixKind(
       'USE_NOT_EQ_NULL', 50, "Use != null instead of 'is! Null'",
       appliedTogetherMessage:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 2fba47c..db40113 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -551,6 +551,11 @@
     if (errorCode == CompileTimeErrorCode.CONST_INSTANCE_FIELD) {
       await _addFix_addStatic();
     }
+    if (errorCode ==
+        StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR) {
+      await _addFix_moveTypeArgumentsToClass();
+      await _addFix_removeTypeArguments();
+    }
     // lints
     if (errorCode is LintCode) {
       String name = errorCode.name;
@@ -628,12 +633,18 @@
     return fixes;
   }
 
+  Future<Fix> computeFix() async {
+    List<Fix> fixes = await compute();
+    fixes.sort(Fix.SORT_BY_RELEVANCE);
+    return fixes.isNotEmpty ? fixes.first : null;
+  }
+
   Future<void> _addFix_addAsync() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     FunctionBody body = node.getAncestor((n) => n is FunctionBody);
     if (body != null && body.keyword == null) {
-      TypeProvider typeProvider = await this.typeProvider;
+      TypeProvider typeProvider = this.typeProvider;
       DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
       await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
         builder.convertFunctionFromSyncToAsync(body, typeProvider);
@@ -1959,20 +1970,20 @@
     ClassDeclaration targetClass = node.parent as ClassDeclaration;
     ClassElement targetClassElement = targetClass.declaredElement;
     utils.targetClassElement = targetClassElement;
-    List<ExecutableElement> elements =
+    List<FunctionType> signatures =
         InheritanceOverrideVerifier.missingOverrides(targetClass).toList();
     // sort by name, getters before setters
-    elements.sort((Element a, Element b) {
-      int names = compareStrings(a.displayName, b.displayName);
+    signatures.sort((FunctionType a, FunctionType b) {
+      int names = compareStrings(a.element.displayName, b.element.displayName);
       if (names != 0) {
         return names;
       }
-      if (a.kind == ElementKind.GETTER) {
+      if (a.element.kind == ElementKind.GETTER) {
         return -1;
       }
       return 1;
     });
-    int numElements = elements.length;
+    int numElements = signatures.length;
 
     ClassMemberLocation location =
         utils.prepareNewClassMemberLocation(targetClass, (_) => true);
@@ -1981,9 +1992,6 @@
     DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
       builder.addInsertion(location.offset, (DartEditBuilder builder) {
-        // TODO(brianwilkerson) Compare with builder.writeOverrideOfInheritedMember
-        // The builder method doesn't merge getter/setter pairs into fields.
-
         // Separator management.
         int numOfMembersWritten = 0;
         void addSeparatorBetweenDeclarations() {
@@ -1998,14 +2006,15 @@
         }
 
         // merge getter/setter pairs into fields
-        for (int i = 0; i < elements.length; i++) {
-          ExecutableElement element = elements[i];
-          if (element.kind == ElementKind.GETTER && i + 1 < elements.length) {
-            ExecutableElement nextElement = elements[i + 1];
+        for (int i = 0; i < signatures.length; i++) {
+          FunctionType signature = signatures[i];
+          ExecutableElement element = signature.element;
+          if (element.kind == ElementKind.GETTER && i + 1 < signatures.length) {
+            ExecutableElement nextElement = signatures[i + 1].element;
             if (nextElement.kind == ElementKind.SETTER) {
               // remove this and the next elements, adjust iterator
-              elements.removeAt(i + 1);
-              elements.removeAt(i);
+              signatures.removeAt(i + 1);
+              signatures.removeAt(i);
               i--;
               numElements--;
               // separator
@@ -2015,7 +2024,7 @@
               builder.write(eol);
               // add field
               builder.write(prefix);
-              builder.writeType(element.type.returnType, required: true);
+              builder.writeType(signature.returnType, required: true);
               builder.write(' ');
               builder.write(element.name);
               builder.write(';');
@@ -2023,10 +2032,9 @@
           }
         }
         // add elements
-        for (ExecutableElement element in elements) {
+        for (FunctionType signature in signatures) {
           addSeparatorBetweenDeclarations();
-          _addFix_createMissingOverridesForBuilder(
-              builder, targetClass, element);
+          builder.writeOverride(signature);
         }
         builder.write(location.suffix);
       });
@@ -2036,65 +2044,6 @@
         args: [numElements]);
   }
 
-  void _addFix_createMissingOverridesForBuilder(DartEditBuilder builder,
-      ClassDeclaration targetClass, ExecutableElement element) {
-    utils.targetExecutableElement = element;
-    // prepare environment
-    String prefix = utils.getIndent(1);
-    String prefix2 = utils.getIndent(2);
-    // may be property
-    ElementKind elementKind = element.kind;
-    bool isGetter = elementKind == ElementKind.GETTER;
-    bool isSetter = elementKind == ElementKind.SETTER;
-    bool isMethod = elementKind == ElementKind.METHOD;
-    bool isOperator = isMethod && (element as MethodElement).isOperator;
-    if (isGetter) {
-      builder.write('// TODO: implement ${element.displayName}');
-      builder.write(eol);
-      builder.write(prefix);
-    }
-    // @override
-    builder.write('@override');
-    builder.write(eol);
-    builder.write(prefix);
-    // return type
-    if (!isSetter) {
-      if (builder.writeType(element.type.returnType,
-          methodBeingCopied: element)) {
-        builder.write(' ');
-      }
-    }
-    // keyword
-    if (isGetter) {
-      builder.write('get ');
-    } else if (isSetter) {
-      builder.write('set ');
-    } else if (isOperator) {
-      builder.write('operator ');
-    }
-    // name
-    builder.write(element.displayName);
-    builder.writeTypeParameters(element.typeParameters,
-        methodBeingCopied: element);
-    // parameters + body
-    if (isGetter) {
-      builder.write(' => null;');
-    } else {
-      List<ParameterElement> parameters = element.parameters;
-      builder.writeParameters(parameters, methodBeingCopied: element);
-      builder.write(' {');
-      // TO-DO
-      builder.write(eol);
-      builder.write(prefix2);
-      builder.write('// TODO: implement ${element.displayName}');
-      builder.write(eol);
-      // close method
-      builder.write(prefix);
-      builder.write('}');
-    }
-    utils.targetExecutableElement = null;
-  }
-
   Future<void> _addFix_createMixin() async {
     Element prefixElement = null;
     String name = null;
@@ -2562,6 +2511,33 @@
     }
   }
 
+  Future<void> _addFix_moveTypeArgumentsToClass() async {
+    if (coveredNode is TypeArgumentList) {
+      TypeArgumentList typeArguments = coveredNode;
+      if (typeArguments.parent is! InstanceCreationExpression) {
+        return;
+      }
+      InstanceCreationExpression creation = typeArguments.parent;
+      TypeName typeName = creation.constructorName.type;
+      if (typeName.typeArguments != null) {
+        return;
+      }
+      Element element = typeName.type.element;
+      if (element is ClassElement &&
+          element.typeParameters != null &&
+          element.typeParameters.length == typeArguments.arguments.length) {
+        DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+          String argumentText = utils.getNodeText(typeArguments);
+          builder.addSimpleInsertion(typeName.end, argumentText);
+          builder.addDeletion(range.node(typeArguments));
+        });
+        _addFixFromBuilder(
+            changeBuilder, DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS);
+      }
+    }
+  }
+
   Future<void> _addFix_nonBoolCondition_addNotNull() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -2814,6 +2790,17 @@
     }
   }
 
+  Future<void> _addFix_removeTypeArguments() async {
+    if (coveredNode is TypeArgumentList) {
+      TypeArgumentList typeArguments = coveredNode;
+      DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addDeletion(range.node(typeArguments));
+      });
+      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_ARGUMENTS);
+    }
+  }
+
   Future<void> _addFix_removeUnnecessaryCast() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
diff --git a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
index cea1e5c..23c804b 100644
--- a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/generated/bazel.dart';
 import 'package:analyzer/src/generated/gn.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
@@ -94,7 +94,7 @@
   final ResourceProvider resourceProvider;
   final List<KytheEntry> entries;
   final String corpus;
-  final InheritanceManager _inheritanceManager;
+  final InheritanceManager2 _inheritanceManager;
   final String _contents;
 
   String _enclosingFilePath = '';
@@ -695,19 +695,19 @@
           returnNode: node.returnType);
 
       // override edges
-      List<ExecutableElement> overriddenList =
-          _inheritanceManager.lookupOverrides(_enclosingClassElement,
-              resolutionMap.elementDeclaredByMethodDeclaration(node).name);
-      for (ExecutableElement overridden in overriddenList) {
-        if (overridden is MultiplyInheritedExecutableElement) {
-          for (ExecutableElement elt in overridden.inheritedElements) {
-            addEdge(methodVName, schema.OVERRIDES_EDGE,
-                _vNameFromElement(elt, schema.FUNCTION_KIND));
-          }
-        } else {
-          addEdge(methodVName, schema.OVERRIDES_EDGE,
-              _vNameFromElement(overridden, schema.FUNCTION_KIND));
-        }
+      var overriddenSignatures = _inheritanceManager.getOverridden(
+        _enclosingClassElement.type,
+        new Name(
+          _enclosingClassElement.library.source.uri,
+          node.declaredElement.name,
+        ),
+      );
+      for (FunctionType signature in overriddenSignatures) {
+        addEdge(
+          methodVName,
+          schema.OVERRIDES_EDGE,
+          _vNameFromElement(signature.element, schema.FUNCTION_KIND),
+        );
       }
 
       // visit children
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index d5d1853..d2e3c69 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -127,19 +127,27 @@
    */
   String _computeNewUri(SourceReference reference) {
     String refDir = pathContext.dirname(reference.file);
-    // try to keep package: URI
-    // if (_isPackageReference(reference)) {
-    //   Source newSource = new NonExistingSource(
-    //       newFile, pathos.toUri(newFile), UriKind.FILE_URI);
-    //   Uri restoredUri = context.sourceFactory.restoreUri(newSource);
-    //   if (restoredUri != null) {
-    //     return restoredUri.toString();
-    //   }
-    // }
-    // if no package: URI, prepare relative
+    // Try to keep package: URI
+    if (_isPackageReference(reference)) {
+      Source newSource = new NonExistingSource(
+          newFile, pathos.toUri(newFile), UriKind.FILE_URI);
+      Uri restoredUri = driver.sourceFactory.restoreUri(newSource);
+      if (restoredUri != null) {
+        return restoredUri.toString();
+      }
+    }
     return _getRelativeUri(newFile, refDir);
   }
 
+  final packagePrefixedStringPattern = new RegExp(r'''^r?['"]+package:''');
+  bool _isPackageReference(SourceReference reference) {
+    final Source source = reference.element.source;
+    final String quotedImportUri = source.contents.data.substring(
+        reference.range.offset,
+        reference.range.offset + reference.range.length);
+    return packagePrefixedStringPattern.hasMatch(quotedImportUri);
+  }
+
   String _getRelativeUri(String path, String from) {
     String uri = pathContext.relative(path, from: from);
     List<String> parts = pathContext.split(uri);
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 4628c6f..56423be 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -389,7 +389,6 @@
 
     b.write(
         writeOption('Analyze function bodies', options.analyzeFunctionBodies));
-    b.write(writeOption('Enable super mixins', options.enableSuperMixins));
     b.write(writeOption('Generate dart2js hints', options.dart2jsHint));
     b.write(writeOption(
         'Generate errors in implicit files', options.generateImplicitErrors));
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index 06c3d3c..f116530 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -229,12 +229,18 @@
 
 /**
  * Attempt to find and return the closest expression that encloses the [node]
- * and is a Flutter `Widget`.  Return `null` if nothing found.
+ * and is an independent Flutter `Widget`.  Return `null` if nothing found.
  */
 Expression identifyWidgetExpression(AstNode node) {
   for (; node != null; node = node.parent) {
     if (isWidgetExpression(node)) {
-      return node;
+      var parent = node.parent;
+      if (parent is ArgumentList ||
+          parent is ListLiteral ||
+          parent is NamedExpression && parent.expression == node ||
+          parent is Statement) {
+        return node;
+      }
     }
     if (node is ArgumentList || node is Statement || node is FunctionBody) {
       return null;
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 2b6249c..f635e39 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -2,7 +2,7 @@
 publish_to: none
 description: A server that performs analysis of Dart code over character streams using JSON-RPC encoded information.
 dependencies:
-  analyzer: ^0.30.0
+  analyzer: ^0.33.0
   args: '>=0.13.0 <2.0.0'
   dart_style: '^1.0.6'
   intl: ^0.15.0
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
index 56b2399..305acd3 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
@@ -119,7 +119,7 @@
     expect(analyzedFilesReceived, isTrue);
 
     analyzedFilesReceived = false;
-    modifyTestFile('import "${convertPathForImport('/foo.dart')}";');
+    modifyTestFile('import "${convertAbsolutePathToUri('/foo.dart')}";');
     await prepareAnalyzedFiles();
     assertHasFile(convertPath('/foo.dart'));
   }
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index a2911fa..e04d0de 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -13,8 +13,10 @@
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
 import 'package:analyzer/src/generated/sdk.dart';
@@ -24,8 +26,6 @@
 import 'package:analyzer/src/summary/summary_file_builder.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/util/glob.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:linter/src/rules.dart';
 import 'package:linter/src/rules/avoid_as.dart';
 import 'package:path/path.dart' as path;
@@ -1807,8 +1807,6 @@
 embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
-  language:
-    enableSuperMixins: true
   errors:
     unused_local_variable: false
 linter:
@@ -1823,7 +1821,6 @@
     // Verify options were set.
     expect(errorProcessors, hasLength(1));
     expect(lints, hasLength(1));
-    expect(analysisOptions.enableSuperMixins, isTrue);
 
     // Remove options.
     deleteOptionsFile();
@@ -1832,7 +1829,6 @@
     // Verify defaults restored.
     expect(errorProcessors, isEmpty);
     expect(lints, isEmpty);
-    expect(analysisOptions.enableSuperMixins, isFalse);
   }
 
   @failingTest
@@ -1859,8 +1855,6 @@
     // Setup analysis options
     newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
-  language:
-    enableSuperMixins: true
   errors:
     unused_local_variable: false
 linter:
@@ -1873,7 +1867,6 @@
     await pumpEventQueue();
 
     // Verify options were set.
-    expect(analysisOptions.enableSuperMixins, isTrue);
     expect(errorProcessors, hasLength(2));
     expect(lints, hasLength(2));
 
@@ -1882,7 +1875,6 @@
     await pumpEventQueue();
 
     // Verify defaults restored.
-    expect(analysisOptions.enableSuperMixins, isFalse);
     expect(lints, hasLength(1));
     expect(lints.first, const TypeMatcher<AvoidAs>());
     expect(errorProcessors, hasLength(1));
@@ -1903,8 +1895,6 @@
 ''');
     newFile('$projPath/other_options.yaml', content: r'''
 analyzer:
-  language:
-    enableSuperMixins: true
   errors:
     unused_local_variable: false
 linter:
@@ -1915,7 +1905,6 @@
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     await pumpEventQueue();
     // Verify options were set.
-    expect(analysisOptions.enableSuperMixins, isTrue);
     expect(errorProcessors, hasLength(1));
     expect(lints, hasLength(1));
     expect(lints[0].name, 'camel_case_types');
@@ -1933,8 +1922,6 @@
     String booLibPosixPath = '/my/pkg/boo/lib';
     newFile('$booLibPosixPath/other_options.yaml', content: r'''
 analyzer:
-  language:
-    enableSuperMixins: true
   errors:
     unused_local_variable: false
 linter:
@@ -1951,7 +1938,6 @@
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     await pumpEventQueue();
     // Verify options were set.
-    expect(analysisOptions.enableSuperMixins, isTrue);
     expect(errorProcessors, hasLength(1));
     expect(lints, hasLength(1));
     expect(lints[0].name, 'camel_case_types');
@@ -2009,8 +1995,6 @@
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
   strong-mode: true
-  language:
-    enableSuperMixins: true
   errors:
     missing_return: false
 linter:
@@ -2026,8 +2010,6 @@
 analyzer:
   exclude:
     - 'test/**'
-  language:
-    enableSuperMixins: true
   errors:
     unused_local_variable: false
 linter:
@@ -2046,12 +2028,8 @@
 
     // Verify options.
     // * from `_embedder.yaml`:
-    // TODO(brianwilkerson) Figure out what to use in place of 'strongMode' and
-    // why 'enableSuperMixins' is assumed to come from two different sources.
+    // TODO(brianwilkerson) Figure out what to use in place of 'strongMode'.
 //    expect(analysisOptions.strongMode, isTrue);
-    expect(analysisOptions.enableSuperMixins, isTrue);
-    // * from analysis options:
-    expect(analysisOptions.enableSuperMixins, isTrue);
 
     // * verify tests are excluded
     expect(
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 5a877b3..0566e1f 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -251,7 +251,7 @@
 
   test_import_uri_with_trailing() {
     final filePath = '/project/bin/testA.dart';
-    final incompleteImportText = convertPathForImport('/project/bin/t');
+    final incompleteImportText = convertAbsolutePathToUri('/project/bin/t');
     newFile(filePath, content: 'library libA;');
     addTestFile('''
     import "$incompleteImportText^.dart";
@@ -261,7 +261,7 @@
           equals(completionOffset - incompleteImportText.length));
       expect(replacementLength, equals(5 + incompleteImportText.length));
       assertHasResult(
-          CompletionSuggestionKind.IMPORT, convertPathForImport(filePath));
+          CompletionSuggestionKind.IMPORT, convertAbsolutePathToUri(filePath));
       assertNoResult('test');
     });
   }
@@ -509,7 +509,7 @@
   foo(bar) => 0;''');
     addTestFile('''
   library libA;
-  part "${convertPathForImport('/testA.dart')}";
+  part "${convertAbsolutePathToUri('/testA.dart')}";
   import "dart:math";
   /// The [^]
   main(aaa, bbb) {}
@@ -734,7 +734,7 @@
   test_partFile() {
     newFile('/project/bin/testA.dart', content: '''
       library libA;
-      part "${convertPathForImport(testFile)}";
+      part "${convertAbsolutePathToUri(testFile)}";
       import 'dart:html';
       class A { }
     ''');
@@ -760,7 +760,7 @@
       class A { }''');
     addTestFile('''
       library libA;
-      part "${convertPathForImport("/testA.dart")}";
+      part "${convertAbsolutePathToUri("/testA.dart")}";
       import 'dart:html';
       main() {^}
     ''');
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index b2954eb..3976d6c 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
-// This file has been automatically generated.  Please do not edit it manually.
+// This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
@@ -438,6 +438,11 @@
    *
    *   The name of the function being invoked at the given offset.
    *
+   * parameters: List<ParameterInfo>
+   *
+   *   A list of information about each of the parameters of the function being
+   *   invoked.
+   *
    * dartdoc: String (optional)
    *
    *   The dartdoc associated with the function being invoked. Other than the
@@ -445,11 +450,6 @@
    *   case of a block comment, the dartdoc is unprocessed markdown. This data
    *   is omitted if there is no referenced element, or if the element has no
    *   dartdoc.
-   *
-   * parameters: List<ParameterInfo>
-   *
-   *   A list of information about each of the parameters of the function being
-   *   invoked.
    */
   Future<AnalysisGetSignatureResult> sendAnalysisGetSignature(
       String file, int offset) async {
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index f2f732b..db9505f 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 //
-// This file has been automatically generated.  Please do not edit it manually.
+// This file has been automatically generated. Please do not edit it manually.
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
@@ -1723,8 +1723,8 @@
  *
  * {
  *   "name": String
- *   "dartdoc": optional String
  *   "parameters": List<ParameterInfo>
+ *   "dartdoc": optional String
  * }
  */
 final Matcher isAnalysisGetSignatureResult = new LazyMatcher(() =>
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 2178be8..07f8f15 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -1,9 +1,7 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library testing.mock_sdk;
-
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
 import 'package:analyzer/src/context/context.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 2353870..a75c2e4 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -145,7 +145,7 @@
     addSource('/libA.dart', '''
 library libA; class A { const A({int one, String two: 'defaultValue'}); }''');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; @A(^) main() { }');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; @A(^) main() { }');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(
         namedArgumentsWithTypes: {'one': 'int', 'two': 'String'});
@@ -158,7 +158,7 @@
 }
 ''');
     addTestSource('''
-import "${convertPathForImport("/libA.dart")}" as p;
+import "${convertAbsolutePathToUri("/libA.dart")}" as p;
 @p.A(^)
 main() {}
 ''');
@@ -465,7 +465,7 @@
     // ArgumentList  InstanceCreationExpression  ExpressionStatement
     addSource('/libA.dart', 'library libA; class A{A({int one}); }');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; main() { new A(^);}');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; main() { new A(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
   }
@@ -474,7 +474,7 @@
     // ArgumentList  InstanceCreationExpression  ExpressionStatement
     addSource('/libA.dart', 'library libA; class A{A.foo({int one}); }');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; main() { new A.foo(^);}');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; main() { new A.foo(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
   }
@@ -484,7 +484,7 @@
     addSource(
         '/libA.dart', 'library libA; class A { A({int i, String s, d}) {} }}');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; main() { var a = new A(^);}');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; main() { var a = new A(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(
         namedArgumentsWithTypes: {'i': 'int', 's': 'String', 'd': 'dynamic'});
@@ -495,7 +495,7 @@
     addSource(
         '/libA.dart', 'library libA; class A{factory A({int one}) => null;}');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; main() { new A(^);}');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; main() { new A(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
   }
@@ -505,7 +505,7 @@
     addSource('/libA.dart',
         'library libA; abstract class A{factory A.foo({int one});}');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; main() { new A.foo(^);}');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; main() { new A.foo(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
   }
@@ -515,7 +515,7 @@
     addSource('/libA.dart',
         'library libA; class A {factory A({int i, String s, d}) {} }}');
     addTestSource(
-        'import "${convertPathForImport("/libA.dart")}"; main() { var a = new A(^);}');
+        'import "${convertAbsolutePathToUri("/libA.dart")}"; main() { var a = new A(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(
         namedArgumentsWithTypes: {'i': 'int', 's': 'String', 'd': 'dynamic'});
@@ -529,7 +529,7 @@
       expect() { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect(a^)}''');
@@ -545,7 +545,7 @@
       expect(String arg) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect(^)}''');
@@ -561,7 +561,7 @@
       expect(String arg1, int arg2) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect(^)}''');
@@ -577,7 +577,7 @@
       expect(String arg1, int arg2, {bool arg3}) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect(^)}''');
@@ -593,7 +593,7 @@
       expect(String arg1, int arg2, {bool arg3}) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect('hello', ^)}''');
@@ -609,7 +609,7 @@
       expect(String arg1, int arg2, {bool arg3}) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect('hello', ^x)}''');
@@ -625,7 +625,7 @@
       expect(String arg1, int arg2, {bool arg3}) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect('hello', x^)}''');
@@ -641,7 +641,7 @@
       expect(String arg1, int arg2, {bool arg3}) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B { }
       String bar() => true;
       void main() {expect('hello', x ^)}''');
@@ -1030,7 +1030,7 @@
       bool hasLength(int expected) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B {
         expect() { }
         void foo() {expect(^)}}
@@ -1046,7 +1046,7 @@
       bool hasLength(int expected) { }
       void baz() { }''');
     addTestSource('''
-      import '${convertPathForImport('/libA.dart')}'
+      import '${convertAbsolutePathToUri('/libA.dart')}'
       class B {
         expect(arg, int blat) { }
         void foo() {expect(^)}}
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index ac4c454..66d2115 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -38,7 +38,7 @@
     // SimpleIdentifier  HideCombinator  ImportDirective
     addSource('/testAB.dart', '''
       library libAB;
-      part "${convertPathForImport('/partAB.dart')}";
+      part "${convertAbsolutePathToUri('/partAB.dart')}";
       class A { }
       class B { }''');
     addSource('/partAB.dart', '''
@@ -50,8 +50,8 @@
       class C { }
       class D { }''');
     addTestSource('''
-      import "${convertPathForImport("/testAB.dart")}" hide ^;
-      import "${convertPathForImport("/testCD.dart")}";
+      import "${convertAbsolutePathToUri("/testAB.dart")}" hide ^;
+      import "${convertAbsolutePathToUri("/testCD.dart")}";
       class X {}''');
 
     await computeSuggestions();
@@ -78,7 +78,7 @@
     // SimpleIdentifier  HideCombinator  ImportDirective
     addSource('/testAB.dart', '''
       library libAB;
-      part "${convertPathForImport('/partAB.dart')}";
+      part "${convertAbsolutePathToUri('/partAB.dart')}";
       class A { }
       class B { }
       class _AB''');
@@ -93,8 +93,8 @@
       class C { }
       class D { }''');
     addTestSource('''
-      import "${convertPathForImport("/testAB.dart")}" show ^;
-      import "${convertPathForImport("/testCD.dart")}";
+      import "${convertAbsolutePathToUri("/testAB.dart")}" show ^;
+      import "${convertAbsolutePathToUri("/testCD.dart")}";
       class X {}''');
 
     await computeSuggestions();
@@ -158,7 +158,7 @@
 class B {}
 ''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}" show ^;
+import "${convertAbsolutePathToUri("/testB.dart")}" show ^;
 ''');
     await computeSuggestions();
     assertSuggestClass('A',
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index 0809c6e..c6f9a95 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -86,7 +86,7 @@
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     newFile('/project/bin/myLib.dart',
         content:
-            'library L; part "${convertPathForImport(testFile)}"; class A {static int s2;}');
+            'library L; part "${convertAbsolutePathToUri(testFile)}"; class A {static int s2;}');
     addTestFile('part of L; foo() {A.^}');
     await getSuggestionsWith({
       'L.A': ['s2']
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index b9546e7..263f905 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -41,7 +41,7 @@
     addSource('/libB.dart', '''
 library libB;
 import "/libA.dart" as foo;
-part '${convertPathForImport(testFile)}';
+part '${convertAbsolutePathToUri(testFile)}';
 ''');
     addTestSource('part of libB; main() {^}');
 
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 556616f..26100ebf 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -40,7 +40,7 @@
 ''');
 
     addTestSource('''
-import "${convertPathForImport('/testB.dart')}";
+import "${convertAbsolutePathToUri('/testB.dart')}";
 
 void main() {f^}''');
     await computeSuggestions();
@@ -56,7 +56,7 @@
         bool hasLength(int expected) { }
         void baz() { }''');
     addTestSource('''
-        import '${convertPathForImport('/libA.dart')}';
+        import '${convertAbsolutePathToUri('/libA.dart')}';
         class B { }
         String bar() => true;
         void main() {expect(^)}''');
@@ -83,7 +83,7 @@
         expect(arg) { }
         void baz() { }''');
     addTestSource('''
-        import '${convertPathForImport('/libA.dart')}'
+        import '${convertAbsolutePathToUri('/libA.dart')}'
         class B { }
         String bar() => true;
         void main() {expect(^)}''');
@@ -111,7 +111,7 @@
         void baz() { }''');
     addTestSource('''
         import 'dart:async';
-        import '${convertPathForImport('/libA.dart')}';
+        import '${convertAbsolutePathToUri('/libA.dart')}';
         class B { }
         String bar() => true;
         void main() {new A(^)}''');
@@ -143,7 +143,7 @@
         void baz() { }''');
     addTestSource('''
         import 'dart:async';
-        import '${convertPathForImport('/libA.dart')}';
+        import '${convertAbsolutePathToUri('/libA.dart')}';
         class B { }
         String bar() => true;
         void main() {new A(^)}''');
@@ -172,7 +172,7 @@
         bool hasLength(int expected) { }
         void baz() { }''');
     addTestSource('''
-        import '${convertPathForImport('/libA.dart')}'
+        import '${convertAbsolutePathToUri('/libA.dart')}'
         expect(arg) { }
         class B { }
         String bar() => true;
@@ -199,7 +199,7 @@
         bool hasLength(int expected) { }
         void baz() { }''');
     addTestSource('''
-        import '${convertPathForImport('/libA.dart')}'
+        import '${convertAbsolutePathToUri('/libA.dart')}'
         class B {
           expect(arg) { }
           void foo() {expect(^)}}
@@ -228,7 +228,7 @@
         void baz() { }''');
     addTestSource('''
         import 'dart:async';
-        import '${convertPathForImport('/libA.dart')}';
+        import '${convertAbsolutePathToUri('/libA.dart')}';
         class B { }
         String bar(f()) => true;
         void main() {bar(^);}''');
@@ -259,7 +259,7 @@
         void baz() { }''');
     addTestSource('''
         import 'dart:async';
-        import '${convertPathForImport('/libA.dart')}';
+        import '${convertAbsolutePathToUri('/libA.dart')}';
         class B { String bar(f()) => true; }
         void main() {new B().bar(^);}''');
 
@@ -286,7 +286,7 @@
         library A;
         bool hasLength(int expected) { }''');
     addTestSource('''
-        import '${convertPathForImport('/libA.dart')}'
+        import '${convertAbsolutePathToUri('/libA.dart')}'
         String bar() => true;
         void main() {expect(foo: ^)}''');
 
@@ -325,7 +325,7 @@
           class A {} class B extends A {} class C extends B {}
           class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-          import "${convertPathForImport('/testB.dart')}";
+          import "${convertAbsolutePathToUri('/testB.dart')}";
          main(){A a; if (a as ^)}''');
 
     await computeSuggestions();
@@ -347,7 +347,7 @@
           class A {} class B implements A {} class C implements B {}
           class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-          import "${convertPathForImport('/testB.dart')}";
+          import "${convertAbsolutePathToUri('/testB.dart')}";
           main(){A a; if (a as ^)}''');
 
     await computeSuggestions();
@@ -495,7 +495,7 @@
 Future y() async {return 0;}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   int x;
   foo() async {await ^}
@@ -517,7 +517,7 @@
   Future y() async { return 0; }
 }''');
     addTestSource('''
-import "${convertPathForImport('/testB.dart')}";
+import "${convertAbsolutePathToUri('/testB.dart')}";
 class B extends A {
   foo() async {await ^}
 }
@@ -584,10 +584,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testAB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g;
+        import "${convertAbsolutePathToUri('/testAB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g;
         int T5;
         var _T6;
         String get T7 => 'hello';
@@ -687,10 +687,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testAB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g;
+        import "${convertAbsolutePathToUri('/testAB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g;
         int T5;
         var _T6;
         String get T7 => 'hello';
@@ -800,10 +800,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testAB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g hide G;
+        import "${convertAbsolutePathToUri('/testAB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g hide G;
         int T5;
         var _T6;
         String get T7 => 'hello';
@@ -901,10 +901,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testAB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g;
+        import "${convertAbsolutePathToUri('/testAB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g;
         int T5;
         var _T6;
         String get T7 => 'hello';
@@ -1000,10 +1000,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testAB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g;
+        import "${convertAbsolutePathToUri('/testAB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g;
         int T5;
         var _T6;
         Z D2() {int x;}
@@ -1065,7 +1065,7 @@
         class I { int i1; i2() { } }
         class M { var m1; int m2() { } }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class A extends E implements I with M {a() {^}}''');
 
     await computeSuggestions();
@@ -1131,10 +1131,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testAB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g;
+        import "${convertAbsolutePathToUri('/testAB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g;
         int T5;
         var _T6;
         String get T7 => 'hello';
@@ -1183,10 +1183,10 @@
         int T3;
         var _T4;'''); // not imported
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
-        import "${convertPathForImport('/testCD.dart')}" hide D;
-        import "${convertPathForImport('/testEEF.dart')}" show EE;
-        import "${convertPathForImport('/testG.dart')}" as g;
+        import "${convertAbsolutePathToUri('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testCD.dart')}" hide D;
+        import "${convertAbsolutePathToUri('/testEEF.dart')}" show EE;
+        import "${convertAbsolutePathToUri('/testG.dart')}" as g;
         int T5;
         var _T6;
         Z D2() {int x;}
@@ -1221,7 +1221,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class A {var b; X _c;}
         class X{}
         // looks like a cascade to the parser
@@ -1246,7 +1246,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class A {var b; X _c;}
         class X{}
         main() {A a; a..^z}''');
@@ -1269,7 +1269,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class A {var b; X _c;}
         class X{}
         main() {A a; a..^ return}''');
@@ -1364,7 +1364,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('testB.dart')}" as x;
+        import "${convertAbsolutePathToUri('testB.dart')}" as x;
         @deprecated class A {^}
         class _B {}
         A T;''');
@@ -1389,7 +1389,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('testB.dart')}" as x;
+        import "${convertAbsolutePathToUri('testB.dart')}" as x;
         class A {final ^}
         class _B {}
         A T;''');
@@ -1410,7 +1410,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('testB.dart')}" as x;
+        import "${convertAbsolutePathToUri('testB.dart')}" as x;
         class A {final ^ A(){}}
         class _B {}
         A T;''');
@@ -1431,7 +1431,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('testB.dart')}" as Soo;
+        import "${convertAbsolutePathToUri('testB.dart')}" as Soo;
         class A {final S^ A();}
         class _B {}
         A Sew;''');
@@ -1452,7 +1452,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('testB.dart')}" as x;
+        import "${convertAbsolutePathToUri('testB.dart')}" as x;
         class A {final ^ final foo;}
         class _B {}
         A T;''');
@@ -1473,7 +1473,7 @@
     addSource('/testB.dart', '''
         class B { }''');
     addTestSource('''
-        import "${convertPathForImport('testB.dart')}" as x;
+        import "${convertAbsolutePathToUri('testB.dart')}" as x;
         class A {final ^ var foo;}
         class _B {}
         A T;''');
@@ -1505,8 +1505,8 @@
         class C { }
         class D { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}" hide ^;
-        import "${convertPathForImport('/testCD.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}" hide ^;
+        import "${convertAbsolutePathToUri('/testCD.dart')}";
         class X {}''');
 
     await computeSuggestions();
@@ -1531,8 +1531,8 @@
         class C { }
         class D { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}" show ^;
-        import "${convertPathForImport('/testCD.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}" show ^;
+        import "${convertAbsolutePathToUri('/testCD.dart')}";
         class X {}''');
 
     await computeSuggestions();
@@ -1546,7 +1546,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -1566,7 +1566,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -1595,7 +1595,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -1615,7 +1615,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -1644,7 +1644,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -1666,7 +1666,7 @@
         F1() { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         var m;
         main() {new X.^}''');
 
@@ -1691,7 +1691,7 @@
         F1() { }
         class X {factory X.c(); factory X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         var m;
         main() {new X.^}''');
 
@@ -1794,7 +1794,8 @@
 /// Longer description.
 class A {}
 ''');
-    addTestSource('import "${convertPathForImport('/libA.dart')}"; main() {^}');
+    addTestSource(
+        'import "${convertAbsolutePathToUri('/libA.dart')}"; main() {^}');
 
     await computeSuggestions();
 
@@ -1816,7 +1817,8 @@
 /// Longer description.
 int myFunc() {}
 ''');
-    addTestSource('import "${convertPathForImport('/libA.dart')}"; main() {^}');
+    addTestSource(
+        'import "${convertAbsolutePathToUri('/libA.dart')}"; main() {^}');
 
     await computeSuggestions();
 
@@ -1837,7 +1839,8 @@
  */
 int myFunc() {}
 ''');
-    addTestSource('import "${convertPathForImport('/libA.dart')}"; main() {^}');
+    addTestSource(
+        'import "${convertAbsolutePathToUri('/libA.dart')}"; main() {^}');
 
     await computeSuggestions();
 
@@ -1849,7 +1852,8 @@
 
   test_enum() async {
     addSource('/libA.dart', 'library A; enum E { one, two }');
-    addTestSource('import "${convertPathForImport('/libA.dart')}"; main() {^}');
+    addTestSource(
+        'import "${convertAbsolutePathToUri('/libA.dart')}"; main() {^}');
     await computeSuggestions();
     assertSuggestEnum('E');
     assertNotSuggested('one');
@@ -1858,7 +1862,8 @@
 
   test_enum_deprecated() async {
     addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
-    addTestSource('import "${convertPathForImport('/libA.dart')}"; main() {^}');
+    addTestSource(
+        'import "${convertAbsolutePathToUri('/libA.dart')}"; main() {^}');
     await computeSuggestions();
     // TODO(danrube) investigate why suggestion/element is not deprecated
     // when AST node has correct @deprecated annotation
@@ -1899,7 +1904,7 @@
         class A {int x;}
         class _B { }''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         typedef int F2(int blat);
         class Clz = Object with Object;
         class C {foo(){^} void bar() {}}''');
@@ -1928,7 +1933,7 @@
         B T1;
         class B{}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         class C {a() {C ^}}''');
 
     await computeSuggestions();
@@ -1940,7 +1945,7 @@
     // FieldDeclaration
     addSource('/testA.dart', 'class A { }');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         class C {A ^}''');
 
     await computeSuggestions();
@@ -1952,7 +1957,7 @@
     // FieldDeclaration
     addSource('/testA.dart', 'class A { }');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         class C {var ^}''');
 
     await computeSuggestions();
@@ -2136,7 +2141,7 @@
 int m(x, {int y}) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -2157,7 +2162,7 @@
 void m(x, [int y]) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -2178,7 +2183,7 @@
 void m({x, int y}) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -2199,7 +2204,7 @@
 void m() {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -2218,7 +2223,7 @@
 void m([x, int y]) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -2239,7 +2244,7 @@
 void m(x, int y) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -2263,7 +2268,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -2293,7 +2298,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -2323,7 +2328,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -2474,7 +2479,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -2503,7 +2508,7 @@
         F1() { }
         class A {int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         class B {int x;}
@@ -2522,7 +2527,7 @@
 class B {B(this.x, [String boo]) { } int x;}
 class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
     addTestSource('''
-import "${convertPathForImport('/testA.dart')}";
+import "${convertAbsolutePathToUri('/testA.dart')}";
 import "dart:math" as math;
 main() {new ^ String x = "hello";}''');
 
@@ -2639,7 +2644,7 @@
         F1() { }
         class A {A(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         import "dart:async";
         int T2;
         F2() { }
@@ -2701,7 +2706,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -2736,7 +2741,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -2809,7 +2814,7 @@
         foo() { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class Y {Y.c(); Y._d(); z() {}}
         main() {var x; if (x is ^) { }}''');
 
@@ -2879,7 +2884,7 @@
         class A {} class B extends A {} class C extends B {}
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         main(){A a; if (a is ^)}''');
 
     await computeSuggestions();
@@ -2901,7 +2906,7 @@
         class A {} class B implements A {} class C implements B {}
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         main(){A a; if (a is ^)}''');
 
     await computeSuggestions();
@@ -2924,7 +2929,7 @@
         nowIsIt() { }
         class X {factory X.c(); factory X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         String newer() {}
         var m;
         main() {new^ X.c();}''');
@@ -2984,7 +2989,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3021,7 +3026,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3048,7 +3053,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3067,7 +3072,7 @@
 void m(x, {int y}) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3088,7 +3093,7 @@
 void m(x, [int y]) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3109,7 +3114,7 @@
 void m({x, int y}) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3130,7 +3135,7 @@
 void m() {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3149,7 +3154,7 @@
 void m([x, int y]) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3170,7 +3175,7 @@
 void m(x, int y) {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B {
   main() {^}
 }
@@ -3207,7 +3212,7 @@
           static c3() {}
           static var c4;}''');
     addTestSource('''
-        import "${convertPathForImport('/testC.dart')}";
+        import "${convertAbsolutePathToUri('/testC.dart')}";
         class B extends C {
           b1() {}
           var b2;
@@ -3294,7 +3299,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3323,7 +3328,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3352,7 +3357,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3381,7 +3386,7 @@
         typedef D1();
         class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         int T2;
         F2() { }
         typedef D2();
@@ -3448,7 +3453,7 @@
 }
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class C extends B with M1, M2 {
   void f() {
     ^
@@ -3487,8 +3492,8 @@
       class ClassInLocalContext {int x;}''');
     testFile = '/context1/completionTest.dart';
     addTestSource('''
-      import "${convertPathForImport("/context1/libA.dart")}";
-      import "${convertPathForImport("/foo.dart")}";
+      import "${convertAbsolutePathToUri("/context1/libA.dart")}";
+      import "${convertAbsolutePathToUri("/foo.dart")}";
       main() {C^}
       ''');
 
@@ -3518,7 +3523,7 @@
 int x;
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3533,7 +3538,7 @@
 int get x => null;
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3548,7 +3553,7 @@
 set x(int value) {};
 ''');
     addTestSource('''
-import '${convertPathForImport('/libA.dart')}';
+import '${convertAbsolutePathToUri('/libA.dart')}';
 class B extends A {
   main() {^}
 }
@@ -3574,8 +3579,8 @@
         class X {X.c(); X._d(); z() {}}''');
     addSource('/testA.dart', '''
         library libA;
-        import "${convertPathForImport('/testB.dart')}";
-        part "${convertPathForImport(testFile)}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
+        part "${convertAbsolutePathToUri(testFile)}";
         class A { }
         var m;''');
     addTestSource('''
@@ -3613,7 +3618,7 @@
         class B { }''');
     addTestSource('''
         library libA;
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         part "testA.dart";
         class A { A({String boo: 'hoo'}) { } }
         main() {new ^}
@@ -3653,7 +3658,7 @@
           m(X x) {} I _n(X x) {}}
         class X{}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class A extends B {
           static const String scA = 'foo';
           w() { }}
@@ -3697,7 +3702,7 @@
           m(X x) {} I _n(X x) {}}
         class X{}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         main() {A a; a.^}''');
 
     await computeSuggestions();
@@ -3771,7 +3776,7 @@
         class X { }
         class Y { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}" as b;
+        import "${convertAbsolutePathToUri('/testB.dart')}" as b;
         var T2;
         class A { }
         main() {b.^}''');
@@ -3798,7 +3803,7 @@
         class X { }
         class Y { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}" as b;
+        import "${convertAbsolutePathToUri('/testB.dart')}" as b;
         var T2;
         class A { }
         foo(b.^ f) {}''');
@@ -3825,7 +3830,7 @@
         class X { }
         class Y { }''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}" as b;
+        import "${convertAbsolutePathToUri('/testB.dart')}" as b;
         var T2;
         class A { }
         foo(b.^) {}''');
@@ -3852,7 +3857,7 @@
         class X extends _W {}
         class M{}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         foo(X x) {x.^}''');
 
     await computeSuggestions();
@@ -3869,7 +3874,7 @@
         class A {static int bar = 10;}
         _B() {}''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";
+        import "${convertAbsolutePathToUri('/testA.dart')}";
         class X {foo(){A^.bar}}''');
 
     await computeSuggestions();
@@ -4314,7 +4319,7 @@
         F1() => 0;
         typedef String T1(int blat);''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";'
+        import "${convertAbsolutePathToUri('/testA.dart')}";'
         class C2 {int x;}
         F2() => 0;
         typedef int T2(int blat);
@@ -4340,7 +4345,7 @@
         F1() => 0;
         typedef String T1(int blat);''');
     addTestSource('''
-        import "${convertPathForImport('/testA.dart')}";'
+        import "${convertAbsolutePathToUri('/testA.dart')}";'
         class C2 {int x;}
         F2() => 0;
         typedef int T2(int blat);
@@ -4364,7 +4369,7 @@
 class B {}
 ''');
     addTestSource('''
-import '${convertPathForImport('/testB.dart')}';
+import '${convertAbsolutePathToUri('/testB.dart')}';
 List<^> x;
 ''');
     await computeSuggestions();
@@ -4383,7 +4388,7 @@
         class _B { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class Y {Y.c(); Y._d(); z() {}}
         main() {var ^}''');
 
@@ -4410,7 +4415,7 @@
         class _B { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         class Y {Y.c(); Y._d(); z() {}}
         class C {bar(){var f; {var x;} var e = ^}}''');
 
@@ -4436,7 +4441,7 @@
         class _B { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport('/testB.dart')}";
+        import "${convertAbsolutePathToUri('/testB.dart')}";
         foo2() { }
         void bar2() { }
         class Y {Y.c(); Y._d(); z() {}}
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index 3f3f9fc..0bf6a76 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -91,7 +91,7 @@
     addSource(libFile, '''
         library testA;
         import "dart:async" deferred as bar;
-        part "${convertPathForImport(testFile)}";''');
+        part "${convertAbsolutePathToUri(testFile)}";''');
     addTestSource('part of testA; foo() {bar.^}');
     // Assume that libraries containing has been computed for part files
     await computeLibrariesContaining();
@@ -105,11 +105,11 @@
     addSource('/libA.dart', 'library libA; class A { }');
     addSource('/libB.dart', '''
         library libB;
-        export "${convertPathForImport("/libA.dart")}";
+        export "${convertAbsolutePathToUri("/libA.dart")}";
         class B { }
         @deprecated class B1 { }''');
     addTestSource(
-        'import "${convertPathForImport("/libB.dart")}" as foo; main() {foo.^} class C { }');
+        'import "${convertAbsolutePathToUri("/libB.dart")}" as foo; main() {foo.^} class C { }');
     await computeSuggestions();
     assertSuggestClass('B');
     assertSuggestClass('B1', relevance: DART_RELEVANCE_LOW, isDeprecated: true);
@@ -125,7 +125,7 @@
         class X { }
         class Y { }''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}" as b;
+        import "${convertAbsolutePathToUri("/testB.dart")}" as b;
         var T2;
         class A { }
         main() {b.^}''');
@@ -187,8 +187,8 @@
         class Y { }''');
     addSource(libFile, '''
         library testA;
-        import "${convertPathForImport("/testB.dart")}" as b;
-        part "${convertPathForImport(testFile)}";
+        import "${convertAbsolutePathToUri("/testB.dart")}" as b;
+        part "${convertAbsolutePathToUri(testFile)}";
         var T2;
         class A { }''');
     addTestSource('''
@@ -217,7 +217,7 @@
         class X { }
         class Y { }''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}" as b;
+        import "${convertAbsolutePathToUri("/testB.dart")}" as b;
         var T2;
         class A { }
         foo(b.^ f) {}''');
@@ -242,7 +242,7 @@
         class X { }
         class Y { }''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}" as b;
+        import "${convertAbsolutePathToUri("/testB.dart")}" as b;
         var T2;
         class A { }
         foo(b.^) {}''');
@@ -267,7 +267,7 @@
         class X extends _W {}
         class M{}''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
         foo(X x) {x.^}''');
     await computeSuggestions();
     assertNoSuggestions();
@@ -279,7 +279,7 @@
         class A {static int bar = 10;}
         _B() {}''');
     addTestSource('''
-        import "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testA.dart")}";
         class X {foo(){A^.bar}}''');
     await computeSuggestions();
     assertNoSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
index 5fb24d4..052103e 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -297,9 +297,9 @@
 class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
     addSource('/testB.dart', '''
 library testB;
-import "${convertPathForImport("/testA.dart")}" as t;
+import "${convertAbsolutePathToUri("/testA.dart")}" as t;
 import "dart:math" as math;
-part "${convertPathForImport(testFile)}"
+part "${convertAbsolutePathToUri(testFile)}"
 main() {new ^ String x = "hello";}''');
     addTestSource('''
 part of testB;
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index e3d07b2..07d9364 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -31,8 +31,8 @@
         class X {X.c(); X._d(); z() {}}''');
     addSource('/testA.dart', '''
         library libA;
-        import "${convertPathForImport("/testB.dart")}";
-        part "${convertPathForImport(testFile)}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
+        part "${convertAbsolutePathToUri(testFile)}";
         class A { }
         var m;''');
     addTestSource('''
@@ -69,8 +69,8 @@
         class B { }''');
     addTestSource('''
         library libA;
-        import "${convertPathForImport("/testB.dart")}";
-        part "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
+        part "${convertAbsolutePathToUri("/testA.dart")}";
         class A { A({String boo: 'hoo'}) { } }
         main() {new ^}
         var m;''');
@@ -105,8 +105,8 @@
         ''');
     addTestSource('''
         library libA;
-        import "${convertPathForImport("/testB.dart")}";
-        part "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
+        part "${convertAbsolutePathToUri("/testA.dart")}";
         class Local { }
         main() {
           A a;
@@ -158,8 +158,8 @@
         ''');
     addTestSource('''
         library libA;
-        import "${convertPathForImport("/testB.dart")}";
-        part "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
+        part "${convertAbsolutePathToUri("/testA.dart")}";
         class Local { }
         main() {
           A a = new ^
@@ -204,8 +204,8 @@
         class X {X.c(); X._d(); z() {}}''');
     addSource('/testA.dart', '''
         library libA;
-        import "${convertPathForImport("/testB.dart")}";
-        part "${convertPathForImport(testFile)}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
+        part "${convertAbsolutePathToUri(testFile)}";
         class A { var a1; a2(){}}
         var m;
         typedef t1(int blue);
@@ -256,8 +256,8 @@
         var n;''');
     addTestSource('''
         library libA;
-        import "${convertPathForImport("/testB.dart")}";
-        part "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
+        part "${convertAbsolutePathToUri("/testA.dart")}";
         class A { A({String boo: 'hoo'}) { } }
         main() {^}
         var m;''');
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 3987353..e96883c 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -142,7 +142,7 @@
 bool hasLength(int expected) { }
 void baz() { }''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 class B { }
 String bar() => true;
 void main() {expect(^)}''');
@@ -170,7 +170,7 @@
 expect(arg) { }
 void baz() { }''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}"
+import "${convertAbsolutePathToUri('/libA.dart')}"
 class B { }
 String bar() => true;
 void main() {expect(^)}''');
@@ -199,7 +199,7 @@
 void baz() { }''');
     addTestSource('''
 import 'dart:async';
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 class B { }
 String bar() => true;
 void main() {new A(^)}''');
@@ -231,7 +231,7 @@
 void baz() { }''');
     addTestSource('''
 import 'dart:async';
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 class B { }
 String bar() => true;
 void main() {new A(^)}''');
@@ -260,7 +260,7 @@
 bool hasLength(int expected) { }
 void baz() { }''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}"
+import "${convertAbsolutePathToUri('/libA.dart')}"
 expect(arg) { }
 class B { }
 String bar() => true;
@@ -288,7 +288,7 @@
 bool hasLength(int expected) { }
 void baz() { }''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}"
+import "${convertAbsolutePathToUri('/libA.dart')}"
 class B {
   expect(arg) { }
   void foo() {expect(^)}}
@@ -318,7 +318,7 @@
 void baz() { }''');
     addTestSource('''
 import 'dart:async';
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 class B { }
 String bar(f()) => true;
 void main() {boo(){} bar(^);}''');
@@ -352,7 +352,7 @@
 void baz() { }''');
     addTestSource('''
 import 'dart:async';
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 class B { }
 String bar({inc()}) => true;
 void main() {boo(){} bar(inc: ^);}''');
@@ -388,7 +388,7 @@
 void baz() { }''');
     addTestSource('''
 import 'dart:async';
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 class B { String bar(f()) => true; }
 void main() {new B().bar(^);}''');
     await computeSuggestions();
@@ -416,7 +416,7 @@
 }
 ''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 
 class PageState {
   void _incrementCounter() { }
@@ -442,7 +442,7 @@
 library A;
 bool hasLength(int expected) { }''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}"
+import "${convertAbsolutePathToUri('/libA.dart')}"
 String bar() => true;
 void main() {expect(foo: ^)}''');
     await computeSuggestions();
@@ -501,7 +501,7 @@
 }
 ''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 
 class PageState {
   void _incrementCounter() { }
@@ -529,7 +529,7 @@
 }
 ''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 
 class PageState {
   void _incrementCounter() { }
@@ -557,7 +557,7 @@
 }
 ''');
     addTestSource('''
-import "${convertPathForImport('/libA.dart')}";
+import "${convertAbsolutePathToUri('/libA.dart')}";
 
 class PageState {
   void _incrementCounter() { }
@@ -841,10 +841,10 @@
 int T3;
 var _T4;'''); // not imported
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}";
-import "${convertPathForImport("/testCD.dart")}" hide D;
-import "${convertPathForImport("/testEEF.dart")}" show EE;
-import "${convertPathForImport("/testG.dart")}" as g;
+import "${convertAbsolutePathToUri("/testAB.dart")}";
+import "${convertAbsolutePathToUri("/testCD.dart")}" hide D;
+import "${convertAbsolutePathToUri("/testEEF.dart")}" show EE;
+import "${convertAbsolutePathToUri("/testG.dart")}" as g;
 int T5;
 var _T6;
 String get T7 => 'hello';
@@ -939,10 +939,10 @@
 int T3;
 var _T4;'''); // not imported
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}";
-import "${convertPathForImport("/testCD.dart")}" hide D;
-import "${convertPathForImport("/testEEF.dart")}" show EE;
-import "${convertPathForImport("/testG.dart")}" as g;
+import "${convertAbsolutePathToUri("/testAB.dart")}";
+import "${convertAbsolutePathToUri("/testCD.dart")}" hide D;
+import "${convertAbsolutePathToUri("/testEEF.dart")}" show EE;
+import "${convertAbsolutePathToUri("/testG.dart")}" as g;
 int T5;
 var _T6;
 String get T7 => 'hello';
@@ -1052,10 +1052,10 @@
 int T3;
 var _T4;'''); // not imported
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}";
-import "${convertPathForImport("/testCD.dart")}" hide D;
-import "${convertPathForImport("/testEEF.dart")}" show EE;
-import "${convertPathForImport("/testG.dart")}" as g;
+import "${convertAbsolutePathToUri("/testAB.dart")}";
+import "${convertAbsolutePathToUri("/testCD.dart")}" hide D;
+import "${convertAbsolutePathToUri("/testEEF.dart")}" show EE;
+import "${convertAbsolutePathToUri("/testG.dart")}" as g;
 int T5;
 var _T6;
 String get T7 => 'hello';
@@ -1151,10 +1151,10 @@
 int T3;
 var _T4;'''); // not imported
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}";
-import "${convertPathForImport("/testCD.dart")}" hide D;
-import "${convertPathForImport("/testEEF.dart")}" show EE;
-import "${convertPathForImport("/testG.dart")}" as g;
+import "${convertAbsolutePathToUri("/testAB.dart")}";
+import "${convertAbsolutePathToUri("/testCD.dart")}" hide D;
+import "${convertAbsolutePathToUri("/testEEF.dart")}" show EE;
+import "${convertAbsolutePathToUri("/testG.dart")}" as g;
 int T5;
 var _T6;
 String get T7 => 'hello';
@@ -1250,10 +1250,10 @@
 int T3;
 var _T4;'''); // not imported
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}";
-import "${convertPathForImport("/testCD.dart")}" hide D;
-import "${convertPathForImport("/testEEF.dart")}" show EE;
-import "${convertPathForImport("/testG.dart")}" as g;
+import "${convertAbsolutePathToUri("/testAB.dart")}";
+import "${convertAbsolutePathToUri("/testCD.dart")}" hide D;
+import "${convertAbsolutePathToUri("/testEEF.dart")}" show EE;
+import "${convertAbsolutePathToUri("/testG.dart")}" as g;
 int T5;
 var _T6;
 Z D2() {int x;}
@@ -1317,7 +1317,7 @@
 class I { int i1; i2() { } }
 class M { var m1; int m2() { } }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class A extends E implements I with M {a() {^}}''');
     await computeSuggestions();
 
@@ -1383,10 +1383,10 @@
 int T3;
 var _T4;'''); // not imported
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}";
-import "${convertPathForImport("/testCD.dart")}" hide D;
-import "${convertPathForImport("/testEEF.dart")}" show EE;
-import "${convertPathForImport("/testG.dart")}" as g;
+import "${convertAbsolutePathToUri("/testAB.dart")}";
+import "${convertAbsolutePathToUri("/testCD.dart")}" hide D;
+import "${convertAbsolutePathToUri("/testEEF.dart")}" show EE;
+import "${convertAbsolutePathToUri("/testG.dart")}" as g;
 int T5;
 var _T6;
 String get T7 => 'hello';
@@ -1435,7 +1435,7 @@
     addSource('/testB.dart', '''
 class B { }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class A {var b; X _c;}
 class X{}
 // looks like a cascade to the parser
@@ -1460,7 +1460,7 @@
     addSource('/testB.dart', '''
 class B { }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class A {var b; X _c;}
 class X{}
 main() {A a; a..^z}''');
@@ -1483,7 +1483,7 @@
     addSource('/testB.dart', '''
 class B { }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class A {var b; X _c;}
 class X{}
 main() {A a; a..^ return}''');
@@ -1724,8 +1724,8 @@
 class C { }
 class D { }''');
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}" hide ^;
-import "${convertPathForImport("/testCD.dart")}";
+import "${convertAbsolutePathToUri("/testAB.dart")}" hide ^;
+import "${convertAbsolutePathToUri("/testCD.dart")}";
 class X {}''');
     await computeSuggestions();
 
@@ -1750,8 +1750,8 @@
 class C { }
 class D { }''');
     addTestSource('''
-import "${convertPathForImport("/testAB.dart")}" show ^;
-import "${convertPathForImport("/testCD.dart")}";
+import "${convertAbsolutePathToUri("/testAB.dart")}" show ^;
+import "${convertAbsolutePathToUri("/testCD.dart")}";
 class X {}''');
     await computeSuggestions();
 
@@ -1765,7 +1765,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -1786,7 +1786,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -1814,7 +1814,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -1835,7 +1835,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -1863,7 +1863,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -1921,7 +1921,7 @@
 F1() { }
 class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 var m;
 main() {new X.^}''');
     await computeSuggestions();
@@ -1946,7 +1946,7 @@
 F1() { }
 class X {factory X.c(); factory X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 var m;
 main() {new X.^}''');
     await computeSuggestions();
@@ -2276,7 +2276,7 @@
 class A {int x;}
 class _B { }''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 typedef int F2(int blat);
 class Clz = Object with Object;
 class C {foo(){^} void bar() {}}''');
@@ -2304,7 +2304,7 @@
         B T1;
         class B{}''');
     addTestSource('''
-        import "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testA.dart")}";
         class C {a() {C ^}}''');
     await computeSuggestions();
 
@@ -2316,7 +2316,7 @@
     // FieldDeclaration
     addSource('/testA.dart', 'class A { }');
     addTestSource('''
-        import "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testA.dart")}";
         class C {A ^}''');
     await computeSuggestions();
 
@@ -2328,7 +2328,7 @@
     // FieldDeclaration
     addSource('/testA.dart', 'class A { }');
     addTestSource('''
-        import "${convertPathForImport("/testA.dart")}";
+        import "${convertAbsolutePathToUri("/testA.dart")}";
         class C {var ^}''');
     await computeSuggestions();
 
@@ -2643,7 +2643,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -2673,7 +2673,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -2703,7 +2703,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -2866,7 +2866,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -2894,7 +2894,7 @@
 F1() { }
 class A {int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 class B {int x;}
@@ -2932,7 +2932,7 @@
 F1() { }
 class A {A(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 import "dart:async";
 int T2;
 F2() { }
@@ -2977,7 +2977,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3008,7 +3008,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3080,7 +3080,7 @@
 foo() { }
 class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class Y {Y.c(); Y._d(); z() {}}
 main() {var x; if (x is ^) { }}''');
     await computeSuggestions();
@@ -3197,7 +3197,7 @@
 nowIsIt() { }
 class X {factory X.c(); factory X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 String newer() {}
 var m;
 main() {new^ X.c();}''');
@@ -3260,7 +3260,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3290,7 +3290,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3313,7 +3313,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3442,7 +3442,7 @@
   static c3() {}
   static var c4;}''');
     addTestSource('''
-import "${convertPathForImport("/testC.dart")}";
+import "${convertAbsolutePathToUri("/testC.dart")}";
 class B extends C {
   b1() {}
   var b2;
@@ -3582,7 +3582,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3611,7 +3611,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3640,7 +3640,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3669,7 +3669,7 @@
 typedef D1();
 class C1 {C1(this.x) { } int x;}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 int T2;
 F2() { }
 typedef D2();
@@ -3854,7 +3854,7 @@
   m(X x) {} I _n(X x) {}}
 class X{}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class A extends B {
   static const String scA = 'foo';
   w() { }}
@@ -3898,7 +3898,7 @@
   m(X x) {} I _n(X x) {}}
 class X{}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 main() {A a; a.^}''');
     await computeSuggestions();
 
@@ -3972,7 +3972,7 @@
 class X { }
 class Y { }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}" as b;
+import "${convertAbsolutePathToUri("/testB.dart")}" as b;
 var T2;
 class A { }
 main() {b.^}''');
@@ -3999,7 +3999,7 @@
 class X { }
 class Y { }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}" as b;
+import "${convertAbsolutePathToUri("/testB.dart")}" as b;
 var T2;
 class A { }
 foo(b.^ f) {}''');
@@ -4026,7 +4026,7 @@
 class X { }
 class Y { }''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}" as b;
+import "${convertAbsolutePathToUri("/testB.dart")}" as b;
 var T2;
 class A { }
 foo(b.^) {}''');
@@ -4053,7 +4053,7 @@
 class X extends _W {}
 class M{}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 foo(X x) {x.^}''');
     await computeSuggestions();
 
@@ -4070,7 +4070,7 @@
 class A {static int bar = 10;}
 _B() {}''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";
+import "${convertAbsolutePathToUri("/testA.dart")}";
 class X {foo(){A^.bar}}''');
     await computeSuggestions();
 
@@ -4554,7 +4554,7 @@
 F1() => 0;
 typedef String T1(int blat);''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";'
+import "${convertAbsolutePathToUri("/testA.dart")}";'
 class C2 {int x;}
 F2() => 0;
 typedef int T2(int blat);
@@ -4580,7 +4580,7 @@
 F1() => 0;
 typedef String T1(int blat);''');
     addTestSource('''
-import "${convertPathForImport("/testA.dart")}";'
+import "${convertAbsolutePathToUri("/testA.dart")}";'
 class C2 {int x;}
 F2() => 0;
 typedef int T2(int blat);
@@ -4603,7 +4603,7 @@
 class _B { }
 class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class Y {Y.c(); Y._d(); z() {}}
 main() {var ^}''');
     await computeSuggestions();
@@ -4630,7 +4630,7 @@
 class _B { }
 class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 class Y {Y.c(); Y._d(); z() {}}
 class C {bar(){var f; {var x;} var e = ^}}''');
     await computeSuggestions();
@@ -4656,7 +4656,7 @@
 class _B { }
 class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-import "${convertPathForImport("/testB.dart")}";
+import "${convertAbsolutePathToUri("/testB.dart")}";
 foo2() { }
 void bar2() { }
 class Y {Y.c(); Y._d(); z() {}}
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
index 499eb2b..ea0d067 100644
--- a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -51,7 +51,7 @@
         F1() { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
         var m;
         main() {new X.^}''');
 
@@ -75,7 +75,7 @@
         F1() { }
         class X {X.c(); X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
         var m;
         main() {new X.^}''');
     // Assume that imported libraries are NOT resolved
@@ -100,7 +100,7 @@
         F1() { }
         class X {factory X.c(); factory X._d(); z() {}}''');
     addTestSource('''
-        import "${convertPathForImport("/testB.dart")}";
+        import "${convertAbsolutePathToUri("/testB.dart")}";
         var m;
         main() {new X.^}''');
 
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index 61a9a87c..8d5a329 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -95,8 +95,8 @@
   test_fromPart() async {
     addSource('/myLib.dart', '''
 library myLib;
-part '${convertPathForImport(testFile)}'
-part '${convertPathForImport('/otherPart.dart')}'
+part '${convertAbsolutePathToUri(testFile)}'
+part '${convertAbsolutePathToUri('/otherPart.dart')}'
 class A {
   A suggested1(int x) => null;
   B suggested2(String y) => null;
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index a20b367..a39270d 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -3094,7 +3094,7 @@
     addTestSource('''
         library libA;
         import "testB.dart";
-        part "${convertPathForImport('/testA.dart')}";
+        part "${convertAbsolutePathToUri('/testA.dart')}";
         class A { A({String boo: 'hoo'}) { } }
         main() {new ^}
         var m;''');
diff --git a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
index f1f2c23..36c4d2d 100644
--- a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
@@ -54,6 +54,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
   }
 
   test_ExpressionStatement_long_semicolon() async {
@@ -68,6 +74,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
   }
 
   test_ExpressionStatement_prefixed() async {
@@ -82,6 +94,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
   }
 
   test_ExpressionStatement_prefixed_semicolon() async {
@@ -96,6 +114,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
   }
 
   test_ExpressionStatement_short() async {
@@ -106,6 +130,8 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestName('a');
+    // private version
+    assertNotSuggested('_a');
   }
 
   test_ExpressionStatement_short_semicolon() async {
@@ -116,6 +142,8 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestName('a');
+    // private version
+    assertNotSuggested('_a');
   }
 
   test_TopLevelVariableDeclaration_dont_suggest_type() async {
@@ -126,6 +154,8 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertNotSuggested('a');
+    // private version
+    assertNotSuggested('_a');
   }
 
   test_TopLevelVariableDeclaration_dont_suggest_type_semicolon() async {
@@ -136,6 +166,8 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertNotSuggested('a');
+    // private version
+    assertNotSuggested('_a');
   }
 
   test_TopLevelVariableDeclaration_long() async {
@@ -150,6 +182,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertSuggestName('_abstractCrazyNonsenseClassName');
+    assertSuggestName('_crazyNonsenseClassName');
+    assertSuggestName('_nonsenseClassName');
+    assertSuggestName('_className');
+    assertSuggestName('_name');
   }
 
   test_TopLevelVariableDeclaration_long_semicolon() async {
@@ -164,6 +202,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertSuggestName('_abstractCrazyNonsenseClassName');
+    assertSuggestName('_crazyNonsenseClassName');
+    assertSuggestName('_nonsenseClassName');
+    assertSuggestName('_className');
+    assertSuggestName('_name');
   }
 
   test_TopLevelVariableDeclaration_partial() async {
@@ -178,6 +222,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertSuggestName('_abstractCrazyNonsenseClassName');
+    assertSuggestName('_crazyNonsenseClassName');
+    assertSuggestName('_nonsenseClassName');
+    assertSuggestName('_className');
+    assertSuggestName('_name');
   }
 
   test_TopLevelVariableDeclaration_partial_semicolon() async {
@@ -192,6 +242,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertSuggestName('_abstractCrazyNonsenseClassName');
+    assertSuggestName('_crazyNonsenseClassName');
+    assertSuggestName('_nonsenseClassName');
+    assertSuggestName('_className');
+    assertSuggestName('_name');
   }
 
   test_TopLevelVariableDeclaration_prefixed() async {
@@ -206,6 +262,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertSuggestName('_abstractCrazyNonsenseClassName');
+    assertSuggestName('_crazyNonsenseClassName');
+    assertSuggestName('_nonsenseClassName');
+    assertSuggestName('_className');
+    assertSuggestName('_name');
   }
 
   test_TopLevelVariableDeclaration_prefixed_semicolon() async {
@@ -220,6 +282,12 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
+    // private versions
+    assertSuggestName('_abstractCrazyNonsenseClassName');
+    assertSuggestName('_crazyNonsenseClassName');
+    assertSuggestName('_nonsenseClassName');
+    assertSuggestName('_className');
+    assertSuggestName('_name');
   }
 
   test_TopLevelVariableDeclaration_short() async {
@@ -230,6 +298,8 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestName('a');
+    // private version
+    assertSuggestName('_a');
   }
 
   test_TopLevelVariableDeclaration_short_semicolon() async {
@@ -240,5 +310,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestName('a');
+    // private version
+    assertSuggestName('_a');
   }
 }
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 2241cfd..b9e542f 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -2504,6 +2504,38 @@
 ''');
   }
 
+  test_convertToIntLiteral() async {
+    await resolveTestUnit('''
+const double myDouble = 42.0;
+''');
+    await assertHasAssistAt('42.0', DartAssistKind.CONVERT_TO_INT_LITERAL, '''
+const double myDouble = 42;
+''');
+  }
+
+  test_convertToIntLiteral_e() async {
+    await resolveTestUnit('''
+const double myDouble = 4.2e1;
+''');
+    await assertHasAssistAt('4.2e1', DartAssistKind.CONVERT_TO_INT_LITERAL, '''
+const double myDouble = 42;
+''');
+  }
+
+  test_convertToIntLiteral_eBig() async {
+    await resolveTestUnit('''
+const double myDouble = 4.2e99999;
+''');
+    await assertNoAssistAt('4.2e99999', DartAssistKind.CONVERT_TO_INT_LITERAL);
+  }
+
+  test_convertToIntLiteral_notDouble() async {
+    await resolveTestUnit('''
+const double myDouble = 42;
+''');
+    await assertNoAssistAt('42', DartAssistKind.CONVERT_TO_INT_LITERAL);
+  }
+
   test_convertToIsNot_BAD_is_alreadyIsNot() async {
     await resolveTestUnit('''
 main(p) {
@@ -5014,6 +5046,60 @@
     }
   }
 
+  test_flutterWrapWidget_OK_prefixedIdentifier_identifier() async {
+    addFlutterPackage();
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+  Widget bar;
+}
+
+main(Foo foo) {
+  return foo./*caret*/bar;
+}
+''');
+    _setCaretLocation();
+    await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+  Widget bar;
+}
+
+main(Foo foo) {
+  return widget(child: foo./*caret*/bar);
+}
+''');
+  }
+
+  test_flutterWrapWidget_OK_prefixedIdentifier_prefix() async {
+    addFlutterPackage();
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+  Widget bar;
+}
+
+main(Foo foo) {
+  return /*caret*/foo.bar;
+}
+''');
+    _setCaretLocation();
+    await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+  Widget bar;
+}
+
+main(Foo foo) {
+  return /*caret*/widget(child: foo.bar);
+}
+''');
+  }
+
   test_flutterWrapWidget_OK_singleLine1() async {
     addFlutterPackage();
     await resolveTestUnit('''
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 93b95a7..db6d6b7 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -3744,7 +3744,7 @@
   test_createMissingOverrides_functionTypedParameter() async {
     await resolveTestUnit('''
 abstract class A {
-  forEach(int f(double p1, String p2));
+  void forEach(int f(double p1, String p2));
 }
 
 class B extends A {
@@ -3752,12 +3752,12 @@
 ''');
     await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
 abstract class A {
-  forEach(int f(double p1, String p2));
+  void forEach(int f(double p1, String p2));
 }
 
 class B extends A {
   @override
-  forEach(int Function(double p1, String p2) f) {
+  void forEach(int Function(double p1, String p2) f) {
     // TODO: implement forEach
   }
 }
@@ -3785,8 +3785,8 @@
 }
 
 class Test extends IterableMixin<int> {
-  // TODO: implement iterator
   @override
+  // TODO: implement iterator
   Iterator<int> get iterator => null;
 }
 ''');
@@ -3810,6 +3810,7 @@
   @override
   List<V> getItems() {
     // TODO: implement getItems
+    return null;
   }
 }
 ''');
@@ -3832,12 +3833,12 @@
 }
 
 class B extends A {
-  // TODO: implement g1
   @override
+  // TODO: implement g1
   get g1 => null;
 
-  // TODO: implement g2
   @override
+  // TODO: implement g2
   int get g2 => null;
 }
 ''');
@@ -3863,6 +3864,7 @@
   @override
   Map<aaa.Future, List<aaa.Future>> g(aaa.Future p) {
     // TODO: implement g
+    return null;
   }
 }
 ''');
@@ -3904,7 +3906,7 @@
   test_createMissingOverrides_method() async {
     await resolveTestUnit('''
 abstract class A {
-  m1();
+  void m1();
   int m2();
   String m3(int p1, double p2, Map<int, List<String>> p3);
   String m4(p1, p2);
@@ -3917,7 +3919,7 @@
 ''');
     String expectedCode = '''
 abstract class A {
-  m1();
+  void m1();
   int m2();
   String m3(int p1, double p2, Map<int, List<String>> p3);
   String m4(p1, p2);
@@ -3927,33 +3929,38 @@
 
 class B extends A {
   @override
-  m1() {
+  void m1() {
     // TODO: implement m1
   }
 
   @override
   int m2() {
     // TODO: implement m2
+    return null;
   }
 
   @override
   String m3(int p1, double p2, Map<int, List<String>> p3) {
     // TODO: implement m3
+    return null;
   }
 
   @override
   String m4(p1, p2) {
     // TODO: implement m4
+    return null;
   }
 
   @override
   String m5(p1, [int p2 = 2, int p3, p4 = 4]) {
     // TODO: implement m5
+    return null;
   }
 
   @override
   String m6(p1, {int p2 = 2, int p3, p4 = 4}) {
     // TODO: implement m6
+    return null;
   }
 }
 ''';
@@ -4020,6 +4027,45 @@
   @override
   E1 foo<E1, E2 extends C<int>>(V<E2> v) {
     // TODO: implement foo
+    return null;
+  }
+}
+''');
+  }
+
+  test_createMissingOverrides_method_genericClass2() async {
+    await resolveTestUnit('''
+class A<R> {
+  R foo(int a) => null;
+}
+
+class B<R> extends A<R> {
+  R bar(double b) => null;
+}
+
+class X implements B<bool> {
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+class A<R> {
+  R foo(int a) => null;
+}
+
+class B<R> extends A<R> {
+  R bar(double b) => null;
+}
+
+class X implements B<bool> {
+  @override
+  bool bar(double b) {
+    // TODO: implement bar
+    return null;
+  }
+
+  @override
+  bool foo(int a) {
+    // TODO: implement foo
+    return null;
   }
 }
 ''');
@@ -4044,6 +4090,7 @@
   @override
   List<T> foo<T extends V>(K key) {
     // TODO: implement foo
+    return null;
   }
 }
 ''');
@@ -4095,6 +4142,7 @@
   @override
   int operator [](int index) {
     // TODO: implement []
+    return null;
   }
 
   @override
@@ -4125,17 +4173,17 @@
 
 class B extends A {
   @override
-  set s1(x) {
+  void set s1(x) {
     // TODO: implement s1
   }
 
   @override
-  set s2(int x) {
+  void set s2(int x) {
     // TODO: implement s2
   }
 
   @override
-  set s3(String x) {
+  void set s3(String x) {
     // TODO: implement s3
   }
 }
@@ -5495,6 +5543,106 @@
 ''');
   }
 
+  test_moveTypeArgumentsToClass_explicitConst() async {
+    await resolveTestUnit('''
+main() {
+  const C.named<int>();
+}
+class C<E> {
+  const C.named();
+}
+''');
+    await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
+main() {
+  const C<int>.named();
+}
+class C<E> {
+  const C.named();
+}
+''');
+  }
+
+  test_moveTypeArgumentsToClass_explicitNew() async {
+    await resolveTestUnit('''
+main() {
+  new C.named<int>();
+}
+class C<E> {
+  C.named();
+}
+''');
+    await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
+main() {
+  new C<int>.named();
+}
+class C<E> {
+  C.named();
+}
+''');
+  }
+
+  test_moveTypeArgumentsToClass_explicitNew_BAD_alreadyThere() async {
+    await resolveTestUnit('''
+main() {
+  new C<String>.named<int>();
+}
+class C<E> {
+  C.named();
+}
+''');
+    await assertNoFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS);
+  }
+
+  test_moveTypeArgumentsToClass_explicitNew_BAD_wrongNumber() async {
+    await resolveTestUnit('''
+main() {
+  new C.named<int, String>();
+}
+class C<E> {
+  C.named();
+}
+''');
+    await assertNoFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS);
+  }
+
+  test_moveTypeArgumentsToClass_implicitConst() async {
+    await resolveTestUnit('''
+main() {
+  const C c = C.named<int>();
+}
+class C<E> {
+  const C.named();
+}
+''');
+    await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
+main() {
+  const C c = C<int>.named();
+}
+class C<E> {
+  const C.named();
+}
+''');
+  }
+
+  test_moveTypeArgumentsToClass_implicitNew() async {
+    await resolveTestUnit('''
+main() {
+  C.named<int>();
+}
+class C<E> {
+  C.named();
+}
+''');
+    await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
+main() {
+  C<int>.named();
+}
+class C<E> {
+  C.named();
+}
+''');
+  }
+
   test_noException_1() async {
     await resolveTestUnit('''
 main(p) {
@@ -5629,6 +5777,82 @@
 ''');
   }
 
+  test_removeTypeArguments_explicitConst() async {
+    await resolveTestUnit('''
+main() {
+  const C.named<int>();
+}
+class C<E> {
+  const C.named();
+}
+''');
+    await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
+main() {
+  const C.named();
+}
+class C<E> {
+  const C.named();
+}
+''');
+  }
+
+  test_removeTypeArguments_explicitNew() async {
+    await resolveTestUnit('''
+main() {
+  new C.named<int>();
+}
+class C<E> {
+  C.named();
+}
+''');
+    await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
+main() {
+  new C.named();
+}
+class C<E> {
+  C.named();
+}
+''');
+  }
+
+  test_removeTypeArguments_implicitConst() async {
+    await resolveTestUnit('''
+main() {
+  const C c = C.named<int>();
+}
+class C<E> {
+  const C.named();
+}
+''');
+    await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
+main() {
+  const C c = C.named();
+}
+class C<E> {
+  const C.named();
+}
+''');
+  }
+
+  test_removeTypeArguments_implicitNew() async {
+    await resolveTestUnit('''
+main() {
+  C.named<int>();
+}
+class C<E> {
+  C.named();
+}
+''');
+    await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
+main() {
+  C.named();
+}
+class C<E> {
+  C.named();
+}
+''');
+  }
+
   test_removeUnnecessaryCast_assignment() async {
     await resolveTestUnit('''
 main(Object p) {
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 3710f03..2616261 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -22,13 +22,6 @@
 class MoveFileTest extends RefactoringTest {
   MoveFileRefactoring refactoring;
 
-  @failingTest
-  test_dart_uris_are_unmodified() async {
-    // TODO(dantup): See _computeNewUri implementation which currently only
-    // handles relative + package: urls (package url handling is also incomplete)
-    fail('Not yet implemented/tested');
-  }
-
   test_file_containing_imports_exports_parts() async {
     String pathA = '/project/000/1111/a.dart';
     String pathB = '/project/000/1111/b.dart';
@@ -44,7 +37,7 @@
 import '22/c.dart';
 export '333/d.dart';
 part 'a.dart';
-part '/absolute/uri.dart';
+part '${convertAbsolutePathToUri('/absolute/uri.dart')}';
 ''');
     // perform refactoring
     _createRefactoring('/project/000/1111/22/new_name.dart');
@@ -58,7 +51,7 @@
 import 'c.dart';
 export '../333/d.dart';
 part '../a.dart';
-part '/absolute/uri.dart';
+part '${convertAbsolutePathToUri('/absolute/uri.dart')}';
 ''');
   }
 
@@ -110,6 +103,26 @@
     assertNoFileChange(testFile);
   }
 
+  test_file_imported_with_package_uri() async {
+    // Set up package uri resolution for local package.
+    packageMap['my_package'] = [getFolder('/project/lib')];
+    configureDriver();
+
+    String pathA = '/project/000/1111/a.dart';
+    testFile = '/project/lib/test.dart';
+    addSource(pathA, '''
+  import 'package:my_package/test.dart';
+  ''');
+    addTestSource('');
+    // perform refactoring
+    _createRefactoring('/project/lib/222/new_name.dart');
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(pathA, '''
+  import 'package:my_package/222/new_name.dart';
+  ''');
+    assertNoFileChange(testFile);
+  }
+
   @failingTest
   test_file_referenced_by_multiple_libraries() async {
     // This test fails because the search index doesn't support multiple uris for
@@ -172,7 +185,8 @@
     // TODO(dantup): These paths should all use convertPath so they're as expected
     // on Windows.
     await _assertFailedRefactoring(RefactoringProblemSeverity.FATAL,
-        expectedMessage: '/tmp does not belong to an analysis root.');
+        expectedMessage:
+            '${convertPath('/tmp')} does not belong to an analysis root.');
   }
 
   test_nonexistent_file_returns_failure() async {
@@ -194,7 +208,7 @@
     _createRefactoring('/project2', oldName: '/project');
     await _assertFailedRefactoring(RefactoringProblemSeverity.FATAL,
         expectedMessage:
-            'Renaming an analysis root is not supported (/project)');
+            'Renaming an analysis root is not supported (${convertPath('/project')})');
   }
 
   test_renaming_part_that_uses_uri_in_part_of() async {
@@ -235,13 +249,13 @@
     // Allow passing an oldName for when we don't want to rename testSource,
     // but otherwise fall back to that.
     if (oldName != null) {
-      refactoring =
-          new MoveFileRefactoring(resourceProvider, workspace, null, oldName);
+      refactoring = new MoveFileRefactoring(
+          resourceProvider, workspace, null, convertPath(oldName));
     } else {
       refactoring = new MoveFileRefactoring(
           resourceProvider, workspace, testSource, null);
     }
-    refactoring.newFile = newName;
+    refactoring.newFile = convertPath(newName);
   }
 
   Future _assertFailedRefactoring(RefactoringProblemSeverity expectedSeverity,
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index 00006c5..a7e9148 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -722,7 +722,7 @@
 }
 ''');
     await indexTestUnit('''
-import '${convertPathForImport(pkgLib)}';
+import '${convertAbsolutePathToUri(pkgLib)}';
 class A {
   test() {}
 }
@@ -737,7 +737,7 @@
     refactoring.newName = 'newName';
     // validate change
     await assertSuccessfulRefactoring('''
-import '${convertPathForImport('/.pub-cache/lib.dart')}';
+import '${convertAbsolutePathToUri('/.pub-cache/lib.dart')}';
 class A {
   newName() {}
 }
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index 1db7113..7ace7de 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -234,7 +234,7 @@
 class A {}
 ''');
     await indexTestUnit('''
-import "${convertPathForImport('/other/lib.dart')}";
+import "${convertAbsolutePathToUri('/other/lib.dart')}";
 main() {
   A a;
 }
diff --git a/pkg/analysis_server/test/src/utilities/flutter_test.dart b/pkg/analysis_server/test/src/utilities/flutter_test.dart
index b4a0ef0..c148ef0 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_test.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_test.dart
@@ -90,22 +90,7 @@
     expect(getWidgetPresentationText(w), isNull);
   }
 
-  test_identifyWidgetExpression_identifier() async {
-    await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-main() {
-  var text = new Text('abc');
-  text;
-}
-''');
-    {
-      Expression expression = findNodeAtString("text;");
-      expect(identifyWidgetExpression(expression), expression);
-    }
-  }
-
-  test_identifyWidgetExpression_instanceCreation() async {
+  test_identifyWidgetExpression_node_instanceCreation() async {
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 
@@ -155,7 +140,7 @@
     }
   }
 
-  test_identifyWidgetExpression_invocation() async {
+  test_identifyWidgetExpression_node_invocation() async {
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 
@@ -185,7 +170,7 @@
     }
   }
 
-  test_identifyWidgetExpression_namedExpression() async {
+  test_identifyWidgetExpression_node_namedExpression() async {
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 
@@ -199,6 +184,50 @@
     expect(identifyWidgetExpression(childExpression), isNull);
   }
 
+  test_identifyWidgetExpression_node_prefixedIdentifier_identifier() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+  Widget bar;
+}
+
+main(Foo foo) {
+  foo.bar; // ref
+}
+''');
+    SimpleIdentifier bar = findNodeAtString('bar; // ref');
+    expect(identifyWidgetExpression(bar), bar.parent);
+  }
+
+  test_identifyWidgetExpression_node_prefixedIdentifier_prefix() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+  Widget bar;
+}
+
+main(Foo foo) {
+  foo.bar; // ref
+}
+''');
+    SimpleIdentifier foo = findNodeAtString('foo.bar');
+    expect(identifyWidgetExpression(foo), foo.parent);
+  }
+
+  test_identifyWidgetExpression_node_simpleIdentifier() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main(Widget widget) {
+  widget; // ref
+}
+''');
+    Expression expression = findNodeAtString('widget; // ref');
+    expect(identifyWidgetExpression(expression), expression);
+  }
+
   test_identifyWidgetExpression_null() async {
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
@@ -222,6 +251,72 @@
     }
   }
 
+  test_identifyWidgetExpression_parent_argumentList() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main() {
+  var text = new Text('abc');
+  useWidget(text); // ref
+}
+
+void useWidget(Widget w) {}
+''');
+    Expression expression = findNodeAtString("text); // ref");
+    expect(identifyWidgetExpression(expression), expression);
+  }
+
+  test_identifyWidgetExpression_parent_expressionStatement() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main(Widget widget) {
+  widget; // ref
+}
+''');
+    Expression expression = findNodeAtString("widget; // ref");
+    expect(identifyWidgetExpression(expression), expression);
+  }
+
+  test_identifyWidgetExpression_parent_listLiteral() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main(Widget widget) {
+  return [widget]; // ref
+}
+''');
+    Expression expression = findNodeAtString("widget]; // ref");
+    expect(identifyWidgetExpression(expression), expression);
+  }
+
+  test_identifyWidgetExpression_parent_namedExpression() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main() {
+  var text = new Text('abc');
+  useWidget(child: text); // ref
+}
+
+void useWidget({Widget child}) {}
+''');
+    Expression expression = findNodeAtString("text); // ref");
+    expect(identifyWidgetExpression(expression), expression);
+  }
+
+  test_identifyWidgetExpression_parent_returnStatement() async {
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main(Widget widget) {
+  return widget; // ref
+}
+''');
+    Expression expression = findNodeAtString("widget; // ref");
+    expect(identifyWidgetExpression(expression), expression);
+  }
+
   test_isWidget() async {
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
diff --git a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
new file mode 100644
index 0000000..068063c
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import '../../../tool/lsp_spec/codegen_dart.dart';
+
+main() {
+  group('mapType', () {
+    test('handles basic types', () {
+      expect(mapType(['string']), equals('String'));
+      expect(mapType(['boolean']), equals('bool'));
+      expect(mapType(['any']), equals('dynamic'));
+      expect(mapType(['object']), equals('dynamic'));
+      expect(mapType(['int']), equals('int'));
+      expect(mapType(['num']), equals('num'));
+    });
+
+    test('handles union types', () {
+      expect(mapType(['string', 'int']), equals('Either2<String, int>'));
+      expect(mapType(['string | int']), equals('Either2<String, int>'));
+    });
+
+    test('handles arrays', () {
+      expect(mapType(['string[]']), equals('List<String>'));
+      expect(mapType(['Array<string>']), equals('List<String>'));
+    });
+
+    test('handles types with args', () {
+      expect(mapType(['Class<string[]>']), equals('Class<List<String>>'));
+      expect(mapType(['Array<string | num>']),
+          equals('List<Either2<String, num>>'));
+    });
+
+    test('handles complex nested types', () {
+      expect(
+          mapType([
+            'Array<string>',
+            'any[]',
+            'Response<A>',
+            'Request<Array<string | num>>'
+          ]),
+          equals(
+              'Either4<List<String>, List<dynamic>, Response<A>, Request<List<Either2<String, num>>>>'));
+    });
+  });
+}
diff --git a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
new file mode 100644
index 0000000..e12b850
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:test/test.dart';
+
+main() {
+  group('toJson', () {
+    test('returns correct JSON for a union', () {
+      final _num = new Either2.t1(1);
+      final _string = new Either2.t2('Test');
+      expect(json.encode(_num.toJson()), equals('1'));
+      expect(json.encode(_string.toJson()), equals('"Test"'));
+    });
+
+    test('returns correct output for union types', () {
+      final message =
+          new RequestMessage(new Either2.t1(1), "test", null, "test");
+      String output = json.encode(message.toJson());
+      expect(output, equals('{"id":1,"method":"test","jsonrpc":"test"}'));
+    });
+
+    test('returns correct output for union types containing interface types',
+        () {
+      final params = new Either2<String, WorkspaceClientCapabilities>.t2(
+          new WorkspaceClientCapabilities(
+        true,
+        null,
+        null,
+        null,
+      ));
+      String output = json.encode(params);
+      expect(output, equals('{"applyEdit":true}'));
+    });
+
+    test('returns correct output for types with lists', () {
+      final start = new Position(1, 1);
+      final end = new Position(2, 2);
+      final range = new Range(start, end);
+      final location = new Location('y-uri', range);
+      final codeAction = new Diagnostic(
+        range,
+        DiagnosticSeverity.Error,
+        new Either2.t2('test_err'),
+        '/tmp/source.dart',
+        'err!!',
+        [new DiagnosticRelatedInformation(location, 'message')],
+      );
+      final output = json.encode(codeAction.toJson());
+      final expected = '''{
+        "range":{
+            "start":{"line":1,"character":1},
+            "end":{"line":2,"character":2}
+        },
+        "severity":1,
+        "code":"test_err",
+        "source":"/tmp/source.dart",
+        "message":"err!!",
+        "relatedInformation":[
+            {
+              "location":{
+                  "uri":"y-uri",
+                  "range":{
+                    "start":{"line":1,"character":1},
+                    "end":{"line":2,"character":2}
+                  }
+              },
+              "message":"message"
+            }
+        ]
+      }'''
+          .replaceAll(new RegExp('[ \n]'), '');
+      expect(output, equals(expected));
+    });
+
+    test('serialises enums to their underlying values', () {
+      final foldingRange =
+          new FoldingRange(1, 2, 3, 4, FoldingRangeKind.Comment);
+      final output = json.encode(foldingRange.toJson());
+      final expected = '''{
+        "startLine":1,
+        "startCharacter":2,
+        "endLine":3,
+        "endCharacter":4,
+        "kind":"comment"
+      }'''
+          .replaceAll(new RegExp('[ \n]'), '');
+      expect(output, equals(expected));
+    });
+  });
+
+  group('fromJson', () {
+    test('parses JSON for types with unions (left side)', () {
+      final input = '{"id":1,"method":"test","jsonrpc":"test"}';
+      final message = new RequestMessage.fromJson(jsonDecode(input));
+      expect(message.id, equals(new Either2<num, String>.t1(1)));
+      expect(message.id.valueEquals(1), isTrue);
+      expect(message.jsonrpc, "test");
+      expect(message.method, "test");
+    });
+
+    test('parses JSON for types with unions (right side)', () {
+      final input = '{"id":"one","method":"test","jsonrpc":"test"}';
+      final message = new RequestMessage.fromJson(jsonDecode(input));
+      expect(message.id, equals(new Either2<num, String>.t2("one")));
+      expect(message.id.valueEquals("one"), isTrue);
+      expect(message.jsonrpc, "test");
+      expect(message.method, "test");
+    });
+  });
+
+  test('objects with lists and enums can round-trip through to json and back',
+      () {
+    final obj = new ClientCapabilities(
+        new WorkspaceClientCapabilities(
+            true,
+            false,
+            [ResourceOperationKind.Create, ResourceOperationKind.Delete],
+            FailureHandlingKind.Undo),
+        new TextDocumentClientCapabilities(true, false, true, false),
+        null);
+    final String json = jsonEncode(obj);
+    final restoredObj = new ClientCapabilities.fromJson(jsonDecode(json));
+
+    expect(restoredObj.workspace.applyEdit, equals(obj.workspace.applyEdit));
+    expect(restoredObj.workspace.documentChanges,
+        equals(obj.workspace.documentChanges));
+    expect(restoredObj.workspace.resourceOperations,
+        equals(obj.workspace.resourceOperations));
+    expect(restoredObj.workspace.failureHandling,
+        equals(obj.workspace.failureHandling));
+    expect(restoredObj.textDocument.didSave, equals(obj.textDocument.didSave));
+    expect(restoredObj.textDocument.dynamicRegistration,
+        equals(obj.textDocument.dynamicRegistration));
+    expect(
+        restoredObj.textDocument.willSave, equals(obj.textDocument.willSave));
+    expect(restoredObj.textDocument.willSaveWaitUntil,
+        equals(obj.textDocument.willSaveWaitUntil));
+    expect(restoredObj.experimental, equals(obj.experimental));
+  });
+}
diff --git a/pkg/analysis_server/test/tool/lsp_spec/markdown_test.dart b/pkg/analysis_server/test/tool/lsp_spec/markdown_test.dart
new file mode 100644
index 0000000..23afaca
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/markdown_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import '../../../tool/lsp_spec/markdown.dart';
+
+main() {
+  group('markdown parser', () {
+    test('extracts a typescript fenced block from Markdown', () {
+      final String input = '''
+```typescript
+CONTENT
+```
+    ''';
+      final List<String> output = extractTypeScriptBlocks(input);
+      expect(output, hasLength(1));
+      expect(output, contains('CONTENT'));
+    });
+
+    test('does not extract unknown code blocks', () {
+      final String input = '''
+```
+CONTENT
+```
+
+```dart
+CONTENT
+```
+    ''';
+      final List<String> output = extractTypeScriptBlocks(input);
+      expect(output, hasLength(0));
+    });
+
+    test('extracts multiple code blocks', () {
+      final String input = '''
+```typescript
+CONTENT1
+```
+
+```typescript
+CONTENT2
+```
+    ''';
+      final List<String> output = extractTypeScriptBlocks(input);
+      expect(output, hasLength(2));
+      expect(output, contains('CONTENT1'));
+      expect(output, contains('CONTENT2'));
+    });
+  });
+}
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
new file mode 100644
index 0000000..1fad598
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
@@ -0,0 +1,229 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import '../../../tool/lsp_spec/typescript.dart';
+
+main() {
+  group('typescript parser', () {
+    test('parses an interface', () {
+      final String input = '''
+/**
+ * Some options.
+ */
+export interface SomeOptions {
+	/**
+	 * Options used by something.
+	 */
+	options?: OptionKind[];
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final Interface interface = output[0];
+      expect(interface.name, equals('SomeOptions'));
+      expect(interface.comment, equals('Some options.'));
+      expect(interface.baseTypes, hasLength(0));
+      expect(interface.members, hasLength(1));
+      expect(interface.members[0], const TypeMatcher<Field>());
+      final Field field = interface.members[0];
+      expect(field.name, equals('options'));
+      expect(field.comment, equals('''Options used by something.'''));
+      expect(field.allowsNull, isFalse);
+      expect(field.allowsUndefined, isTrue);
+      expect(field.types, hasLength(1));
+      expect(field.types[0], equals('OptionKind[]'));
+    });
+
+    test('parses an interface with multiple fields', () {
+      final String input = '''
+export interface SomeOptions {
+	/**
+	 * Options0 used by something.
+	 */
+	options0: any;
+	/**
+	 * Options1 used by something.
+	 */
+	options1: any;
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final Interface interface = output[0];
+      expect(interface.members, hasLength(2));
+      [0, 1].forEach((i) {
+        expect(interface.members[i], const TypeMatcher<Field>());
+        final Field field = interface.members[i];
+        expect(field.name, equals('options$i'));
+        expect(field.comment, equals('''Options$i used by something.'''));
+      });
+    });
+
+    test('parses an interface with type args', () {
+      final String input = '''
+interface ResponseError<D> {
+	data?: D;
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final Interface interface = output[0];
+      expect(interface.members, hasLength(1));
+      final Field field = interface.members.first;
+      expect(field, const TypeMatcher<Field>());
+      expect(field.name, equals('data'));
+      expect(field.allowsUndefined, true);
+      expect(field.allowsNull, false);
+      expect(field.types, equals(['D']));
+    });
+
+    test('parses an interface with Arrays in Array<T> format', () {
+      final String input = '''
+export interface RequestMessage {
+	/**
+	 * The method's params.
+	 */
+	params?: Array<any> | object;
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final Interface interface = output[0];
+      expect(interface.members, hasLength(1));
+      final Field field = interface.members.first;
+      expect(field, const TypeMatcher<Field>());
+      expect(field.name, equals('params'));
+      expect(field.comment, equals('''The method's params.'''));
+      expect(field.allowsUndefined, true);
+      expect(field.allowsNull, false);
+      expect(field.types, equals(['Array<any>', 'object']));
+    });
+
+    test('flags nullable undefined values', () {
+      final String input = '''
+export interface A {
+  canBeBoth?: string | null;
+  canBeNeither: string;
+	canBeNull: string | null;
+  canBeUndefined?: string;
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      final Interface interface = output[0];
+      expect(interface.members, hasLength(4));
+      interface.members.forEach((m) => expect(m, const TypeMatcher<Field>()));
+      final Field canBeBoth = interface.members[0],
+          canBeNeither = interface.members[1],
+          canBeNull = interface.members[2],
+          canBeUndefined = interface.members[3];
+      expect(canBeNeither.allowsNull, isFalse);
+      expect(canBeNeither.allowsUndefined, isFalse);
+      expect(canBeNull.allowsNull, isTrue);
+      expect(canBeNull.allowsUndefined, isFalse);
+      expect(canBeUndefined.allowsNull, isFalse);
+      expect(canBeUndefined.allowsUndefined, isTrue);
+      expect(canBeBoth.allowsNull, isTrue);
+      expect(canBeBoth.allowsUndefined, isTrue);
+    });
+
+    test('formats comments correctly', () {
+      final String input = '''
+/**
+ * Describes the what this class in lots of words that wrap onto
+ * multiple lines that will need re-wrapping to format nicely when
+ * converted into Dart.
+ *
+ * Blank lines should remain in-tact, as should:
+ *   - Indented
+ *   - Things
+ * 
+ * Some docs have:
+ * - List items that are not indented
+ * 
+ * Sometimes after a blank line we'll have a note.
+ * 
+ * *Note* that something.
+ */
+export interface A {
+  a: a;
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      final Interface interface = output[0];
+      expect(interface.comment, equals('''
+Describes the what this class in lots of words that wrap onto multiple lines that will need re-wrapping to format nicely when converted into Dart.
+
+Blank lines should remain in-tact, as should:
+  - Indented
+  - Things
+
+Some docs have:
+- List items that are not indented
+
+Sometimes after a blank line we'll have a note.
+
+*Note* that something.'''));
+    });
+
+    test('parses a type alias', () {
+      final String input = '''
+export type DocumentSelector = DocumentFilter[];
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<TypeAlias>());
+      final TypeAlias typeAlias = output[0];
+      expect(typeAlias.name, equals('DocumentSelector'));
+      expect(typeAlias.baseType, equals('DocumentFilter[]'));
+    });
+
+    test('parses a namespace of constants', () {
+      final String input = '''
+export namespace ResourceOperationKind {
+	/**
+	 * Supports creating new files and folders.
+	 */
+	export const Create: ResourceOperationKind = 'create';
+
+	/**
+	 * Supports deleting existing files and folders.
+	 */
+	export const Delete: ResourceOperationKind = 'delete';
+
+	/**
+	 * Supports renaming existing files and folders.
+	 */
+	export const Rename: ResourceOperationKind = 'rename';
+}
+    ''';
+      final List<ApiItem> output = extractTypes(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Namespace>());
+      final Namespace namespace = output[0];
+      expect(namespace.members, hasLength(3));
+      namespace.members.forEach((m) => expect(m, const TypeMatcher<Const>()));
+      final Const create = namespace.members[0],
+          delete = namespace.members[1],
+          rename = namespace.members[2];
+      expect(create.name, equals('Create'));
+      expect(create.type, equals('ResourceOperationKind'));
+      expect(
+          create.comment, equals('Supports creating new files and folders.'));
+      expect(rename.name, equals('Rename'));
+      expect(rename.type, equals('ResourceOperationKind'));
+      expect(rename.comment,
+          equals('Supports renaming existing files and folders.'));
+      expect(delete.name, equals('Delete'));
+      expect(delete.type, equals('ResourceOperationKind'));
+      expect(delete.comment,
+          equals('Supports deleting existing files and folders.'));
+    });
+  });
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
new file mode 100644
index 0000000..79b2b63
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -0,0 +1,591 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:dart_style/dart_style.dart';
+import 'package:meta/meta.dart';
+
+import 'typescript.dart';
+
+final formatter = new DartFormatter();
+Map<String, Interface> _interfaces = {};
+Map<String, Namespace> _namespaces = {};
+Map<String, TypeAlias> _typeAliases = {};
+
+String generateDartForTypes(List<ApiItem> types) {
+  // Keep maps of items we may need to look up quickly later.
+  types
+      .whereType<TypeAlias>()
+      .forEach((alias) => _typeAliases[alias.name] = alias);
+  types
+      .whereType<Interface>()
+      .forEach((interface) => _interfaces[interface.name] = interface);
+  types
+      .whereType<Namespace>()
+      .forEach((namespace) => _namespaces[namespace.name] = namespace);
+  final buffer = new IndentableStringBuffer();
+  _getSorted(types).forEach((t) => _writeType(buffer, t));
+  final formattedCode = _formatCode(buffer.toString());
+  return formattedCode.trim() + '\n'; // Ensure a single trailing newline.
+}
+
+List<String> _extractTypesFromUnion(String type) {
+  return type.split('|').map((t) => t.trim()).toList();
+}
+
+String _formatCode(String code) {
+  try {
+    code = formatter.format(code);
+  } catch (e) {
+    print('Failed to format code, returning unformatted code.');
+  }
+  return code;
+}
+
+/// Recursively gets all members from superclasses.
+List<Field> _getAllFields(Interface interface) {
+  // Handle missing interfaces (such as special cased interfaces that won't
+  // be included in this model).
+  if (interface == null) {
+    return [];
+  }
+  return interface.members
+      .whereType<Field>()
+      .followedBy(interface.baseTypes
+          .map((name) => _getAllFields(_interfaces[name]))
+          .expand((ts) => ts))
+      .toList();
+}
+
+String _getListType(String type) {
+  return type.substring('List<'.length, type.length - 1);
+}
+
+/// Returns a copy of the list sorted by name.
+List<ApiItem> _getSorted(List<ApiItem> items) {
+  final sortedList = items.toList();
+  sortedList.sort((item1, item2) => item1.name.compareTo(item2.name));
+  return sortedList;
+}
+
+List<String> _getUnionTypes(String type) {
+  return type
+      .substring('EitherX<'.length, type.length - 1)
+      .split(',')
+      .map((s) => s.trim())
+      .toList();
+}
+
+bool _isList(String type) {
+  return type.startsWith('List<') && type.endsWith('>');
+}
+
+bool _isLiteral(String type) {
+  const literals = ['num', 'String', 'bool'];
+  return literals.contains(type);
+}
+
+bool _isSpecType(String type) {
+  return _interfaces.containsKey(type) || _namespaces.containsKey(type);
+}
+
+bool _isUnion(String type) {
+  return type.startsWith('Either') && type.endsWith('>');
+}
+
+/// Maps reserved words and identifiers that cause issues in field names.
+String _makeValidIdentifier(String identifier) {
+  // The SymbolKind class has uses these names which cause issues for code that
+  // uses them as types.
+  const map = {
+    'Object': 'Obj',
+    'String': 'Str',
+  };
+  return map[identifier] ?? identifier;
+}
+
+/// Maps a TypeScript type on to a Dart type, including following TypeAliases.
+@visibleForTesting
+String mapType(List<String> types) {
+  const mapping = <String, String>{
+    'boolean': 'bool',
+    'string': 'String',
+    'number': 'num',
+    'any': 'dynamic',
+    'object': 'dynamic',
+    // Special cases that are hard to parse or anonymous types.
+    '{ [uri: string]: TextEdit[]; }': 'Map<String, List<TextEdit>>',
+    '{ language: string; value: string }': 'MarkedStringWithLanguage'
+  };
+  if (types.length > 4) {
+    throw 'Unions of more than 4 types are not supported.';
+  }
+  if (types.length >= 2) {
+    final typeArgs = types.map((t) => mapType([t])).join(', ');
+    return 'Either${types.length}<$typeArgs>';
+  }
+
+  final type = types.first;
+  if (type.endsWith('[]')) {
+    return 'List<${mapType([type.substring(0, type.length - 2)])}>';
+  } else if (type.startsWith('Array<') && type.endsWith('>')) {
+    return 'List<${mapType([type.substring(6, type.length - 1)])}>';
+  } else if (type.contains('<')) {
+    // For types with type args, we need to map the type and each type arg.
+    final declaredType = _stripTypeArgs(type);
+    final typeArgs = type
+        .substring(declaredType.length + 1, type.length - 1)
+        .split(',')
+        .map((t) => t.trim());
+    return '${mapType([
+      declaredType
+    ])}<${typeArgs.map((t) => mapType([t])).join(', ')}>';
+  } else if (type.contains('|')) {
+    // It's possible we ended up with nested unions that the parsing.
+    // TODO(dantup): This is now partly done during parsing and partly done
+    // here. Maybe consider removing from typescript.dart and just carrying a
+    // String through so the logic is all in one place in this function?
+    return mapType(_extractTypesFromUnion(type));
+  } else if (_typeAliases.containsKey(type)) {
+    return mapType([_typeAliases[type].baseType]);
+  } else if (mapping.containsKey(type)) {
+    return mapType([mapping[type]]);
+  } else {
+    return type;
+  }
+}
+
+String _rewriteCommentReference(String comment) {
+  final commentReferencePattern = new RegExp(r'\[([\w ]+)\]\(#(\w+)\)');
+  return comment.replaceAllMapped(commentReferencePattern, (m) {
+    final description = m.group(1);
+    final reference = m.group(2);
+    if (description == reference) {
+      return '[$reference]';
+    } else {
+      return '$description ([$reference])';
+    }
+  });
+}
+
+String _stripTypeArgs(String typeName) => typeName.contains('<')
+    ? typeName.substring(0, typeName.indexOf('<'))
+    : typeName;
+
+Iterable<String> _wrapLines(List<String> lines, int maxLength) sync* {
+  lines = lines.map((l) => l.trimRight()).toList();
+  for (var line in lines) {
+    while (true) {
+      if (line.length <= maxLength) {
+        yield line;
+        break;
+      } else {
+        int lastSpace = line.lastIndexOf(' ', maxLength);
+        // If there was no valid place to wrap, yield the whole string.
+        if (lastSpace == -1) {
+          yield line;
+          break;
+        } else {
+          yield line.substring(0, lastSpace);
+          line = line.substring(lastSpace + 1);
+        }
+      }
+    }
+  }
+}
+
+void _writeCanParseMethod(IndentableStringBuffer buffer, Interface interface) {
+  buffer
+    ..writeIndentedln('static bool canParse(Object obj) {')
+    ..indent()
+    ..writeIndented('return obj is Map<String, dynamic>');
+  // In order to consider this valid for parsing, all fields that may not be
+  // undefined must be present and also type check for the correct type.
+  final requiredFields =
+      _getAllFields(interface).where((f) => !f.allowsUndefined);
+  for (var field in requiredFields) {
+    buffer.write(" && obj.containsKey('${field.name}') && ");
+    _writeTypeCheckCondition(
+        buffer, "obj['${field.name}']", mapType(field.types));
+  }
+  buffer
+    ..writeln(';')
+    ..outdent()
+    ..writeIndentedln('}');
+}
+
+void _writeConst(IndentableStringBuffer buffer, Const cons) {
+  _writeDocCommentsAndAnnotations(buffer, cons);
+  buffer.writeIndentedln('static const ${cons.name} = ${cons.value};');
+}
+
+void _writeConstructor(IndentableStringBuffer buffer, Interface interface) {
+  final allFields = _getAllFields(interface);
+  if (allFields.isEmpty) {
+    return;
+  }
+  buffer
+    ..writeIndented('${_stripTypeArgs(interface.name)}(')
+    ..write(allFields.map((field) => 'this.${field.name}').join(', '))
+    ..write(')');
+  final fieldsWithValidation =
+      allFields.where((f) => !f.allowsNull && !f.allowsUndefined).toList();
+  if (fieldsWithValidation.isNotEmpty) {
+    buffer
+      ..writeIndentedln(' {')
+      ..indent();
+    for (var field in fieldsWithValidation) {
+      buffer
+        ..writeIndentedln('if (${field.name} == null) {')
+        ..indent()
+        ..writeIndentedln(
+            "throw '${field.name} is required but was not provided';")
+        ..outdent()
+        ..writeIndentedln('}');
+    }
+    buffer
+      ..outdent()
+      ..writeIndentedln('}');
+  } else {
+    buffer.writeln(';');
+  }
+}
+
+void _writeDocCommentsAndAnnotations(
+    IndentableStringBuffer buffer, ApiItem item) {
+  var comment = item.comment?.trim();
+  if (comment == null || comment.length == 0) {
+    return;
+  }
+  comment = _rewriteCommentReference(comment);
+  Iterable<String> lines = comment.split('\n');
+  // Wrap at 80 - 4 ('/// ') - indent characters.
+  lines = _wrapLines(lines, (80 - 4 - buffer.totalIndent).clamp(0, 80));
+  lines.forEach((l) => buffer.writeIndentedln('/// $l'.trim()));
+  if (item.isDeprecated) {
+    buffer.writeIndentedln('@core.deprecated');
+  }
+}
+
+void _writeEnumClass(IndentableStringBuffer buffer, Namespace namespace) {
+  _writeDocCommentsAndAnnotations(buffer, namespace);
+  buffer
+    ..writeln('class ${namespace.name} {')
+    ..indent()
+    ..writeIndentedln('const ${namespace.name}._(this._value);')
+    ..writeIndentedln('const ${namespace.name}.fromJson(this._value);')
+    ..writeln()
+    ..writeIndentedln('final Object _value;')
+    ..writeln()
+    ..writeIndentedln('static bool canParse(Object obj) {')
+    ..indent()
+    ..writeIndentedln('switch (obj) {')
+    ..indent();
+  namespace.members.whereType<Const>().forEach((cons) {
+    buffer..writeIndentedln('case ${cons.value}:');
+  });
+  buffer
+    ..indent()
+    ..writeIndentedln('return true;')
+    ..outdent()
+    ..writeIndentedln('}')
+    ..writeIndentedln('return false;')
+    ..outdent()
+    ..writeIndentedln('}');
+  namespace.members.whereType<Const>().forEach((cons) {
+    _writeDocCommentsAndAnnotations(buffer, cons);
+    buffer
+      ..writeIndentedln(
+          'static const ${_makeValidIdentifier(cons.name)} = const ${namespace.name}._(${cons.value});');
+  });
+  buffer
+    ..writeln()
+    ..writeIndentedln('Object toJson() => _value;')
+    ..writeln()
+    ..writeIndentedln('@override String toString() => _value.toString();')
+    ..writeln()
+    ..writeIndentedln('@override get hashCode => _value.hashCode;')
+    ..writeln()
+    ..writeIndentedln(
+        'bool operator ==(o) => o is ${namespace.name} && o._value == _value;')
+    ..outdent()
+    ..writeln('}')
+    ..writeln();
+}
+
+void _writeField(IndentableStringBuffer buffer, Field field) {
+  _writeDocCommentsAndAnnotations(buffer, field);
+  buffer
+    ..writeIndented('final ')
+    ..write(mapType(field.types))
+    ..writeln(' ${field.name};');
+}
+
+void _writeFromJsonCode(
+    IndentableStringBuffer buffer, List<String> types, String valueCode) {
+  final type = mapType(types);
+  if (_isLiteral(type)) {
+    buffer.write("$valueCode");
+  } else if (_isSpecType(type)) {
+    // Our own types have fromJson() constructors we can call.
+    buffer.write("$valueCode != null ? new $type.fromJson($valueCode) : null");
+  } else if (_isList(type)) {
+    // Lists need to be mapped so we can recursively call (they may need fromJson).
+    buffer.write("$valueCode?.map((item) => ");
+    final listType = _getListType(type);
+    _writeFromJsonCode(buffer, [listType], 'item');
+    buffer.write(')?.cast<$listType>()?.toList()');
+  } else if (_isUnion(type)) {
+    _writeFromJsonCodeForUnion(buffer, types, valueCode);
+  } else {
+    buffer.write("$valueCode");
+  }
+}
+
+void _writeFromJsonCodeForUnion(
+    IndentableStringBuffer buffer, List<String> types, String valueCode) {
+  final unionTypeName = mapType(types);
+  // Write a check against each type, eg.:
+  // x is y ? new Either.tx(x) : (...)
+  var hasIncompleteCondition = false;
+  var unclosedParens = 0;
+  for (var i = 0; i < types.length; i++) {
+    final dartType = mapType([types[i]]);
+
+    // Dynamic matches all type checks, so only emit it if required.
+    if (dartType != 'dynamic') {
+      _writeTypeCheckCondition(buffer, valueCode, dartType);
+      buffer.write(' ? ');
+    }
+
+    // The code to construct a value with this "side" of the union.
+    buffer.write('new $unionTypeName.t${i + 1}(');
+    _writeFromJsonCode(buffer, [dartType], valueCode); // Call recursively!
+    buffer.write(')');
+
+    // If we output the type condition at the top, prepare for the next condition.
+    if (dartType != 'dynamic') {
+      buffer.write(' : (');
+      hasIncompleteCondition = true;
+      unclosedParens++;
+    } else {
+      hasIncompleteCondition = false;
+    }
+  }
+  // Fill the final parens with a throw because if we fell through all of the
+  // cases then the value we had didn't match any of the types in the union.
+  if (hasIncompleteCondition) {
+    buffer.write(
+        "throw '''\${$valueCode} was not one of (${types.join(', ')})'''");
+  }
+  buffer.write(')' * unclosedParens);
+}
+
+void _writeFromJsonConstructor(
+    IndentableStringBuffer buffer, Interface interface) {
+  final allFields = _getAllFields(interface);
+  if (allFields.isEmpty) {
+    return;
+  }
+  buffer
+    ..writeIndentedln(
+        'factory ${_stripTypeArgs(interface.name)}.fromJson(Map<String, dynamic> json) {')
+    ..indent();
+  for (final field in allFields) {
+    buffer.writeIndented('final ${field.name} = ');
+    _writeFromJsonCode(buffer, field.types, "json['${field.name}']");
+    buffer.writeln(';');
+  }
+  buffer
+    ..writeIndented('return new ${interface.name}(')
+    ..write(allFields.map((field) => '${field.name}').join(', '))
+    ..writeln(');')
+    ..outdent()
+    ..writeIndented('}');
+}
+
+void _writeInterface(IndentableStringBuffer buffer, Interface interface) {
+  _writeDocCommentsAndAnnotations(buffer, interface);
+
+  buffer.writeIndented('class ${interface.name} ');
+  var allBaseTypes = interface.baseTypes.followedBy(['ToJsonable']);
+  if (allBaseTypes.isNotEmpty) {
+    buffer.writeIndented('implements ${allBaseTypes.join(', ')} ');
+  }
+  buffer
+    ..writeln('{')
+    ..indent();
+  _writeConstructor(buffer, interface);
+  _writeFromJsonConstructor(buffer, interface);
+  // Handle Consts and Fields separately, since we need to include superclass
+  // Fields.
+  final consts = interface.members.whereType<Const>().toList();
+  final fields = _getAllFields(interface);
+  buffer.writeln();
+  _writeMembers(buffer, consts);
+  buffer.writeln();
+  _writeMembers(buffer, fields);
+  buffer.writeln();
+  _writeToJsonMethod(buffer, interface);
+  _writeCanParseMethod(buffer, interface);
+  buffer
+    ..outdent()
+    ..writeIndentedln('}')
+    ..writeln();
+}
+
+void _writeJsonMapAssignment(
+    IndentableStringBuffer buffer, Field field, String mapName) {
+  // If we are allowed to be undefined (which essentially means required to be
+  // undefined and never explicitly null), we'll only add the value if set.
+  if (field.allowsUndefined) {
+    buffer
+      ..writeIndentedlnIf(
+          field.isDeprecated, '// ignore: deprecated_member_use')
+      ..writeIndentedln('if (${field.name} != null) {')
+      ..indent();
+  }
+  buffer
+    ..writeIndentedlnIf(field.isDeprecated, '// ignore: deprecated_member_use')
+    ..writeIndented('''$mapName['${field.name}'] = ${field.name}''');
+  if (!field.allowsUndefined && !field.allowsNull) {
+    buffer.write(''' ?? (throw '${field.name} is required but was not set')''');
+  }
+  buffer.writeln(';');
+  if (field.allowsUndefined) {
+    buffer
+      ..outdent()
+      ..writeIndentedln('}');
+  }
+}
+
+void _writeMember(IndentableStringBuffer buffer, Member member) {
+  if (member is Field) {
+    _writeField(buffer, member);
+  } else if (member is Const) {
+    _writeConst(buffer, member);
+  } else {
+    throw 'Unknown type';
+  }
+}
+
+void _writeMembers(IndentableStringBuffer buffer, List<Member> members) {
+  _getSorted(members).forEach((m) => _writeMember(buffer, m));
+}
+
+void _writeNamespace(IndentableStringBuffer buffer, Namespace namespace) {
+  // Namespaces are just groups of constants. For some uses we can write these
+  // as enum classes for extra type safety, but not for all - for example
+  // CodeActionKind can be an arbitrary String even though it also defines
+  // constants for common values. We can tell which can have their own values
+  // because they're marked with type aliases, with the exception of ErrorCodes!
+  if (!_typeAliases.containsKey(namespace.name) &&
+      namespace.name != 'ErrorCodes') {
+    _writeEnumClass(buffer, namespace);
+    return;
+  }
+
+  _writeDocCommentsAndAnnotations(buffer, namespace);
+  buffer
+    ..writeln('abstract class ${namespace.name} {')
+    ..indent();
+  _writeMembers(buffer, namespace.members);
+  buffer
+    ..outdent()
+    ..writeln('}')
+    ..writeln();
+}
+
+void _writeToJsonMethod(IndentableStringBuffer buffer, Interface interface) {
+  // It's important the name we use for the map here isn't in use in the object
+  // already. 'result' was, so we prefix it with some underscores.
+  buffer
+    ..writeIndentedln('Map<String, dynamic> toJson() {')
+    ..indent()
+    ..writeIndentedln('Map<String, dynamic> __result = {};');
+  for (var field in _getAllFields(interface)) {
+    _writeJsonMapAssignment(buffer, field, '__result');
+  }
+  buffer
+    ..writeIndentedln('return __result;')
+    ..outdent()
+    ..writeIndentedln('}');
+}
+
+void _writeType(IndentableStringBuffer buffer, ApiItem type) {
+  if (type is Interface) {
+    _writeInterface(buffer, type);
+  } else if (type is Namespace) {
+    _writeNamespace(buffer, type);
+  } else if (type is TypeAlias) {
+    // For now type aliases are not supported, so are collected at the start
+    // of the process in a map, and just replaced with the aliased type during
+    // generation.
+    // _writeTypeAlias(buffer, type);
+  } else {
+    throw 'Unknown type';
+  }
+}
+
+void _writeTypeCheckCondition(
+    IndentableStringBuffer buffer, String valueCode, String dartType) {
+  if (dartType == 'dynamic') {
+    buffer.write('true');
+  } else if (_isLiteral(dartType)) {
+    buffer.write('$valueCode is $dartType');
+  } else if (_isSpecType(dartType)) {
+    buffer.write('$dartType.canParse($valueCode)');
+  } else if (_isList(dartType)) {
+    final listType = _getListType(dartType);
+    buffer.write('($valueCode is List');
+    if (dartType != 'dynamic') {
+      // TODO(dantup): If we're happy to assume we never have two lists in a union
+      // we could skip this bit.
+      buffer
+          .write(' && ($valueCode.length == 0 || $valueCode.every((item) => ');
+      _writeTypeCheckCondition(buffer, 'item', listType);
+      buffer.write('))');
+    }
+    buffer.write(')');
+  } else if (_isUnion(dartType)) {
+    // To type check a union, we just recursively check against each of its types.
+    final unionTypes = _getUnionTypes(dartType);
+    buffer.write('(');
+    for (var i = 0; i < unionTypes.length; i++) {
+      if (i != 0) {
+        buffer.write(' || ');
+      }
+      _writeTypeCheckCondition(buffer, valueCode, mapType([unionTypes[i]]));
+    }
+    buffer.write(')');
+  } else {
+    throw 'Unable to type check $valueCode against $dartType';
+  }
+}
+
+class IndentableStringBuffer extends StringBuffer {
+  int _indentLevel = 0;
+  int _indentSpaces = 2;
+
+  int get totalIndent => _indentLevel * _indentSpaces;
+  String get _indentString => ' ' * totalIndent;
+
+  void indent() => _indentLevel++;
+  void outdent() => _indentLevel--;
+
+  void writeIndented(Object obj) {
+    write(_indentString);
+    write(obj);
+  }
+
+  void writeIndentedln(Object obj) {
+    write(_indentString);
+    writeln(obj);
+  }
+
+  void writeIndentedlnIf(bool condition, Object obj) {
+    if (condition) {
+      writeIndentedln(obj);
+    }
+  }
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
new file mode 100644
index 0000000..caa6aea
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:http/http.dart' as http;
+import 'package:path/path.dart' as path;
+
+import 'codegen_dart.dart';
+import 'markdown.dart';
+import 'typescript.dart';
+
+main() async {
+  final String script = Platform.script.toFilePath();
+  // 3x parent = file -> lsp_spec -> tool -> analysis_server.
+  final String packageFolder = new File(script).parent.parent.parent.path;
+  final String outFolder = path.join(packageFolder, 'lib', 'lsp_protocol');
+  new Directory(outFolder).createSync();
+
+  final String spec = await fetchSpec();
+  final List<ApiItem> types = extractAllTypes(extractTypeScriptBlocks(spec));
+  types.addAll(_getSpecialCaseTypes());
+  final String output = generateDartForTypes(types);
+
+  new File(path.join(outFolder, 'protocol_generated.dart'))
+      .writeAsStringSync(_generatedFileHeader + output);
+}
+
+const _generatedFileHeader = '''
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
+
+import 'dart:core' hide deprecated;
+import 'dart:core' as core show deprecated;
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+
+''';
+
+final Uri specUri = Uri.parse(
+    'https://raw.githubusercontent.com/Microsoft/language-server-protocol/gh-pages/specification.md');
+
+Future<String> fetchSpec() async {
+  final resp = await http.get(specUri);
+  return resp.body;
+}
+
+/// Fabricates types for things that don't parse well from the TS spec,
+/// such as anonymous types:
+///     type MarkedString = string | { language: string; value: string };
+List<ApiItem> _getSpecialCaseTypes() {
+  return [
+    // For MarkedString, we drop the string-only version since we can always
+    // supply a language and it makes the type a little simpler.
+    new Interface('MarkedString', null, [], [
+      new Field('language', null, ['string'], false, false),
+      new Field('value', null, ['string'], false, false)
+    ])
+  ];
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/markdown.dart b/pkg/analysis_server/tool/lsp_spec/markdown.dart
new file mode 100644
index 0000000..ae99df1
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/markdown.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final _typeScriptBlockPattern =
+    new RegExp(r'\B```typescript([\S\s]*?)\n```', multiLine: true);
+
+/// Extracts fenced code blocks that are explicitly marked as TypeScript from a
+/// markdown document.
+List<String> extractTypeScriptBlocks(String text) {
+  return _typeScriptBlockPattern
+      .allMatches(text)
+      .map((m) => m.group(1).trim())
+      .toList();
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart
new file mode 100644
index 0000000..017c666
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/typescript.dart
@@ -0,0 +1,313 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(dantup): Regex seemed like a good choice when parsing the first few...
+// maybe it's not so great now. We should parse this properly if it turns out
+// there are issues with what we have here.
+const String _blockBody = r'\{([\s\S]*?)\s*\n\s*\}';
+const String _comment = r'(?:\/\*\*((?:[\S\s](?!\*\/))+?)\s\*\/)?\s*';
+
+List<ApiItem> extractAllTypes(List<String> code) {
+  return extractTypes(code.join('\n'));
+}
+
+List<ApiItem> extractTypes(String code) {
+  final types = ApiItem.extractFrom(code);
+  _removeUnwantedTypes(types);
+  return types;
+}
+
+String _cleanComment(String comment) {
+  if (comment == null) {
+    return null;
+  }
+  final _commentLinePrefixes = new RegExp(r'\n\s*\* ?');
+  final _nonConcurrentNewlines = new RegExp(r'\n(?![\n\s\-*])');
+  final _newLinesThatRequireReinserting = new RegExp(r'\n (\w)');
+  // Remove any Windows newlines from the source.
+  comment = comment.replaceAll('\r', '');
+  // Remove the * prefixes.
+  comment = comment.replaceAll(_commentLinePrefixes, '\n');
+  // Remove and newlines that look like wrapped text.
+  comment = comment.replaceAll(_nonConcurrentNewlines, ' ');
+  // The above will remove one of the newlines when there are two, so we need
+  // to re-insert newlines for any block that starts immediately after a newline.
+  comment = comment.replaceAllMapped(
+      _newLinesThatRequireReinserting, (m) => '\n\n${m.group(1)}');
+  return comment.trim();
+}
+
+/// Fixes up some enum types that are not as specific as they could be in the
+/// spec. For example, Diagnostic.severity is typed "number" but can be mapped
+/// to the DiagnosticSeverity enum class.
+String _getImprovedType(String interfaceName, String fieldName) {
+  const Map<String, Map<String, String>> _improvedTypeMappings = {
+    "Diagnostic": {
+      "severity": "DiagnosticSeverity",
+    },
+    "TextDocumentSyncOptions": {
+      "change": "TextDocumentSyncKind",
+    },
+    "FileSystemWatcher": {
+      "kind": "WatchKind",
+    },
+    "CompletionItem": {
+      "kind": "CompletionItemKind",
+    },
+    "DocumentHighlight": {
+      "kind": "DocumentHighlightKind",
+    },
+    "FoldingRange": {
+      "kind": "FoldingRangeKind",
+    },
+  };
+
+  final interface = _improvedTypeMappings[interfaceName];
+
+  return interface != null ? interface[fieldName] : null;
+}
+
+List<String> _getSpecialBaseClasses(String name) {
+  const fileOperationTypes = [
+    'TextDocumentEdit',
+    'CreateFile',
+    'RenameFile',
+    'DeleteFile'
+  ];
+  if (fileOperationTypes.contains(name)) {
+    return ['FileOperation'];
+  } else {
+    return [];
+  }
+}
+
+List<String> _parseTypes(String baseTypes, String sep) {
+  // Special case for a single complicated type we can't parse easily...
+  if (baseTypes ==
+      '(TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[])') {
+    return ['FileOperation[]'];
+  }
+  return baseTypes?.split(sep)?.map((t) => t.trim())?.toList() ?? [];
+}
+
+/// Removes types that are in the spec that we don't want.
+void _removeUnwantedTypes(List<ApiItem> types) {
+  // These types are not used for v3.0 (Feb 2017) and by dropping them we don't
+  // have to handle any cases where both a namespace and interfaces are declared
+  // with the same name.
+  types.removeWhere((item) => item.name == 'InitializeError');
+}
+
+/// Base class for Interface, Field, Constant, etc. parsed from the LSP spec.
+abstract class ApiItem {
+  String name, comment;
+  bool isDeprecated;
+  ApiItem(this.name, String comment)
+      : comment = _cleanComment(comment),
+        isDeprecated = comment?.contains('@deprecated') ?? false;
+
+  static List<ApiItem> extractFrom(String code) {
+    List<ApiItem> types = [];
+    types.addAll(Interface.extractFrom(code));
+    types.addAll(Namespace.extractFrom(code));
+    types.addAll(TypeAlias.extractFrom(code));
+    return types;
+  }
+}
+
+/// A Constant parsed from the LSP spec.
+class Const extends Member {
+  final String type, value;
+  Const(String name, String comment, this.type, this.value)
+      : super(name, comment);
+
+  static List<Const> extractFrom(String code) {
+    final RegExp _constPattern = new RegExp(_comment +
+        r'''(?:export\s+)?const\s+(\w+)(?::\s+([\w\[\]'".-]+?))?\s*=\s*([\w\[\]'".-]+)\s*(?:;|$)''');
+
+    final consts = _constPattern.allMatches(code).map((m) {
+      final String comment = m.group(1);
+      final String name = m.group(2);
+      final String type = m.group(3);
+      final String value = m.group(4);
+      return new Const(name, comment, type, value);
+    }).toList();
+    return consts;
+  }
+
+  static List<Const> extractFromEnumValue(String code) {
+    final RegExp _constPattern =
+        new RegExp(_comment + r'''(\w+)\s*=\s*([\w\[\]'".-]+)\s*(?:,|$)''');
+
+    final consts = _constPattern.allMatches(code).map((m) {
+      final String comment = m.group(1);
+      final String name = m.group(2);
+      final String value = m.group(3);
+      return new Const(name, comment, null, value);
+    }).toList();
+    return consts;
+  }
+}
+
+/// A Field for an Interface parsed from the LSP spec.
+class Field extends Member {
+  final List<String> types;
+  final bool allowsNull, allowsUndefined;
+  Field(String name, String comment, this.types, this.allowsNull,
+      this.allowsUndefined)
+      : super(name, comment);
+
+  static List<Field> extractFrom(String interfaceName, String code) {
+    final RegExp _fieldPattern = new RegExp(_comment +
+        r'([\w\[\]]+\??)\s*:\s*([\w\[\] \|\{\}\(\)<>:;]+)\s*(?:;|$)');
+
+    final fields = _fieldPattern.allMatches(code).where((m) {
+      // Skip over the indexer in FormattingOptions since we don't need this
+      // (for now) and it's complicated to represent.
+      if (m.group(0).contains('[key: string]: boolean | number | string;')) {
+        return false;
+      }
+      return true;
+    }).map((m) {
+      String comment = m.group(1);
+      String name = m.group(2);
+      String typesString = m.group(3).trim();
+      // Our regex may result in semicolons on the end...
+      // TODO(dantup): Fix this, or make a simple parser.
+      if (typesString.endsWith(';')) {
+        typesString = typesString.substring(0, typesString.length - 1);
+      }
+      // Some fields have weird comments like this in the spec:
+      //     {@link MessageType}
+      // These seem to be the correct type of the field, while the field is
+      // marked with number.
+      if (comment != null) {
+        final RegExp _linkTypePattern = new RegExp(r'See \{@link (\w+)\}\.?');
+        final linkTypeMatch = _linkTypePattern.firstMatch(comment);
+        if (linkTypeMatch != null) {
+          typesString = linkTypeMatch.group(1);
+          comment = comment.replaceAll(_linkTypePattern, '');
+        }
+      }
+      List<String> types = _parseTypes(typesString, '|');
+      final bool allowsNull = types.contains('null');
+      if (allowsNull) {
+        types.remove('null');
+      }
+      final bool allowsUndefined = name.endsWith('?');
+      if (allowsUndefined) {
+        name = name.substring(0, name.length - 1);
+      }
+      // Perform simple type improvements for enums values that are typed as
+      // num/string in the spec but are enums.
+      // the spec.
+      if (types.length == 1) {
+        types[0] = _getImprovedType(interfaceName, name) ?? types[0];
+      }
+      return new Field(name, comment, types, allowsNull, allowsUndefined);
+    }).toList();
+    return fields;
+  }
+}
+
+/// An Interface parsed from the LSP spec.
+class Interface extends ApiItem {
+  final List<String> baseTypes;
+  final List<Member> members;
+  Interface(String name, String comment, this.baseTypes, this.members)
+      : super(name, comment);
+
+  static List<Interface> extractFrom(String code) {
+    final RegExp _interfacePattern = new RegExp(_comment +
+        r'(?:export\s+)?(?:interface|class)\s+([\w<>]+)(?:\s+extends\s+([\w, ]+?))?\s*' +
+        _blockBody);
+
+    final interfaces = _interfacePattern.allMatches(code).map((match) {
+      final String comment = match.group(1);
+      final String name = match.group(2);
+      final List<String> baseTypes = _parseTypes(match.group(3), ',');
+      final String body = match.group(4);
+      final List<Member> members = Member.extractFrom(name, body);
+
+      // Add any special base classes we've added to simplify types.
+      baseTypes.addAll(_getSpecialBaseClasses(name));
+
+      return new Interface(name, comment, baseTypes, members);
+    }).toList();
+    return interfaces;
+  }
+}
+
+/// A Field or Constant parsed from the LSP type.
+abstract class Member extends ApiItem {
+  Member(String name, String comment) : super(name, comment);
+
+  static List<Member> extractFrom(String interfaceName, String code) {
+    List<Member> members = [];
+    members.addAll(Field.extractFrom(interfaceName, code));
+    members.addAll(Const.extractFrom(code));
+    return members;
+  }
+}
+
+/// An Enum or Namsepace containing constants parsed from the LSP spec.
+class Namespace extends ApiItem {
+  final List<Member> members;
+  Namespace(String name, String comment, this.members) : super(name, comment);
+
+  static List<Namespace> extractFrom(String code) {
+    final enums = <Namespace>[];
+    enums.addAll(_extractNamespacesFrom(code));
+    enums.addAll(_extractEnumsFrom(code));
+    return enums;
+  }
+
+  static List<Namespace> _extractEnumsFrom(String code) {
+    final RegExp _namespacePattern =
+        new RegExp(_comment + r'(?:export\s+)?enum\s+(\w+)\s*' + _blockBody);
+
+    final namespaces = _namespacePattern.allMatches(code).map((match) {
+      final String comment = match.group(1);
+      final String name = match.group(2);
+      final String body = match.group(3);
+
+      final List<Member> members = Const.extractFromEnumValue(body);
+      return new Namespace(name, comment, members);
+    }).toList();
+    return namespaces;
+  }
+
+  static List<Namespace> _extractNamespacesFrom(String code) {
+    final RegExp _namespacePattern = new RegExp(
+        _comment + r'(?:export\s+)?namespace\s+(\w+)\s*' + _blockBody);
+
+    final namespaces = _namespacePattern.allMatches(code).map((match) {
+      final String comment = match.group(1);
+      final String name = match.group(2);
+      final String body = match.group(3);
+      final List<Member> members = Member.extractFrom(name, body);
+      return new Namespace(name, comment, members);
+    }).toList();
+    return namespaces;
+  }
+}
+
+/// A type alias parsed from the LSP spec.
+class TypeAlias extends ApiItem {
+  final String baseType;
+  TypeAlias(name, comment, this.baseType) : super(name, comment);
+
+  static List<TypeAlias> extractFrom(String code) {
+    final RegExp _typeAliasPattern =
+        new RegExp(_comment + r'type\s+([\w]+)\s+=\s+([\w\[\]]+)\s*;');
+
+    final typeAliases = _typeAliasPattern.allMatches(code).map((match) {
+      final String comment = match.group(1);
+      final String name = match.group(2);
+      final String baseType = match.group(3);
+      return new TypeAlias(name, comment, baseType);
+    }).toList();
+    return typeAliases;
+  }
+}
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index 6b29f65..d1e02b4 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -89,7 +89,7 @@
   bool isDeclaredInSpec(TypeDecl type) {
 //    TypeReference resolvedType = super.resolveTypeReferenceChain(type);
 //    if(resolvedType is TypeObject) {
-//      return truye;
+//      return true;
 //    }
     if (type is TypeReference) {
       return api.types.containsKey(type.typeName) && javaType(type) != 'String';
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 8ef1779..ae85d07 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
  * for details. All rights reserved. Use of this source code is governed by a
  * BSD-style license that can be found in the LICENSE file.
  *
- * This file has been automatically generated.  Please do not edit it manually.
+ * This file has been automatically generated. Please do not edit it manually.
  * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
  */
 package com.google.dart.server.generated;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
index f41ac9a..e3fad08 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
  * for details. All rights reserved. Use of this source code is governed by a
  * BSD-style license that can be found in the LICENSE file.
  *
- * This file has been automatically generated.  Please do not edit it manually.
+ * This file has been automatically generated. Please do not edit it manually.
  * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
  */
 package org.dartlang.analysis.server.protocol;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
index c65d0c9..d4affbc 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
  * for details. All rights reserved. Use of this source code is governed by a
  * BSD-style license that can be found in the LICENSE file.
  *
- * This file has been automatically generated.  Please do not edit it manually.
+ * This file has been automatically generated. Please do not edit it manually.
  * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
  */
 package org.dartlang.analysis.server.protocol;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
index b6aef1f..78cc51f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
  * for details. All rights reserved. Use of this source code is governed by a
  * BSD-style license that can be found in the LICENSE file.
  *
- * This file has been automatically generated.  Please do not edit it manually.
+ * This file has been automatically generated. Please do not edit it manually.
  * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
  */
 package org.dartlang.analysis.server.protocol;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
index 79ae62f..96166f9 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
  * for details. All rights reserved. Use of this source code is governed by a
  * BSD-style license that can be found in the LICENSE file.
  *
- * This file has been automatically generated.  Please do not edit it manually.
+ * This file has been automatically generated. Please do not edit it manually.
  * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
  */
 package org.dartlang.analysis.server.protocol;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
index eb45bf9..3c4d6d9 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
  * for details. All rights reserved. Use of this source code is governed by a
  * BSD-style license that can be found in the LICENSE file.
  *
- * This file has been automatically generated.  Please do not edit it manually.
+ * This file has been automatically generated. Please do not edit it manually.
  * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
  */
 package org.dartlang.analysis.server.protocol;
diff --git