Version 2.10.0-52.0.dev

Merge commit 'c9b4f1b5d57086e9ac383134c2ec94a5553cb5f3' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3325b41..c9eefa2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@
 
 *   Adds `Abort` method to class `HttpClientRequest`, which allows users
     to cancel outgoing HTTP requests and stop following IO operations.
+*   A validtion check is added to `path` of class `Cookie`. Having characters
+    ranging from 0x00 to 0x1f and 0x3b (";") will lead to a `FormatException`.
 
 #### `dart:typed_data`
 
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 46b2b3e..0923d43 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -6273,35 +6273,6 @@
     }
     _type = type;
   }
-
-  /// Return the error reported during type inference for this variable, or
-  /// `null` if this variable is not a subject of type inference, or there was
-  /// no error.
-  TopLevelInferenceError get typeInferenceError {
-    if (linkedNode != null) {
-      return linkedContext.getTypeInferenceError(linkedNode);
-    }
-
-    // We don't support type inference errors without linking.
-    return null;
-  }
-
-  /// Return `true` if this variable needs the setter.
-  bool get _hasSetter {
-    if (isConst) {
-      return false;
-    }
-
-    // TODO(scheglov) is this right?
-    if (isLate) {
-      if (isFinal) {
-        return !hasInitializer;
-      }
-      return true;
-    }
-
-    return !isFinal;
-  }
 }
 
 /// A concrete implementation of a [ParameterElement].
@@ -7126,6 +7097,18 @@
   @override
   DartType get type => ElementTypeProvider.current.getFieldType(this);
 
+  /// Return the error reported during type inference for this variable, or
+  /// `null` if this variable is not a subject of type inference, or there was
+  /// no error.
+  TopLevelInferenceError get typeInferenceError {
+    if (linkedNode != null) {
+      return linkedContext.getTypeInferenceError(linkedNode);
+    }
+
+    // We don't support type inference errors without linking.
+    return null;
+  }
+
   @override
   DartType get typeInternal {
     if (linkedNode != null) {
@@ -7146,6 +7129,19 @@
     }
     return super.typeInternal;
   }
+
+  /// Return `true` if this variable needs the setter.
+  bool get _hasSetter {
+    if (isConst) {
+      return false;
+    }
+
+    if (isLate) {
+      return !isFinal || !hasInitializer;
+    }
+
+    return !isFinal;
+  }
 }
 
 /// Instances of this class are set for fields and top-level variables
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 0a37c30..427d11f 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -261,145 +261,6 @@
     _objectElement = null;
   }
 
-  static FunctionElementImpl functionElement(String functionName) =>
-      functionElement4(functionName, null, null, null, null);
-
-  static FunctionElementImpl functionElement2(
-          String functionName, DartType returnType) =>
-      functionElement3(functionName, returnType, null, null);
-
-  static FunctionElementImpl functionElement3(
-      String functionName,
-      DartType returnType,
-      List<TypeDefiningElement> normalParameters,
-      List<TypeDefiningElement> optionalParameters) {
-    // We don't create parameter elements because we don't have parameter names
-    FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
-    functionElement.returnType = returnType ?? VoidTypeImpl.instance;
-    // parameters
-    int normalCount = normalParameters == null ? 0 : normalParameters.length;
-    int optionalCount =
-        optionalParameters == null ? 0 : optionalParameters.length;
-    int totalCount = normalCount + optionalCount;
-    List<ParameterElement> parameters = List<ParameterElement>(totalCount);
-    for (int i = 0; i < totalCount; i++) {
-      ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
-      if (i < normalCount) {
-        parameter.type = _typeDefiningElementType(normalParameters[i]);
-        parameter.parameterKind = ParameterKind.REQUIRED;
-      } else {
-        parameter.type =
-            _typeDefiningElementType(optionalParameters[i - normalCount]);
-        parameter.parameterKind = ParameterKind.POSITIONAL;
-      }
-      parameters[i] = parameter;
-    }
-    functionElement.parameters = parameters;
-    // done
-    return functionElement;
-  }
-
-  static FunctionElementImpl functionElement4(
-      String functionName,
-      ClassElement returnElement,
-      List<ClassElement> normalParameters,
-      List<String> names,
-      List<ClassElement> namedParameters) {
-    FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
-    // parameters
-    int normalCount = normalParameters == null ? 0 : normalParameters.length;
-    int nameCount = names == null ? 0 : names.length;
-    int typeCount = namedParameters == null ? 0 : namedParameters.length;
-    if (names != null && nameCount != typeCount) {
-      throw StateError(
-          "The passed String[] and ClassElement[] arrays had different lengths.");
-    }
-    int totalCount = normalCount + nameCount;
-    List<ParameterElement> parameters = List<ParameterElement>(totalCount);
-    for (int i = 0; i < totalCount; i++) {
-      if (i < normalCount) {
-        ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
-        parameter.type = _typeDefiningElementType(normalParameters[i]);
-        parameter.parameterKind = ParameterKind.REQUIRED;
-        parameters[i] = parameter;
-      } else {
-        ParameterElementImpl parameter =
-            ParameterElementImpl(names[i - normalCount], i);
-        parameter.type =
-            _typeDefiningElementType(namedParameters[i - normalCount]);
-        parameter.parameterKind = ParameterKind.NAMED;
-        parameters[i] = parameter;
-      }
-    }
-    functionElement.parameters = parameters;
-    // return type
-    if (returnElement == null) {
-      functionElement.returnType = VoidTypeImpl.instance;
-    } else {
-      functionElement.returnType = _typeDefiningElementType(returnElement);
-    }
-    return functionElement;
-  }
-
-  static FunctionElementImpl functionElement5(
-          String functionName, List<ClassElement> normalParameters) =>
-      functionElement3(functionName, null, normalParameters, null);
-
-  static FunctionElementImpl functionElement6(
-          String functionName,
-          List<ClassElement> normalParameters,
-          List<ClassElement> optionalParameters) =>
-      functionElement3(
-          functionName, null, normalParameters, optionalParameters);
-
-  static FunctionElementImpl functionElement7(
-          String functionName,
-          List<ClassElement> normalParameters,
-          List<String> names,
-          List<ClassElement> namedParameters) =>
-      functionElement4(
-          functionName, null, normalParameters, names, namedParameters);
-
-  static FunctionElementImpl functionElement8(
-      List<DartType> parameters, DartType returnType,
-      {List<DartType> optional, Map<String, DartType> named}) {
-    List<ParameterElement> parameterElements = <ParameterElement>[];
-    for (int i = 0; i < parameters.length; i++) {
-      ParameterElementImpl parameterElement = ParameterElementImpl("a$i", i);
-      parameterElement.type = parameters[i];
-      parameterElement.parameterKind = ParameterKind.REQUIRED;
-      parameterElements.add(parameterElement);
-    }
-    if (optional != null) {
-      int j = parameters.length;
-      for (int i = 0; i < optional.length; i++) {
-        ParameterElementImpl parameterElement = ParameterElementImpl("o$i", j);
-        parameterElement.type = optional[i];
-        parameterElement.parameterKind = ParameterKind.POSITIONAL;
-        parameterElements.add(parameterElement);
-        j++;
-      }
-    } else if (named != null) {
-      int j = parameters.length;
-      for (String s in named.keys) {
-        ParameterElementImpl parameterElement = ParameterElementImpl(s, j);
-        parameterElement.type = named[s];
-        parameterElement.parameterKind = ParameterKind.NAMED;
-        parameterElements.add(parameterElement);
-      }
-    }
-
-    return functionElementWithParameters("f", returnType, parameterElements);
-  }
-
-  static FunctionElementImpl functionElementWithParameters(String functionName,
-      DartType returnType, List<ParameterElement> parameters) {
-    FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
-    functionElement.returnType = returnType ?? VoidTypeImpl.instance;
-    functionElement.parameters = parameters;
-    return functionElement;
-  }
-
   static GenericTypeAliasElementImpl genericTypeAliasElement(String name,
       {List<ParameterElement> parameters = const [], DartType returnType}) {
     var element = GenericTypeAliasElementImpl(name, -1);
@@ -648,17 +509,4 @@
     typeParameter.variance = variance;
     return typeParameter;
   }
-
-  static DartType _typeDefiningElementType(TypeDefiningElement element) {
-    if (element is ClassElement) {
-      return element.instantiate(
-        typeArguments: List.filled(
-          element.typeParameters.length,
-          DynamicTypeImpl.instance,
-        ),
-        nullabilitySuffix: NullabilitySuffix.star,
-      );
-    }
-    throw ArgumentError('element: (${element.runtimeType}) $element');
-  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 727b439..1a6410a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -632,12 +632,8 @@
   }
 
   TopLevelInferenceError getTypeInferenceError(AstNode node) {
-    if (node is DefaultFormalParameter) {
-      return getTypeInferenceError(node.parameter);
-    } else if (node is MethodDeclaration) {
+    if (node is MethodDeclaration) {
       return LazyMethodDeclaration.getTypeInferenceError(node);
-    } else if (node is SimpleFormalParameter) {
-      return LazyFormalParameter.getTypeInferenceError(node);
     } else if (node is VariableDeclaration) {
       return LazyVariableDeclaration.getTypeInferenceError(node);
     } else {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index f036ec1..4e67d44 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1057,7 +1057,7 @@
 
   void validateHasType(AstNode n, PropertyAccessorElement e) {
     if (e.hasImplicitReturnType) {
-      var variable = e.declaration.variable as NonParameterVariableElementImpl;
+      var variable = e.declaration.variable as PropertyInducingElementImpl;
       TopLevelInferenceError error = variable.typeInferenceError;
       if (error != null) {
         if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 5518018..1b926d3 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -1080,112 +1080,129 @@
   }
 
   void test_getNamedParameterTypes_namedParameters() {
-    TestTypeProvider typeProvider = TestTypeProvider();
-    FunctionElement element = ElementFactory.functionElementWithParameters(
-        'f', VoidTypeImpl.instance, [
-      ElementFactory.requiredParameter2('a', typeProvider.intType),
-      ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
-      ElementFactory.namedParameter2('c', typeProvider.stringType),
-      ElementFactory.namedParameter2('d', typeProvider.dynamicType)
-    ]);
-    FunctionTypeImpl type = element.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [
+        requiredParameter(name: 'a', type: intNone),
+        namedParameter(name: 'b', type: doubleNone),
+        namedParameter(name: 'c', type: stringNone),
+      ],
+      returnType: voidNone,
+    );
     Map<String, DartType> types = type.namedParameterTypes;
     expect(types, hasLength(2));
-    expect(types['c'], typeProvider.stringType);
-    expect(types['d'], DynamicTypeImpl.instance);
+    expect(types['b'], doubleNone);
+    expect(types['c'], stringNone);
   }
 
   void test_getNamedParameterTypes_noNamedParameters() {
-    TestTypeProvider typeProvider = TestTypeProvider();
-    FunctionElement element = ElementFactory.functionElementWithParameters(
-        'f', VoidTypeImpl.instance, [
-      ElementFactory.requiredParameter2('a', typeProvider.intType),
-      ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
-      ElementFactory.positionalParameter2('c', typeProvider.stringType)
-    ]);
-    FunctionTypeImpl type = element.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [
+        requiredParameter(type: intNone),
+        requiredParameter(type: doubleNone),
+        positionalParameter(type: stringNone),
+      ],
+      returnType: voidNone,
+    );
     Map<String, DartType> types = type.namedParameterTypes;
     expect(types, hasLength(0));
   }
 
   void test_getNamedParameterTypes_noParameters() {
-    FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [],
+      returnType: voidNone,
+    );
     Map<String, DartType> types = type.namedParameterTypes;
     expect(types, hasLength(0));
   }
 
   void test_getNormalParameterTypes_noNormalParameters() {
-    TestTypeProvider typeProvider = TestTypeProvider();
-    FunctionElement element = ElementFactory.functionElementWithParameters(
-        'f', VoidTypeImpl.instance, [
-      ElementFactory.positionalParameter2('c', typeProvider.stringType),
-      ElementFactory.positionalParameter2('d', typeProvider.dynamicType)
-    ]);
-    FunctionTypeImpl type = element.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [
+        positionalParameter(type: intNone),
+        positionalParameter(type: doubleNone),
+      ],
+      returnType: voidNone,
+    );
     List<DartType> types = type.normalParameterTypes;
     expect(types, hasLength(0));
   }
 
   void test_getNormalParameterTypes_noParameters() {
-    FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [],
+      returnType: voidNone,
+    );
     List<DartType> types = type.normalParameterTypes;
     expect(types, hasLength(0));
   }
 
   void test_getNormalParameterTypes_normalParameters() {
-    TestTypeProvider typeProvider = TestTypeProvider();
-    FunctionElement element = ElementFactory.functionElementWithParameters(
-        'f', VoidTypeImpl.instance, [
-      ElementFactory.requiredParameter2('a', typeProvider.intType),
-      ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
-      ElementFactory.positionalParameter2('c', typeProvider.stringType)
-    ]);
-    FunctionTypeImpl type = element.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [
+        requiredParameter(type: intNone),
+        requiredParameter(type: doubleNone),
+        positionalParameter(type: stringNone),
+      ],
+      returnType: voidNone,
+    );
     List<DartType> types = type.normalParameterTypes;
     expect(types, hasLength(2));
