Version 2.12.0-18.0.dev

Merge commit '172647612080b72c07a5f48c439215d11db880d0' into 'dev'
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 392a4b1..5ee814d 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -613,7 +613,8 @@
   @override
   void visitPostfixExpression(PostfixExpression node) {
     _deprecatedVerifier.postfixExpression(node);
-    if (node.operand.staticType?.isDartCoreNull ?? false) {
+    if (node.operator.type == TokenType.BANG &&
+        node.operand.staticType.isDartCoreNull) {
       _errorReporter.reportErrorForNode(HintCode.NULL_CHECK_ALWAYS_FAILS, node);
     }
     super.visitPostfixExpression(node);
@@ -1641,9 +1642,12 @@
 
 class _InvalidAccessVerifier {
   static final _templateExtension = '.template';
-  static final _testDir = '${path.separator}test${path.separator}';
-  static final _testDriverDir = '${path.separator}test_driver${path.separator}';
-  static final _testingDir = '${path.separator}testing${path.separator}';
+  static final _testDirectories = [
+    '${path.separator}test${path.separator}',
+    '${path.separator}integration_test${path.separator}',
+    '${path.separator}test_driver${path.separator}',
+    '${path.separator}testing${path.separator}',
+  ];
 
   final ErrorReporter _errorReporter;
   final LibraryElement _library;
@@ -1658,9 +1662,7 @@
       this._errorReporter, this._library, this._workspacePackage) {
     var path = _library.source.fullName;
     _inTemplateSource = path.contains(_templateExtension);
-    _inTestDirectory = path.contains(_testDir) ||
-        path.contains(_testDriverDir) ||
-        path.contains(_testingDir);
+    _inTestDirectory = _testDirectories.any(path.contains);
   }
 
   /// Produces a hint if [identifier] is accessed from an invalid location.
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 9772a68..8e9e71c 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -491,6 +491,8 @@
   int toInt();
 }
 
+abstract class Match {}
+
 class Object {
   const Object();
 
@@ -503,7 +505,9 @@
   external dynamic noSuchMethod(Invocation invocation);
 }
 
-abstract class Pattern {}
+abstract class Pattern {
+  Iterable<Match> allMatches(String string, [int start = 0]);
+}
 
 abstract class RegExp implements Pattern {
   external factory RegExp(String source);
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
index 9cbadeb..998e775 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
@@ -39,6 +39,25 @@
     await _resolveFile('$testPackageRootPath/lib2.dart');
   }
 
+  test_fromIntegrationTestDirectory() async {
+    newFile('$testPackageRootPath/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    newFile('$testPackageRootPath/integration_test/test.dart', content: r'''
+import '../lib1.dart';
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveFile('$testPackageRootPath/lib1.dart');
+    await _resolveFile('$testPackageRootPath/integration_test/test.dart');
+  }
+
   test_fromTestDirectory() async {
     newFile('$testPackageRootPath/lib1.dart', content: r'''
 import 'package:meta/meta.dart';
@@ -58,6 +77,25 @@
     await _resolveFile('$testPackageRootPath/test/test.dart');
   }
 
+  test_fromTestDriverDirectory() async {
+    newFile('$testPackageRootPath/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    newFile('$testPackageRootPath/test_driver/test.dart', content: r'''
+import '../lib1.dart';
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveFile('$testPackageRootPath/lib1.dart');
+    await _resolveFile('$testPackageRootPath/test_driver/test.dart');
+  }
+
   test_fromTestingDirectory() async {
     newFile('$testPackageRootPath/lib1.dart', content: r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart b/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart
index e21d37c..ce1298b 100644
--- a/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart
@@ -37,10 +37,10 @@
   test_nullLiteral_parenthesized() async {
     await assertErrorsInCode(r'''
 void f() {
-  null!;
+  (null)!;
 }
 ''', [
-      error(HintCode.NULL_CHECK_ALWAYS_FAILS, 13, 5),
+      error(HintCode.NULL_CHECK_ALWAYS_FAILS, 13, 7),
     ]);
   }
 
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 34f07a4..6b7cfdc 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -6,7 +6,6 @@
 import 'dart:io' as io hide exit;
 import 'dart:isolate';
 
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:args/args.dart';
 import 'package:args/command_runner.dart';
 import 'package:cli_util/cli_logging.dart';
@@ -172,8 +171,6 @@
     argParser.addFlag('disable-analytics',
         negatable: false, help: 'Disable anonymous analytics.');
 
-    addExperimentalFlags(argParser, verbose);
-
     argParser.addFlag('diagnostics',
         negatable: false, help: 'Show tool diagnostic output.', hide: !verbose);
 
@@ -189,7 +186,7 @@
 
     addCommand(AnalyzeCommand());
     addCommand(CreateCommand(verbose: verbose));
-    addCommand(CompileCommand());
+    addCommand(CompileCommand(verbose: verbose));
     addCommand(FixCommand());
     addCommand(FormatCommand(verbose: verbose));
     addCommand(MigrateCommand(verbose: verbose));
@@ -206,26 +203,6 @@
   String get invocation =>
       'dart [<vm-flags>] <command|dart-file> [<arguments>]';
 
-  void addExperimentalFlags(ArgParser argParser, bool verbose) {
-    List<ExperimentalFeature> features = experimentalFeatures;
-
-    Map<String, String> allowedHelp = {};
-    for (ExperimentalFeature feature in features) {
-      String suffix =
-          feature.isEnabledByDefault ? ' (no-op - enabled by default)' : '';
-      allowedHelp[feature.enableString] = '${feature.documentation}$suffix';
-    }
-
-    argParser.addMultiOption(
-      experimentFlagName,
-      valueHelp: 'experiment',
-      allowedHelp: verbose ? allowedHelp : null,
-      help: 'Enable one or more experimental features '
-          '(see dart.dev/go/experiments).',
-      hide: !verbose,
-    );
-  }
-
   @override
   Future<int> runCommand(ArgResults topLevelResults) async {
     final stopwatch = Stopwatch()..start();
@@ -250,18 +227,6 @@
         ? Logger.verbose(ansi: ansi)
         : Logger.standard(ansi: ansi);
 
-    if (topLevelResults.wasParsed(experimentFlagName)) {
-      List<String> experimentIds = topLevelResults[experimentFlagName];
-      for (ExperimentalFeature feature in experimentalFeatures) {
-        // We allow default true flags, but complain when they are passed in.
-        if (feature.isEnabledByDefault &&
-            experimentIds.contains(feature.enableString)) {
-          print("'${feature.enableString}' is now enabled by default; this "
-              'flag is no longer required.');
-        }
-      }
-    }
-
     var command = topLevelResults.command;
     final commandNames = [];
     while (command != null) {
@@ -276,10 +241,6 @@
       analyticsInstance.sendScreenView(path),
     );
 
-    final topLevelCommand = topLevelResults.command == null
-        ? null
-        : commands[topLevelResults.command.name];
-
     try {
       final exitCode = await super.runCommand(topLevelResults);
 
@@ -299,7 +260,7 @@
                 //
                 // Note that this will also conflate short-options and long-options.
                 command?.options?.where(command.wasParsed)?.toList(),
-            specifiedExperiments: topLevelCommand?.specifiedExperiments,
+            specifiedExperiments: topLevelResults.enabledExperiments,
           ),
         );
       }
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 024bea8..c0fdea3 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// 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.
 
@@ -9,6 +9,7 @@
 import 'package:path/path.dart' as path;
 
 import '../core.dart';
+import '../experiments.dart';
 import '../sdk.dart';
 import '../vm_interop_handler.dart';
 
@@ -45,7 +46,8 @@
 class CompileJSCommand extends CompileSubcommandCommand {
   static const String cmdName = 'js';
 
-  CompileJSCommand() : super(cmdName, 'Compile Dart to JavaScript.') {
+  CompileJSCommand({bool verbose})
+      : super(cmdName, 'Compile Dart to JavaScript.') {
     argParser
       ..addOption(
         commonOptions['outputFile'].flag,
@@ -58,6 +60,7 @@
         abbr: 'm',
         negatable: false,
       );
+    addExperimentalFlags(argParser, verbose);
   }
 
   @override
@@ -91,6 +94,8 @@
 
     VmInteropHandler.run(sdk.dart2jsSnapshot, [
       '--libraries-spec=$librariesPath',
+      if (argResults.enabledExperiments.isNotEmpty)
+        "--enable-experiment=${argResults.enabledExperiments.join(',')}",
       ...argResults.arguments,
     ]);
 
@@ -112,6 +117,7 @@
     this.help,
     this.fileExt,
     this.formatName,
+    bool verbose,
   }) : super(commandName, 'Compile Dart $help') {
     argParser
       ..addOption(
@@ -119,6 +125,7 @@
         help: commonOptions['outputFile'].help,
         abbr: commonOptions['outputFile'].abbr,
       );
+    addExperimentalFlags(argParser, verbose);
   }
 
   @override
@@ -144,10 +151,14 @@
       outputFile = '$inputWithoutDart.$fileExt';
     }
 
+    final enabledExperiments = argResults.enabledExperiments;
     // Build arguments.
     List<String> args = [];
     args.add('--snapshot-kind=$formatName');
     args.add('--snapshot=${path.canonicalize(outputFile)}');
+    if (enabledExperiments.isNotEmpty) {
+      args.add("--enable-experiment=${enabledExperiments.join(',')}");
+    }
     if (verbose) {
       args.add('-v');
     }
@@ -173,6 +184,7 @@
     this.commandName,
     this.format,
     this.help,
+    bool verbose,
   }) : super(commandName, 'Compile Dart $help') {
     argParser
       ..addOption(
@@ -195,6 +207,8 @@
       ..addOption('save-debugging-info', abbr: 'S', valueHelp: 'path', help: '''
 Remove debugging information from the output and save it separately to the specified file.
 <path> can be relative or absolute.''');
+
+    addExperimentalFlags(argParser, verbose);
   }
 
   @override
@@ -225,6 +239,7 @@
         defines: argResults['define'],
         packages: argResults['packages'],
         enableAsserts: argResults['enable-asserts'],
+        enableExperiment: argResults.enabledExperiments.join(','),
         debugFile: argResults['save-debugging-info'],
         verbose: verbose,
       );
@@ -245,30 +260,36 @@
 
 class CompileCommand extends DartdevCommand {
   static const String cmdName = 'compile';
-
-  CompileCommand() : super(cmdName, 'Compile Dart to various formats.') {
-    addSubcommand(CompileJSCommand());
+  CompileCommand({bool verbose = false})
+      : super(cmdName, 'Compile Dart to various formats.') {
+    addSubcommand(CompileJSCommand(
+      verbose: verbose,
+    ));
     addSubcommand(CompileSnapshotCommand(
       commandName: CompileSnapshotCommand.jitSnapshotCmdName,
       help: 'to a JIT snapshot.',
       fileExt: 'jit',
       formatName: 'app-jit',
+      verbose: verbose,
     ));
     addSubcommand(CompileSnapshotCommand(
       commandName: CompileSnapshotCommand.kernelCmdName,
       help: 'to a kernel snapshot.',
       fileExt: 'dill',
       formatName: 'kernel',
+      verbose: verbose,
     ));
     addSubcommand(CompileNativeCommand(
       commandName: CompileNativeCommand.exeCmdName,
       help: 'to a self-contained executable.',
       format: 'exe',
+      verbose: verbose,
     ));
     addSubcommand(CompileNativeCommand(
       commandName: CompileNativeCommand.aotSnapshotCmdName,
       help: 'to an AOT snapshot.',
       format: 'aot',
+      verbose: verbose,
     ));
   }
 }
diff --git a/pkg/dartdev/lib/src/commands/pub.dart b/pkg/dartdev/lib/src/commands/pub.dart
index d77dce6..9f18a82 100644
--- a/pkg/dartdev/lib/src/commands/pub.dart
+++ b/pkg/dartdev/lib/src/commands/pub.dart
@@ -63,20 +63,19 @@
     final command = sdk.pubSnapshot;
     var args = argResults.arguments;
 
+    final enabledExperiments = argResults.enabledExperiments;
     // Pass any --enable-experiment options along.
-    if (args.isNotEmpty && wereExperimentsSpecified) {
-      List<String> experimentIds = specifiedExperiments;
-
+    if (args.isNotEmpty && enabledExperiments.isNotEmpty) {
       if (args.first == 'run') {
         args = [
           ...args.sublist(0, 1),
-          '--$experimentFlagName=${experimentIds.join(',')}',
+          '--$experimentFlagName=${enabledExperiments.join(',')}',
           ...args.sublist(1),
         ];
       } else if (args.length > 1 && args[0] == 'global' && args[0] == 'run') {
         args = [
           ...args.sublist(0, 2),
-          '--$experimentFlagName=${experimentIds.join(',')}',
+          '--$experimentFlagName=${enabledExperiments.join(',')}',
           ...args.sublist(2),
         ];
       }
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 52dab76..b350b38 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -145,6 +145,7 @@
         negatable: false,
         help: 'Enables tracing of library and script loading.',
       );
+    addExperimentalFlags(argParser, verbose);
   }
 
   @override
@@ -216,15 +217,6 @@
       }
     }
 
