Version 2.5.0-dev.3.0

Merge commit '9f13d07670ac27597538309954d3e21b49752748' into dev
diff --git a/BUILD.gn b/BUILD.gn
index c9f1531..5fd2b63 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -16,7 +16,7 @@
   deps = [
     ":runtime",
   ]
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps += [
       ":llvm_codegen"
     ]
@@ -126,7 +126,7 @@
 }
 
 group("check_llvm") {
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps = [
       "runtime/llvm_codegen/test",
     ]
@@ -134,7 +134,7 @@
 }
 
 group("llvm_codegen") {
-  if (checkout_llvm) {
+  if (defined(checkout_llvm) && checkout_llvm) {
     deps = [
       "runtime/llvm_codegen/codegen",
       "runtime/llvm_codegen/bit",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a0fafe4..c048c13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,46 @@
 
 ### Language
 
+The set of operations allowed in constant expressions has been expanded as
+described in
+the [constant update proposal](https://github.com/dart-lang/language/issues/61).
+The control flow and spread collection features shipped in Dart 2.3 are now also
+supported in constants
+as
+[described in the specification here](https://github.com/dart-lang/language/blob/master/accepted/2.3/unified-collections/feature-specification.md#constant-semantics).
+
+Specifically, it is now valid to use the following operations in constant
+expressions under the appropriate conditions:
+  - Casts (`e as T`) and type tests (`e is T`).
+  - Comparisons to `null`, even for types which override the `==` operator.
+  - The `&`, `|`, and `^` binary operators on booleans.
+  - The spread operators (`...` and `...?`).
+  - An `if` element in a collection literal.
+
+```dart
+// Example: these are now valid constants.
+const i = 3;
+const list = [i as int];
+const set = {if (list is List<int>) ...list};
+const map = {if (i is int) i : "int"};
+```
+
+In addition, the semantics of constant evaluation has been changed as follows:
+  - The `&&` operator only evaluates its second operand if the first evaluates
+  to true.
+  - The `||` operator only evaluates its second operand if the first evaluates
+  to false.
+  - The `??` operator only evaluates its second operand if the first evaluates
+  to null.
+  - The conditional operator (`e ? e1 : e2`) only evaluates one of the two
+    branches, depending on the value of the first operand.
+
+```dart
+// Example: x is now a valid constant definition.
+const String s = null;
+const int x = (s == null) ? 0 : s.length;
+```
+
 ### Core libraries
 
 * **Breaking change** [#36900](https://github.com/dart-lang/sdk/issues/36900):
diff --git a/DEPS b/DEPS
index c512f03..b32253a 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
-  "co19_2_rev": "a6f62f2024492b2c79b741d4b96e67fce31a9830",
+  "co19_2_rev": "d2c051f7537e6fe47c8ccf0bd7a7e84b02010a2a",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
   # should be kept up to date with the revisions pulled by the Flutter engine.
@@ -135,7 +135,7 @@
   "term_glyph_tag": "1.0.1",
   "test_reflective_loader_tag": "0.1.8",
   "test_tag": "test-v1.6.4",
-  "tflite_native_rev": "7f3748a2adf0e7c246813d0b206396312cbaa0db",
+  "tflite_native_rev": "65889224d8ee32ceaf4f78d8d29fd59750e1b817",
   "typed_data_tag": "1.1.6",
   "unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
   "usage_tag": "3.4.0",
diff --git a/PATENTS b/PATENT_GRANT
similarity index 100%
rename from PATENTS
rename to PATENT_GRANT
diff --git a/README.md b/README.md
index 288dac5..e0d4071 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@
 
 Dart is free and open source.
 
-See [LICENSE][license] and [PATENTS][patents].
+See [LICENSE][license] and [PATENT_GRANT][patent_grant].
 
 ## Using Dart
 
@@ -63,4 +63,4 @@
 [dartbug]: http://dartbug.com
 [contrib]: https://github.com/dart-lang/sdk/wiki/Contributing
 [pubsite]: https://pub.dev
-[patents]: https://github.com/dart-lang/sdk/blob/master/PATENTS
+[patent_grant]: https://github.com/dart-lang/sdk/blob/master/PATENT_GRANT
diff --git a/WATCHLISTS b/WATCHLISTS
index 0316d25..1e08225 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -69,8 +69,7 @@
     'dart2js': [ 'johnniwinther@google.com', 'sigmund@google.com',
                  'sra@google.com', 'fishythefish@google.com' ],
     'front_end': [ 'dart-fe-team+reviews@google.com' ],
-    'kernel': [ 'karlklose@google.com', 'jensj@google.com',
-                'alexmarkov@google.com' ],
+    'kernel': [ 'jensj@google.com', 'alexmarkov@google.com' ],
     'messages_review': [ 'dart-uxr+reviews@google.com' ],
     'observatory': [ 'bkonyi@google.com' ],
     'package_vm': [ 'alexmarkov@google.com' ],
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index 06e27a6..295dd33 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -1,4 +1,7 @@
 analyzer:
+  # This currently finds ~1,200 implicit-casts issues when enabled.
+  # strong-mode:
+  #   implicit-casts: false
   exclude:
     - test/mock_packages/**
 
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 85b9e43..0054ab8 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -55,6 +55,9 @@
   if (kind == engine.ElementKind.CONSTRUCTOR) {
     return ElementKind.CONSTRUCTOR;
   }
+  if (kind == engine.ElementKind.EXTENSION) {
+    return ElementKind.EXTENSION;
+  }
   if (kind == engine.ElementKind.FIELD) {
     return ElementKind.FIELD;
   }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 6f3daf6..88d6f46 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -744,6 +744,9 @@
   /// Whether to use the Language Server Protocol.
   bool useLanguageServerProtocol = false;
 
+  /// Whether or not to enable ML code completion.
+  bool enableCompletionModel = false;
+
   /// Base path to locate trained completion language model files.
   String completionModelFolder;
 
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index cecf404..ec7b422 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -6,6 +6,7 @@
 import 'dart:ffi' as ffi;
 import 'dart:io';
 import 'dart:math';
+import 'package:path/path.dart' as path;
 
 import 'package:analysis_server/protocol/protocol_constants.dart'
     show PROTOCOL_VERSION;
@@ -287,6 +288,11 @@
   static const String USE_LSP = "lsp";
 
   /**
+   * Whether or not to enable ML ranking for code completion.
+   */
+  static const String ENABLE_COMPLETION_MODEL = "enable-completion-model";
+
+  /**
    * The path on disk to a directory containing language model files for smart
    * code completion.
    */
@@ -349,6 +355,20 @@
     analysisServerOptions.useLanguageServerProtocol = results[USE_LSP];
     analysisServerOptions.completionModelFolder =
         results[COMPLETION_MODEL_FOLDER];
+    if (results[ENABLE_COMPLETION_MODEL] &&
+        analysisServerOptions.completionModelFolder == null) {
+      // The user has enabled ML code completion without explicitly setting
+      // a model for us to choose, so use the default one. We need to walk over
+      // from $SDK/bin/snapshots/analysis_server.dart.snapshot to
+      // $SDK/model/lexeme.
+      analysisServerOptions.completionModelFolder = path.join(
+          File.fromUri(Platform.script).parent.path,
+          '..',
+          '..',
+          'model',
+          'lexeme');
+    }
+
     AnalysisDriver.useSummary2 = results[USE_SUMMARY2];
 
     bool disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG];
@@ -617,25 +637,27 @@
       SocketServer socketServer,
       LspSocketServer lspSocketServer,
       AnalysisServerOptions analysisServerOptions) {
-    if (analysisServerOptions.completionModelFolder != null &&
-        ffi.sizeOf<ffi.IntPtr>() != 4) {
-      // Start completion model isolate if this is a 64 bit system and
-      // analysis server was configured to load a language model on disk.
-      CompletionRanking.instance =
-          CompletionRanking(analysisServerOptions.completionModelFolder);
-      CompletionRanking.instance.start().catchError((error) {
-        // Disable smart ranking if model startup fails.
-        analysisServerOptions.completionModelFolder = null;
-        CompletionRanking.instance = null;
-        if (socketServer != null) {
-          socketServer.analysisServer.sendServerErrorNotification(
-              'Failed to start ranking model isolate', error, error.stackTrace);
-        } else {
-          lspSocketServer.analysisServer.sendServerErrorNotification(
-              'Failed to start ranking model isolate', error, error.stackTrace);
-        }
-      });
+    if (analysisServerOptions.completionModelFolder == null ||
+        ffi.sizeOf<ffi.IntPtr>() == 4) {
+      return;
     }
+
+    // Start completion model isolate if this is a 64 bit system and
+    // analysis server was configured to load a language model on disk.
+    CompletionRanking.instance =
+        CompletionRanking(analysisServerOptions.completionModelFolder);
+    CompletionRanking.instance.start().catchError((error) {
+      // Disable smart ranking if model startup fails.
+      analysisServerOptions.completionModelFolder = null;
+      CompletionRanking.instance = null;
+      if (socketServer != null) {
+        socketServer.analysisServer.sendServerErrorNotification(
+            'Failed to start ranking model isolate', error, error.stackTrace);
+      } else {
+        lspSocketServer.analysisServer.sendServerErrorNotification(
+            'Failed to start ranking model isolate', error, error.stackTrace);
+      }
+    });
   }
 
   /**
@@ -762,6 +784,8 @@
         help: "Whether to enable parsing via the Fasta parser");
     parser.addFlag(USE_LSP,
         defaultsTo: false, help: "Whether to use the Language Server Protocol");
+    parser.addFlag(ENABLE_COMPLETION_MODEL,
+        help: "Whether or not to turn on ML ranking for code completion");
     parser.addOption(COMPLETION_MODEL_FOLDER,
         help: "[path] path to the location of a code completion model");
     parser.addFlag(USE_SUMMARY2,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index fecfc80..27b6639 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -15,6 +15,7 @@
 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
 import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
@@ -110,6 +111,7 @@
     List<DartCompletionContributor> contributors = <DartCompletionContributor>[
       new ArgListContributor(),
       new CombinatorContributor(),
+      new ExtensionMemberContributor(),
       new FieldFormalContributor(),
       new InheritedReferenceContributor(),
       new KeywordContributor(),
@@ -179,6 +181,7 @@
     performance.logStartTime(SORT_TAG);
     await contributionSorter.sort(dartRequest, suggestions);
     if (ranking != null) {
+      request.checkAborted();
       suggestions = await ranking.rerank(
           probabilityFuture,
           suggestions,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
index 5c7fde6..5858406 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
@@ -76,6 +76,7 @@
       return Future.value(null);
     }
 
+    request.checkAborted();
     final response = await makeRequest('predict', query);
     return response['data'];
   }
@@ -116,10 +117,7 @@
     if (testInsideQuotes(request)) {
       // If completion is requested inside of quotes, remove any suggestions
       // which are not string literal.
-      entries = entries
-          .where((MapEntry entry) =>
-              isStringLiteral(entry.key) && isNotWhitespace(entry.key))
-          .toList();
+      entries = selectStringLiterals(entries);
     } else if (request.opType.includeVarNameSuggestions &&
         suggestions.every((CompletionSuggestion suggestion) =>
             suggestion.kind == CompletionSuggestionKind.IDENTIFIER)) {
@@ -158,8 +156,10 @@
         } else {
           suggestions
               .add(createCompletionSuggestion(entry.key, featureSet, high--));
-          includedSuggestionRelevanceTags
-              .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+          if (includedSuggestionRelevanceTags != null) {
+            includedSuggestionRelevanceTags
+                .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+          }
         }
       } else if (completionSuggestions.isNotEmpty ||
           includedSuggestions.isNotEmpty) {
@@ -174,8 +174,10 @@
         final relevance = low--;
         suggestions
             .add(createCompletionSuggestion(entry.key, featureSet, relevance));
-        includedSuggestionRelevanceTags
-            .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+        if (includedSuggestionRelevanceTags != null) {
+          includedSuggestionRelevanceTags
+              .add(IncludedSuggestionRelevanceTag(entry.key, relevance));
+        }
       }
     });
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
index cb8c923..b552cf6 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
@@ -160,7 +160,9 @@
   }
 
   final result = List<String>();
-  for (var size = 0; size < n && !token.isEof; token = token.previous) {
+  for (var size = 0;
+      size < n && token != null && !token.isEof;
+      token = token.previous) {
     if (!token.isSynthetic && token is! ErrorToken) {
       result.add(token.lexeme);
       size += 1;
@@ -180,3 +182,21 @@
 
   return tag.substring(index + 2);
 }
+
+/// Filters the entries list down to only those which represent string literals
+/// and then strips quotes.
+List<MapEntry<String, double>> selectStringLiterals(List<MapEntry> entries) {
+  return entries
+      .where((MapEntry entry) =>
+          isStringLiteral(entry.key) && isNotWhitespace(entry.key))
+      .map<MapEntry<String, double>>(
+          (MapEntry entry) => MapEntry(trimQuotes(entry.key), entry.value))
+      .toList();
+}
+
+String trimQuotes(String input) {
+  final result = input[0] == '\'' ? input.substring(1) : input;
+  return result[result.length - 1] == '\''
+      ? result.substring(0, result.length - 1)
+      : result;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
new file mode 100644
index 0000000..ab489ad
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2019, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.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/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+
+import '../../../protocol_server.dart' show CompletionSuggestion;
+
+/// A contributor for calculating suggestions based on the members of
+/// extensions.
+class ExtensionMemberContributor extends DartCompletionContributor {
+  MemberSuggestionBuilder builder;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    LibraryElement containingLibrary = request.libraryElement;
+    // Gracefully degrade if the library element is not resolved
+    // e.g. detached part file or source change
+    if (containingLibrary == null) {
+      return const <CompletionSuggestion>[];
+    }
+
+    // Recompute the target since resolution may have changed it.
+    Expression expression = request.dotTarget;
+    if (expression == null || expression.isSynthetic) {
+      return const <CompletionSuggestion>[];
+    }
+    if (expression is Identifier) {
+      Element elem = expression.staticElement;
+      if (elem is ClassElement) {
+        // Suggestions provided by StaticMemberContributor
+        return const <CompletionSuggestion>[];
+      }
+      if (elem is PrefixElement) {
+        // Suggestions provided by LibraryMemberContributor
+        return const <CompletionSuggestion>[];
+      }
+    }
+    builder = MemberSuggestionBuilder(containingLibrary);
+    if (expression is ExtensionOverride) {
+      _addInstanceMembers(expression.staticElement);
+    } else {
+      var type = expression.staticType;
+      LibraryScope nameScope = new LibraryScope(containingLibrary);
+      for (var extension in nameScope.extensions) {
+        var typeSystem = containingLibrary.context.typeSystem;
+        var typeProvider = containingLibrary.context.typeProvider;
+        var extendedType =
+            _resolveExtendedType(typeSystem, typeProvider, extension, type);
+        if (extendedType != null &&
+            typeSystem.isSubtypeOf(type, extendedType)) {
+          // TODO(brianwilkerson) We might want to apply the substitution to the
+          //  members of the extension for display purposes.
+          _addInstanceMembers(extension);
+        }
+      }
+      expression.staticType;
+    }
+    return builder.suggestions.toList();
+  }
+
+  void _addInstanceMembers(ExtensionElement extension) {
+    for (MethodElement method in extension.methods) {
+      if (!method.isStatic) {
+        builder.addSuggestion(method);
+      }
+    }
+    for (PropertyAccessorElement accessor in extension.accessors) {
+      if (!accessor.isStatic) {
+        builder.addSuggestion(accessor);
+      }
+    }
+  }
+
+  /// Use the [typeProvider], [typeSystem] and the [type] of the object being
+  /// extended to compute the actual type extended by the [extension]. Return
+  /// the computed type, or `null` if the type cannot be computed.
+  DartType _resolveExtendedType(TypeSystem typeSystem,
+      TypeProvider typeProvider, ExtensionElement extension, DartType type) {
+    var typeParameters = extension.typeParameters;
+    var inferrer = GenericInferrer(
+      typeProvider,
+      typeSystem,
+      typeParameters,
+    );
+    inferrer.constrainArgument(
+      type,
+      extension.extendedType,
+      'extendedType',
+    );
+    var typeArguments = inferrer.infer(typeParameters, failAtError: true);
+    if (typeArguments == null) {
+      return null;
+    }
+    var substitution = Substitution.fromPairs(
+      typeParameters,
+      typeArguments,
+    );
+    return substitution.substituteType(
+      extension.extendedType,
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
index 71c209a..67a4ebc 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/language_model.dart
@@ -105,6 +105,6 @@
 
     // Get tokens with scores, limiting the length.
     return Map.fromEntries(entries.sublist(0, completions))
-        .map((k, v) => MapEntry(_idx2word[k], v));
+        .map((k, v) => MapEntry(_idx2word[k].replaceAll('"', '\''), v));
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 5d4dfaf..327aca1 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -2,6 +2,8 @@
 // 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:collection';
+
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
@@ -12,6 +14,8 @@
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/util/comment.dart';
 
+import '../../../protocol_server.dart' show CompletionSuggestion;
+
 /**
  * Return a suggestion based upon the given element or `null` if a suggestion
  * is not appropriate for the given element.
@@ -238,3 +242,124 @@
     }
   }
 }
+
+/**
+ * This class provides suggestions based upon the visible instance members in
+ * an interface type.
+ */
+class MemberSuggestionBuilder {
+  /**
+   * Enumerated value indicating that we have not generated any completions for
+   * a given identifier yet.
+   */
+  static const int _COMPLETION_TYPE_NONE = 0;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * getter.
+   */
+  static const int _COMPLETION_TYPE_GETTER = 1;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * setter.
+   */
+  static const int _COMPLETION_TYPE_SETTER = 2;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * field, a method, or a getter/setter pair.
+   */
+  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
+
+  /**
+   * The library containing the unit in which the completion is requested.
+   */
+  final LibraryElement containingLibrary;
+
+  /**
+   * Map indicating, for each possible completion identifier, whether we have
+   * already generated completions for a getter, setter, or both.  The "both"
+   * case also handles the case where have generated a completion for a method
+   * or a field.
+   *
+   * Note: the enumerated values stored in this map are intended to be bitwise
+   * compared.
+   */
+  final Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
+
+  /**
+   * Map from completion identifier to completion suggestion
+   */
+  final Map<String, CompletionSuggestion> _suggestionMap =
+      <String, CompletionSuggestion>{};
+
+  MemberSuggestionBuilder(this.containingLibrary);
+
+  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
+  /**
+   * Add a suggestion based upon the given element, provided that it is not
+   * shadowed by a previously added suggestion.
+   */
+  void addSuggestion(Element element,
+      {int relevance = DART_RELEVANCE_DEFAULT}) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        // Do not suggest private members for imported libraries
+        return;
+      }
+    }
+    String identifier = element.displayName;
+
+    if (relevance == DART_RELEVANCE_DEFAULT && identifier != null) {
+      // Decrease relevance of suggestions starting with $
+      // https://github.com/dart-lang/sdk/issues/27303
+      if (identifier.startsWith(r'$')) {
+        relevance = DART_RELEVANCE_LOW;
+      }
+    }
+
+    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
+        identifier, () => _COMPLETION_TYPE_NONE);
+    if (element is MethodElement) {
+      // Anything shadows a method.
+      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else if (element is PropertyAccessorElement) {
+      if (element.isGetter) {
+        // Getters, fields, and methods shadow a getter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+      } else {
+        // Setters, fields, and methods shadow a setter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+      }
+    } else if (element is FieldElement) {
+      // Fields and methods shadow a field.  A getter/setter pair shadows a
+      // field, but a getter or setter by itself doesn't.
+      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else {
+      // Unexpected element type; skip it.
+      assert(false);
+      return;
+    }
+    CompletionSuggestion suggestion =
+        createSuggestion(element, relevance: relevance);
+    if (suggestion != null) {
+      _suggestionMap[suggestion.completion] = suggestion;
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 909a158..ca30c558 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -236,56 +236,9 @@
  * This class provides suggestions based upon the visible instance members in
  * an interface type.
  */
-class _SuggestionBuilder {
-  /**
-   * Enumerated value indicating that we have not generated any completions for
-   * a given identifier yet.
-   */
-  static const int _COMPLETION_TYPE_NONE = 0;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * getter.
-   */
-  static const int _COMPLETION_TYPE_GETTER = 1;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * setter.
-   */
-  static const int _COMPLETION_TYPE_SETTER = 2;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * field, a method, or a getter/setter pair.
-   */
-  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
-
-  /**
-   * The library containing the unit in which the completion is requested.
-   */
-  final LibraryElement containingLibrary;
-
-  /**
-   * Map indicating, for each possible completion identifier, whether we have
-   * already generated completions for a getter, setter, or both.  The "both"
-   * case also handles the case where have generated a completion for a method
-   * or a field.
-   *
-   * Note: the enumerated values stored in this map are intended to be bitwise
-   * compared.
-   */
-  final Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
-
-  /**
-   * Map from completion identifier to completion suggestion
-   */
-  final Map<String, CompletionSuggestion> _suggestionMap =
-      <String, CompletionSuggestion>{};
-
-  _SuggestionBuilder(this.containingLibrary);
-
-  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+class _SuggestionBuilder extends MemberSuggestionBuilder {
+  _SuggestionBuilder(LibraryElement containingLibrary)
+      : super(containingLibrary);
 
   /**
    * Return completion suggestions for 'dot' completions on the given [type].
@@ -311,7 +264,7 @@
         if (!method.isStatic) {
           // Boost the relevance of a super expression
           // calling a method of the same name as the containing method
-          _addSuggestion(method,
+          addSuggestion(method,
               relevance: method.name == containingMethodName
                   ? DART_RELEVANCE_HIGH
                   : DART_RELEVANCE_DEFAULT);
@@ -322,10 +275,10 @@
           if (propertyAccessor.isSynthetic) {
             // Avoid visiting a field twice
             if (propertyAccessor.isGetter) {
-              _addSuggestion(propertyAccessor.variable);
+              addSuggestion(propertyAccessor.variable);
             }
           } else {
-            _addSuggestion(propertyAccessor);
+            addSuggestion(propertyAccessor);
           }
         }
       }
@@ -333,71 +286,6 @@
   }
 
   /**
-   * Add a suggestion based upon the given element, provided that it is not
-   * shadowed by a previously added suggestion.
-   */
-  void _addSuggestion(Element element,
-      {int relevance = DART_RELEVANCE_DEFAULT}) {
-    if (element.isPrivate) {
-      if (element.library != containingLibrary) {
-        // Do not suggest private members for imported libraries
-        return;
-      }
-    }
-    String identifier = element.displayName;
-
-    if (relevance == DART_RELEVANCE_DEFAULT && identifier != null) {
-      // Decrease relevance of suggestions starting with $
-      // https://github.com/dart-lang/sdk/issues/27303
-      if (identifier.startsWith(r'$')) {
-        relevance = DART_RELEVANCE_LOW;
-      }
-    }
-
-    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
-        identifier, () => _COMPLETION_TYPE_NONE);
-    if (element is MethodElement) {
-      // Anything shadows a method.
-      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else if (element is PropertyAccessorElement) {
-      if (element.isGetter) {
-        // Getters, fields, and methods shadow a getter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
-      } else {
-        // Setters, fields, and methods shadow a setter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
-      }
-    } else if (element is FieldElement) {
-      // Fields and methods shadow a field.  A getter/setter pair shadows a
-      // field, but a getter or setter by itself doesn't.
-      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else {
-      // Unexpected element type; skip it.
-      assert(false);
-      return;
-    }
-    CompletionSuggestion suggestion =
-        createSuggestion(element, relevance: relevance);
-    if (suggestion != null) {
-      _suggestionMap[suggestion.completion] = suggestion;
-    }
-  }
-
-  /**
    * Get a list of [InterfaceType]s that should be searched to find the
    * possible completions for an object having type [type].
    */
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 774612b..d2cd3f5 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -342,13 +342,16 @@
       await _addFix_updateSdkConstraints('2.2.0');
     }
     if (errorCode == HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT ||
-        errorCode == HintCode.SDK_VERSION_BOOL_OPERATOR ||
+        errorCode == HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT ||
         errorCode == HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT ||
         errorCode == HintCode.SDK_VERSION_GT_GT_GT_OPERATOR ||
         errorCode == HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT ||
         errorCode == HintCode.SDK_VERSION_UI_AS_CODE) {
       await _addFix_updateSdkConstraints('2.2.2');
     }
+    if (errorCode == HintCode.SDK_VERSION_EXTENSION_METHODS) {
+      await _addFix_updateSdkConstraints('2.6.0');
+    }
     if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
       await _addFix_isNotNull();
     }
@@ -2103,11 +2106,7 @@
     String prefix = utils.getNodePrefix(target);
     // compute type
     DartType type = _inferUndefinedExpressionType(node);
-    if (!(type == null ||
-        type is InterfaceType ||
-        type is FunctionType &&
-            type.element != null &&
-            !type.element.isSynthetic)) {
+    if (!(type == null || type is InterfaceType || type is FunctionType)) {
       return;
     }
     // build variable declaration source
@@ -4012,21 +4011,18 @@
    * the given [element].
    */
   Future<void> _addFix_useStaticAccess(AstNode target, Element element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    Element declaringElement = element.enclosingElement;
-    if (declaringElement is ClassElement) {
-      DartType declaringType = declaringElement.type;
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        // replace "target" with class name
-        builder.addReplacement(range.node(target), (DartEditBuilder builder) {
-          builder.writeType(declaringType);
-        });
+    var declaringElement = element.enclosingElement;
+    var changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(target), (DartEditBuilder builder) {
+        builder.writeReference(declaringElement);
       });
-      _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO_STATIC_ACCESS,
-          args: [declaringType]);
-    }
+    });
+    _addFixFromBuilder(
+      changeBuilder,
+      DartFixKind.CHANGE_TO_STATIC_ACCESS,
+      args: [declaringElement.name],
+    );
   }
 
   Future<void> _addFix_useStaticAccess_method() async {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index c88d8a5..233123c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -15,6 +15,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/rename_class_member.dart';
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -39,7 +40,8 @@
   Element element = node.staticElement;
   if (element is LocalVariableElement ||
       element is ParameterElement ||
-      element is FunctionElement && element.visibleRange != null) {
+      element is FunctionElement &&
+          element.enclosingElement is! CompilationUnitElement) {
     return element;
   }
   return null;
@@ -93,6 +95,11 @@
   final List<int> lengths = <int>[];
 
   /**
+   * The map of local elements to their visibility ranges.
+   */
+  Map<LocalElement, SourceRange> _visibleRangeMap;
+
+  /**
    * The map of local names to their visibility ranges.
    */
   final Map<String, List<SourceRange>> _localNames =
@@ -733,8 +740,13 @@
     _parameterReferencesMap.clear();
     RefactoringStatus result = new RefactoringStatus();
     List<VariableElement> assignedUsedVariables = [];
-    resolveResult.unit
-        .accept(new _InitializeParametersVisitor(this, assignedUsedVariables));
+
+    var unit = resolveResult.unit;
+    _visibleRangeMap = VisibleRangesComputer.forNode(unit);
+    unit.accept(
+      _InitializeParametersVisitor(this, assignedUsedVariables),
+    );
+
     // single expression
     if (_selectionExpression != null) {
       _returnType = _selectionExpression.staticType;
@@ -1294,7 +1306,7 @@
       // declared local elements
       if (node.inDeclarationContext()) {
         ref._localNames.putIfAbsent(name, () => <SourceRange>[]);
-        ref._localNames[name].add(element.visibleRange);
+        ref._localNames[name].add(ref._visibleRangeMap[element]);
       }
     } else {
       // unqualified non-local names
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 5a1634f..b487d2d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -156,13 +157,12 @@
   {
     SourceRange localsRange = _getLocalsConflictingRange(node);
     AstNode enclosingExecutable = getEnclosingExecutableNode(node);
-    List<LocalElement> elements = getDefinedLocalElements(enclosingExecutable);
-    for (LocalElement element in elements) {
-      SourceRange elementRange = element.visibleRange;
-      if (elementRange != null && elementRange.intersects(localsRange)) {
+    var visibleRangeMap = VisibleRangesComputer.forNode(enclosingExecutable);
+    visibleRangeMap.forEach((element, elementRange) {
+      if (elementRange.intersects(localsRange)) {
         result.add(element.displayName);
       }
-    }
+    });
   }
   // fields
   {
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 8bb80c3..5bc5afa 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -16,7 +16,8 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
 import 'package:path/path.dart' as pathos;
 
 /**
@@ -69,19 +70,21 @@
 
   @override
   Future<SourceChange> createChange() async {
-    final DartChangeBuilder changeBuilder =
-        new DartChangeBuilder(driver.currentSession);
+    final ChangeBuilder changeBuilder = new ChangeBuilder();
     final CompilationUnitElement element = resolvedUnit.unit.declaredElement;
     if (element == null) {
       return changeBuilder.sourceChange;
     }
-    final LibraryElement libraryElement = element.library;
+
+    var libraryElement = element.library;
+    var libraryPath = libraryElement.source.fullName;
 
     // If this element is a library, update outgoing references inside the file.
     if (element == libraryElement.definingCompilationUnit) {
       // Handle part-of directives in this library
       final ResolvedLibraryResult libraryResult = await driver.currentSession
           .getResolvedLibraryByElement(libraryElement);
+      ResolvedUnitResult definingUnitResult;
       for (ResolvedUnitResult result in libraryResult.units) {
         if (result.isPart) {
           Iterable<PartOfDirective> partOfs = result.unit.directives
@@ -103,15 +106,19 @@
             });
           }
         }
+        if (result.path == libraryPath) {
+          definingUnitResult = result;
+        }
       }
 
-      await changeBuilder.addFileEdit(libraryElement.source.fullName,
-          (builder) {
+      await changeBuilder.addFileEdit(definingUnitResult.path, (builder) {
         final String oldDir = pathContext.dirname(oldFile);
         final String newDir = pathContext.dirname(newFile);
-        _updateUriReferences(builder, libraryElement.imports, oldDir, newDir);
-        _updateUriReferences(builder, libraryElement.exports, oldDir, newDir);
-        _updateUriReferences(builder, libraryElement.parts, oldDir, newDir);
+        for (var directive in definingUnitResult.unit.directives) {
+          if (directive is UriBasedDirective) {
+            _updateUriReference(builder, directive, oldDir, newDir);
+          }
+        }
       });
     } else {
       // Otherwise, we need to update any relative part-of references.
@@ -198,25 +205,14 @@
     return true;
   }
 
-  void _updateUriReference(DartFileEditBuilder builder,
-      UriReferencedElement element, String oldDir, String newDir) {
-    if (!element.isSynthetic) {
-      String elementUri = element.uri;
-      if (_isRelativeUri(elementUri)) {
-        String elementPath = pathContext.join(oldDir, elementUri);
-        String newUri = _getRelativeUri(elementPath, newDir);
-        int uriOffset = element.uriOffset;
-        int uriLength = element.uriEnd - uriOffset;
-        builder.addSimpleReplacement(
-            new SourceRange(uriOffset, uriLength), "'$newUri'");
-      }
-    }
-  }
-
-  void _updateUriReferences(DartFileEditBuilder builder,
-      List<UriReferencedElement> elements, String oldDir, String newDir) {
-    for (UriReferencedElement element in elements) {
-      _updateUriReference(builder, element, oldDir, newDir);
+  void _updateUriReference(FileEditBuilder builder, UriBasedDirective directive,
+      String oldDir, String newDir) {
+    var uriNode = directive.uri;
+    var uriValue = uriNode.stringValue;
+    if (_isRelativeUri(uriValue)) {
+      String elementPath = pathContext.join(oldDir, uriValue);
+      String newUri = _getRelativeUri(elementPath, newDir);
+      builder.addSimpleReplacement(range.node(uriNode), "'$newUri'");
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 4f8afd4..645e6de 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/session.dart';
@@ -257,22 +258,25 @@
   }
 
   Future<_MatchShadowedByLocal> _getShadowingLocalElement() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var localElementMap = <CompilationUnitElement, List<LocalElement>>{};
-    Future<List<LocalElement>> getLocalElements(Element element) async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
+    var visibleRangeMap = <LocalElement, SourceRange>{};
 
-      var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
-      var unitElement = resolvedUnit.unit.declaredElement;
+    Future<List<LocalElement>> getLocalElements(Element element) async {
+      var unitElement = element.getAncestor((e) => e is CompilationUnitElement);
       var localElements = localElementMap[unitElement];
+
       if (localElements == null) {
+        var result = await sessionHelper.getResolvedUnitByElement(element);
+        var unit = result.unit;
+
         var collector = new _LocalElementsCollector(name);
-        resolvedUnit.unit.accept(collector);
+        unit.accept(collector);
         localElements = collector.elements;
         localElementMap[unitElement] = localElements;
+
+        visibleRangeMap.addAll(VisibleRangesComputer.forNode(unit));
       }
+
       return localElements;
     }
 
@@ -284,7 +288,7 @@
       // Check local elements that might shadow the reference.
       var localElements = await getLocalElements(match.element);
       for (LocalElement localElement in localElements) {
-        SourceRange elementRange = localElement.visibleRange;
+        SourceRange elementRange = visibleRangeMap[localElement];
         if (elementRange != null &&
             elementRange.intersects(match.sourceRange)) {
           return new _MatchShadowedByLocal(match, localElement);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 7fac53a..6d1f602 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -11,6 +11,7 @@
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
+import 'package:analysis_server/src/services/refactoring/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -47,14 +48,19 @@
 
   @override
   Future<RefactoringStatus> checkFinalConditions() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     RefactoringStatus result = new RefactoringStatus();
     await _prepareElements();
     for (LocalElement element in elements) {
       var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
       var unit = resolvedUnit.unit;
-      unit.accept(new _ConflictValidatorVisitor(result, newName, element));
+      unit.accept(
+        _ConflictValidatorVisitor(
+          result,
+          newName,
+          element,
+          VisibleRangesComputer.forNode(unit),
+        ),
+      );
     }
     return result;
   }
@@ -92,8 +98,6 @@
    * Fills [elements] with [Element]s to rename.
    */
   Future _prepareElements() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     Element element = this.element;
     if (element is ParameterElement && element.isNamed) {
       elements = await getHierarchyNamedParameters(searchEngine, element);
@@ -107,9 +111,15 @@
   final RefactoringStatus result;
   final String newName;
   final LocalElement target;
+  final Map<Element, SourceRange> visibleRangeMap;
   final Set<Element> conflictingLocals = new Set<Element>();
 
-  _ConflictValidatorVisitor(this.result, this.newName, this.target);
+  _ConflictValidatorVisitor(
+    this.result,
+    this.newName,
+    this.target,
+    this.visibleRangeMap,
+  );
 
   @override
   visitSimpleIdentifier(SimpleIdentifier node) {
@@ -127,7 +137,7 @@
         return;
       }
       // Shadowing by the target element.
-      SourceRange targetRange = target.visibleRange;
+      SourceRange targetRange = _getVisibleRange(target);
       if (targetRange != null &&
           targetRange.contains(node.offset) &&
           !node.isQualified &&
@@ -144,13 +154,17 @@
     }
   }
 
+  SourceRange _getVisibleRange(LocalElement element) {
+    return visibleRangeMap[element];
+  }
+
   /**
    * Returns whether [element] and [target] are visible together.
    */
   bool _isVisibleWithTarget(Element element) {
     if (element is LocalElement) {
-      SourceRange targetRange = target.visibleRange;
-      SourceRange elementRange = element.visibleRange;
+      SourceRange targetRange = _getVisibleRange(target);
+      SourceRange elementRange = _getVisibleRange(element);
       return targetRange != null &&
           elementRange != null &&
           elementRange.intersects(targetRange);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart b/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
new file mode 100644
index 0000000..f894bee
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/refactoring/visible_ranges_computer.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+/// Computer of local elements and source ranges in which they are visible.
+class VisibleRangesComputer extends GeneralizingAstVisitor<void> {
+  final Map<LocalElement, SourceRange> _map = {};
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    _addLocalVariable(node, node.exceptionParameter?.staticElement);
+    _addLocalVariable(node, node.stackTraceParameter?.staticElement);
+    node.body.accept(this);
+  }
+
+  @override
+  void visitFormalParameter(FormalParameter node) {
+    var element = node.declaredElement;
+    if (element is ParameterElement) {
+      var body = _getFunctionBody(node);
+      if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
+        _map[element] = range.node(body);
+      }
+    }
+  }
+
+  @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    var loop = node.parent;
+    for (var variable in node.variables.variables) {
+      _addLocalVariable(loop, variable.declaredElement);
+      variable.initializer?.accept(this);
+    }
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    var block = node.parent?.parent;
+    if (block is Block) {
+      var element = node.declaredElement as FunctionElement;
+      _map[element] = range.node(block);
+    }
+
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    var block = node.parent;
+    for (var variable in node.variables.variables) {
+      _addLocalVariable(block, variable.declaredElement);
+      variable.initializer?.accept(this);
+    }
+  }
+
+  void _addLocalVariable(AstNode scopeNode, Element element) {
+    if (element is LocalVariableElement) {
+      _map[element] = range.node(scopeNode);
+    }
+  }
+
+  static Map<LocalElement, SourceRange> forNode(AstNode unit) {
+    var computer = VisibleRangesComputer();
+    unit.accept(computer);
+    return computer._map;
+  }
+
+  /**
+   * Return the body of the function that contains the given [parameter], or
+   * `null` if no function body could be found.
+   */
+  static FunctionBody _getFunctionBody(FormalParameter parameter) {
+    var parent = parameter?.parent?.parent;
+    if (parent is ConstructorDeclaration) {
+      return parent.body;
+    } else if (parent is FunctionExpression) {
+      return parent.body;
+    } else if (parent is MethodDeclaration) {
+      return parent.body;
+    }
+    return null;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 461c167..bbac8d1 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -73,6 +73,11 @@
   // TODO(brianwilkerson) Determine whether this await is necessary.
   await null;
   Set<ClassMemberElement> result = new HashSet<ClassMemberElement>();
+  // extension member
+  if (member.enclosingElement is ExtensionElement) {
+    result.add(member);
+    return new Future.value(result);
+  }
   // static elements
   if (member.isStatic || member is ConstructorElement) {
     result.add(member);
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 4f34392..5783123 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -363,6 +363,19 @@
     assertHasRegionTarget('BBB p', 'BBB {}');
   }
 
+  test_extension_on() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+class C //1
+{}
+extension E on C //2
+{}
+''');
+    await prepareNavigation();
+    assertHasRegion('C //2');
+    assertHasTarget('C //1');
+  }
+
   test_factoryRedirectingConstructor_implicit() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index e3c256c..84fd4df 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -227,7 +227,6 @@
       engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
       engine.ElementKind.ERROR: ElementKind.UNKNOWN,
       engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
-      engine.ElementKind.EXTENSION: ElementKind.UNKNOWN,
       engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 3e88bcd..eadbc58 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -128,6 +128,26 @@
     assertHasResult(SearchResultKind.REFERENCE, '(1)', 0);
   }
 
+  test_extension() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  static void foo() {}
+  void bar() {}
+}
+
+main() {
+  E.foo();
+  E(0).bar();
+}
+''');
+    await findElementReferences('E on int', false);
+    expect(searchElement.kind, ElementKind.EXTENSION);
+    expect(results, hasLength(2));
+    assertHasResult(SearchResultKind.REFERENCE, 'E.foo();');
+    assertHasResult(SearchResultKind.REFERENCE, 'E(0)');
+  }
+
   Future<void> test_field_explicit() async {
     addTestFile('''
 class A {
@@ -218,6 +238,112 @@
     assertHasResult(SearchResultKind.READ, 'fff); // in m()');
   }
 
+  test_field_ofExtension_explicit_static() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  static var fff; // declaration
+
+  void m() {
+    fff = 2;
+    fff += 3;
+    print(fff); // in m()
+    fff(); // in m()
+  }
+}
+
+main() {
+  E.fff = 20;
+  E.fff += 30;
+  print(E.fff); // in main()
+  E.fff(); // in main()
+}
+''');
+    await findElementReferences('fff; // declaration', false);
+    expect(searchElement.kind, ElementKind.FIELD);
+    expect(results, hasLength(8));
+    // m()
+    assertHasResult(SearchResultKind.WRITE, 'fff = 2;');
+    assertHasResult(SearchResultKind.WRITE, 'fff += 3;');
+    assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+    assertHasResult(SearchResultKind.INVOCATION, 'fff(); // in m()');
+    // main()
+    assertHasResult(SearchResultKind.WRITE, 'fff = 20;');
+    assertHasResult(SearchResultKind.WRITE, 'fff += 30;');
+    assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+    assertHasResult(SearchResultKind.INVOCATION, 'fff(); // in main()');
+  }
+
+  test_field_ofExtension_implicit_instance() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  var get fff => null;
+  set fff(x) {}
+  m() {
+    print(fff); // in m()
+    fff = 1;
+  }
+}
+main() {
+  print(0.fff); // in main()
+  0.fff = 10;
+}
+''');
+    {
+      await findElementReferences('fff =>', false);
+      expect(searchElement.kind, ElementKind.FIELD);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+    {
+      await findElementReferences('fff(x) {}', false);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+  }
+
+  test_field_ofExtension_implicit_static() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  static var get fff => null;
+  static set fff(x) {}
+  m() {
+    print(fff); // in m()
+    fff = 1;
+  }
+}
+main() {
+  print(E.fff); // in main()
+  E.fff = 10;
+}
+''');
+    {
+      await findElementReferences('fff =>', false);
+      expect(searchElement.kind, ElementKind.FIELD);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+    {
+      await findElementReferences('fff(x) {}', false);
+      expect(results, hasLength(4));
+      assertHasResult(SearchResultKind.READ, 'fff); // in m()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 1;');
+      assertHasResult(SearchResultKind.READ, 'fff); // in main()');
+      assertHasResult(SearchResultKind.WRITE, 'fff = 10;');
+    }
+  }
+
   Future<void> test_function() async {
     addTestFile('''
 fff(p) {}
@@ -389,6 +515,29 @@
     assertHasResult(SearchResultKind.REFERENCE, 'mmm); // in main()');
   }
 
+  test_method_ofExtension() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension E on int {
+  void foo() {}
+}
+
+main() {
+  E(0).foo(); // 1
+  E(0).foo; // 2
+  0.foo(); // 3
+  0.foo; // 4
+}
+''');
+    await findElementReferences('foo() {}', false);
+    expect(searchElement.kind, ElementKind.METHOD);
+    expect(results, hasLength(4));
+    assertHasResult(SearchResultKind.INVOCATION, 'foo(); // 1');
+    assertHasResult(SearchResultKind.REFERENCE, 'foo; // 2');
+    assertHasResult(SearchResultKind.INVOCATION, 'foo(); // 3');
+    assertHasResult(SearchResultKind.REFERENCE, 'foo; // 4');
+  }
+
   Future<void> test_method_propagatedType() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 913f821..b020a05 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_test.dart
@@ -57,6 +57,15 @@
     return null;
   }
 
+  test_extensionDeclaration() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    addTestFile('''
+extension MyExtension on int {}
+''');
+    await findTopLevelDeclarations('My*');
+    assertHasDeclaration(ElementKind.EXTENSION, 'MyExtension');
+  }
+
   test_invalidRegex() async {
     var result = await findTopLevelDeclarations('[A');
     expect(result, const TypeMatcher<RequestError>());
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart
index 1e1e041..ad33cdb 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_ranking_internal_test.dart
@@ -199,4 +199,17 @@
         'package::flutter/src/widgets/preferred_size.dart::::PreferredSizeWidget';
     expect(elementNameFromRelevanceTag(tag), equals('PreferredSizeWidget'));
   });
+
+  test('selectStringLiterals', () {
+    final result = selectStringLiterals([
+      MapEntry('foo', 0.2),
+      MapEntry("'bar'", 0.3),
+      MapEntry('\'baz\'', 0.1),
+      MapEntry("'qu\'ux'", 0.4),
+    ]);
+    expect(result[0].key, equals('bar'));
+    expect(result[1].key, equals('baz'));
+    expect(result[2].key, equals('qu\'ux'));
+    expect(result, hasLength(3));
+  });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
new file mode 100644
index 0000000..1e42d22
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2019, 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/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_contributor_util.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExtensionMemberContributorTest);
+  });
+}
+
+@reflectiveTest
+class ExtensionMemberContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new ExtensionMemberContributor();
+  }
+
+  void setUp() {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    super.setUp();
+  }
+
+  test_extensionOverride_doesNotMatch() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  E('3').a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_extensionOverride_matches() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  E(2).a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_function_doesNotMatch() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+List<T> g<T>(T x) => [x];
+void f(String s) {
+  g(s).a^
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('c');
+  }
+
+  test_function_matches() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  g().a^
+}
+int g() => 3;
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_identifier_doesNotMatch() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f(List<String> l) {
+  l.a^
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('c');
+  }
+
+  test_identifier_matches() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f(List<int> l) {
+  l.a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+
+  test_literal_doesNotMatch() async {
+    addTestSource('''
+extension E<T extends num> on List<T> {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  ['a'].a^
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('c');
+  }
+
+  test_literal_matches() async {
+    addTestSource('''
+extension E on int {
+  bool a(int b, int c) {}
+  int get b => 0;
+  set c(int d) {}
+}
+void f() {
+  2.a^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', null, 'bool', defaultArgListString: 'b, c');
+    assertSuggestGetter('b', 'int');
+    assertSuggestSetter('c');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/language_model_test.dart b/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
index 32a09a8..2163e7b 100644
--- a/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/language_model_test.dart
@@ -48,12 +48,12 @@
     final best = suggestions.entries.first;
     expect(best.key, 'length');
     expect(best.value, greaterThan(0.8));
+    expect(suggestions, hasLength(model.completions));
   });
 
   test('predict when no previous tokens', () {
     final tokens = <String>[];
     final suggestions = model.predict(tokens);
-    expect(suggestions, hasLength(model.completions));
     expect(suggestions.first, isNotEmpty);
   });
 
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 3cd1ed2..b91a939 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
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -13,6 +14,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(LocalReferenceContributorTest);
+    defineReflectiveTests(LocalReferenceContributorWithExtensionMethodsTest);
   });
 }
 
@@ -3947,6 +3949,35 @@
     await computeSuggestions();
   }
 
+  test_mixinDeclaration_body() async {
+    // MixinDeclaration  CompilationUnit
+    addSource('/home/test/lib/b.dart', '''
+class B { }''');
+    addTestSource('''
+import "b.dart" as x;
+mixin M {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion suggestionM = assertSuggestMixin('M');
+    if (suggestionM != null) {
+      expect(suggestionM.element.isDeprecated, isFalse);
+      expect(suggestionM.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion suggestionB = assertSuggestClass('_B');
+    if (suggestionB != null) {
+      expect(suggestionB.element.isDeprecated, isFalse);
+      expect(suggestionB.element.isPrivate, isTrue);
+    }
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
   test_new_instance() async {
     addTestSource('import "dart:math"; class A {x() {new Random().^}}');
     await computeSuggestions();
@@ -4905,3 +4936,42 @@
     assertSuggestMixin('M');
   }
 }
+
+@reflectiveTest
+class LocalReferenceContributorWithExtensionMethodsTest
+    extends LocalReferenceContributorTest {
+  @override
+  void setUp() {
+    createAnalysisOptionsFile(
+      experiments: [
+        EnableString.extension_methods,
+      ],
+    );
+    super.setUp();
+  }
+
+  test_extensionDeclaration_body() async {
+    // ExtensionDeclaration  CompilationUnit
+    addSource('/home/test/lib/b.dart', '''
+class B { }''');
+    addTestSource('''
+import "b.dart" as x;
+extension E on int {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion suggestionB = assertSuggestClass('_B');
+    if (suggestionB != null) {
+      expect(suggestionB.element.isDeprecated, isFalse);
+      expect(suggestionB.element.isPrivate, isTrue);
+    }
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('E');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index d94b577..3bf866a 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -8,10 +8,11 @@
 import 'combinator_contributor_test.dart' as combinator_test;
 import 'common_usage_sorter_test.dart' as common_usage_test;
 import 'completion_manager_test.dart' as completion_manager;
-// ignore: unused_import
-import 'completion_ranking_test.dart' as completion_ranking_test;
 import 'completion_ranking_internal_test.dart'
     as completion_ranking_internal_test;
+// ignore: unused_import
+import 'completion_ranking_test.dart' as completion_ranking_test;
+import 'extension_member_contributor_test.dart' as extension_member_contributor;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
 import 'imported_reference_contributor_test.dart' as imported_ref_test;
 import 'inherited_reference_contributor_test.dart' as inherited_ref_test;
@@ -41,6 +42,7 @@
     //   output from the tflite shared library
     // completion_ranking_test.main();
     completion_ranking_internal_test.main();
+    extension_member_contributor.main();
     field_formal_contributor_test.main();
     imported_ref_test.main();
     inherited_ref_test.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
index 507b291..8ae3d08 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
@@ -10,12 +10,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ChangeToStaticAccessTest);
+    defineReflectiveTests(ChangeToStaticAccessClassTest);
+    defineReflectiveTests(ChangeToStaticAccessExtensionTest);
   });
 }
 
 @reflectiveTest
-class ChangeToStaticAccessTest extends FixProcessorTest {
+class ChangeToStaticAccessClassTest extends FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
 
@@ -128,3 +129,50 @@
 ''');
   }
 }
+
+@reflectiveTest
+class ChangeToStaticAccessExtensionTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
+
+  test_method() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    await resolveTestUnit('''
+extension E on int {
+  static void foo() {}
+}
+main() {
+  0.foo();
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  static void foo() {}
+}
+main() {
+  E.foo();
+}
+''');
+  }
+
+  @failingTest
+  test_property() async {
+    createAnalysisOptionsFile(experiments: ['extension-methods']);
+    await resolveTestUnit('''
+extension E on int {
+  static int get foo => 42;
+}
+main() {
+  0.foo;
+}
+''');
+    await assertHasFix('''
+extension E on int {
+  static int get foo => 42;
+}
+main() {
+  E.foo;
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
index 03dda70..e240531 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -87,7 +87,7 @@
 
 class B extends A {
   @override
-  void forEach(int Function(double, String) f) {
+  void forEach(int Function(double p1, String p2) f) {
     // TODO: implement forEach
   }
 }
diff --git a/pkg/analysis_server_client/analysis_options.yaml b/pkg/analysis_server_client/analysis_options.yaml
new file mode 100644
index 0000000..8211da4
--- /dev/null
+++ b/pkg/analysis_server_client/analysis_options.yaml
@@ -0,0 +1,10 @@
+analyzer:
+  #strong-mode:
+  #  implicit-casts: false
+
+linter:
+  rules:
+    - empty_constructor_bodies
+    - empty_statements
+    - unnecessary_brace_in_string_interps
+    - valid_regexps
diff --git a/pkg/analysis_server_client/example/example.dart b/pkg/analysis_server_client/example/example.dart
index 21573b4..f9dc7ce 100644
--- a/pkg/analysis_server_client/example/example.dart
+++ b/pkg/analysis_server_client/example/example.dart
@@ -99,7 +99,7 @@
       if (errorCount == 0) {
         print('No issues found.');
       } else {
-        print('Found ${errorCount} errors/warnings/hints');
+        print('Found $errorCount errors/warnings/hints');
       }
       errorCount = 0;
       print('--------- ctrl-c to exit ---------');
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart
index bdce37f..39dc294 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_util.dart
@@ -32,13 +32,14 @@
   }
 
   /// Combines together two hash codes.
-  static int hash2(a, b) => finish(combine(combine(0, a), b));
+  static int hash2(int a, int b) => finish(combine(combine(0, a), b));
 
   /// Combines together three hash codes.
-  static int hash3(a, b, c) => finish(combine(combine(combine(0, a), b), c));
+  static int hash3(int a, int b, int c) =>
+      finish(combine(combine(combine(0, a), b), c));
 
   /// Combines together four hash codes.
-  static int hash4(a, b, c, d) =>
+  static int hash4(int a, int b, int c, int d) =>
       finish(combine(combine(combine(combine(0, a), b), c), d));
 
   int _hash = 0;
diff --git a/pkg/analysis_tool/analysis_options.yaml b/pkg/analysis_tool/analysis_options.yaml
new file mode 100644
index 0000000..7b2fbe6
--- /dev/null
+++ b/pkg/analysis_tool/analysis_options.yaml
@@ -0,0 +1,10 @@
+analyzer:
+  strong-mode:
+    implicit-casts: false
+
+linter:
+  rules:
+    - empty_constructor_bodies
+    - empty_statements
+    - unnecessary_brace_in_string_interps
+    - valid_regexps
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index a4090eb..3071788 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,22 @@
-## 0.37.1 (Not yet published)
+## 0.38.0
+* The deprecated method `AstFactory.compilationUnit2` has been removed.  Clients
+  should switch back to `AstFactory.compilationUnit`.
+* Removed the deprecated constructor `ParsedLibraryResultImpl.tmp` and the
+  deprecated method `ResolvedLibraryResultImpl.tmp`.  Please use
+  `AnalysisSession.getParsedLibraryByElement` and
+  `AnalysisSession.getResolvedLibraryByElement` instead.
+* Removed `MethodElement.getReifiedType`.
+* The return type of `ClassMemberElement.enclosingElement` was changed from
+  `ClassElement` to `Element`.
+
+## 0.37.1+1
+* Reverted an unintentional breaking API change (the return type of
+  `ClassMemberElement.enclosingElement` was changed from `ClassElement` to
+  `Element`).  This change will be postponed until 0.38.0.
+
+## 0.37.1
 * Added the getters `isDartCoreList`, `isDartCoreMap`, `isDartCoreNum`,
-  `isDartCoreSet`, and `isDartCoreSymbol` to `DartType`.
+  `isDartCoreSet`, `isDartCoreSymbol`, and `isDartCoreObject` to `DartType`.
 * Added the method `DartObject.toFunctionValue`.
 * Deprecated the `isEquivalentTo(DartType)` method of `DartType`.
   The operator `==` now correctly considers two types equal if and
@@ -16,6 +32,12 @@
 * Added the optional parameter `path` to `parseString`.
 * Changed `TypeSystem.resolveToBound(DartType)` implementation to do
   what its documentation says.
+* This version of the analyzer should contain all the necessary parsing support
+  and AST data structures for the experimental "extension-methods" feature.
+  Further element model improvements needed to support extension methods will be
+  published in 0.38.x.
+* Deprecated `InterfaceType.isDirectSupertypeOf`.  There is no replacement; this
+  method was not intended to be used outside of the analyzer.
 
 ## 0.37.0
 * Removed deprecated getter `DartType.isUndefined`.
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index a8010a3..1c02e60 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -1,3 +1,8 @@
+analyzer:
+  # This currently finds ~4,500 implicit-casts issues when enabled.
+  # strong-mode:
+  #   implicit-casts: false
+
 linter:
   rules:
     - empty_constructor_bodies # pedantic
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index e389879..588b923 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -989,7 +989,10 @@
   ConstructorDeclaration getConstructor(String name);
 }
 
-/// A node that declares a name within the scope of a class.
+/// A node that declares a name within the scope of a class declarations.
+///
+/// When the 'extension-methods' experiment is enabled, these nodes can also be
+/// located inside extension declarations.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ClassMember implements Declaration {}
@@ -2189,6 +2192,10 @@
 ///    fieldDeclaration ::=
 ///        'static'? [VariableDeclarationList] ';'
 ///
+/// Prior to the 'extension-methods' experiment, these nodes were always
+/// children of a class declaration. When the experiment is enabled, these nodes
+/// can also be children of an extension declaration.
+///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FieldDeclaration implements ClassMember {
   /// The 'covariant' keyword, or `null` if the keyword was not used.
@@ -3739,6 +3746,10 @@
 ///        [SimpleIdentifier]
 ///      | 'operator' [SimpleIdentifier]
 ///
+/// Prior to the 'extension-methods' experiment, these nodes were always
+/// children of a class declaration. When the experiment is enabled, these nodes
+/// can also be children of an extension declaration.
+///
 /// Clients may not extend, implement or mix-in this class.
 abstract class MethodDeclaration implements ClassMember {
   /// Return the body of the method.
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index d8cffd0..911b6b5 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -167,23 +167,6 @@
       @required Token endToken,
       @required FeatureSet featureSet});
 
-  /// Returns a newly created compilation unit to have the given directives and
-  /// declarations.  The [scriptTag] can be `null` (or omitted) if there is no
-  /// script tag in the compilation unit.  The list of [declarations] can be
-  /// `null` (or omitted) if there are no directives in the compilation unit.
-  /// The list of `declarations` can be `null` (or omitted) if there are no
-  /// declarations in the compilation unit.  The [featureSet] can be `null` if
-  /// the set of features for this compilation unit is not known (this
-  /// restricts what analysis can be done of the compilation unit).
-  @Deprecated('Use compilationUnit')
-  CompilationUnit compilationUnit2(
-      {@required Token beginToken,
-      ScriptTag scriptTag,
-      List<Directive> directives,
-      List<CompilationUnitMember> declarations,
-      @required Token endToken,
-      @required FeatureSet featureSet});
-
   /// Returns a newly created conditional expression.
   ConditionalExpression conditionalExpression(
       Expression condition,
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 9a1f011..da6c473 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -347,10 +347,14 @@
 
 /// An element that is contained within a [ClassElement].
 ///
+/// When the 'extension-methods' experiment is enabled, these elements can also
+/// be contained within an extension element.
+///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ClassMemberElement implements Element {
   // TODO(brianwilkerson) Either remove this class or rename it to something
-  //  more correct, such as PotentiallyStaticElement.
+  //  more correct.
+
   /// Return `true` if this element is a static element. A static element is an
   /// element that is not associated with a particular instance, but rather with
   /// an entire library or class.
@@ -1090,7 +1094,10 @@
   PropertyAccessorElement /*?*/ getSetter(String name);
 }
 
-/// A field defined within a type.
+/// A field defined within a class.
+///
+/// When the 'extension-methods' experiment is enabled, these elements can also
+/// be contained within an extension element.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FieldElement
@@ -1391,21 +1398,16 @@
   bool get isLate;
 }
 
-/// An element that represents a method defined within a type.
+/// An element that represents a method defined within a class.
+///
+/// When the 'extension-methods' experiment is enabled, these elements can also
+/// be contained within an extension element.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
   @deprecated
   @override
   MethodDeclaration computeNode();
-
-  /// Gets the reified type of a tear-off of this method.
-  ///
-  /// If any of the parameters in the method are covariant, they are replaced
-  /// with Object in the returned type. If no covariant parameters are present,
-  /// returns `this`.
-  @deprecated
-  FunctionType getReifiedType(DartType objectType);
 }
 
 /// A pseudo-element that represents multiple elements defined within a single
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 30a77d9..f147121 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -83,6 +83,10 @@
   /// dart:core library.
   bool get isDartCoreNum;
 
+  /// Return `true` if this type represents the type `Object` defined in the
+  /// dart:core library.
+  bool get isDartCoreObject;
+
   /// Returns `true` if this type represents the type 'Set' defined in the
   /// dart:core library.
   bool get isDartCoreSet;
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 0879f80..433060a 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -33,7 +33,7 @@
   /// Other type systems may define this operation differently.
   DartType flatten(DartType type);
 
-  /// Return `true` if the [rightType] is assignable to the [leftType].
+  /// Return `true` if the [leftType] is assignable to the [rightType].
   ///
   /// For the Dart 2.0 type system, the definition of this relationship is given
   /// in the Dart Language Specification, section 19.4 Subtypes:
@@ -46,8 +46,8 @@
   /// The subtype relationship (<:) can be tested using [isSubtypeOf].
   ///
   /// Other type systems may define this operation differently. In particular,
-  /// while the operation is commutative in the Dart 2.0 type system, that is
-  /// not a requirement of a type system, so the order of the arguments is
+  /// while the operation is commutative in the Dart 2.0 type system, it will
+  /// not be commutative when NNBD is enabled, so the order of the arguments is
   /// important.
   bool isAssignableTo(DartType leftType, DartType rightType);
 
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index feb9217..b919610 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -65,7 +65,6 @@
   CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
   CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
   CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
-  CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER,
   CompileTimeErrorCode.AMBIGUOUS_EXPORT,
   CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS,
   CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH,
@@ -137,6 +136,7 @@
   CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS,
   CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
   CompileTimeErrorCode.EXTENDS_NON_CLASS,
+  CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
   CompileTimeErrorCode.EXTENSION_DECLARES_ABSTRACT_MEMBER,
   CompileTimeErrorCode.EXTENSION_DECLARES_CONSTRUCTOR,
   CompileTimeErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD,
@@ -156,6 +156,7 @@
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+  CompileTimeErrorCode.IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
@@ -238,9 +239,6 @@
   CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT,
   CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT,
-  CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-  CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
-  CompileTimeErrorCode.NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
   // ignore: deprecated_member_use_from_same_package
   CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
   CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
@@ -287,7 +285,9 @@
   CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH,
   CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR,
   CompileTimeErrorCode.RETURN_IN_GENERATOR,
+  CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
+  CompileTimeErrorCode.SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
   CompileTimeErrorCode.SUPER_IN_EXTENSION,
   CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
@@ -366,8 +366,9 @@
   HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT,
   HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE,
   HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT,
-  HintCode.SDK_VERSION_BOOL_OPERATOR,
+  HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT,
+  HintCode.SDK_VERSION_EXTENSION_METHODS,
   HintCode.SDK_VERSION_GT_GT_GT_OPERATOR,
   HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_NEVER,
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index b942b0e..341366d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -180,7 +180,7 @@
 /// value in [IsEnabledByDefault]).
 class IsExpired {
   /// Expiration status of the experiment "constant-update-2018"
-  static const bool constant_update_2018 = false;
+  static const bool constant_update_2018 = true;
 
   /// Expiration status of the experiment "control-flow-collections"
   static const bool control_flow_collections = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 2292ce4..8d45ba7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -398,7 +398,8 @@
       nameIdParameter = _getStringInfo(element.name);
       element = element.enclosingElement;
     }
-    if (element?.enclosingElement is ClassElement) {
+    if (element?.enclosingElement is ClassElement ||
+        element?.enclosingElement is ExtensionElement) {
       nameIdClassMember = _getStringInfo(element.name);
       element = element.enclosingElement;
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index e14ef3f..9da05f9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -77,39 +77,6 @@
   ParsedLibraryResultImpl.external(AnalysisSession session, Uri uri)
       : this(session, null, uri, null);
 
-  @Deprecated('This factory exists temporary until AnalysisSession migration.')
-  factory ParsedLibraryResultImpl.tmp(LibraryElement library) {
-    var session = library.session;
-    if (session != null) {
-      return session.getParsedLibraryByElement(library);
-    } else {
-      var analysisContext = library.context;
-      var units = <ParsedUnitResult>[];
-      for (var unitElement in library.units) {
-        var unitSource = unitElement.source;
-
-        if (!analysisContext.exists(unitSource)) {
-          continue;
-        }
-
-        var content = analysisContext.getContents(unitSource).data;
-        var lineInfo = analysisContext.getLineInfo(unitSource);
-        var unit = analysisContext.parseCompilationUnit(unitSource);
-        units.add(ParsedUnitResultImpl(
-            null,
-            unitSource.fullName,
-            unitSource.uri,
-            content,
-            lineInfo,
-            unitSource != library.source,
-            unit, const []));
-      }
-      var libraryPath = library.source.fullName;
-      return ParsedLibraryResultImpl(
-          null, libraryPath, library.source.uri, units);
-    }
-  }
-
   @override
   ResultState get state {
     if (path == null) {
@@ -230,34 +197,6 @@
 
     return ElementDeclarationResultImpl(element, declaration, null, unitResult);
   }
-
-  @Deprecated('This method exists temporary until AnalysisSession migration.')
-  static Future<ResolvedLibraryResult> tmp(LibraryElement library) async {
-    var session = library.session;
-    if (session != null) {
-      return session.getResolvedLibraryByElement(library);
-    } else {
-      var units = <ResolvedUnitResult>[];
-      var analysisContext = library.context;
-      for (var unitElement in library.units) {
-        var unitSource = unitElement.source;
-
-        if (!analysisContext.exists(unitSource)) {
-          continue;
-        }
-
-        var path = unitSource.fullName;
-        var content = analysisContext.getContents(unitSource).data;
-        var lineInfo = analysisContext.getLineInfo(unitSource);
-        var unit = analysisContext.resolveCompilationUnit(unitSource, library);
-        units.add(ResolvedUnitResultImpl(null, path, unitSource.uri, true,
-            content, lineInfo, unitSource != library.source, unit, const []));
-      }
-      var libraryPath = library.source.fullName;
-      return ResolvedLibraryResultImpl(null, libraryPath, library.source.uri,
-          library, library.context.typeProvider, units);
-    }
-  }
 }
 
 class ResolvedUnitResultImpl extends FileResultImpl
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 1b58efc..7a638cd 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -80,6 +80,7 @@
     ElementKind kind = element.kind;
     if (kind == ElementKind.CLASS ||
         kind == ElementKind.CONSTRUCTOR ||
+        kind == ElementKind.EXTENSION ||
         kind == ElementKind.FUNCTION_TYPE_ALIAS ||
         kind == ElementKind.SETTER) {
       return _searchReferences(element, searchedFiles);
@@ -193,6 +194,7 @@
         CompilationUnitElement unitElement = unitResult.element;
         unitElement.accessors.forEach(addElement);
         unitElement.enums.forEach(addElement);
+        unitElement.extensions.forEach(addElement);
         unitElement.functions.forEach(addElement);
         unitElement.functionTypeAliases.forEach(addElement);
         unitElement.mixins.forEach(addElement);
@@ -817,7 +819,8 @@
    */
   int getElementClassMemberId(Element element) {
     for (; element != null; element = element.enclosingElement) {
-      if (element.enclosingElement is ClassElement) {
+      if (element.enclosingElement is ClassElement ||
+          element.enclosingElement is ExtensionElement) {
         return getStringId(element.name);
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 87d899b..747ecf1 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -4661,6 +4661,7 @@
 
   @override
   Token get beginToken => _variableList?.beginToken ?? super.beginToken;
+
   @override
   Iterable<SyntacticEntity> get childEntities => new ChildEntities()
     ..add(_variableList)
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index f542bd2..9091adc 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -190,18 +190,6 @@
           endToken, featureSet);
 
   @override
-  @deprecated
-  CompilationUnit compilationUnit2(
-          {Token beginToken,
-          ScriptTag scriptTag,
-          List<Directive> directives,
-          List<CompilationUnitMember> declarations,
-          Token endToken,
-          FeatureSet featureSet}) =>
-      new CompilationUnitImpl(beginToken, scriptTag, directives, declarations,
-          endToken, featureSet);
-
-  @override
   ConditionalExpression conditionalExpression(
           Expression condition,
           Token question,
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 1ec4362..3c2efbf 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -600,8 +600,7 @@
       return CompileTimeErrorCode
           .NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY;
     } else if (forSet) {
-      return CompileTimeErrorCode
-          .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY;
+      return CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY;
     }
 
     return null;
@@ -640,10 +639,8 @@
       // The errors have already been reported.
       if (conditionBool == null) return false;
 
-      verifier._reportErrorIfFromDeferredLibrary(
-          element.condition,
-          CompileTimeErrorCode
-              .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY);
+      verifier._reportErrorIfFromDeferredLibrary(element.condition,
+          CompileTimeErrorCode.IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY);
 
       var thenValid = true;
       var elseValid = true;
@@ -670,10 +667,8 @@
       var value = verifier._validate(element.expression, errorCode);
       if (value == null) return false;
 
-      verifier._reportErrorIfFromDeferredLibrary(
-          element.expression,
-          CompileTimeErrorCode
-              .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY);
+      verifier._reportErrorIfFromDeferredLibrary(element.expression,
+          CompileTimeErrorCode.SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY);
 
       if (forList || forSet) {
         return _validateListOrSetSpread(element, value);
@@ -896,7 +891,7 @@
 
     verifier._reportErrorIfFromDeferredLibrary(
       expression,
-      CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
+      CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
     );
 
     if (setUniqueValues.containsKey(value)) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index b145b76..00779a3 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7863,38 +7863,6 @@
   @override
   MethodDeclaration computeNode() =>
       getNodeMatching((node) => node is MethodDeclaration);
-
-  @deprecated
-  @override
-  FunctionType getReifiedType(DartType objectType) {
-    // TODO(jmesserly): this implementation is completely wrong:
-    // It does not handle covariant parameters from a generic class.
-    // It drops type parameters from generic methods.
-    // Since this method was for DDC, it should be removed.
-    //
-    // Check whether we have any covariant parameters.
-    // Usually we don't, so we can use the same type.
-    bool hasCovariant = false;
-    for (ParameterElement parameter in parameters) {
-      if (parameter.isCovariant) {
-        hasCovariant = true;
-        break;
-      }
-    }
-
-    if (!hasCovariant) {
-      return type;
-    }
-
-    List<ParameterElement> covariantParameters = parameters.map((parameter) {
-      DartType type = parameter.isCovariant ? objectType : parameter.type;
-      return new ParameterElementImpl.synthetic(
-          parameter.name, type, parameter.parameterKind);
-    }).toList();
-
-    return new FunctionElementImpl.synthetic(covariantParameters, returnType)
-        .type;
-  }
 }
 
 /// A [ClassElementImpl] representing a mixin declaration.
@@ -10043,6 +10011,11 @@
   /// The unlinked representation of the type parameter in the summary.
   final UnlinkedTypeParam _unlinkedTypeParam;
 
+  /// The default value of the type parameter. It is used to provide the
+  /// corresponding missing type argument in type annotations and as the
+  /// fall-back type value in type inference.
+  DartType _defaultType;
+
   /// The type defined by this type parameter.
   TypeParameterType _type;
 
@@ -10131,12 +10104,18 @@
   /// corresponding missing type argument in type annotations and as the
   /// fall-back type value in type inference.
   DartType get defaultType {
+    if (_defaultType != null) return _defaultType;
+
     if (linkedNode != null) {
-      return linkedContext.getDefaultType(linkedNode);
+      return _defaultType = linkedContext.getDefaultType(linkedNode);
     }
     return null;
   }
 
+  set defaultType(DartType defaultType) {
+    _defaultType = defaultType;
+  }
+
   @override
   String get displayName => name;
 
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 597c39a..ab33e17 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -1035,11 +1035,6 @@
   @deprecated
   @override
   MethodDeclaration computeNode() => actualElement.computeNode();
-
-  @deprecated
-  @override
-  FunctionType getReifiedType(DartType objectType) =>
-      actualElement.getReifiedType(objectType);
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 2bbc114..d763f18 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -217,6 +217,10 @@
       combined = Substitution.fromMap(map);
     }
 
+    if (combined.map.isEmpty) {
+      return element;
+    }
+
     if (element is ConstructorElement) {
       return ConstructorMember(element, combined);
     } else if (element is MethodElement) {
@@ -227,20 +231,6 @@
       throw UnimplementedError('(${element.runtimeType}) $element');
     }
   }
-
-  static ExecutableElement from3(
-    ExecutableElement element,
-    List<TypeParameterElement> typeParameters,
-    List<DartType> typeArguments,
-  ) {
-    if (typeParameters.isEmpty) {
-      return element;
-    }
-    return from2(
-      element,
-      Substitution.fromPairs(typeParameters, typeArguments),
-    );
-  }
 }
 
 /**
@@ -541,18 +531,6 @@
     }
   }
 
-  /**
-   * Return the type that results from replacing the type parameters in the
-   * given [type] with the type arguments associated with this member.
-   */
-  @Deprecated("Used only by 'getReifiedType', which is deprecated")
-  DartType substituteFor(DartType type) {
-    if (type == null) {
-      return null;
-    }
-    return _substitution.substituteType(type);
-  }
-
   @override
   void visitChildren(ElementVisitor visitor) {
     // There are no children to visit
@@ -586,11 +564,6 @@
   @override
   MethodDeclaration computeNode() => baseElement.computeNode();
 
-  @deprecated
-  @override
-  FunctionType getReifiedType(DartType objectType) =>
-      substituteFor(baseElement.getReifiedType(objectType));
-
   @override
   String toString() {
     MethodElement baseElement = this.baseElement;
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index d4067ce..3c1e839 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1286,7 +1286,7 @@
    * Initialize a newly created type to be declared by the given [element].
    */
   InterfaceTypeImpl(ClassElement element,
-      [this.prunedTypedefs, this.nullabilitySuffix = NullabilitySuffix.star])
+      {this.prunedTypedefs, this.nullabilitySuffix = NullabilitySuffix.star})
       : super(element, element.displayName);
 
   /**
@@ -1514,6 +1514,15 @@
   }
 
   @override
+  bool get isDartCoreObject {
+    ClassElement element = this.element;
+    if (element == null) {
+      return false;
+    }
+    return element.name == "Object" && element.library.isDartCore;
+  }
+
+  @override
   bool get isDartCoreSet {
     ClassElement element = this.element;
     if (element == null) {
@@ -2259,8 +2268,8 @@
     List<DartType> newTypeArguments = TypeImpl.substitute(
         typeArguments, argumentTypes, parameterTypes, prune);
 
-    InterfaceTypeImpl newType =
-        new InterfaceTypeImpl(element, prune, nullabilitySuffix);
+    InterfaceTypeImpl newType = new InterfaceTypeImpl(element,
+        prunedTypedefs: prune, nullabilitySuffix: nullabilitySuffix);
     newType.typeArguments = newTypeArguments;
     return newType;
   }
@@ -2503,8 +2512,8 @@
       return NullabilitySuffix.none;
     }
 
-    InterfaceTypeImpl lub =
-        new InterfaceTypeImpl(firstElement, null, computeNullability());
+    InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement,
+        nullabilitySuffix: computeNullability());
     lub.typeArguments = lubArguments;
     return lub;
   }
@@ -2663,6 +2672,9 @@
   bool get isDartCoreNum => false;
 
   @override
+  bool get isDartCoreObject => false;
+
+  @override
   bool get isDartCoreSet => false;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index fede84b..f3e234d 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -126,7 +126,7 @@
   }
 
   /// Substitutes each parameter to the type it maps to in [map].
-  static Substitution fromMap(Map<TypeParameterElement, DartType> map) {
+  static MapSubstitution fromMap(Map<TypeParameterElement, DartType> map) {
     if (map.isEmpty) {
       return _NullSubstitution.instance;
     }
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 99d3f9e..4d7e6e6 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -194,8 +194,10 @@
       .accept(visitor); // ignore: deprecated_member_use_from_same_package
 
   @override
-  String computeDocumentationComment() =>
-      wrappedUnit.computeDocumentationComment();
+  String computeDocumentationComment() {
+    // ignore: deprecated_member_use_from_same_package
+    return wrappedUnit.computeDocumentationComment();
+  }
 
   @deprecated
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 136e290..e596bcd 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -649,11 +649,11 @@
    * The operator '&', '|' or '^' is being used on boolean values in code that
    * is expected to run on versions of the SDK that did not support it.
    */
-  static const HintCode SDK_VERSION_BOOL_OPERATOR = const HintCode(
-      'SDK_VERSION_BOOL_OPERATOR',
-      "Using the operator '{0}' for 'bool's wasn't supported until version "
-          "2.3.2, but this code is required to be able to run on earlier "
-          "versions.",
+  static const HintCode SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT = const HintCode(
+      'SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT',
+      "Using the operator '{0}' for 'bool's in a constant expression wasn't "
+          "supported until version 2.3.2, but this code is required to be able "
+          "to run on earlier versions.",
       correction: "Try updating the SDK constraints.");
 
   /**
@@ -669,6 +669,16 @@
           correction: "Try updating the SDK constraints.");
 
   /**
+   * Extension method features are being used in code that is expected to run
+   * on versions of the SDK that did not support them.
+   */
+  static const HintCode SDK_VERSION_EXTENSION_METHODS = const HintCode(
+      'SDK_VERSION_EXTENSION_METHODS',
+      "Extension methods weren't supported until version 2.X.0, "
+          "but this code is required to be able to run on earlier versions.",
+      correction: "Try updating the SDK constraints.");
+
+  /**
    * The operator '>>>' is being used in code that is expected to run on
    * versions of the SDK that did not support it.
    */
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 964531c..58353ea5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -3,12 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/ast_factory.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -56,7 +55,6 @@
       }
       Element element = nameScope.lookup(methodName, definingLibrary);
       if (element is ClassElement) {
-        AstFactory astFactory = new AstFactoryImpl();
         TypeName typeName = astFactory.typeName(methodName, node.typeArguments);
         ConstructorName constructorName =
             astFactory.constructorName(typeName, null, null);
@@ -65,7 +63,6 @@
                 _getKeyword(node), constructorName, node.argumentList);
         NodeReplacer.replace(node, instanceCreationExpression);
       } else if (element is ExtensionElement) {
-        AstFactory astFactory = new AstFactoryImpl();
         ExtensionOverride extensionOverride = astFactory.extensionOverride(
             extensionName: methodName,
             typeArguments: node.typeArguments,
@@ -91,10 +88,10 @@
                 typeArguments,
                 [element.name, constructorElement.name]);
           }
-          AstFactory astFactory = new AstFactoryImpl();
           TypeName typeName = astFactory.typeName(target, null);
           ConstructorName constructorName =
               astFactory.constructorName(typeName, node.operator, methodName);
+          // TODO(scheglov) I think we should drop "typeArguments" below.
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
                   _getKeyword(node), constructorName, node.argumentList,
@@ -103,7 +100,6 @@
         }
       } else if (element is PrefixElement) {
         // Possible cases: p.C() or p.C<>()
-        AstFactory astFactory = new AstFactoryImpl();
         Identifier identifier = astFactory.prefixedIdentifier(
             astFactory.simpleIdentifier(target.token),
             null,
@@ -120,7 +116,6 @@
                   _getKeyword(node), constructorName, node.argumentList);
           NodeReplacer.replace(node, instanceCreationExpression);
         } else if (prefixedElement is ExtensionElement) {
-          AstFactory astFactory = new AstFactoryImpl();
           PrefixedIdentifier extensionName =
               astFactory.prefixedIdentifier(target, node.operator, methodName);
           ExtensionOverride extensionOverride = astFactory.extensionOverride(
@@ -147,7 +142,6 @@
                   typeArguments,
                   [element.name, constructorElement.name]);
             }
-            AstFactory astFactory = new AstFactoryImpl();
             TypeName typeName = astFactory.typeName(target, typeArguments);
             ConstructorName constructorName =
                 astFactory.constructorName(typeName, node.operator, methodName);
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index e7b0ca8..1f86708 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -35,23 +36,21 @@
   /// If no applicable extensions, return `null`.
   ///
   /// If the match is ambiguous, report an error and return `null`.
-  ExtensionResolutionResult findExtension(
+  ResolutionResult findExtension(
       DartType type, String name, Expression target, ElementKind kind) {
     var extensions = _getApplicable(type, name, kind);
 
     if (extensions.isEmpty) {
-      return ExtensionResolutionResult.none;
+      return ResolutionResult.none;
     }
 
     if (extensions.length == 1) {
-      return ExtensionResolutionResult(
-          ExtensionResolutionState.single, extensions[0]);
+      return ResolutionResult(extensions[0].instantiatedMember);
     }
 
     var extension = _chooseMostSpecific(extensions);
     if (extension != null) {
-      return ExtensionResolutionResult(
-          ExtensionResolutionState.single, extension);
+      return ResolutionResult(extension.instantiatedMember);
     }
 
     _errorReporter.reportErrorForNode(
@@ -63,9 +62,36 @@
         extensions[1].element.name,
       ],
     );
-    return ExtensionResolutionResult.ambiguous;
+    return ResolutionResult.ambiguous;
   }
 
+  /// Return the member with the [name] (without `=`) of the given [kind].
+  ///
+  /// The [node] is fully resolved, and its type arguments are set.
+  ExecutableElement getOverrideMember(
+      ExtensionOverride node, String name, ElementKind kind) {
+    ExtensionElement element = node.extensionName.staticElement;
+
+    ExecutableElement member;
+    if (kind == ElementKind.GETTER) {
+      member = element.getGetter(name);
+    } else if (kind == ElementKind.METHOD) {
+      member = element.getMethod(name);
+    } else if (kind == ElementKind.SETTER) {
+      member = element.getSetter(name);
+    }
+    if (member == null) return null;
+
+    return ExecutableMember.from2(
+      member,
+      Substitution.fromPairs(
+        element.typeParameters,
+        node.typeArgumentTypes,
+      ),
+    );
+  }
+
+  /// Perform upward inference for the override.
   void resolveOverride(ExtensionOverride node) {
     var nodeImpl = node as ExtensionOverrideImpl;
     var element = node.staticElement;
@@ -93,17 +119,22 @@
     var receiverExpression = arguments[0];
     var receiverType = receiverExpression.staticType;
 
-    var typeArgumentTypes = _inferTypeArguments(
-      element,
-      receiverType,
-      node.typeArguments,
-    );
-
+    var typeArgumentTypes = _inferTypeArguments(node, receiverType);
     nodeImpl.typeArgumentTypes = typeArgumentTypes;
-    nodeImpl.extendedType = Substitution.fromPairs(
+
+    var substitution = Substitution.fromPairs(
       typeParameters,
       typeArgumentTypes,
-    ).substituteType(element.extendedType);
+    );
+
+    nodeImpl.extendedType = substitution.substituteType(element.extendedType);
+
+    _checkTypeArgumentsMatchingBounds(
+      typeParameters,
+      node.typeArguments,
+      typeArgumentTypes,
+      substitution,
+    );
 
     if (!_typeSystem.isAssignableTo(receiverType, node.extendedType)) {
       _errorReporter.reportErrorForNode(
@@ -114,10 +145,72 @@
     }
   }
 
+  /// Set the type context for the receiver of the override.
+  ///
+  /// The context of the invocation that is made through the override does
+  /// not affect the type inference of the override and the receiver.
+  void setOverrideReceiverContextType(ExtensionOverride node) {
+    var element = node.staticElement;
+    var typeParameters = element.typeParameters;
+
+    var arguments = node.argumentList.arguments;
+    if (arguments.length != 1) {
+      return;
+    }
+
+    List<DartType> typeArgumentTypes;
+    var typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      var arguments = typeArguments.arguments;
+      if (arguments.length == typeParameters.length) {
+        typeArgumentTypes = arguments.map((a) => a.type).toList();
+      } else {
+        typeArgumentTypes = _listOfDynamic(typeParameters);
+      }
+    } else {
+      typeArgumentTypes = List.filled(
+        typeParameters.length,
+        UnknownInferredType.instance,
+      );
+    }
+
+    var extendedForDownward = Substitution.fromPairs(
+      typeParameters,
+      typeArgumentTypes,
+    ).substituteType(element.extendedType);
+
+    var receiver = arguments[0];
+    InferenceContext.setType(receiver, extendedForDownward);
+  }
+
+  void _checkTypeArgumentsMatchingBounds(
+    List<TypeParameterElement> typeParameters,
+    TypeArgumentList typeArgumentList,
+    List<DartType> typeArgumentTypes,
+    Substitution substitution,
+  ) {
+    if (typeArgumentList != null) {
+      for (var i = 0; i < typeArgumentTypes.length; i++) {
+        var argType = typeArgumentTypes[i];
+        var boundType = typeParameters[i].bound;
+        if (boundType != null) {
+          boundType = substitution.substituteType(boundType);
+          if (!_typeSystem.isSubtypeOf(argType, boundType)) {
+            _errorReporter.reportTypeErrorForNode(
+              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+              typeArgumentList.arguments[i],
+              [argType, boundType],
+            );
+          }
+        }
+      }
+    }
+  }
+
   /// Return the most specific extension or `null` if no single one can be
   /// identified.
-  InstantiatedExtension _chooseMostSpecific(
-      List<InstantiatedExtension> extensions) {
+  _InstantiatedExtension _chooseMostSpecific(
+      List<_InstantiatedExtension> extensions) {
     //
     // https://github.com/dart-lang/language/blob/master/accepted/future-releases/static-extension-methods/feature-specification.md#extension-conflict-resolution:
     //
@@ -160,11 +253,11 @@
 
   /// Return extensions for the [type] that match the given [name] in the
   /// current scope.
-  List<InstantiatedExtension> _getApplicable(
+  List<_InstantiatedExtension> _getApplicable(
       DartType type, String name, ElementKind kind) {
     var candidates = _getExtensionsWithMember(name, kind);
 
-    var instantiatedExtensions = <InstantiatedExtension>[];
+    var instantiatedExtensions = <_InstantiatedExtension>[];
     for (var candidate in candidates) {
       var typeParameters = candidate.extension.typeParameters;
       var inferrer = GenericInferrer(
@@ -194,14 +287,12 @@
       }
 
       instantiatedExtensions.add(
-        InstantiatedExtension(
+        _InstantiatedExtension(
           candidate.extension,
           extendedType,
-          // TODO(scheglov) Hm... Maybe not use from3(), but identify null subst?
-          ExecutableMember.from3(
+          ExecutableMember.from2(
             candidate.member,
-            typeParameters,
-            typeArguments,
+            substitution,
           ),
         ),
       );
@@ -269,7 +360,7 @@
     return candidates;
   }
 
-  /// Given the generic [extension] element, either return types specified
+  /// Given the generic [element] element, either return types specified
   /// explicitly in [typeArguments], or infer type arguments from the given
   /// [receiverType].
   ///
@@ -277,15 +368,16 @@
   /// of extension's type parameters, or inference fails, return `dynamic`
   /// for all type parameters.
   List<DartType> _inferTypeArguments(
-    ExtensionElement extension,
+    ExtensionOverride node,
     DartType receiverType,
-    TypeArgumentList typeArguments,
   ) {
-    var typeParameters = extension.typeParameters;
+    var element = node.staticElement;
+    var typeParameters = element.typeParameters;
     if (typeParameters.isEmpty) {
       return const <DartType>[];
     }
 
+    var typeArguments = node.typeArguments;
     if (typeArguments != null) {
       var arguments = typeArguments.arguments;
       if (arguments.length == typeParameters.length) {
@@ -295,21 +387,21 @@
         return _listOfDynamic(typeParameters);
       }
     } else {
-      if (receiverType != null) {
-        var inferrer = GenericInferrer(
-          _typeProvider,
-          _typeSystem,
-          typeParameters,
-        );
-        inferrer.constrainArgument(
-          receiverType,
-          extension.extendedType,
-          'extendedType',
-        );
-        return inferrer.infer(typeParameters);
-      } else {
-        return _listOfDynamic(typeParameters);
-      }
+      var inferrer = GenericInferrer(
+        _typeProvider,
+        _typeSystem,
+        typeParameters,
+      );
+      inferrer.constrainArgument(
+        receiverType,
+        element.extendedType,
+        'extendedType',
+      );
+      return inferrer.infer(
+        typeParameters,
+        errorReporter: _errorReporter,
+        errorNode: node.extensionName,
+      );
     }
   }
 
@@ -323,7 +415,7 @@
     ).substituteType(extension.extendedType);
   }
 
-  bool _isMoreSpecific(InstantiatedExtension e1, InstantiatedExtension e2) {
+  bool _isMoreSpecific(_InstantiatedExtension e1, _InstantiatedExtension e2) {
     var t10 = e1.element.extendedType;
     var t20 = e2.element.extendedType;
     var t11 = e1._extendedType;
@@ -348,9 +440,9 @@
     // 2. they are both declared in platform libraries or both declared in
     //    non-platform libraries, and
     if (_isSubtypeAndNotViceVersa(t11, t21)) {
-      // 3. the instantiated type (the type after applying type inference from the
-      //    receiver) of T1 is a subtype of the instantiated type of T2 and either
-      //    not vice versa
+      // 3. the instantiated type (the type after applying type inference from
+      //    the receiver) of T1 is a subtype of the instantiated type of T2 and
+      //    either not vice versa
       return true;
     }
 
@@ -392,63 +484,21 @@
   }
 }
 
-/// The result of attempting to resolve an identifier to an extension member.
-class ExtensionResolutionResult {
-  /// An instance that can be used anywhere that no extension member was found.
-  static const ExtensionResolutionResult none =
-      ExtensionResolutionResult(ExtensionResolutionState.none, null);
-
-  /// An instance that can be used anywhere that multiple ambiguous members were
-  /// found.
-  static const ExtensionResolutionResult ambiguous =
-      ExtensionResolutionResult(ExtensionResolutionState.ambiguous, null);
-
-  /// The state of the result.
-  final ExtensionResolutionState state;
-
-  /// The extension that was found, or `null` if the [state] is not
-  /// [ExtensionResolutionState.single].
-  final InstantiatedExtension extension;
-
-  /// Initialize a newly created result.
-  const ExtensionResolutionResult(this.state, this.extension);
-
-  /// Return `true` if this result represents the case where no extension member
-  /// was found.
-  bool get isNone => state == ExtensionResolutionState.none;
-
-  /// Return `true` if this result represents the case where a single extension
-  /// member was found.
-  bool get isSingle => extension != null;
-}
-
-/// The state of an [ExtensionResolutionResult].
-enum ExtensionResolutionState {
-  /// Indicates that no extension member was found.
-  none,
-
-  /// Indicates that a single extension member was found.
-  single,
-
-  /// Indicates that multiple ambiguous members were found.
-  ambiguous
-}
-
-class InstantiatedExtension {
-  final ExtensionElement element;
-  final DartType _extendedType;
-  final ExecutableElement instantiatedMember;
-
-  InstantiatedExtension(
-    this.element,
-    this._extendedType,
-    this.instantiatedMember,
-  );
-}
-
 class _CandidateExtension {
   final ExtensionElement extension;
   final ExecutableElement member;
 
   _CandidateExtension(this.extension, this.member);
 }
+
+class _InstantiatedExtension {
+  final ExtensionElement element;
+  final DartType _extendedType;
+  final ExecutableElement instantiatedMember;
+
+  _InstantiatedExtension(
+    this.element,
+    this._extendedType,
+    this.instantiatedMember,
+  );
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index c126f1f..51d08be 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -66,13 +66,10 @@
 
   factory FlowAnalysisHelper(
       TypeSystem typeSystem, AstNode node, bool retainDataForTesting) {
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    node.accept(_AssignedVariablesVisitor(assignedVariables));
-
     return FlowAnalysisHelper._(
         const AnalyzerNodeOperations(),
         _TypeSystemTypeOperations(typeSystem),
-        assignedVariables,
+        computeAssignedVariables(node),
         retainDataForTesting ? FlowAnalysisResult() : null);
   }
 
@@ -169,7 +166,7 @@
   }
 
   void breakStatement(BreakStatement node) {
-    var target = _getLabelTarget(node, node.label?.staticElement);
+    var target = getLabelTarget(node, node.label?.staticElement);
     flow.handleBreak(target);
   }
 
@@ -191,7 +188,7 @@
   }
 
   void continueStatement(ContinueStatement node) {
-    var target = _getLabelTarget(node, node.label?.staticElement);
+    var target = getLabelTarget(node, node.label?.staticElement);
     flow.handleContinue(target);
   }
 
@@ -288,7 +285,7 @@
   /// Return the target of the `break` or `continue` statement with the
   /// [element] label. The [element] might be `null` (when the statement does
   /// not specify a label), so the default enclosing target is returned.
-  AstNode _getLabelTarget(AstNode node, LabelElement element) {
+  static Statement getLabelTarget(AstNode node, LabelElement element) {
     for (; node != null; node = node.parent) {
       if (node is DoStatement ||
           node is ForStatement ||
@@ -318,6 +315,14 @@
     }
     return null;
   }
+
+  /// Computes the [AssignedVariables] map for the given [node].
+  static AssignedVariables<Statement, VariableElement> computeAssignedVariables(
+      AstNode node) {
+    var assignedVariables = AssignedVariables<Statement, VariableElement>();
+    node.accept(_AssignedVariablesVisitor(assignedVariables));
+    return assignedVariables;
+  }
 }
 
 /// The result of performing flow analysis on a unit.
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 60d1e92..7fe1505 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -8,9 +8,9 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -41,23 +41,22 @@
   /// The object providing promoted or declared types of variables.
   final LocalVariableTypeProvider _localVariableTypeProvider;
 
+  /// Helper for extension method resolution.
+  final ExtensionMemberResolver _extensionResolver;
+
   /// The invocation being resolved.
   MethodInvocationImpl _invocation;
 
   /// The [Name] object of the invocation being resolved by [resolve].
   Name _currentName;
 
-  /// Helper for extension method resolution.
-  //todo(pq): consider sharing instance with element_resolver
-  final ExtensionMemberResolver _extensionResolver;
-
   MethodInvocationResolver(this._resolver)
       : _typeType = _resolver.typeProvider.typeType,
         _inheritance = _resolver.inheritance,
         _definingLibrary = _resolver.definingLibrary,
         _definingLibraryUri = _resolver.definingLibrary.source.uri,
         _localVariableTypeProvider = _resolver.localVariableTypeProvider,
-        _extensionResolver = ExtensionMemberResolver(_resolver);
+        _extensionResolver = _resolver.extensionResolver;
 
   /// The scope used to resolve identifiers.
   Scope get nameScope => _resolver.nameScope;
@@ -338,8 +337,9 @@
 
   /// If there is an extension matching the [receiverType] and defining a
   /// member with the given [name], resolve to the corresponding extension
-  /// method and return `true`. Otherwise return `false`.
-  ExtensionResolutionResult _resolveExtension(
+  /// method. Return a result indicating whether the [node] was resolved and if
+  /// not why.
+  ResolutionResult _resolveExtension(
     MethodInvocation node,
     DartType receiverType,
     SimpleIdentifier nameNode,
@@ -357,18 +357,18 @@
       return result;
     }
 
-    ExecutableElement member = result.extension.instantiatedMember;
+    ExecutableElement member = result.element;
+    nameNode.staticElement = member;
 
     if (member.isStatic) {
       _setDynamicResolution(node);
       _resolver.errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER,
-        nameNode,
-      );
+          StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+          nameNode,
+          [name, member.kind.displayName, member.enclosingElement.name]);
       return result;
     }
 
-    nameNode.staticElement = member;
     var calleeType = _getCalleeType(node, member);
     _setResolution(node, calleeType);
     return result;
@@ -394,27 +394,22 @@
 
   void _resolveExtensionOverride(MethodInvocation node,
       ExtensionOverride override, SimpleIdentifier nameNode, String name) {
-    ExtensionElement element = override.extensionName.staticElement;
-    ExecutableElement member =
-        element.getMethod(name) ?? element.getGetter(name);
+    var member = _extensionResolver.getOverrideMember(
+            override, name, ElementKind.METHOD) ??
+        _extensionResolver.getOverrideMember(
+            override, name, ElementKind.GETTER);
 
     if (member == null) {
       _setDynamicResolution(node);
       _resolver.errorReporter.reportErrorForNode(
         CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
         nameNode,
-        [name, element.name],
+        [name, override.staticElement.name],
       );
       return;
     }
 
-    member = ExecutableMember.from3(
-      member,
-      element.typeParameters,
-      override.typeArgumentTypes,
-    );
-
-    if (member is ExecutableElement && member.isStatic) {
+    if (member.isStatic) {
       _resolver.errorReporter.reportErrorForNode(
         CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
         nameNode,
@@ -446,9 +441,18 @@
       return;
     }
 
+    ResolutionResult result = _extensionResolver.findExtension(
+        receiverType, name, nameNode, ElementKind.METHOD);
+    if (result.isSingle) {
+      nameNode.staticElement = result.element;
+      var calleeType = _getCalleeType(node, result.element);
+      return _setResolution(node, calleeType);
+    } else if (result.isAmbiguous) {
+      return;
+    }
     // We can invoke Object methods on Function.
     var member = _inheritance.getMember(
-      _resolver.typeProvider.objectType,
+      _resolver.typeProvider.functionType,
       new Name(null, name),
     );
     if (member != null) {
@@ -579,7 +583,7 @@
     var result = _extensionResolver.findExtension(
         receiverType, name, nameNode, ElementKind.METHOD);
     if (result.isSingle) {
-      var target = result.extension.instantiatedMember;
+      var target = result.element;
       if (target != null) {
         nameNode.staticElement = target;
         var calleeType = _getCalleeType(node, target);
@@ -744,7 +748,9 @@
         var result = _extensionResolver.findExtension(
             type, _nameCall.name, node.methodName, ElementKind.METHOD);
         if (result.isSingle) {
-          call = result.extension.instantiatedMember;
+          call = result.element;
+        } else if (result.isAmbiguous) {
+          return;
         }
       }
       if (call != null && call.kind == ElementKind.METHOD) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
new file mode 100644
index 0000000..1d91bf8
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2019, 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:analyzer/dart/element/element.dart';
+
+/// The result of attempting to resolve an identifier to a element.
+class ResolutionResult {
+  /// An instance that can be used anywhere that no element was found.
+  static const ResolutionResult none =
+      ResolutionResult._(_ResolutionResultState.none);
+
+  /// An instance that can be used anywhere that multiple elements were found.
+  static const ResolutionResult ambiguous =
+      ResolutionResult._(_ResolutionResultState.ambiguous);
+
+  /// The state of the result.
+  final _ResolutionResultState state;
+
+  /// The element that was found, or `null` if the [state] is not
+  /// [_ResolutionResultState.single].
+  final ExecutableElement element;
+
+  /// Initialize a newly created result to represent resolving to a single
+  /// [element].
+  ResolutionResult(this.element)
+      : assert(element != null),
+        state = _ResolutionResultState.single;
+
+  /// Initialize a newly created result with no element and the given [state].
+  const ResolutionResult._(this.state) : element = null;
+
+  /// Return `true` if this result represents the case where multiple ambiguous
+  /// elements were found.
+  bool get isAmbiguous => state == _ResolutionResultState.ambiguous;
+
+  /// Return `true` if this result represents the case where no element was
+  /// found.
+  bool get isNone => state == _ResolutionResultState.none;
+
+  /// Return `true` if this result represents the case where a single element
+  /// was found.
+  bool get isSingle => state == _ResolutionResultState.single;
+}
+
+/// The state of a [ResolutionResult].
+enum _ResolutionResultState {
+  /// Indicates that no element was found.
+  none,
+
+  /// Indicates that a single element was found.
+  single,
+
+  /// Indicates that multiple ambiguous elements were found.
+  ambiguous
+}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index a3db80c..abe1bf8 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -126,15 +126,6 @@
               "same library.");
 
   /**
-   * No parameters.
-   */
-  //todo (pq): refactor to reuse StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER.
-  static const CompileTimeErrorCode ACCESS_STATIC_EXTENSION_MEMBER =
-      const CompileTimeErrorCode('ACCESS_STATIC_EXTENSION_MEMBER',
-          "Static extension members can't be accessed.",
-          correction: "Try removing the static member access.");
-
-  /**
    * 14.2 Exports: It is a compile-time error if a name <i>N</i> is re-exported
    * by a library <i>L</i> and <i>N</i> is introduced into the export namespace
    * of <i>L</i> by more than one export, unless each all exports refer to same
@@ -1269,6 +1260,22 @@
               "removing the extends clause.");
 
   /**
+   * It is for an extension to define a static member and an instance member
+   * with the same base name.
+   *
+   * Parameters:
+   * 0: the name of the extension defining the conflicting member
+   * 1: the name of the conflicting static member
+   */
+  static const CompileTimeErrorCode EXTENSION_CONFLICTING_STATIC_AND_INSTANCE =
+      const CompileTimeErrorCode(
+          'EXTENSION_CONFLICTING_STATIC_AND_INSTANCE',
+          "Extension '{0}' can't define static member '{1}' and instance "
+              "member with the same name.",
+          correction:
+              "Try renaming the member to a name that doesn't conflict.");
+
+  /**
    * No parameters.
    */
   static const CompileTimeErrorCode EXTENSION_DECLARES_ABSTRACT_MEMBER =
@@ -1459,6 +1466,13 @@
               "Try using an explicit typedef, or changing type parameters to "
               "`dynamic`.");
 
+  static const CompileTimeErrorCode IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be used as values in "
+              "an if condition inside a const collection literal.",
+          correction: "Try making the deferred import non-deferred.");
+
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause
    * of a class <i>C</i> specifies a malformed type or deferred type as a
@@ -2618,30 +2632,6 @@
           "The values in a const set literal must be constants.",
           correction: "Try removing the keyword 'const' from the set literal.");
 
-  static const CompileTimeErrorCode
-      NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be spread into a "
-              "const literal.",
-          correction: "Try making the deferred import non-deferred.");
-
-  static const CompileTimeErrorCode
-      NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be used as values in "
-              "an if condition inside a const collection literal.",
-          correction: "Try making the deferred import non-deferred.");
-
-  static const CompileTimeErrorCode
-      NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY',
-          "Constant values from a deferred library can't be used as values in "
-              "a 'const' set.",
-          correction: "Try removing the keyword 'const' from the set literal.");
-
   /**
    * This error code is no longer being generated. It should be removed when the
    * reference to it in the linter has been removed and rolled into the SDK.
@@ -3199,6 +3189,13 @@
               "Try removing the value, replacing 'return' with 'yield' or "
               "changing the method body modifier.");
 
+  static const CompileTimeErrorCode SET_ELEMENT_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'SET_ELEMENT_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be used as values in "
+              "a const set.",
+          correction: "Try making the deferred import non-deferred.");
+
   /**
    * 14.1 Imports: It is a compile-time error if a prefix used in a deferred
    * import is used in another import clause.
@@ -3210,6 +3207,13 @@
               "directives.",
           correction: "Try renaming one of the prefixes.");
 
+  static const CompileTimeErrorCode SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY =
+      const CompileTimeErrorCode(
+          'SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY',
+          "Constant values from a deferred library can't be spread into a "
+              "const literal.",
+          correction: "Try making the deferred import non-deferred.");
+
   /**
    * No parameters.
    */
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
new file mode 100644
index 0000000..0dfad29
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -0,0 +1,408 @@
+// Copyright (c) 2019, 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:collection';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+class DuplicateDefinitionVerifier {
+  final LibraryElement _currentLibrary;
+  final ErrorReporter _errorReporter;
+
+  DuplicateDefinitionVerifier(this._currentLibrary, this._errorReporter);
+
+  /// Check that the exception and stack trace parameters have different names.
+  void checkCatchClause(CatchClause node) {
+    SimpleIdentifier exceptionParameter = node.exceptionParameter;
+    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
+    if (exceptionParameter != null && stackTraceParameter != null) {
+      String exceptionName = exceptionParameter.name;
+      if (exceptionName == stackTraceParameter.name) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.DUPLICATE_DEFINITION,
+            stackTraceParameter,
+            [exceptionName]);
+      }
+    }
+  }
+
+  void checkClass(ClassDeclaration node) {
+    _checkClassMembers(node.declaredElement, node.members);
+  }
+
+  /// Check that there are no members with the same name.
+  void checkEnum(EnumDeclaration node) {
+    ClassElement element = node.declaredElement;
+
+    Map<String, Element> instanceGetters = new HashMap<String, Element>();
+    Map<String, Element> staticGetters = new HashMap<String, Element>();
+
+    String indexName = 'index';
+    String valuesName = 'values';
+    instanceGetters[indexName] = element.getGetter(indexName);
+    staticGetters[valuesName] = element.getGetter(valuesName);
+
+    for (EnumConstantDeclaration constant in node.constants) {
+      _checkDuplicateIdentifier(staticGetters, constant.name);
+    }
+
+    for (EnumConstantDeclaration constant in node.constants) {
+      SimpleIdentifier identifier = constant.name;
+      String name = identifier.name;
+      if (instanceGetters.containsKey(name)) {
+        String enumName = element.displayName;
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+            identifier,
+            [enumName, name, enumName]);
+      }
+    }
+  }
+
+  /// Check that there are no members with the same name.
+  void checkExtension(ExtensionDeclaration node) {
+    var instanceGetters = <String, Element>{};
+    var instanceSetters = <String, Element>{};
+    var staticGetters = <String, Element>{};
+    var staticSetters = <String, Element>{};
+
+    for (var member in node.members) {
+      if (member is FieldDeclaration) {
+        for (var field in member.fields.variables) {
+          var identifier = field.name;
+          _checkDuplicateIdentifier(
+            member.isStatic ? staticGetters : instanceGetters,
+            identifier,
+            setterScope: member.isStatic ? staticSetters : instanceSetters,
+          );
+        }
+      } else if (member is MethodDeclaration) {
+        _checkDuplicateIdentifier(
+          member.isStatic ? staticGetters : instanceGetters,
+          member.name,
+          setterScope: member.isStatic ? staticSetters : instanceSetters,
+        );
+      }
+    }
+
+    // Check for local static members conflicting with local instance members.
+    for (var member in node.members) {
+      if (member is FieldDeclaration) {
+        if (member.isStatic) {
+          for (var field in member.fields.variables) {
+            var identifier = field.name;
+            var name = identifier.name;
+            if (instanceGetters.containsKey(name) ||
+                instanceSetters.containsKey(name)) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
+                identifier,
+                [node.declaredElement.name, name],
+              );
+            }
+          }
+        }
+      } else if (member is MethodDeclaration) {
+        if (member.isStatic) {
+          var identifier = member.name;
+          var name = identifier.name;
+          if (instanceGetters.containsKey(name) ||
+              instanceSetters.containsKey(name)) {
+            _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
+              identifier,
+              [node.declaredElement.name, name],
+            );
+          }
+        }
+      }
+    }
+  }
+
+  /// Check that the given list of variable declarations does not define
+  /// multiple variables of the same name.
+  void checkForVariables(VariableDeclarationList node) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (VariableDeclaration variable in node.variables) {
+      _checkDuplicateIdentifier(definedNames, variable.name);
+    }
+  }
+
+  void checkMixin(MixinDeclaration node) {
+    _checkClassMembers(node.declaredElement, node.members);
+  }
+
+  /**
+   * Check that all of the parameters have unique names.
+   */
+  void checkParameters(FormalParameterList node) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (FormalParameter parameter in node.parameters) {
+      SimpleIdentifier identifier = parameter.identifier;
+      if (identifier != null) {
+        // The identifier can be null if this is a parameter list for a generic
+        // function type.
+        _checkDuplicateIdentifier(definedNames, identifier);
+      }
+    }
+  }
+
+  /// Check that all of the variables have unique names.
+  void checkStatements(List<Statement> statements) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (Statement statement in statements) {
+      if (statement is VariableDeclarationStatement) {
+        for (VariableDeclaration variable in statement.variables.variables) {
+          _checkDuplicateIdentifier(definedNames, variable.name);
+        }
+      } else if (statement is FunctionDeclarationStatement) {
+        _checkDuplicateIdentifier(
+            definedNames, statement.functionDeclaration.name);
+      }
+    }
+  }
+
+  /// Check that all of the parameters have unique names.
+  void checkTypeParameters(TypeParameterList node) {
+    Map<String, Element> definedNames = new HashMap<String, Element>();
+    for (TypeParameter parameter in node.typeParameters) {
+      _checkDuplicateIdentifier(definedNames, parameter.name);
+    }
+  }
+
+  /// Check that there are no members with the same name.
+  void checkUnit(CompilationUnit node) {
+    Map<String, Element> definedGetters = new HashMap<String, Element>();
+    Map<String, Element> definedSetters = new HashMap<String, Element>();
+
+    void addWithoutChecking(CompilationUnitElement element) {
+      for (PropertyAccessorElement accessor in element.accessors) {
+        String name = accessor.name;
+        if (accessor.isSetter) {
+          name += '=';
+        }
+        definedGetters[name] = accessor;
+      }
+      for (ClassElement type in element.enums) {
+        definedGetters[type.name] = type;
+      }
+      for (FunctionElement function in element.functions) {
+        definedGetters[function.name] = function;
+      }
+      for (FunctionTypeAliasElement alias in element.functionTypeAliases) {
+        definedGetters[alias.name] = alias;
+      }
+      for (TopLevelVariableElement variable in element.topLevelVariables) {
+        definedGetters[variable.name] = variable;
+        if (!variable.isFinal && !variable.isConst) {
+          definedGetters[variable.name + '='] = variable;
+        }
+      }
+      for (ClassElement type in element.types) {
+        definedGetters[type.name] = type;
+      }
+    }
+
+    for (ImportElement importElement in _currentLibrary.imports) {
+      PrefixElement prefix = importElement.prefix;
+      if (prefix != null) {
+        definedGetters[prefix.name] = prefix;
+      }
+    }
+    CompilationUnitElement element = node.declaredElement;
+    if (element != _currentLibrary.definingCompilationUnit) {
+      addWithoutChecking(_currentLibrary.definingCompilationUnit);
+      for (CompilationUnitElement part in _currentLibrary.parts) {
+        if (element == part) {
+          break;
+        }
+        addWithoutChecking(part);
+      }
+    }
+    for (CompilationUnitMember member in node.declarations) {
+      if (member is ExtensionDeclaration) {
+        var identifier = member.name;
+        if (identifier != null) {
+          _checkDuplicateIdentifier(definedGetters, identifier,
+              setterScope: definedSetters);
+        }
+      } else if (member is NamedCompilationUnitMember) {
+        _checkDuplicateIdentifier(definedGetters, member.name,
+            setterScope: definedSetters);
+      } else if (member is TopLevelVariableDeclaration) {
+        for (VariableDeclaration variable in member.variables.variables) {
+          _checkDuplicateIdentifier(definedGetters, variable.name,
+              setterScope: definedSetters);
+        }
+      }
+    }
+  }
+
+  /// Check that there are no members with the same name.
+  void _checkClassMembers(ClassElement element, List<ClassMember> members) {
+    Set<String> constructorNames = new HashSet<String>();
+    Map<String, Element> instanceGetters = new HashMap<String, Element>();
+    Map<String, Element> instanceSetters = new HashMap<String, Element>();
+    Map<String, Element> staticGetters = new HashMap<String, Element>();
+    Map<String, Element> staticSetters = new HashMap<String, Element>();
+
+    for (ClassMember member in members) {
+      if (member is ConstructorDeclaration) {
+        var name = member.name?.name ?? '';
+        if (!constructorNames.add(name)) {
+          if (name.isEmpty) {
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, member);
+          } else {
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
+                member,
+                [name]);
+          }
+        }
+      } else if (member is FieldDeclaration) {
+        for (VariableDeclaration field in member.fields.variables) {
+          SimpleIdentifier identifier = field.name;
+          _checkDuplicateIdentifier(
+            member.isStatic ? staticGetters : instanceGetters,
+            identifier,
+            setterScope: member.isStatic ? staticSetters : instanceSetters,
+          );
+        }
+      } else if (member is MethodDeclaration) {
+        _checkDuplicateIdentifier(
+          member.isStatic ? staticGetters : instanceGetters,
+          member.name,
+          setterScope: member.isStatic ? staticSetters : instanceSetters,
+        );
+      }
+    }
+
+    // Check for local static members conflicting with local instance members.
+    for (ClassMember member in members) {
+      if (member is ConstructorDeclaration) {
+        if (member.name != null) {
+          String name = member.name.name;
+          var staticMember = staticGetters[name] ?? staticSetters[name];
+          if (staticMember != null) {
+            if (staticMember is PropertyAccessorElement) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
+                member.name,
+                [name],
+              );
+            } else {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+                member.name,
+                [name],
+              );
+            }
+          }
+        }
+      } else if (member is FieldDeclaration) {
+        if (member.isStatic) {
+          for (VariableDeclaration field in member.fields.variables) {
+            SimpleIdentifier identifier = field.name;
+            String name = identifier.name;
+            if (instanceGetters.containsKey(name) ||
+                instanceSetters.containsKey(name)) {
+              String className = element.displayName;
+              _errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+                  identifier,
+                  [className, name, className]);
+            }
+          }
+        }
+      } else if (member is MethodDeclaration) {
+        if (member.isStatic) {
+          SimpleIdentifier identifier = member.name;
+          String name = identifier.name;
+          if (instanceGetters.containsKey(name) ||
+              instanceSetters.containsKey(name)) {
+            String className = identifier.staticElement.enclosingElement.name;
+            _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
+                identifier,
+                [className, name, className]);
+          }
+        }
+      }
+    }
+  }
+
+  /// Check whether the given [element] defined by the [identifier] is already
+  /// in one of the scopes - [getterScope] or [setterScope], and produce an
+  /// error if it is.
+  void _checkDuplicateIdentifier(
+      Map<String, Element> getterScope, SimpleIdentifier identifier,
+      {Element element, Map<String, Element> setterScope}) {
+    element ??= identifier.staticElement;
+
+    // Fields define getters and setters, so check them separately.
+    if (element is PropertyInducingElement) {
+      _checkDuplicateIdentifier(getterScope, identifier,
+          element: element.getter, setterScope: setterScope);
+      if (!element.isConst && !element.isFinal) {
+        _checkDuplicateIdentifier(getterScope, identifier,
+            element: element.setter, setterScope: setterScope);
+      }
+      return;
+    }
+
+    ErrorCode getError(Element previous, Element current) {
+      if (previous is PrefixElement) {
+        return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
+      }
+      return CompileTimeErrorCode.DUPLICATE_DEFINITION;
+    }
+
+    bool isGetterSetterPair(Element a, Element b) {
+      if (a is PropertyAccessorElement && b is PropertyAccessorElement) {
+        return a.isGetter && b.isSetter || a.isSetter && b.isGetter;
+      }
+      return false;
+    }
+
+    String name = identifier.name;
+    if (element is MethodElement && element.isOperator && name == '-') {
+      if (element.parameters.isEmpty) {
+        name = 'unary-';
+      }
+    }
+
+    Element previous = getterScope[name];
+    if (previous != null) {
+      if (isGetterSetterPair(element, previous)) {
+        // OK
+      } else {
+        _errorReporter.reportErrorForNode(
+          getError(previous, element),
+          identifier,
+          [name],
+        );
+      }
+    } else {
+      getterScope[name] = element;
+    }
+
+    if (element is PropertyAccessorElement && element.isSetter) {
+      previous = setterScope[name];
+      if (previous != null) {
+        _errorReporter.reportErrorForNode(
+          getError(previous, element),
+          identifier,
+          [name],
+        );
+      } else {
+        setterScope[name] = element;
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
new file mode 100644
index 0000000..634f41a
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -0,0 +1,431 @@
+// Copyright (c) 2019, 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:math" as math;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/resolver.dart';
+
+class TypeArgumentsVerifier {
+  final AnalysisOptionsImpl _options;
+  final TypeSystem _typeSystem;
+  final ErrorReporter _errorReporter;
+
+  TypeArgumentsVerifier(this._options, this._typeSystem, this._errorReporter);
+
+  TypeProvider get _typeProvider => _typeSystem.typeProvider;
+
+  void checkFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    _checkTypeArguments(node);
+    _checkForImplicitDynamicInvoke(node);
+  }
+
+  void checkListLiteral(ListLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        _checkTypeArgumentConst(
+          typeArguments.arguments,
+          CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
+        );
+      }
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+  }
+
+  void checkMapLiteral(SetOrMapLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        _checkTypeArgumentConst(
+          typeArguments.arguments,
+          CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
+        );
+      }
+      _checkTypeArgumentCount(typeArguments, 2,
+          StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+  }
+
+  void checkMethodInvocation(MethodInvocation node) {
+    _checkTypeArguments(node);
+    _checkForImplicitDynamicInvoke(node);
+  }
+
+  void checkSetLiteral(SetOrMapLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        _checkTypeArgumentConst(
+          typeArguments.arguments,
+          CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET,
+        );
+      }
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+  }
+
+  void checkTypeName(TypeName node) {
+    _checkForTypeArgumentNotMatchingBounds(node);
+    if (node.parent is ConstructorName &&
+        node.parent.parent is InstanceCreationExpression) {
+      _checkForInferenceFailureOnInstanceCreation(node, node.parent.parent);
+    } else {
+      _checkForRawTypeName(node);
+    }
+  }
+
+  void _checkForImplicitDynamicInvoke(InvocationExpression node) {
+    if (_options.implicitDynamic ||
+        node == null ||
+        node.typeArguments != null) {
+      return;
+    }
+    DartType invokeType = node.staticInvokeType;
+    DartType declaredType = node.function.staticType;
+    if (invokeType is FunctionType &&
+        declaredType is FunctionType &&
+        declaredType.typeFormals.isNotEmpty) {
+      List<DartType> typeArgs = node.typeArgumentTypes;
+      if (typeArgs.any((t) => t.isDynamic)) {
+        // Issue an error depending on what we're trying to call.
+        Expression function = node.function;
+        if (function is Identifier) {
+          Element element = function.staticElement;
+          if (element is MethodElement) {
+            _errorReporter.reportErrorForNode(
+                StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
+                node.function,
+                [element.displayName, element.typeParameters.join(', ')]);
+            return;
+          }
+
+          if (element is FunctionElement) {
+            _errorReporter.reportErrorForNode(
+                StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
+                node.function,
+                [element.displayName, element.typeParameters.join(', ')]);
+            return;
+          }
+        }
+
+        // The catch all case if neither of those matched.
+        // For example, invoking a function expression.
+        _errorReporter.reportErrorForNode(
+            StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
+            node.function,
+            [declaredType]);
+      }
+    }
+  }
+
+  void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
+    if (_options.implicitDynamic || node.typeArguments != null) {
+      return;
+    }
+    DartType type = node.staticType;
+    // It's an error if either the key or value was inferred as dynamic.
+    if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
+      // TODO(brianwilkerson) Add StrongModeCode.IMPLICIT_DYNAMIC_SET_LITERAL
+      ErrorCode errorCode = node is ListLiteral
+          ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
+          : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
+      _errorReporter.reportErrorForNode(errorCode, node);
+    }
+  }
+
+  /// Checks a type on an instance creation expression for an inference
+  /// failure, and reports the appropriate error if
+  /// [AnalysisOptionsImpl.strictInference] is set.
+  ///
+  /// This checks if [node] refers to a generic type and does not have explicit
+  /// or inferred type arguments. When that happens, it reports a
+  /// HintMode.INFERENCE_FAILURE_ON_INSTANCE_CREATION error.
+  void _checkForInferenceFailureOnInstanceCreation(
+      TypeName node, InstanceCreationExpression inferenceContextNode) {
+    if (!_options.strictInference || node == null) return;
+    if (node.typeArguments != null) {
+      // Type has explicit type arguments.
+      return;
+    }
+    if (_isMissingTypeArguments(
+        node, node.type, node.name.staticElement, inferenceContextNode)) {
+      _errorReporter.reportErrorForNode(
+          HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, node, [node.type]);
+    }
+  }
+
+  /// Checks a type annotation for a raw generic type, and reports the
+  /// appropriate error if [AnalysisOptionsImpl.strictRawTypes] is set.
+  ///
+  /// This checks if [node] refers to a generic type and does not have explicit
+  /// or inferred type arguments. When that happens, it reports error code
+  /// [HintCode.STRICT_RAW_TYPE].
+  void _checkForRawTypeName(TypeName node) {
+    AstNode parentEscapingTypeArguments(TypeName node) {
+      AstNode parent = node.parent;
+      while (parent is TypeArgumentList || parent is TypeName) {
+        if (parent.parent == null) {
+          return parent;
+        }
+        parent = parent.parent;
+      }
+      return parent;
+    }
+
+    if (!_options.strictRawTypes || node == null) return;
+    if (node.typeArguments != null) {
+      // Type has explicit type arguments.
+      return;
+    }
+    if (_isMissingTypeArguments(
+        node, node.type, node.name.staticElement, null)) {
+      AstNode unwrappedParent = parentEscapingTypeArguments(node);
+      if (unwrappedParent is AsExpression) {
+        _errorReporter.reportErrorForNode(
+            HintCode.STRICT_RAW_TYPE_IN_AS, node, [node.type]);
+      } else if (unwrappedParent is IsExpression) {
+        _errorReporter.reportErrorForNode(
+            HintCode.STRICT_RAW_TYPE_IN_IS, node, [node.type]);
+      } else {
+        _errorReporter
+            .reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [node.type]);
+      }
+    }
+  }
+
+  /**
+   * Verify that the type arguments in the given [typeName] are all within
+   * their bounds.
+   */
+  void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
+    // prepare Type
+    DartType type = typeName.type;
+    if (type == null) {
+      return;
+    }
+    if (type is ParameterizedType) {
+      var element = typeName.name.staticElement;
+      // prepare type parameters
+      List<TypeParameterElement> parameterElements;
+      if (element is ClassElement) {
+        parameterElements = element.typeParameters;
+      } else if (element is GenericTypeAliasElement) {
+        parameterElements = element.typeParameters;
+      } else if (element is GenericFunctionTypeElement) {
+        // TODO(paulberry): it seems like either this case or the one above
+        // should be unnecessary.
+        FunctionTypeAliasElement typedefElement = element.enclosingElement;
+        parameterElements = typedefElement.typeParameters;
+      } else if (type is FunctionType) {
+        parameterElements = type.typeFormals;
+      } else {
+        // There are no other kinds of parameterized types.
+        throw new UnimplementedError(
+            'Unexpected element associated with parameterized type: '
+            '${element.runtimeType}');
+      }
+      var parameterTypes =
+          parameterElements.map<DartType>((p) => p.type).toList();
+      List<DartType> arguments = type.typeArguments;
+      // iterate over each bounded type parameter and corresponding argument
+      NodeList<TypeAnnotation> argumentNodes =
+          typeName.typeArguments?.arguments;
+      var typeArguments = type.typeArguments;
+      int loopThroughIndex =
+          math.min(typeArguments.length, parameterElements.length);
+      bool shouldSubstitute =
+          arguments.isNotEmpty && arguments.length == parameterTypes.length;
+      for (int i = 0; i < loopThroughIndex; i++) {
+        DartType argType = typeArguments[i];
+        TypeAnnotation argumentNode =
+            argumentNodes != null && i < argumentNodes.length
+                ? argumentNodes[i]
+                : typeName;
+        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
+          _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+            argumentNode,
+          );
+          continue;
+        }
+        DartType boundType = parameterElements[i].bound;
+        if (argType != null && boundType != null) {
+          if (shouldSubstitute) {
+            boundType = boundType.substitute2(arguments, parameterTypes);
+          }
+
+          if (!_typeSystem.isSubtypeOf(argType, boundType)) {
+            if (_shouldAllowSuperBoundedTypes(typeName)) {
+              var replacedType =
+                  (argType as TypeImpl).replaceTopAndBottom(_typeProvider);
+              if (!identical(replacedType, argType) &&
+                  _typeSystem.isSubtypeOf(replacedType, boundType)) {
+                // Bound is satisfied under super-bounded rules, so we're ok.
+                continue;
+              }
+            }
+            _errorReporter.reportTypeErrorForNode(
+                CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+                argumentNode,
+                [argType, boundType]);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Checks to ensure that the given list of type [arguments] does not have a
+   * type parameter as a type argument. The [errorCode] is either
+   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
+   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP].
+   */
+  void _checkTypeArgumentConst(
+      NodeList<TypeAnnotation> arguments, ErrorCode errorCode) {
+    for (TypeAnnotation type in arguments) {
+      if (type is TypeName && type.type is TypeParameterType) {
+        _errorReporter.reportErrorForNode(errorCode, type, [type.name]);
+      }
+    }
+  }
+
+  /// Verify that the given list of [typeArguments] contains exactly the
+  /// [expectedCount] of elements, reporting an error with the [errorCode]
+  /// if not.
+  void _checkTypeArgumentCount(
+    TypeArgumentList typeArguments,
+    int expectedCount,
+    ErrorCode errorCode,
+  ) {
+    int actualCount = typeArguments.arguments.length;
+    if (actualCount != expectedCount) {
+      _errorReporter.reportErrorForNode(
+        errorCode,
+        typeArguments,
+        [actualCount],
+      );
+    }
+  }
+
+  /**
+   * Verify that the given [typeArguments] are all within their bounds, as
+   * defined by the given [element].
+   */
+  void _checkTypeArguments(InvocationExpression node) {
+    NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments;
+    if (typeArgumentList == null) {
+      return;
+    }
+
+    var genericType = node.function.staticType;
+    var instantiatedType = node.staticInvokeType;
+    if (genericType is FunctionType && instantiatedType is FunctionType) {
+      var fnTypeParams =
+          TypeParameterTypeImpl.getTypes(genericType.typeFormals);
+      var typeArgs = typeArgumentList.map((t) => t.type).toList();
+
+      // If the amount mismatches, clean up the lists to be substitutable. The
+      // mismatch in size is reported elsewhere, but we must successfully
+      // perform substitution to validate bounds on mismatched lists.
+      final providedLength = math.min(typeArgs.length, fnTypeParams.length);
+      fnTypeParams = fnTypeParams.sublist(0, providedLength);
+      typeArgs = typeArgs.sublist(0, providedLength);
+
+      for (int i = 0; i < providedLength; i++) {
+        // Check the `extends` clause for the type parameter, if any.
+        //
+        // Also substitute to handle cases like this:
+        //
+        //     <TFrom, TTo extends TFrom>
+        //     <TFrom, TTo extends Iterable<TFrom>>
+        //     <T extends Clonable<T>>
+        //
+        DartType argType = typeArgs[i];
+
+        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
+          _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+            typeArgumentList[i],
+          );
+          continue;
+        }
+
+        DartType bound =
+            fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
+        if (!_typeSystem.isSubtypeOf(argType, bound)) {
+          _errorReporter.reportTypeErrorForNode(
+              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+              typeArgumentList[i],
+              [argType, bound]);
+        }
+      }
+    }
+  }
+
+  /// Given a [node] without type arguments that refers to [element], issues
+  /// an error if [type] is a generic type, and the type arguments were not
+  /// supplied from inference or a non-dynamic default instantiation.
+  ///
+  /// This function is used by other node-specific type checking functions, and
+  /// should only be called when [node] has no explicit `typeArguments`.
+  ///
+  /// [inferenceContextNode] is the node that has the downwards context type,
+  /// if any. For example an [InstanceCreationExpression].
+  ///
+  /// This function will return false if any of the following are true:
+  ///
+  /// - [inferenceContextNode] has an inference context type that does not
+  ///   contain `?`
+  /// - [type] does not have any `dynamic` type arguments.
+  /// - the element is marked with `@optionalTypeArgs` from "package:meta".
+  bool _isMissingTypeArguments(AstNode node, DartType type, Element element,
+      Expression inferenceContextNode) {
+    // Check if this type has type arguments and at least one is dynamic.
+    // If so, we may need to issue a strict-raw-types error.
+    if (type is ParameterizedType &&
+        type.typeArguments.any((t) => t.isDynamic)) {
+      // If we have an inference context node, check if the type was inferred
+      // from it. Some cases will not have a context type, such as the type
+      // annotation `List` in `List list;`
+      if (inferenceContextNode != null) {
+        var contextType = InferenceContext.getContext(inferenceContextNode);
+        if (contextType != null && UnknownInferredType.isKnown(contextType)) {
+          // Type was inferred from downwards context: not an error.
+          return false;
+        }
+      }
+      if (element.hasOptionalTypeArgs) {
+        return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /// Determines if the given [typeName] occurs in a context where super-bounded
+  /// types are allowed.
+  bool _shouldAllowSuperBoundedTypes(TypeName typeName) {
+    var parent = typeName.parent;
+    if (parent is ExtendsClause) return false;
+    if (parent is OnClause) return false;
+    if (parent is ClassTypeAlias) return false;
+    if (parent is WithClause) return false;
+    if (parent is ConstructorName) return false;
+    if (parent is ImplementsClause) return false;
+    return true;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 0baf769..7c64ff0 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -19,10 +19,10 @@
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -116,9 +116,10 @@
   /// Whether constant evaluation errors should be reported during resolution.
   final bool reportConstEvaluationErrors;
 
-  final MethodInvocationResolver _methodInvocationResolver;
+  /// Helper for extension method resolution.
+  final ExtensionMemberResolver _extensionResolver;
 
-  final ExtensionMemberResolver _extensionMemberResolver;
+  final MethodInvocationResolver _methodInvocationResolver;
 
   /**
    * Initialize a newly created visitor to work for the given [_resolver] to
@@ -127,7 +128,7 @@
   ElementResolver(this._resolver, {this.reportConstEvaluationErrors: true})
       : _inheritance = _resolver.inheritance,
         _definingLibrary = _resolver.definingLibrary,
-        _extensionMemberResolver = ExtensionMemberResolver(_resolver),
+        _extensionResolver = _resolver.extensionResolver,
         _methodInvocationResolver = new MethodInvocationResolver(_resolver) {
     _dynamicType = _resolver.typeProvider.dynamicType;
     _typeType = _resolver.typeProvider.typeType;
@@ -171,10 +172,10 @@
         String methodName = operatorType.lexeme;
         // TODO(brianwilkerson) Change the [methodNameNode] from the left hand
         //  side to the operator.
-        MethodElement staticMethod =
+        ResolutionResult result =
             _lookUpMethod(leftHandSide, staticType, methodName, leftHandSide);
-        node.staticElement = staticMethod;
-        if (_shouldReportInvalidMember(staticType, staticMethod)) {
+        node.staticElement = result.element;
+        if (_shouldReportInvalidMember(staticType, result)) {
           _recordUndefinedToken(
               staticType.element,
               StaticTypeWarningCode.UNDEFINED_OPERATOR,
@@ -270,7 +271,8 @@
               memberElement = element.getNamedConstructor(name.name);
               if (memberElement == null) {
                 memberElement =
-                    _lookUpSetter(prefix, element.type, name.name, name);
+                    _lookUpSetter(prefix, element.type, name.name, name)
+                        .element;
               }
             }
             if (memberElement == null) {
@@ -403,8 +405,8 @@
     Expression function = node.function;
     DartType functionType;
     if (function is ExtensionOverride) {
-      ExtensionElement element = function.extensionName.staticElement;
-      MethodElement member = element.getMethod('call');
+      var member = _extensionResolver.getOverrideMember(
+          function, 'call', ElementKind.METHOD);
       if (member != null && member.isStatic) {
         _resolver.errorReporter.reportErrorForNode(
             CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
@@ -480,41 +482,41 @@
     bool isInSetterContext = node.inSetterContext();
     if (isInGetterContext && isInSetterContext) {
       // lookup setter
-      MethodElement setterStaticMethod =
+      ResolutionResult setterResult =
           _lookUpMethod(target, staticType, setterMethodName, target);
       // set setter element
-      node.staticElement = setterStaticMethod;
+      node.staticElement = setterResult.element;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, setterMethodName, setterStaticMethod, staticType);
+          node, target, setterMethodName, setterResult, staticType);
       // lookup getter method
-      MethodElement getterStaticMethod =
+      ResolutionResult getterResult =
           _lookUpMethod(target, staticType, getterMethodName, target);
       // set getter element
       AuxiliaryElements auxiliaryElements =
-          new AuxiliaryElements(getterStaticMethod, null);
+          new AuxiliaryElements(getterResult.element, null);
       node.auxiliaryElements = auxiliaryElements;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, getterMethodName, getterStaticMethod, staticType);
+          node, target, getterMethodName, getterResult, staticType);
     } else if (isInGetterContext) {
       // lookup getter method
-      MethodElement staticMethod =
+      ResolutionResult methodResult =
           _lookUpMethod(target, staticType, getterMethodName, target);
       // set getter element
-      node.staticElement = staticMethod;
+      node.staticElement = methodResult.element;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, getterMethodName, staticMethod, staticType);
+          node, target, getterMethodName, methodResult, staticType);
     } else if (isInSetterContext) {
       // lookup setter method
-      MethodElement staticMethod =
+      ResolutionResult methodResult =
           _lookUpMethod(target, staticType, setterMethodName, target);
       // set setter element
-      node.staticElement = staticMethod;
+      node.staticElement = methodResult.element;
       // generate undefined method warning
       _checkForUndefinedIndexOperator(
-          node, target, setterMethodName, staticMethod, staticType);
+          node, target, setterMethodName, methodResult, staticType);
     }
   }
 
@@ -569,10 +571,10 @@
     DartType staticType = _getStaticType(operand);
     // TODO(brianwilkerson) Change the [methodNameNode] from the operand to
     //  the operator.
-    MethodElement staticMethod =
+    ResolutionResult result =
         _lookUpMethod(operand, staticType, methodName, operand);
-    node.staticElement = staticMethod;
-    if (_shouldReportInvalidMember(staticType, staticMethod)) {
+    node.staticElement = result.element;
+    if (_shouldReportInvalidMember(staticType, result)) {
       if (operand is SuperExpression) {
         _recordUndefinedToken(
             staticType.element,
@@ -677,10 +679,10 @@
       DartType staticType = _getStaticType(operand, read: true);
       // TODO(brianwilkerson) Change the [methodNameNode] from the operand to
       //  the operator.
-      MethodElement staticMethod =
+      ResolutionResult result =
           _lookUpMethod(operand, staticType, methodName, operand);
-      node.staticElement = staticMethod;
-      if (_shouldReportInvalidMember(staticType, staticMethod)) {
+      node.staticElement = result.element;
+      if (_shouldReportInvalidMember(staticType, result)) {
         if (operand is SuperExpression) {
           _recordUndefinedToken(
               staticType.element,
@@ -714,7 +716,8 @@
       String memberName = propertyName.name;
       ExecutableElement member;
       if (propertyName.inSetterContext()) {
-        member = element.getSetter(memberName);
+        member = _extensionResolver.getOverrideMember(
+            target, memberName, ElementKind.SETTER);
         if (member == null) {
           _resolver.errorReporter.reportErrorForNode(
               CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
@@ -722,7 +725,8 @@
               [memberName, element.name]);
         }
         if (propertyName.inGetterContext()) {
-          PropertyAccessorElement getter = element.getGetter(memberName);
+          PropertyAccessorElement getter = _extensionResolver.getOverrideMember(
+              target, memberName, ElementKind.GETTER);
           if (getter == null) {
             _resolver.errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -732,7 +736,10 @@
           propertyName.auxiliaryElements = AuxiliaryElements(getter, null);
         }
       } else if (propertyName.inGetterContext()) {
-        member = element.getGetter(memberName) ?? element.getMethod(memberName);
+        member = _extensionResolver.getOverrideMember(
+                target, memberName, ElementKind.GETTER) ??
+            _extensionResolver.getOverrideMember(
+                target, memberName, ElementKind.METHOD);
         if (member == null) {
           _resolver.errorReporter.reportErrorForNode(
               CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -746,12 +753,6 @@
             propertyName);
       }
 
-      member = ExecutableMember.from3(
-        member,
-        element.typeParameters,
-        target.typeArgumentTypes,
-      );
-
       propertyName.staticElement = member;
       return;
     }
@@ -877,7 +878,7 @@
         enclosingClass != null) {
       InterfaceType enclosingType = enclosingClass.type;
       AuxiliaryElements auxiliaryElements = new AuxiliaryElements(
-          _lookUpGetter(null, enclosingType, node.name, node), null);
+          _lookUpGetter(null, enclosingType, node.name, node).element, null);
       node.auxiliaryElements = auxiliaryElements;
     }
     //
@@ -978,9 +979,9 @@
       IndexExpression expression,
       Expression target,
       String methodName,
-      MethodElement staticMethod,
+      ResolutionResult result,
       DartType staticType) {
-    if (_shouldReportInvalidMember(staticType, staticMethod)) {
+    if (_shouldReportInvalidMember(staticType, result)) {
       Token leftBracket = expression.leftBracket;
       Token rightBracket = expression.rightBracket;
       ErrorCode errorCode;
@@ -1075,19 +1076,6 @@
    * type analysis.
    */
   DartType _getStaticType(Expression expression, {bool read: false}) {
-    DartType staticType = _getStaticTypeOrFunctionType(expression, read: read);
-    if (staticType is FunctionType) {
-      //
-      // All function types are subtypes of 'Function', which is itself a
-      // subclass of 'Object'.
-      //
-      staticType = _resolver.typeProvider.functionType;
-    }
-    return staticType;
-  }
-
-  DartType _getStaticTypeOrFunctionType(Expression expression,
-      {bool read: false}) {
     if (expression is NullLiteral) {
       return _resolver.typeProvider.nullType;
     }
@@ -1240,13 +1228,13 @@
       return callMethod;
     }
 
-    var result = _extensionMemberResolver.findExtension(
+    var result = _extensionResolver.findExtension(
       type,
       FunctionElement.CALL_METHOD_NAME,
       node,
       ElementKind.METHOD,
     );
-    var instantiatedMember = result.extension?.instantiatedMember;
+    var instantiatedMember = result.element;
     if (instantiatedMember is MethodElement) {
       return instantiatedMember;
     }
@@ -1255,27 +1243,35 @@
   }
 
   /**
-   * Look up the getter with the given [getterName] in the given [type]. Return
-   * the element representing the getter that was found, or `null` if there is
-   * no getter with the given name. The [target] is the target of the
-   * invocation, or `null` if there is no target.
+   * Look up the getter with the given [name] in the given [type]. Return a
+   * result representing the result of that lookup. The [target] is the target
+   * of the invocation, or `null` if there is no target.
    */
-  PropertyAccessorElement _lookUpGetter(
+  ResolutionResult _lookUpGetter(
       Expression target, DartType type, String name, Expression nameNode) {
     type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
+    ResolutionResult result = ResolutionResult.none;
+
+    void lookupIn(InterfaceType type) {
       var getter = type.lookUpInheritedGetter(name,
           library: _definingLibrary, thisType: target is! SuperExpression);
       if (getter != null) {
-        return getter;
-      }
-      var result = _extensionMemberResolver.findExtension(
-          type, name, nameNode, ElementKind.GETTER);
-      if (result.isSingle) {
-        return result.extension.instantiatedMember;
+        result = ResolutionResult(getter);
       }
     }
-    return null;
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_resolver.typeProvider.functionType);
+    } else {
+      return ResolutionResult.none;
+    }
+    if (result.isNone) {
+      result = _extensionResolver.findExtension(
+          type, name, nameNode, ElementKind.GETTER);
+    }
+    return result;
   }
 
   /**
@@ -1293,51 +1289,67 @@
   }
 
   /**
-   * Look up the method with the given [name] in the given [type]. Return
-   * the element representing the method that was found, or `null` if there is
-   * no method with the given name. The [target] is the target of the
-   * invocation, or `null` if there is no target.
+   * Look up the method with the given [name] in the given [type]. Return a
+   * result representing the result of that lookup. The [target] is the target
+   * of the invocation, or `null` if there is no target.
    */
-  MethodElement _lookUpMethod(
+  ResolutionResult _lookUpMethod(
       Expression target, DartType type, String name, Expression nameNode) {
     type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
+    ResolutionResult result = ResolutionResult.none;
+
+    void lookupIn(InterfaceType type) {
       var method = type.lookUpInheritedMethod(name,
           library: _definingLibrary, thisType: target is! SuperExpression);
       if (method != null) {
-        return method;
-      }
-      var result = _extensionMemberResolver.findExtension(
-          type, name, nameNode, ElementKind.METHOD);
-      if (result.isSingle) {
-        return result.extension.instantiatedMember;
+        result = ResolutionResult(method);
       }
     }
-    return null;
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_resolver.typeProvider.functionType);
+    } else {
+      return ResolutionResult.none;
+    }
+    if (result.isNone) {
+      result = _extensionResolver.findExtension(
+          type, name, nameNode, ElementKind.METHOD);
+    }
+    return result;
   }
 
   /**
-   * Look up the setter with the given [name] in the given [type]. Return
-   * the element representing the setter that was found, or `null` if there is
-   * no setter with the given name. The [target] is the target of the
-   * invocation, or `null` if there is no target.
+   * Look up the setter with the given [name] in the given [type]. Return a
+   * result representing the result of that lookup. The [target] is the target
+   * of the invocation, or `null` if there is no target.
    */
-  PropertyAccessorElement _lookUpSetter(
+  ResolutionResult _lookUpSetter(
       Expression target, DartType type, String name, Expression nameNode) {
     type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
+    ResolutionResult result = ResolutionResult.none;
+
+    void lookupIn(InterfaceType type) {
       var setter = type.lookUpInheritedSetter(name,
           library: _definingLibrary, thisType: target is! SuperExpression);
       if (setter != null) {
-        return setter;
-      }
-      var result = _extensionMemberResolver.findExtension(
-          type, name, nameNode, ElementKind.SETTER);
-      if (result.isSingle) {
-        return result.extension.instantiatedMember;
+        result = ResolutionResult(setter);
       }
     }
-    return null;
+
+    if (type is InterfaceType) {
+      lookupIn(type);
+    } else if (type is FunctionType) {
+      lookupIn(_resolver.typeProvider.functionType);
+    } else {
+      return ResolutionResult.none;
+    }
+    if (result.isNone) {
+      result = _extensionResolver.findExtension(
+          type, name, nameNode, ElementKind.SETTER);
+    }
+    return result;
   }
 
   /**
@@ -1580,26 +1592,33 @@
       DartType leftType = _getStaticType(leftOperand);
       var isSuper = leftOperand is SuperExpression;
 
-      ExecutableElement invokeElement;
-      if (leftType is InterfaceType) {
-        invokeElement = _inheritance.getMember(
-          leftType,
+      ResolutionResult result = ResolutionResult.none;
+
+      void lookupIn(InterfaceType type) {
+        ExecutableElement invokeElement = _inheritance.getMember(
+          type,
           new Name(_definingLibrary.source.uri, methodName),
           forSuper: isSuper,
         );
-      }
-
-      if (invokeElement == null && leftType is InterfaceType) {
-        var result = _extensionMemberResolver.findExtension(
-            leftType, methodName, node, ElementKind.METHOD);
-        if (result.isSingle) {
-          invokeElement = result.extension.instantiatedMember;
+        if (invokeElement != null) {
+          result = ResolutionResult(invokeElement);
         }
       }
 
-      node.staticElement = invokeElement;
-      node.staticInvokeType = invokeElement?.type;
-      if (_shouldReportInvalidMember(leftType, invokeElement)) {
+      if (leftType is InterfaceType) {
+        lookupIn(leftType);
+      } else if (leftType is FunctionType) {
+        lookupIn(_resolver.typeProvider.functionType);
+      }
+
+      if (result.isNone) {
+        result = _extensionResolver.findExtension(
+            leftType, methodName, node, ElementKind.METHOD);
+      }
+
+      node.staticElement = result.element;
+      node.staticInvokeType = result.element?.type;
+      if (_shouldReportInvalidMember(leftType, result)) {
         if (isSuper) {
           _recordUndefinedToken(
               leftType.element,
@@ -1691,29 +1710,35 @@
    * given [propertyName], return the element that represents the property. The
    * [target] is the target of the invocation ('e').
    */
-  ExecutableElement _resolveProperty(
+  ResolutionResult _resolveProperty(
       Expression target, DartType targetType, SimpleIdentifier propertyName) {
-    ExecutableElement memberElement = null;
+    ResolutionResult result = ResolutionResult.none;
     if (propertyName.inSetterContext()) {
-      memberElement =
+      result =
           _lookUpSetter(target, targetType, propertyName.name, propertyName);
     }
-    if (memberElement == null) {
-      memberElement =
+    if (result.isNone) {
+      result =
           _lookUpGetter(target, targetType, propertyName.name, propertyName);
     }
-    if (memberElement == null) {
-      memberElement =
+    if (result.isNone) {
+      result =
           _lookUpMethod(target, targetType, propertyName.name, propertyName);
     }
-    return memberElement;
+    return result;
   }
 
   void _resolvePropertyAccess(
       Expression target, SimpleIdentifier propertyName, bool isCascaded) {
     DartType staticType = _getStaticType(target);
-    Element staticElement;
+    //
+    // If this property access is of the form 'E.m' where 'E' is an extension,
+    // then look for the member in the extension. This does not apply to
+    // conditional property accesses (i.e. 'C?.m').
+    //
+    ResolutionResult result = ResolutionResult.none;
     if (target is Identifier && target.staticElement is ExtensionElement) {
+      Element staticElement;
       ExtensionElement extension = target.staticElement;
       String memberName = propertyName.name;
       if (propertyName.inSetterContext()) {
@@ -1727,6 +1752,9 @@
             propertyName,
             [memberName]);
       }
+      if (staticElement != null) {
+        result = ResolutionResult(staticElement);
+      }
     }
     //
     // If this property access is of the form 'C.m' where 'C' is a class,
@@ -1734,13 +1762,17 @@
     // hierarchy, instead we just look for the member in the type only.  This
     // does not apply to conditional property accesses (i.e. 'C?.m').
     //
-    if (staticElement == null) {
+    if (result.isNone) {
+      Element staticElement;
       ClassElement typeReference = getTypeReference(target);
       if (typeReference != null) {
         if (isCascaded) {
           typeReference = _typeType.element;
         }
         staticElement = _resolveElement(typeReference, propertyName);
+        if (staticElement != null) {
+          result = ResolutionResult(staticElement);
+        }
       } else {
         if (target is SuperExpression) {
           if (staticType is InterfaceTypeImpl) {
@@ -1770,21 +1802,28 @@
               }
             }
           }
+          if (staticElement != null) {
+            result = ResolutionResult(staticElement);
+          }
         } else {
-          staticElement = _resolveProperty(target, staticType, propertyName);
+          result = _resolveProperty(target, staticType, propertyName);
         }
       }
     }
-    // May be part of annotation, record property element only if exists.
+    // Might be part of an annotation, record property element only if exists.
     // Error was already reported in validateAnnotationElement().
     if (target.parent.parent is Annotation) {
-      if (staticElement != null) {
-        propertyName.staticElement = staticElement;
+      if (result.isSingle) {
+        propertyName.staticElement = result.element;
       }
       return;
     }
-    propertyName.staticElement = staticElement;
-    if (_shouldReportInvalidMember(staticType, staticElement)) {
+    propertyName.staticElement = result.element;
+    if (_shouldReportInvalidMember(staticType, result)) {
+      if (staticType is FunctionType &&
+          propertyName.name == FunctionElement.CALL_METHOD_NAME) {
+        return;
+      }
       Element enclosingElement = staticType.element;
       bool isStaticProperty = _isStatic(enclosingElement);
       // Special getter cases.
@@ -1865,7 +1904,8 @@
           ClassElement enclosingClass = _resolver.enclosingClass;
           if (enclosingClass != null) {
             setter = _lookUpSetter(
-                null, enclosingClass.type, identifier.name, identifier);
+                    null, enclosingClass.type, identifier.name, identifier)
+                .element;
           }
         }
         if (setter != null) {
@@ -1904,15 +1944,18 @@
             (identifier.inSetterContext() ||
                 identifier.parent is CommentReference)) {
           element =
-              _lookUpSetter(null, enclosingType, identifier.name, identifier);
+              _lookUpSetter(null, enclosingType, identifier.name, identifier)
+                  .element;
         }
         if (element == null && identifier.inGetterContext()) {
           element =
-              _lookUpGetter(null, enclosingType, identifier.name, identifier);
+              _lookUpGetter(null, enclosingType, identifier.name, identifier)
+                  .element;
         }
         if (element == null) {
           element =
-              _lookUpMethod(null, enclosingType, identifier.name, identifier);
+              _lookUpMethod(null, enclosingType, identifier.name, identifier)
+                  .element;
         }
       }
     }
@@ -1930,8 +1973,8 @@
    * Return `true` if we should report an error for a [member] lookup that found
    * no match on the given [type].
    */
-  bool _shouldReportInvalidMember(DartType type, Element member) =>
-      type != null && member == null && !type.isDynamic;
+  bool _shouldReportInvalidMember(DartType type, ResolutionResult result) =>
+      type != null && !type.isDynamic && result.isNone;
 
   /**
    * Checks whether the given [expression] is a reference to a class. If it is
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c4fb17b..bde9710 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:collection';
-import "dart:math" as math;
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -24,8 +23,10 @@
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/error/duplicate_definition_verifier.dart';
 import 'package:analyzer/src/error/literal_element_verifier.dart';
 import 'package:analyzer/src/error/required_parameters_verifier.dart';
+import 'package:analyzer/src/error/type_arguments_verifier.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -301,6 +302,8 @@
   FeatureSet _featureSet;
 
   final RequiredParametersVerifier _requiredParametersVerifier;
+  final DuplicateDefinitionVerifier _duplicateDefinitionVerifier;
+  TypeArgumentsVerifier _typeArgumentsVerifier;
 
   /**
    * Initialize a newly created error verifier.
@@ -323,8 +326,9 @@
         _inheritanceManager = inheritanceManager.asInheritanceManager3,
         _uninstantiatedBoundChecker =
             new _UninstantiatedBoundChecker(errorReporter),
-        _requiredParametersVerifier =
-            RequiredParametersVerifier(errorReporter) {
+        _requiredParametersVerifier = RequiredParametersVerifier(errorReporter),
+        _duplicateDefinitionVerifier =
+            DuplicateDefinitionVerifier(_currentLibrary, errorReporter) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
     _isEnclosingConstructorConst = false;
@@ -339,6 +343,8 @@
     _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = _typeProvider.nonSubtypableTypes;
     _typeSystem = _currentLibrary.context.typeSystem;
     _options = _currentLibrary.context.analysisOptions;
+    _typeArgumentsVerifier =
+        TypeArgumentsVerifier(_options, _typeSystem, _errorReporter);
   }
 
   /**
@@ -460,7 +466,7 @@
   void visitBlock(Block node) {
     _hiddenElements = new HiddenElements(_hiddenElements, node);
     try {
-      _checkDuplicateDeclarationInStatements(node.statements);
+      _duplicateDefinitionVerifier.checkStatements(node.statements);
       super.visitBlock(node);
     } finally {
       _hiddenElements = _hiddenElements.outerElements;
@@ -510,7 +516,7 @@
 
   @override
   void visitCatchClause(CatchClause node) {
-    _checkDuplicateDefinitionInCatchClause(node);
+    _duplicateDefinitionVerifier.checkCatchClause(node);
     bool previousIsInCatchClause = _isInCatchClause;
     try {
       _isInCatchClause = true;
@@ -530,7 +536,7 @@
       _enclosingClass = AbstractClassElementImpl.getImpl(node.declaredElement);
 
       List<ClassMember> members = node.members;
-      _checkDuplicateClassMembers(members);
+      _duplicateDefinitionVerifier.checkClass(node);
       _checkForBuiltInIdentifierAsName(
           node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForMemberWithClassName();
@@ -588,7 +594,7 @@
   @override
   void visitCompilationUnit(CompilationUnit node) {
     _featureSet = node.featureSet;
-    _checkDuplicateUnitMembers(node);
+    _duplicateDefinitionVerifier.checkUnit(node);
     _checkForDeferredPrefixCollisions(node);
     super.visitCompilationUnit(node);
     _featureSet = null;
@@ -678,7 +684,7 @@
     ClassElement outerEnum = _enclosingEnum;
     try {
       _enclosingEnum = node.declaredElement;
-      _checkDuplicateEnumMembers(node);
+      _duplicateDefinitionVerifier.checkEnum(node);
       super.visitEnumDeclaration(node);
     } finally {
       _enclosingEnum = outerEnum;
@@ -726,6 +732,8 @@
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     _enclosingExtension = node.declaredElement;
+    _duplicateDefinitionVerifier.checkExtension(node);
+    _checkForMismatchedAccessorTypesInExtension(node);
     super.visitExtensionDeclaration(node);
     _enclosingExtension = null;
   }
@@ -795,7 +803,7 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    _checkDuplicateDefinitionInParameterList(node);
+    _duplicateDefinitionVerifier.checkParameters(node);
     _checkUseOfCovariantInParameters(node);
     _checkUseOfDefaultValuesInParameters(node);
     super.visitFormalParameterList(node);
@@ -807,7 +815,7 @@
       _checkForNonBoolCondition(node.condition);
     }
     if (node.variables != null) {
-      _checkDuplicateVariables(node.variables);
+      _duplicateDefinitionVerifier.checkForVariables(node.variables);
     }
     super.visitForPartsWithDeclarations(node);
   }
@@ -880,12 +888,11 @@
   @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     Expression functionExpression = node.function;
+
     if (functionExpression is ExtensionOverride) {
-      // TODO(brianwilkerson) Update `_checkTypeArguments` to handle extension
-      //  overrides.
-//      _checkTypeArguments(node);
       return super.visitFunctionExpressionInvocation(node);
     }
+
     DartType expressionType = functionExpression.staticType;
     if (!_checkForNullableDereference(functionExpression) &&
         !_checkForUseOfVoidResult(functionExpression) &&
@@ -896,9 +903,8 @@
           StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
           functionExpression);
     } else if (expressionType is FunctionType) {
-      _checkTypeArguments(node);
+      _typeArgumentsVerifier.checkFunctionExpressionInvocation(node);
     }
-    _checkForImplicitDynamicInvoke(node);
     _checkForNullableDereference(functionExpression);
     _requiredParametersVerifier.visitFunctionExpressionInvocation(node);
     super.visitFunctionExpressionInvocation(node);
@@ -1047,19 +1053,7 @@
 
   @override
   void visitListLiteral(ListLiteral node) {
-    TypeArgumentList typeArguments = node.typeArguments;
-    if (typeArguments != null) {
-      if (node.isConst) {
-        NodeList<TypeAnnotation> arguments = typeArguments.arguments;
-        if (arguments.isNotEmpty) {
-          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
-              CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
-        }
-      }
-      _checkTypeArgumentCount(typeArguments, 1,
-          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
-    }
-    _checkForImplicitDynamicTypedLiteral(node);
+    _typeArgumentsVerifier.checkListLiteral(node);
     _checkForListElementTypeNotAssignable(node);
 
     super.visitListLiteral(node);
@@ -1101,14 +1095,14 @@
     if (target != null) {
       ClassElement typeReference = ElementResolver.getTypeReference(target);
       _checkForStaticAccessToInstanceMember(typeReference, methodName);
-      _checkForInstanceAccessToStaticMember(typeReference, methodName);
+      _checkForInstanceAccessToStaticMember(
+          typeReference, node.target, methodName);
       _checkForUnnecessaryNullAware(target, node.operator);
     } else {
       _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
       _checkForNullableDereference(node.function);
     }
-    _checkTypeArguments(node);
-    _checkForImplicitDynamicInvoke(node);
+    _typeArgumentsVerifier.checkMethodInvocation(node);
     _checkForNullableDereference(methodName);
     _requiredParametersVerifier.visitMethodInvocation(node);
     if (node.operator?.type != TokenType.QUESTION_PERIOD &&
@@ -1127,7 +1121,7 @@
       _enclosingClass = AbstractClassElementImpl.getImpl(node.declaredElement);
 
       List<ClassMember> members = node.members;
-      _checkDuplicateClassMembers(members);
+      _duplicateDefinitionVerifier.checkMixin(node);
       _checkForBuiltInIdentifierAsName(
           node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForMemberWithClassName();
@@ -1189,7 +1183,7 @@
           ElementResolver.getTypeReference(node.prefix);
       SimpleIdentifier name = node.identifier;
       _checkForStaticAccessToInstanceMember(typeReference, name);
-      _checkForInstanceAccessToStaticMember(typeReference, name);
+      _checkForInstanceAccessToStaticMember(typeReference, node.prefix, name);
     }
     String property = node.identifier.name;
     if (node.staticElement is ExecutableElement &&
@@ -1222,7 +1216,8 @@
         ElementResolver.getTypeReference(node.realTarget);
     SimpleIdentifier propertyName = node.propertyName;
     _checkForStaticAccessToInstanceMember(typeReference, propertyName);
-    _checkForInstanceAccessToStaticMember(typeReference, propertyName);
+    _checkForInstanceAccessToStaticMember(
+        typeReference, node.target, propertyName);
     if (node.operator?.type != TokenType.QUESTION_PERIOD &&
         !_objectPropertyNames.contains(propertyName.name)) {
       _checkForNullableDereference(node.target);
@@ -1262,35 +1257,12 @@
 
   @override
   void visitSetOrMapLiteral(SetOrMapLiteral node) {
-    TypeArgumentList typeArguments = node.typeArguments;
     if (node.isMap) {
-      if (typeArguments != null) {
-        NodeList<TypeAnnotation> arguments = typeArguments.arguments;
-        if (node.isConst) {
-          if (arguments.isNotEmpty) {
-            _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
-                CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
-          }
-        }
-        _checkTypeArgumentCount(typeArguments, 2,
-            StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
-      }
-      _checkForImplicitDynamicTypedLiteral(node);
+      _typeArgumentsVerifier.checkMapLiteral(node);
       _checkForMapTypeNotAssignable(node);
       _checkForNonConstMapAsExpressionStatement3(node);
     } else if (node.isSet) {
-      if (typeArguments != null) {
-        if (node.isConst) {
-          NodeList<TypeAnnotation> arguments = typeArguments.arguments;
-          if (arguments.isNotEmpty) {
-            _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
-                CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET);
-          }
-        }
-        _checkTypeArgumentCount(typeArguments, 1,
-            StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
-      }
-      _checkForImplicitDynamicTypedLiteral(node);
+      _typeArgumentsVerifier.checkSetLiteral(node);
       _checkForSetElementTypeNotAssignable3(node);
     }
     super.visitSetOrMapLiteral(node);
@@ -1348,13 +1320,13 @@
 
   @override
   void visitSwitchCase(SwitchCase node) {
-    _checkDuplicateDeclarationInStatements(node.statements);
+    _duplicateDefinitionVerifier.checkStatements(node.statements);
     super.visitSwitchCase(node);
   }
 
   @override
   void visitSwitchDefault(SwitchDefault node) {
-    _checkDuplicateDeclarationInStatements(node.statements);
+    _duplicateDefinitionVerifier.checkStatements(node.statements);
     super.visitSwitchDefault(node);
   }
 
@@ -1398,13 +1370,7 @@
 
   @override
   void visitTypeName(TypeName node) {
-    _checkForTypeArgumentNotMatchingBounds(node);
-    if (node.parent is ConstructorName &&
-        node.parent.parent is InstanceCreationExpression) {
-      _checkForInferenceFailureOnInstanceCreation(node, node.parent.parent);
-    } else {
-      _checkForRawTypeName(node);
-    }
+    _typeArgumentsVerifier.checkTypeName(node);
     super.visitTypeName(node);
   }
 
@@ -1422,7 +1388,7 @@
 
   @override
   void visitTypeParameterList(TypeParameterList node) {
-    _checkDuplicateDefinitionInTypeParameterList(node);
+    _duplicateDefinitionVerifier.checkTypeParameters(node);
     super.visitTypeParameterList(node);
   }
 
@@ -1554,338 +1520,6 @@
   }
 
   /**
-   * Check that there are no members with the same name.
-   */
-  void _checkDuplicateClassMembers(List<ClassMember> members) {
-    Set<String> constructorNames = new HashSet<String>();
-    Map<String, Element> instanceGetters = new HashMap<String, Element>();
-    Map<String, Element> instanceSetters = new HashMap<String, Element>();
-    Map<String, Element> staticGetters = new HashMap<String, Element>();
-    Map<String, Element> staticSetters = new HashMap<String, Element>();
-
-    for (ClassMember member in members) {
-      if (member is ConstructorDeclaration) {
-        var name = member.name?.name ?? '';
-        if (!constructorNames.add(name)) {
-          if (name.isEmpty) {
-            _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, member);
-          } else {
-            _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
-                member,
-                [name]);
-          }
-        }
-      } else if (member is FieldDeclaration) {
-        for (VariableDeclaration field in member.fields.variables) {
-          SimpleIdentifier identifier = field.name;
-          _checkDuplicateIdentifier(
-            member.isStatic ? staticGetters : instanceGetters,
-            identifier,
-            setterScope: member.isStatic ? staticSetters : instanceSetters,
-          );
-        }
-      } else if (member is MethodDeclaration) {
-        _checkDuplicateIdentifier(
-          member.isStatic ? staticGetters : instanceGetters,
-          member.name,
-          setterScope: member.isStatic ? staticSetters : instanceSetters,
-        );
-      }
-    }
-
-    // Check for local static members conflicting with local instance members.
-    for (ClassMember member in members) {
-      if (member is ConstructorDeclaration) {
-        if (member.name != null) {
-          String name = member.name.name;
-          var staticMember = staticGetters[name] ?? staticSetters[name];
-          if (staticMember != null) {
-            if (staticMember is PropertyAccessorElement) {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
-                member.name,
-                [name],
-              );
-            } else {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
-                member.name,
-                [name],
-              );
-            }
-          }
-        }
-      } else if (member is FieldDeclaration) {
-        if (member.isStatic) {
-          for (VariableDeclaration field in member.fields.variables) {
-            SimpleIdentifier identifier = field.name;
-            String name = identifier.name;
-            if (instanceGetters.containsKey(name) ||
-                instanceSetters.containsKey(name)) {
-              String className = _enclosingClass.displayName;
-              _errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-                  identifier,
-                  [className, name, className]);
-            }
-          }
-        }
-      } else if (member is MethodDeclaration) {
-        if (member.isStatic) {
-          SimpleIdentifier identifier = member.name;
-          String name = identifier.name;
-          if (instanceGetters.containsKey(name) ||
-              instanceSetters.containsKey(name)) {
-            String className = identifier.staticElement.enclosingElement.name;
-            _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-                identifier,
-                [className, name, className]);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Check that all of the parameters have unique names.
-   */
-  void _checkDuplicateDeclarationInStatements(List<Statement> statements) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (Statement statement in statements) {
-      if (statement is VariableDeclarationStatement) {
-        for (VariableDeclaration variable in statement.variables.variables) {
-          _checkDuplicateIdentifier(definedNames, variable.name);
-        }
-      } else if (statement is FunctionDeclarationStatement) {
-        _checkDuplicateIdentifier(
-            definedNames, statement.functionDeclaration.name);
-      }
-    }
-  }
-
-  /**
-   * Check that the exception and stack trace parameters have different names.
-   */
-  void _checkDuplicateDefinitionInCatchClause(CatchClause node) {
-    SimpleIdentifier exceptionParameter = node.exceptionParameter;
-    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
-    if (exceptionParameter != null && stackTraceParameter != null) {
-      String exceptionName = exceptionParameter.name;
-      if (exceptionName == stackTraceParameter.name) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.DUPLICATE_DEFINITION,
-            stackTraceParameter,
-            [exceptionName]);
-      }
-    }
-  }
-
-  /**
-   * Check that all of the parameters have unique names.
-   */
-  void _checkDuplicateDefinitionInParameterList(FormalParameterList node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (FormalParameter parameter in node.parameters) {
-      SimpleIdentifier identifier = parameter.identifier;
-      if (identifier != null) {
-        // The identifier can be null if this is a parameter list for a generic
-        // function type.
-        _checkDuplicateIdentifier(definedNames, identifier);
-      }
-    }
-  }
-
-  /**
-   * Check that all of the parameters have unique names.
-   */
-  void _checkDuplicateDefinitionInTypeParameterList(TypeParameterList node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (TypeParameter parameter in node.typeParameters) {
-      _checkDuplicateIdentifier(definedNames, parameter.name);
-    }
-  }
-
-  /**
-   * Check that there are no members with the same name.
-   */
-  void _checkDuplicateEnumMembers(EnumDeclaration node) {
-    ClassElement element = node.declaredElement;
-
-    Map<String, Element> instanceGetters = new HashMap<String, Element>();
-    Map<String, Element> staticGetters = new HashMap<String, Element>();
-
-    String indexName = 'index';
-    String valuesName = 'values';
-    instanceGetters[indexName] = element.getGetter(indexName);
-    staticGetters[valuesName] = element.getGetter(valuesName);
-
-    for (EnumConstantDeclaration constant in node.constants) {
-      _checkDuplicateIdentifier(staticGetters, constant.name);
-    }
-
-    for (EnumConstantDeclaration constant in node.constants) {
-      SimpleIdentifier identifier = constant.name;
-      String name = identifier.name;
-      if (instanceGetters.containsKey(name)) {
-        String enumName = element.displayName;
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
-            identifier,
-            [enumName, name, enumName]);
-      }
-    }
-  }
-
-  /**
-   * Check whether the given [element] defined by the [identifier] is already
-   * in one of the scopes - [getterScope] or [setterScope], and produce an
-   * error if it is.
-   */
-  void _checkDuplicateIdentifier(
-      Map<String, Element> getterScope, SimpleIdentifier identifier,
-      {Element element, Map<String, Element> setterScope}) {
-    element ??= identifier.staticElement;
-
-    // Fields define getters and setters, so check them separately.
-    if (element is PropertyInducingElement) {
-      _checkDuplicateIdentifier(getterScope, identifier,
-          element: element.getter, setterScope: setterScope);
-      if (!element.isConst && !element.isFinal) {
-        _checkDuplicateIdentifier(getterScope, identifier,
-            element: element.setter, setterScope: setterScope);
-      }
-      return;
-    }
-
-    ErrorCode getError(Element previous, Element current) {
-      if (previous is PrefixElement) {
-        return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
-      }
-      return CompileTimeErrorCode.DUPLICATE_DEFINITION;
-    }
-
-    bool isGetterSetterPair(Element a, Element b) {
-      if (a is PropertyAccessorElement && b is PropertyAccessorElement) {
-        return a.isGetter && b.isSetter || a.isSetter && b.isGetter;
-      }
-      return false;
-    }
-
-    String name = identifier.name;
-    if (element is MethodElement && element.isOperator && name == '-') {
-      if (element.parameters.isEmpty) {
-        name = 'unary-';
-      }
-    }
-
-    Element previous = getterScope[name];
-    if (previous != null) {
-      if (isGetterSetterPair(element, previous)) {
-        // OK
-      } else {
-        _errorReporter.reportErrorForNode(
-          getError(previous, element),
-          identifier,
-          [name],
-        );
-      }
-    } else {
-      getterScope[name] = element;
-    }
-
-    if (element is PropertyAccessorElement && element.isSetter) {
-      previous = setterScope[name];
-      if (previous != null) {
-        _errorReporter.reportErrorForNode(
-          getError(previous, element),
-          identifier,
-          [name],
-        );
-      } else {
-        setterScope[name] = element;
-      }
-    }
-  }
-
-  /**
-   * Check that there are no members with the same name.
-   */
-  void _checkDuplicateUnitMembers(CompilationUnit node) {
-    Map<String, Element> definedGetters = new HashMap<String, Element>();
-    Map<String, Element> definedSetters = new HashMap<String, Element>();
-
-    void addWithoutChecking(CompilationUnitElement element) {
-      for (PropertyAccessorElement accessor in element.accessors) {
-        String name = accessor.name;
-        if (accessor.isSetter) {
-          name += '=';
-        }
-        definedGetters[name] = accessor;
-      }
-      for (ClassElement type in element.enums) {
-        definedGetters[type.name] = type;
-      }
-      for (FunctionElement function in element.functions) {
-        definedGetters[function.name] = function;
-      }
-      for (FunctionTypeAliasElement alias in element.functionTypeAliases) {
-        definedGetters[alias.name] = alias;
-      }
-      for (TopLevelVariableElement variable in element.topLevelVariables) {
-        definedGetters[variable.name] = variable;
-        if (!variable.isFinal && !variable.isConst) {
-          definedGetters[variable.name + '='] = variable;
-        }
-      }
-      for (ClassElement type in element.types) {
-        definedGetters[type.name] = type;
-      }
-    }
-
-    for (ImportElement importElement in _currentLibrary.imports) {
-      PrefixElement prefix = importElement.prefix;
-      if (prefix != null) {
-        definedGetters[prefix.name] = prefix;
-      }
-    }
-    CompilationUnitElement element = node.declaredElement;
-    if (element != _currentLibrary.definingCompilationUnit) {
-      addWithoutChecking(_currentLibrary.definingCompilationUnit);
-      for (CompilationUnitElement part in _currentLibrary.parts) {
-        if (element == part) {
-          break;
-        }
-        addWithoutChecking(part);
-      }
-    }
-    for (CompilationUnitMember member in node.declarations) {
-      if (member is NamedCompilationUnitMember) {
-        _checkDuplicateIdentifier(definedGetters, member.name,
-            setterScope: definedSetters);
-      } else if (member is TopLevelVariableDeclaration) {
-        for (VariableDeclaration variable in member.variables.variables) {
-          _checkDuplicateIdentifier(definedGetters, variable.name,
-              setterScope: definedSetters);
-        }
-      }
-    }
-  }
-
-  /**
-   * Check that the given list of variable declarations does not define multiple
-   * variables of the same name.
-   */
-  void _checkDuplicateVariables(VariableDeclarationList node) {
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    for (VariableDeclaration variable in node.variables) {
-      _checkDuplicateIdentifier(definedNames, variable.name);
-    }
-  }
-
-  /**
    * Check that return statements without expressions are not in a generative
    * constructor and the return type is not assignable to `null`; that is, we
    * don't have `return;` if the enclosing method has a non-void containing
@@ -3574,50 +3208,6 @@
     }
   }
 
-  void _checkForImplicitDynamicInvoke(InvocationExpression node) {
-    if (_options.implicitDynamic ||
-        node == null ||
-        node.typeArguments != null) {
-      return;
-    }
-    DartType invokeType = node.staticInvokeType;
-    DartType declaredType = node.function.staticType;
-    if (invokeType is FunctionType &&
-        declaredType is FunctionType &&
-        declaredType.typeFormals.isNotEmpty) {
-      List<DartType> typeArgs = node.typeArgumentTypes;
-      if (typeArgs.any((t) => t.isDynamic)) {
-        // Issue an error depending on what we're trying to call.
-        Expression function = node.function;
-        if (function is Identifier) {
-          Element element = function.staticElement;
-          if (element is MethodElement) {
-            _errorReporter.reportErrorForNode(
-                StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
-                node.function,
-                [element.displayName, element.typeParameters.join(', ')]);
-            return;
-          }
-
-          if (element is FunctionElement) {
-            _errorReporter.reportErrorForNode(
-                StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
-                node.function,
-                [element.displayName, element.typeParameters.join(', ')]);
-            return;
-          }
-        }
-
-        // The catch all case if neither of those matched.
-        // For example, invoking a function expression.
-        _errorReporter.reportErrorForNode(
-            StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
-            node.function,
-            [declaredType]);
-      }
-    }
-  }
-
   void _checkForImplicitDynamicReturn(
       AstNode functionName, ExecutableElement element) {
     if (_options.implicitDynamic) {
@@ -3649,21 +3239,6 @@
     }
   }
 
-  void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
-    if (_options.implicitDynamic || node.typeArguments != null) {
-      return;
-    }
-    DartType type = node.staticType;
-    // It's an error if either the key or value was inferred as dynamic.
-    if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
-      // TODO(brianwilkerson) Add StrongModeCode.IMPLICIT_DYNAMIC_SET_LITERAL
-      ErrorCode errorCode = node is ListLiteral
-          ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
-          : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
-      _errorReporter.reportErrorForNode(errorCode, node);
-    }
-  }
-
   /**
    * Verify that if the given [identifier] is part of a constructor initializer,
    * then it does not implicitly reference 'this' expression.
@@ -3799,27 +3374,6 @@
         [directive.uri.stringValue]);
   }
 
-  /// Checks a type on an instance creation expression for an inference
-  /// failure, and reports the appropriate error if
-  /// [AnalysisOptionsImpl.strictInference] is set.
-  ///
-  /// This checks if [node] refers to a generic type and does not have explicit
-  /// or inferred type arguments. When that happens, it reports a
-  /// HintMode.INFERENCE_FAILURE_ON_INSTANCE_CREATION error.
-  void _checkForInferenceFailureOnInstanceCreation(
-      TypeName node, InstanceCreationExpression inferenceContextNode) {
-    if (!_options.strictInference || node == null) return;
-    if (node.typeArguments != null) {
-      // Type has explicit type arguments.
-      return;
-    }
-    if (_isMissingTypeArguments(
-        node, node.type, node.name.staticElement, inferenceContextNode)) {
-      _errorReporter.reportErrorForNode(
-          HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, node, [node.type]);
-    }
-  }
-
   /**
    * Check that the given [typeReference] is not a type reference and that then
    * the [name] is reference to an instance member.
@@ -3827,25 +3381,39 @@
    * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER].
    */
   void _checkForInstanceAccessToStaticMember(
-      ClassElement typeReference, SimpleIdentifier name) {
-    // OK, in comment
+      ClassElement typeReference, Expression target, SimpleIdentifier name) {
     if (_isInComment) {
-      return;
-    }
-    // OK, target is a type
-    if (typeReference != null) {
+      // OK, in comment
       return;
     }
     // prepare member Element
     Element element = name.staticElement;
     if (element is ExecutableElement) {
-      // OK, top-level element
-      if (element.enclosingElement is! ClassElement) {
+      if (!element.isStatic) {
+        // OK, instance member
         return;
       }
-      // OK, instance member
-      if (!element.isStatic) {
-        return;
+      Element enclosingElement = element.enclosingElement;
+      if (enclosingElement is ExtensionElement) {
+        if (target is ExtensionOverride) {
+          // OK, target is an extension override
+          return;
+        } else if (target is SimpleIdentifier &&
+            target.staticElement is ExtensionElement) {
+          return;
+        } else if (target is PrefixedIdentifier &&
+            target.staticElement is ExtensionElement) {
+          return;
+        }
+      } else {
+        if (typeReference != null) {
+          // OK, target is a type
+          return;
+        }
+        if (enclosingElement is! ClassElement) {
+          // OK, top-level element
+          return;
+        }
       }
       _errorReporter.reportErrorForNode(
           StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
@@ -3982,21 +3550,6 @@
     }
   }
 
-  /**
-   * Checks to ensure that the given list of type [arguments] does not have a
-   * type parameter as a type argument. The [errorCode] is either
-   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
-   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP].
-   */
-  void _checkForInvalidTypeArgumentInConstTypedLiteral(
-      NodeList<TypeAnnotation> arguments, ErrorCode errorCode) {
-    for (TypeAnnotation type in arguments) {
-      if (type is TypeName && type.type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(errorCode, type, [type.name]);
-      }
-    }
-  }
-
   void _checkForListConstructor(
       InstanceCreationExpression node, InterfaceType type) {
     if (!_isNonNullable) return;
@@ -4160,6 +3713,36 @@
   }
 
   /**
+   * Check whether all similarly named accessors have consistent types.
+   */
+  void _checkForMismatchedAccessorTypesInExtension(
+      ExtensionDeclaration extension) {
+    for (ClassMember member in extension.members) {
+      if (member is MethodDeclaration && member.isGetter) {
+        PropertyAccessorElement getterElement =
+            member.declaredElement as PropertyAccessorElement;
+        PropertyAccessorElement setterElement =
+            getterElement.correspondingSetter;
+        if (setterElement != null) {
+          DartType getterType = _getGetterType(getterElement);
+          DartType setterType = _getSetterType(setterElement);
+          if (setterType != null &&
+              getterType != null &&
+              !_typeSystem.isAssignableTo(getterType, setterType,
+                  featureSet: _featureSet)) {
+            SimpleIdentifier nameNode = member.name;
+            String name = nameNode.name;
+            _errorReporter.reportTypeErrorForNode(
+                StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
+                nameNode,
+                [name, getterType, setterType, name]);
+          }
+        }
+      }
+    }
+  }
+
+  /**
    * Check to make sure that the given switch [statement] whose static type is
    * an enum type either have a default case or include all of the enum
    * constants.
@@ -4928,45 +4511,6 @@
         CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
   }
 
-  /// Checks a type annotation for a raw generic type, and reports the
-  /// appropriate error if [AnalysisOptionsImpl.strictRawTypes] is set.
-  ///
-  /// This checks if [node] refers to a generic type and does not have explicit
-  /// or inferred type arguments. When that happens, it reports error code
-  /// [StrongModeCode.STRICT_RAW_TYPE].
-  void _checkForRawTypeName(TypeName node) {
-    AstNode parentEscapingTypeArguments(TypeName node) {
-      AstNode parent = node.parent;
-      while (parent is TypeArgumentList || parent is TypeName) {
-        if (parent.parent == null) {
-          return parent;
-        }
-        parent = parent.parent;
-      }
-      return parent;
-    }
-
-    if (!_options.strictRawTypes || node == null) return;
-    if (node.typeArguments != null) {
-      // Type has explicit type arguments.
-      return;
-    }
-    if (_isMissingTypeArguments(
-        node, node.type, node.name.staticElement, null)) {
-      AstNode unwrappedParent = parentEscapingTypeArguments(node);
-      if (unwrappedParent is AsExpression) {
-        _errorReporter.reportErrorForNode(
-            HintCode.STRICT_RAW_TYPE_IN_AS, node, [node.type]);
-      } else if (unwrappedParent is IsExpression) {
-        _errorReporter.reportErrorForNode(
-            HintCode.STRICT_RAW_TYPE_IN_IS, node, [node.type]);
-      } else {
-        _errorReporter
-            .reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [node.type]);
-      }
-    }
-  }
-
   /**
    * Check whether the given constructor [declaration] is the redirecting
    * generative constructor and references itself directly or indirectly. The
@@ -5416,87 +4960,6 @@
     }
   }
 
-  /**
-   * Verify that the type arguments in the given [typeName] are all within
-   * their bounds.
-   */
-  void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
-    // prepare Type
-    DartType type = typeName.type;
-    if (type == null) {
-      return;
-    }
-    if (type is ParameterizedType) {
-      var element = typeName.name.staticElement;
-      // prepare type parameters
-      List<TypeParameterElement> parameterElements;
-      if (element is ClassElement) {
-        parameterElements = element.typeParameters;
-      } else if (element is GenericTypeAliasElement) {
-        parameterElements = element.typeParameters;
-      } else if (element is GenericFunctionTypeElement) {
-        // TODO(paulberry): it seems like either this case or the one above
-        // should be unnecessary.
-        FunctionTypeAliasElement typedefElement = element.enclosingElement;
-        parameterElements = typedefElement.typeParameters;
-      } else if (type is FunctionType) {
-        parameterElements = type.typeFormals;
-      } else {
-        // There are no other kinds of parameterized types.
-        throw new UnimplementedError(
-            'Unexpected element associated with parameterized type: '
-            '${element.runtimeType}');
-      }
-      var parameterTypes =
-          parameterElements.map<DartType>((p) => p.type).toList();
-      List<DartType> arguments = type.typeArguments;
-      // iterate over each bounded type parameter and corresponding argument
-      NodeList<TypeAnnotation> argumentNodes =
-          typeName.typeArguments?.arguments;
-      var typeArguments = type.typeArguments;
-      int loopThroughIndex =
-          math.min(typeArguments.length, parameterElements.length);
-      bool shouldSubstitute =
-          arguments.isNotEmpty && arguments.length == parameterTypes.length;
-      for (int i = 0; i < loopThroughIndex; i++) {
-        DartType argType = typeArguments[i];
-        TypeAnnotation argumentNode =
-            argumentNodes != null && i < argumentNodes.length
-                ? argumentNodes[i]
-                : typeName;
-        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-            argumentNode,
-          );
-          continue;
-        }
-        DartType boundType = parameterElements[i].bound;
-        if (argType != null && boundType != null) {
-          if (shouldSubstitute) {
-            boundType = boundType.substitute2(arguments, parameterTypes);
-          }
-
-          if (!_typeSystem.isSubtypeOf(argType, boundType)) {
-            if (_shouldAllowSuperBoundedTypes(typeName)) {
-              var replacedType =
-                  (argType as TypeImpl).replaceTopAndBottom(_typeProvider);
-              if (!identical(replacedType, argType) &&
-                  _typeSystem.isSubtypeOf(replacedType, boundType)) {
-                // Bound is satisfied under super-bounded rules, so we're ok.
-                continue;
-              }
-            }
-            _errorReporter.reportTypeErrorForNode(
-                CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
-                argumentNode,
-                [argType, boundType]);
-          }
-        }
-      }
-    }
-  }
-
   void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
       var element = identifier.staticElement;
@@ -6013,75 +5476,6 @@
     }
   }
 
-  /**
-   * Verify that the given list of [typeArguments] contains exactly the
-   * [expectedCount] of elements, reporting an error with the given [errorCode]
-   * if not.
-   */
-  void _checkTypeArgumentCount(
-      TypeArgumentList typeArguments, int expectedCount, ErrorCode errorCode) {
-    int actualCount = typeArguments.arguments.length;
-    if (actualCount != expectedCount) {
-      _errorReporter
-          .reportErrorForNode(errorCode, typeArguments, [actualCount]);
-    }
-  }
-
-  /**
-   * Verify that the given [typeArguments] are all within their bounds, as
-   * defined by the given [element].
-   */
-  void _checkTypeArguments(InvocationExpression node) {
-    NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments;
-    if (typeArgumentList == null) {
-      return;
-    }
-
-    var genericType = node.function.staticType;
-    var instantiatedType = node.staticInvokeType;
-    if (genericType is FunctionType && instantiatedType is FunctionType) {
-      var fnTypeParams =
-          TypeParameterTypeImpl.getTypes(genericType.typeFormals);
-      var typeArgs = typeArgumentList.map((t) => t.type).toList();
-
-      // If the amount mismatches, clean up the lists to be substitutable. The
-      // mismatch in size is reported elsewhere, but we must successfully
-      // perform substitution to validate bounds on mismatched lists.
-      final providedLength = math.min(typeArgs.length, fnTypeParams.length);
-      fnTypeParams = fnTypeParams.sublist(0, providedLength);
-      typeArgs = typeArgs.sublist(0, providedLength);
-
-      for (int i = 0; i < providedLength; i++) {
-        // Check the `extends` clause for the type parameter, if any.
-        //
-        // Also substitute to handle cases like this:
-        //
-        //     <TFrom, TTo extends TFrom>
-        //     <TFrom, TTo extends Iterable<TFrom>>
-        //     <T extends Clonable<T>>
-        //
-        DartType argType = typeArgs[i];
-
-        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
-            typeArgumentList[i],
-          );
-          continue;
-        }
-
-        DartType bound =
-            fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
-        if (!_typeSystem.isSubtypeOf(argType, bound)) {
-          _errorReporter.reportTypeErrorForNode(
-              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
-              typeArgumentList[i],
-              [argType, bound]);
-        }
-      }
-    }
-  }
-
   void _checkUseOfCovariantInParameters(FormalParameterList node) {
     AstNode parent = node.parent;
     if (_enclosingClass != null &&
@@ -6457,46 +5851,6 @@
     return false;
   }
 
-  /// Given a [node] without type arguments that refers to [element], issues
-  /// an error if [type] is a generic type, and the type arguments were not
-  /// supplied from inference or a non-dynamic default instantiation.
-  ///
-  /// This function is used by other node-specific type checking functions, and
-  /// should only be called when [node] has no explicit `typeArguments`.
-  ///
-  /// [inferenceContextNode] is the node that has the downwards context type,
-  /// if any. For example an [InstanceCreationExpression].
-  ///
-  /// This function will return false if any of the following are true:
-  ///
-  /// - [inferenceContextNode] has an inference context type that does not
-  ///   contain `?`
-  /// - [type] does not have any `dynamic` type arguments.
-  /// - the element is marked with `@optionalTypeArgs` from "package:meta".
-  bool _isMissingTypeArguments(AstNode node, DartType type, Element element,
-      Expression inferenceContextNode) {
-    // Check if this type has type arguments and at least one is dynamic.
-    // If so, we may need to issue a strict-raw-types error.
-    if (type is ParameterizedType &&
-        type.typeArguments.any((t) => t.isDynamic)) {
-      // If we have an inference context node, check if the type was inferred
-      // from it. Some cases will not have a context type, such as the type
-      // annotation `List` in `List list;`
-      if (inferenceContextNode != null) {
-        var contextType = InferenceContext.getContext(inferenceContextNode);
-        if (contextType != null && UnknownInferredType.isKnown(contextType)) {
-          // Type was inferred from downwards context: not an error.
-          return false;
-        }
-      }
-      if (element.hasOptionalTypeArgs) {
-        return false;
-      }
-      return true;
-    }
-    return false;
-  }
-
   /**
    * Return `true` if the given 'this' [expression] is in a valid context.
    */
@@ -6567,19 +5921,6 @@
     return null;
   }
 
-  /// Determines if the given [typeName] occurs in a context where super-bounded
-  /// types are allowed.
-  bool _shouldAllowSuperBoundedTypes(TypeName typeName) {
-    var parent = typeName.parent;
-    if (parent is ExtendsClause) return false;
-    if (parent is OnClause) return false;
-    if (parent is ClassTypeAlias) return false;
-    if (parent is WithClause) return false;
-    if (parent is ConstructorName) return false;
-    if (parent is ImplementsClause) return false;
-    return true;
-  }
-
   /**
    * Return [FieldElement]s that are declared in the [ClassDeclaration] with
    * the given [constructor], but are not initialized.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0310cdf..93ef44a 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -25,6 +25,7 @@
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/exit_detector.dart';
+import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
@@ -3050,6 +3051,9 @@
 
   final bool _uiAsCodeEnabled;
 
+  /// Helper for extension method resolution.
+  ExtensionMemberResolver extensionResolver;
+
   /// The object used to resolve the element associated with the current node.
   ElementResolver elementResolver;
 
@@ -3159,6 +3163,7 @@
             nameScope: nameScope) {
     this.typeSystem = definingLibrary.context.typeSystem;
     this._promoteManager = TypePromotionManager(typeSystem);
+    this.extensionResolver = ExtensionMemberResolver(this);
     this.elementResolver = new ElementResolver(this,
         reportConstEvaluationErrors: reportConstEvaluationErrors);
     bool strongModeHints = false;
@@ -3422,10 +3427,10 @@
       left?.accept(this);
 
       if (_flowAnalysis != null) {
-        flow?.logicalAnd_rightBegin(node, left);
+        flow?.logicalBinaryOp_rightBegin(left, isAnd: true);
         _flowAnalysis.checkUnreachableNode(right);
         right.accept(this);
-        flow?.logicalAnd_end(node, right);
+        flow?.logicalBinaryOp_end(node, right, isAnd: true);
       } else {
         _promoteManager.visitBinaryExpression_and_rhs(
           left,
@@ -3443,10 +3448,10 @@
 
       left?.accept(this);
 
-      flow?.logicalOr_rightBegin(node, left);
+      flow?.logicalBinaryOp_rightBegin(left, isAnd: false);
       _flowAnalysis?.checkUnreachableNode(right);
       right.accept(this);
-      flow?.logicalOr_end(node, right);
+      flow?.logicalBinaryOp_end(node, right, isAnd: false);
 
       node.accept(elementResolver);
     } else if (operator == TokenType.BANG_EQ || operator == TokenType.EQ_EQ) {
@@ -3605,7 +3610,7 @@
 
     if (_flowAnalysis != null) {
       if (flow != null) {
-        flow.conditional_thenBegin(node, condition);
+        flow.conditional_thenBegin(condition);
         _flowAnalysis.checkUnreachableNode(thenExpression);
       }
       thenExpression.accept(this);
@@ -3623,11 +3628,10 @@
     InferenceContext.setTypeFromNode(elseExpression, node);
 
     if (flow != null) {
-      var isBool = thenExpression.staticType.isDartCoreBool;
-      flow.conditional_elseBegin(node, thenExpression, isBool);
+      flow.conditional_elseBegin(thenExpression);
       _flowAnalysis.checkUnreachableNode(elseExpression);
       elseExpression.accept(this);
-      flow.conditional_end(node, elseExpression, isBool);
+      flow.conditional_end(node, elseExpression);
     } else {
       elseExpression.accept(this);
     }
@@ -3739,7 +3743,7 @@
     _flowAnalysis?.flow?.doStatement_conditionBegin();
     condition.accept(this);
 
-    _flowAnalysis?.flow?.doStatement_end(node, node.condition);
+    _flowAnalysis?.flow?.doStatement_end(node.condition);
   }
 
   @override
@@ -3825,6 +3829,18 @@
   }
 
   @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    node.extensionName.accept(this);
+    node.typeArguments?.accept(this);
+
+    ExtensionMemberResolver(this).setOverrideReceiverContextType(node);
+    node.argumentList.accept(this);
+
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+  }
+
+  @override
   void visitForElementInScope(ForElement node) {
     ForLoopParts forLoopParts = node.forLoopParts;
     if (forLoopParts is ForParts) {
@@ -5365,13 +5381,6 @@
           enclosingExtension = extensionElement;
           nameScope = new TypeParameterScope(nameScope, extensionElement);
           visitExtensionDeclarationInScope(node);
-          DartType extendedType = extensionElement.extendedType;
-          if (extendedType is InterfaceType) {
-            nameScope = new ClassScope(nameScope, extendedType.element);
-          } else if (extendedType is FunctionType) {
-            nameScope =
-                new ClassScope(nameScope, typeProvider.functionType.element);
-          }
           nameScope = ExtensionScope(nameScope, extensionElement);
           visitExtensionMembersInScope(node);
         } finally {
@@ -6204,8 +6213,9 @@
       }
     } else {
       if (element is GenericTypeAliasElementImpl) {
+        var ts = typeSystem as Dart2TypeSystem;
         List<DartType> typeArguments =
-            typeSystem.instantiateTypeFormalsToBounds(element.typeParameters);
+            ts.instantiateTypeFormalsToBounds2(element);
         type = GenericTypeAliasElementImpl.typeAfterSubstitution(
                 element, typeArguments) ??
             dynamicType;
@@ -6451,8 +6461,8 @@
       if (redirectedType != null) {
         typeArguments = redirectedType.typeArguments;
       } else {
-        var typeFormals = typeParameters;
-        typeArguments = typeSystem.instantiateTypeFormalsToBounds(typeFormals);
+        var ts = typeSystem as Dart2TypeSystem;
+        typeArguments = ts.instantiateTypeFormalsToBounds2(element);
       }
     }
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index c36e138..2dc19dc 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -479,8 +478,7 @@
 
   @override
   void visitExtensionOverride(ExtensionOverride node) {
-    var extensionResolver = ExtensionMemberResolver(_resolver);
-    extensionResolver.resolveOverride(node);
+    _resolver.extensionResolver.resolveOverride(node);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 6f89335..85a737b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -475,6 +475,31 @@
     return orderedArguments;
   }
 
+  /// Given the type defining [element], instantiate its type formals to
+  /// their bounds.
+  List<DartType> instantiateTypeFormalsToBounds2(Element element) {
+    List<TypeParameterElement> typeParameters;
+    if (element is ClassElement) {
+      typeParameters = element.typeParameters;
+    } else if (element is GenericTypeAliasElement) {
+      typeParameters = element.typeParameters;
+    } else {
+      throw StateError('Unexpected: $element');
+    }
+
+    if (typeParameters.isEmpty) {
+      return const <DartType>[];
+    }
+
+    if (AnalysisDriver.useSummary2) {
+      return typeParameters
+          .map((p) => (p as TypeParameterElementImpl).defaultType)
+          .toList();
+    } else {
+      return instantiateTypeFormalsToBounds(typeParameters);
+    }
+  }
+
   @override
   bool isAssignableTo(DartType fromType, DartType toType,
       {FeatureSet featureSet}) {
@@ -1081,8 +1106,9 @@
       var newTypeArgs = _transformList(
           type.typeArguments, (t) => _substituteType(t, lowerBound, visitType));
       if (identical(type.typeArguments, newTypeArgs)) return type;
-      return new InterfaceTypeImpl(
-          type.element, type.prunedTypedefs, type.nullabilitySuffix)
+      return new InterfaceTypeImpl(type.element,
+          prunedTypedefs: type.prunedTypedefs,
+          nullabilitySuffix: type.nullabilitySuffix)
         ..typeArguments = newTypeArgs;
     }
     if (type is FunctionType) {
@@ -1514,7 +1540,7 @@
   ///   - `GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>`
   ///   - `GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>`
   ///   - else `GLB(FutureOr<A>, B) == GLB(A, B)`
-  /// - `GLB(A, FutureOr<B>) ==  GLB(FutureOr<A>, B)` (defined above),
+  /// - `GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)` (defined above),
   /// - else `GLB(A, B) == Null`
   DartType _getGreatestLowerBound(DartType t1, DartType t2) {
     var result = _typeSystem.getGreatestLowerBound(t1, t2);
@@ -1540,7 +1566,7 @@
         return _getGreatestLowerBound(t1TypeArg, t2);
       }
       if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
-        // GLB(A, FutureOr<B>) ==  GLB(FutureOr<A>, B)
+        // GLB(A, FutureOr<B>) ==  GLB(FutureOr<B>, A)
         return _getGreatestLowerBound(t2, t1);
       }
       return typeProvider.nullType;
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 33dee1e..9a559a5 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -81,6 +81,12 @@
   bool get checkConstantUpdate2018 => _checkConstantUpdate2018 ??=
       !before_2_5_0.intersect(_versionConstraint).isEmpty;
 
+  /// Return `true` if references to the extension method features need to
+  /// be checked.
+  // TODO(brianwilkerson) Implement this as a version check when a version has
+  //  been selected.
+  bool get checkExtensionMethods => true;
+
   /// Return `true` if references to Future and Stream need to be checked.
   bool get checkFutureAndStream => _checkFutureAndStream ??=
       !before_2_1_0.intersect(_versionConstraint).isEmpty;
@@ -122,8 +128,10 @@
               operatorType == TokenType.CARET) &&
           (node as BinaryExpressionImpl).inConstantContext) {
         if (node.leftOperand.staticType.isDartCoreBool) {
-          _errorReporter.reportErrorForToken(HintCode.SDK_VERSION_BOOL_OPERATOR,
-              node.operator, [node.operator.lexeme]);
+          _errorReporter.reportErrorForToken(
+              HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
+              node.operator,
+              [node.operator.lexeme]);
         }
       } else if (operatorType == TokenType.EQ_EQ &&
           (node as BinaryExpressionImpl).inConstantContext) {
@@ -147,6 +155,24 @@
   }
 
   @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    if (checkExtensionMethods) {
+      _errorReporter.reportErrorForToken(
+          HintCode.SDK_VERSION_EXTENSION_METHODS, node.extensionKeyword);
+    }
+    super.visitExtensionDeclaration(node);
+  }
+
+  @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    if (checkExtensionMethods) {
+      _errorReporter.reportErrorForNode(
+          HintCode.SDK_VERSION_EXTENSION_METHODS, node.extensionName);
+    }
+    super.visitExtensionOverride(node);
+  }
+
+  @override
   void visitForElement(ForElement node) {
     _validateUiAsCode(node);
     _validateUiAsCodeInConstContext(node);
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 3b231d7..2ac377b 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -23598,6 +23598,7 @@
   List<int> _variantField_7;
   int _variantField_6;
   int _variantField_5;
+  String _variantField_10;
   int _variantField_1;
   List<String> _variantField_4;
   idl.LinkedNodeKind _kind;
@@ -23768,6 +23769,19 @@
   }
 
   @override
+  String get defaultFormalParameter_defaultValueCode {
+    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
+    return _variantField_10 ??= '';
+  }
+
+  /// If the parameter has a default value, the source text of the constant
+  /// expression in the default value.  Otherwise the empty string.
+  set defaultFormalParameter_defaultValueCode(String value) {
+    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
+    _variantField_10 = value;
+  }
+
+  @override
   int get directiveKeywordOffset {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -23923,9 +23937,11 @@
   UnlinkedInformativeDataBuilder.defaultFormalParameter({
     int codeLength,
     int codeOffset,
+    String defaultFormalParameter_defaultValueCode,
   })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
         _variantField_2 = codeLength,
-        _variantField_3 = codeOffset;
+        _variantField_3 = codeOffset,
+        _variantField_10 = defaultFormalParameter_defaultValueCode;
 
   UnlinkedInformativeDataBuilder.enumConstantDeclaration({
     int nameOffset,
@@ -24199,6 +24215,7 @@
       signature.addInt(this.kind == null ? 0 : this.kind.index);
       signature.addInt(this.codeLength ?? 0);
       signature.addInt(this.codeOffset ?? 0);
+      signature.addString(this.defaultFormalParameter_defaultValueCode ?? '');
     } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       signature.addInt(this.kind == null ? 0 : this.kind.index);
       signature.addInt(this.nameOffset ?? 0);
@@ -24383,10 +24400,14 @@
 
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_variantField_7;
+    fb.Offset offset_variantField_10;
     fb.Offset offset_variantField_4;
     if (!(_variantField_7 == null || _variantField_7.isEmpty)) {
       offset_variantField_7 = fbBuilder.writeListUint32(_variantField_7);
     }
+    if (_variantField_10 != null) {
+      offset_variantField_10 = fbBuilder.writeString(_variantField_10);
+    }
     if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
       offset_variantField_4 = fbBuilder.writeList(
           _variantField_4.map((b) => fbBuilder.writeString(b)).toList());
@@ -24413,6 +24434,9 @@
     if (_variantField_5 != null && _variantField_5 != 0) {
       fbBuilder.addUint32(5, _variantField_5);
     }
+    if (offset_variantField_10 != null) {
+      fbBuilder.addOffset(10, offset_variantField_10);
+    }
     if (_variantField_1 != null && _variantField_1 != 0) {
       fbBuilder.addUint32(1, _variantField_1);
     }
@@ -24450,6 +24474,7 @@
   List<int> _variantField_7;
   int _variantField_6;
   int _variantField_5;
+  String _variantField_10;
   int _variantField_1;
   List<String> _variantField_4;
   idl.LinkedNodeKind _kind;
@@ -24546,6 +24571,14 @@
   }
 
   @override
+  String get defaultFormalParameter_defaultValueCode {
+    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
+    _variantField_10 ??=
+        const fb.StringReader().vTableGet(_bc, _bcOffset, 10, '');
+    return _variantField_10;
+  }
+
+  @override
   int get directiveKeywordOffset {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -24650,6 +24683,9 @@
     if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (defaultFormalParameter_defaultValueCode != '')
+        _result["defaultFormalParameter_defaultValueCode"] =
+            defaultFormalParameter_defaultValueCode;
     }
     if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       if (nameOffset != 0) _result["nameOffset"] = nameOffset;
@@ -24820,6 +24856,8 @@
       return {
         "codeLength": codeLength,
         "codeOffset": codeOffset,
+        "defaultFormalParameter_defaultValueCode":
+            defaultFormalParameter_defaultValueCode,
         "kind": kind,
       };
     }
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index cfb2b67..4ce0eca 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -2837,6 +2837,10 @@
 
   variantField_5:uint (id: 5);
 
+  /// If the parameter has a default value, the source text of the constant
+  /// expression in the default value.  Otherwise the empty string.
+  variantField_10:string (id: 10);
+
   variantField_1:uint (id: 1);
 
   variantField_4:[string] (id: 4);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 42e5b1f..5e71b0e 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -3703,6 +3703,11 @@
   @VariantId(5, variant: LinkedNodeKind.constructorDeclaration)
   int get constructorDeclaration_returnTypeOffset;
 
+  /// If the parameter has a default value, the source text of the constant
+  /// expression in the default value.  Otherwise the empty string.
+  @VariantId(10, variant: LinkedNodeKind.defaultFormalParameter)
+  String get defaultFormalParameter_defaultValueCode;
+
   @VariantId(1, variantList: [
     LinkedNodeKind.exportDirective,
     LinkedNodeKind.importDirective,
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 62f79f8..9068bfd 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
@@ -88,16 +89,22 @@
   List<int> build() {
     librarySources.forEach(_addLibrary);
 
-    Map<String, LinkedLibraryBuilder> map = link(libraryUris, (uri) {
-      throw new StateError('Unexpected call to GetDependencyCallback($uri).');
-    }, (uri) {
-      UnlinkedUnit unlinked = unlinkedMap[uri];
-      if (unlinked == null) {
-        throw new StateError('Unable to find unresolved unit $uri.');
-      }
-      return unlinked;
-    }, DeclaredVariables(), context.analysisOptions);
-    map.forEach(bundleAssembler.addLinkedLibrary);
+    var useSummary2 = AnalysisDriver.useSummary2;
+    try {
+      AnalysisDriver.useSummary2 = false;
+      Map<String, LinkedLibraryBuilder> map = link(libraryUris, (uri) {
+        throw new StateError('Unexpected call to GetDependencyCallback($uri).');
+      }, (uri) {
+        UnlinkedUnit unlinked = unlinkedMap[uri];
+        if (unlinked == null) {
+          throw new StateError('Unable to find unresolved unit $uri.');
+        }
+        return unlinked;
+      }, DeclaredVariables(), context.analysisOptions);
+      map.forEach(bundleAssembler.addLinkedLibrary);
+    } finally {
+      AnalysisDriver.useSummary2 = useSummary2;
+    }
 
     _link2();
 
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index 121c99f..1bf085d 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -98,11 +98,13 @@
 
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    var defaultValueCode = node.defaultValue?.toSource();
     setData(
       node,
       UnlinkedInformativeDataBuilder.defaultFormalParameter(
         codeOffset: node.offset,
         codeLength: node.length,
+        defaultFormalParameter_defaultValueCode: defaultValueCode,
       ),
     );
 
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index 4bea1b2..97fd87a 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -890,6 +890,21 @@
     return node.offset;
   }
 
+  static String getDefaultValueCode(
+    LinkedUnitContext context,
+    DefaultFormalParameter node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null) {
+      if (lazy.data.defaultFormalParameter_defaultValue == null) {
+        return null;
+      }
+      return context.getDefaultValueCodeData(lazy.data);
+    } else {
+      return node.defaultValue?.toSource();
+    }
+  }
+
   static DartType getType(
     AstBinaryReader reader,
     FormalParameter node,
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 15c7bf2..25e5b7f 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -76,6 +76,14 @@
     var library = libraryMap[uriStr];
     if (library == null) return const [];
 
+    // Ask for source to trigger dependency tracking.
+    //
+    // Usually we record a dependency because we request an element from a
+    // library, so we build its library element, so request its source.
+    // However if a library is just exported, and the exporting library is not
+    // imported itself, we just copy references, without computing elements.
+    analysisContext.sourceFactory.forUri(uriStr);
+
     var exportIndexList = library.node.exports;
     var exportReferences = List<Reference>(exportIndexList.length);
     for (var i = 0; i < exportIndexList.length; ++i) {
@@ -293,7 +301,7 @@
       elementFactory.analysisSession,
       libraryNode.name,
       hasName ? libraryNode.nameOffset : -1,
-      libraryNode.name.length,
+      libraryNode.nameLength,
       definingUnitContext,
       reference,
       definingUnitContext.unit_withDeclarations,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index cc0ae97..2b30438 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -238,12 +238,16 @@
 
   String getDefaultValueCode(AstNode node) {
     if (node is DefaultFormalParameter) {
-      LazyFormalParameter.readDefaultValue(_astReader, node);
-      return node.defaultValue?.toString();
+      return LazyFormalParameter.getDefaultValueCode(this, node);
     }
     return null;
   }
 
+  String getDefaultValueCodeData(LinkedNode data) {
+    var informativeData = getInformativeData(data);
+    return informativeData?.defaultFormalParameter_defaultValueCode;
+  }
+
   int getDirectiveOffset(Directive node) {
     return node.keyword.offset;
   }
@@ -998,11 +1002,17 @@
       VariableDeclarationList variableList = node.parent;
       if (variableList.isConst) return true;
 
+      FieldDeclaration fieldDeclaration = variableList.parent;
+      if (fieldDeclaration.staticKeyword != null) return false;
+
       if (variableList.isFinal) {
-        ClassOrMixinDeclaration class_ = variableList.parent.parent;
-        for (var member in class_.members) {
-          if (member is ConstructorDeclaration && member.constKeyword != null) {
-            return true;
+        var class_ = fieldDeclaration.parent;
+        if (class_ is ClassOrMixinDeclaration) {
+          for (var member in class_.members) {
+            if (member is ConstructorDeclaration &&
+                member.constKeyword != null) {
+              return true;
+            }
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 8187614..8516655 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -203,13 +203,17 @@
 
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    super.visitInstanceCreationExpression(node);
     var element = node.staticElement;
+    if (element == null) return;
+
     if (element is ConstructorMember) {
       element = (element as ConstructorMember).baseElement;
     }
-    if (element != null) {
-      _set.add(element);
+
+    _set.add(element);
+
+    if (element.enclosingElement.typeParameters.isNotEmpty) {
+      node.argumentList.accept(this);
     }
   }
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 8491beb..c5ed643 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.37.1-dev
+version: 0.38.0
 author: Dart Team <misc@dartlang.org>
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -13,10 +13,10 @@
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.20
+  front_end: 0.1.22
   glob: ^1.0.3
   html: '>=0.13.4+1 <0.15.0'
-  kernel: 0.3.20
+  kernel: 0.3.22
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index ed10771..e011614 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1097,186 +1097,6 @@
     ]);
   }
 
-  test_duplicateDefinition_acrossLibraries() async {
-    var libFile = newFile('/test/lib/lib.dart', content: '''
-library lib;
-
-part 'a.dart';
-part 'test.dart';
-''');
-    newFile('/test/lib/a.dart', content: '''
-part of lib;
-
-class A {}
-''');
-    String partContent = '''
-part of lib;
-
-class A {}
-''';
-    newFile('/test/lib/test.dart', content: partContent);
-    await resolveFile(libFile.path);
-    await assertErrorsInCode(partContent, [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 20, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_catch() async {
-    await assertErrorsInCode(r'''
-main() {
-  try {} catch (e, e) {}
-}''', [
-      error(HintCode.UNUSED_CATCH_STACK, 28, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_inPart() async {
-    var libFile = newFile('/test/lib/lib1.dart', content: '''
-library test;
-part 'test.dart';
-class A {}
-''');
-    String partContent = '''
-part of test;
-class A {}
-''';
-    newFile('/test/lib/test.dart', content: partContent);
-    await resolveFile(libFile.path);
-    await assertErrorsInCode(partContent, [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 20, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inCase() async {
-    await assertErrorsInCode(r'''
-main() {
-  switch(1) {
-    case 1:
-      var a;
-      var a;
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 45, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 58, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 58, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inFunctionBlock() async {
-    await assertErrorsInCode(r'''
-main() {
-  int m = 0;
-  m(a) {}
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
-      error(HintCode.UNUSED_ELEMENT, 24, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inIf() async {
-    await assertErrorsInCode(r'''
-main(int p) {
-  if (p != 0) {
-    var a;
-    var a;
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 38, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 49, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 49, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_locals_inMethodBlock() async {
-    await assertErrorsInCode(r'''
-class A {
-  m() {
-    int a;
-    int a;
-  }
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 26, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 37, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_notInDefiningUnit() async {
-    newFile('/test/lib/a.dart', content: '''
-part of test;
-class A {}
-''');
-    await assertNoErrorsInCode('''
-library test;
-part 'a.dart';
-class A {}
-''');
-  }
-
-  test_duplicateDefinition_parameters_inConstructor() async {
-    await assertErrorsInCode(r'''
-class A {
-  int a;
-  A(int a, this.a);
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 35, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inFunctionTypeAlias() async {
-    await assertErrorsInCode(r'''
-typedef F(int a, double a);
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inLocalFunction() async {
-    await assertErrorsInCode(r'''
-main() {
-  f(int a, double a) {
-  };
-}
-''', [
-      error(HintCode.UNUSED_ELEMENT, 11, 1),
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inMethod() async {
-    await assertErrorsInCode(r'''
-class A {
-  m(int a, double a) {
-  }
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_parameters_inTopLevelFunction() async {
-    await assertErrorsInCode(r'''
-f(int a, double a) {}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 16, 1),
-    ]);
-  }
-
-  test_duplicateDefinition_typeParameters() async {
-    await assertErrorsInCode(r'''
-class A<T, T> {}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 11, 1),
-    ]);
-  }
-
   test_duplicateNamedArgument() async {
     await assertErrorsInCode(r'''
 f({a, b}) {}
@@ -5061,19 +4881,6 @@
     ]);
   }
 
-  test_typeArgumentNotMatchingBounds_const() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {
-  const G();
-}
-f() { return const G<B>(); }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1),
-    ]);
-  }
-
   test_typedef_infiniteParameterBoundCycle() async {
     await assertErrorsInCode(r'''
 typedef F<X extends F> = F Function();
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 7346b25..ba715e5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -138,17 +138,6 @@
     ]);
   }
 
-  test_duplicateDefinition_for_initializers() async {
-    await assertErrorsInCode(r'''
-f() {
-  for (int i = 0, i = 0; i < 5;) {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 24, 1),
-    ]);
-  }
-
   test_expectedOneListTypeArgument() async {
     await assertErrorsInCode(r'''
 main() {
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index 778ecc8..33617ea 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -48,7 +48,6 @@
 ''');
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/37733')
   test_fuzz_01() async {
     await _assertCanBeAnalyzed(r'''
 typedef K=Function(<>($
@@ -61,7 +60,6 @@
 ''');
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/37735')
   test_fuzz_03() async {
     await _assertCanBeAnalyzed('''
 class{const():super.{n
@@ -89,6 +87,38 @@
 ''');
   }
 
+  test_keywordInConstructorInitializer_assert() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : assert = 0;
+}
+''');
+  }
+
+  test_keywordInConstructorInitializer_null() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : null = 0;
+}
+''');
+  }
+
+  test_keywordInConstructorInitializer_super() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : super = 0;
+}
+''');
+  }
+
+  test_keywordInConstructorInitializer_this() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  C() : this = 0;
+}
+''');
+  }
+
   Future<void> _assertCanBeAnalyzed(String text) async {
     addTestFile(text);
     await resolveTestFile();
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 9873beb..383986c 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -97,6 +97,24 @@
     expect(rightHandSide.name, 'value');
   }
 
+  void test_parseConstructor_nullSuperArgList_openBrace_37735() {
+    // https://github.com/dart-lang/sdk/issues/37735
+    var unit = parseCompilationUnit('class{const():super.{n', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 5, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 1),
+      expectedError(ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, 20, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 21, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 22, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 22, 1),
+    ]);
+    var classDeclaration = unit.declarations[0] as ClassDeclaration;
+    var constructor = classDeclaration.members[0] as ConstructorDeclaration;
+    var invocation = constructor.initializers[0] as SuperConstructorInvocation;
+    expect(invocation.argumentList.arguments, hasLength(0));
+  }
+
   void test_parseField_const_late() {
     createParser('const late T f = 0;', featureSet: nonNullable);
     ClassMember member = parser.parseClassMember('C');
@@ -1024,8 +1042,6 @@
       expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 25, 5),
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 30, 2),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 33, 1),
-      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 34, 1),
-      expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 36, 1),
     ]);
   }
 
@@ -1068,8 +1084,6 @@
       expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 25, 4),
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 29, 2),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 32, 1),
-      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 33, 1),
-      expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 35, 1),
     ]);
   }
 
@@ -1209,16 +1223,13 @@
 
   void test_listLiteral_invalid_assert() {
     // https://github.com/dart-lang/sdk/issues/37674
-    parseExpression('n=<.["\$assert',
-        errors: [
-          expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 3, 1),
-          expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 1),
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 6),
-          expectedError(ParserErrorCode.EXPECTED_STRING_LITERAL, 7, 6),
-          expectedError(ScannerErrorCode.EXPECTED_TOKEN, 7, 1),
-          expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 12, 1),
-        ],
-        expectedEndOffset: 7);
+    parseExpression('n=<.["\$assert', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 3, 1),
+      expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 6),
+      expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 12, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 13, 1),
+    ]);
   }
 
   void test_listLiteral_spread_disabled() {
@@ -1394,6 +1405,22 @@
     expect(map.elements, hasLength(0));
   }
 
+  void test_parseStringLiteral_interpolated_void() {
+    Expression expression = parseStringLiteral(r"'<html>$void</html>'");
+    expect(expression, isNotNull);
+    assertErrors(
+        errors: [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 4)]);
+    expect(expression, isStringInterpolation);
+    StringInterpolation literal = expression;
+    NodeList<InterpolationElement> elements = literal.elements;
+    expect(elements, hasLength(3));
+    expect(elements[0] is InterpolationString, isTrue);
+    expect(elements[1] is InterpolationExpression, isTrue);
+    expect(elements[2] is InterpolationString, isTrue);
+    expect((elements[1] as InterpolationExpression).leftBracket.lexeme, '\$');
+    expect((elements[1] as InterpolationExpression).rightBracket, isNull);
+  }
+
   @override
   @failingTest
   void test_parseUnaryExpression_decrement_super() {
@@ -3159,6 +3186,19 @@
 @reflectiveTest
 class SimpleParserTest_Fasta extends FastaParserTestCase
     with SimpleParserTestMixin {
+  void test_method_name_notNull_37733() {
+    // https://github.com/dart-lang/sdk/issues/37733
+    var unit = parseCompilationUnit(r'class C { f(<T>()); }', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 12, 1),
+    ]);
+    var classDeclaration = unit.declarations[0] as ClassDeclaration;
+    var method = classDeclaration.members[0] as MethodDeclaration;
+    expect(method.parameters.parameters, hasLength(1));
+    var parameter =
+        method.parameters.parameters[0] as FunctionTypedFormalParameter;
+    expect(parameter.identifier, isNotNull);
+  }
+
   test_parseArgument() {
     Expression result = parseArgument('3');
     expect(result, const TypeMatcher<IntegerLiteral>());
@@ -3235,6 +3275,38 @@
     expect(declarationList.type, isNotNull);
     expect(declarationList.variables, hasLength(1));
   }
+
+  void test_typeAlias_37733() {
+    // https://github.com/dart-lang/sdk/issues/37733
+    var unit = parseCompilationUnit(r'typedef K=Function(<>($', errors: [
+      expectedError(CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 19, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 22, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
+      expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
+    ]);
+    var typeAlias = unit.declarations[0] as GenericTypeAlias;
+    expect(typeAlias.name.toSource(), 'K');
+    var functionType = typeAlias.functionType;
+    expect(functionType.parameters.parameters, hasLength(1));
+    var parameter = functionType.parameters.parameters[0];
+    expect(parameter.identifier, isNotNull);
+  }
+
+  void test_typeAlias_parameter_missingIdentifier_37733() {
+    // https://github.com/dart-lang/sdk/issues/37733
+    var unit = parseCompilationUnit(r'typedef T=Function(<S>());', errors: [
+      expectedError(CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 19, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1),
+    ]);
+    var typeAlias = unit.declarations[0] as GenericTypeAlias;
+    expect(typeAlias.name.toSource(), 'T');
+    var functionType = typeAlias.functionType;
+    expect(functionType.parameters.parameters, hasLength(1));
+    var parameter = functionType.parameters.parameters[0];
+    expect(parameter.identifier, isNotNull);
+  }
 }
 
 /**
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1e77ec8..663ec18 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2307,7 +2307,11 @@
   }
 
   test_visitTypeName_parameters_noArguments() async {
-    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
+    var tpE = ElementFactory.typeParameterElement('E');
+    tpE.defaultType = DynamicTypeImpl.instance;
+
+    ClassElement classA =
+        ElementFactory.classElement3(name: 'A', typeParameters: [tpE]);
     TypeName typeName = AstTestFactory.typeName(classA);
     typeName.type = null;
     _resolveNode(typeName, [classA]);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 6b2cfd5..b9c570d 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1063,281 +1063,6 @@
     ]);
   }
 
-  test_typeArgumentNotMatchingBounds_classTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C {}
-class G<E extends A> {}
-class D = G<B> with C;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_extends() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C extends G<B>{}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_extends_regressionInIssue18468Fix() async {
-    // https://code.google.com/p/dart/issues/detail?id=18628
-    await assertErrorsInCode(r'''
-class X<T extends Type> {}
-class Y<U> extends X<U> {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_fieldFormalParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C {
-  var f;
-  C(G<B> this.f) {}
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionReturnType() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-G<B> f() { return null; }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-typedef G<B> f();
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionTypedFormalParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f(G<B> h()) {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_implements() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C implements G<B>{}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_is() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-var b = 1 is G<B>;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_localFunction() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-main() {
-  Point<T> f<T extends num>(T x, T y) {
-    return new Point<T>(x, y);
-  }
-  print(f<String>('hello', 'world'));
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_method() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-class PointFactory {
-  Point<T> point<T extends num>(T x, T y) {
-    return new Point<T>(x, y);
-  }
-}
-
-f(PointFactory factory) {
-  print(factory.point<String>('hello', 'world'));
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_topLevelFunction() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-Point<T> f<T extends num>(T x, T y) {
-  return new Point<T>(x, y);
-}
-
-main() {
-  print(f<String>('hello', 'world'));
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodReturnType() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C {
-  G<B> m() { return null; }
-}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f() { return new G<B>(); }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new_superTypeOfUpperBound() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {}
-class C extends B {}
-class G<E extends B> {}
-f() { return new G<A>(); }
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-typedef F<T extends A>();
-F<B> fff;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_parameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f(G<B> g) {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_redirectingConstructor() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class X<T extends A> {
-  X(int x, int y) {}
-  factory X.name(int x, int y) = X<B>;
-}
-''', [
-      error(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4),
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_typeArgumentList() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C<E> {}
-class D<E extends A> {}
-C<D<B>> Var;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_typeParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C {}
-class G<E extends A> {}
-class D<F extends G<B>> {}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_variableDeclaration() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-G<B> g;
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_with() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C extends Object with G<B>{}
-''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
-    ]);
-  }
-
   test_typeParameterSupertypeOfItsBound() async {
     await assertErrorsInCode(r'''
 class A<T extends T> {
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 815c659..16f0d8d 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -48,17 +48,29 @@
   Dart2TypeSystem typeSystem;
 
   DartType get bottomType => typeProvider.bottomType;
+
   InterfaceType get doubleType => typeProvider.doubleType;
+
   DartType get dynamicType => typeProvider.dynamicType;
+
   InterfaceType get functionType => typeProvider.functionType;
+
   InterfaceType get intType => typeProvider.intType;
+
   InterfaceType get iterableType => typeProvider.iterableType;
+
   InterfaceType get listType => typeProvider.listType;
+
   DartType get neverType => typeProvider.neverType;
+
   DartType get nullType => typeProvider.nullType;
+
   InterfaceType get numType => typeProvider.numType;
+
   InterfaceType get objectType => typeProvider.objectType;
+
   InterfaceType get stringType => typeProvider.stringType;
+
   DartType get voidType => VoidTypeImpl.instance;
 
   void setUp() {
@@ -342,16 +354,27 @@
   FunctionType simpleFunctionType;
 
   DartType get bottomType => typeProvider.bottomType;
+
   InterfaceType get doubleType => typeProvider.doubleType;
+
   DartType get dynamicType => typeProvider.dynamicType;
+
   InterfaceType get functionType => typeProvider.functionType;
+
   InterfaceType get futureOrType => typeProvider.futureOrType;
+
   InterfaceType get intType => typeProvider.intType;
+
   InterfaceType get iterableType => typeProvider.iterableType;
+
   InterfaceType get listType => typeProvider.listType;
+
   InterfaceType get nullType => typeProvider.nullType;
+
   InterfaceType get numType => typeProvider.numType;
+
   InterfaceType get objectType => typeProvider.objectType;
+
   InterfaceType get stringType => typeProvider.stringType;
 
   DartType get voidType => VoidTypeImpl.instance;
@@ -2673,7 +2696,7 @@
     ]);
 
     // Create a non-identical but equal copy of Function, and verify subtyping
-    var copyOfFunction = new InterfaceTypeImpl(functionType.element, null);
+    var copyOfFunction = new InterfaceTypeImpl(functionType.element);
     _checkEquivalent(functionType, copyOfFunction);
   }
 
@@ -2907,16 +2930,27 @@
   TypeSystem typeSystem;
 
   DartType get bottomType => typeProvider.bottomType;
+
   InterfaceType get doubleType => typeProvider.doubleType;
+
   DartType get dynamicType => typeProvider.dynamicType;
+
   InterfaceType get functionType => typeProvider.functionType;
+
   InterfaceType get futureOrType => typeProvider.futureOrType;
+
   InterfaceType get intType => typeProvider.intType;
+
   InterfaceType get listType => typeProvider.listType;
+
   DartType get nullType => typeProvider.nullType;
+
   InterfaceType get numType => typeProvider.numType;
+
   InterfaceType get objectType => typeProvider.objectType;
+
   InterfaceType get stringType => typeProvider.stringType;
+
   DartType get voidType => VoidTypeImpl.instance;
 
   void setUp() {
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index df9540b..38f6ff8 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -5,10 +5,12 @@
 import 'dart:async';
 import 'dart:convert';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:test/test.dart';
@@ -19,6 +21,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(IndexTest);
+    defineReflectiveTests(IndexWithExtensionMethodsTest);
   });
 }
 
@@ -1286,7 +1289,8 @@
       }
     }
     for (Element e = element; e != null; e = e.enclosingElement) {
-      if (e.enclosingElement is ClassElement) {
+      if (e.enclosingElement is ClassElement ||
+          e.enclosingElement is ExtensionElement) {
         classMemberId = _getStringId(e.name);
         break;
       }
@@ -1370,6 +1374,112 @@
   }
 }
 
+@reflectiveTest
+class IndexWithExtensionMethodsTest extends IndexTest {
+  @override
+  AnalysisOptionsImpl createAnalysisOptions() => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_isInvokedBy_MethodElement_ofExtension_instance() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  void foo() {}
+}
+
+main(A a) {
+  a.foo();
+}
+''');
+    MethodElement element = findElement('foo');
+    assertThat(element)..isInvokedAt('foo();', true);
+  }
+
+  test_isInvokedBy_MethodElement_ofExtension_static() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  static void foo() {}
+}
+
+main(A a) {
+  E.foo();
+}
+''');
+    MethodElement element = findElement('foo');
+    assertThat(element)..isInvokedAt('foo();', true);
+  }
+
+  test_isReferencedBy_ClassElement_fromExtension() async {
+    await _indexTestUnit('''
+class A<T> {}
+
+extension E on A<int> {}
+''');
+    ClassElement element = findElement('A');
+    assertThat(element)..isReferencedAt('A<int>', false);
+  }
+
+  test_isReferencedBy_ExtensionElement() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  void foo() {}
+}
+
+main(A a) {
+  E(a).foo();
+}
+''');
+    ExtensionElement element = findElement('E');
+    assertThat(element)..isReferencedAt('E(a).foo()', false);
+  }
+
+  test_isReferencedBy_PropertyAccessor_ofExtension_instance() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  int get foo => 0;
+  void set foo(int _) {}
+}
+
+main(A a) {
+  a.foo;
+  a.foo = 0;
+}
+''');
+    PropertyAccessorElement getter = findElement('foo', ElementKind.GETTER);
+    PropertyAccessorElement setter = findElement('foo=');
+    assertThat(getter)..isReferencedAt('foo;', true);
+    assertThat(setter)..isReferencedAt('foo = 0;', true);
+  }
+
+  test_isReferencedBy_PropertyAccessor_ofExtension_static() async {
+    await _indexTestUnit('''
+class A {}
+
+extension E on A {
+  static int get foo => 0;
+  static void set foo(int _) {}
+}
+
+main(A a) {
+  a.foo;
+  a.foo = 0;
+}
+''');
+    PropertyAccessorElement getter = findElement('foo', ElementKind.GETTER);
+    PropertyAccessorElement setter = findElement('foo=');
+    assertThat(getter)..isReferencedAt('foo;', true);
+    assertThat(setter)..isReferencedAt('foo = 0;', true);
+  }
+}
+
 class _ElementIndexAssert {
   final IndexTest test;
   final Element element;
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index ac142d0..fb4a4ef 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart' hide Declaration;
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -12,6 +13,7 @@
 import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/testing/element_search.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -21,6 +23,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SearchTest);
+    defineReflectiveTests(SearchWithExtensionMethodsTest);
   });
 }
 
@@ -1636,3 +1639,152 @@
     expect(matches, unorderedEquals(expectedMatches));
   }
 }
+
+@reflectiveTest
+class SearchWithExtensionMethodsTest extends SearchTest {
+  @override
+  AnalysisOptionsImpl createAnalysisOptions() => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_searchReferences_ExtensionElement() async {
+    await _resolveTestUnit('''
+extension E on int {
+  void foo() {}
+  static void bar() {}
+}
+
+main() {
+  E(0).foo();
+  E.bar();
+}
+''');
+    var element = _findElement('E');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(main, SearchResultKind.REFERENCE, 'E(0)'),
+      _expectId(main, SearchResultKind.REFERENCE, 'E.bar()'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_MethodElement_ofExtension_instance() async {
+    await _resolveTestUnit('''
+extension E on int {
+  void foo() {}
+
+  void bar() {
+    foo(); // 1
+    this.foo(); // 2
+    foo; // 3
+    this.foo; // 4
+  }
+}
+
+main() {
+  E(0).foo(); // 5
+  0.foo(); // 6
+  E(0).foo; // 7
+  0.foo; // 8
+}
+''');
+    var element = _findElement('foo');
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
+      _expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo; // 3'),
+      _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 4'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 5'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 6'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 7'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 8'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_MethodElement_ofExtension_static() async {
+    await _resolveTestUnit('''
+extension E on int {
+  static void foo() {}
+
+  static void bar() {
+    foo(); // 1
+    foo; // 2
+  }
+}
+
+main() {
+  E.foo(); // 3
+  E.foo; // 4
+}
+''');
+    var element = _findElement('foo');
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
+      _expectIdQ(main, SearchResultKind.INVOCATION, 'foo(); // 3'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 4'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_PropertyAccessor_getter_ofExtension_instance() async {
+    await _resolveTestUnit('''
+extension E on int {
+  int get foo => 0;
+
+  void bar() {
+    foo; // 1
+    this.foo; // 2
+  }
+}
+
+main() {
+  E(0).foo; // 3
+  0.foo; // 4
+}
+''');
+    var element = _findElement('foo', ElementKind.GETTER);
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo; // 1'),
+      _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 3'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo; // 4'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+
+  test_searchReferences_PropertyAccessor_setter_ofExtension_instance() async {
+    await _resolveTestUnit('''
+extension E on int {
+  set foo(int _) {}
+
+  void bar() {
+    foo = 1;
+    this.foo = 2;
+  }
+}
+
+main() {
+  E(0).foo = 3;
+  0.foo = 4;
+}
+''');
+    var element = _findElement('foo=');
+    var bar = _findElement('bar');
+    var main = _findElement('main');
+    var expected = [
+      _expectId(bar, SearchResultKind.REFERENCE, 'foo = 1;'),
+      _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo = 2;'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo = 3;'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'foo = 4;'),
+    ];
+    await _verifyReferences(element, expected);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
new file mode 100644
index 0000000..73316d2
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
@@ -0,0 +1,394 @@
+// Copyright (c) 2019, 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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AstRewriteMethodInvocationTest);
+    defineReflectiveTests(AstRewriteMethodInvocationWithExtensionMethodsTest);
+  });
+}
+
+@reflectiveTest
+class AstRewriteMethodInvocationTest extends DriverResolutionTest {
+  test_targetNull_cascade() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+
+f(A a) {
+  a..foo();
+}
+''');
+
+    var invocation = findNode.methodInvocation('foo();');
+    assertElement(invocation, findElement.method('foo'));
+  }
+
+  test_targetNull_class() async {
+    await assertNoErrorsInCode(r'''
+class A<T, U> {
+  A(int a);
+}
+
+f() {
+  A<int, String>(0);
+}
+''');
+
+    var creation = findNode.instanceCreation('A<int, String>(0);');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int, String>',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetNull_function() async {
+    await assertNoErrorsInCode(r'''
+void A<T, U>(int a) {}
+
+f() {
+  A<int, String>(0);
+}
+''');
+
+    var invocation = findNode.methodInvocation('A<int, String>(0);');
+    assertElement(invocation, findElement.topFunction('A'));
+    assertInvokeType(invocation, 'void Function(int)');
+    _assertArgumentList(invocation.argumentList, ['0']);
+  }
+
+  test_targetPrefixedIdentifier_prefix_class_constructor() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {
+  A.named(T a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A.named(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('A.named(0);');
+    assertInstanceCreation(
+      creation,
+      importFind.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedPrefix: importFind.prefix,
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetPrefixedIdentifier_prefix_class_constructor_typeArguments() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {
+  A.named(int a);
+}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A.named<int>(0);
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+          50, 5),
+    ]);
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('named<int>(0);');
+    assertInstanceCreation(
+      creation,
+      importFind.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedPrefix: importFind.prefix,
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    _assertTypeArgumentList(
+      creation.constructorName.type.typeArguments,
+      ['int'],
+    );
+    expect((creation as InstanceCreationExpressionImpl).typeArguments, isNull);
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetPrefixedIdentifier_prefix_getter_method() async {
+    newFile('/test/lib/a.dart', content: r'''
+A get foo => A();
+
+class A {
+  void bar(int a) {}
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.foo.bar(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var invocation = findNode.methodInvocation('bar(0);');
+    assertElement(invocation, importFind.class_('A').getMethod('bar'));
+    assertInvokeType(invocation, 'void Function(int)');
+    _assertArgumentList(invocation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_class_constructor() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  A.named(T a);
+}
+
+f() {
+  A.named(0);
+}
+''');
+
+    var creation = findNode.instanceCreation('A.named(0);');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      'A<int>',
+      constructorName: 'named',
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_class_constructor_typeArguments() async {
+    await assertErrorsInCode(r'''
+class A<T, U> {
+  A.named(int a);
+}
+
+f() {
+  A.named<int, String>(0);
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+          52, 13),
+    ]);
+
+    var creation = findNode.instanceCreation('named<int, String>(0);');
+    assertInstanceCreation(
+      creation,
+      findElement.class_('A'),
+      // TODO(scheglov) Move type arguments
+      'A<dynamic, dynamic>',
+//      'A<int, String>',
+      constructorName: 'named',
+      expectedConstructorMember: true,
+      // TODO(scheglov) Move type arguments
+      expectedSubstitution: {'T': 'dynamic', 'U': 'dynamic'},
+//      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+    // TODO(scheglov) Move type arguments
+//    _assertTypeArgumentList(
+//      creation.constructorName.type.typeArguments,
+//      ['int', 'String'],
+//    );
+    // TODO(scheglov) Fix and uncomment.
+//    expect((creation as InstanceCreationExpressionImpl).typeArguments, isNull);
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_class_staticMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static void foo(int a) {}
+}
+
+f() {
+  A.foo(0);
+}
+''');
+
+    var invocation = findNode.methodInvocation('foo(0);');
+    assertElement(invocation, findElement.method('foo'));
+  }
+
+  test_targetSimpleIdentifier_prefix_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T, U> {
+  A(int a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A<int, String>(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var creation = findNode.instanceCreation('A<int, String>(0);');
+    assertInstanceCreation(
+      creation,
+      importFind.class_('A'),
+      'A<int, String>',
+      expectedPrefix: importFind.prefix,
+      expectedConstructorMember: true,
+      expectedSubstitution: {'T': 'int', 'U': 'String'},
+    );
+    _assertArgumentList(creation.argumentList, ['0']);
+  }
+
+  test_targetSimpleIdentifier_prefix_function() async {
+    newFile('/test/lib/a.dart', content: r'''
+void A<T, U>(int a) {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f() {
+  prefix.A<int, String>(0);
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var invocation = findNode.methodInvocation('A<int, String>(0);');
+    assertElement(invocation, importFind.topFunction('A'));
+    assertInvokeType(invocation, 'void Function(int)');
+    _assertArgumentList(invocation.argumentList, ['0']);
+  }
+
+  void _assertArgumentList(
+    ArgumentList argumentList,
+    List<String> expectedArguments,
+  ) {
+    var argumentStrings = argumentList.arguments
+        .map((e) => result.content.substring(e.offset, e.end))
+        .toList();
+    expect(argumentStrings, expectedArguments);
+  }
+
+  void _assertTypeArgumentList(
+    TypeArgumentList argumentList,
+    List<String> expectedArguments,
+  ) {
+    var argumentStrings = argumentList.arguments
+        .map((e) => result.content.substring(e.offset, e.end))
+        .toList();
+    expect(argumentStrings, expectedArguments);
+  }
+}
+
+@reflectiveTest
+class AstRewriteMethodInvocationWithExtensionMethodsTest
+    extends AstRewriteMethodInvocationTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.forTesting(
+      sdkVersion: '2.3.0',
+      additionalFeatures: [Feature.extension_methods],
+    );
+
+  test_targetNull_extension() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+
+extension E<T> on A {
+  void foo() {}
+}
+
+f(A a) {
+  E<int>(a).foo();
+}
+''');
+
+    var override = findNode.extensionOverride('E<int>(a)');
+    _assertExtensionOverride(
+      override,
+      expectedElement: findElement.extension_('E'),
+      expectedTypeArguments: ['int'],
+      expectedExtendedType: 'A',
+    );
+  }
+
+  test_targetSimpleIdentifier_prefix_extension() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {}
+
+extension E<T> on A {
+  void foo() {}
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as prefix;
+
+f(prefix.A a) {
+  prefix.E<int>(a).foo();
+}
+''');
+
+    var importFind = findElement.importFind('package:test/a.dart');
+
+    var override = findNode.extensionOverride('E<int>(a)');
+    _assertExtensionOverride(
+      override,
+      expectedElement: importFind.extension_('E'),
+      expectedTypeArguments: ['int'],
+      expectedExtendedType: 'A',
+    );
+    assertImportPrefix(findNode.simple('prefix.E'), importFind.prefix);
+  }
+
+  void _assertExtensionOverride(
+    ExtensionOverride override, {
+    @required ExtensionElement expectedElement,
+    @required List<String> expectedTypeArguments,
+    @required String expectedExtendedType,
+  }) {
+    expect(override.staticElement, expectedElement);
+    assertElementTypeStrings(
+      override.typeArgumentTypes,
+      expectedTypeArguments,
+    );
+    assertElementTypeString(
+      override.extendedType,
+      expectedExtendedType,
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index f384b0d..53ff0e9 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -478,450 +478,6 @@
         [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
   }
 
-  test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
-    addTestFile(r'''
-class C {
-  static int get foo => 0;
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_method() async {
-    addTestFile(r'''
-class C {
-  static int get foo => 0;
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
-    addTestFile(r'''
-class C {
-  static int get foo => 0;
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_getter() async {
-    addTestFile(r'''
-class C {
-  static void foo() {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_method() async {
-    addTestFile(r'''
-class C {
-  static void foo() {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_setter() async {
-    addTestFile(r'''
-class C {
-  static void foo() {}
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
-    addTestFile(r'''
-class C {
-  static set foo(_) {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_method() async {
-    addTestFile(r'''
-class C {
-  static set foo(_) {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
-    addTestFile(r'''
-class C {
-  static set foo(_) {}
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-abstract class B implements A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-abstract class B implements A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-abstract class B implements A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-abstract class B implements A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-abstract class B implements A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_getter_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends Object with A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_getter_method() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_getter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends Object with A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_method_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_method_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_method_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends Object with A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_setter_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends Object with A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inMixin_setter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends Object with A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_getter_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_getter_method() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_getter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends A {
-  static int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_method_getter() async {
-    addTestFile(r'''
-class A {
-  int get foo => 0;
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_method_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_method_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends A {
-  static void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_setter_method() async {
-    addTestFile(r'''
-class A {
-  void foo() {}
-}
-class B extends A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
-  test_error_conflictingStaticAndInstance_inSuper_setter_setter() async {
-    addTestFile(r'''
-class A {
-  set foo(_) {}
-}
-class B extends A {
-  static set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
   test_error_duplicateConstructorDefault() async {
     addTestFile(r'''
 class C {
@@ -948,160 +504,6 @@
     ]);
   }
 
-  test_error_duplicateDefinition_field_field() async {
-    addTestFile(r'''
-class C {
-  int foo;
-  int foo;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_field_field_static() async {
-    addTestFile(r'''
-class C {
-  static int foo;
-  static int foo;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_field_getter() async {
-    addTestFile(r'''
-class C {
-  int foo;
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_field_method() async {
-    addTestFile(r'''
-class C {
-  int foo;
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_getter_getter() async {
-    addTestFile(r'''
-class C {
-  int get foo => 0;
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_getter_method() async {
-    addTestFile(r'''
-class C {
-  int get foo => 0;
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_method_getter() async {
-    addTestFile(r'''
-class C {
-  void foo() {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_method_method() async {
-    addTestFile(r'''
-class C {
-  void foo() {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_method_setter() async {
-    addTestFile(r'''
-class C {
-  void foo() {}
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_OK_fieldFinal_setter() async {
-    addTestFile(r'''
-class C {
-  final int foo = 0;
-  set foo(int x) {}
-}
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
-  test_error_duplicateDefinition_OK_getter_setter() async {
-    addTestFile(r'''
-class C {
-  int get foo => 0;
-  set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
-  test_error_duplicateDefinition_OK_setter_getter() async {
-    addTestFile(r'''
-class C {
-  set foo(_) {}
-  int get foo => 0;
-}
-''');
-    await resolveTestFile();
-    assertNoTestErrors();
-  }
-
-  test_error_duplicateDefinition_setter_method() async {
-    addTestFile(r'''
-class C {
-  set foo(_) {}
-  void foo() {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_error_duplicateDefinition_setter_setter() async {
-    addTestFile(r'''
-class C {
-  void set foo(_) {}
-  void set foo(_) {}
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
   test_error_extendsNonClass_dynamic() async {
     addTestFile(r'''
 class A extends dynamic {}
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index c731596..8e9b10b 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -2,7 +2,6 @@
 // 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:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,17 +19,6 @@
     with EnumResolutionMixin {}
 
 mixin EnumResolutionMixin implements ResolutionTest {
-  test_error_conflictingStaticAndInstance_index() async {
-    addTestFile(r'''
-enum E {
-  a, index
-}
-''');
-    await resolveTestFile();
-    assertTestErrorsWithCodes(
-        [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
-  }
-
   test_inference_listLiteral() async {
     addTestFile(r'''
 enum E1 {a, b}
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index b6633c9..40f8562 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -363,6 +363,20 @@
     assertType(identifier, 'int');
   }
 
+  test_instance_getter_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  int get a => 1;
+}
+g(int Function(int) f) {
+  f.a;
+}
+''');
+    var access = findNode.prefixed('f.a');
+    assertElement(access, findElement.getter('a'));
+    assertType(access, 'int');
+  }
+
   test_instance_getter_fromInstance() async {
     await assertNoErrorsInCode('''
 class C {}
@@ -443,6 +457,20 @@
     assertType(access, 'int');
   }
 
+  test_instance_getterInvoked_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  String Function() get a => () => 'a';
+}
+g(int Function(int) f) {
+  f.a();
+}
+''');
+    var invocation = findNode.methodInvocation('f.a()');
+    assertElement(invocation, findElement.getter('a'));
+    assertType(invocation, 'String');
+  }
+
   test_instance_method_fromDifferentExtension_usingBounds() async {
     await assertNoErrorsInCode('''
 class B {}
@@ -509,6 +537,20 @@
     assertInvokeType(invocation, 'void Function()');
   }
 
+  test_instance_method_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void a() {}
+}
+g(int Function(int) f) {
+  f.a();
+}
+''');
+    var invocation = findNode.methodInvocation('f.a()');
+    assertElement(invocation, findElement.method('a'));
+    assertInvokeType(invocation, 'void Function()');
+  }
+
   test_instance_method_fromInstance() async {
     await assertNoErrorsInCode('''
 class B {}
@@ -584,7 +626,6 @@
     assertInvokeType(invocation, 'void Function()');
   }
 
-  @failingTest
   test_instance_method_specificSubtypeMatchLocalGenerics() async {
     await assertNoErrorsInCode('''
 class A<T> {}
@@ -606,8 +647,12 @@
 }
 ''');
     var invocation = findNode.methodInvocation('x.f(o)');
-    assertElement(invocation, findElement.method('f', of: 'B_Ext'));
-    assertInvokeType(invocation, 'void Function(T)');
+    assertMember(
+      invocation,
+      findElement.method('f', of: 'B_Ext'),
+      {'T': 'C'},
+    );
+    assertInvokeType(invocation, 'void Function(C)');
   }
 
   test_instance_method_specificSubtypeMatchPlatform() async {
@@ -654,7 +699,20 @@
     assertElement(binary, findElement.method('+', of: 'C'));
   }
 
-  test_instance_operator_binary_fromExtension() async {
+  test_instance_operator_binary_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator +(int i) {}
+}
+g(int Function(int) f) {
+  f + 2;
+}
+''');
+    var binary = findNode.binary('+ ');
+    assertElement(binary, findElement.method('+', of: 'E'));
+  }
+
+  test_instance_operator_binary_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -684,7 +742,20 @@
     assertElement(index, findElement.method('[]', of: 'C'));
   }
 
-  test_instance_operator_index_fromExtension() async {
+  test_instance_operator_index_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator [](int index) {}
+}
+g(int Function(int) f) {
+  f[2];
+}
+''');
+    var index = findNode.index('f[2]');
+    assertElement(index, findElement.method('[]', of: 'E'));
+  }
+
+  test_instance_operator_index_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -714,7 +785,20 @@
     assertElement(index, findElement.method('[]=', of: 'C'));
   }
 
-  test_instance_operator_indexEquals_fromExtension() async {
+  test_instance_operator_indexEquals_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator []=(int index, int value) {}
+}
+g(int Function(int) f) {
+  f[2] = 3;
+}
+''');
+    var index = findNode.index('f[2]');
+    assertElement(index, findElement.method('[]=', of: 'E'));
+  }
+
+  test_instance_operator_indexEquals_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -744,7 +828,20 @@
     assertElement(postfix, findElement.method('+', of: 'C'));
   }
 
-  test_instance_operator_postfix_fromExtension() async {
+  test_instance_operator_postfix_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator +(int i) {}
+}
+g(int Function(int) f) {
+  f++;
+}
+''');
+    var postfix = findNode.postfix('++');
+    assertElement(postfix, findElement.method('+', of: 'E'));
+  }
+
+  test_instance_operator_postfix_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -774,7 +871,20 @@
     assertElement(prefix, findElement.method('+', of: 'C'));
   }
 
-  test_instance_operator_prefix_fromExtension() async {
+  test_instance_operator_prefix_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator +(int i) {}
+}
+g(int Function(int) f) {
+  ++f;
+}
+''');
+    var prefix = findNode.prefix('++');
+    assertElement(prefix, findElement.method('+', of: 'E'));
+  }
+
+  test_instance_operator_prefix_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -804,7 +914,20 @@
     assertElement(prefix, findElement.method('unary-', of: 'C'));
   }
 
-  test_instance_operator_unary_fromExtension() async {
+  test_instance_operator_unary_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void operator -() {}
+}
+g(int Function(int) f) {
+  -f;
+}
+''');
+    var prefix = findNode.prefix('-f');
+    assertElement(prefix, findElement.method('unary-', of: 'E'));
+  }
+
+  test_instance_operator_unary_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 extension E on C {
@@ -818,6 +941,19 @@
     assertElement(prefix, findElement.method('unary-', of: 'E'));
   }
 
+  test_instance_setter_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  set a(int x) {}
+}
+g(int Function(int) f) {
+  f.a = 1;
+}
+''');
+    var access = findNode.prefixed('f.a');
+    assertElement(access, findElement.setter('a'));
+  }
+
   test_instance_setter_oneMatch() async {
     await assertNoErrorsInCode('''
 class C {}
@@ -855,7 +991,19 @@
     assertType(access, 'int');
   }
 
-  test_instance_tearoff() async {
+  test_instance_tearoff_fromExtension_functionType() async {
+    await assertNoErrorsInCode('''
+extension E on int Function(int) {
+  void a(int x) {}
+}
+g(int Function(int) f) => f.a;
+''');
+    var identifier = findNode.simple('a;');
+    assertElement(identifier, findElement.method('a'));
+    assertType(identifier, 'void Function(int)');
+  }
+
+  test_instance_tearoff_fromExtension_interfaceType() async {
     await assertNoErrorsInCode('''
 class C {}
 
@@ -1490,4 +1638,116 @@
     assertElement(identifier, findElement.method('a'));
     assertType(identifier, 'void Function(int)');
   }
+
+  test_topLevel_function_fromInstance() async {
+    await assertNoErrorsInCode('''
+class C {
+  void a() {}
+}
+
+void a() {}
+
+extension E on C {
+  void b() {
+    a();
+  }
+}
+''');
+    var invocation = findNode.methodInvocation('a();');
+    assertElement(invocation, findElement.topFunction('a'));
+    assertInvokeType(invocation, 'void Function()');
+  }
+
+  test_topLevel_function_fromStatic() async {
+    await assertNoErrorsInCode('''
+class C {
+  void a() {}
+}
+
+void a() {}
+
+extension E on C {
+  static void b() {
+    a();
+  }
+}
+''');
+    var invocation = findNode.methodInvocation('a();');
+    assertElement(invocation, findElement.topFunction('a'));
+    assertInvokeType(invocation, 'void Function()');
+  }
+
+  test_topLevel_getter_fromInstance() async {
+    await assertNoErrorsInCode('''
+class C {
+  int get a => 0;
+}
+
+int get a => 0;
+
+extension E on C {
+  void b() {
+    a;
+  }
+}
+''');
+    var identifier = findNode.simple('a;');
+    assertElement(identifier, findElement.topGet('a'));
+    assertType(identifier, 'int');
+  }
+
+  test_topLevel_getter_fromStatic() async {
+    await assertNoErrorsInCode('''
+class C {
+  int get a => 0;
+}
+
+int get a => 0;
+
+extension E on C {
+  static void b() {
+    a;
+  }
+}
+''');
+    var identifier = findNode.simple('a;');
+    assertElement(identifier, findElement.topGet('a'));
+    assertType(identifier, 'int');
+  }
+
+  test_topLevel_setter_fromInstance() async {
+    await assertNoErrorsInCode('''
+class C {
+  set a(int _) {}
+}
+
+set a(int _) {}
+
+extension E on C {
+  void b() {
+    a = 0;
+  }
+}
+''');
+    var identifier = findNode.simple('a = 0;');
+    assertElement(identifier, findElement.topSet('a'));
+  }
+
+  test_topLevel_setter_fromStatic() async {
+    await assertNoErrorsInCode('''
+class C {
+  set a(int _) {}
+}
+
+set a(int _) {}
+
+extension E on C {
+  static void b() {
+    a = 0;
+  }
+}
+''');
+    var identifier = findNode.simple('a = 0;');
+    assertElement(identifier, findElement.topSet('a'));
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index 77c2a17..cb1bd80 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -59,7 +59,6 @@
     validateCall();
   }
 
-  @failingTest
   test_call_noPrefix_typeArguments() async {
     // The test is failing because we're not yet doing type inference.
     await assertNoErrorsInCode('''
@@ -97,7 +96,6 @@
     validateCall();
   }
 
-  @failingTest
   test_call_prefix_typeArguments() async {
     // The test is failing because we're not yet doing type inference.
     newFile('/test/lib/lib.dart', content: '''
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 57179a1..2a5fd62 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -114,10 +114,14 @@
     assertInstanceCreation(
       creation,
       findElement.class_('Foo'),
+      // TODO(scheglov) Move type arguments
       'Foo<dynamic>',
+//      'Foo<int>',
       constructorName: 'bar',
       expectedConstructorMember: true,
+      // TODO(scheglov) Move type arguments
       expectedSubstitution: {'X': 'dynamic'},
+//      expectedSubstitution: {'X': 'int'},
     );
   }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 100d12e..827c61b 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -234,313 +234,6 @@
 ''');
   }
 
-  test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static int get foo => 0;
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static int get foo => 0;
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static int get foo => 0;
-  set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static void foo() {}
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static void foo() {}
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_method_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static void foo() {}
-  set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static set foo(_) {}
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static set foo(_) {}
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  static set foo(_) {}
-  set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_getter_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M on A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_getter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_getter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M on A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 60, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_method_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_method_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_method_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M on A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_setter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M on A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inConstraint_setter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M on A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M implements A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 72, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M implements A {
-  static int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 68, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M implements A {
-  static void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-mixin M implements A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
-    ]);
-  }
-
-  test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  set foo(_) {}
-}
-mixin M implements A {
-  static set foo(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
-    ]);
-  }
-
   test_error_conflictingTypeVariableAndClass() async {
     await assertErrorsInCode(r'''
 mixin M<M> {}
@@ -599,83 +292,6 @@
     ]);
   }
 
-  test_error_duplicateDefinition_field() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int t;
-  int t;
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 25, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_field_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int t;
-  void t() {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 26, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int get t => 0;
-  int get t => 0;
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 38, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_getter_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  int get foo => 0;
-  void foo() {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 3),
-    ]);
-  }
-
-  test_error_duplicateDefinition_method() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  void t() {}
-  void t() {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 31, 1),
-    ]);
-  }
-
-  test_error_duplicateDefinition_method_getter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  void foo() {}
-  int get foo => 0;
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 36, 3),
-    ]);
-  }
-
-  test_error_duplicateDefinition_setter() async {
-    await assertErrorsInCode(r'''
-mixin M {
-  void set t(_) {}
-  void set t(_) {}
-}
-''', [
-      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 1),
-    ]);
-  }
-
   test_error_finalNotInitialized() async {
     await assertErrorsInCode(r'''
 mixin M {
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index bd793ba..3fd1ab2 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -413,13 +413,10 @@
       var name = node.name as SimpleIdentifier;
       assertElement(name, expectedElement);
       // TODO(scheglov) Should this be null?
-      assertType(name, expectedType);
+//      assertType(name, expectedType);
     } else {
       var name = node.name as PrefixedIdentifier;
-
-      assertElement(name.prefix, expectedPrefix);
-      expect(name.prefix.staticType, isNull);
-
+      assertImportPrefix(name.prefix, expectedPrefix);
       assertElement(name.identifier, expectedElement);
 
       // TODO(scheglov) This should be null, but it is not.
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 243bad8..8261f8b 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'assignment_test.dart' as assignment;
+import 'ast_rewrite_test.dart' as ast_rewrite;
 import 'class_alias_test.dart' as class_alias;
 import 'class_test.dart' as class_resolution;
 import 'comment_test.dart' as comment;
@@ -41,6 +42,7 @@
 main() {
   defineReflectiveSuite(() {
     assignment.main();
+    ast_rewrite.main();
     class_alias.main();
     class_resolution.main();
     comment.main();
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
index 410fc08..dfbb4ac 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -137,6 +138,48 @@
     );
   }
 
+  test_override_downward_hasTypeArguments() async {
+    await assertNoErrorsInCode('''
+extension E<T> on Set<T> {
+  void foo() {}
+}
+
+main() {
+  E<int>({}).foo();
+}
+''');
+    var literal = findNode.setOrMapLiteral('{}).');
+    assertType(literal, 'Set<int>');
+  }
+
+  test_override_downward_hasTypeArguments_wrongNumber() async {
+    await assertNoErrorsInCode('''
+extension E<T> on Set<T> {
+  void foo() {}
+}
+
+main() {
+  E<int, bool>({}).foo();
+}
+''');
+    var literal = findNode.setOrMapLiteral('{}).');
+    assertType(literal, 'Set<dynamic>');
+  }
+
+  test_override_downward_noTypeArguments() async {
+    await assertNoErrorsInCode('''
+extension E<T> on Set<T> {
+  void foo() {}
+}
+
+main() {
+  E({}).foo();
+}
+''');
+    var literal = findNode.setOrMapLiteral('{}).');
+    assertType(literal, 'Set<dynamic>');
+  }
+
   test_override_hasTypeArguments_getter() async {
     await assertNoErrorsInCode('''
 class A<T> {}
@@ -241,6 +284,23 @@
     );
   }
 
+  test_override_inferTypeArguments_error_couldNotInfer() async {
+    await assertErrorsInCode('''
+extension E<T extends num> on T {
+  void foo() {}
+}
+
+f(String s) {
+  E(s).foo();
+}
+''', [
+      error(StrongModeCode.COULD_NOT_INFER, 69, 1),
+    ]);
+    var override = findNode.extensionOverride('E(s)');
+    assertElementTypeStrings(override.typeArgumentTypes, ['String']);
+    assertElementTypeString(override.extendedType, 'String');
+  }
+
   test_override_inferTypeArguments_getter() async {
     await assertNoErrorsInCode('''
 class A<T> {}
diff --git a/pkg/analyzer/test/src/diagnostics/access_static_extension_member_test.dart b/pkg/analyzer/test/src/diagnostics/access_static_extension_member_test.dart
deleted file mode 100644
index deb739c..0000000
--- a/pkg/analyzer/test/src/diagnostics/access_static_extension_member_test.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2019, 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:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/driver_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AccessStaticExtensionMemberTest);
-  });
-}
-
-@reflectiveTest
-class AccessStaticExtensionMemberTest extends DriverResolutionTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = new FeatureSet.forTesting(
-        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
-
-  @failingTest
-  test_getter() async {
-    await assertErrorsInCode('''
-class C {}
-
-extension E on C {
-  static int get a => 0;
-}
-
-f(C c) {
-  c.a;
-}
-''', [
-      error(CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER, 72, 1),
-    ]);
-  }
-
-  test_method() async {
-    await assertErrorsInCode('''
-class C {}
-
-extension E on C {
-  static void a() {}
-}
-
-f(C c) {
-  c.a();
-}
-''', [
-      error(CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER, 68, 1),
-    ]);
-  }
-
-  @failingTest
-  test_setter() async {
-    await assertErrorsInCode('''
-class C {}
-
-extension E on C {
-  static set a(v) {}}
-}
-
-f(C c) {
-  c.a = 2;
-}
-''', [
-      error(CompileTimeErrorCode.ACCESS_STATIC_EXTENSION_MEMBER, 69, 1),
-    ]);
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart
index 02dc727..bf7926d 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_export_test.dart
@@ -41,7 +41,7 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
-  test_extension() async {
+  test_extensions_bothExported() async {
     newFile('/test/lib/lib1.dart', content: r'''
 extension E on String {}
 ''');
@@ -55,4 +55,15 @@
       error(CompileTimeErrorCode.AMBIGUOUS_EXPORT, 20, 19),
     ]);
   }
+
+  test_extensions_localAndExported() async {
+    newFile('/test/lib/lib1.dart', content: r'''
+extension E on String {}
+''');
+    await assertNoErrorsInCode(r'''
+export 'lib1.dart';
+
+extension E on String {}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart
index cc03f82..21ffe97 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_method_access_test.dart
@@ -22,16 +22,33 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
 
-  test_getter() async {
-    // TODO(brianwilkerson) Ensure that only one diagnostic is produced.
+  test_call() async {
     await assertErrorsInCode('''
 class A {}
 
-extension A1_Ext on A {
+extension E1 on A {
+  int call() => 0;
+}
+
+extension E2 on A {
+  int call() => 0;
+}
+
+int f(A a) => a();
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 110, 1),
+    ]);
+  }
+
+  test_getter() async {
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
   void get a => 1;
 }
 
-extension A2_Ext on A {
+extension E2 on A {
   void get a => 2;
 }
 
@@ -39,8 +56,7 @@
   a.a;
 }
 ''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 117, 1),
-      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 117, 1),
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 109, 1),
     ]);
   }
 
@@ -48,11 +64,11 @@
     await assertErrorsInCode('''
 class A {}
 
-extension A1_Ext on A {
+extension E1 on A {
   void a() {}
 }
 
-extension A2_Ext on A {
+extension E2 on A {
   void a() {}
 }
 
@@ -60,20 +76,74 @@
   a.a();
 }
 ''', [
-      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 107, 1),
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 99, 1),
+    ]);
+  }
+
+  test_operator_binary() async {
+    // There is no error reported.
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+  A operator +(A a) => a;
+}
+
+extension E2 on A {
+  A operator +(A a) => a;
+}
+
+A f(A a) => a + a;
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 122, 5),
+    ]);
+  }
+
+  test_operator_index() async {
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+  int operator [](int i) => 0;
+}
+
+extension E2 on A {
+  int operator [](int i) => 0;
+}
+
+int f(A a) => a[0];
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 134, 1),
+    ]);
+  }
+
+  test_operator_unary() async {
+    await assertErrorsInCode('''
+class A {}
+
+extension E1 on A {
+  int operator -() => 0;
+}
+
+extension E2 on A {
+  int operator -() => 0;
+}
+
+int f(A a) => -a;
+''', [
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 123, 1),
     ]);
   }
 
   test_setter() async {
-    // TODO(brianwilkerson) Ensure that only one diagnostic is produced.
     await assertErrorsInCode('''
 class A {}
 
-extension A1_Ext on A {
+extension E1 on A {
   set a(x) {}
 }
 
-extension A2_Ext on A {
+extension E2 on A {
   set a(x) {}
 }
 
@@ -81,8 +151,7 @@
   a.a = 3;
 }
 ''', [
-      error(StaticTypeWarningCode.UNDEFINED_SETTER, 107, 1),
-      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 107, 1),
+      error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_METHOD_ACCESS, 99, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
new file mode 100644
index 0000000..d7ac1a6
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
@@ -0,0 +1,753 @@
+// Copyright (c) 2019, 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:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConflictingStaticAndInstanceClassTest);
+    defineReflectiveTests(ConflictingStaticAndInstanceEnumTest);
+    defineReflectiveTests(ConflictingStaticAndInstanceMixinTest);
+  });
+}
+
+@reflectiveTest
+class ConflictingStaticAndInstanceClassTest extends DriverResolutionTest {
+  test_inClass_getter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inClass_getter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inClass_getter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inClass_method_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inClass_method_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inClass_method_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inClass_setter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inClass_setter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inClass_setter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inInterface_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 81, 3),
+    ]);
+  }
+
+  test_inInterface_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inInterface_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 77, 3),
+    ]);
+  }
+
+  test_inInterface_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inInterface_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inInterface_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inInterface_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+abstract class B implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inInterface_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+abstract class B implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inMixin_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 81, 3),
+    ]);
+  }
+
+  test_inMixin_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inMixin_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 77, 3),
+    ]);
+  }
+
+  test_inMixin_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 78, 3),
+    ]);
+  }
+
+  test_inMixin_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inMixin_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 74, 3),
+    ]);
+  }
+
+  test_inMixin_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends Object with A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inMixin_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends Object with A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 73, 3),
+    ]);
+  }
+
+  test_inSuper_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
+    ]);
+  }
+
+  test_inSuper_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 66, 3),
+    ]);
+  }
+
+  test_inSuper_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
+    ]);
+  }
+
+  test_inSuper_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 66, 3),
+    ]);
+  }
+
+  test_inSuper_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 62, 3),
+    ]);
+  }
+
+  test_inSuper_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 62, 3),
+    ]);
+  }
+
+  test_inSuper_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+class B extends A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+
+  test_inSuper_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+class B extends A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class ConflictingStaticAndInstanceEnumTest extends DriverResolutionTest {
+  test_index() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, index
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 5),
+    ]);
+  }
+}
+
+@reflectiveTest
+class ConflictingStaticAndInstanceMixinTest extends DriverResolutionTest {
+  test_inConstraint_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
+    ]);
+  }
+
+  test_inConstraint_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+
+  test_inConstraint_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 60, 3),
+    ]);
+  }
+
+  test_inConstraint_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 61, 3),
+    ]);
+  }
+
+  test_inConstraint_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
+    ]);
+  }
+
+  test_inConstraint_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 57, 3),
+    ]);
+  }
+
+  test_inConstraint_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M on A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
+    ]);
+  }
+
+  test_inConstraint_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M on A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 56, 3),
+    ]);
+  }
+
+  test_inInterface_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 72, 3),
+    ]);
+  }
+
+  test_inInterface_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
+    ]);
+  }
+
+  test_inInterface_getter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 68, 3),
+    ]);
+  }
+
+  test_inInterface_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 69, 3),
+    ]);
+  }
+
+  test_inInterface_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
+    ]);
+  }
+
+  test_inInterface_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 65, 3),
+    ]);
+  }
+
+  test_inInterface_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+mixin M implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
+    ]);
+  }
+
+  test_inInterface_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  set foo(_) {}
+}
+mixin M implements A {
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 64, 3),
+    ]);
+  }
+
+  test_inMixin_getter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inMixin_getter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inMixin_getter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 27, 3),
+    ]);
+  }
+
+  test_inMixin_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inMixin_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inMixin_method_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 24, 3),
+    ]);
+  }
+
+  test_inMixin_setter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inMixin_setter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+
+  test_inMixin_setter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 23, 3),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
new file mode 100644
index 0000000..8fa1978
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
@@ -0,0 +1,1184 @@
+// Copyright (c) 2019, 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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/test_support.dart';
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DuplicateDefinitionTest);
+    defineReflectiveTests(DuplicateDefinitionClassTest);
+    defineReflectiveTests(DuplicateDefinitionExtensionTest);
+    defineReflectiveTests(DuplicateDefinitionMixinTest);
+  });
+}
+
+@reflectiveTest
+class DuplicateDefinitionClassTest extends DriverResolutionTest {
+  test_instance_field_field() async {
+    await assertErrorsInCode(r'''
+class C {
+  int foo;
+  int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 3),
+    ]);
+  }
+
+  test_instance_field_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  int foo;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 31, 3),
+    ]);
+  }
+
+  test_instance_field_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  int foo;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  final int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  final int foo = 0;
+  set foo(int x) {}
+}
+''');
+  }
+
+  test_instance_getter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 3),
+    ]);
+  }
+
+  test_instance_getter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 3),
+    ]);
+  }
+
+  test_instance_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+  }
+
+  test_instance_method_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 36, 3),
+    ]);
+  }
+
+  test_instance_method_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_method_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 32, 3),
+    ]);
+  }
+
+  test_instance_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+  }
+
+  test_instance_setter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_setter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_field_field() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int foo;
+  static int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_static_field_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int foo;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 45, 3),
+    ]);
+  }
+
+  test_static_field_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int foo;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static final int foo = 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 55, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  static final int foo = 0;
+  static set foo(int x) {}
+}
+''');
+  }
+
+  test_static_getter_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 54, 3),
+    ]);
+  }
+
+  test_static_getter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 51, 3),
+    ]);
+  }
+
+  test_static_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  static int get foo => 0;
+  static set foo(_) {}
+}
+''');
+  }
+
+  test_static_method_getter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 50, 3),
+    ]);
+  }
+
+  test_static_method_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_method_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void foo() {}
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 46, 3),
+    ]);
+  }
+
+  test_static_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_static_setter_method() async {
+    await assertErrorsInCode(r'''
+class C {
+  static set foo(_) {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_setter_setter() async {
+    await assertErrorsInCode(r'''
+class C {
+  static void set foo(_) {}
+  static void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DuplicateDefinitionExtensionTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_extendedType_instance() async {
+    await assertNoErrorsInCode('''
+class A {
+  int get foo => 0;
+  set foo(_) {}
+  void bar() {}
+}
+
+extension E on A {
+  int get foo => 0;
+  set foo(_) {}
+  void bar() {}
+}
+''');
+  }
+
+  test_extendedType_static() async {
+    await assertNoErrorsInCode('''
+class A {
+  static int get foo => 0;
+  static set foo(_) {}
+  static void bar() {}
+}
+
+extension E on A {
+  static int get foo => 0;
+  static set foo(_) {}
+  static void bar() {}
+}
+''');
+  }
+
+  test_instance_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 60, 3),
+    ]);
+  }
+
+  test_instance_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 57, 3),
+    ]);
+  }
+
+  test_instance_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+  }
+
+  test_instance_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
+    ]);
+  }
+
+  test_instance_method_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 53, 3),
+    ]);
+  }
+
+  test_instance_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 52, 3),
+    ]);
+  }
+
+  test_instance_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+  }
+
+  test_instance_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 53, 3),
+    ]);
+  }
+
+  test_instance_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 62, 3),
+    ]);
+  }
+
+  test_static_field_field() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int foo;
+  static int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 61, 3),
+    ]);
+  }
+
+  test_static_field_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int foo;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 65, 3),
+    ]);
+  }
+
+  test_static_field_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int foo;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 62, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static final int foo = 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 75, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  static final int foo = 0;
+  static set foo(int x) {}
+}
+''');
+  }
+
+  test_static_getter_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int get foo => 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 74, 3),
+    ]);
+  }
+
+  test_static_getter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int get foo => 0;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 71, 3),
+    ]);
+  }
+
+  test_static_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+extension E on A {
+  static int get foo => 0;
+  static set foo(_) {}
+}
+''');
+  }
+
+  test_static_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void foo() {}
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 70, 3),
+    ]);
+  }
+
+  test_static_method_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void foo() {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 67, 3),
+    ]);
+  }
+
+  test_static_method_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void foo() {}
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 66, 3),
+    ]);
+  }
+
+  test_static_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_static_setter_method() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static set foo(_) {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 67, 3),
+    ]);
+  }
+
+  test_static_setter_setter() async {
+    await assertErrorsInCode(r'''
+class A {}
+extension E on A {
+  static void set foo(_) {}
+  static void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 76, 3),
+    ]);
+  }
+
+  test_unitMembers_extension() async {
+    await assertErrorsInCode('''
+class A {}
+extension E on A {}
+extension E on A {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DuplicateDefinitionMixinTest extends DriverResolutionTest {
+  test_instance_field_field() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int foo;
+  int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 3),
+    ]);
+  }
+
+  test_instance_field_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int foo;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 31, 3),
+    ]);
+  }
+
+  test_instance_field_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int foo;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  final int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_instance_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  final int foo = 0;
+  set foo(int x) {}
+}
+''');
+  }
+
+  test_instance_getter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 3),
+    ]);
+  }
+
+  test_instance_getter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 3),
+    ]);
+  }
+
+  test_instance_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  int get foo => 0;
+  set foo(_) {}
+}
+''');
+  }
+
+  test_instance_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 36, 3),
+    ]);
+  }
+
+  test_instance_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void foo() {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_method_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 32, 3),
+    ]);
+  }
+
+  test_instance_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  set foo(_) {}
+  int get foo => 0;
+}
+''');
+  }
+
+  test_instance_setter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 33, 3),
+    ]);
+  }
+
+  test_instance_setter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  void set foo(_) {}
+  void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_field_field() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int foo;
+  static int foo;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 41, 3),
+    ]);
+  }
+
+  test_static_field_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int foo;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 45, 3),
+    ]);
+  }
+
+  test_static_field_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int foo;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 42, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static final int foo = 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 55, 3),
+    ]);
+  }
+
+  test_static_fieldFinal_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static final int foo = 0;
+  static set foo(int x) {}
+}
+''');
+  }
+
+  test_static_getter_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 54, 3),
+    ]);
+  }
+
+  test_static_getter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 51, 3),
+    ]);
+  }
+
+  test_static_getter_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static int get foo => 0;
+  static set foo(_) {}
+}
+''');
+  }
+
+  test_static_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  static int get foo => 0;
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 50, 3),
+    ]);
+  }
+
+  test_static_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_method_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void foo() {}
+  static set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 46, 3),
+    ]);
+  }
+
+  test_static_setter_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  static int get foo => 0;
+}
+''');
+  }
+
+  test_static_setter_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static set foo(_) {}
+  static void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 47, 3),
+    ]);
+  }
+
+  test_static_setter_setter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static void set foo(_) {}
+  static void set foo(_) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DuplicateDefinitionTest extends DriverResolutionTest {
+  test_catch() async {
+    await assertErrorsInCode(r'''
+main() {
+  try {} catch (e, e) {}
+}''', [
+      error(HintCode.UNUSED_CATCH_STACK, 28, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
+    ]);
+  }
+
+  test_for_initializers() async {
+    await assertErrorsInCode(r'''
+f() {
+  for (int i = 0, i = 0; i < 5;) {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 24, 1),
+    ]);
+  }
+
+  test_locals_block_if() async {
+    await assertErrorsInCode(r'''
+main(int p) {
+  if (p != 0) {
+    var a;
+    var a;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 38, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 49, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 49, 1),
+    ]);
+  }
+
+  test_locals_block_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  m() {
+    int a;
+    int a;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 26, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 37, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 37, 1),
+    ]);
+  }
+
+  test_locals_block_switchCase() async {
+    await assertErrorsInCode(r'''
+main() {
+  switch(1) {
+    case 1:
+      var a;
+      var a;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 45, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 58, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 58, 1),
+    ]);
+  }
+
+  test_locals_block_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+main() {
+  int m = 0;
+  m(a) {}
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 15, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1),
+      error(HintCode.UNUSED_ELEMENT, 24, 1),
+    ]);
+  }
+
+  test_parameters_constructor() async {
+    await assertErrorsInCode(r'''
+class A {
+  int a;
+  A(int a, this.a);
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 35, 1),
+    ]);
+  }
+
+  test_parameters_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+typedef void F(int a, double a);
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 29, 1),
+    ]);
+  }
+
+  test_parameters_genericFunction() async {
+    await assertErrorsInCode(r'''
+typedef F = void Function(int a, double a);
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 40, 1),
+    ]);
+  }
+
+  test_parameters_localFunction() async {
+    await assertErrorsInCode(r'''
+main() {
+  f(int a, double a) {
+  };
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 11, 1),
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
+    ]);
+  }
+
+  test_parameters_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  m(int a, double a) {
+  }
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
+    ]);
+  }
+
+  test_parameters_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+f(int a, double a) {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 16, 1),
+    ]);
+  }
+
+  test_typeParameters_class() async {
+    await assertErrorsInCode(r'''
+class A<T, T> {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 11, 1),
+    ]);
+  }
+
+  test_typeParameters_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+typedef void F<T, T>();
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 18, 1),
+    ]);
+  }
+
+  test_typeParameters_genericFunction() async {
+    await assertErrorsInCode(r'''
+typedef F = void Function<T, T>();
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 29, 1),
+    ]);
+  }
+
+  test_typeParameters_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  void m<T, T>() {}
+}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 22, 1),
+    ]);
+  }
+
+  test_typeParameters_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+void f<T, T>() {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 10, 1),
+    ]);
+  }
+
+  test_unitMembers_class() async {
+    await assertErrorsInCode('''
+class A {}
+class B {}
+class A {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 28, 1),
+    ]);
+  }
+
+  test_unitMembers_part_library() async {
+    var libPath = convertPath('/test/lib/lib.dart');
+    var aPath = convertPath('/test/lib/a.dart');
+    newFile(libPath, content: '''
+part 'a.dart';
+
+class A {}
+''');
+    newFile(aPath, content: '''
+part of 'lib.dart';
+
+class A {}
+''');
+
+    await resolveFile(libPath);
+
+    var aResult = await resolveFile(aPath);
+    GatheringErrorListener()
+      ..addAll(aResult.errors)
+      ..assertErrors([
+        error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
+      ]);
+  }
+
+  test_unitMembers_part_part() async {
+    var libPath = convertPath('/test/lib/lib.dart');
+    var aPath = convertPath('/test/lib/a.dart');
+    var bPath = convertPath('/test/lib/b.dart');
+    newFile(libPath, content: '''
+part 'a.dart';
+part 'b.dart';
+''');
+    newFile(aPath, content: '''
+part of 'lib.dart';
+
+class A {}
+''');
+    newFile(bPath, content: '''
+part of 'lib.dart';
+
+class A {}
+''');
+
+    await resolveFile(libPath);
+
+    var aResult = await resolveFile(aPath);
+    GatheringErrorListener()
+      ..addAll(aResult.errors)
+      ..assertNoErrors();
+
+    var bResult = await resolveFile(bPath);
+    GatheringErrorListener()
+      ..addAll(bResult.errors)
+      ..assertErrors([
+        error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 1),
+      ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
new file mode 100644
index 0000000..10df3869
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
@@ -0,0 +1,215 @@
+// Copyright (c) 2019, 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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExtensionConflictingStaticAndInstanceTest);
+  });
+}
+
+@reflectiveTest
+class ExtensionConflictingStaticAndInstanceTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  CompileTimeErrorCode get _errorCode =>
+      CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE;
+
+  test_extendedType_field() async {
+    await assertNoErrorsInCode('''
+class A {
+  static int foo = 0;
+  int bar = 0;
+}
+
+extension E on A {
+  int get foo => 0;
+  static int get bar => 0;
+}
+''');
+  }
+
+  test_extendedType_getter() async {
+    await assertNoErrorsInCode('''
+class A {
+  static int get foo => 0;
+  int get bar => 0;
+}
+
+extension E on A {
+  int get foo => 0;
+  static int get bar => 0;
+}
+''');
+  }
+
+  test_extendedType_method() async {
+    await assertNoErrorsInCode('''
+class A {
+  static void foo() {}
+  void bar() {}
+}
+
+extension E on A {
+  void foo() {}
+  static void bar() {}
+}
+''');
+  }
+
+  test_extendedType_setter() async {
+    await assertNoErrorsInCode('''
+class A {
+  static set foo(_) {}
+  set bar(_) {}
+}
+
+extension E on A {
+  set foo(_) {}
+  static set bar(_) {}
+}
+''');
+  }
+
+  test_field_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_field_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int foo = 0;
+  void foo() {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_field_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int foo = 0;
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_getter_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 41, 3),
+    ]);
+  }
+
+  test_getter_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int get foo => 0;
+  void foo() {}
+}
+''', [
+      error(_errorCode, 41, 3),
+    ]);
+  }
+
+  test_getter_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static int get foo => 0;
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 41, 3),
+    ]);
+  }
+
+  test_method_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static void foo() {}
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 38, 3),
+    ]);
+  }
+
+  test_method_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static void foo() {}
+  void foo() {}
+}
+''', [
+      error(_errorCode, 38, 3),
+    ]);
+  }
+
+  test_method_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static void foo() {}
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 38, 3),
+    ]);
+  }
+
+  test_setter_getter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static set foo(_) {}
+  int get foo => 0;
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_setter_method() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static set foo(_) {}
+  void foo() {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+
+  test_setter_setter() async {
+    await assertErrorsInCode('''
+extension E on String {
+  static set foo(_) {}
+  set foo(_) {}
+}
+''', [
+      error(_errorCode, 37, 3),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/if_element_condition_from_deferred_library_test.dart
similarity index 87%
rename from pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
rename to pkg/analyzer/test/src/diagnostics/if_element_condition_from_deferred_library_test.dart
index 7f85015..a717195 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/if_element_condition_from_deferred_library_test.dart
@@ -11,15 +11,14 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonConstantIfElementConditionFromDeferredLibraryTest);
+    defineReflectiveTests(IfElementConditionFromDeferredLibraryTest);
     defineReflectiveTests(
-        NonConstantIfElementConditionFromDeferredLibraryWithConstantsTest);
+        IfElementConditionFromDeferredLibraryWithConstantsTest);
   });
 }
 
 @reflectiveTest
-class NonConstantIfElementConditionFromDeferredLibraryTest
-    extends DriverResolutionTest {
+class IfElementConditionFromDeferredLibraryTest extends DriverResolutionTest {
   test_inList_deferred() async {
     newFile(convertPath('/test/lib/lib1.dart'), content: r'''
 const bool c = true;''');
@@ -33,7 +32,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
+                        .IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -81,7 +80,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
+                        .IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -129,7 +128,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
+                        .IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -166,8 +165,8 @@
 }
 
 @reflectiveTest
-class NonConstantIfElementConditionFromDeferredLibraryWithConstantsTest
-    extends NonConstantIfElementConditionFromDeferredLibraryTest {
+class IfElementConditionFromDeferredLibraryWithConstantsTest
+    extends IfElementConditionFromDeferredLibraryTest {
   @override
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
diff --git a/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart b/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
new file mode 100644
index 0000000..cd3cb61
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/instance_access_to_static_member_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2019, 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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InstanceAccessToStaticMemberTest);
+    defineReflectiveTests(InstanceAccessToStaticMemberWithExtensionMethodsTest);
+  });
+}
+
+@reflectiveTest
+class InstanceAccessToStaticMemberTest extends DriverResolutionTest {}
+
+@reflectiveTest
+class InstanceAccessToStaticMemberWithExtensionMethodsTest
+    extends InstanceAccessToStaticMemberTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_getter() async {
+    await assertErrorsInCode('''
+class C {}
+
+extension E on C {
+  static int get a => 0;
+}
+
+C g(C c) => null;
+f(C c) {
+  g(c).a;
+}
+''', [
+      error(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 93, 1),
+    ]);
+    assertElement(
+      findNode.simple('a;'),
+      findElement.getter('a'),
+    );
+  }
+
+  test_method() async {
+    await assertErrorsInCode('''
+class C {}
+
+extension E on C {
+  static void a() {}
+}
+
+f(C c) {
+  c.a();
+}
+''', [
+      error(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 68, 1),
+    ]);
+    assertElement(
+      findNode.methodInvocation('a();'),
+      findElement.method('a'),
+    );
+  }
+
+  test_setter() async {
+    await assertErrorsInCode('''
+class C {}
+
+extension E on C {
+  static set a(v) {}
+}
+
+f(C c) {
+  c.a = 2;
+}
+''', [
+      error(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 68, 1),
+    ]);
+    assertElement(
+      findNode.simple('a = 2;'),
+      findElement.setter('a'),
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart b/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart
index ec3b2bc..d4c8ccd 100644
--- a/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mismatched_getter_and_setter_types_test.dart
@@ -2,7 +2,9 @@
 // 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:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -10,6 +12,9 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MismatchedGetterAndSetterTypesTest);
+    defineReflectiveTests(
+        MismatchedGetterAndSetterTypesWithExtensionMethodsTest);
+    defineReflectiveTests(MismatchedGetterAndSetterTypesWithNNBDTest);
   });
 }
 
@@ -23,3 +28,66 @@
     ]);
   }
 }
+
+@reflectiveTest
+class MismatchedGetterAndSetterTypesWithExtensionMethodsTest
+    extends MismatchedGetterAndSetterTypesTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_extensionMembers_instance() async {
+    await assertErrorsInCode('''
+extension E on Object {
+  int get g { return 0; }
+  set g(String v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 34, 1),
+    ]);
+  }
+
+  test_extensionMembers_static() async {
+    await assertErrorsInCode('''
+extension E on Object {
+  static int get g { return 0; }
+  static set g(String v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 41, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class MismatchedGetterAndSetterTypesWithNNBDTest
+    extends MismatchedGetterAndSetterTypesTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  test_classMembers_instance() async {
+    await assertErrorsInCode('''
+class C {
+  num get g { return 0; }
+  set g(int v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 20, 1),
+    ]);
+  }
+
+  @failingTest
+  test_classMembers_static() async {
+    await assertErrorsInCode('''
+class C {
+  static num get g { return 0; }
+  static set g(int v) {}
+}
+''', [
+      error(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, 12, 30),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart b/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
index 8bd294a..ee4c362 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
@@ -4,15 +4,15 @@
 
 import 'package:pub_semver/pub_semver.dart';
 
-import '../dart/resolution/driver_resolution.dart';
 import '../../generated/test_support.dart';
+import '../dart/resolution/driver_resolution.dart';
 
 /// A base class designed to be used by tests of the hints produced by the
 /// SdkConstraintVerifier.
 class SdkConstraintVerifierTest extends DriverResolutionTest {
   /// Verify that the [errorCodes] are produced if the [source] is analyzed in
   /// a context that specifies the minimum SDK version to be [version].
-  verifyVersion(String version, String source,
+  Future<void> verifyVersion(String version, String source,
       {List<ExpectedError> expectedErrors}) async {
     driver.configure(
         analysisOptions: analysisOptions
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart
index d7f2330..095a6a2 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_as_expression_in_const_context_test.dart
@@ -22,15 +22,15 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
 
-  test_equals() {
-    verifyVersion('2.5.0', '''
+  test_equals() async {
+    await verifyVersion('2.5.0', '''
 const dynamic a = 2;
 const c = (a as int) + 2;
 ''');
   }
 
-  test_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_lessThan() async {
+    await verifyVersion('2.2.0', '''
 const dynamic a = 2;
 const c = (a as int) + 2;
 ''', expectedErrors: [
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_in_const_context_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_in_const_context_test.dart
new file mode 100644
index 0000000..32adcd5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_in_const_context_test.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2019, 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:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'sdk_constraint_verifier_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SdkVersionBoolOperatorInConstContextTest);
+  });
+}
+
+@reflectiveTest
+class SdkVersionBoolOperatorInConstContextTest
+    extends SdkConstraintVerifierTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [EnableString.constant_update_2018];
+
+  test_and_const_equals() async {
+    await verifyVersion('2.5.0', '''
+const c = true & false;
+''');
+  }
+
+  test_and_const_lessThan() async {
+    await verifyVersion('2.2.0', '''
+const c = true & false;
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT, 15, 1),
+    ]);
+  }
+
+  test_and_nonConst_equals() async {
+    await verifyVersion('2.5.0', '''
+var c = true & false;
+''');
+  }
+
+  test_and_nonConst_lessThan() async {
+    await verifyVersion('2.2.0', '''
+var c = true & false;
+''');
+  }
+
+  test_or_const_equals() async {
+    await verifyVersion('2.5.0', '''
+const c = true | false;
+''');
+  }
+
+  test_or_const_lessThan() async {
+    await verifyVersion('2.2.0', '''
+const c = true | false;
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT, 15, 1),
+    ]);
+  }
+
+  test_or_nonConst_equals() async {
+    await verifyVersion('2.5.0', '''
+var c = true | false;
+''');
+  }
+
+  test_or_nonConst_lessThan() async {
+    await verifyVersion('2.2.0', '''
+var c = true | false;
+''');
+  }
+
+  test_xor_const_equals() async {
+    await verifyVersion('2.5.0', '''
+const c = true ^ false;
+''');
+  }
+
+  test_xor_const_lessThan() async {
+    await verifyVersion('2.2.0', '''
+const c = true ^ false;
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT, 15, 1),
+    ]);
+  }
+
+  test_xor_nonConst_equals() async {
+    await verifyVersion('2.5.0', '''
+var c = true ^ false;
+''');
+  }
+
+  test_xor_nonConst_lessThan() async {
+    await verifyVersion('2.2.0', '''
+var c = true ^ false;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_test.dart
deleted file mode 100644
index 6cd9411..0000000
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_bool_operator_test.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2019, 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:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'sdk_constraint_verifier_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(SdkVersionBoolOperatorTest);
-  });
-}
-
-@reflectiveTest
-class SdkVersionBoolOperatorTest extends SdkConstraintVerifierTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..enabledExperiments = [EnableString.constant_update_2018];
-
-  test_and_const_equals() {
-    verifyVersion('2.5.0', '''
-const c = true & false;
-''');
-  }
-
-  test_and_const_lessThan() {
-    verifyVersion('2.2.0', '''
-const c = true & false;
-''', expectedErrors: [
-      error(HintCode.SDK_VERSION_BOOL_OPERATOR, 15, 1),
-    ]);
-  }
-
-  test_and_nonConst_equals() {
-    verifyVersion('2.5.0', '''
-var c = true & false;
-''');
-  }
-
-  test_and_nonConst_lessThan() {
-    verifyVersion('2.2.0', '''
-var c = true & false;
-''');
-  }
-
-  test_or_const_equals() {
-    verifyVersion('2.5.0', '''
-const c = true | false;
-''');
-  }
-
-  test_or_const_lessThan() {
-    verifyVersion('2.2.0', '''
-const c = true | false;
-''', expectedErrors: [
-      error(HintCode.SDK_VERSION_BOOL_OPERATOR, 15, 1),
-    ]);
-  }
-
-  test_or_nonConst_equals() {
-    verifyVersion('2.5.0', '''
-var c = true | false;
-''');
-  }
-
-  test_or_nonConst_lessThan() {
-    verifyVersion('2.2.0', '''
-var c = true | false;
-''');
-  }
-
-  test_xor_const_equals() {
-    verifyVersion('2.5.0', '''
-const c = true ^ false;
-''');
-  }
-
-  test_xor_const_lessThan() {
-    verifyVersion('2.2.0', '''
-const c = true ^ false;
-''', expectedErrors: [
-      error(HintCode.SDK_VERSION_BOOL_OPERATOR, 15, 1),
-    ]);
-  }
-
-  test_xor_nonConst_equals() {
-    verifyVersion('2.5.0', '''
-var c = true ^ false;
-''');
-  }
-
-  test_xor_nonConst_lessThan() {
-    verifyVersion('2.2.0', '''
-var c = true ^ false;
-''');
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart
index a173f44..4e7d20b 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_eq_eq_operator_test.dart
@@ -21,8 +21,8 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
 
-  test_left_equals() {
-    verifyVersion('2.5.0', '''
+  test_left_equals() async {
+    await verifyVersion('2.5.0', '''
 class A {
   const A();
 }
@@ -31,8 +31,8 @@
 ''');
   }
 
-  test_left_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_left_lessThan() async {
+    await verifyVersion('2.2.0', '''
 class A {
   const A();
 }
@@ -43,8 +43,8 @@
     ]);
   }
 
-  test_right_equals() {
-    verifyVersion('2.5.0', '''
+  test_right_equals() async {
+    await verifyVersion('2.5.0', '''
 class A {
   const A();
 }
@@ -53,8 +53,8 @@
 ''');
   }
 
-  test_right_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_right_lessThan() async {
+    await verifyVersion('2.2.0', '''
 class A {
   const A();
 }
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
new file mode 100644
index 0000000..9afa451
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_extension_methods_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2019, 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:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'sdk_constraint_verifier_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SdkVersionExtensionMethodsTest);
+  });
+}
+
+@reflectiveTest
+class SdkVersionExtensionMethodsTest extends SdkConstraintVerifierTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [EnableString.extension_methods];
+
+  @failingTest
+  test_extension_equals() async {
+    await verifyVersion('2.6.0', '''
+extension E on int {}
+''');
+  }
+
+  test_extension_lessThan() async {
+    await verifyVersion('2.2.0', '''
+extension E on int {}
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_EXTENSION_METHODS, 0, 9),
+    ]);
+  }
+
+  @failingTest
+  test_extensionOverride_equals() async {
+    await verifyVersion('2.6.0', '''
+extension E on int {
+  int get a => 0;
+}
+void f() {
+  E(0).a;
+}
+''');
+  }
+
+  test_extensionOverride_lessThan() async {
+    await verifyVersion('2.2.0', '''
+extension E on int {
+  int get a => 0;
+}
+void f() {
+  E(0).a;
+}
+''', expectedErrors: [
+      error(HintCode.SDK_VERSION_EXTENSION_METHODS, 0, 9),
+      error(HintCode.SDK_VERSION_EXTENSION_METHODS, 54, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
index 416079f..d73c523 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_gt_gt_gt_operator_test.dart
@@ -21,20 +21,20 @@
   AnalysisOptionsImpl get analysisOptions =>
       AnalysisOptionsImpl()..enabledExperiments = [EnableString.triple_shift];
 
-  test_const_equals() {
+  test_const_equals() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
-    verifyVersion('2.5.0', '''
+    await verifyVersion('2.5.0', '''
 const a = 42 >>> 3;
 ''', expectedErrors: [
       error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 13, 3),
     ]);
   }
 
-  test_const_lessThan() {
+  test_const_lessThan() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when triple_shift is enabled by default.
-    verifyVersion('2.2.0', '''
+    await verifyVersion('2.2.0', '''
 const a = 42 >>> 3;
 ''', expectedErrors: [
       error(HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, 13, 3),
@@ -42,16 +42,16 @@
     ]);
   }
 
-  test_declaration_equals() {
-    verifyVersion('2.5.0', '''
+  test_declaration_equals() async {
+    await verifyVersion('2.5.0', '''
 class A {
   A operator >>>(A a) => this;
 }
 ''');
   }
 
-  test_declaration_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_declaration_lessThan() async {
+    await verifyVersion('2.2.0', '''
 class A {
   A operator >>>(A a) => this;
 }
@@ -60,20 +60,20 @@
     ]);
   }
 
-  test_nonConst_equals() {
+  test_nonConst_equals() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when constant update is enabled by default.
-    verifyVersion('2.5.0', '''
+    await verifyVersion('2.5.0', '''
 var a = 42 >>> 3;
 ''', expectedErrors: [
       error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 11, 3),
     ]);
   }
 
-  test_nonConst_lessThan() {
+  test_nonConst_lessThan() async {
     // TODO(brianwilkerson) Add '>>>' to MockSdk and remove the code
     //  UNDEFINED_OPERATOR when constant update is enabled by default.
-    verifyVersion('2.2.0', '''
+    await verifyVersion('2.2.0', '''
 var a = 42 >>> 3;
 ''', expectedErrors: [
       error(HintCode.SDK_VERSION_GT_GT_GT_OPERATOR, 11, 3),
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart
index ab7ff21..517982f 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_is_expression_in_const_context_test.dart
@@ -22,15 +22,15 @@
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
 
-  test_equals() {
-    verifyVersion('2.5.0', '''
+  test_equals() async {
+    await verifyVersion('2.5.0', '''
 const dynamic a = 2;
 const c = a is int;
 ''');
   }
 
-  test_lessThan() {
-    verifyVersion('2.2.0', '''
+  test_lessThan() async {
+    await verifyVersion('2.2.0', '''
 const dynamic a = 2;
 const c = a is int;
 ''', expectedErrors: [
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/set_element_from_deferred_library_test.dart
similarity index 70%
rename from pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
rename to pkg/analyzer/test/src/diagnostics/set_element_from_deferred_library_test.dart
index 7dd39c4..ff2ce80 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/set_element_from_deferred_library_test.dart
@@ -11,15 +11,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonConstantSetElementFromDeferredLibraryTest);
-    defineReflectiveTests(
-        NonConstantSetElementFromDeferredLibraryWithConstantsTest);
+    defineReflectiveTests(SetElementFromDeferredLibraryTest);
+    defineReflectiveTests(SetElementFromDeferredLibraryWithConstantsTest);
   });
 }
 
 @reflectiveTest
-class NonConstantSetElementFromDeferredLibraryTest
-    extends DriverResolutionTest {
+class SetElementFromDeferredLibraryTest extends DriverResolutionTest {
   @failingTest
   test_const_ifElement_thenTrue_elseDeferred() async {
     // reports wrong error code
@@ -30,8 +28,7 @@
 const cond = true;
 var v = const {if (cond) null else a.c};
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-          88, 3),
+      error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY, 88, 3),
     ]);
   }
 
@@ -46,11 +43,8 @@
 ''',
         analysisOptions.experimentStatus.constant_update_2018
             ? [
-                error(
-                    CompileTimeErrorCode
-                        .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-                    78,
-                    3),
+                error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
+                    78, 3),
               ]
             : [
                 error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT, 68, 13),
@@ -64,8 +58,7 @@
 import 'lib1.dart' deferred as a;
 var v = const {a.c};
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-          49, 3),
+      error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY, 49, 3),
     ]);
   }
 
@@ -76,15 +69,14 @@
 import 'lib1.dart' deferred as a;
 var v = const {a.c + 1};
 ''', [
-      error(CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
-          49, 7),
+      error(CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY, 49, 7),
     ]);
   }
 }
 
 @reflectiveTest
-class NonConstantSetElementFromDeferredLibraryWithConstantsTest
-    extends NonConstantSetElementFromDeferredLibraryTest {
+class SetElementFromDeferredLibraryWithConstantsTest
+    extends SetElementFromDeferredLibraryTest {
   @override
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/spread_expression_from_deferred_library_test.dart
similarity index 87%
rename from pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
rename to pkg/analyzer/test/src/diagnostics/spread_expression_from_deferred_library_test.dart
index b8ad8b4..88274ec 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/spread_expression_from_deferred_library_test.dart
@@ -11,15 +11,13 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(NonConstantSpreadExpressionFromDeferredLibraryTest);
-    defineReflectiveTests(
-        NonConstantSpreadExpressionFromDeferredLibraryWithConstantsTest);
+    defineReflectiveTests(SpreadExpressionFromDeferredLibraryTest);
+    defineReflectiveTests(SpreadExpressionFromDeferredLibraryWithConstantsTest);
   });
 }
 
 @reflectiveTest
-class NonConstantSpreadExpressionFromDeferredLibraryTest
-    extends DriverResolutionTest {
+class SpreadExpressionFromDeferredLibraryTest extends DriverResolutionTest {
   test_inList_deferred() async {
     newFile(convertPath('/test/lib/lib1.dart'), content: r'''
 const List c = [];''');
@@ -33,7 +31,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+                        .SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -81,7 +79,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+                        .SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -129,7 +127,7 @@
             ? [
                 error(
                     CompileTimeErrorCode
-                        .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
+                        .SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
                     59,
                     3),
               ]
@@ -166,8 +164,8 @@
 }
 
 @reflectiveTest
-class NonConstantSpreadExpressionFromDeferredLibraryWithConstantsTest
-    extends NonConstantSpreadExpressionFromDeferredLibraryTest {
+class SpreadExpressionFromDeferredLibraryWithConstantsTest
+    extends SpreadExpressionFromDeferredLibraryTest {
   @override
   AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
     ..enabledExperiments = [EnableString.constant_update_2018];
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3f0007b..0d182ed 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -4,8 +4,6 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'access_static_extension_member_test.dart'
-    as access_static_extension_member;
 import 'ambiguous_export_test.dart' as ambiguous_export;
 import 'ambiguous_extension_method_access_test.dart'
     as ambiguous_extension_method_access;
@@ -27,6 +25,8 @@
 import 'cast_to_non_type_test.dart' as cast_to_non_type;
 import 'concrete_class_with_abstract_member_test.dart'
     as concrete_class_with_abstract_member;
+import 'conflicting_static_and_instance_test.dart'
+    as conflicting_static_and_instance;
 import 'const_constructor_param_type_mismatch_test.dart'
     as const_constructor_param_type_mismatch;
 import 'const_constructor_with_mixin_with_field_test.dart'
@@ -52,6 +52,7 @@
 import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
 import 'division_optimization_test.dart' as division_optimization;
 import 'down_cast_composite_test.dart' as down_cast_composite;
+import 'duplicate_definition_test.dart' as duplicate_definition;
 import 'duplicate_hidden_name_test.dart' as duplicate_hidden_name;
 import 'duplicate_import_test.dart' as duplicate_import;
 import 'duplicate_shown_name_test.dart' as duplicate_shown_name;
@@ -61,6 +62,8 @@
     as export_suplicated_library_named;
 import 'expression_in_map_test.dart' as expression_in_map;
 import 'extends_non_class_test.dart' as extends_non_class;
+import 'extension_conflicting_static_and_instance_test.dart'
+    as extension_conflicting_static_and_instance;
 import 'extension_declares_abstract_method_test.dart'
     as extension_declares_abstract_method;
 import 'extension_declares_constructor_test.dart'
@@ -86,6 +89,8 @@
 import 'final_not_initialized_constructor_test.dart'
     as final_not_initialized_constructor;
 import 'final_not_initialized_test.dart' as final_not_initialized;
+import 'if_element_condition_from_deferred_library_test.dart'
+    as if_element_condition_from_deferred_library;
 import 'implements_non_class_test.dart' as implements_non_class;
 import 'implicit_this_reference_in_initializer_test.dart'
     as implicit_this_reference_in_initializer;
@@ -94,6 +99,8 @@
 import 'import_duplicated_library_named_test.dart'
     as import_duplicated_library_named;
 import 'import_of_non_library_test.dart' as import_of_non_library;
+import 'instance_access_to_static_member_test.dart'
+    as instance_access_to_static_member;
 import 'invalid_assignment_test.dart' as invalid_assignment;
 import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr;
 import 'invalid_extension_argument_count_test.dart'
@@ -160,8 +167,6 @@
 import 'non_bool_condition_test.dart' as non_bool_condition;
 import 'non_bool_negation_expression_test.dart' as non_bool_negation_expression;
 import 'non_bool_operand_test.dart' as non_bool_operand;
-import 'non_constant_if_element_condition_from_deferred_library_test.dart'
-    as non_constant_if_element_condition_from_deferred_library;
 import 'non_constant_list_element_from_deferred_library_test.dart'
     as non_constant_list_element_from_deferred_library;
 import 'non_constant_list_element_test.dart' as non_constant_list_element;
@@ -172,11 +177,7 @@
 import 'non_constant_map_value_from_deferred_library_test.dart'
     as non_constant_map_value_from_deferred_library;
 import 'non_constant_map_value_test.dart' as non_constant_map_value;
-import 'non_constant_set_element_from_deferred_library_test.dart'
-    as non_constant_set_element_from_deferred_library;
 import 'non_constant_set_element_test.dart' as non_constant_set_element;
-import 'non_constant_spread_expression_from_deferred_library_test.dart'
-    as non_constant_spread_expression_from_deferred_library;
 import 'non_null_opt_out_test.dart' as non_null_opt_out;
 import 'non_type_in_catch_clause_test.dart' as non_type_in_catch_clause;
 import 'non_void_return_for_operator_test.dart' as non_void_return_for_operator;
@@ -228,8 +229,11 @@
     as sdk_version_as_expression_in_const_context;
 import 'sdk_version_async_exported_from_core_test.dart'
     as sdk_version_async_exported_from_core;
-import 'sdk_version_bool_operator_test.dart' as sdk_version_bool_operator;
+import 'sdk_version_bool_operator_in_const_context_test.dart'
+    as sdk_version_bool_operator_in_const_context;
 import 'sdk_version_eq_eq_operator_test.dart' as sdk_version_eq_eq_operator;
+import 'sdk_version_extension_methods_test.dart'
+    as sdk_version_extension_methods;
 import 'sdk_version_gt_gt_gt_operator_test.dart'
     as sdk_version_gt_gt_gt_operator;
 import 'sdk_version_is_expression_in_const_context_test.dart'
@@ -239,14 +243,20 @@
 import 'sdk_version_ui_as_code_in_const_context_test.dart'
     as sdk_version_ui_as_code_in_const_context;
 import 'sdk_version_ui_as_code_test.dart' as sdk_version_ui_as_code;
+import 'set_element_from_deferred_library_test.dart'
+    as set_element_from_deferred_library;
 import 'set_element_type_not_assignable_test.dart'
     as set_element_type_not_assignable;
+import 'spread_expression_from_deferred_library_test.dart'
+    as spread_expression_from_deferred_library;
 import 'static_access_to_instance_member_test.dart'
     as static_access_to_instance_member;
 import 'subtype_of_sealed_class_test.dart' as subtype_of_sealed_class;
 import 'super_in_extension_test.dart' as super_in_extension;
 import 'top_level_instance_getter_test.dart' as top_level_instance_getter;
 import 'top_level_instance_method_test.dart' as top_level_instance_method;
+import 'type_argument_not_matching_bounds_test.dart'
+    as type_argument_not_matching_bounds;
 import 'type_check_is_not_null_test.dart' as type_check_is_not_null;
 import 'type_check_is_null_test.dart' as type_check_is_null;
 import 'unchecked_use_of_nullable_value_test.dart'
@@ -286,7 +296,6 @@
 
 main() {
   defineReflectiveSuite(() {
-    access_static_extension_member.main();
     ambiguous_export.main();
     ambiguous_extension_method_access.main();
     ambiguous_import.main();
@@ -304,6 +313,7 @@
     case_block_not_terminated.main();
     cast_to_non_type.main();
     concrete_class_with_abstract_member.main();
+    conflicting_static_and_instance.main();
     const_constructor_param_type_mismatch.main();
     const_constructor_with_mixin_with_field.main();
     const_eval_throws_exception.main();
@@ -321,6 +331,7 @@
     deprecated_mixin_function.main();
     division_optimization.main();
     down_cast_composite.main();
+    duplicate_definition.main();
     duplicate_hidden_name.main();
     duplicate_import.main();
     duplicate_shown_name.main();
@@ -329,6 +340,7 @@
     export_suplicated_library_named.main();
     expression_in_map.main();
     extends_non_class.main();
+    extension_conflicting_static_and_instance.main();
     extension_declares_abstract_method.main();
     extension_declares_constructor.main();
     extension_declares_field.main();
@@ -343,11 +355,13 @@
     final_initialized_in_delcaration_and_constructor.main();
     final_not_initialized_constructor.main();
     final_not_initialized.main();
+    if_element_condition_from_deferred_library.main();
     implements_non_class.main();
     implicit_this_reference_in_initializer.main();
     import_deferred_library_with_load_function.main();
     import_duplicated_library_named.main();
     import_of_non_library.main();
+    instance_access_to_static_member.main();
     invalid_assignment.main();
     invalid_cast_new_expr.main();
     invalid_extension_argument_count.main();
@@ -397,7 +411,6 @@
     non_bool_condition.main();
     non_bool_negation_expression.main();
     non_bool_operand.main();
-    non_constant_if_element_condition_from_deferred_library.main();
     non_constant_list_element.main();
     non_constant_list_element_from_deferred_library.main();
     non_constant_map_key.main();
@@ -406,8 +419,6 @@
     non_constant_map_value.main();
     non_constant_map_value_from_deferred_library.main();
     non_constant_set_element.main();
-    non_constant_set_element_from_deferred_library.main();
-    non_constant_spread_expression_from_deferred_library.main();
     non_null_opt_out.main();
     non_type_in_catch_clause.main();
     non_void_return_for_operator.main();
@@ -439,10 +450,12 @@
     redirect_to_missing_constructor.main();
     redirect_to_non_class.main();
     return_without_value.main();
+    set_element_from_deferred_library.main();
     sdk_version_as_expression_in_const_context.main();
     sdk_version_async_exported_from_core.main();
-    sdk_version_bool_operator.main();
+    sdk_version_bool_operator_in_const_context.main();
     sdk_version_eq_eq_operator.main();
+    sdk_version_extension_methods.main();
     sdk_version_gt_gt_gt_operator.main();
     sdk_version_is_expression_in_const_context.main();
     sdk_version_never.main();
@@ -450,11 +463,13 @@
     sdk_version_ui_as_code.main();
     sdk_version_ui_as_code_in_const_context.main();
     set_element_type_not_assignable.main();
+    spread_expression_from_deferred_library.main();
     static_access_to_instance_member.main();
     subtype_of_sealed_class.main();
     super_in_extension.main();
     top_level_instance_getter.main();
     top_level_instance_method.main();
+    type_argument_not_matching_bounds.main();
     type_check_is_not_null.main();
     type_check_is_null.main();
     unchecked_use_of_nullable_value.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
new file mode 100644
index 0000000..e1c52d5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -0,0 +1,347 @@
+// Copyright (c) 2019, 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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TypeArgumentNotMatchingBoundsTest);
+    defineReflectiveTests(
+      TypeArgumentNotMatchingBoundsWithExtensionMethodsTest,
+    );
+  });
+}
+
+@reflectiveTest
+class TypeArgumentNotMatchingBoundsTest extends DriverResolutionTest {
+  test_classTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C {}
+class G<E extends A> {}
+class D = G<B> with C;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
+    ]);
+  }
+
+  test_const() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {
+  const G();
+}
+f() { return const G<B>(); }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1),
+    ]);
+  }
+
+  test_extends() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C extends G<B>{}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+    ]);
+  }
+
+  test_extends_regressionInIssue18468Fix() async {
+    // https://code.google.com/p/dart/issues/detail?id=18628
+    await assertErrorsInCode(r'''
+class X<T extends Type> {}
+class Y<U> extends X<U> {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+    ]);
+  }
+
+  test_fieldFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C {
+  var f;
+  C(G<B> this.f) {}
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
+    ]);
+  }
+
+  test_functionReturnType() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+G<B> f() { return null; }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+    ]);
+  }
+
+  test_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+typedef G<B> f();
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
+    ]);
+  }
+
+  test_functionTypedFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f(G<B> h()) {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+    ]);
+  }
+
+  test_implements() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C implements G<B>{}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
+    ]);
+  }
+
+  test_is() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+var b = 1 is G<B>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
+    ]);
+  }
+
+  test_methodInvocation_localFunction() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+main() {
+  Point<T> f<T extends num>(T x, T y) {
+    return new Point<T>(x, y);
+  }
+  print(f<String>('hello', 'world'));
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
+    ]);
+  }
+
+  test_methodInvocation_method() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+class PointFactory {
+  Point<T> point<T extends num>(T x, T y) {
+    return new Point<T>(x, y);
+  }
+}
+
+f(PointFactory factory) {
+  print(factory.point<String>('hello', 'world'));
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
+    ]);
+  }
+
+  test_methodInvocation_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+Point<T> f<T extends num>(T x, T y) {
+  return new Point<T>(x, y);
+}
+
+main() {
+  print(f<String>('hello', 'world'));
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
+    ]);
+  }
+
+  test_methodReturnType() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C {
+  G<B> m() { return null; }
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
+    ]);
+  }
+
+  test_new() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f() { return new G<B>(); }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
+    ]);
+  }
+
+  test_new_superTypeOfUpperBound() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {}
+class C extends B {}
+class G<E extends B> {}
+f() { return new G<A>(); }
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
+    ]);
+  }
+
+  test_ofFunctionTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+typedef F<T extends A>();
+F<B> fff;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+    ]);
+  }
+
+  test_parameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f(G<B> g) {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+    ]);
+  }
+
+  test_redirectingConstructor() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class X<T extends A> {
+  X(int x, int y) {}
+  factory X.name(int x, int y) = X<B>;
+}
+''', [
+      error(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
+    ]);
+  }
+
+  test_typeArgumentList() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C<E> {}
+class D<E extends A> {}
+C<D<B>> Var;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+    ]);
+  }
+
+  test_typeParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C {}
+class G<E extends A> {}
+class D<F extends G<B>> {}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
+    ]);
+  }
+
+  test_variableDeclaration() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+G<B> g;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+    ]);
+  }
+
+  test_with() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C extends Object with G<B>{}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class TypeArgumentNotMatchingBoundsWithExtensionMethodsTest
+    extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+  test_extensionOverride_hasTypeArguments() async {
+    await assertErrorsInCode(r'''
+extension E<T extends num> on int {
+  void foo() {}
+}
+
+void f() {
+  E<String>(0).foo();
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 70, 6),
+    ]);
+  }
+
+  test_extensionOverride_hasTypeArguments_call() async {
+    await assertErrorsInCode(r'''
+extension E<T extends num> on int {
+  void call() {}
+}
+
+void f() {
+  E<String>(0)();
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 6),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index 385c03e..fcdb51f3 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -22,6 +23,7 @@
 import 'test_strategies.dart';
 
 main() {
+  if (AnalysisDriver.useSummary2) return;
   defineReflectiveSuite(() {
     defineReflectiveTests(ExprBuilderTest);
     defineReflectiveTests(ExprBuilderWithConstantUpdateTest);
diff --git a/pkg/analyzer/test/src/summary/prelinker_test.dart b/pkg/analyzer/test/src/summary/prelinker_test.dart
index 59d8a62..6e932bd 100644
--- a/pkg/analyzer/test/src/summary/prelinker_test.dart
+++ b/pkg/analyzer/test/src/summary/prelinker_test.dart
@@ -2,12 +2,14 @@
 // 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:analyzer/src/dart/analysis/driver.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'summary_common.dart';
 import 'test_strategies.dart';
 
 main() {
+  if (AnalysisDriver.useSummary2) return;
   defineReflectiveSuite(() {
     defineReflectiveTests(PrelinkerTest);
   });
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index ff7f676..8745996 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -10093,6 +10093,35 @@
 ''');
   }
 
+  test_type_inference_instanceCreation_notGeneric() async {
+    var library = await checkLibrary('''
+class A {
+  A(_);
+}
+var a = A(() => b);
+var b = A(() => a);
+''');
+    if (isAstBasedSummary) {
+      // There is no cycle with `a` and `b`, because `A` is not generic,
+      // so the type of `new A(...)` does not depend on its arguments.
+      checkElementText(library, '''
+class A {
+  A(dynamic _);
+}
+A a;
+A b;
+''');
+    } else {
+      checkElementText(library, '''
+class A {
+  A(dynamic _);
+}
+dynamic a/*error: dependencyCycle*/;
+dynamic b/*error: dependencyCycle*/;
+''');
+    }
+  }
+
   test_type_inference_multiplyDefinedElement() async {
     addLibrarySource('/a.dart', 'class C {}');
     addLibrarySource('/b.dart', 'class C {}');
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index 7a9c6bf..3911aab 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -2,12 +2,14 @@
 // 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:analyzer/src/dart/analysis/driver.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'summary_common.dart';
 import 'test_strategies.dart';
 
 main() {
+  if (AnalysisDriver.useSummary2) return;
   defineReflectiveSuite(() {
     defineReflectiveTests(LinkedSummarizeAstStrongTest);
   });
diff --git a/pkg/analyzer/test/util/id_testing_helper.dart b/pkg/analyzer/test/util/id_testing_helper.dart
index 7002715..28fa311 100644
--- a/pkg/analyzer/test/util/id_testing_helper.dart
+++ b/pkg/analyzer/test/util/id_testing_helper.dart
@@ -56,16 +56,15 @@
   computeExpectedMap(testFileUri, testFileName, code, expectedMaps,
       onFailure: onFailure);
   Map<Uri, AnnotatedCode> codeMap = {testFileUri: code};
-  var libFileNames = <String>[];
-  var testData = TestData(testFileUri, testFileUri, memorySourceFiles, codeMap,
-      expectedMaps, libFileNames);
+  var testData = TestData(testFileName, testFileUri, testFileUri,
+      memorySourceFiles, codeMap, expectedMaps);
   var config =
       TestConfig(marker, 'provisional test config', featureSet: featureSet);
   return runTestForConfig<T>(testData, dataComputer, config);
 }
 
 /// Creates the testing URI used for [fileName] in annotated tests.
-Uri createUriForFileName(String fileName, {bool isLib}) => _toTestUri(fileName);
+Uri createUriForFileName(String fileName) => _toTestUri(fileName);
 
 void onFailure(String message) {
   throw StateError(message);
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 287af32..52a0e77 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1060,8 +1060,8 @@
 
     Element element = type.element;
 
-    // No element, e.g. "void".
-    if (element == null) {
+    // The type `void` does not have an element.
+    if (type is VoidType) {
       write(type.displayName);
       return true;
     }
@@ -1074,14 +1074,12 @@
     }
 
     // Just a Function, not FunctionTypeAliasElement.
-    if (type is FunctionType &&
-        element is FunctionTypedElement &&
-        element is! FunctionTypeAliasElement) {
+    if (type is FunctionType && element is! FunctionTypeAliasElement) {
       if (_writeType(type.returnType, methodBeingCopied: methodBeingCopied)) {
         write(' ');
       }
       write('Function');
-      writeTypeParameters(element.typeParameters,
+      writeTypeParameters(type.typeFormals,
           methodBeingCopied: methodBeingCopied);
       writeParameters(type.parameters, methodBeingCopied: methodBeingCopied);
       return true;
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 9e50791..2b22b73 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -616,6 +616,14 @@
   }
 
   @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    // Make suggestions in the body of the extension declaration
+    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
   visitFieldDeclaration(FieldDeclaration node) {
     if (offset <= node.semicolon.offset) {
       optype.includeVarNameSuggestions = true;
@@ -877,6 +885,14 @@
   }
 
   @override
+  visitMixinDeclaration(MixinDeclaration node) {
+    // Make suggestions in the body of the mixin declaration
+    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
   void visitNamedExpression(NamedExpression node) {
     if (identical(entity, node.expression)) {
       optype.includeReturnValueSuggestions = true;
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index ff2cb12..abf151b 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/ast/standard_resolution_map.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_manager3.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -1135,9 +1136,10 @@
     await _assertWriteType('int Function(double a, String b)');
   }
 
-  @failingTest
   test_writeType_function_generic() async {
     // TODO(scheglov) Fails because T/U are considered invisible.
+    if (!AnalysisDriver.useSummary2) return;
+
     await _assertWriteType('T Function<T, U>(T a, U b)');
   }
 
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 186cfa7..024a5e1 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -17,6 +18,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(OpTypeTest);
     defineReflectiveTests(OpTypeDart1OnlyTest);
+    defineReflectiveTests(OpTypeTestWithExtensionMethods);
   });
 }
 
@@ -1950,19 +1952,19 @@
     await assertOpType(methodBody: true);
   }
 
-  test_MethodDeclaration1() async {
+  test_MethodDeclaration_inClass1() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('class Bar {const ^Fara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration2() async {
+  test_MethodDeclaration_inClass2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('class Bar {const F^ara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inLineComment() async {
+  test_MethodDeclaration_inClass_inLineComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1971,7 +1973,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineComment2() async {
+  test_MethodDeclaration_inClass_inLineComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1980,7 +1982,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineComment3() async {
+  test_MethodDeclaration_inClass_inLineComment3() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1990,7 +1992,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineDocComment() async {
+  test_MethodDeclaration_inClass_inLineDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1999,7 +2001,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inLineDocComment2() async {
+  test_MethodDeclaration_inClass_inLineDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2008,37 +2010,37 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarComment() async {
+  test_MethodDeclaration_inClass_inStarComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarComment2() async {
+  test_MethodDeclaration_inClass_inStarComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarDocComment() async {
+  test_MethodDeclaration_inClass_inStarDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inStarDocComment2() async {
+  test_MethodDeclaration_inClass_inStarDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
     await assertOpType();
   }
 
-  test_MethodDeclaration_returnType() async {
+  test_MethodDeclaration_inClass_returnType() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineComment() async {
+  test_MethodDeclaration_inClass_returnType_afterLineComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2047,7 +2049,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterLineComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
     addTestSource('''
@@ -2057,7 +2059,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineDocComment() async {
+  test_MethodDeclaration_inClass_returnType_afterLineDocComment() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2066,7 +2068,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterLineDocComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
 class C2 {
@@ -2075,30 +2077,60 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarComment() async {
+  test_MethodDeclaration_inClass_returnType_afterStarComment() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterStarComment2() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarDocComment() async {
+  test_MethodDeclaration_inClass_returnType_afterStarDocComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_returnType_afterStarDocComment2() async {
+  test_MethodDeclaration_inClass_returnType_afterStarDocComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
+  test_methodDeclaration_inMixin1() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {const ^Fara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inMixin2() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {const F^ara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inMixin_returnType() async {
+    // MixinDeclaration  CompilationUnit
+    addTestSource('mixin M {^ zoo(z) { } String name; }');
+    await assertOpType(typeNames: true);
+  }
+
+  test_mixinDeclaration_body() async {
+    // MixinDeclaration  CompilationUnit
+    addTestSource('mixin M {^}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_mixinDeclaration_body2() async {
+    // SimpleIdentifier  MethodDeclaration  MixinDeclaration
+    addTestSource('mixin M {^mth() {}}');
+    await assertOpType(typeNames: true);
+  }
+
   test_NamedExpression() async {
     addTestSource('''
 main() { f(3, ^); }
@@ -2401,3 +2433,46 @@
     testPath = convertPath('/completionTest.dart');
   }
 }
+
+@reflectiveTest
+class OpTypeTestWithExtensionMethods extends OpTypeTestCommon {
+  @override
+  void setUp() {
+    createAnalysisOptionsFile(
+      experiments: [
+        EnableString.extension_methods,
+      ],
+    );
+    super.setUp();
+  }
+
+  test_extensionDeclaration_body() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('extension E on int {^}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_extensionDeclaration_body2() async {
+    // SimpleIdentifier  MethodDeclaration  ExtensionDeclaration
+    addTestSource('extension E on int {^mth() {}}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inExtension1() async {
+    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
+    addTestSource('extension E on int {const ^Fara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inExtension2() async {
+    // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
+    addTestSource('extension E on int {const F^ara();}');
+    await assertOpType(typeNames: true);
+  }
+
+  test_methodDeclaration_inExtension_returnType() async {
+    // ExtensionDeclaration  CompilationUnit
+    addTestSource('extension E on int {^ zoo(z) { } String name; }');
+    await assertOpType(typeNames: true);
+  }
+}
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 4d53d40..3dab917 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -483,11 +483,14 @@
 
   FunctionEntity get findType;
   FunctionEntity get instanceType;
+  FunctionEntity get arrayInstanceType;
+  FunctionEntity get simpleInstanceType;
   FunctionEntity get typeLiteralMaker;
   FunctionEntity get checkTypeBound;
   FieldEntity get rtiAsField;
   FieldEntity get rtiCheckField;
   FieldEntity get rtiIsField;
+  FieldEntity get rtiRestField;
   FunctionEntity get rtiEvalMethod;
   FunctionEntity get rtiBindMethod;
   FunctionEntity get rtiAddRulesMethod;
@@ -511,6 +514,9 @@
   FunctionEntity get specializedAsStringNullable;
   FunctionEntity get specializedCheckStringNullable;
 
+  FunctionEntity get instantiatedGenericFunctionTypeNewRti;
+  FunctionEntity get closureFunctionType;
+
   // From dart:_internal
 
   ClassEntity get symbolImplementationClass;
@@ -1757,7 +1763,7 @@
 
   @override
   FunctionEntity get createRuntimeType => _options.experimentNewRti
-      ? _findRtiFunction('_createRuntimeType')
+      ? _findRtiFunction('createRuntimeType')
       : _findHelperFunction('createRuntimeType');
 
   @override
@@ -1846,6 +1852,16 @@
   FunctionEntity get instanceType =>
       _instanceType ??= _findRtiFunction('instanceType');
 
+  FunctionEntity _arrayInstanceType;
+  @override
+  FunctionEntity get arrayInstanceType =>
+      _arrayInstanceType ??= _findRtiFunction('_arrayInstanceType');
+
+  FunctionEntity _simpleInstanceType;
+  @override
+  FunctionEntity get simpleInstanceType =>
+      _simpleInstanceType ??= _findRtiFunction('_instanceType');
+
   FunctionEntity _typeLiteralMaker;
   @override
   FunctionEntity get typeLiteralMaker =>
@@ -1874,6 +1890,10 @@
   FieldEntity get rtiCheckField =>
       _rtiCheckField ??= _findRtiClassField('_check');
 
+  FieldEntity _rtiRestField;
+  @override
+  FieldEntity get rtiRestField => _rtiRestField ??= _findRtiClassField('_rest');
+
   FunctionEntity _rtiEvalMethod;
   @override
   FunctionEntity get rtiEvalMethod =>
@@ -1959,6 +1979,14 @@
   FunctionEntity get specializedCheckStringNullable =>
       _findRtiFunction('_checkStringNullable');
 
+  @override
+  FunctionEntity get instantiatedGenericFunctionTypeNewRti =>
+      _findRtiFunction('instantiatedGenericFunctionType');
+
+  @override
+  FunctionEntity get closureFunctionType =>
+      _findRtiFunction('closureFunctionType');
+
   // From dart:_internal
 
   ClassEntity _symbolImplementationClass;
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 67332be..8864815 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -356,6 +356,7 @@
               break;
             case TypeUseKind.RTI_VALUE:
             case TypeUseKind.TYPE_ARGUMENT:
+            case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
               failedAt(element, "Unexpected type use: $typeUse.");
               break;
           }
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index ef7c2f8..d793fe9 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -75,7 +75,8 @@
   /// variable.
   // TODO(sra): Review uses of [containsTypeVariables] for update with
   // [containsFreeTypeVariables].
-  bool get containsFreeTypeVariables => _containsFreeTypeVariables(null);
+  bool get containsFreeTypeVariables =>
+      _ContainsFreeTypeVariablesVisitor().run(this);
 
   /// Is `true` if this type is the 'Object' type defined in 'dart:core'.
   bool get isObject => false;
@@ -93,14 +94,20 @@
   /// See [TypeVariableType] for a motivation for this method.
   ///
   /// Invariant: There must be the same number of [arguments] and [parameters].
-  DartType subst(List<DartType> arguments, List<DartType> parameters);
+  DartType subst(List<DartType> arguments, List<DartType> parameters) {
+    assert(arguments.length == parameters.length);
+    if (parameters.isEmpty) return this;
+    return SimpleDartTypeSubstitutionVisitor(arguments, parameters)
+        .substitute(this);
+  }
 
   /// Calls the visit method on [visitor] corresponding to this type.
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument);
 
   bool _equals(DartType other, _Assumptions assumptions);
 
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => false;
+  @override
+  String toString() => _DartTypeToStringVisitor().run(this);
 }
 
 /// Pairs of [FunctionTypeVariable]s that are currently assumed to be
@@ -185,32 +192,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
-    return typeArguments
-        .any((type) => type._containsFreeTypeVariables(bindings));
-  }
-
-  @override
-  InterfaceType subst(List<DartType> arguments, List<DartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic types.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    List<DartType> newTypeArguments =
-        _substTypes(typeArguments, arguments, parameters);
-    if (!identical(typeArguments, newTypeArguments)) {
-      // Create a new type only if necessary.
-      return new InterfaceType(element, newTypeArguments);
-    }
-    return this;
-  }
-
-  @override
   bool get treatAsRaw {
     for (DartType type in typeArguments) {
       if (!type.treatAsDynamic) return false;
@@ -250,25 +231,6 @@
     return identical(element, other.element) &&
         _equalTypes(typeArguments, other.typeArguments, assumptions);
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(element.name);
-    if (typeArguments.isNotEmpty) {
-      sb.write('<');
-      bool needsComma = false;
-      for (DartType typeArgument in typeArguments) {
-        if (needsComma) {
-          sb.write(',');
-        }
-        sb.write(typeArgument);
-        needsComma = true;
-      }
-      sb.write('>');
-    }
-    return sb.toString();
-  }
 }
 
 class TypedefType extends DartType {
@@ -292,32 +254,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) =>
-      typeArguments.any((type) => type._containsFreeTypeVariables(bindings));
-
-  @override
-  TypedefType subst(List<DartType> arguments, List<DartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic types.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    List<DartType> newTypeArguments =
-        _substTypes(typeArguments, arguments, parameters);
-    FunctionType newUnaliased = unaliased.subst(arguments, parameters);
-    if (!identical(typeArguments, newTypeArguments) ||
-        !identical(unaliased, newUnaliased)) {
-      // Create a new type only if necessary.
-      return new TypedefType(element, newTypeArguments, newUnaliased);
-    }
-    return this;
-  }
-
-  @override
   bool get treatAsRaw {
     for (DartType type in typeArguments) {
       if (!type.treatAsDynamic) return false;
@@ -357,25 +293,6 @@
     return identical(element, other.element) &&
         _equalTypes(typeArguments, other.typeArguments, assumptions);
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(element.name);
-    if (typeArguments.isNotEmpty) {
-      sb.write('<');
-      bool needsComma = false;
-      for (DartType typeArgument in typeArguments) {
-        if (needsComma) {
-          sb.write(',');
-        }
-        sb.write(typeArgument);
-        needsComma = true;
-      }
-      sb.write('>');
-    }
-    return sb.toString();
-  }
 }
 
 class TypeVariableType extends DartType {
@@ -395,24 +312,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => true;
-
-  @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    assert(arguments.length == parameters.length);
-    if (parameters.isEmpty) {
-      // Return fast on empty substitutions.
-      return this;
-    }
-    int index = parameters.indexOf(this);
-    if (index != -1) {
-      return arguments[index];
-    }
-    // The type variable was not substituted.
-    return this;
-  }
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitTypeVariableType(this, argument);
 
@@ -432,9 +331,6 @@
     }
     return false;
   }
-
-  @override
-  String toString() => '${element.typeDeclaration.name}.${element.name}';
 }
 
 /// A type variable declared on a function type.
@@ -457,7 +353,7 @@
   FunctionTypeVariable(this.index);
 
   DartType get bound {
-    assert(_bound != null, "Bound hasn't been set.");
+    assert(_bound != null, "Bound has not been set.");
     return _bound;
   }
 
@@ -470,28 +366,6 @@
   bool get isFunctionTypeVariable => true;
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
-    if (bindings == null) return true;
-    if (bindings.indexOf(this) >= 0) return false;
-    return true;
-  }
-
-  @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    assert(arguments.length == parameters.length);
-    if (parameters.isEmpty) {
-      // Return fast on empty substitutions.
-      return this;
-    }
-    int index = parameters.indexOf(this);
-    if (index != -1) {
-      return arguments[index];
-    }
-    // The function type variable was not substituted.
-    return this;
-  }
-
-  @override
   int get hashCode => index.hashCode * 19;
 
   @override
@@ -512,9 +386,6 @@
   @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitFunctionTypeVariable(this, argument);
-
-  @override
-  String toString() => '#${new String.fromCharCode(0x41 + index)}';
 }
 
 class VoidType extends DartType {
@@ -524,12 +395,6 @@
   bool get isVoid => true;
 
   @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    // `void` cannot be substituted.
-    return this;
-  }
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitVoidType(this, argument);
 
@@ -540,9 +405,6 @@
   bool _equals(DartType other, _Assumptions assumptions) {
     return identical(this, other);
   }
-
-  @override
-  String toString() => 'void';
 }
 
 class DynamicType extends DartType {
@@ -555,12 +417,6 @@
   bool get treatAsDynamic => true;
 
   @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    // `dynamic` cannot be substituted.
-    return this;
-  }
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitDynamicType(this, argument);
 
@@ -571,9 +427,6 @@
   bool _equals(DartType other, _Assumptions assumptions) {
     return identical(this, other);
   }
-
-  @override
-  String toString() => 'dynamic';
 }
 
 class FunctionType extends DartType {
@@ -627,88 +480,8 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
-    int restore;
-    if (typeVariables.isNotEmpty) {
-      if (bindings == null) {
-        bindings = <FunctionTypeVariable>[];
-      } else {
-        restore = bindings.length;
-      }
-      bindings.addAll(typeVariables);
-    }
-
-    bool hasFree(DartType type) => type._containsFreeTypeVariables(bindings);
-
-    bool result = hasFree(returnType) ||
-        typeVariables.any((type) => hasFree(type.bound)) ||
-        parameterTypes.any(hasFree) ||
-        optionalParameterTypes.any(hasFree) ||
-        namedParameterTypes.any(hasFree);
-
-    if (restore != null) bindings.length = restore;
-    return result;
-  }
-
-  @override
   bool get isFunctionType => true;
 
-  @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    DartType newReturnType = returnType.subst(arguments, parameters);
-    bool changed = !identical(newReturnType, returnType);
-    List<DartType> newParameterTypes =
-        _substTypes(parameterTypes, arguments, parameters);
-    List<DartType> newOptionalParameterTypes =
-        _substTypes(optionalParameterTypes, arguments, parameters);
-    List<DartType> newNamedParameterTypes =
-        _substTypes(namedParameterTypes, arguments, parameters);
-    if (!changed &&
-        (!identical(parameterTypes, newParameterTypes) ||
-            !identical(optionalParameterTypes, newOptionalParameterTypes) ||
-            !identical(namedParameterTypes, newNamedParameterTypes))) {
-      changed = true;
-    }
-    List<FunctionTypeVariable> newTypeVariables;
-    if (typeVariables.isNotEmpty) {
-      if (parameters == typeVariables) {
-        newTypeVariables = const <FunctionTypeVariable>[];
-        changed = true;
-      } else {
-        int index = 0;
-        for (FunctionTypeVariable typeVariable in typeVariables) {
-          DartType newBound = typeVariable.bound.subst(arguments, parameters);
-          if (!identical(typeVariable.bound, newBound)) {
-            newTypeVariables ??= typeVariables.sublist(0, index);
-            changed = true;
-          } else {
-            newTypeVariables?.add(typeVariable);
-          }
-          index++;
-        }
-        newTypeVariables ??= typeVariables;
-      }
-    } else {
-      newTypeVariables = typeVariables;
-    }
-    if (changed) {
-      // Create a new type only if necessary.
-      return new FunctionType(
-          newReturnType,
-          newParameterTypes,
-          newOptionalParameterTypes,
-          namedParameters,
-          newNamedParameterTypes,
-          newTypeVariables);
-    }
-    return this;
-  }
-
   FunctionType instantiate(List<DartType> arguments) {
     return subst(arguments, typeVariables);
   }
@@ -778,74 +551,6 @@
     }
     return result;
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write(returnType);
-    sb.write(' Function');
-    if (typeVariables.isNotEmpty) {
-      sb.write('<');
-      bool needsComma = false;
-      for (FunctionTypeVariable typeVariable in typeVariables) {
-        if (needsComma) {
-          sb.write(',');
-        }
-        sb.write(typeVariable);
-        DartType bound = typeVariable.bound;
-        if (!bound.isObject) {
-          sb.write(' extends ');
-          sb.write(typeVariable.bound);
-        }
-        needsComma = true;
-      }
-      sb.write('>');
-    }
-    sb.write('(');
-    bool needsComma = false;
-    for (DartType parameterType in parameterTypes) {
-      if (needsComma) {
-        sb.write(',');
-      }
-      sb.write(parameterType);
-      needsComma = true;
-    }
-    if (optionalParameterTypes.isNotEmpty) {
-      if (needsComma) {
-        sb.write(',');
-      }
-      sb.write('[');
-      bool needsOptionalComma = false;
-      for (DartType typeArgument in optionalParameterTypes) {
-        if (needsOptionalComma) {
-          sb.write(',');
-        }
-        sb.write(typeArgument);
-        needsOptionalComma = true;
-      }
-      sb.write(']');
-      needsComma = true;
-    }
-    if (namedParameters.isNotEmpty) {
-      if (needsComma) {
-        sb.write(',');
-      }
-      sb.write('{');
-      bool needsNamedComma = false;
-      for (int index = 0; index < namedParameters.length; index++) {
-        if (needsNamedComma) {
-          sb.write(',');
-        }
-        sb.write(namedParameterTypes[index]);
-        sb.write(' ');
-        sb.write(namedParameters[index]);
-        needsNamedComma = true;
-      }
-      sb.write('}');
-    }
-    sb.write(')');
-    return sb.toString();
-  }
 }
 
 class FutureOrType extends DartType {
@@ -857,13 +562,6 @@
   bool get isFutureOr => true;
 
   @override
-  DartType subst(List<DartType> arguments, List<DartType> parameters) {
-    DartType newTypeArgument = typeArgument.subst(arguments, parameters);
-    if (identical(typeArgument, newTypeArgument)) return this;
-    return new FutureOrType(newTypeArgument);
-  }
-
-  @override
   bool get containsTypeVariables => typeArgument.containsTypeVariables;
 
   @override
@@ -872,10 +570,6 @@
   }
 
   @override
-  bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) =>
-      typeArgument._containsFreeTypeVariables(bindings);
-
-  @override
   R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
       visitor.visitFutureOrType(this, argument);
 
@@ -899,36 +593,6 @@
   bool _equalsInternal(FutureOrType other, _Assumptions assumptions) {
     return typeArgument._equals(other.typeArgument, assumptions);
   }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write('FutureOr');
-    sb.write('<');
-    sb.write(typeArgument);
-    sb.write('>');
-    return sb.toString();
-  }
-}
-
-/// Helper method for performing substitution of a list of types.
-///
-/// If no types are changed by the substitution, the [types] is returned
-/// instead of a newly created list.
-List<DartType> _substTypes(
-    List<DartType> types, List<DartType> arguments, List<DartType> parameters) {
-  bool changed = false;
-  List<DartType> result =
-      new List<DartType>.generate(types.length, (int index) {
-    DartType type = types[index];
-    DartType argument = type.subst(arguments, parameters);
-    if (!changed && !identical(argument, type)) {
-      changed = true;
-    }
-    return argument;
-  });
-  // Use the new List only if necessary.
-  return changed ? result : types;
 }
 
 bool _equalTypes(List<DartType> a, List<DartType> b, _Assumptions assumptions) {
@@ -1000,6 +664,579 @@
       visitType(type, argument);
 }
 
+abstract class DartTypeSubstitutionVisitor<A>
+    extends DartTypeVisitor<DartType, A> {
+  // The input type is a DAG and we must preserve the sharing.
+  Map<DartType, DartType> _map = Map.identity();
+
+  DartType _mapped(DartType oldType, DartType newType) {
+    assert(_map[oldType] == null);
+    return _map[oldType] = newType;
+  }
+
+  /// Returns the replacement for the type variable [type]. Returns the original
+  /// [type] if not substituted. The substitution algorithm sometimes visits the
+  /// same subterm more than once. When this happens, [freshReference] is `true`
+  /// on only one visit. This allows the substitution visitor to count the
+  /// number of times the replacement term occurs in the final term.
+  DartType substituteTypeVariableType(
+      TypeVariableType type, A argument, bool freshReference);
+
+  /// Returns the replacement for the function type variable [type]. Returns the
+  /// original [type] if not substituted. The substitution algorithm sometimes
+  /// visits the same subterm more than once. When this happens,
+  /// [freshReference] is `true` on only one visit. This allows the substitution
+  /// visitor to count the number of times the replacement term occurs in the
+  /// final term.
+  DartType substituteFunctionTypeVariable(
+          FunctionTypeVariable type, A argument, bool freshReference) =>
+      type;
+
+  @override
+  DartType visitTypeVariableType(covariant TypeVariableType type, A argument) {
+    return substituteTypeVariableType(type, argument, true);
+  }
+
+  @override
+  DartType visitFunctionTypeVariable(
+      covariant FunctionTypeVariable type, A argument) {
+    // Function type variables are added to the map only for type variables that
+    // need to be replaced with updated bounds.
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+    return substituteFunctionTypeVariable(type, argument, true);
+  }
+
+  @override
+  DartType visitVoidType(covariant VoidType type, A argument) => type;
+
+  @override
+  DartType visitFunctionType(covariant FunctionType type, A argument) {
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    List<FunctionTypeVariable> newTypeVariables =
+        _handleFunctionTypeVariables(type.typeVariables, argument);
+
+    DartType newReturnType = visit(type.returnType, argument);
+    List<DartType> newParameterTypes =
+        _substTypes(type.parameterTypes, argument);
+    List<DartType> newOptionalParameterTypes =
+        _substTypes(type.optionalParameterTypes, argument);
+    List<DartType> newNamedParameterTypes =
+        _substTypes(type.namedParameterTypes, argument);
+
+    // Create a new type only if necessary.
+    if (identical(type.typeVariables, newTypeVariables) &&
+        identical(type.returnType, newReturnType) &&
+        identical(type.parameterTypes, newParameterTypes) &&
+        identical(type.optionalParameterTypes, newOptionalParameterTypes) &&
+        identical(type.namedParameterTypes, newNamedParameterTypes)) {
+      return _mapped(type, type);
+    }
+
+    return _mapped(
+        type,
+        FunctionType(
+            newReturnType,
+            newParameterTypes,
+            newOptionalParameterTypes,
+            type.namedParameters,
+            newNamedParameterTypes,
+            newTypeVariables));
+  }
+
+  List<FunctionTypeVariable> _handleFunctionTypeVariables(
+      List<FunctionTypeVariable> variables, A argument) {
+    if (variables.isEmpty) return variables;
+
+    // Are the function type variables being substituted (i.e. generic function
+    // type instantiation).
+    // TODO(sra): This should happen only from via
+    // [FunctionType.instantiate]. Perhaps it would be handled better there.
+    int count = 0;
+    for (int i = 0; i < variables.length; i++) {
+      FunctionTypeVariable variable = variables[i];
+      if (variable !=
+          substituteFunctionTypeVariable(variable, argument, false)) {
+        count++;
+      }
+    }
+    if (count == variables.length) return const <FunctionTypeVariable>[];
+    assert(count == 0, 'Generic function type instantiation is all-or-none');
+
+    // Type variables may depend on each other. Consider:
+    //
+    //     <A extends List<B>,
+    //      B extends Set<A>,
+    //      C extends D,
+    //      D extends Map<B, F>>(){}
+    //
+    // A and B have a cycle but are not changed by the subsitution of F->G. C is
+    // indirectly changed by the substitution of F. When D is replaced by `D2
+    // extends Map<B,G>`, C must be replaced by `C2 extends D2`.
+
+    List<FunctionTypeVariable> undecided = variables.toList();
+    List<FunctionTypeVariable> newVariables;
+
+    _DependencyCheck<A> dependencyCheck = _DependencyCheck<A>(this, argument);
+
+    bool changed = true;
+    while (changed) {
+      changed = false;
+      for (int i = 0; i < undecided.length; i++) {
+        FunctionTypeVariable variable = undecided[i];
+        if (variable == null) continue;
+        if (dependencyCheck.run(variable.bound)) {
+          changed = true;
+          undecided[i] = null;
+          newVariables ??= variables.toList();
+          FunctionTypeVariable newVariable =
+              FunctionTypeVariable(variable.index);
+          newVariables[i] = newVariable;
+          _mapped(variable, newVariable);
+        }
+      }
+    }
+    if (newVariables == null) return variables;
+
+    // Substitute the bounds of the new variables;
+    for (int i = 0; i < newVariables.length; i++) {
+      FunctionTypeVariable oldVariable = variables[i];
+      FunctionTypeVariable newVariable = newVariables[i];
+      if (identical(oldVariable, newVariable)) continue;
+      newVariable.bound = visit(oldVariable.bound, argument);
+    }
+    return newVariables;
+  }
+
+  @override
+  DartType visitInterfaceType(covariant InterfaceType type, A argument) {
+    List<DartType> typeArguments = type.typeArguments;
+    if (typeArguments.isEmpty) {
+      // Return fast on non-generic types.
+      return type;
+    }
+
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    List<DartType> newTypeArguments = _substTypes(typeArguments, argument);
+    // Create a new type only if necessary.
+    if (identical(typeArguments, newTypeArguments)) {
+      return _mapped(type, type);
+    }
+    return _mapped(type, InterfaceType(type.element, newTypeArguments));
+  }
+
+  @override
+  DartType visitTypedefType(covariant TypedefType type, A argument) {
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    List<DartType> newTypeArguments = _substTypes(type.typeArguments, argument);
+    FunctionType newUnaliased = visit(type.unaliased, argument);
+    // Create a new type only if necessary.
+    if (identical(type.typeArguments, newTypeArguments) &&
+        identical(type.unaliased, newUnaliased)) {
+      return _mapped(type, type);
+    }
+    return _mapped(
+        type, TypedefType(type.element, newTypeArguments, newUnaliased));
+  }
+
+  @override
+  DartType visitDynamicType(covariant DynamicType type, A argument) => type;
+
+  @override
+  DartType visitFutureOrType(covariant FutureOrType type, A argument) {
+    DartType seen = _map[type];
+    if (seen != null) return seen;
+
+    DartType newTypeArgument = visit(type.typeArgument, argument);
+    // Create a new type only if necessary.
+    if (identical(type.typeArgument, newTypeArgument)) {
+      return _mapped(type, type);
+    }
+    return _mapped(type, FutureOrType(newTypeArgument));
+  }
+
+  List<DartType> _substTypes(List<DartType> types, A argument) {
+    List<DartType> result;
+    for (int i = 0; i < types.length; i++) {
+      DartType oldType = types[i];
+      DartType newType = visit(oldType, argument);
+      if (!identical(newType, oldType)) {
+        result ??= types.sublist(0, i);
+      }
+      result?.add(newType);
+    }
+    return result ?? types;
+  }
+}
+
+class _DependencyCheck<A> extends DartTypeStructuralPredicateVisitor {
+  final DartTypeSubstitutionVisitor<A> _substitutionVisitor;
+  final A argument;
+
+  _DependencyCheck(this._substitutionVisitor, this.argument);
+
+  @override
+  bool handleTypeVariableType(TypeVariableType type) {
+    return !identical(type,
+        _substitutionVisitor.substituteTypeVariableType(type, argument, false));
+  }
+
+  @override
+  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) {
+    // Function type variables are added to the map for type variables that need
+    // to be replaced with updated bounds.
+    DartType seen = _substitutionVisitor._map[type];
+    if (seen != null) return seen != type;
+    return !identical(
+        type,
+        _substitutionVisitor.substituteFunctionTypeVariable(
+            type, argument, false));
+  }
+}
+
+/// A visitor that by default visits the substructure of the type until some
+/// visit returns`true`.  The default handers return `false` which will search
+/// the whole structure unless overridden.
+abstract class DartTypeStructuralPredicateVisitor
+    extends DartTypeVisitor<bool, List<FunctionTypeVariable>> {
+  const DartTypeStructuralPredicateVisitor();
+
+  bool run(DartType type) => visit(type, null);
+
+  bool handleVoidType(VoidType type) => false;
+  bool handleTypeVariableType(TypeVariableType type) => false;
+  bool handleBoundFunctionTypeVariable(FunctionTypeVariable type) => false;
+  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) => false;
+  bool handleFunctionType(FunctionType type) => false;
+  bool handleInterfaceType(InterfaceType type) => false;
+  bool handleTypedefType(TypedefType type) => false;
+  bool handleDynamicType(DynamicType type) => false;
+  bool handleFutureOrType(FutureOrType type) => false;
+
+  @override
+  bool visitVoidType(VoidType type, List<FunctionTypeVariable> bindings) =>
+      handleVoidType(type);
+
+  @override
+  bool visitTypeVariableType(
+          TypeVariableType type, List<FunctionTypeVariable> bindings) =>
+      handleTypeVariableType(type);
+
+  @override
+  bool visitFunctionTypeVariable(
+      FunctionTypeVariable type, List<FunctionTypeVariable> bindings) {
+    return bindings != null && bindings.indexOf(type) >= 0
+        ? handleBoundFunctionTypeVariable(type)
+        : handleFreeFunctionTypeVariable(type);
+  }
+
+  @override
+  bool visitFunctionType(
+      FunctionType type, List<FunctionTypeVariable> bindings) {
+    if (handleFunctionType(type)) return true;
+    List<FunctionTypeVariable> typeVariables = type.typeVariables;
+    if (typeVariables.isNotEmpty) {
+      bindings ??= <FunctionTypeVariable>[];
+      bindings.addAll(typeVariables);
+    }
+
+    bool result = visit(type.returnType, bindings);
+    result = result ||
+        _visitAll(type.typeVariables.map((variable) => variable.bound).toList(),
+            bindings);
+    result = result || _visitAll(type.parameterTypes, bindings);
+    result = result || _visitAll(type.optionalParameterTypes, bindings);
+    result = result || _visitAll(type.namedParameterTypes, bindings);
+
+    bindings?.length -= typeVariables.length;
+    return result;
+  }
+
+  @override
+  bool visitInterfaceType(
+      InterfaceType type, List<FunctionTypeVariable> bindings) {
+    if (handleInterfaceType(type)) return true;
+    return _visitAll(type.typeArguments, bindings);
+  }
+
+  @override
+  bool visitTypedefType(TypedefType type, List<FunctionTypeVariable> bindings) {
+    if (handleTypedefType(type)) return true;
+    if (_visitAll(type.typeArguments, bindings)) return true;
+    return visit(type.unaliased, bindings);
+  }
+
+  @override
+  bool visitDynamicType(
+          DynamicType type, List<FunctionTypeVariable> bindings) =>
+      handleDynamicType(type);
+
+  @override
+  bool visitFutureOrType(
+      FutureOrType type, List<FunctionTypeVariable> bindings) {
+    if (handleFutureOrType(type)) return true;
+    return visit(type.typeArgument, bindings);
+  }
+
+  bool _visitAll(List<DartType> types, List<FunctionTypeVariable> bindings) {
+    for (DartType type in types) {
+      if (visit(type, bindings)) return true;
+    }
+    return false;
+  }
+}
+
+class _ContainsFreeTypeVariablesVisitor
+    extends DartTypeStructuralPredicateVisitor {
+  @override
+  bool handleTypeVariableType(TypeVariableType type) => true;
+
+  @override
+  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) => true;
+}
+
+class SimpleDartTypeSubstitutionVisitor
+    extends DartTypeSubstitutionVisitor<Null> {
+  final List<DartType> arguments;
+  final List<DartType> parameters;
+
+  SimpleDartTypeSubstitutionVisitor(this.arguments, this.parameters);
+
+  DartType substitute(DartType input) => visit(input, null);
+
+  @override
+  DartType substituteTypeVariableType(
+      TypeVariableType type, Null _, bool freshReference) {
+    int index = this.parameters.indexOf(type);
+    if (index != -1) {
+      return this.arguments[index];
+    }
+    // The type variable was not substituted.
+    return type;
+  }
+
+  @override
+  DartType substituteFunctionTypeVariable(
+      covariant FunctionTypeVariable type, Null _, bool freshReference) {
+    int index = this.parameters.indexOf(type);
+    if (index != -1) {
+      return this.arguments[index];
+    }
+    // The function type variable was not substituted.
+    return type;
+  }
+}
+
+class _DeferredName {
+  String name;
+  _DeferredName();
+  @override
+  String toString() => name;
+}
+
+class _DartTypeToStringVisitor extends DartTypeVisitor<void, void> {
+  final List _fragments = []; // Strings and _DeferredNames
+  bool _lastIsIdentifier = false;
+  List<FunctionTypeVariable> _boundVariables;
+  Map<FunctionTypeVariable, _DeferredName> _variableToName;
+  Set<FunctionType> _genericFunctions;
+
+  String run(DartType type) {
+    _visit(type);
+    if (_variableToName != null &&
+        _variableToName.values.any((deferred) => deferred.name == null)) {
+      // Assign names to _DeferredNames that were not assigned while visiting a
+      // generic function type.
+      Set<String> usedNames =
+          _variableToName.values.map((deferred) => deferred.name).toSet();
+      int startGroup = (_genericFunctions?.length ?? 0) + 1;
+      for (var entry in _variableToName.entries) {
+        if (entry.value.name != null) continue;
+        for (int group = startGroup;; group++) {
+          String name = _functionTypeVariableName(entry.key, group);
+          if (!usedNames.add(name)) continue;
+          entry.value.name = name;
+          break;
+        }
+      }
+    }
+    return _fragments.join();
+  }
+
+  String _functionTypeVariableName(FunctionTypeVariable variable, int group) {
+    String prefix = String.fromCharCode(0x41 + variable.index);
+    String suffix = group == 1 ? '' : '$group';
+    return prefix + suffix;
+  }
+
+  void _identifier(String text) {
+    if (_lastIsIdentifier) _fragments.add(' ');
+    _fragments.add(text);
+    _lastIsIdentifier = true;
+  }
+
+  void _deferredNameIdentifier(_DeferredName name) {
+    if (_lastIsIdentifier) _fragments.add(' ');
+    _fragments.add(name);
+    _lastIsIdentifier = true;
+  }
+
+  void _token(String text) {
+    _fragments.add(text);
+    _lastIsIdentifier = false;
+  }
+
+  bool _comma(bool needsComma) {
+    if (needsComma) _token(',');
+    return true;
+  }
+
+  void _visit(DartType type) {
+    type.accept(this, null);
+  }
+
+  @override
+  void visitVoidType(covariant VoidType type, _) {
+    _identifier('void');
+  }
+
+  @override
+  void visitDynamicType(covariant DynamicType type, _) {
+    _identifier('dynamic');
+  }
+
+  @override
+  void visitTypeVariableType(covariant TypeVariableType type, _) {
+    _identifier(type.element.typeDeclaration.name);
+    _token('.');
+    _identifier(type.element.name);
+  }
+
+  _DeferredName _nameFor(FunctionTypeVariable type) {