-    expect(types[0], typeProvider.intType);
-    expect(types[1], DynamicTypeImpl.instance);
+    expect(types[0], intNone);
+    expect(types[1], doubleNone);
   }
 
   void test_getOptionalParameterTypes_noOptionalParameters() {
-    TestTypeProvider typeProvider = TestTypeProvider();
-    FunctionElement element = ElementFactory.functionElementWithParameters(
-        'f', VoidTypeImpl.instance, [
-      ElementFactory.requiredParameter2('a', typeProvider.intType),
-      ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
-      ElementFactory.namedParameter2('c', typeProvider.stringType),
-      ElementFactory.namedParameter2('d', typeProvider.dynamicType)
-    ]);
-    FunctionTypeImpl type = element.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [
+        requiredParameter(name: 'a', type: intNone),
+        namedParameter(name: 'b', type: doubleNone),
+      ],
+      returnType: voidNone,
+    );
     List<DartType> types = type.optionalParameterTypes;
     expect(types, hasLength(0));
   }
 
   void test_getOptionalParameterTypes_noParameters() {
-    FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [],
+      returnType: voidNone,
+    );
     List<DartType> types = type.optionalParameterTypes;
     expect(types, hasLength(0));
   }
 
   void test_getOptionalParameterTypes_optionalParameters() {
-    TestTypeProvider typeProvider = TestTypeProvider();
-    FunctionElement element = ElementFactory.functionElementWithParameters(
-        'f', VoidTypeImpl.instance, [
-      ElementFactory.requiredParameter2('a', typeProvider.intType),
-      ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
-      ElementFactory.positionalParameter2('c', typeProvider.stringType),
-      ElementFactory.positionalParameter2('d', typeProvider.dynamicType)
-    ]);
-    FunctionTypeImpl type = element.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [
+        requiredParameter(type: intNone),
+        positionalParameter(type: doubleNone),
+        positionalParameter(type: stringNone),
+      ],
+      returnType: voidNone,
+    );
     List<DartType> types = type.optionalParameterTypes;
     expect(types, hasLength(2));
-    expect(types[0], typeProvider.stringType);
-    expect(types[1], DynamicTypeImpl.instance);
+    expect(types[0], doubleNone);
+    expect(types[1], stringNone);
   }
 
   void test_resolveToBound() {
-    FunctionElementImpl f = ElementFactory.functionElement('f');
-    FunctionTypeImpl type = f.type;
+    var type = functionTypeNone(
+      typeFormals: [],
+      parameters: [],
+      returnType: voidNone,
+    );
 
     // Returns this.
     expect(type.resolveToBound(null), same(type));
diff --git a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
index eaac79c..8729624 100644
--- a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
@@ -23,52 +23,75 @@
 
   test_final_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
-void f() {
-  final x;
-  x = 0;
-  x; // 0
+void f(final x) {
+  x;
 }
 ''');
-    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+    _assertAssigned('x;', assigned: true, unassigned: false);
   }
 
   test_final_definitelyAssigned_read_prefixNegate() async {
     await assertNoErrorsInCode(r'''
-void f() {
-  // ignore:unused_local_variable
-  final x;
-  x = 0;
-  -x; // 0
+void f(final x) {
+  -x;
 }
 ''');
-    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+    _assertAssigned('x;', assigned: true, unassigned: false);
   }
 
-  test_final_definitelyAssigned_write_assignment_simple() async {
+  test_final_definitelyAssigned_readWrite_compoundAssignment() async {
     await assertErrorsInCode(r'''
-void f() {
-  // ignore:unused_local_variable
-  final x;
-  x = 0;
-  x = 1;
+void f(final x) {
+  x += 1;
 }
 ''', [
-      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 67, 1),
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 20, 1),
     ]);
-    _assertAssigned('x = 0', assigned: false, unassigned: true);
-    _assertAssigned('x = 1', assigned: true, unassigned: false);
+    _assertAssigned('x +=', assigned: true, unassigned: false);
+  }
+
+  test_final_definitelyAssigned_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f(final x) {
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 20, 1),
+    ]);
+    _assertAssigned('x++', assigned: true, unassigned: false);
+  }
+
+  test_final_definitelyAssigned_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f(final x) {
+  ++x;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 22, 1),
+    ]);
+    _assertAssigned('x;', assigned: true, unassigned: false);
+  }
+
+  test_final_definitelyAssigned_write() async {
+    await assertErrorsInCode(r'''
+void f(final x) {
+  x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 20, 1),
+    ]);
+    _assertAssigned('x =', assigned: true, unassigned: false);
   }
 
   test_final_definitelyAssigned_write_forEachLoop_identifier() async {
     await assertErrorsInCode(r'''
-void f() {
-  final x = 0;
+void f(final x) {
   for (x in [0, 1, 2]) {
     x;
   }
 }
 ''', [
-      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 33, 1),
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 25, 1),
     ]);
     _assertAssigned('x in', assigned: true, unassigned: false);
   }
@@ -88,6 +111,56 @@
     _assertAssigned('x()', assigned: false, unassigned: true);
   }
 
+  test_final_definitelyUnassigned_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  final x;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 58, 1),
+    ]);
+    _assertAssigned('x +=', assigned: false, unassigned: true);
+  }
+
+  test_final_definitelyUnassigned_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  final x;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 58, 1),
+    ]);
+    _assertAssigned('x++', assigned: false, unassigned: true);
+  }
+
+  test_final_definitelyUnassigned_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  final x;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 60, 1),
+    ]);
+    _assertAssigned('x; // 0', assigned: false, unassigned: true);
+  }
+
+  test_final_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  final x;
+  x = 0;
+}
+''');
+    _assertAssigned('x = 0', assigned: false, unassigned: true);
+  }
+
   test_final_neither_read() async {
     await assertErrorsInCode(r'''
 void f(bool b) {
@@ -101,6 +174,65 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_final_neither_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  final x;
+  if (b) x = 0;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 80, 1),
+      error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 80, 1),
+    ]);
+    _assertAssigned('x +=', assigned: false, unassigned: false);
+  }
+
+  test_final_neither_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  final x;
+  if (b) x = 0;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 80, 1),
+      error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 80, 1),
+    ]);
+    _assertAssigned('x++', assigned: false, unassigned: false);
+  }
+
+  test_final_neither_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  final x;
+  if (b) x = 0;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 82, 1),
+      error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 82, 1),
+    ]);
+    _assertAssigned('x; // 0', assigned: false, unassigned: false);
+  }
+
+  test_final_neither_write() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  final x;
+  if (b) x = 0;
+  x = 1;
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 80, 1),
+    ]);
+    _assertAssigned('x = 1', assigned: false, unassigned: false);
+  }
+
   test_lateFinal_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
 void f() {
@@ -112,6 +244,62 @@
     _assertAssigned('x; // 0', assigned: true, unassigned: false);
   }
 
+  test_lateFinal_definitelyAssigned_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x = 0;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 72, 1),
+    ]);
+    _assertAssigned('x +=', assigned: true, unassigned: false);
+  }
+
+  test_lateFinal_definitelyAssigned_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x = 0;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 72, 1),
+    ]);
+    _assertAssigned('x++', assigned: true, unassigned: false);
+  }
+
+  test_lateFinal_definitelyAssigned_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x = 0;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 74, 1),
+    ]);
+    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+  }
+
+  test_lateFinal_definitelyAssigned_write() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x = 0;
+  x = 1;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 72, 1),
+    ]);
+    _assertAssigned('x = 1', assigned: true, unassigned: false);
+  }
+
   test_lateFinal_definitelyUnassigned_read() async {
     await assertErrorsInCode(r'''
 void f() {
@@ -125,10 +313,63 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
 
+  test_lateFinal_definitelyUnassigned_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 63,
+          1),
+    ]);
+    _assertAssigned('x +=', assigned: false, unassigned: true);
+  }
+
+  test_lateFinal_definitelyUnassigned_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 63,
+          1),
+    ]);
+    _assertAssigned('x++', assigned: false, unassigned: true);
+  }
+
+  test_lateFinal_definitelyUnassigned_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 65,
+          1),
+    ]);
+    _assertAssigned('x; // 0', assigned: false, unassigned: true);
+  }
+
+  test_lateFinal_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final x;
+  x = 0;
+}
+''');
+    _assertAssigned('x =', assigned: false, unassigned: true);
+  }
+
   test_lateFinal_neither_read() async {
     await assertNoErrorsInCode(r'''
 void f(bool b) {
-  late var x;
+  late final x;
   if (b) x = 0;
   x; // 0
 }
@@ -136,6 +377,54 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_lateFinal_neither_readWrite_compoundAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final x;
+  if (b) x = 0;
+  x += 1;
+}
+''');
+    _assertAssigned('x +=', assigned: false, unassigned: false);
+  }
+
+  test_lateFinal_neither_readWrite_postfixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final x;
+  if (b) x = 0;
+  x++;
+}
+''');
+    _assertAssigned('x++', assigned: false, unassigned: false);
+  }
+
+  test_lateFinal_neither_readWrite_prefixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final x;
+  if (b) x = 0;
+  ++x; // 0
+}
+''');
+    _assertAssigned('x; // 0', assigned: false, unassigned: false);
+  }
+
+  test_lateFinal_neither_write() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final x;
+  if (b) x = 0;
+  x = 1;
+}
+''');
+    _assertAssigned('x = 1', assigned: false, unassigned: false);
+  }
+
   test_lateFinalNullable_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
 void f() {
@@ -147,6 +436,62 @@
     _assertAssigned('x; // 0', assigned: true, unassigned: false);
   }
 
+  test_lateFinalNullable_definitelyAssigned_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x = 0;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 77, 1),
+    ]);
+    _assertAssigned('x +=', assigned: true, unassigned: false);
+  }
+
+  test_lateFinalNullable_definitelyAssigned_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x = 0;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 77, 1),
+    ]);
+    _assertAssigned('x++', assigned: true, unassigned: false);
+  }
+
+  test_lateFinalNullable_definitelyAssigned_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x = 0;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 79, 1),
+    ]);
+    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+  }
+
+  test_lateFinalNullable_definitelyAssigned_write() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x = 0;
+  x = 1;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 77, 1),
+    ]);
+    _assertAssigned('x = 1', assigned: true, unassigned: false);
+  }
+
   test_lateFinalNullable_definitelyUnassigned_read() async {
     await assertErrorsInCode(r'''
 void f() {
@@ -160,6 +505,62 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
 
+  test_lateFinalNullable_definitelyUnassigned_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 68,
+          1),
+      error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 68, 1),
+    ]);
+    _assertAssigned('x +=', assigned: false, unassigned: true);
+  }
+
+  test_lateFinalNullable_definitelyUnassigned_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 68,
+          1),
+      error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 68, 1),
+    ]);
+    _assertAssigned('x++', assigned: false, unassigned: true);
+  }
+
+  test_lateFinalNullable_definitelyUnassigned_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 70,
+          1),
+      error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 70, 1),
+    ]);
+    _assertAssigned('x; // 0', assigned: false, unassigned: true);
+  }
+
+  test_lateFinalNullable_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late final int? x;
+  x = 0;
+}
+''');
+    _assertAssigned('x = 0', assigned: false, unassigned: true);
+  }
+
   test_lateFinalNullable_neither_read() async {
     await assertNoErrorsInCode(r'''
 void f(bool b) {
@@ -171,6 +572,60 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_lateFinalNullable_neither_readWrite_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final int? x;
+  if (b) x = 0;
+  x += 1;
+}
+''', [
+      error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 90, 1),
+    ]);
+    _assertAssigned('x +=', assigned: false, unassigned: false);
+  }
+
+  test_lateFinalNullable_neither_readWrite_postfixIncrement() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final int? x;
+  if (b) x = 0;
+  x++;
+}
+''', [
+      error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 90, 1),
+    ]);
+    _assertAssigned('x++', assigned: false, unassigned: false);
+  }
+
+  test_lateFinalNullable_neither_readWrite_prefixIncrement() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final int? x;
+  if (b) x = 0;
+  ++x; // 0
+}
+''', [
+      error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 92, 1),
+    ]);
+    _assertAssigned('x; // 0', assigned: false, unassigned: false);
+  }
+
+  test_lateFinalNullable_neither_write() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late final int? x;
+  if (b) x = 0;
+  x = 1;
+}
+''');
+    _assertAssigned('x = 1', assigned: false, unassigned: false);
+  }
+
   test_lateFinalPotentiallyNonNullable_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
 void f<T>(T t) {
@@ -182,6 +637,20 @@
     _assertAssigned('x; // 0', assigned: true, unassigned: false);
   }
 