-    // Pass any --enable-experiment options along.
-    if (args.isNotEmpty && wereExperimentsSpecified) {
-      List<String> experimentIds = specifiedExperiments;
-      args = [
-        '--$experimentFlagName=${experimentIds.join(',')}',
-        ...args,
-      ];
-    }
-
     // If the user wants to start a debugging session we need to do some extra
     // work and spawn a Dart Development Service (DDS) instance. DDS is a VM
     // service intermediary which implements the VM service protocol and
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index 43117fa..b4fe29c 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -58,11 +58,14 @@
       _printMissingDepInstructions(isHelpCommand);
       return 65;
     }
-
+    List<String> enabledExperiments = [];
+    if (!(testArgs.length == 1 && testArgs[0] == '-h')) {
+      enabledExperiments = argResults.enabledExperiments;
+    }
     final args = [
       'run',
-      if (wereExperimentsSpecified)
-        '--$experimentFlagName=${specifiedExperiments.join(',')}',
+      if (enabledExperiments.isNotEmpty)
+        '--$experimentFlagName=${enabledExperiments.join(',')}',
       'test',
       ...testArgs,
     ];
diff --git a/pkg/dartdev/lib/src/events.dart b/pkg/dartdev/lib/src/events.dart
index 29395dc..b2c936a 100644
--- a/pkg/dartdev/lib/src/events.dart
+++ b/pkg/dartdev/lib/src/events.dart
@@ -56,7 +56,8 @@
   /// pattern from the flutter cli tool which always passes 'flutter' as the
   /// category.
   final category = _dartdev;