+  test_lateFinalPotentiallyNonNullable_definitelyAssigned_write() async {
+    await assertErrorsInCode(r'''
+void f<T>(T t, T t2) {
+  // ignore:unused_local_variable
+  late final T x;
+  x = t;
+  x = t2;
+}
+''', [
+      error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 86, 1),
+    ]);
+    _assertAssigned('x = t2', assigned: true, unassigned: false);
+  }
+
   test_lateFinalPotentiallyNonNullable_definitelyUnassigned_read() async {
     await assertErrorsInCode(r'''
 void f<T>() {
@@ -195,6 +664,17 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
 
+  test_lateFinalPotentiallyNonNullable_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f<T>(T t) {
+  // ignore:unused_local_variable
+  late final T x;
+  x = t;
+}
+''');
+    _assertAssigned('x = t', assigned: false, unassigned: true);
+  }
+
   test_lateFinalPotentiallyNonNullable_neither_read() async {
     await assertNoErrorsInCode(r'''
 void f<T>(bool b, T t) {
@@ -206,6 +686,18 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_lateFinalPotentiallyNonNullable_neither_write() async {
+    await assertNoErrorsInCode(r'''
+void f<T>(bool b, T t, T t2) {
+  // ignore:unused_local_variable
+  late final T x;
+  if (b) x = t;
+  x = t2;
+}
+''');
+    _assertAssigned('x = t2', assigned: false, unassigned: false);
+  }
+
   test_lateNullable_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
 void f() {
@@ -287,6 +779,54 @@
     _assertAssigned('x; // 0', assigned: true, unassigned: false);
   }
 
+  test_lateVar_definitelyAssigned_readWrite_compoundAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late var x;
+  x = 0;
+  x += 1;
+}
+''');
+    _assertAssigned('x +=', assigned: true, unassigned: false);
+  }
+
+  test_lateVar_definitelyAssigned_readWrite_postfixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late var x;
+  x = 0;
+  x++;
+}
+''');
+    _assertAssigned('x++', assigned: true, unassigned: false);
+  }
+
+  test_lateVar_definitelyAssigned_readWrite_prefixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late var x;
+  x = 0;
+  ++x; // 0
+}
+''');
+    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+  }
+
+  test_lateVar_definitelyAssigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  late var x;
+  x = 0;
+  x = 1;
+}
+''');
+    _assertAssigned('x = 1', assigned: true, unassigned: false);
+  }
+
   test_lateVar_definitelyUnassigned_read() async {
     await assertErrorsInCode(r'''
 void f() {
@@ -311,6 +851,54 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_lateVar_neither_readWrite_compoundAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late var x;
+  if (b) x = 0;
+  x += 1;
+}
+''');
+    _assertAssigned('x +=', assigned: false, unassigned: false);
+  }
+
+  test_lateVar_neither_readWrite_postfixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late var x;
+  if (b) x = 0;
+  x++;
+}
+''');
+    _assertAssigned('x++', assigned: false, unassigned: false);
+  }
+
+  test_lateVar_neither_readWrite_prefixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late var x;
+  if (b) x = 0;
+  ++x; // 0
+}
+''');
+    _assertAssigned('x; // 0', assigned: false, unassigned: false);
+  }
+
+  test_lateVar_neither_write() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  late var x;
+  if (b) x = 0;
+  x = 1;
+}
+''');
+    _assertAssigned('x = 1', assigned: false, unassigned: false);
+  }
+
   test_notNullable_write_forEachLoop_identifier() async {
     await assertNoErrorsInCode(r'''
 void f() {
@@ -320,16 +908,26 @@
   }
 }
 ''');
+    _assertAssigned('x in', assigned: false, unassigned: true);
     _assertAssigned('x; // 0', assigned: true, unassigned: false);
   }
 
   test_nullable_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
 void f(int? x) {
-  x; // 0
+  x;
 }
 ''');
-    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+    _assertAssigned('x;', assigned: true, unassigned: false);
+  }
+
+  test_nullable_definitelyAssigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f(int? x) {
+  x = 0;
+}
+''');
+    _assertAssigned('x = 0', assigned: true, unassigned: false);
   }
 
   test_nullable_definitelyUnassigned_read() async {
@@ -342,6 +940,17 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
 
+  test_nullable_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  int? x;
+  x = 0;
+}
+''');
+    _assertAssigned('x = 0', assigned: false, unassigned: true);
+  }
+
   test_nullable_neither_read() async {
     await assertNoErrorsInCode(r'''
 void f(bool b) {
@@ -353,6 +962,18 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_nullable_neither_write() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  int? x;
+  if (b) x = 0;
+  x = 1;
+}
+''');
+    _assertAssigned('x = 1', assigned: false, unassigned: false);
+  }
+
   test_potentiallyNonNullable_definitelyAssigned_read() async {
     await assertNoErrorsInCode(r'''
 void f<T>(T x) {
@@ -362,6 +983,15 @@
     _assertAssigned('x; // 0', assigned: true, unassigned: false);
   }
 
+  test_potentiallyNonNullable_definitelyAssigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f<T>(T x, T t) {
+  x = t;
+}
+''');
+    _assertAssigned('x = t', assigned: true, unassigned: false);
+  }
+
   test_potentiallyNonNullable_definitelyUnassigned_read() async {
     await assertErrorsInCode(r'''
 void f<T>() {
@@ -378,6 +1008,17 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
 
+  test_potentiallyNonNullable_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f<T>(T t) {
+  // ignore:unused_local_variable
+  T x;
+  x = t;
+}
+''');
+    _assertAssigned('x = t', assigned: false, unassigned: true);
+  }
+
   test_potentiallyNonNullable_neither_read() async {
     await assertErrorsInCode(r'''
 void f<T>(bool b, T t) {
@@ -395,15 +1036,61 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
-  test_var_definitelyAssigned_read() async {
+  test_potentiallyNonNullable_neither_write() async {
     await assertNoErrorsInCode(r'''
-void f() {
-  var x;
-  x = 0;
-  x; // 0
+void f<T>(bool b, T t, T t2) {
+  // ignore:unused_local_variable
+  T x;
+  if (b) x = t;
+  x = t2;
 }
 ''');
-    _assertAssigned('x; // 0', assigned: true, unassigned: false);
+    _assertAssigned('x = t2', assigned: false, unassigned: false);
+  }
+
+  test_var_definitelyAssigned_read() async {
+    await assertNoErrorsInCode(r'''
+void f(var x) {
+  x;
+}
+''');
+    _assertAssigned('x;', assigned: true, unassigned: false);
+  }
+
+  test_var_definitelyAssigned_readWrite_compoundAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f(var x) {
+  x += 1;
+}
+''');
+    _assertAssigned('x +=', assigned: true, unassigned: false);
+  }
+
+  test_var_definitelyAssigned_readWrite_postfixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(var x) {
+  x++;
+}
+''');
+    _assertAssigned('x++', assigned: true, unassigned: false);
+  }
+
+  test_var_definitelyAssigned_readWrite_prefixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(var x) {
+  ++x;
+}
+''');
+    _assertAssigned('x;', assigned: true, unassigned: false);
+  }
+
+  test_var_definitelyAssigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f(var x) {
+  x = 0;
+}
+''');
+    _assertAssigned('x =', assigned: true, unassigned: false);
   }
 
   test_var_definitelyUnassigned_read() async {
@@ -416,6 +1103,50 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: true);
   }
 