-  commandFlags = commandFlags?.toList() ?? [];
+  commandFlags =
+      commandFlags?.where((e) => e != 'enable-experiment')?.toList() ?? [];
   specifiedExperiments = specifiedExperiments?.toList() ?? [];
 
   // Sort the flag lists to slightly reduce the explosion of possibilities.
diff --git a/pkg/dartdev/lib/src/experiments.dart b/pkg/dartdev/lib/src/experiments.dart
index 3921900..ebbff07 100644
--- a/pkg/dartdev/lib/src/experiments.dart
+++ b/pkg/dartdev/lib/src/experiments.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:args/args.dart';
 
 const experimentFlagName = 'enable-experiment';
 
@@ -14,3 +15,53 @@
   features.sort((a, b) => a.enableString.compareTo(b.enableString));
   return features;
 }
+
+void addExperimentalFlags(ArgParser argParser, bool verbose) {
+  List<ExperimentalFeature> features = experimentalFeatures;
+
+  Map<String, String> allowedHelp = {};
+  for (ExperimentalFeature feature in features) {
+    String suffix =
+        feature.isEnabledByDefault ? ' (no-op - enabled by default)' : '';
+    allowedHelp[feature.enableString] = '${feature.documentation}$suffix';
+  }
+
+  argParser.addMultiOption(
+    experimentFlagName,
+    valueHelp: 'experiment',
+    allowedHelp: verbose ? allowedHelp : null,
+    help: 'Enable one or more experimental features '
+        '(see dart.dev/go/experiments).',
+    hide: !verbose,
+  );
+}
+
+extension EnabledExperimentsArg on ArgResults {
+  List<String> get enabledExperiments {
+    List<String> enabledExperiments = [];
+    if (options.contains(experimentFlagName)) {
+      if (wasParsed(experimentFlagName)) {
+        enabledExperiments = this[experimentFlagName];
+      }
+    } else {
+      String experiments = arguments.firstWhere(
+        (e) => e.startsWith('--enable-experiment'),
+        orElse: () => null,
+      );
+      if (experiments == null) {
+        return [];
+      }
+      enabledExperiments = experiments.split('=')[1].split(',');
+    }
+
+    for (ExperimentalFeature feature in experimentalFeatures) {
+      // We allow default true flags, but complain when they are passed in.
+      if (feature.isEnabledByDefault &&
+          enabledExperiments.contains(feature.enableString)) {
+        print("'${feature.enableString}' is now enabled by default; this "
+            'flag is no longer required.');
+      }
+    }
+    return enabledExperiments;
+  }
+}
diff --git a/pkg/dartdev/test/analytics_test.dart b/pkg/dartdev/test/analytics_test.dart
index df4359d..cb25407 100644
--- a/pkg/dartdev/test/analytics_test.dart
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -182,10 +182,10 @@
 
     test('run --enable-experiments', () {
       final p = project(
-          mainSrc: 'void main(List<String> args) => print(args)',
+          mainSrc: 'void main(List<String> args) => print(args);',
           logAnalytics: true);
-      final result = p.runSync('--enable-experiment=non-nullable', [
-        'run',
+      final result = p.runSync('run', [
+        '--enable-experiment=non-nullable',
         'lib/main.dart',
       ]);
       expect(extractAnalytics(result), [
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 1e887b1..70660b4 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -4,7 +4,6 @@
 
 import 'dart:io';
 
-import 'package:args/args.dart';
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
 import 'package:test/test.dart';
@@ -48,17 +47,6 @@
       }
     });
   });
-
-  test('enable experiments flag is supported', () {
-    final args = [
-      '--disable-dartdev-analytics',
-      '--enable-experiment=non-nullable'
-    ];
-    final runner = DartdevRunner(args);
-    ArgResults results = runner.parse(args);
-    expect(results['enable-experiment'], isNotEmpty);
-    expect(results['enable-experiment'].first, 'non-nullable');
-  });
 }
 
 void help() {
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index e5a1a86..14db6be 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -69,20 +69,20 @@
   test('run --enable-experiment', () {
     p = project();
     p.file('bin/main.dart',
-        "void main() { int a; a = null; print('a is \$a.'); }");
+        "void main() { int? a; a = null; print('a is \$a.'); }");
 
     // run 'pub get'
     p.runSync('pub', ['get']);
 
     var result = p.runSync(
-        'pub', ['run', '--enable-experiment=non-nullable', 'main.dart']);
+        'pub', ['run', '--enable-experiment=no-non-nullable', 'main.dart']);
 
     expect(result.exitCode, 254);
     expect(result.stdout, isEmpty);
     expect(
         result.stderr,
-        contains("A value of type 'Null' can't be assigned to a variable of "
-            "type 'int'"));
+        contains('bin/main.dart:1:18: Error: This requires the \'non-nullable\''
+            ' language feature to be enabled.\n'));
   });
 
   test('failure', () {
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index f33cb83..4c0a9c1 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -145,7 +145,7 @@
     expect(
       result.stdout,
       matches(
-          r'Observatory listening on http:\/\/127.0.0.1:8181\/[a-zA-Z0-9]+=\/\n.*'),
+          r'Observatory listening on http:\/\/127.0.0.1:8181\/[a-zA-Z0-9_-]+=\/\n.*'),
     );
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index ef2ae06..93aa6b1 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -85,6 +85,8 @@
   test('has package:test dependency', () {
     p = project(mainSrc: 'int get foo => 1;\n');
     p.file('test/foo_test.dart', '''
+$dartVersionFilePrefix2_9
+
 import 'package:test/test.dart';
 
 void main() {
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 32be6a6..f959b95 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,8 +1,3 @@
-# 1.5.0
-- Added event caching for `Stdout`, `Stderr`, and `Extension` streams. When a
-client subscribes to one of these streams, they will be sent up to 10,000
-historical events from the stream.
-
 # 1.4.1
 - Fixed issue where `evaluate` and `evaluateInFrame` requests were not being
   forwarded to the VM service properly when no external compilation service
diff --git a/pkg/dds/dds_protocol.md b/pkg/dds/dds_protocol.md
index 253ef99..be9da7e 100644
--- a/pkg/dds/dds_protocol.md
+++ b/pkg/dds/dds_protocol.md
@@ -47,22 +47,6 @@
 
 See the corresponding section in the VM Service protocol [here][service-protocol-ids-and-names].
 
-## Streams
-
-For a list of core VM service streams, see [streamListen][service-protocol-streams].
-
-DDS will keep a history of events on certain streams and send historical events
-when a client first subscribes to a stream with history. These streams currently
-consist of the following:
-
-- `Logging`
-- `Stdout`
-- `Stderr`
-- `Extension`
-
-In addition, subscribing to the `Service` stream will result in a `ServiceRegistered`
-event being sent to the subscribing client for each existing service extension.
-
 ## Public RPCs
 
 The DDS Protocol supports all [public RPCs defined in the VM Service protocol][service-protocol-public-rpcs].
@@ -203,7 +187,6 @@
 [service-protocol]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md
 [service-protocol-rpcs-requests-and-responses]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses
 [service-protocol-events]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#events
-[service-protocol-streams]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#streamlisten
 [service-protocol-binary-events]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#binary-events
 [service-protocol-types]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#types
 [service-protocol-ids-and-names]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#ids-and-names
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 2c85aae..79e4233 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -140,9 +140,7 @@
         'getLogHistorySize',
         (parameters) => {
               'type': 'Size',
-              'size': _StreamManager
-                  .loggingRepositories[_StreamManager.kLoggingStream]
-                  .bufferSize,
+              'size': dds.loggingRepository.bufferSize,
             });
 
     _clientPeer.registerMethod('setLogHistorySize', (parameters) {
@@ -152,8 +150,7 @@
           "'size' must be greater or equal to zero",
         );
       }
-      _StreamManager.loggingRepositories[_StreamManager.kLoggingStream]
-          .resize(size);
+      dds.loggingRepository.resize(size);
       return _RPCResponses.success;
     });
 
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index d2a6dcb..06327a8 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -10,6 +10,7 @@
     _clientManager = _ClientManager(this);
     _expressionEvaluator = _ExpressionEvaluator(this);
     _isolateManager = _IsolateManager(this);
+    _loggingRepository = _LoggingRepository();
     _streamManager = _StreamManager(this);
     _authCode = _authCodesEnabled ? _makeAuthToken() : '';
   }
@@ -269,6 +270,9 @@
   _IsolateManager get isolateManager => _isolateManager;
   _IsolateManager _isolateManager;
 
+  _LoggingRepository get loggingRepository => _loggingRepository;
+  _LoggingRepository _loggingRepository;
+
   _StreamManager get streamManager => _streamManager;
   _StreamManager _streamManager;
 
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 542fe91..abb233c 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -91,14 +91,7 @@
     // The _IsolateManager requires information from both the Debug and
     // Isolate streams, so they must always be subscribed to by DDS.
     for (final stream in ddsCoreStreams) {
-      try {
-        await streamListen(null, stream);
-        if (loggingRepositoryStreams.contains(stream)) {
-          loggingRepositories[stream] = _LoggingRepository();
-        }
-      } on json_rpc.RpcException {
-        // Stdout and Stderr streams may not exist.
-      }
+      await streamListen(null, stream);
     }
     dds._vmServiceClient.registerMethod(
       'streamNotify',
@@ -108,10 +101,10 @@
         if (isolateManagerStreams.contains(streamId)) {
           dds.isolateManager.handleIsolateEvent(parameters);
         }
-        // Keep a history of messages to send to clients when they first
-        // subscribe to a stream with an event history.
-        if (loggingRepositories.containsKey(streamId)) {
-          loggingRepositories[streamId].add(parameters.asMap);
+        // Keep a history of log messages to send to clients when they first
+        // subscribe to the Logging stream.
+        if (streamId == kLoggingStream) {
+          dds.loggingRepository.add(parameters.asMap);
         }
         streamNotify(streamId, parameters.value);
       },
@@ -144,8 +137,8 @@
     }
     if (client != null) {
       streamListeners[stream].add(client);
-      if (loggingRepositories.containsKey(stream)) {
-        loggingRepositories[stream].sendHistoricalLogs(client);
+      if (stream == kLoggingStream) {
+        dds.loggingRepository.sendHistoricalLogs(client);
       } else if (stream == kServiceStream) {
         // Send all previously registered service extensions when a client
         // subscribes to the Service stream.
@@ -230,13 +223,8 @@
   );
 
   static const kDebugStream = 'Debug';
-  static const kExtensionStream = 'Extension';
   static const kIsolateStream = 'Isolate';
   static const kLoggingStream = 'Logging';
-  static const kStderrStream = 'Stderr';
-  static const kStdoutStream = 'Stdout';
-
-  static Map<String, _LoggingRepository> loggingRepositories = {};
 
   // Never cancel the Debug or Isolate stream as `_IsolateManager` requires
   // them for isolate state notifications.
@@ -245,13 +233,10 @@
     kIsolateStream,
   };
 
-  // Never cancel the logging and extension event streams as `_LoggingRepository`
-  // requires them keep history.
+  // Never cancel the Logging stream as `_LoggingRepository` requires it to
+  // keep a log history.
   static const loggingRepositoryStreams = <String>{
-    kExtensionStream,
     kLoggingStream,
-    kStderrStream,
-    kStdoutStream,
   };
 
   // The set of streams that DDS requires to function.
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index d2fdbdb..a7ae669 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 1.5.0
+version: 1.4.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
diff --git a/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
index 7bc0288..067ee7d 100644
--- a/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
@@ -61,12 +61,20 @@
 
   WhereOrNullTransformer(this._typeProvider, this._typeSystem);
 
-  /// If [expression] is the `orElse` argument of a call that can be
-  /// transformed, returns information about the transformable call; otherwise
-  /// returns `null`.
+  /// If [expression] is the expression part of the `orElse` argument of a call
+  /// that can be transformed, returns information about the transformable call;
+  /// otherwise returns `null`.
   WhereOrNullTransformationInfo tryTransformOrElseArgument(
-          Expression expression) =>
-      _tryTransformMethodInvocation(expression?.parent?.parent?.parent);
+      Expression expression) {
+    var transformationInfo =
+        _tryTransformMethodInvocation(expression?.parent?.parent?.parent);
+    if (transformationInfo != null &&
+        identical(transformationInfo.orElseArgument.expression, expression)) {
+      return transformationInfo;
+    } else {
+      return null;
+    }
+  }
 
   /// Searches [argumentList] for a named argument with the name "orElse".  If
   /// such an argument is found, and no other named arguments are found, it is
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index a822486..b0ba46d 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -2757,6 +2757,29 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_firstWhere_complex_target() async {
+    // See https://github.com/dart-lang/sdk/issues/43956
+    var content = '''
+Iterable<Match> allMatches(String str) => 'x'.allMatches(str);
+
+Match matchAsPrefix(String str, [int start = 0]) {
+  return allMatches(str)
+      .firstWhere((match) => match.start == start, orElse: () => null);
+}
+''';
+    var expected = '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+Iterable<Match> allMatches(String str) => 'x'.allMatches(str);
+
+Match? matchAsPrefix(String str, [int start = 0]) {
+  return allMatches(str)
+      .firstWhereOrNull((match) => match.start == start);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_firstWhere_non_nullable() async {
     var content = '''
 int firstEven(Iterable<int> x)
diff --git a/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart b/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart
index 27e7033..8360432 100644
--- a/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart
+++ b/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart
@@ -133,6 +133,15 @@
         isNull);
   }
 
+  Future<void> test_mismatch_other_subexpression() async {
+    await analyze('''
+List<int> f(List<int> x) => x;
+g(List<int> x) => f(x).firstWhere((i) => i.isEven, orElse: () => null);
+''');
+    var xExpression = findNode.simple('x).firstWhere');
+    expect(transformer.tryTransformOrElseArgument(xExpression), isNull);
+  }
+
   Future<void> test_mismatch_unrelated_type() async {
     await analyze('''
 abstract class C {
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index e644202..a4f3270 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -557,44 +557,6 @@
 
   vm_options->AddArguments(vm_argv, vm_argc);
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  if (!enabled_experiments_.is_empty()) {
-    intptr_t num_experiments = enabled_experiments_.length();
-    if (!(Options::disable_dart_dev() || run_script)) {
-      const char* kEnableExperiment = "--enable-experiment=";
-      int option_size = strlen(kEnableExperiment);
-      for (intptr_t i = 0; i < num_experiments; ++i) {
-        const char* flag = enabled_experiments_.At(i);
-        option_size += strlen(flag);
-        if (i + 1 != num_experiments) {
-          // Account for comma if there's more experiments to add.
-          ++option_size;
-        }
-      }
-      // Make room for null terminator
-      ++option_size;
-
-      char* enabled_experiments_arg = new char[option_size];
-      int offset = snprintf(enabled_experiments_arg, option_size, "%s",
-                            kEnableExperiment);
-      for (intptr_t i = 0; i < num_experiments; ++i) {
-        const char* flag = enabled_experiments_.At(i);
-        const char* kFormat = (i + 1 != num_experiments) ? "%s," : "%s";
-        offset += snprintf(enabled_experiments_arg + offset,
-                           option_size - offset, kFormat, flag);
-        free(const_cast<char*>(flag));
-        ASSERT(offset < option_size);
-      }
-      DartDevIsolate::set_should_run_dart_dev(true);
-      dart_options->AddArgument(enabled_experiments_arg);
-    } else {
-      for (intptr_t i = 0; i < num_experiments; ++i) {
-        free(const_cast<char*>(enabled_experiments_.At(i)));
-      }
-    }
-  }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
   // If running with dartdev, attempt to parse VM flags which are part of the
   // dartdev command (e.g., --enable-vm-service, --observe, etc).
   if (!run_script) {
diff --git a/runtime/observatory/tests/service/dds_extension_event_history_test.dart b/runtime/observatory/tests/service/dds_extension_event_history_test.dart
deleted file mode 100644
index 0c3d165..0000000
--- a/runtime/observatory/tests/service/dds_extension_event_history_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:developer';
-
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
-  // Post a total of 9 events
-  for (int i = 1; i <= 9; ++i) {
-    postEvent('Test', {
-      'id': i,
-    });
-  }
-}
-
-var tests = <IsolateTest>[
-  isPausedAtStart,
-  resumeIsolate,
-  (Isolate isolate) async {
-    final completer = Completer<void>();
-    int i = 1;
-    await subscribeToStream(isolate.vm, 'Extension', (event) async {
-      expect(event.extensionKind, 'Test');
-      expect(event.extensionData!['id'], i);
-      i++;
-
-      if (i == 10) {
-        await cancelStreamSubscription('Extension');
-        completer.complete();
-      } else if (i > 10) {
-        fail('Too many log messages');
-      }
-    });
-    await completer.future;
-  },
-];
-
-main(args) => runIsolateTests(
-      args,
-      tests,
-      enableService: false, // DDS specific feature
-      testeeConcurrent: testMain,
-      pause_on_start: true,
-      pause_on_exit: true,
-    );
diff --git a/runtime/observatory/tests/service/dds_stdout_stderr_history_test.dart b/runtime/observatory/tests/service/dds_stdout_stderr_history_test.dart
deleted file mode 100644
index c0d6ba5..0000000
--- a/runtime/observatory/tests/service/dds_stdout_stderr_history_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
-  // Log a total of 9 messages
-  for (int i = 1; i <= 9; ++i) {
-    print('Stdout log$i');
-    stderr.writeln('Stderr log$i');
-  }
-}
-
-Future streamHistoryTest(Isolate isolate, String stream) async {
-  final completer = Completer<void>();
-  int i = 1;
-  await subscribeToStream(isolate.vm, stream, (event) async {
-    // Newlines are sent as separate events for some reason. Ignore them.
-    if (!event.bytesAsString!.startsWith(stream)) {
-      return;
-    }
-    expect(event.bytesAsString, '$stream log$i');
-    i++;
-
-    if (i == 10) {
-      await cancelStreamSubscription(stream);
-      completer.complete();
-    } else if (i > 10) {
-      fail('Too many log messages');
-    }
-  });
-  await completer.future;
-}
-
-var tests = <IsolateTest>[
-  isPausedAtStart,
-  resumeIsolate,
-  (Isolate isolate) async {
-    await streamHistoryTest(isolate, 'Stdout');
-  },
-  (Isolate isolate) async {
-    await streamHistoryTest(isolate, 'Stderr');
-  },
-];
-
-main(args) => runIsolateTests(
-      args,
-      tests,
-      enableService: false, // DDS specific feature
-      testeeConcurrent: testMain,
-      pause_on_start: true,
-      pause_on_exit: true,
-    );
diff --git a/runtime/observatory/tests/service/network_profiling_test.dart b/runtime/observatory/tests/service/network_profiling_test.dart
index 3a318ca..d68fbeb 100644
--- a/runtime/observatory/tests/service/network_profiling_test.dart
+++ b/runtime/observatory/tests/service/network_profiling_test.dart
@@ -56,14 +56,11 @@
   postEvent('socketTest', {'socket': 'test'});
 }
 
-bool checkFinishEvent(ServiceEvent event) {
+void checkFinishEvent(ServiceEvent event) {
   expect(event.kind, equals(ServiceEvent.kExtension));
-  if (event.extensionKind != 'socketTest') {
-    return false;
-  }
+  expect(event.extensionKind, equals('socketTest'));
   expect(event.extensionData, isA<Map>());
   expect(event.extensionData!['socket'], equals('test'));
-  return true;
 }
 
 var tests = <IsolateTest>[
@@ -105,10 +102,9 @@
     var sub;
     sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
         (ServiceEvent event) {
-      if (checkFinishEvent(event)) {
-        sub.cancel();
-        completer.complete();
-      }
+      checkFinishEvent(event);
+      sub.cancel();
+      completer.complete();
     });
 
     dynamic result = await isolate.invokeRpc("invoke",
@@ -154,10 +150,9 @@
       completer = Completer();
       sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
           (ServiceEvent event) {
-        if (checkFinishEvent(event)) {
-          sub.cancel();
-          completer.complete();
-        }
+        checkFinishEvent(event);
+        sub.cancel();
+        completer.complete();
       });
       dynamic result = await isolate.invokeRpc("invoke",
           {"targetId": lib.id, "selector": "socketTest", "argumentIds": []});
@@ -202,10 +197,9 @@
     var sub;
     sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
         (ServiceEvent event) {
-      if (checkFinishEvent(event)) {
-        sub.cancel();
-        completer.complete();
-      }
+      checkFinishEvent(event);
+      sub.cancel();
+      completer.complete();
     });
 
     dynamic result = await isolate.invokeRpc("invoke",
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 9e721f2..f8d96f8 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -111,6 +111,7 @@
 get_object_rpc_test: SkipByDesign
 get_source_report_test: Skip, Timeout
 get_source_report_with_mixin_test: Skip, Timeout
+get_stack_limit_test: Skip, Timeout
 get_stack_rpc_test: Skip, Timeout
 implicit_getter_setter_test: SkipByDesign
 invoke_test: Skip, Timeout
diff --git a/runtime/observatory_2/tests/service_2/dds_extension_event_history_test.dart b/runtime/observatory_2/tests/service_2/dds_extension_event_history_test.dart
deleted file mode 100644
index ea8ab07..0000000
--- a/runtime/observatory_2/tests/service_2/dds_extension_event_history_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:developer';
-
-import 'package:observatory_2/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
-  // Post a total of 9 events
-  for (int i = 1; i <= 9; ++i) {
-    postEvent('Test', {
-      'id': i,
-    });
-  }
-}
-
-var tests = <IsolateTest>[
-  isPausedAtStart,
-  resumeIsolate,
-  (Isolate isolate) async {
-    final completer = Completer<void>();
-    int i = 1;
-    await subscribeToStream(isolate.vm, 'Extension', (event) async {
-      expect(event.extensionKind, 'Test');
-      expect(event.extensionData['id'], i);
-      i++;
-
-      if (i == 10) {
-        await cancelStreamSubscription('Extension');
-        completer.complete();
-      } else if (i > 10) {
-        fail('Too many log messages');
-      }
-    });
-    await completer.future;
-  },
-];
-
-main(args) => runIsolateTests(
-      args,
-      tests,
-      enableService: false, // DDS specific feature
-      testeeConcurrent: testMain,
-      pause_on_start: true,
-      pause_on_exit: true,
-    );
diff --git a/runtime/observatory_2/tests/service_2/dds_stdout_stderr_history_test.dart b/runtime/observatory_2/tests/service_2/dds_stdout_stderr_history_test.dart
deleted file mode 100644
index 9fc0b7a..0000000
--- a/runtime/observatory_2/tests/service_2/dds_stdout_stderr_history_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:observatory_2/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
-  // Log a total of 9 messages
-  for (int i = 1; i <= 9; ++i) {
-    print('Stdout log$i');
-    stderr.writeln('Stderr log$i');
-  }
-}
-
-Future streamHistoryTest(Isolate isolate, String stream) async {
-  final completer = Completer<void>();
-  int i = 1;
-  await subscribeToStream(isolate.vm, stream, (event) async {
-    // Newlines are sent as separate events for some reason. Ignore them.
-    if (!event.bytesAsString.startsWith(stream)) {
-      return;
-    }
-    expect(event.bytesAsString, '$stream log$i');
-    i++;
-
-    if (i == 10) {
-      await cancelStreamSubscription(stream);
-      completer.complete();
-    } else if (i > 10) {
-      fail('Too many log messages');
-    }
-  });
-  await completer.future;
-}
-
-var tests = <IsolateTest>[
-  isPausedAtStart,
-  resumeIsolate,
-  (Isolate isolate) async {
-    await streamHistoryTest(isolate, 'Stdout');
-  },
-  (Isolate isolate) async {
-    await streamHistoryTest(isolate, 'Stderr');
-  },
-];
-
-main(args) => runIsolateTests(
-      args,
-      tests,
-      enableService: false, // DDS specific feature
-      testeeConcurrent: testMain,
-      pause_on_start: true,
-      pause_on_exit: true,
-    );
diff --git a/runtime/observatory_2/tests/service_2/network_profiling_test.dart b/runtime/observatory_2/tests/service_2/network_profiling_test.dart
index 8ba995f..5c27795 100644
--- a/runtime/observatory_2/tests/service_2/network_profiling_test.dart
+++ b/runtime/observatory_2/tests/service_2/network_profiling_test.dart
@@ -56,14 +56,11 @@
   postEvent('socketTest', {'socket': 'test'});
 }
 
-bool checkFinishEvent(ServiceEvent event) {
+Future<void> checkFinishEvent(ServiceEvent event) {
   expect(event.kind, equals(ServiceEvent.kExtension));
-  if (event.extensionKind != 'socketTest') {
-    return false;
-  }
+  expect(event.extensionKind, equals('socketTest'));
   expect(event.extensionData, isA<Map>());
   expect(event.extensionData['socket'], equals('test'));
-  return true;
 }
 
 var tests = <IsolateTest>[
@@ -105,10 +102,9 @@
     var sub;
     sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
         (ServiceEvent event) {
-      if (checkFinishEvent(event)) {
-        sub.cancel();
-        completer.complete();
-      }
+      checkFinishEvent(event);
+      sub.cancel();
+      completer.complete();
     });
 
     dynamic result = await isolate.invokeRpc("invoke",
@@ -154,10 +150,9 @@
       completer = Completer();
       sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
           (ServiceEvent event) {
-        if (checkFinishEvent(event)) {
-          sub.cancel();
-          completer.complete();
-        }
+        checkFinishEvent(event);
+        sub.cancel();
+        completer.complete();
       });
       dynamic result = await isolate.invokeRpc("invoke",
           {"targetId": lib.id, "selector": "socketTest", "argumentIds": []});
@@ -202,10 +197,9 @@
     var sub;
     sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
         (ServiceEvent event) {
-      if (checkFinishEvent(event)) {
-        sub.cancel();
-        completer.complete();
-      }
+      checkFinishEvent(event);
+      sub.cancel();
+      completer.complete();
     });
 
     dynamic result = await isolate.invokeRpc("invoke",
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 9e721f2..8c09f06 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -111,6 +111,7 @@
 get_object_rpc_test: SkipByDesign
 get_source_report_test: Skip, Timeout
 get_source_report_with_mixin_test: Skip, Timeout
+get_stack_limit_rpc_test: Skip, Timeout
 get_stack_rpc_test: Skip, Timeout
 implicit_getter_setter_test: SkipByDesign
 invoke_test: Skip, Timeout
diff --git a/runtime/tests/vm/dart/regress_44026_main.dart b/runtime/tests/vm/dart/regress_44026_main.dart
new file mode 100644
index 0000000..e4278bd
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44026_main.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, 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.
+
+// Main script for regress_44026_test.dart.
+// @dart=2.12
+
+import 'regress_44026_opt_out_lib.dart';
+
+void main() {
+  sayHello(true);
+}
diff --git a/runtime/tests/vm/dart/regress_44026_opt_out_lib.dart b/runtime/tests/vm/dart/regress_44026_opt_out_lib.dart
new file mode 100644
index 0000000..b036fba
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44026_opt_out_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, 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.
+
+// Opted-out library for regress_44026_test.dart.
+// @dart = 2.7
+
+void sayHello(bool t) {
+  String s;
+  if (t) {
+    s = 'hello';
+  }
+  print(s);
+}
diff --git a/runtime/tests/vm/dart/regress_44026_test.dart b/runtime/tests/vm/dart/regress_44026_test.dart
new file mode 100644
index 0000000..5d14bf9
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44026_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, 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.
+
+// OtherResources=regress_44026_main.dart
+// OtherResources=regress_44026_opt_out_lib.dart
+
+// Tests that compile-time error is issued if NNBD opted-out library is used
+// from opted-in entry point (with null safety auto-detection).
+// Regression test for https://github.com/dart-lang/sdk/issues/44026.
+
+import 'dart:io' show File, Platform, Process;
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+import 'snapshot_test_helper.dart';
+
+const int kCompilationErrorExitCode = 254;
+
+main() async {
+  await withTempDir((String temp) async {
+    // Need to copy test scripts out of Dart SDK to avoid hardcoded
+    // opted-in/opted-out status for Dart SDK tests.
+    for (String script in [
+      'regress_44026_main.dart',
+      'regress_44026_opt_out_lib.dart'
+    ]) {
+      final scriptInTemp = path.join(temp, script);
+      File.fromUri(Platform.script.resolve(script)).copySync(scriptInTemp);
+    }
+
+    // Do not add Platform.executableArguments into arguments to avoid passing
+    // --sound-null-safety / --no-sound-null-safety arguments.
+    final result = await Process.run(Platform.executable, [
+      path.join(temp, 'regress_44026_main.dart'),
+    ]);
+    print('stdout: ${result.stdout}');
+    print('stderr: ${result.stderr}');
+    Expect.equals(kCompilationErrorExitCode, result.exitCode);
+    Expect.stringContainsInOrder(result.stderr, [
+      "Error: A library can't opt out of null safety by default, when using sound null safety."
+    ]);
+  });
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index ad2333e..16ee403 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -256,6 +256,7 @@
 dart/kernel_determinism_test: SkipByDesign # Test needs to run from source
 dart/minimal_kernel_test: SkipByDesign # Test needs to run from source
 dart/null_safety_autodetection_in_kernel_compiler_test: SkipByDesign # Test needs to run from source
+dart/regress_44026_test: SkipByDesign # Test needs to run from source
 dart/snapshot_depfile_test: SkipByDesign # Test needs to run from source
 dart/type_casts_with_null_safety_autodetection_test: SkipByDesign # Test needs to run from source
 dart_2/appjit*: SkipByDesign # Test needs to run from source
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index dac8c18..5d7112a 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -806,7 +806,7 @@
   }
 
   // If we are loading from source, figure out the mode from the source.
-  if (KernelIsolate::GetExperimentalFlag("non-nullable")) {
+  if (!KernelIsolate::GetExperimentalFlag("no-non-nullable")) {
     return KernelIsolate::DetectNullSafety(script_uri, package_config,
                                            original_working_directory);
   }
diff --git a/tests/lib/isolate/detect_nullsafety_1_test.dart b/tests/lib/isolate/detect_nullsafety_1_test.dart
index 1fecd54..fc7ae94 100644
--- a/tests/lib/isolate/detect_nullsafety_1_test.dart
+++ b/tests/lib/isolate/detect_nullsafety_1_test.dart
@@ -21,8 +21,8 @@
   try {
     // Running from Source.
     testNullSafetyMode(sourcePath, 'Strong Mode');
-    // Without the enable experiment option it will be in weak mode.
-    testNullSafetyMode1(sourcePath, 'Weak Mode');
+    // Without the enable experiment option it will be in strong mode.
+    testNullSafetyMode1(sourcePath, 'Strong Mode');
 
     // Running from Kernel File.
     testNullSafetyMode(dillPath, 'Strong Mode');
diff --git a/tools/VERSION b/tools/VERSION
index ead15d6..52a2514 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 17
+PRERELEASE 18
 PRERELEASE_PATCH 0
\ No newline at end of file