+  test_var_definitelyUnassigned_readWrite_compoundAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  var x;
+  x += 0;
+}
+''');
+    _assertAssigned('x +=', assigned: false, unassigned: true);
+  }
+
+  test_var_definitelyUnassigned_readWrite_postfixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  var x;
+  x++;
+}
+''');
+    _assertAssigned('x++', assigned: false, unassigned: true);
+  }
+
+  test_var_definitelyUnassigned_readWrite_prefixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  var x;
+  ++x; // 0
+}
+''');
+    _assertAssigned('x; // 0', assigned: false, unassigned: true);
+  }
+
+  test_var_definitelyUnassigned_write() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  // ignore:unused_local_variable
+  var x;
+  x = 0;
+}
+''');
+    _assertAssigned('x = 0', assigned: false, unassigned: true);
+  }
+
   test_var_neither_read() async {
     await assertNoErrorsInCode(r'''
 void f(bool b) {
@@ -427,6 +1158,54 @@
     _assertAssigned('x; // 0', assigned: false, unassigned: false);
   }
 
+  test_var_neither_readWrite_compoundAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  var x;
+  if (b) x = 0;
+  x += 1;
+}
+''');
+    _assertAssigned('x += 1', assigned: false, unassigned: false);
+  }
+
+  test_var_neither_readWrite_postfixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  var x;
+  if (b) x = 0;
+  ++x; // 0
+}
+''');
+    _assertAssigned('x; // 0', assigned: false, unassigned: false);
+  }
+
+  test_var_neither_readWrite_prefixIncrement() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  var x;
+  if (b) x = 0;
+  x++;
+}
+''');
+    _assertAssigned('x++', assigned: false, unassigned: false);
+  }
+
+  test_var_neither_write() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  // ignore:unused_local_variable
+  var x;
+  if (b) x = 0;
+  x = 1;
+}
+''');
+    _assertAssigned('x = 1', assigned: false, unassigned: false);
+  }
+
   void _assertAssigned(
     String search, {
     @required bool assigned,
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 6d6be56..1158676 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -1029,7 +1029,7 @@
     TopLevelInferenceError inferenceError;
     if (e is MethodElementImpl) {
       inferenceError = e.typeInferenceError;
-    } else if (e is NonParameterVariableElementImpl) {
+    } else if (e is PropertyInducingElementImpl) {
       inferenceError = e.typeInferenceError;
     }
 
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index ba32abd..0f031ac 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -17,6 +17,7 @@
 import 'src/commands/analyze.dart';
 import 'src/commands/compile.dart';
 import 'src/commands/create.dart';
+import 'src/commands/fix.dart';
 import 'src/commands/pub.dart';
 import 'src/commands/run.dart';
 import 'src/commands/test.dart';
@@ -205,8 +206,7 @@
     addCommand(AnalyzeCommand());
     addCommand(CreateCommand(verbose: verbose));
     addCommand(CompileCommand());
-// Enable experimental `fix` command
-//    addCommand(FixCommand());
+    addCommand(FixCommand());
     addCommand(FormatCommand());
     addCommand(MigrateCommand(verbose: verbose));
     addCommand(PubCommand());
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 90ee11a..e9d92c8 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## Unreleased
+- Added `isSystemIsolate` property to `IsolateRef` and `Isolate`.
+- Added `isSystemIsolateGroup` property to `IsolateGroupRef` and `IsolateGroup`.
+- Added `serviceIsolates` and `serviceIsolateGroups` properties to `VM`.
+
 ## 4.2.0
 - Update to version `3.37.0` of the spec.
 - Added `getProcessMemoryUsage` RPC and `ProcessMemoryUsage` and `ProcessMemoryItem` objects.
diff --git a/pkg/vm_service/example/vm_service_assert.dart b/pkg/vm_service/example/vm_service_assert.dart
index 8e64c27..4dc33b5 100644
--- a/pkg/vm_service/example/vm_service_assert.dart
+++ b/pkg/vm_service/example/vm_service_assert.dart
@@ -656,6 +656,7 @@
   assertString(obj.id);
   assertString(obj.number);
   assertString(obj.name);
+  assertBool(obj.isSystemIsolate);
   return obj;
 }
 
@@ -672,6 +673,7 @@
   assertString(obj.id);
   assertString(obj.number);
   assertString(obj.name);
+  assertBool(obj.isSystemIsolate);
   assertInt(obj.startTime);
   assertBool(obj.runnable);
   assertInt(obj.livePorts);
@@ -689,6 +691,7 @@
   assertString(obj.id);
   assertString(obj.number);
   assertString(obj.name);
+  assertBool(obj.isSystemIsolateGroup);
   return obj;
 }
 
@@ -706,6 +709,7 @@
   assertString(obj.id);
   assertString(obj.number);
   assertString(obj.name);
+  assertBool(obj.isSystemIsolateGroup);
   assertListOfIsolateRef(obj.isolates);
   return obj;
 }
@@ -1193,6 +1197,8 @@
   assertInt(obj.startTime);
   assertListOfIsolateRef(obj.isolates);
   assertListOfIsolateGroupRef(obj.isolateGroups);
+  assertListOfIsolateRef(obj.systemIsolates);
+  assertListOfIsolateGroupRef(obj.systemIsolateGroups);
   return obj;
 }
 
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index 8e5109e..0fa4741 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.37
+version=3.38
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 9fd8aba..8cc7123 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -28,7 +28,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.37.0';
+const String vmServiceVersion = '3.38.0';
 
 /// @optional
 const String optional = 'optional';
@@ -4804,16 +4804,22 @@
   /// A name identifying this isolate. Not guaranteed to be unique.
   String name;
 
+  /// Specifies whether the isolate was spawned by the VM or embedder for
+  /// internal use. If `false`, this isolate is likely running user code.
+  bool isSystemIsolate;
+
   IsolateRef({
     @required this.id,
     @required this.number,
     @required this.name,
+    @required this.isSystemIsolate,
   });
 
   IsolateRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     id = json['id'];
     number = json['number'];
     name = json['name'];
+    isSystemIsolate = json['isSystemIsolate'];
   }
 
   @override
@@ -4824,6 +4830,7 @@
       'id': id,
       'number': number,
       'name': name,
+      'isSystemIsolate': isSystemIsolate,
     });
     return json;
   }
@@ -4832,8 +4839,9 @@
 
   operator ==(other) => other is IsolateRef && id == other.id;
 
-  String toString() =>
-      '[IsolateRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
+  String toString() => '[IsolateRef ' //
+      'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
+      'isSystemIsolate: ${isSystemIsolate}]';
 }
 
 /// An `Isolate` object provides information about one isolate in the VM.
@@ -4850,6 +4858,10 @@
   /// A name identifying this isolate. Not guaranteed to be unique.
   String name;
 
+  /// Specifies whether the isolate was spawned by the VM or embedder for
+  /// internal use. If `false`, this isolate is likely running user code.
+  bool isSystemIsolate;
+
   /// The time that the VM started in milliseconds since the epoch.
   ///
   /// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
@@ -4898,6 +4910,7 @@
     @required this.id,
     @required this.number,
     @required this.name,
+    @required this.isSystemIsolate,
     @required this.startTime,
     @required this.runnable,
     @required this.livePorts,
@@ -4915,6 +4928,7 @@
     id = json['id'];
     number = json['number'];
     name = json['name'];
+    isSystemIsolate = json['isSystemIsolate'];
     startTime = json['startTime'];
     runnable = json['runnable'];
     livePorts = json['livePorts'];
@@ -4940,6 +4954,7 @@
       'id': id,
       'number': number,
       'name': name,
+      'isSystemIsolate': isSystemIsolate,
       'startTime': startTime,
       'runnable': runnable,
       'livePorts': livePorts,
@@ -4978,16 +4993,22 @@
   /// A name identifying this isolate group. Not guaranteed to be unique.
   String name;
 
+  /// Specifies whether the isolate group was spawned by the VM or embedder for
+  /// internal use. If `false`, this isolate group is likely running user code.
+  bool isSystemIsolateGroup;
+
   IsolateGroupRef({
     @required this.id,
     @required this.number,
     @required this.name,
+    @required this.isSystemIsolateGroup,
   });
 
   IsolateGroupRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     id = json['id'];
     number = json['number'];
     name = json['name'];
+    isSystemIsolateGroup = json['isSystemIsolateGroup'];
   }
 
   @override
@@ -4998,6 +5019,7 @@
       'id': id,
       'number': number,
       'name': name,
+      'isSystemIsolateGroup': isSystemIsolateGroup,
     });
     return json;
   }
@@ -5006,8 +5028,9 @@
 
   operator ==(other) => other is IsolateGroupRef && id == other.id;
 
-  String toString() =>
-      '[IsolateGroupRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
+  String toString() => '[IsolateGroupRef ' //
+      'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
+      'isSystemIsolateGroup: ${isSystemIsolateGroup}]';
 }
 
 /// An `Isolate` object provides information about one isolate in the VM.
@@ -5024,6 +5047,10 @@
   /// A name identifying this isolate. Not guaranteed to be unique.
   String name;
 
+  /// Specifies whether the isolate group was spawned by the VM or embedder for
+  /// internal use. If `false`, this isolate group is likely running user code.
+  bool isSystemIsolateGroup;
+
   /// A list of all isolates in this isolate group.
   List<IsolateRef> isolates;
 
@@ -5031,6 +5058,7 @@
     @required this.id,
     @required this.number,
     @required this.name,
+    @required this.isSystemIsolateGroup,
     @required this.isolates,
   });
 
@@ -5038,6 +5066,7 @@
     id = json['id'];
     number = json['number'];
     name = json['name'];
+    isSystemIsolateGroup = json['isSystemIsolateGroup'];
     isolates = List<IsolateRef>.from(
         createServiceObject(json['isolates'], const ['IsolateRef']) ?? []);
   }
@@ -5050,6 +5079,7 @@
       'id': id,
       'number': number,
       'name': name,
+      'isSystemIsolateGroup': isSystemIsolateGroup,
       'isolates': isolates.map((f) => f.toJson()).toList(),
     });
     return json;
@@ -5061,7 +5091,7 @@
 
   String toString() => '[IsolateGroup ' //
       'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
-      'isolates: ${isolates}]';
+      'isSystemIsolateGroup: ${isSystemIsolateGroup}, isolates: ${isolates}]';
 }
 
 /// See [getInboundReferences].
@@ -7063,6 +7093,12 @@
   /// A list of isolate groups running in the VM.
   List<IsolateGroupRef> isolateGroups;
 
+  /// A list of system isolates running in the VM.
+  List<IsolateRef> systemIsolates;
+
+  /// A list of isolate groups which contain system isolates running in the VM.
+  List<IsolateGroupRef> systemIsolateGroups;
+
   VM({
     @required this.name,
     @required this.architectureBits,
@@ -7074,6 +7110,8 @@
     @required this.startTime,
     @required this.isolates,
     @required this.isolateGroups,
+    @required this.systemIsolates,
+    @required this.systemIsolateGroups,
   });
 
   VM._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
@@ -7090,6 +7128,12 @@
     isolateGroups = List<IsolateGroupRef>.from(
         createServiceObject(json['isolateGroups'], const ['IsolateGroupRef']) ??
             []);
+    systemIsolates = List<IsolateRef>.from(
+        createServiceObject(json['systemIsolates'], const ['IsolateRef']) ??
+            []);
+    systemIsolateGroups = List<IsolateGroupRef>.from(createServiceObject(
+            json['systemIsolateGroups'], const ['IsolateGroupRef']) ??
+        []);
   }
 
   @override
@@ -7107,6 +7151,9 @@
       'startTime': startTime,
       'isolates': isolates.map((f) => f.toJson()).toList(),
       'isolateGroups': isolateGroups.map((f) => f.toJson()).toList(),
+      'systemIsolates': systemIsolates.map((f) => f.toJson()).toList(),
+      'systemIsolateGroups':
+          systemIsolateGroups.map((f) => f.toJson()).toList(),
     });
     return json;
   }
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
index b85f8c3..c5a8908 100644
--- a/runtime/bin/dartdev_isolate.cc
+++ b/runtime/bin/dartdev_isolate.cc
@@ -176,6 +176,7 @@
   flags.null_safety = false;
   flags.use_field_guards = true;
   flags.use_osr = true;
+  flags.is_system_isolate = true;
 
   char* error;
   Dart_Isolate dartdev_isolate = runner->create_isolate_(
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index d12d6c7..821ae12 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -621,6 +621,7 @@
   bool load_vmservice_library;
   bool copy_parent_code;
   bool null_safety;
+  bool is_system_isolate;
 } Dart_IsolateFlags;
 
 /**
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 95e16c4..eae5565 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -29,47 +29,10 @@
       : IsolateVisitor(),
         register_function_(Function::Handle(thread->zone())),
         service_isolate_(thread->isolate()) {
-    ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
-    // Get library.
-    const String& library_url = Symbols::DartVMService();
-    ASSERT(!library_url.IsNull());
-    const Library& library =
-        Library::Handle(Library::LookupLibrary(thread, library_url));
-    ASSERT(!library.IsNull());
-    // Get function.
-    const String& function_name =
-        String::Handle(String::New("_registerIsolate"));
-    ASSERT(!function_name.IsNull());
-    register_function_ = library.LookupFunctionAllowPrivate(function_name);
-    ASSERT(!register_function_.IsNull());
   }
 
   virtual void VisitIsolate(Isolate* isolate) {
-    ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
-    if (!FLAG_show_invisible_isolates && IsVMInternalIsolate(isolate)) {
-      // We do not register the service (and descendants), the vm-isolate, or
-      // the kernel isolate.
-      return;
-    }
-    // Setup arguments for call.
-    Dart_Port port_id = isolate->main_port();
-    const Integer& port_int = Integer::Handle(Integer::New(port_id));
-    ASSERT(!port_int.IsNull());
-    const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
-    const String& name = String::Handle(String::New(isolate->name()));
-    ASSERT(!name.IsNull());
-    const Array& args = Array::Handle(Array::New(3));
-    ASSERT(!args.IsNull());
-    args.SetAt(0, port_int);
-    args.SetAt(1, send_port);
-    args.SetAt(2, name);
-    const Object& r =
-        Object::Handle(DartEntry::InvokeFunction(register_function_, args));
-    if (FLAG_trace_service) {
-      OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
-                   name.ToCString(), port_id);
-    }
-    ASSERT(!r.IsError());
+    ServiceIsolate::RegisterRunningIsolate(isolate);
   }
 
  private:
diff --git a/runtime/observatory/lib/src/elements/isolate_ref.dart b/runtime/observatory/lib/src/elements/isolate_ref.dart
index 960661b..344f4b6 100644
--- a/runtime/observatory/lib/src/elements/isolate_ref.dart
+++ b/runtime/observatory/lib/src/elements/isolate_ref.dart
@@ -56,9 +56,10 @@
   }
 
   void render() {
+    final isolateType = isolate.isSystemIsolate ? 'System Isolate' : 'Isolate';
     children = <Element>[
       new AnchorElement(href: Uris.inspect(isolate))
-        ..text = 'Isolate ${isolate.number} (${isolate.name})'
+        ..text = '$isolateType ${isolate.number} (${isolate.name})'
         ..classes = ['isolate-ref']
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/vm_view.dart b/runtime/observatory/lib/src/elements/vm_view.dart
index d183dc3..fed475a 100644
--- a/runtime/observatory/lib/src/elements/vm_view.dart
+++ b/runtime/observatory/lib/src/elements/vm_view.dart
@@ -94,6 +94,9 @@
     for (var group in _vm.isolateGroups) {
       await _isolateGroups.get(group);
     }
+    for (var group in _vm.systemIsolateGroups) {
+      await _isolateGroups.get(group);
+    }
     _r.dirty();
   }
 
@@ -115,6 +118,7 @@
       describeProcess(),
       describeVM(),
       describeIsolateGroups(),
+      describeSystemIsolateGroups(),
       new ViewFooterElement(queue: _r.queue).element
     ];
   }
@@ -325,14 +329,22 @@
       ..children = isolateGroups.map(describeIsolateGroup).toList();
   }
 
+  Element describeSystemIsolateGroups() {
+    final isolateGroups = _vm.systemIsolateGroups.toList();
+    return new DivElement()
+      ..children = isolateGroups.map(describeIsolateGroup).toList();
+  }
+
   Element describeIsolateGroup(M.IsolateGroupRef group) {
+    final isolateType =
+        group.isSystemIsolateGroup ? 'System Isolate' : 'Isolate';
     final isolates = (group as M.IsolateGroup).isolates;
     return new DivElement()
       ..classes = ['content-centered-big']
       ..children = <Element>[
         new HRElement(),
         new HeadingElement.h1()
-          ..text = "Isolate Group ${group.number} (${group.name})",
+          ..text = "$isolateType Group ${group.number} (${group.name})",
         new LIElement()
           ..classes = ['list-group-item']
           ..children = <Element>[
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
index 039e0bd..a3c063a 100644
--- a/runtime/observatory/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate.dart
@@ -15,6 +15,9 @@
   /// A name identifying this isolate. Not guaranteed to be unique.
   String get name;
 
+  /// True if the isolate is a system isolate which is not running user code.
+  bool get isSystemIsolate;
+
   /// Trigger a full GC, collecting all unreachable or weakly reachable objects.
   Future collectAllGarbage();
 }
diff --git a/runtime/observatory/lib/src/models/objects/isolate_group.dart b/runtime/observatory/lib/src/models/objects/isolate_group.dart
index b18bbf7..7b7a83c 100644
--- a/runtime/observatory/lib/src/models/objects/isolate_group.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate_group.dart
@@ -14,6 +14,8 @@
 
   /// A name identifying this isolate group. Not guaranteed to be unique.
   String get name;
+
+  bool get isSystemIsolateGroup;
 }
 
 abstract class IsolateGroup extends IsolateGroupRef {
diff --git a/runtime/observatory/lib/src/models/objects/vm.dart b/runtime/observatory/lib/src/models/objects/vm.dart
index ae8210c..b69d744 100644
--- a/runtime/observatory/lib/src/models/objects/vm.dart
+++ b/runtime/observatory/lib/src/models/objects/vm.dart
@@ -51,7 +51,9 @@
 
   // A list of isolates running in the VM.
   Iterable<IsolateRef> get isolates;
+  Iterable<IsolateRef> get systemIsolates;
   Iterable<IsolateGroupRef> get isolateGroups;
+  Iterable<IsolateGroupRef> get systemIsolateGroups;
 
   /// Enable the sampling profiler.
   Future enableProfiler();
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 9c9c76b..046513d 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -668,8 +668,10 @@
 
   // The list of live isolates, ordered by isolate start time.
   final List<Isolate> isolates = <Isolate>[];
+  final List<Isolate> systemIsolates = <Isolate>[];
 
   final List<IsolateGroup> isolateGroups = <IsolateGroup>[];
+  final List<IsolateGroup> systemIsolateGroups = <IsolateGroup>[];
 
   final List<Service> services = <Service>[];
 
@@ -755,10 +757,17 @@
   }
 
   void _buildIsolateList() {
-    var isolateList = _isolateCache.values.toList();
+    var isolateList =
+        _isolateCache.values.where((i) => !i.isSystemIsolate).toList();
     isolateList.sort(_compareIsolates);
     isolates.clear();
     isolates.addAll(isolateList);
+
+    var systemIsolateList =
+        _isolateCache.values.where((i) => i.isSystemIsolate).toList();
+    systemIsolateList.sort(_compareIsolates);
+    systemIsolates.clear();
+    systemIsolates.addAll(systemIsolateList);
   }
 
   void _removeDeadIsolates(List newIsolates) {
@@ -851,10 +860,18 @@
   }
 
   void _buildIsolateGroupList() {
-    final isolateGroupList = _isolateGroupCache.values.toList();
+    final isolateGroupList = _isolateGroupCache.values
+        .where((g) => !g.isSystemIsolateGroup)
+        .toList();
     isolateGroupList.sort(_compareIsolateGroups);
     isolateGroups.clear();
     isolateGroups.addAll(isolateGroupList);
+
+    final systemIsolateGroupList =
+        _isolateGroupCache.values.where((g) => g.isSystemIsolateGroup).toList();
+    systemIsolateGroupList.sort(_compareIsolateGroups);
+    systemIsolateGroups.clear();
+    systemIsolateGroups.addAll(systemIsolateGroupList);
   }
 
   void _removeDeadIsolateGroups(List newIsolateGroups) {
@@ -1039,8 +1056,14 @@
     profileVM = map['_profilerMode'] == 'VM';
     assertsEnabled = map['_assertsEnabled'];
     typeChecksEnabled = map['_typeChecksEnabled'];
-    _removeDeadIsolates(map['isolates']);
-    _removeDeadIsolateGroups(map['isolateGroups']);
+    _removeDeadIsolates([
+      ...map['isolates'],
+      ...map['systemIsolates'],
+    ]);
+    _removeDeadIsolateGroups([
+      ...map['isolateGroups'],
+      ...map['systemIsolateGroups'],
+    ]);
   }
 
   // Reload all isolates.
@@ -1297,6 +1320,7 @@
     name = map['name'];
     vmName = map.containsKey('_vmName') ? map['_vmName'] : name;
     number = int.tryParse(map['number']);
+    isSystemIsolateGroup = map['isSystemIsolateGroup'];
     if (mapIsRef) {
       return;
     }
@@ -1357,6 +1381,8 @@
   @override
   int number;
 
+  bool isSystemIsolateGroup;
+
   final Map<String, ServiceObject> _cache = Map<String, ServiceObject>();
 }
 
@@ -1614,6 +1640,8 @@
   int get numScopedHandles => _numScopedHandles;
   int _numScopedHandles;
 
+  bool isSystemIsolate;
+
   void _loadHeapSnapshot(ServiceEvent event) {
     if (_snapshotFetch == null) {
       // No outstanding snapshot request. Presumably another client asked for a
@@ -1648,6 +1676,7 @@
     name = map['name'];
     vmName = map.containsKey('_vmName') ? map['_vmName'] : name;
     number = int.tryParse(map['number']);
+    isSystemIsolate = map['isSystemIsolate'];
     if (mapIsRef) {
       return;
     }
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index 8c4c378..efd6952 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -1,3 +1,11 @@
 name: observatory
 environment:
-  sdk: '>=2.2.2 <3.0.0'
\ No newline at end of file
+  sdk: '>=2.2.2 <3.0.0'
+
+dependencies:
+  usage: 'any'
+
+dev_dependencies:
+  build_runner: '>=1.6.2 <2.0.0'
+  build_web_compilers: '>=2.6.1 <3.0.0'
+
diff --git a/runtime/observatory/tests/service/get_isolate_rpc_test.dart b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
index 293b0d3..adffeb7 100644
--- a/runtime/observatory/tests/service/get_isolate_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
@@ -16,6 +16,7 @@
     expect(result['type'], equals('Isolate'));
     expect(result['id'], startsWith('isolates/'));
     expect(result['number'], isA<String>());
+    expect(result['isSystemIsolate'], isFalse);
     expect(result['_originNumber'], equals(result['number']));
     expect(result['startTime'], isPositive);
     expect(result['livePorts'], isPositive);
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index ff51911..37c147a 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(37));
+    expect(result['minor'], equals(38));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart b/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart
index ebe21f5..47ae51c 100644
--- a/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart
@@ -66,6 +66,7 @@
     Expect.equals(result['type'], 'IsolateGroup');
     Expect.isTrue(result['id'].startsWith('isolateGroups/'));
     Expect.type<String>(result['number']);
+    Expect.isFalse(result['isSystemIsolateGroup']);
     Expect.isTrue(result['isolates'].length > 0);
     Expect.equals(result['isolates'][0]['type'], '@Isolate');
   } catch (e) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 9bb5958..f33a41c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -262,7 +262,7 @@
   if ((FLAG_stacktrace_every > 0) || (FLAG_deoptimize_every > 0) ||
       (FLAG_gc_every > 0) ||
       (isolate()->reload_every_n_stack_overflow_checks() > 0)) {
-    if (!Isolate::IsVMInternalIsolate(isolate())) {
+    if (!Isolate::IsSystemIsolate(isolate())) {
       return true;
     }
   }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 0ffe978..60a36ec 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -259,13 +259,14 @@
     // Setup default flags for the VM isolate.
     Dart_IsolateFlags api_flags;
     Isolate::FlagsInitialize(&api_flags);
+    api_flags.is_system_isolate = true;
 
     // We make a fake [IsolateGroupSource] here, since the "vm-isolate" is not
     // really an isolate itself - it acts more as a container for VM-global
     // objects.
-    std::unique_ptr<IsolateGroupSource> source(
-        new IsolateGroupSource(nullptr, kVmIsolateName, vm_isolate_snapshot,
-                               instructions_snapshot, nullptr, -1, api_flags));
+    std::unique_ptr<IsolateGroupSource> source(new IsolateGroupSource(
+        kVmIsolateName, kVmIsolateName, vm_isolate_snapshot,
+        instructions_snapshot, nullptr, -1, api_flags));
     // ObjectStore should be created later, after null objects are initialized.
     auto group = new IsolateGroup(std::move(source), /*embedder_data=*/nullptr,
                                   /*object_store=*/nullptr);
@@ -432,7 +433,7 @@
                               bool only_aplication_isolates) {
   IsolateGroup::ForEach([&](IsolateGroup* group) {
     group->ForEachIsolate([&](Isolate* isolate) {
-      if (!only_aplication_isolates || !Isolate::IsVMInternalIsolate(isolate)) {
+      if (!only_aplication_isolates || !Isolate::IsSystemIsolate(isolate)) {
         OS::PrintErr("Attempt:%" Pd " waiting for isolate %s to check in\n",
                      num_attempts, isolate->name());
       }
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3669dc2..7f385cb 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -317,12 +317,12 @@
 }
 
 bool Debugger::NeedsIsolateEvents() {
-  return !Isolate::IsVMInternalIsolate(isolate_) &&
+  return !Isolate::IsSystemIsolate(isolate_) &&
          Service::isolate_stream.enabled();
 }
 
 bool Debugger::NeedsDebugEvents() {
-  ASSERT(!Isolate::IsVMInternalIsolate(isolate_));
+  ASSERT(!Isolate::IsSystemIsolate(isolate_));
   return FLAG_warn_on_pause_with_no_debugger || Service::debug_stream.enabled();
 }
 
@@ -1856,7 +1856,7 @@
 void Debugger::Shutdown() {
   // TODO(johnmccutchan): Do not create a debugger for isolates that don't need
   // them. Then, assert here that isolate_ is not one of those isolates.
-  if (Isolate::IsVMInternalIsolate(isolate_)) {
+  if (Isolate::IsSystemIsolate(isolate_)) {
     return;
   }
   while (breakpoint_locations_ != NULL) {
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index fb19f98..a4bf348 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -197,8 +197,6 @@
   P(enable_isolate_groups, bool, false, "Enable isolate group support.")       \
   P(show_invisible_frames, bool, false,                                        \
     "Show invisible frames in stack traces.")                                  \
-  R(show_invisible_isolates, false, bool, false,                               \
-    "Show invisible isolates in the vm-service.")                              \
   R(support_il_printer, false, bool, true, "Support the IL printer.")          \
   D(trace_cha, bool, false, "Trace CHA operations")                            \
   R(trace_field_guards, false, bool, false, "Trace changes in field's cids.")  \
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 170f52c..25a24ce 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -1009,7 +1009,7 @@
   // For now we'll emit the same GC events on all isolates.
   if (Service::gc_stream.enabled()) {
     isolate_group_->ForEachIsolate([&](Isolate* isolate) {
-      if (!Isolate::IsVMInternalIsolate(isolate)) {
+      if (!Isolate::IsSystemIsolate(isolate)) {
         ServiceEvent event(isolate, ServiceEvent::kGC);
         event.set_gc_stats(&stats_);
         Service::HandleEvent(&event);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5f37ada..281a6b8 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -345,6 +345,7 @@
       isolates_lock_(new SafepointRwLock()),
       isolates_(),
       start_time_micros_(OS::GetCurrentMonotonicMicros()),
+      is_system_isolate_group_(source->flags.is_system_isolate),
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
       last_reload_timestamp_(OS::GetCurrentTimeMillis()),
 #endif
@@ -730,6 +731,7 @@
 
   jsobj->AddProperty("name", source()->script_uri);
   jsobj->AddPropertyF("number", "%" Pu64 "", id());
+  jsobj->AddProperty("isSystemIsolateGroup", is_system_isolate_group());
   if (ref) {
     return;
   }
@@ -801,7 +803,7 @@
 bool IsolateGroup::HasApplicationIsolateGroups() {
   ReadRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
   for (auto group : *isolate_groups_) {
-    if (!IsolateGroup::IsVMInternalIsolateGroup(group)) {
+    if (!IsolateGroup::IsSystemIsolateGroup(group)) {
       return true;
     }
   }
@@ -836,8 +838,8 @@
   isolate_groups_ = nullptr;
 }
 
-bool IsolateVisitor::IsVMInternalIsolate(Isolate* isolate) const {
-  return Isolate::IsVMInternalIsolate(isolate);
+bool IsolateVisitor::IsSystemIsolate(Isolate* isolate) const {
+  return Isolate::IsSystemIsolate(isolate);
 }
 
 NoOOBMessageScope::NoOOBMessageScope(Thread* thread)
@@ -1356,7 +1358,7 @@
     }
   } else {
 #ifndef PRODUCT
-    if (!Isolate::IsVMInternalIsolate(I)) {
+    if (!Isolate::IsSystemIsolate(I)) {
       // Mark all the user isolates as using a simplified timeline page of
       // Observatory. The internal isolates will be filtered out from
       // the Timeline due to absence of this argument. We still send them in
@@ -1379,7 +1381,7 @@
 
 #ifndef PRODUCT
 void IsolateMessageHandler::NotifyPauseOnStart() {
-  if (Isolate::IsVMInternalIsolate(I)) {
+  if (Isolate::IsSystemIsolate(I)) {
     return;
   }
   if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
@@ -1395,7 +1397,7 @@
 }
 
 void IsolateMessageHandler::NotifyPauseOnExit() {
-  if (Isolate::IsVMInternalIsolate(I)) {
+  if (Isolate::IsSystemIsolate(I)) {
     return;
   }
   if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
@@ -1514,6 +1516,7 @@
   api_flags->load_vmservice_library = false;
   api_flags->copy_parent_code = false;
   api_flags->null_safety = false;
+  api_flags->is_system_isolate = false;
 }
 
 void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const {
@@ -1526,6 +1529,7 @@
   api_flags->load_vmservice_library = should_load_vmservice();
   api_flags->copy_parent_code = false;
   api_flags->null_safety = null_safety();
+  api_flags->is_system_isolate = is_system_isolate();
 }
 
 void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) {
@@ -1556,7 +1560,7 @@
 
   set_should_load_vmservice(api_flags.load_vmservice_library);
   set_null_safety(api_flags.null_safety);
-
+  set_is_system_isolate(api_flags.is_system_isolate);
   // Copy entry points list.
   ASSERT(embedder_entry_points_ == NULL);
   if (api_flags.entry_points != NULL) {
@@ -1960,7 +1964,7 @@
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 bool Isolate::CanReload() const {
-  return !Isolate::IsVMInternalIsolate(this) && is_runnable() &&
+  return !Isolate::IsSystemIsolate(this) && is_runnable() &&
          !group()->IsReloading() && (no_reload_scope_depth_ == 0) &&
          IsolateCreationEnabled() &&
          OSThread::Current()->HasStackHeadroom(64 * KB);
@@ -2059,7 +2063,7 @@
   ASSERT(object_store()->root_library() != Library::null());
   set_is_runnable(true);
 #ifndef PRODUCT
-  if (!Isolate::IsVMInternalIsolate(this)) {
+  if (!Isolate::IsSystemIsolate(this)) {
     debugger()->OnIsolateRunnable();
     if (FLAG_pause_isolates_on_unhandled_exceptions) {
       debugger()->SetExceptionPauseInfo(kPauseOnUnhandledExceptions);
@@ -2081,8 +2085,7 @@
   }
 #endif
 #ifndef PRODUCT
-  if (!Isolate::IsVMInternalIsolate(this) &&
-      Service::isolate_stream.enabled()) {
+  if (!Isolate::IsSystemIsolate(this) && Service::isolate_stream.enabled()) {
     ServiceEvent runnableEvent(this, ServiceEvent::kIsolateRunnable);
     Service::HandleEvent(&runnableEvent);
   }
@@ -2604,8 +2607,7 @@
   }
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-  if (FLAG_check_reloaded && is_runnable() &&
-      !Isolate::IsVMInternalIsolate(this)) {
+  if (FLAG_check_reloaded && is_runnable() && !Isolate::IsSystemIsolate(this)) {
     if (!HasAttemptedReload()) {
       FATAL(
           "Isolate did not reload before exiting and "
@@ -3068,6 +3070,7 @@
 
   jsobj.AddProperty("name", name());
   jsobj.AddPropertyF("number", "%" Pd64 "", static_cast<int64_t>(main_port()));
+  jsobj.AddProperty("isSystemIsolate", is_system_isolate());
   if (ref) {
     return;
   }
@@ -3435,7 +3438,7 @@
 // done atomically.
 void Isolate::RegisterServiceExtensionHandler(const String& name,
                                               const Instance& closure) {
-  if (Isolate::IsVMInternalIsolate(this)) {
+  if (Isolate::IsSystemIsolate(this)) {
     return;
   }
   GrowableObjectArray& handlers =
@@ -3631,15 +3634,8 @@
   return creation_enabled_;
 }
 
-bool IsolateGroup::IsVMInternalIsolateGroup(const IsolateGroup* group) {
-  // We use a name comparison here because this method can be called during
-  // shutdown, where the actual isolate pointers might've already been cleared.
-  const char* name = group->source()->name;
-  return Dart::VmIsolateNameEquals(name) ||
-#if !defined(DART_PRECOMPILED_RUNTIME)
-         KernelIsolate::NameEquals(name) ||
-#endif
-         ServiceIsolate::NameEquals(name);
+bool IsolateGroup::IsSystemIsolateGroup(const IsolateGroup* group) {
+  return group->source()->flags.is_system_isolate;
 }
 
 void Isolate::KillLocked(LibMsgId msg_id) {
@@ -3708,7 +3704,7 @@
     // If a target_ is specified, then only kill the target_.
     // Otherwise, don't kill the service isolate or vm isolate.
     return (((target_ != nullptr) && (isolate == target_)) ||
-            ((target_ == nullptr) && !IsVMInternalIsolate(isolate)));
+            ((target_ == nullptr) && !IsSystemIsolate(isolate)));
   }
 
   Isolate* target_;
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 0e175bd1..f59147d 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -121,7 +121,7 @@
 
  protected:
   // Returns true if |isolate| is the VM or service isolate.
-  bool IsVMInternalIsolate(Isolate* isolate) const;
+  bool IsSystemIsolate(Isolate* isolate) const;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(IsolateVisitor);
@@ -396,6 +396,9 @@
   SharedClassTable* shared_class_table() const {
     return shared_class_table_.get();
   }
+
+  bool is_system_isolate_group() const { return is_system_isolate_group_; }
+
   StoreBuffer* store_buffer() const { return store_buffer_.get(); }
   ClassTable* class_table() const { return class_table_.get(); }
   ObjectStore* object_store() const { return object_store_.get(); }
@@ -562,7 +565,7 @@
 
   static bool HasApplicationIsolateGroups();
   static bool HasOnlyVMIsolateGroup();
-  static bool IsVMInternalIsolateGroup(const IsolateGroup* group);
+  static bool IsSystemIsolateGroup(const IsolateGroup* group);
 
   int64_t UptimeMicros() const;
 
@@ -647,6 +650,7 @@
   Dart_LibraryTagHandler library_tag_handler_ = nullptr;
   Dart_DeferredLoadHandler deferred_load_handler_ = nullptr;
   int64_t start_time_micros_;
+  bool is_system_isolate_group_;
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   int64_t last_reload_timestamp_;
@@ -934,9 +938,7 @@
   Mutex* kernel_constants_mutex() { return &kernel_constants_mutex_; }
 
 #if !defined(PRODUCT)
-  Debugger* debugger() const {
-    return debugger_;
-  }
+  Debugger* debugger() const { return debugger_; }
 
   void set_single_step(bool value) { single_step_ = value; }
   bool single_step() const { return single_step_; }
@@ -1321,8 +1323,8 @@
   static void DisableIsolateCreation();
   static void EnableIsolateCreation();
   static bool IsolateCreationEnabled();
-  static bool IsVMInternalIsolate(const Isolate* isolate) {
-    return IsolateGroup::IsVMInternalIsolateGroup(isolate->group());
+  static bool IsSystemIsolate(const Isolate* isolate) {
+    return IsolateGroup::IsSystemIsolateGroup(isolate->group());
   }
 
 #if !defined(PRODUCT)
@@ -1399,6 +1401,11 @@
 
   void set_user_tag(uword tag) { user_tag_ = tag; }
 
+  void set_is_system_isolate(bool is_system_isolate) {
+    is_system_isolate_ = is_system_isolate;
+  }
+  bool is_system_isolate() const { return is_system_isolate_; }
+
 #if !defined(PRODUCT)
   GrowableObjectArrayPtr GetAndClearPendingServiceExtensionCalls();
   GrowableObjectArrayPtr pending_service_extension_calls() const {
@@ -1441,6 +1448,7 @@
   ClassPtr* cached_class_table_table_ = nullptr;
   FieldTable* field_table_ = nullptr;
   bool single_step_ = false;
+  bool is_system_isolate_ = false;
   // End accessed from generated code.
 
   IsolateGroup* isolate_group_;
@@ -1544,7 +1552,7 @@
   Dart_EnvironmentCallback environment_callback_ = nullptr;
   Random random_;
   Simulator* simulator_ = nullptr;
-  Mutex mutex_;          // Protects compiler stats.
+  Mutex mutex_;                            // Protects compiler stats.
   Mutex constant_canonicalization_mutex_;  // Protects const canonicalization.
   Mutex megamorphic_mutex_;  // Protects the table of megamorphic caches and
                              // their entries.
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 786c2ed..10b3e76 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -484,7 +484,7 @@
   // TODO(dartbug.com/36097): We need to change the "reloadSources" service-api
   // call to accept an isolate group instead of an isolate.
   Isolate* isolate = Isolate::Current();
-  if (Isolate::IsVMInternalIsolate(isolate)) {
+  if (Isolate::IsSystemIsolate(isolate)) {
     return;
   }
   TIR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
@@ -497,7 +497,7 @@
   // TODO(dartbug.com/36097): We need to change the "reloadSources" service-api
   // call to accept an isolate group instead of an isolate.
   Isolate* isolate = Isolate::Current();
-  if (Isolate::IsVMInternalIsolate(isolate)) {
+  if (Isolate::IsSystemIsolate(isolate)) {
     return;
   }
   ServiceEvent service_event(isolate, ServiceEvent::kIsolateReload);
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 968c212..8fdc9d0 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -92,6 +92,7 @@
     Dart_IsolateFlags api_flags;
     Isolate::FlagsInitialize(&api_flags);
     api_flags.enable_asserts = false;
+    api_flags.is_system_isolate = true;
 #if !defined(DART_PRECOMPILER)
     api_flags.use_field_guards = true;
 #endif
diff --git a/runtime/vm/log.cc b/runtime/vm/log.cc
index 9dc6ce0..998ff60 100644
--- a/runtime/vm/log.cc
+++ b/runtime/vm/log.cc
@@ -125,7 +125,7 @@
 
 bool Log::ShouldLogForIsolateGroup(const IsolateGroup* isolate_group) {
   if (FLAG_isolate_log_filter == nullptr) {
-    if (IsolateGroup::IsVMInternalIsolateGroup(isolate_group)) {
+    if (IsolateGroup::IsSystemIsolateGroup(isolate_group)) {
       // By default, do not log for the service or kernel isolates.
       return false;
     }
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index cf921ac..1d18cae 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2461,7 +2461,7 @@
       isolate->reload_every_n_stack_overflow_checks();
   if ((FLAG_deoptimize_every > 0) || (FLAG_stacktrace_every > 0) ||
       (FLAG_gc_every > 0) || (isolate_reload_every > 0)) {
-    if (!Isolate::IsVMInternalIsolate(isolate)) {
+    if (!Isolate::IsSystemIsolate(isolate)) {
       // TODO(turnidge): To make --deoptimize_every and
       // --stacktrace-every faster we could move this increment/test to
       // the generated code.
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index f82c430..e20e9a9 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -986,8 +986,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
-  ASSERT(FLAG_show_invisible_isolates ||
-         !Isolate::IsVMInternalIsolate(isolate));
+  ASSERT(!Isolate::IsSystemIsolate(isolate));
 
   if (FLAG_trace_service) {
     OS::PrintErr(
@@ -1341,10 +1340,10 @@
     return -1;
   }
   Dart_EmbedderInformation info = {
-    0,  // version
-    NULL,  // name
-    0,  // max_rss
-    0  // current_rss
+      0,     // version
+      NULL,  // name
+      0,     // max_rss
+      0      // current_rss
   };
   embedder_information_callback_(&info);
   ASSERT(info.version == DART_EMBEDDER_INFORMATION_CURRENT_VERSION);
@@ -1356,10 +1355,10 @@
     return -1;
   }
   Dart_EmbedderInformation info = {
-    0,  // version
-    NULL,  // name
-    0,  // max_rss
-    0  // current_rss
+      0,     // version
+      NULL,  // name
+      0,     // max_rss
+      0      // current_rss
   };
   embedder_information_callback_(&info);
   ASSERT(info.version == DART_EMBEDDER_INFORMATION_CURRENT_VERSION);
@@ -1401,7 +1400,8 @@
 }
 
 static const MethodParameter* get_isolate_params[] = {
-    ISOLATE_PARAMETER, NULL,
+    ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetIsolate(Thread* thread, JSONStream* js) {
@@ -2158,7 +2158,8 @@
 }
 
 static const MethodParameter* get_inbound_references_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetInboundReferences(Thread* thread, JSONStream* js) {
@@ -2275,7 +2276,8 @@
 }
 
 static const MethodParameter* get_retaining_path_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetRetainingPath(Thread* thread, JSONStream* js) {
@@ -2315,7 +2317,9 @@
 }
 
 static const MethodParameter* get_retained_size_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new IdParameter("targetId", true),
+    NULL,
 };
 
 static bool GetRetainedSize(Thread* thread, JSONStream* js) {
@@ -2353,7 +2357,9 @@
 }
 
 static const MethodParameter* get_reachable_size_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new IdParameter("targetId", true),
+    NULL,
 };
 
 static bool GetReachableSize(Thread* thread, JSONStream* js) {
@@ -2525,7 +2531,8 @@
 }
 
 static const MethodParameter* evaluate_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool IsAlpha(char c) {
@@ -3034,8 +3041,10 @@
 }
 
 static const MethodParameter* evaluate_in_frame_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("frameIndex", true),
-    new MethodParameter("expression", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new UIntParameter("frameIndex", true),
+    new MethodParameter("expression", true),
+    NULL,
 };
 
 static bool EvaluateInFrame(Thread* thread, JSONStream* js) {
@@ -3083,7 +3092,8 @@
 };
 
 static const MethodParameter* get_instances_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetInstances(Thread* thread, JSONStream* js) {
@@ -3379,7 +3389,9 @@
 }
 
 static const MethodParameter* add_breakpoint_at_entry_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new IdParameter("functionId", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new IdParameter("functionId", true),
+    NULL,
 };
 
 static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) {
@@ -3407,7 +3419,9 @@
 }
 
 static const MethodParameter* add_breakpoint_at_activation_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new IdParameter("objectId", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new IdParameter("objectId", true),
+    NULL,
 };
 
 static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) {
@@ -3434,7 +3448,8 @@
 }
 
 static const MethodParameter* remove_breakpoint_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool RemoveBreakpoint(Thread* thread, JSONStream* js) {
@@ -3562,7 +3577,8 @@
 }
 
 static const MethodParameter* get_isolate_metric_list_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetIsolateMetricList(Thread* thread, JSONStream* js) {
@@ -3587,7 +3603,8 @@
 }
 
 static const MethodParameter* get_isolate_metric_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetIsolateMetric(Thread* thread, JSONStream* js) {
@@ -3617,7 +3634,8 @@
 }
 
 static const MethodParameter* get_vm_metric_list_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetVMMetricList(Thread* thread, JSONStream* js) {
@@ -3625,7 +3643,8 @@
 }
 
 static const MethodParameter* get_vm_metric_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetVMMetric(Thread* thread, JSONStream* js) {
@@ -3698,7 +3717,8 @@
 }
 
 static const MethodParameter* get_vm_timeline_flags_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) {
@@ -3716,7 +3736,8 @@
 }
 
 static const MethodParameter* get_vm_timeline_micros_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetVMTimelineMicros(Thread* thread, JSONStream* js) {
@@ -3727,7 +3748,8 @@
 }
 
 static const MethodParameter* clear_vm_timeline_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool ClearVMTimeline(Thread* thread, JSONStream* js) {
@@ -3743,8 +3765,10 @@
 }
 
 static const MethodParameter* get_vm_timeline_params[] = {
-    NO_ISOLATE_PARAMETER, new Int64Parameter("timeOriginMicros", false),
-    new Int64Parameter("timeExtentMicros", false), NULL,
+    NO_ISOLATE_PARAMETER,
+    new Int64Parameter("timeOriginMicros", false),
+    new Int64Parameter("timeExtentMicros", false),
+    NULL,
 };
 
 static bool GetVMTimeline(Thread* thread, JSONStream* js) {
@@ -3790,7 +3814,8 @@
 static const MethodParameter* resume_params[] = {
     RUNNABLE_ISOLATE_PARAMETER,
     new EnumParameter("step", false, step_enum_names),
-    new UIntParameter("frameIndex", false), NULL,
+    new UIntParameter("frameIndex", false),
+    NULL,
 };
 
 static bool Resume(Thread* thread, JSONStream* js) {
@@ -3876,7 +3901,8 @@
 }
 
 static const MethodParameter* pause_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool Pause(Thread* thread, JSONStream* js) {
@@ -3905,7 +3931,8 @@
 }
 
 static const MethodParameter* get_tag_profile_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetTagProfile(Thread* thread, JSONStream* js) {
@@ -4063,7 +4090,8 @@
 }
 
 static const MethodParameter* get_heap_map_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetHeapMap(Thread* thread, JSONStream* js) {
@@ -4125,71 +4153,73 @@
       JSONArray(&profiler, "children");
     }
 
-  {
-    JSONObject timeline(&vm_children);
-    timeline.AddProperty("name", "Timeline");
-    timeline.AddProperty(
-        "description",
-        "Timeline events from dart:developer and Dart_TimelineEvent");
-    intptr_t size = Timeline::recorder()->Size();
-    vm_size += size;
-    timeline.AddProperty64("size", size);
-    JSONArray(&timeline, "children");
-  }
-
-  {
-    JSONObject zone(&vm_children);
-    zone.AddProperty("name", "Zone");
-    zone.AddProperty("description", "Arena allocation in the Dart VM");
-    intptr_t size = Zone::Size();
-    vm_size += size;
-    zone.AddProperty64("size", size);
-    JSONArray(&zone, "children");
-  }
-
-  {
-    JSONObject semi(&vm_children);
-    semi.AddProperty("name", "SemiSpace Cache");
-    semi.AddProperty("description", "Cached heap regions");
-    intptr_t size = SemiSpace::CachedSize();
-    vm_size += size;
-    semi.AddProperty64("size", size);
-    JSONArray(&semi, "children");
-  }
-
-  IsolateGroup::ForEach([&vm_children, &vm_size](IsolateGroup* isolate_group) {
-    // Note: new_space()->CapacityInWords() includes memory that hasn't been
-    // allocated from the OS yet.
-    int64_t capacity = (isolate_group->heap()->new_space()->UsedInWords() +
-                        isolate_group->heap()->old_space()->CapacityInWords()) *
-                       kWordSize;
-    int64_t used = isolate_group->heap()->TotalUsedInWords() * kWordSize;
-    int64_t free = capacity - used;
-
-    JSONObject group(&vm_children);
-    group.AddPropertyF("name", "IsolateGroup %s",
-                       isolate_group->source()->name);
-    group.AddProperty("description", "Dart heap capacity");
-    vm_size += capacity;
-    group.AddProperty64("size", capacity);
-    JSONArray group_children(&group, "children");
-
     {
-      JSONObject jsused(&group_children);
-      jsused.AddProperty("name", "Used");
-      jsused.AddProperty("description", "");
-      jsused.AddProperty64("size", used);
-      JSONArray(&jsused, "children");
+      JSONObject timeline(&vm_children);
+      timeline.AddProperty("name", "Timeline");
+      timeline.AddProperty(
+          "description",
+          "Timeline events from dart:developer and Dart_TimelineEvent");
+      intptr_t size = Timeline::recorder()->Size();
+      vm_size += size;
+      timeline.AddProperty64("size", size);
+      JSONArray(&timeline, "children");
     }
 
     {
-      JSONObject jsfree(&group_children);
-      jsfree.AddProperty("name", "Free");
-      jsfree.AddProperty("description", "");
-      jsfree.AddProperty64("size", free);
-      JSONArray(&jsfree, "children");
+      JSONObject zone(&vm_children);
+      zone.AddProperty("name", "Zone");
+      zone.AddProperty("description", "Arena allocation in the Dart VM");
+      intptr_t size = Zone::Size();
+      vm_size += size;
+      zone.AddProperty64("size", size);
+      JSONArray(&zone, "children");
     }
-  });
+
+    {
+      JSONObject semi(&vm_children);
+      semi.AddProperty("name", "SemiSpace Cache");
+      semi.AddProperty("description", "Cached heap regions");
+      intptr_t size = SemiSpace::CachedSize();
+      vm_size += size;
+      semi.AddProperty64("size", size);
+      JSONArray(&semi, "children");
+    }
+
+    IsolateGroup::ForEach(
+        [&vm_children, &vm_size](IsolateGroup* isolate_group) {
+          // Note: new_space()->CapacityInWords() includes memory that hasn't
+          // been allocated from the OS yet.
+          int64_t capacity =
+              (isolate_group->heap()->new_space()->UsedInWords() +
+               isolate_group->heap()->old_space()->CapacityInWords()) *
+              kWordSize;
+          int64_t used = isolate_group->heap()->TotalUsedInWords() * kWordSize;
+          int64_t free = capacity - used;
+
+          JSONObject group(&vm_children);
+          group.AddPropertyF("name", "IsolateGroup %s",
+                             isolate_group->source()->name);
+          group.AddProperty("description", "Dart heap capacity");
+          vm_size += capacity;
+          group.AddProperty64("size", capacity);
+          JSONArray group_children(&group, "children");
+
+          {
+            JSONObject jsused(&group_children);
+            jsused.AddProperty("name", "Used");
+            jsused.AddProperty("description", "");
+            jsused.AddProperty64("size", used);
+            JSONArray(&jsused, "children");
+          }
+
+          {
+            JSONObject jsfree(&group_children);
+            jsfree.AddProperty("name", "Free");
+            jsfree.AddProperty("description", "");
+            jsfree.AddProperty64("size", free);
+            JSONArray(&jsfree, "children");
+          }
+        });
   }  // vm_children
 
   vm.AddProperty("name", "Dart VM");
@@ -4273,7 +4303,8 @@
 }
 
 static const MethodParameter* get_persistent_handles_params[] = {
-    ISOLATE_PARAMETER, NULL,
+    ISOLATE_PARAMETER,
+    NULL,
 };
 
 template <typename T>
@@ -4361,7 +4392,8 @@
 }
 
 static const MethodParameter* get_ports_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetPorts(Thread* thread, JSONStream* js) {
@@ -4389,8 +4421,10 @@
 }
 
 static const MethodParameter* get_object_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("offset", false),
-    new UIntParameter("count", false), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new UIntParameter("offset", false),
+    new UIntParameter("count", false),
+    NULL,
 };
 
 static bool GetObject(Thread* thread, JSONStream* js) {
@@ -4461,7 +4495,8 @@
 }
 
 static const MethodParameter* get_object_store_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetObjectStore(Thread* thread, JSONStream* js) {
@@ -4482,7 +4517,8 @@
 }
 
 static const MethodParameter* get_class_list_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetClassList(Thread* thread, JSONStream* js) {
@@ -4493,7 +4529,8 @@
 }
 
 static const MethodParameter* get_type_arguments_list_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) {
@@ -4529,7 +4566,8 @@
 }
 
 static const MethodParameter* get_version_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetVersion(Thread* thread, JSONStream* js) {
@@ -4550,7 +4588,23 @@
   virtual ~ServiceIsolateVisitor() {}
 
   void VisitIsolate(Isolate* isolate) {
-    if (FLAG_show_invisible_isolates || !IsVMInternalIsolate(isolate)) {
+    if (!IsSystemIsolate(isolate)) {
+      jsarr_->AddValue(isolate);
+    }
+  }
+
+ private:
+  JSONArray* jsarr_;
+};
+
+class SystemServiceIsolateVisitor : public IsolateVisitor {
+ public:
+  explicit SystemServiceIsolateVisitor(JSONArray* jsarr) : jsarr_(jsarr) {}
+  virtual ~SystemServiceIsolateVisitor() {}
+
+  void VisitIsolate(Isolate* isolate) {
+    if (IsSystemIsolate(isolate) &&
+        !Dart::VmIsolateNameEquals(isolate->name())) {
       jsarr_->AddValue(isolate);
     }
   }
@@ -4560,16 +4614,17 @@
 };
 
 static const MethodParameter* get_vm_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
-void Service::PrintJSONForEmbedderInformation(JSONObject *jsobj) {
+void Service::PrintJSONForEmbedderInformation(JSONObject* jsobj) {
   if (embedder_information_callback_ != NULL) {
     Dart_EmbedderInformation info = {
-      0,  // version
-      NULL,  // name
-      -1,  // max_rss
-      -1  // current_rss
+        0,     // version
+        NULL,  // name
+        -1,    // max_rss
+        -1     // current_rss
     };
     embedder_information_callback_(&info);
     ASSERT(info.version == DART_EMBEDDER_INFORMATION_CURRENT_VERSION);
@@ -4612,15 +4667,26 @@
     Isolate::VisitIsolates(&visitor);
   }
   {
+    JSONArray jsarr(&jsobj, "systemIsolates");
+    SystemServiceIsolateVisitor visitor(&jsarr);
+    Isolate::VisitIsolates(&visitor);
+  }
+  {
     JSONArray jsarr_isolate_groups(&jsobj, "isolateGroups");
     IsolateGroup::ForEach([&jsarr_isolate_groups](IsolateGroup* isolate_group) {
-      bool has_internal = false;
-      isolate_group->ForEachIsolate([&has_internal](Isolate* isolate) {
-        if (Isolate::IsVMInternalIsolate(isolate)) {
-          has_internal = true;
-        }
-      });
-      if (FLAG_show_invisible_isolates || !has_internal) {
+      if (!isolate_group->is_system_isolate_group()) {
+        jsarr_isolate_groups.AddValue(isolate_group);
+      }
+    });
+  }
+  {
+    JSONArray jsarr_isolate_groups(&jsobj, "systemIsolateGroups");
+    IsolateGroup::ForEach([&jsarr_isolate_groups](IsolateGroup* isolate_group) {
+      // Don't surface the vm-isolate since it's not a "real" isolate.
+      if (Dart::VmIsolateNameEquals(isolate_group->source()->name)) {
+        return;
+      }
+      if (isolate_group->is_system_isolate_group()) {
         jsarr_isolate_groups.AddValue(isolate_group);
       }
     });
@@ -4638,17 +4704,23 @@
 }
 
 static const char* exception_pause_mode_names[] = {
-    "All", "None", "Unhandled", NULL,
+    "All",
+    "None",
+    "Unhandled",
+    NULL,
 };
 
 static Dart_ExceptionPauseInfo exception_pause_mode_values[] = {
-    kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions,
+    kPauseOnAllExceptions,
+    kNoPauseOnExceptions,
+    kPauseOnUnhandledExceptions,
     kInvalidExceptionPauseInfo,
 };
 
 static const MethodParameter* set_exception_pause_mode_params[] = {
     ISOLATE_PARAMETER,
-    new EnumParameter("mode", true, exception_pause_mode_names), NULL,
+    new EnumParameter("mode", true, exception_pause_mode_names),
+    NULL,
 };
 
 static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) {
@@ -4674,7 +4746,8 @@
 }
 
 static const MethodParameter* get_flag_list_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetFlagList(Thread* thread, JSONStream* js) {
@@ -4683,7 +4756,8 @@
 }
 
 static const MethodParameter* set_flags_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool SetFlag(Thread* thread, JSONStream* js) {
@@ -4763,8 +4837,10 @@
 }
 
 static const MethodParameter* set_library_debuggable_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new IdParameter("libraryId", true),
-    new BoolParameter("isDebuggable", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new IdParameter("libraryId", true),
+    new BoolParameter("isDebuggable", true),
+    NULL,
 };
 
 static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) {
@@ -4785,7 +4861,9 @@
 }
 
 static const MethodParameter* set_name_params[] = {
-    ISOLATE_PARAMETER, new MethodParameter("name", true), NULL,
+    ISOLATE_PARAMETER,
+    new MethodParameter("name", true),
+    NULL,
 };
 
 static bool SetName(Thread* thread, JSONStream* js) {
@@ -4800,7 +4878,9 @@
 }
 
 static const MethodParameter* set_vm_name_params[] = {
-    NO_ISOLATE_PARAMETER, new MethodParameter("name", true), NULL,
+    NO_ISOLATE_PARAMETER,
+    new MethodParameter("name", true),
+    NULL,
 };
 
 static bool SetVMName(Thread* thread, JSONStream* js) {
@@ -4816,8 +4896,10 @@
 }
 
 static const MethodParameter* set_trace_class_allocation_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new IdParameter("classId", true),
-    new BoolParameter("enable", true), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    new IdParameter("classId", true),
+    new BoolParameter("enable", true),
+    NULL,
 };
 
 static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) {
@@ -4842,7 +4924,8 @@
 }
 
 static const MethodParameter* get_default_classes_aliases_params[] = {
-    NO_ISOLATE_PARAMETER, NULL,
+    NO_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetDefaultClassesAliases(Thread* thread, JSONStream* js) {
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 6488425..896c695 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 37
+#define SERVICE_PROTOCOL_MINOR_VERSION 38
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 281f21b..4ba84da 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.37
+# Dart VM Service Protocol 3.38
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.37_ of the Dart VM Service Protocol. This
+This document describes of _version 3.38_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -2858,6 +2858,10 @@
 
   // A name identifying this isolate. Not guaranteed to be unique.
   string name;
+
+  // Specifies whether the isolate was spawned by the VM or embedder for
+  // internal use. If `false`, this isolate is likely running user code.
+  bool isSystemIsolate;
 }
 ```
 
@@ -2875,6 +2879,10 @@
   // A name identifying this isolate. Not guaranteed to be unique.
   string name;
 
+  // Specifies whether the isolate was spawned by the VM or embedder for
+  // internal use. If `false`, this isolate is likely running user code.
+  bool isSystemIsolate;
+
   // The time that the VM started in milliseconds since the epoch.
   //
   // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
@@ -2932,6 +2940,10 @@
 
   // A name identifying this isolate group. Not guaranteed to be unique.
   string name;
+
+  // Specifies whether the isolate group was spawned by the VM or embedder for
+  // internal use. If `false`, this isolate group is likely running user code.
+  bool isSystemIsolateGroup;  
 }
 ```
 
@@ -2949,6 +2961,10 @@
   // A name identifying this isolate. Not guaranteed to be unique.
   string name;
 
+  // Specifies whether the isolate group was spawned by the VM or embedder for
+  // internal use. If `false`, this isolate group is likely running user code.
+  bool isSystemIsolateGroup;  
+
   // A list of all isolates in this isolate group.
   @Isolate[] isolates;
 }
@@ -3862,6 +3878,12 @@
 
   // A list of isolate groups running in the VM.
   @IsolateGroup[] isolateGroups;
+
+  // A list of system isolates running in the VM.
+  @Isolate[] systemIsolates;
+
+  // A list of isolate groups which contain system isolates running in the VM.
+  @IsolateGroup[] systemIsolateGroups;
 }
 ```
 
@@ -3921,5 +3943,7 @@
 3.35 | Added `getSupportedProtocols` RPC and `ProtocolList`, `Protocol` objects.
 3.36 | Added `getProcessMemoryUsage` RPC and `ProcessMemoryUsage` and `ProcessMemoryItem` objects.
 3.37 | Added `getWebSocketTarget` RPC and `WebSocketTarget` object.
+3.38 | Added `isSystemIsolate` property to `@Isolate` and `Isolate`, `isSystemIsolateGroup` property to `@IsolateGroup` and `IsolateGroup`,
+and properties `systemIsolates` and `systemIsolateGroups` to `VM`.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 26cc103..5b90440 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -36,8 +36,9 @@
       timestamp_(OS::GetCurrentTimeMillis()) {
   // We should never generate events for the vm or service isolates.
   ASSERT(isolate_ != Dart::vm_isolate());
-  ASSERT(isolate == NULL || FLAG_show_invisible_isolates ||
-         !Isolate::IsVMInternalIsolate(isolate));
+  ASSERT(isolate == NULL || !Isolate::IsSystemIsolate(isolate) ||
+         (Isolate::IsSystemIsolate(isolate) &&
+          event_kind == ServiceEvent::kResume));
 
   if ((event_kind == ServiceEvent::kPauseStart) ||
       (event_kind == ServiceEvent::kPauseExit)) {
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 068d478..f785a65 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -213,7 +213,7 @@
   }
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
-  if (!FLAG_show_invisible_isolates && Isolate::IsVMInternalIsolate(isolate)) {
+  if (Dart::VmIsolateNameEquals(isolate->name())) {
     return false;
   }
   ASSERT(isolate != NULL);
@@ -239,7 +239,7 @@
   }
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
-  if (!FLAG_show_invisible_isolates && Isolate::IsVMInternalIsolate(isolate)) {
+  if (Dart::VmIsolateNameEquals(isolate->name())) {
     return false;
   }
   ASSERT(isolate != NULL);
@@ -351,7 +351,7 @@
 
     Dart_IsolateFlags api_flags;
     Isolate::FlagsInitialize(&api_flags);
-
+    api_flags.is_system_isolate = true;
     isolate = reinterpret_cast<Isolate*>(
         create_group_callback(ServiceIsolate::kName, ServiceIsolate::kName,
                               NULL, NULL, &api_flags, NULL, &error));
@@ -586,6 +586,44 @@
   ServiceIsolate::SetServicePort(port);
 }
 
+void ServiceIsolate::RegisterRunningIsolate(Isolate* isolate) {
+  ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
+
+  // Get library.
+  const String& library_url = Symbols::DartVMService();
+  ASSERT(!library_url.IsNull());
+  // TODO(bkonyi): hoist Thread::Current()
+  const Library& library =
+      Library::Handle(Library::LookupLibrary(Thread::Current(), library_url));
+  ASSERT(!library.IsNull());
+  // Get function.
+  const String& function_name = String::Handle(String::New("_registerIsolate"));
+  ASSERT(!function_name.IsNull());
+  const Function& register_function_ =
+      Function::Handle(library.LookupFunctionAllowPrivate(function_name));
+  ASSERT(!register_function_.IsNull());
+
+  // Setup arguments for call.
+  Dart_Port port_id = isolate->main_port();
+  const Integer& port_int = Integer::Handle(Integer::New(port_id));
+  ASSERT(!port_int.IsNull());
+  const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
+  const String& name = String::Handle(String::New(isolate->name()));
+  ASSERT(!name.IsNull());
+  const Array& args = Array::Handle(Array::New(3));
+  ASSERT(!args.IsNull());
+  args.SetAt(0, port_int);
+  args.SetAt(1, send_port);
+  args.SetAt(2, name);
+  const Object& r =
+      Object::Handle(DartEntry::InvokeFunction(register_function_, args));
+  if (FLAG_trace_service) {
+    OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
+                 name.ToCString(), port_id);
+  }
+  ASSERT(!r.IsError());
+}
+
 void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {}
 
 }  // namespace dart
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index 44cbd78..5411bb9 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -50,6 +50,8 @@
 
   static void BootVmServiceLibrary();
 
+  static void RegisterRunningIsolate(Isolate* isolate);
+
   static void RequestServerInfo(const SendPort& sp);
   static void ControlWebServer(const SendPort& sp,
                                bool enable,
@@ -106,6 +108,7 @@
   static bool SendIsolateShutdownMessage() { return false; }
   static void SendServiceExitMessage() {}
   static void Shutdown() {}
+  static void RegisterRunningIsolate(Isolate* isolate) {}
   static void VisitObjectPointers(ObjectPointerVisitor* visitor) {}
 
  protected:
diff --git a/sdk/lib/_http/http_headers.dart b/sdk/lib/_http/http_headers.dart
index 73ed901..7d87b88 100644
--- a/sdk/lib/_http/http_headers.dart
+++ b/sdk/lib/_http/http_headers.dart
@@ -913,7 +913,7 @@
   DateTime? expires;
   int? maxAge;
   String? domain;
-  String? path;
+  String? _path;
   bool httpOnly = false;
   bool secure = false;
 
@@ -925,6 +925,13 @@
   String get name => _name;
   String get value => _value;
 
+  String? get path => _path;
+
+  set path(String? newPath) {
+    _validatePath(newPath);
+    _path = newPath;
+  }
+
   set name(String newName) {
     _validateName(newName);
     _name = newName;
@@ -1104,4 +1111,19 @@
     }
     return newValue;
   }
+
+  static void _validatePath(String? path) {
+    if (path == null) return;
+    for (int i = 0; i < path.length; i++) {
+      int codeUnit = path.codeUnitAt(i);
+      // According to RFC 6265, semicolon and controls should not occur in the
+      // path.
+      // path-value = <any CHAR except CTLs or ";">
+      // CTLs = %x00-1F / %x7F
+      if (codeUnit < 0x20 || codeUnit >= 0x7f || codeUnit == 0x3b /*;*/) {
+        throw FormatException(
+            "Invalid character in cookie path, code unit: '$codeUnit'");
+      }
+    }
+  }
 }
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index b0ee0ae..76ced6e 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -2345,7 +2345,7 @@
    * still pending delivery, if the subscription is paused,
    * or if the subscription isn't listening yet.
    * If it's necessary to know whether the "done" event has been delievered,
-   * [done] future will complete when that has happend.
+   * [done] future will complete when that has happened.
    */
   void closeSync();
 }
diff --git a/tests/language/nnbd/definite_assignment/write_error_test.dart b/tests/language/nnbd/definite_assignment/write_error_test.dart
index 81d27b6..4c6c00e 100644
--- a/tests/language/nnbd/definite_assignment/write_error_test.dart
+++ b/tests/language/nnbd/definite_assignment/write_error_test.dart
@@ -17,7 +17,7 @@
 
 /// Test that it is never an error to write to a definitely unassigned local
 /// variable.
-void testDefinitelyUnassignedWrites<T>() {
+void testDefinitelyUnassignedWrites<T>(T t) {
   {
     var x;
     x = 3;
diff --git a/tests/standalone/io/http_cookie_test.dart b/tests/standalone/io/http_cookie_test.dart
index bfe9302..5aa1cf9 100644
--- a/tests/standalone/io/http_cookie_test.dart
+++ b/tests/standalone/io/http_cookie_test.dart
@@ -83,7 +83,35 @@
       () => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
 }
 
+void testValidatePath() {
+  Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
+  Expect.equals('/', cookie.path);
+  cookie.path = null;
+  Expect.throws<FormatException>(() {
+    cookie.path = "something; ";
+  }, (e) => e.toString().contains('Invalid character'));
+
+  StringBuffer buffer = StringBuffer();
+  buffer.writeCharCode(0x1f);
+  Expect.throws<FormatException>(() {
+    cookie.path = buffer.toString();
+  }, (e) => e.toString().contains('Invalid character'));
+
+  buffer.clear();
+  buffer.writeCharCode(0x7f);
+  Expect.throws<FormatException>(() {
+    cookie.path = buffer.toString();
+  }, (e) => e.toString().contains('Invalid character'));
+
+  buffer.clear();
+  buffer.writeCharCode(0x00);
+  Expect.throws<FormatException>(() {
+    cookie.path = buffer.toString();
+  }, (e) => e.toString().contains('Invalid character'));
+}
+
 void main() {
   testCookies();
   testValidateCookieWithDoubleQuotes();
+  testValidatePath();
 }
diff --git a/tests/standalone_2/io/http_cookie_test.dart b/tests/standalone_2/io/http_cookie_test.dart
index bfe9302..5aa1cf9 100644
--- a/tests/standalone_2/io/http_cookie_test.dart
+++ b/tests/standalone_2/io/http_cookie_test.dart
@@ -83,7 +83,35 @@
       () => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
 }
 
+void testValidatePath() {
+  Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
+  Expect.equals('/', cookie.path);
+  cookie.path = null;
+  Expect.throws<FormatException>(() {
+    cookie.path = "something; ";
+  }, (e) => e.toString().contains('Invalid character'));
+
+  StringBuffer buffer = StringBuffer();
+  buffer.writeCharCode(0x1f);
+  Expect.throws<FormatException>(() {
+    cookie.path = buffer.toString();
+  }, (e) => e.toString().contains('Invalid character'));
+
+  buffer.clear();
+  buffer.writeCharCode(0x7f);
+  Expect.throws<FormatException>(() {
+    cookie.path = buffer.toString();
+  }, (e) => e.toString().contains('Invalid character'));
+
+  buffer.clear();
+  buffer.writeCharCode(0x00);
+  Expect.throws<FormatException>(() {
+    cookie.path = buffer.toString();
+  }, (e) => e.toString().contains('Invalid character'));
+}
+
 void main() {
   testCookies();
   testValidateCookieWithDoubleQuotes();
+  testValidatePath();
 }
diff --git a/tools/VERSION b/tools/VERSION
index 3392be0..f0b5f4b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 51
+PRERELEASE 52
 PRERELEASE_PATCH 0
\ No newline at end of file