Version 2.14.0-102.0.dev

Merge commit '85ca8d64729c276bcdb16b517a50054427eacc54' into 'dev'
diff --git a/DEPS b/DEPS
index a54b6f0..6e6db10 100644
--- a/DEPS
+++ b/DEPS
@@ -146,10 +146,10 @@
   "resource_rev": "6b79867d0becf5395e5819a75720963b8298e9a7",
   "root_certificates_rev": "7e5ec82c99677a2e5b95ce296c4d68b0d3378ed8",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
-  "shelf_static_rev": "b8e51372332a27a4939466d94a22f15be53ac3e4",
+  "shelf_static_rev": "fa30419055279a00c9e428439b1abe362d18f25d",
   "shelf_packages_handler_rev": "78302e67c035047e6348e692b0c1182131f0fe35",
   "shelf_proxy_tag": "v1.0.0",
-  "shelf_rev": "c511f06e6d2d28ffe905a45eea1da761b95ea0ca",
+  "shelf_rev": "4b9294e29eb308709444a5c0b890fa8ccd69fae4",
   "shelf_web_socket_rev": "24fb8a04befa75a94ac63a27047b231d1a22aab4",
   "source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
   "source_maps-0.9.4_rev": "38524",
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 3044e88..f4555e0 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -35,14 +35,12 @@
       : resourceProvider =
             resourceProvider ?? PhysicalResourceProvider.INSTANCE;
 
-  /// TODO(scheglov) Remove [overrideWorkspace] when DAS uses collection.
   @override
   List<ContextRoot> locateRoots({
     required List<String> includedPaths,
     List<String>? excludedPaths,
     String? optionsFile,
     String? packagesFile,
-    Workspace? overrideWorkspace,
   }) {
     //
     // Compute the list of folders and files that are to be included.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 7be0e1b..712f844 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 135;
+  static const int DATA_VERSION = 136;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
@@ -1581,7 +1581,6 @@
             analysisOptions as AnalysisOptionsImpl,
             declaredVariables,
             sourceFactory,
-            libraryContext.isLibraryUri,
             libraryContext.analysisContext,
             libraryContext.elementFactory.libraryOfUri2(library.uriStr),
             libraryContext.analysisSession.inheritanceManager,
@@ -1671,7 +1670,6 @@
           analysisOptions as AnalysisOptionsImpl,
           declaredVariables,
           sourceFactory,
-          libraryContext.isLibraryUri,
           libraryContext.analysisContext,
           libraryContext.elementFactory.libraryOfUri2(library.uriStr),
           libraryContext.analysisSession.inheritanceManager,
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 04f85aa..8a9e850 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -34,7 +34,7 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary2/bundle_writer.dart';
+import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/either.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
@@ -385,7 +385,7 @@
     var bytes = _fsState._byteStore.get(_astKey!) as Uint8List?;
     if (bytes == null) {
       unit ??= parse();
-      bytes = writeUnitToBytes(unit: unit);
+      bytes = writeUnitInformative(unit);
       _fsState._byteStore.put(_astKey!, bytes);
     }
     return bytes;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index e85f8b7..17deaf8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -68,7 +68,6 @@
   final FileState _library;
 
   final InheritanceManager3 _inheritance;
-  final bool Function(Uri) _isLibraryUri;
   final AnalysisContext _context;
 
   final LibraryElementImpl _libraryElement;
@@ -88,7 +87,6 @@
       this._analysisOptions,
       this._declaredVariables,
       this._sourceFactory,
-      this._isLibraryUri,
       this._context,
       this._libraryElement,
       this._inheritance,
@@ -506,11 +504,6 @@
     return source == _library.source;
   }
 
-  /// Return `true` if the given [source] is a library.
-  bool _isLibrarySource(Source source) {
-    return _isLibraryUri(source.uri);
-  }
-
   /// Return a new parsed unresolved [CompilationUnit].
   CompilationUnitImpl _parse(FileState file) {
     AnalysisErrorListener errorListener = _getErrorListener(file);
@@ -548,12 +541,14 @@
           if (matchNodeElement(directive, importElement)) {
             directive.element = importElement;
             directive.prefix?.staticElement = importElement.prefix;
-            Source? source = importElement.importedLibrary?.source;
-            if (source != null && !_isLibrarySource(source)) {
-              libraryErrorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
-                  directive.uri,
-                  [directive.uri]);
+            var importedLibrary = importElement.importedLibrary;
+            if (importedLibrary is LibraryElementImpl) {
+              if (importedLibrary.hasPartOfDirective) {
+                libraryErrorReporter.reportErrorForNode(
+                    CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
+                    directive.uri,
+                    [directive.uri]);
+              }
             }
           }
         }
@@ -561,12 +556,14 @@
         for (ExportElement exportElement in _libraryElement.exports) {
           if (matchNodeElement(directive, exportElement)) {
             directive.element = exportElement;
-            Source? source = exportElement.exportedLibrary?.source;
-            if (source != null && !_isLibrarySource(source)) {
-              libraryErrorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                  directive.uri,
-                  [directive.uri]);
+            var exportedLibrary = exportElement.exportedLibrary;
+            if (exportedLibrary is LibraryElementImpl) {
+              if (exportedLibrary.hasPartOfDirective) {
+                libraryErrorReporter.reportErrorForNode(
+                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+                    directive.uri,
+                    [directive.uri]);
+              }
             }
           }
         }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index d8e7821..9cea8d5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -89,12 +89,6 @@
     return elementFactory.libraryOfUri2('$uri');
   }
 
-  /// Return `true` if the given [uri] is known to be a library.
-  bool isLibraryUri(Uri uri) {
-    String uriStr = uri.toString();
-    return elementFactory.isLibraryUri(uriStr);
-  }
-
   /// Load data required to access elements of the given [targetLibrary].
   void load2(FileState targetLibrary) {
     timerLoad2.start();
@@ -122,12 +116,10 @@
         (e) => loadBundle(e, '$debugPrefix  '),
       );
 
-      var uriToLibrary_uriToUnitAstBytes = <String, Map<String, Uint8List>>{};
+      var unitsInformativeBytes = <Uri, Uint8List>{};
       for (var library in cycle.libraries) {
-        var uriToUnitAstBytes = <String, Uint8List>{};
-        uriToLibrary_uriToUnitAstBytes[library.uriStr] = uriToUnitAstBytes;
         for (var file in library.libraryFiles) {
-          uriToUnitAstBytes[file.uriStr] = file.getAstBytes();
+          unitsInformativeBytes[file.uri] = file.getAstBytes();
         }
       }
 
@@ -237,11 +229,11 @@
         librariesLoaded += cycle.libraries.length;
       }
 
-      elementFactory.addLibraries(
-        createLibraryReadersWithAstBytes(
+      elementFactory.addBundle(
+        BundleReader(
           elementFactory: elementFactory,
+          unitsInformativeBytes: unitsInformativeBytes,
           resolutionBytes: resolutionBytes,
-          uriToLibrary_uriToUnitAstBytes: uriToLibrary_uriToUnitAstBytes,
         ),
       );
     }
@@ -287,8 +279,8 @@
         elementFactory.addBundle(
           BundleReader(
             elementFactory: elementFactory,
-            astBytes: bundle.astBytes,
             resolutionBytes: bundle.resolutionBytes,
+            unitsInformativeBytes: {},
           ),
         );
       }
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index c6cb0f7..a8d21a5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -308,9 +308,6 @@
       throw StateError('TypeProvider(s) can be set only once.');
     }
 
-    _typeProviderLegacy = legacy;
-    _typeProviderNonNullableByDefault = nonNullableByDefault;
-
     _typeSystemLegacy = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: false,
@@ -324,5 +321,8 @@
       strictInference: _analysisOptions.strictInference,
       typeProvider: nonNullableByDefault,
     );
+
+    _typeProviderLegacy = legacy;
+    _typeProviderNonNullableByDefault = nonNullableByDefault;
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 592849d..08e9662 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -18,7 +18,6 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
 
 /// Two or more string literals that are implicitly concatenated because of
 /// being adjacent (separated only by whitespace).
@@ -721,18 +720,6 @@
       identical(child, _leftHandSide);
 }
 
-abstract class AstLinkedContext {
-  List<ClassMember> get classMembers;
-  int get codeLength;
-  int get codeOffset;
-  bool get isClassWithConstConstructor;
-  List<Directive> get unitDirectives;
-  void applyResolution(LinkedUnitContext unitContext);
-  int getVariableDeclarationCodeLength(VariableDeclaration node);
-  int getVariableDeclarationCodeOffset(VariableDeclaration node);
-  void readDocumentationComment();
-}
-
 /// A node in the AST structure for a Dart program.
 abstract class AstNodeImpl implements AstNode {
   /// The parent of the node, or `null` if the node is the root of an AST
@@ -1412,7 +1399,6 @@
 ///        [ImplementsClause]?
 ///        '{' [ClassMember]* '}'
 class ClassDeclarationImpl extends ClassOrMixinDeclarationImpl
-    with HasAstLinkedContext
     implements ClassDeclaration {
   /// The 'abstract' keyword, or `null` if the keyword was absent.
   @override
@@ -1656,9 +1642,7 @@
 ///
 ///    mixinApplication ::=
 ///        [TypeName] [WithClause] [ImplementsClause]? ';'
-class ClassTypeAliasImpl extends TypeAliasImpl
-    with HasAstLinkedContext
-    implements ClassTypeAlias {
+class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias {
   /// The type parameters for the class, or `null` if the class does not have
   /// any type parameters.
   TypeParameterListImpl? _typeParameters;
@@ -2009,11 +1993,6 @@
   @override
   final FeatureSet featureSet;
 
-  /// Data that is read during loading this node from summary, but is not
-  /// fully applied yet. For example in many cases we don't need the
-  /// documentation comment, and it is expensive to decode strings.
-  Object? summaryData;
-
   /// Initialize a newly created compilation unit to have the given directives
   /// and declarations. The [scriptTag] can be `null` if there is no script tag
   /// in the compilation unit. The list of [directives] can be `null` if there
@@ -2352,7 +2331,6 @@
 ///    initializerList ::=
 ///        ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
 class ConstructorDeclarationImpl extends ClassMemberImpl
-    with HasAstLinkedContext
     implements ConstructorDeclaration {
   /// The token for the 'external' keyword, or `null` if the constructor is not
   /// external.
@@ -3210,7 +3188,6 @@
 
 /// The declaration of an enum constant.
 class EnumConstantDeclarationImpl extends DeclarationImpl
-    with HasAstLinkedContext
     implements EnumConstantDeclaration {
   /// The name of the constant.
   SimpleIdentifierImpl _name;
@@ -3263,7 +3240,6 @@
 ///        metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier]
 ///        (',' [SimpleIdentifier])* (',')? '}'
 class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
-    with HasAstLinkedContext
     implements EnumDeclaration {
   /// The 'enum' keyword.
   @override
@@ -3342,7 +3318,6 @@
 ///    exportDirective ::=
 ///        [Annotation] 'export' [StringLiteral] [Combinator]* ';'
 class ExportDirectiveImpl extends NamespaceDirectiveImpl
-    with HasAstLinkedContext
     implements ExportDirective {
   /// Initialize a newly created export directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
@@ -3471,6 +3446,13 @@
 ///      | [ThrowExpression]
 abstract class ExpressionImpl extends AstNodeImpl
     implements CollectionElementImpl, Expression {
+  /// To support [inConstantContext] we need to know if an expression is
+  /// an initializer of a constant variable. But when the initializer is
+  /// a part of the element model, there is no parent AST node.
+  ///
+  /// TODO(scheglov) Consider alternative solutions.
+  static final inConstContextWithoutParent = Expando<bool>();
+
   /// The static type of this expression, or `null` if the AST structure has not
   /// been resolved.
   @override
@@ -3486,7 +3468,9 @@
         child is IfElement ||
         child is ForElement) {
       var parent = child.parent;
-      if (parent is TypedLiteralImpl && parent.constKeyword != null) {
+      if (parent == null) {
+        return inConstContextWithoutParent[child] ?? false;
+      } else if (parent is TypedLiteralImpl && parent.constKeyword != null) {
         // Inside an explicitly `const` list or map literal.
         return true;
       } else if (parent is InstanceCreationExpression &&
@@ -3504,8 +3488,6 @@
       } else if (parent is SwitchCase) {
         // Inside a switch case.
         return true;
-      } else if (parent == null) {
-        break;
       }
       child = parent;
     }
@@ -3655,7 +3637,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ExtensionDeclarationImpl extends CompilationUnitMemberImpl
-    with HasAstLinkedContext
     implements ExtensionDeclaration {
   @override
   Token extensionKeyword;
@@ -3862,9 +3843,7 @@
 ///
 ///    fieldDeclaration ::=
 ///        'static'? [VariableDeclarationList] ';'
-class FieldDeclarationImpl extends ClassMemberImpl
-    with HasAstLinkedContext
-    implements FieldDeclaration {
+class FieldDeclarationImpl extends ClassMemberImpl implements FieldDeclaration {
   @override
   Token? abstractKeyword;
 
@@ -4272,11 +4251,6 @@
 ///      | [DefaultFormalParameter]
 abstract class FormalParameterImpl extends AstNodeImpl
     implements FormalParameter {
-  /// Data that is read during loading this node from summary, but is not
-  /// fully applied yet. For example in many cases we don't need the
-  /// documentation comment, and it is expensive to decode strings.
-  Object? summaryData;
-
   @override
   ParameterElement? get declaredElement {
     final identifier = this.identifier;
@@ -4707,7 +4681,6 @@
 ///    functionSignature ::=
 ///        [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
 class FunctionDeclarationImpl extends NamedCompilationUnitMemberImpl
-    with HasAstLinkedContext
     implements FunctionDeclaration {
   /// The token representing the 'external' keyword, or `null` if this is not an
   /// external function.
@@ -4998,9 +4971,7 @@
 ///
 ///    functionPrefix ::=
 ///        [TypeName]? [SimpleIdentifier]
-class FunctionTypeAliasImpl extends TypeAliasImpl
-    with HasAstLinkedContext
-    implements FunctionTypeAlias {
+class FunctionTypeAliasImpl extends TypeAliasImpl implements FunctionTypeAlias {
   /// The name of the return type of the function type being defined, or `null`
   /// if no return type was given.
   TypeAnnotationImpl? _returnType;
@@ -5318,9 +5289,7 @@
 ///    functionTypeAlias ::=
 ///        metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? =
 ///        [FunctionType] ';'
-class GenericTypeAliasImpl extends TypeAliasImpl
-    with HasAstLinkedContext
-    implements GenericTypeAlias {
+class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias {
   /// The type being defined by the alias.
   TypeAnnotationImpl _type;
 
@@ -5407,10 +5376,6 @@
   }
 }
 
-mixin HasAstLinkedContext {
-  AstLinkedContext? linkedContext;
-}
-
 /// A combinator that restricts the names being imported to those that are not
 /// in a given list.
 ///
@@ -5688,7 +5653,6 @@
 ///      | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier
 //         [Combinator]* ';'
 class ImportDirectiveImpl extends NamespaceDirectiveImpl
-    with HasAstLinkedContext
     implements ImportDirective {
   /// The token representing the 'deferred' keyword, or `null` if the imported
   /// is not deferred.
@@ -6504,11 +6468,6 @@
   @override
   Token semicolon;
 
-  /// Data that is read during loading this node from summary, but is not
-  /// fully applied yet. For example in many cases we don't need the
-  /// documentation comment, and it is expensive to decode strings.
-  Object? summaryData;
-
   /// Initialize a newly created library directive. Either or both of the
   /// [comment] and [metadata] can be `null` if the directive does not have the
   /// corresponding attribute.
@@ -6780,7 +6739,6 @@
 ///        [SimpleIdentifier]
 ///      | 'operator' [SimpleIdentifier]
 class MethodDeclarationImpl extends ClassMemberImpl
-    with HasAstLinkedContext
     implements MethodDeclaration {
   /// The token for the 'external' keyword, or `null` if the constructor is not
   /// external.
@@ -7108,7 +7066,6 @@
 ///        metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
 ///        [RequiresClause]? [ImplementsClause]? '{' [ClassMember]* '}'
 class MixinDeclarationImpl extends ClassOrMixinDeclarationImpl
-    with HasAstLinkedContext
     implements MixinDeclaration {
   @override
   Token mixinKeyword;
@@ -9720,7 +9677,6 @@
 ///        ('final' | 'const') type? staticFinalDeclarationList ';'
 ///      | variableDeclaration ';'
 class TopLevelVariableDeclarationImpl extends CompilationUnitMemberImpl
-    with HasAstLinkedContext
     implements TopLevelVariableDeclaration {
   /// The top-level variables being declared.
   VariableDeclarationListImpl _variableList;
@@ -10097,11 +10053,6 @@
   /// explicit upper bound.
   TypeAnnotationImpl? _bound;
 
-  /// Data that is read during loading this node from summary, but is not
-  /// fully applied yet. For example in many cases we don't need the
-  /// documentation comment, and it is expensive to decode strings.
-  Object? summaryData;
-
   /// Initialize a newly created type parameter. Either or both of the [comment]
   /// and [metadata] can be `null` if the parameter does not have the
   /// corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index f4ea31f..cfbe557 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -44,10 +44,10 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/inference_error.dart';
-import 'package:analyzer/src/util/comment.dart';
 
 /// A concrete implementation of a [ClassElement].
 abstract class AbstractClassElementImpl extends _ExistingElementImpl
@@ -80,6 +80,7 @@
 
   /// Set the accessors contained in this class to the given [accessors].
   set accessors(List<PropertyAccessorElement> accessors) {
+    assert(!isMixinApplication);
     for (PropertyAccessorElement accessor in accessors) {
       (accessor as PropertyAccessorElementImpl).enclosingElement = this;
     }
@@ -96,6 +97,7 @@
 
   /// Set the fields contained in this class to the given [fields].
   set fields(List<FieldElement> fields) {
+    assert(!isMixinApplication);
     for (FieldElement field in fields) {
       (field as FieldElementImpl).enclosingElement = this;
     }
@@ -451,6 +453,8 @@
   /// TODO(scheglov) implement as modifier
   bool _isSimplyBounded = true;
 
+  ElementLinkedData? linkedData;
+
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
   ClassElementImpl(String name, int offset) : super(name, offset);
@@ -472,6 +476,12 @@
       return _accessors;
     }
 
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _accessors;
+    }
+
     if (linkedNode != null) {
       if (linkedNode is ClassOrMixinDeclaration) {
         _createPropertiesAndAccessors();
@@ -491,33 +501,24 @@
   }
 
   @override
-  int? get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int? get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset;
-  }
-
-  @override
   List<ConstructorElement> get constructors {
     if (!identical(_constructors, _Sentinel.constructorElement)) {
       return _constructors;
     }
 
     if (isMixinApplication) {
+      // Assign to break a possible infinite recursion during computing.
+      _constructors = const <ConstructorElement>[];
       return _constructors = _computeMixinAppConstructors();
     }
 
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _constructors;
+    }
+
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var context = enclosingUnit.linkedContext!;
       var containerRef = reference!.getChild('@constructor');
       _constructors = context.getConstructors(linkedNode!).map((node) {
@@ -565,24 +566,19 @@
   }
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   List<FieldElement> get fields {
     if (!identical(_fields, _Sentinel.fieldElement)) {
       return _fields;
     }
 
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _fields;
+    }
+
     if (linkedNode != null) {
       if (linkedNode is ClassOrMixinDeclaration) {
-        linkedContext!.applyResolution(linkedNode!);
         _createPropertiesAndAccessors();
         return _fields;
       } else {
@@ -660,12 +656,12 @@
   }
 
   List<InterfaceType> get interfacesInternal {
+    linkedData?.read(this);
     if (!identical(_interfaces, _Sentinel.interfaceType)) {
       return _interfaces;
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var context = enclosingUnit.linkedContext!;
       var implementsClause = context.getImplementsClause(linkedNode!);
       if (implementsClause != null) {
@@ -713,9 +709,6 @@
   /// TODO(scheglov) implement as modifier
   @override
   bool get isSimplyBounded {
-    if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
-    }
     return _isSimplyBounded;
   }
 
@@ -742,13 +735,24 @@
   ElementKind get kind => ElementKind.CLASS;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   List<MethodElement> get methods {
     if (!identical(_methods, _Sentinel.methodElement)) {
       return _methods;
     }
 
+    var linkedData = this.linkedData;
+    if (linkedData is ClassElementLinkedData) {
+      linkedData.readMembers(this);
+      return _methods;
+    }
+
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var context = enclosingUnit.linkedContext!;
       var containerRef = reference!.getChild('@method');
       return _methods = context
@@ -756,6 +760,12 @@
           .where((node) => node.propertyKeyword == null)
           .map((node) {
         var name = node.name.name;
+        if (node.name.name == '-') {
+          var parameters = node.parameters;
+          if (parameters != null && parameters.parameters.isEmpty) {
+            name = 'unary-';
+          }
+        }
         var reference = containerRef.getChild(name);
         var element = node.declaredElement as MethodElement?;
         element ??= MethodElementImpl.forLinkedNode(this, reference, node);
@@ -768,6 +778,7 @@
 
   /// Set the methods contained in this class to the given [methods].
   set methods(List<MethodElement> methods) {
+    assert(!isMixinApplication);
     for (MethodElement method in methods) {
       (method as MethodElementImpl).enclosingElement = this;
     }
@@ -783,12 +794,12 @@
       }
     }
 
+    linkedData?.read(this);
     if (!identical(_mixins, _Sentinel.interfaceType)) {
       return _mixins;
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var context = enclosingUnit.linkedContext!;
       var withClause = context.getWithClause(linkedNode!);
       if (withClause != null) {
@@ -811,6 +822,11 @@
 
   @override
   String get name {
+    final linkedData = this.linkedData;
+    if (linkedData != null) {
+      return linkedData.reference.name;
+    }
+
     if (linkedNode != null) {
       return reference!.name;
     }
@@ -832,6 +848,7 @@
 
   @override
   InterfaceType? get supertype {
+    linkedData?.read(this);
     if (_supertype != null) return _supertype!;
 
     if (hasModifier(Modifier.DART_CORE_OBJECT)) {
@@ -839,7 +856,6 @@
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var type = linkedContext!.getSuperclass(linkedNode!)?.type;
       if (_isInterfaceTypeClass(type)) {
         return _supertype = type as InterfaceType;
@@ -857,6 +873,12 @@
     _supertype = supertype;
   }
 
+  @override
+  List<TypeParameterElement> get typeParameters {
+    linkedData?.read(this);
+    return super.typeParameters;
+  }
+
   /// Set the type parameters defined for this class to the given
   /// [typeParameters].
   set typeParameters(List<TypeParameterElement> typeParameters) {
@@ -885,6 +907,18 @@
   ConstructorElement? getNamedConstructor(String name) =>
       getNamedConstructorFromList(name, constructors);
 
+  void resetAfterMixinInference() {
+    linkedMixinInferenceCallback = null;
+    _mixins = _Sentinel.interfaceType;
+  }
+
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -1195,6 +1229,8 @@
   /// A list containing all of the variables contained in this compilation unit.
   List<TopLevelVariableElement> _variables = _Sentinel.topLevelVariables;
 
+  ElementLinkedData? linkedData;
+
   /// Initialize a newly created compilation unit element to have the given
   /// [name].
   CompilationUnitElementImpl()
@@ -1202,10 +1238,10 @@
         super(null, -1);
 
   CompilationUnitElementImpl.forLinkedNode(LibraryElementImpl enclosingLibrary,
-      this.linkedContext, Reference reference, CompilationUnitImpl linkedNode)
+      this.linkedContext, Reference reference, CompilationUnitImpl? linkedNode)
       : super.forLinkedNode(enclosingLibrary, reference, linkedNode) {
     _nameOffset = -1;
-    linkedNode.declaredElement = this;
+    linkedNode?.declaredElement = this;
   }
 
   @override
@@ -1232,22 +1268,6 @@
   }
 
   @override
-  int get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength!;
-  }
-
-  @override
-  int get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset!;
-  }
-
-  @override
   LibraryElement get enclosingElement =>
       super.enclosingElement as LibraryElement;
 
@@ -1394,6 +1414,12 @@
   ElementKind get kind => ElementKind.COMPILATION_UNIT;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   List<ClassElement> get mixins {
     if (!identical(_mixins, _Sentinel.classElement)) {
       return _mixins;
@@ -1536,7 +1562,7 @@
   }
 
   List<CompilationUnitMember> get _linkedUnitDeclarations {
-    return linkedContext!.unit_withDeclarations.declarations;
+    return linkedContext!.unit.declarations;
   }
 
   @override
@@ -1572,6 +1598,13 @@
     return null;
   }
 
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -1608,7 +1641,7 @@
       variableMap[unitImpl] = variableList;
 
       // TODO(scheglov) Bad, we want to read only functions / variables.
-      var unitNode = context.unit_withDeclarations;
+      var unitNode = context.unit;
       var unitDeclarations = unitNode.declarations;
 
       var variables = context.topLevelVariables(unitNode);
@@ -1695,6 +1728,12 @@
   ConstFieldElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
+
+  @override
+  Expression? get constantInitializer {
+    linkedData?.read(this);
+    return super.constantInitializer;
+  }
 }
 
 /// A field element representing an enum constant.
@@ -1713,16 +1752,6 @@
   Expression? get constantInitializer => null;
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   EvaluationResultImpl? get evaluationResult {
     if (_evaluationResult == null) {
       Map<String, DartObjectImpl> fieldMap = <String, DartObjectImpl>{
@@ -1918,12 +1947,12 @@
   /// Return the constant initializers for this element, which will be empty if
   /// there are no initializers, or `null` if there was an error in the source.
   List<ConstructorInitializer> get constantInitializers {
+    linkedData?.read(this);
     if (!identical(_constantInitializers, _Sentinel.constructorInitializer)) {
       return _constantInitializers;
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       return _constantInitializers = linkedContext!.getConstructorInitializers(
         linkedNode as ConstructorDeclaration,
       );
@@ -1941,6 +1970,11 @@
 
   @override
   String get displayName {
+    final linkedData = this.linkedData;
+    if (linkedData != null) {
+      return linkedData.reference.name;
+    }
+
     if (linkedNode != null) {
       return reference!.name;
     }
@@ -2029,10 +2063,10 @@
 
   @override
   ConstructorElement? get redirectedConstructor {
+    linkedData?.read(this);
     if (_redirectedConstructor != null) return _redirectedConstructor;
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var context = enclosingUnit.linkedContext!;
       if (isFactory) {
         var node = context
@@ -2142,6 +2176,12 @@
   ConstTopLevelVariableElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
+
+  @override
+  Expression? get constantInitializer {
+    linkedData?.read(this);
+    return super.constantInitializer;
+  }
 }
 
 /// Mixin used by elements that represent constant variables and have
@@ -2169,7 +2209,6 @@
     if (_constantInitializer != null) return _constantInitializer!;
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       return _constantInitializer = linkedContext!.getInitializer(linkedNode!);
     }
 
@@ -2227,6 +2266,12 @@
   DefaultParameterElementImpl.forLinkedNode(ElementImpl enclosing,
       Reference? reference, FormalParameterImpl linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
+
+  @override
+  String? get defaultValueCode {
+    var ast = constantInitializer;
+    return ast != null ? ast.toSource() : null;
+  }
 }
 
 /// The synthetic element representing the declaration of the type `dynamic`.
@@ -2620,7 +2665,7 @@
 
   /// The documentation comment source for this element.
   set documentationComment(String? doc) {
-    _docComment = doc?.replaceAll('\r\n', '\n');
+    _docComment = doc;
   }
 
   @override
@@ -2915,7 +2960,6 @@
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var metadata = linkedContext!.getMetadata(linkedNode!);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
@@ -3239,6 +3283,8 @@
 
 /// An [AbstractClassElementImpl] which is an enum.
 class EnumElementImpl extends AbstractClassElementImpl {
+  ElementLinkedData? linkedData;
+
   /// Initialize a newly created class element to have the given [name] at the
   /// given [offset] in the file that contains the declaration of this element.
   EnumElementImpl(String name, int offset) : super(name, offset);
@@ -3251,6 +3297,7 @@
 
   @override
   List<PropertyAccessorElement> get accessors {
+    linkedData?.read(this);
     if (!identical(_accessors, _Sentinel.propertyAccessorElement)) {
       return _accessors;
     }
@@ -3265,26 +3312,14 @@
   @override
   List<InterfaceType> get allSupertypes => <InterfaceType>[supertype];
 
-  @override
-  int? get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int? get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset;
-  }
-
   List<FieldElement> get constants {
     return fields.where((field) => !field.isSynthetic).toList();
   }
 
+  List<FieldElement> get constants_unresolved {
+    return _fields.where((field) => !field.isSynthetic).toList();
+  }
+
   @override
   List<ConstructorElement> get constructors {
     // The equivalent code for enums in the spec shows a single constructor,
@@ -3295,17 +3330,8 @@
   }
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   List<FieldElement> get fields {
+    linkedData?.read(this);
     if (!identical(_fields, _Sentinel.fieldElement)) {
       return _fields;
     }
@@ -3345,7 +3371,14 @@
   ElementKind get kind => ElementKind.ENUM;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   List<MethodElement> get methods {
+    linkedData?.read(this);
     if (!identical(_methods, _Sentinel.methodElement)) {
       return _methods;
     }
@@ -3407,6 +3440,13 @@
   @override
   ConstructorElement? getNamedConstructor(String name) => null;
 
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+
   void _resynthesizeMembers2() {
     var fields = <FieldElementImpl>[];
     var getters = <PropertyAccessorElementImpl>[];
@@ -3466,6 +3506,8 @@
   /// The type of function defined by this executable element.
   FunctionType? _type;
 
+  ElementLinkedData? linkedData;
+
   /// Initialize a newly created executable element to have the given [name] and
   /// [offset].
   ExecutableElementImpl(String name, int offset, {Reference? reference})
@@ -3483,22 +3525,6 @@
   }
 
   @override
-  int? get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int? get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset;
-  }
-
-  @override
   String get displayName {
     if (linkedNode != null) {
       return reference!.name;
@@ -3507,16 +3533,6 @@
   }
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   Element get enclosingElement => super.enclosingElement!;
 
   @override
@@ -3587,6 +3603,12 @@
   bool get isSynchronous => !isAsynchronous;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   String get name {
     if (linkedNode != null) {
       return reference!.name;
@@ -3616,17 +3638,21 @@
     _parameters = parameters;
   }
 
+  List<ParameterElement> get parameters_unresolved {
+    return _parameters;
+  }
+
   /// Gets the element's parameters, without going through the indirection of
   /// [ElementTypeProvider].
   ///
   /// In most cases, the [parameters] getter should be used instead.
   List<ParameterElement> get parametersInternal {
+    linkedData?.read(this);
     if (!identical(_parameters, _Sentinel.parameterElement)) {
       return _parameters;
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var context = enclosingUnit.linkedContext!;
       var containerRef = reference!.getChild('@parameter');
       var formalParameters = context.getFormalParameters(linkedNode!);
@@ -3659,12 +3685,7 @@
 
   @override
   DartType get returnTypeInternal {
-    if (_returnType != null) return _returnType!;
-
-    if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
-      return _returnType!;
-    }
+    linkedData?.read(this);
     return _returnType!;
   }
 
@@ -3702,6 +3723,13 @@
     builder.writeExecutableElement(this, displayName);
   }
 
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -3758,12 +3786,6 @@
 
   @override
   LibraryElement? get exportedLibrary {
-    if (_exportedLibrary != null) return _exportedLibrary;
-
-    if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
-    }
-
     return _exportedLibrary;
   }
 
@@ -3772,7 +3794,7 @@
   }
 
   @override
-  String get identifier => exportedLibrary!.name!;
+  String get identifier => exportedLibrary!.name ?? 'unknown';
 
   @override
   ElementKind get kind => ElementKind.EXPORT;
@@ -3822,10 +3844,12 @@
   /// A list containing all of the methods contained in this extension.
   List<MethodElement> _methods = _Sentinel.methodElement;
 
+  ElementLinkedData? linkedData;
+
   /// Initialize a newly created extension element to have the given [name] at
   /// the given [offset] in the file that contains the declaration of this
   /// element.
-  ExtensionElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  ExtensionElementImpl(String? name, int nameOffset) : super(name, nameOffset);
 
   /// Initialize using the given linked information.
   ExtensionElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
@@ -3858,35 +3882,9 @@
   }
 
   @override
-  int? get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int? get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset;
-  }
-
-  @override
   String get displayName => name ?? '';
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   CompilationUnitElementImpl get enclosingElement {
     return _enclosingElement as CompilationUnitElementImpl;
   }
@@ -3900,11 +3898,11 @@
   }
 
   DartType get extendedTypeInternal {
+    linkedData?.read(this);
     if (_extendedType != null) return _extendedType!;
 
     if (linkedNode != null) {
       final linkedNode = this.linkedNode as ExtensionDeclaration;
-      linkedContext!.applyResolution(linkedNode);
       return _extendedType = linkedNode.extendedType.typeOrThrow;
     }
 
@@ -3938,6 +3936,9 @@
 
   @override
   String get identifier {
+    if (linkedData != null) {
+      return linkedData!.reference.name;
+    }
     if (linkedNode != null) {
       return reference!.name;
     }
@@ -3951,6 +3952,12 @@
   ElementKind get kind => ElementKind.EXTENSION;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   List<MethodElement> get methods {
     if (!identical(_methods, _Sentinel.methodElement)) {
       return _methods;
@@ -3964,6 +3971,12 @@
           .where((node) => node.propertyKeyword == null)
           .map((node) {
         var name = node.name.name;
+        if (node.name.name == '-') {
+          var parameters = node.parameters;
+          if (parameters != null && parameters.parameters.isEmpty) {
+            name = 'unary-';
+          }
+        }
         var reference = containerRef.getChild(name);
         var element = node.declaredElement as MethodElement?;
         element ??= MethodElementImpl.forLinkedNode(this, reference, node);
@@ -3999,6 +4012,12 @@
     return super.nameOffset;
   }
 
+  @override
+  List<TypeParameterElement> get typeParameters {
+    linkedData?.read(this);
+    return super.typeParameters;
+  }
+
   /// Set the type parameters defined by this extension to the given
   /// [typeParameters].
   set typeParameters(List<TypeParameterElement> typeParameters) {
@@ -4048,6 +4067,13 @@
         setterName, accessors);
   }
 
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -4145,18 +4171,7 @@
     }
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference!;
-
-      getter = PropertyAccessorElementImpl_ImplicitGetter(
-        this,
-        reference: enclosingRef.getChild('@getter').getChild(name),
-      );
-
-      if (_hasSetter) {
-        setter = PropertyAccessorElementImpl_ImplicitSetter(
-          this,
-          reference: enclosingRef.getChild('@setter').getChild(name),
-        );
-      }
+      createImplicitAccessors(enclosingRef, name);
     }
   }
 
@@ -4229,6 +4244,12 @@
   ElementKind get kind => ElementKind.FIELD;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   T? accept<T>(ElementVisitor<T> visitor) => visitor.visitFieldElement(this);
 }
 
@@ -4275,6 +4296,15 @@
     _field = field;
   }
 
+  /// Initializing formals are visible only in the "formal parameter
+  /// initializer scope", which is the current scope of the initializer list
+  /// of the constructor, and which is enclosed in the scope where the
+  /// constructor is declared. And according to the specification, they
+  /// introduce final local variables, always, regardless whether the field
+  /// is final.
+  @override
+  bool get isFinal => true;
+
   @override
   bool get isInitializingFormal => true;
 
@@ -4354,6 +4384,9 @@
 @Deprecated('Use TypeAliasElement instead')
 class FunctionTypeAliasElementImpl extends TypeAliasElementImpl
     implements FunctionTypeAliasElement {
+  FunctionTypeAliasElementImpl(String name, int nameOffset)
+      : super(name, nameOffset);
+
   FunctionTypeAliasElementImpl.forLinkedNode(
     CompilationUnitElementImpl enclosingUnit,
     Reference reference,
@@ -4674,12 +4707,6 @@
 
   @override
   LibraryElement? get importedLibrary {
-    if (_importedLibrary != null) return _importedLibrary;
-
-    if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
-    }
-
     return _importedLibrary;
   }
 
@@ -4861,6 +4888,8 @@
   @override
   final LinkedUnitContext? linkedContext;
 
+  LibraryElementLinkedData? linkedData;
+
   @override
   final FeatureSet featureSet;
 
@@ -4889,7 +4918,7 @@
   late FunctionElement _loadLibraryFunction;
 
   @override
-  final int nameLength;
+  int nameLength;
 
   /// The export [Namespace] of this library, `null` if it has not been
   /// computed yet.
@@ -4910,34 +4939,26 @@
   LibraryElementImpl(this.context, this.session, String name, int offset,
       this.nameLength, this.featureSet)
       : linkedContext = null,
+        linkedData = null,
         super(name, offset);
 
   LibraryElementImpl.forLinkedNode(
-      this.context,
-      this.session,
-      String name,
-      int offset,
-      this.nameLength,
-      this.linkedContext,
-      Reference reference,
-      CompilationUnit linkedNode)
-      : featureSet = linkedNode.featureSet,
+    this.context,
+    this.session,
+    String name,
+    int offset,
+    this.nameLength,
+    this.linkedContext,
+    Reference reference,
+    CompilationUnit? linkedNode,
+    FeatureSet featureSet,
+  )   : featureSet = featureSet,
         super.forLinkedNode(null, reference, linkedNode) {
     _name = name;
     _nameOffset = offset;
   }
 
   @override
-  int get codeLength {
-    return _definingCompilationUnit.codeLength;
-  }
-
-  @override
-  int get codeOffset {
-    return _definingCompilationUnit.codeOffset;
-  }
-
-  @override
   CompilationUnitElement get definingCompilationUnit =>
       _definingCompilationUnit;
 
@@ -4950,21 +4971,13 @@
   }
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var comment = linkedContext!.getLibraryDocumentationComment();
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   CompilationUnitElementImpl get enclosingUnit {
     return _definingCompilationUnit;
   }
 
   @override
   FunctionElement? get entryPoint {
+    linkedData?.read(this);
     if (_entryPoint != null) return _entryPoint!;
 
     if (linkedContext != null) {
@@ -4999,6 +5012,12 @@
   Namespace get exportNamespace {
     if (_exportNamespace != null) return _exportNamespace!;
 
+    final linkedData = this.linkedData;
+    if (linkedData != null) {
+      var elements = linkedData.elementFactory;
+      return _exportNamespace = elements.buildExportNamespace(source.uri);
+    }
+
     if (linkedNode != null) {
       var elements = linkedContext!.elementFactory;
       return _exportNamespace = elements.buildExportNamespace(source.uri);
@@ -5013,12 +5032,13 @@
 
   @override
   List<ExportElement> get exports {
+    linkedData?.read(this);
     if (!identical(_exports, _Sentinel.exportElement)) {
       return _exports;
     }
 
     if (linkedNode != null) {
-      var unit = linkedContext!.unit_withDirectives;
+      var unit = linkedContext!.unit;
       return _exports = unit.directives
           .whereType<ExportDirective>()
           .map((node) => node.element!)
@@ -5037,10 +5057,14 @@
     _exports = exports;
   }
 
+  List<ExportElement> get exports_unresolved {
+    return _exports;
+  }
+
   @override
   bool get hasExtUri {
     if (linkedNode != null) {
-      var unit = linkedContext!.unit_withDirectives;
+      var unit = linkedContext!.unit;
       for (var import in unit.directives) {
         if (import is ImportDirective) {
           var uriLiteral = import.uri;
@@ -5074,6 +5098,14 @@
     return false;
   }
 
+  bool get hasPartOfDirective {
+    return hasModifier(Modifier.HAS_PART_OF_DIRECTIVE);
+  }
+
+  set hasPartOfDirective(bool hasPartOfDirective) {
+    setModifier(Modifier.HAS_PART_OF_DIRECTIVE, hasPartOfDirective);
+  }
+
   @override
   String get identifier => '${_definingCompilationUnit.source.uri}';
 
@@ -5091,12 +5123,13 @@
 
   @override
   List<ImportElement> get imports {
+    linkedData?.read(this);
     if (!identical(_imports, _Sentinel.importElement)) {
       return _imports;
     }
 
     if (linkedNode != null) {
-      var unit = linkedContext!.unit_withDirectives;
+      var unit = linkedContext!.unit;
       _imports = unit.directives
           .whereType<ImportDirective>()
           .map((node) => node.element!)
@@ -5133,6 +5166,10 @@
     _prefixes = null;
   }
 
+  List<ImportElement> get imports_unresolved {
+    return _imports;
+  }
+
   @override
   bool get isBrowserApplication =>
       entryPoint != null && isOrImportsBrowserLibrary;
@@ -5211,6 +5248,10 @@
     return _languageVersion!;
   }
 
+  set languageVersion(LibraryLanguageVersion languageVersion) {
+    _languageVersion = languageVersion;
+  }
+
   @override
   LibraryElementImpl get library => this;
 
@@ -5221,6 +5262,7 @@
 
   @override
   List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
     if (!identical(_metadata, _Sentinel.elementAnnotation)) {
       return _metadata;
     }
@@ -5255,6 +5297,11 @@
   Namespace get publicNamespace {
     if (_publicNamespace != null) return _publicNamespace!;
 
+    if (linkedData != null) {
+      return _publicNamespace =
+          NamespaceBuilder().createPublicNamespaceForLibrary(this);
+    }
+
     if (linkedNode != null) {
       return _publicNamespace =
           NamespaceBuilder().createPublicNamespaceForLibrary(this);
@@ -5419,11 +5466,6 @@
     return hasModifier(Modifier.LATE);
   }
 
-  /// Set whether this variable is late.
-  set isLate(bool isLate) {
-    setModifier(Modifier.LATE, isLate);
-  }
-
   @override
   ElementKind get kind => ElementKind.LOCAL_VARIABLE;
 
@@ -5546,13 +5588,13 @@
 
   @override
   List<InterfaceType> get superclassConstraints {
+    linkedData?.read(this);
     if (!identical(_superclassConstraints, _Sentinel.interfaceType)) {
       return _superclassConstraints;
     }
 
     final linkedNode = this.linkedNode;
     if (linkedNode is MixinDeclaration) {
-      linkedContext!.applyResolution(linkedNode);
       List<InterfaceType>? constraints;
       var onClause = linkedNode.onClause;
       if (onClause != null) {
@@ -5637,28 +5679,38 @@
   /// scheme.
   static const Modifier HAS_EXT_URI = Modifier('HAS_EXT_URI', 12);
 
+  /// A flag used for libraries indicating that the variable has an explicit
+  /// initializer.
+  static const Modifier HAS_INITIALIZER = Modifier('HAS_INITIALIZER', 13);
+
+  /// A flag used for libraries indicating that the defining compilation unit
+  /// has a `part of` directive, meaning that this unit should be a part,
+  /// but is used as a library.
+  static const Modifier HAS_PART_OF_DIRECTIVE =
+      Modifier('HAS_PART_OF_DIRECTIVE', 14);
+
   /// Indicates that the associated element did not have an explicit type
   /// associated with it. If the element is an [ExecutableElement], then the
   /// type being referred to is the return type.
-  static const Modifier IMPLICIT_TYPE = Modifier('IMPLICIT_TYPE', 13);
+  static const Modifier IMPLICIT_TYPE = Modifier('IMPLICIT_TYPE', 15);
 
   /// Indicates that modifier 'lazy' was applied to the element.
-  static const Modifier LATE = Modifier('LATE', 14);
+  static const Modifier LATE = Modifier('LATE', 16);
 
   /// Indicates that a class is a mixin application.
-  static const Modifier MIXIN_APPLICATION = Modifier('MIXIN_APPLICATION', 15);
+  static const Modifier MIXIN_APPLICATION = Modifier('MIXIN_APPLICATION', 17);
 
   /// Indicates that the pseudo-modifier 'set' was applied to the element.
-  static const Modifier SETTER = Modifier('SETTER', 16);
+  static const Modifier SETTER = Modifier('SETTER', 18);
 
   /// Indicates that the modifier 'static' was applied to the element.
-  static const Modifier STATIC = Modifier('STATIC', 17);
+  static const Modifier STATIC = Modifier('STATIC', 19);
 
   /// Indicates that the element does not appear in the source code but was
   /// implicitly created. For example, if a class does not define any
   /// constructors, an implicit zero-argument constructor will be created and it
   /// will be marked as being synthetic.
-  static const Modifier SYNTHETIC = Modifier('SYNTHETIC', 18);
+  static const Modifier SYNTHETIC = Modifier('SYNTHETIC', 20);
 
   static const List<Modifier> values = [
     ABSTRACT,
@@ -5674,6 +5726,8 @@
     GENERATOR,
     GETTER,
     HAS_EXT_URI,
+    HAS_INITIALIZER,
+    HAS_PART_OF_DIRECTIVE,
     IMPLICIT_TYPE,
     LATE,
     MIXIN_APPLICATION,
@@ -5942,32 +5996,6 @@
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   @override
-  int? get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength;
-  }
-
-  @override
-  int? get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset;
-  }
-
-  @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   Element get enclosingElement => super.enclosingElement!;
 
   @override
@@ -5979,8 +6007,16 @@
   }
 
   bool get hasInitializer {
-    return linkedNode != null &&
-        linkedContext!.hasInitializer(linkedNode as VariableDeclarationImpl);
+    if (linkedNode != null) {
+      return linkedContext!
+          .hasInitializer(linkedNode as VariableDeclarationImpl);
+    }
+    return hasModifier(Modifier.HAS_INITIALIZER);
+  }
+
+  /// Set whether this variable has an initializer.
+  set hasInitializer(bool hasInitializer) {
+    setModifier(Modifier.HAS_INITIALIZER, hasInitializer);
   }
 
   @override
@@ -6422,7 +6458,8 @@
 
   /// Initialize a newly created method element to have the given [name] and
   /// [nameOffset].
-  PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  PrefixElementImpl(String name, int nameOffset, {Reference? reference})
+      : super(name, nameOffset, reference: reference);
 
   PrefixElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference reference, SimpleIdentifier linkedNode)
@@ -6571,6 +6608,12 @@
   }
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   String get name {
     if (linkedNode != null) {
       var name = reference!.name;
@@ -6754,6 +6797,8 @@
   /// this variable is not a subject of type inference, or there was no error.
   TopLevelInferenceError? typeInferenceError;
 
+  ElementLinkedData? linkedData;
+
   /// Initialize a newly created synthetic element to have the given [name] and
   /// [offset].
   PropertyInducingElementImpl(String name, int offset) : super(name, offset);
@@ -6780,11 +6825,10 @@
 
   @override
   DartType get typeInternal {
+    linkedData?.read(this);
     if (_type != null) return _type!;
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
-
       // While performing inference during linking, the first step is to collect
       // dependencies. During this step we resolve the expression, but we might
       // reference elements that don't have their types inferred yet. So, here
@@ -6824,6 +6868,27 @@
 
     return !isFinal;
   }
+
+  void createImplicitAccessors(Reference enclosingRef, String name) {
+    getter = PropertyAccessorElementImpl_ImplicitGetter(
+      this,
+      reference: enclosingRef.getChild('@getter').getChild(name),
+    );
+
+    if (_hasSetter) {
+      setter = PropertyAccessorElementImpl_ImplicitSetter(
+        this,
+        reference: enclosingRef.getChild('@setter').getChild(name),
+      );
+    }
+  }
+
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
 }
 
 /// Instances of this class are set for fields and top-level variables
@@ -6925,18 +6990,7 @@
     }
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference!;
-
-      getter = PropertyAccessorElementImpl_ImplicitGetter(
-        this,
-        reference: enclosingRef.getChild('@getter').getChild(name),
-      );
-
-      if (_hasSetter) {
-        setter = PropertyAccessorElementImpl_ImplicitSetter(
-          this,
-          reference: enclosingRef.getChild('@setter').getChild(name),
-        );
-      }
+      createImplicitAccessors(enclosingRef, name);
     }
   }
 
@@ -6974,6 +7028,12 @@
   ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   T? accept<T>(ElementVisitor<T> visitor) =>
       visitor.visitTopLevelVariableElement(this);
 }
@@ -6992,6 +7052,10 @@
   /// from anywhere except a class element or type parameter bounds.
   bool hasSelfReference = false;
 
+  bool isFunctionTypeAliasBased = false;
+
+  ElementLinkedData? linkedData;
+
   bool _isAliasedElementReady = false;
   ElementImpl? _aliasedElement;
   DartType? _aliasedType;
@@ -7038,8 +7102,15 @@
     return _aliasedElement;
   }
 
+  set aliasedElement(ElementImpl? aliasedElement) {
+    _isAliasedElementReady = true;
+    _aliasedElement = aliasedElement;
+    aliasedElement?.enclosingElement = this;
+  }
+
   @override
   DartType get aliasedType {
+    linkedData?.read(this);
     if (_aliasedType != null) return _aliasedType!;
 
     _ensureAliasedElement();
@@ -7068,35 +7139,9 @@
   }
 
   @override
-  int get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength!;
-  }
-
-  @override
-  int get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset!;
-  }
-
-  @override
   String get displayName => name;
 
   @override
-  String? get documentationComment {
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      var comment = context.getDocumentationComment(linkedNode!);
-      return getCommentNodeRawText(comment);
-    }
-    return super.documentationComment;
-  }
-
-  @override
   CompilationUnitElement get enclosingElement =>
       super.enclosingElement as CompilationUnitElement;
 
@@ -7110,6 +7155,12 @@
   }
 
   @override
+  List<ElementAnnotation> get metadata {
+    linkedData?.read(this);
+    return super.metadata;
+  }
+
+  @override
   String get name {
     if (linkedNode != null) {
       return reference!.name;
@@ -7126,6 +7177,12 @@
     return super.nameOffset;
   }
 
+  @override
+  List<TypeParameterElement> get typeParameters {
+    linkedData?.read(this);
+    return super.typeParameters;
+  }
+
   /// Set the type parameters defined for this type to the given
   /// [typeParameters].
   set typeParameters(List<TypeParameterElement> typeParameters) {
@@ -7194,10 +7251,19 @@
     }
   }
 
+  void setLinkedData(Reference reference, ElementLinkedData linkedData) {
+    this.reference = reference;
+    reference.element = this;
+
+    this.linkedData = linkedData;
+  }
+
   void _ensureAliasedElement() {
     if (_isAliasedElementReady) return;
     _isAliasedElementReady = true;
 
+    linkedData?.read(this);
+
     final linkedNode = this.linkedNode;
     if (linkedNode != null) {
       if (linkedNode is GenericTypeAlias) {
@@ -7230,7 +7296,6 @@
           linkedNode,
         );
       }
-      linkedContext!.applyResolution(linkedNode);
     }
   }
 
@@ -7296,22 +7361,6 @@
   }
 
   @override
-  int get codeLength {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeLength(linkedNode!);
-    }
-    return super.codeLength!;
-  }
-
-  @override
-  int get codeOffset {
-    if (linkedNode != null) {
-      return linkedContext!.getCodeOffset(linkedNode!);
-    }
-    return super.codeOffset!;
-  }
-
-  @override
   TypeParameterElement get declaration => this;
 
   @override
@@ -7401,7 +7450,6 @@
     }
 
     if (linkedNode != null) {
-      linkedContext!.applyResolution(linkedNode!);
       var typeParameters = linkedContext!.getTypeParameters2(linkedNode!);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
@@ -7417,6 +7465,10 @@
 
     return _typeParameterElements;
   }
+
+  List<TypeParameterElement> get typeParameters_unresolved {
+    return _typeParameterElements;
+  }
 }
 
 /// A concrete implementation of a [UriReferencedElement].
@@ -7437,7 +7489,7 @@
   UriReferencedElementImpl(String? name, int offset) : super(name, offset);
 
   UriReferencedElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference? reference, AstNode linkedNode)
+      ElementImpl enclosing, Reference? reference, AstNode? linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize using the given serialized information.
@@ -7483,7 +7535,8 @@
 
   /// Initialize a newly created variable element to have the given [name] and
   /// [offset].
-  VariableElementImpl(String? name, int offset) : super(name, offset);
+  VariableElementImpl(String? name, int offset, {Reference? reference})
+      : super(name, offset, reference: reference);
 
   VariableElementImpl.forLinkedNode(
       ElementImpl enclosing, Reference? reference, AstNode linkedNode)
@@ -7530,6 +7583,11 @@
     setModifier(Modifier.IMPLICIT_TYPE, hasImplicitType);
   }
 
+  /// Set whether this variable is abstract.
+  set isAbstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
   @override
   bool get isConst {
     if (linkedNode != null) {
@@ -7546,6 +7604,11 @@
   @override
   bool get isConstantEvaluated => true;
 
+  /// Set whether this variable is external.
+  set isExternal(bool isExternal) {
+    setModifier(Modifier.EXTERNAL, isExternal);
+  }
+
   @override
   bool get isFinal {
     if (linkedNode != null) {
@@ -7559,6 +7622,11 @@
     setModifier(Modifier.FINAL, isFinal);
   }
 
+  /// Set whether this variable is late.
+  set isLate(bool isLate) {
+    setModifier(Modifier.LATE, isLate);
+  }
+
   @override
   bool get isStatic => hasModifier(Modifier.STATIC);
 
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 0d6ea0b..99083b7 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -28,6 +28,7 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
+import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
@@ -87,6 +88,7 @@
   late bool _exists;
   late List<int> _apiSignature;
   late UnlinkedUnit2 unlinked2;
+  Uint8List? informativeBytes;
   LibraryCycle? _libraryCycle;
 
   /// id of the cache entry.
@@ -243,6 +245,8 @@
           return parse(AnalysisErrorListener.NULL_LISTENER, content);
         });
 
+        informativeBytes = writeUnitInformative(unit);
+
         performance.run('unlinked', (performance) {
           var unlinkedBuilder = serializeAstCiderUnlinked(_digest, unit);
           bytes = unlinkedBuilder.toBuffer();
@@ -776,10 +780,6 @@
   /// The hash of all the paths of the files in this cycle.
   late String cyclePathsHash;
 
-  /// The ID of the ast cache entry.
-  /// It is `null` if we failed to load libraries of the cycle.
-  int? astId;
-
   /// The ID of the resolution cache entry.
   /// It is `null` if we failed to load libraries of the cycle.
   int? resolutionId;
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index c24aa37..c646953 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -794,7 +794,6 @@
     }
 
     for (var cycle in loadedBundles) {
-      addIfNotNull(cycle.astId);
       addIfNotNull(cycle.resolutionId);
     }
     loadedBundles.clear();
@@ -818,14 +817,21 @@
 
       cycle.directDependencies.forEach(loadBundle);
 
-      var astKey = '${cycle.cyclePathsHash}.ast';
       var resolutionKey = '${cycle.cyclePathsHash}.resolution';
-      var astData = byteStore.get(astKey, cycle.signature);
       var resolutionData = byteStore.get(resolutionKey, cycle.signature);
-      var astBytes = astData?.bytes;
       var resolutionBytes = resolutionData?.bytes;
 
-      if (astBytes == null || resolutionBytes == null) {
+      var unitsInformativeBytes = <Uri, Uint8List>{};
+      for (var library in cycle.libraries) {
+        for (var file in library.libraryFiles) {
+          var informativeBytes = file.informativeBytes;
+          if (informativeBytes != null) {
+            unitsInformativeBytes[file.uri] = informativeBytes;
+          }
+        }
+      }
+
+      if (resolutionBytes == null) {
         librariesLinkedTimer.start();
 
         inputsTimer.start();
@@ -872,13 +878,7 @@
         var linkResult = link2.link(elementFactory, inputLibraries, true);
         librariesLinked += cycle.libraries.length;
 
-        astBytes = linkResult.astBytes;
         resolutionBytes = linkResult.resolutionBytes;
-
-        astData = byteStore.putGet(astKey, cycle.signature, astBytes);
-        astBytes = astData.bytes;
-        performance.getDataInt('bytesPut').add(astBytes.length);
-
         resolutionData =
             byteStore.putGet(resolutionKey, cycle.signature, resolutionBytes);
         resolutionBytes = resolutionData.bytes;
@@ -886,17 +886,15 @@
 
         librariesLinkedTimer.stop();
       } else {
-        performance.getDataInt('bytesGet').add(astBytes.length);
         performance.getDataInt('bytesGet').add(resolutionBytes.length);
         performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
       }
-      cycle.astId = astData!.id;
       cycle.resolutionId = resolutionData!.id;
 
       elementFactory.addBundle(
         BundleReader(
           elementFactory: elementFactory,
-          astBytes: astBytes as Uint8List,
+          unitsInformativeBytes: unitsInformativeBytes,
           resolutionBytes: resolutionBytes as Uint8List,
         ),
       );
@@ -933,7 +931,6 @@
 
     loadedBundles.removeWhere((cycle) {
       if (cycle.libraries.any(removedSet.contains)) {
-        addIfNotNull(cycle.astId);
         addIfNotNull(cycle.resolutionId);
         return true;
       }
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index d7a2feb..1cb1091 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3120,7 +3120,7 @@
     if (withClause == null) {
       return;
     }
-    var declaredSupertype = superclassName?.type;
+    var declaredSupertype = superclassName?.type ?? _typeProvider.objectType;
     if (declaredSupertype is! InterfaceType) {
       return;
     }
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
deleted file mode 100644
index e8fd2a7..0000000
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ /dev/null
@@ -1,1598 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:math';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/exception/exception.dart';
-import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/ast_binary_tag.dart';
-import 'package:analyzer/src/summary2/bundle_reader.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/task/inference_error.dart';
-import 'package:collection/collection.dart';
-
-class ApplyResolutionVisitor extends ThrowingAstVisitor<void> {
-  final LinkedUnitContext _unitContext;
-  final LinkedResolutionReader _resolution;
-
-  /// The stack of [TypeParameterElement]s and [ParameterElement] that are
-  /// available in the scope of [_nextElement] and [_nextType].
-  ///
-  /// This stack is shared with [_resolution].
-  final List<Element> _localElements;
-
-  final List<ElementImpl> _enclosingElements = [];
-
-  ApplyResolutionVisitor(
-    this._unitContext,
-    this._localElements,
-    this._resolution,
-  ) {
-    _enclosingElements.add(_unitContext.element);
-  }
-
-  /// TODO(scheglov) make private
-  void addParentTypeParameters(AstNode node) {
-    var enclosing = node.parent;
-    if (enclosing is ClassOrMixinDeclaration) {
-      var typeParameterList = enclosing.typeParameters;
-      if (typeParameterList == null) return;
-
-      for (var typeParameter in typeParameterList.typeParameters) {
-        var element = typeParameter.declaredElement!;
-        _localElements.add(element);
-      }
-    } else if (enclosing is ExtensionDeclaration) {
-      var typeParameterList = enclosing.typeParameters;
-      if (typeParameterList == null) return;
-
-      for (var typeParameter in typeParameterList.typeParameters) {
-        var element = typeParameter.declaredElement!;
-        _localElements.add(element);
-      }
-    } else if (enclosing is VariableDeclarationList) {
-      var enclosing2 = enclosing.parent;
-      if (enclosing2 is FieldDeclaration) {
-        return addParentTypeParameters(enclosing2);
-      } else if (enclosing2 is TopLevelVariableDeclaration) {
-        return;
-      } else {
-        throw UnimplementedError('${enclosing2.runtimeType}');
-      }
-    } else {
-      throw UnimplementedError('${enclosing.runtimeType}');
-    }
-  }
-
-  @override
-  void visitAdjacentStrings(AdjacentStrings node) {
-    node.strings.accept(this);
-    // TODO(scheglov) type?
-  }
-
-  @override
-  void visitAnnotation(covariant AnnotationImpl node) {
-    _expectMarker(MarkerTag.Annotation_name);
-    node.name.accept(this);
-    _expectMarker(MarkerTag.Annotation_typeArguments);
-    node.typeArguments?.accept(this);
-    _expectMarker(MarkerTag.Annotation_constructorName);
-    node.constructorName?.accept(this);
-    _expectMarker(MarkerTag.Annotation_arguments);
-    node.arguments?.accept(this);
-    _expectMarker(MarkerTag.Annotation_element);
-    node.element = _nextElement();
-  }
-
-  @override
-  void visitArgumentList(ArgumentList node) {
-    _expectMarker(MarkerTag.ArgumentList_arguments);
-    node.arguments.accept(this);
-    _expectMarker(MarkerTag.ArgumentList_end);
-  }
-
-  @override
-  void visitAsExpression(covariant AsExpressionImpl node) {
-    _expectMarker(MarkerTag.AsExpression_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.AsExpression_type);
-    node.type.accept(this);
-    _expectMarker(MarkerTag.AsExpression_expression2);
-    _expression(node);
-    _expectMarker(MarkerTag.AsExpression_end);
-  }
-
-  @override
-  void visitAssertInitializer(AssertInitializer node) {
-    _expectMarker(MarkerTag.AssertInitializer_condition);
-    node.condition.accept(this);
-    _expectMarker(MarkerTag.AssertInitializer_message);
-    node.message?.accept(this);
-    _expectMarker(MarkerTag.AssertInitializer_end);
-  }
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var nodeImpl = node as AssignmentExpressionImpl;
-    _expectMarker(MarkerTag.AssignmentExpression_leftHandSide);
-    node.leftHandSide.accept(this);
-    _expectMarker(MarkerTag.AssignmentExpression_rightHandSide);
-    node.rightHandSide.accept(this);
-    _expectMarker(MarkerTag.AssignmentExpression_staticElement);
-    node.staticElement = _nextElement() as MethodElement?;
-    _expectMarker(MarkerTag.AssignmentExpression_readElement);
-    nodeImpl.readElement = _nextElement();
-    _expectMarker(MarkerTag.AssignmentExpression_readType);
-    nodeImpl.readType = _nextType();
-    _expectMarker(MarkerTag.AssignmentExpression_writeElement);
-    nodeImpl.writeElement = _nextElement();
-    _expectMarker(MarkerTag.AssignmentExpression_writeType);
-    nodeImpl.writeType = _nextType();
-    _expectMarker(MarkerTag.AssignmentExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.AssignmentExpression_end);
-  }
-
-  @override
-  void visitAwaitExpression(covariant AwaitExpressionImpl node) {
-    _expectMarker(MarkerTag.AwaitExpression_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.AwaitExpression_expression2);
-    _expression(node);
-    _expectMarker(MarkerTag.AwaitExpression_end);
-  }
-
-  @override
-  void visitBinaryExpression(covariant BinaryExpressionImpl node) {
-    _expectMarker(MarkerTag.BinaryExpression_leftOperand);
-    node.leftOperand.accept(this);
-    _expectMarker(MarkerTag.BinaryExpression_rightOperand);
-    node.rightOperand.accept(this);
-
-    _expectMarker(MarkerTag.BinaryExpression_staticElement);
-    node.staticElement = _nextElement() as MethodElement?;
-
-    _expectMarker(MarkerTag.BinaryExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.BinaryExpression_end);
-  }
-
-  @override
-  void visitBooleanLiteral(covariant BooleanLiteralImpl node) {
-    _expression(node);
-  }
-
-  @override
-  void visitCascadeExpression(covariant CascadeExpressionImpl node) {
-    _expectMarker(MarkerTag.CascadeExpression_target);
-    node.target.accept(this);
-    _expectMarker(MarkerTag.CascadeExpression_cascadeSections);
-    node.cascadeSections.accept(this);
-    _expectMarker(MarkerTag.CascadeExpression_end);
-    node.staticType = node.target.staticType;
-  }
-
-  @override
-  visitClassDeclaration(ClassDeclaration node) {
-    _assertNoLocalElements();
-
-    var element = node.declaredElement as ClassElementImpl;
-    element.isSimplyBounded = _resolution.readByte() != 0;
-    _enclosingElements.add(element);
-
-    try {
-      _expectMarker(MarkerTag.ClassDeclaration_typeParameters);
-      node.typeParameters?.accept(this);
-      _expectMarker(MarkerTag.ClassDeclaration_extendsClause);
-      node.extendsClause?.accept(this);
-      _expectMarker(MarkerTag.ClassDeclaration_withClause);
-      node.withClause?.accept(this);
-      _expectMarker(MarkerTag.ClassDeclaration_implementsClause);
-      node.implementsClause?.accept(this);
-      _expectMarker(MarkerTag.ClassDeclaration_nativeClause);
-      node.nativeClause?.accept(this);
-      _expectMarker(MarkerTag.ClassDeclaration_namedCompilationUnitMember);
-      _namedCompilationUnitMember(node);
-      _expectMarker(MarkerTag.ClassDeclaration_end);
-    } catch (e, stackTrace) {
-      // TODO(scheglov) Remove after fixing http://dartbug.com/44449
-      var headerStr = _astCodeBeforeMarkerOrMaxLength(node, '{', 1000);
-      throw CaughtExceptionWithFiles(e, stackTrace, {
-        'state': '''
-element: ${element.reference}
-header: $headerStr
-resolution.bytes.length: ${_resolution.bytes.length}
-resolution.byteOffset: ${_resolution.byteOffset}
-''',
-      });
-    }
-
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    _assertNoLocalElements();
-    var element = node.declaredElement as ClassElementImpl;
-    _enclosingElements.add(element);
-
-    element.isSimplyBounded = _resolution.readByte() != 0;
-    _expectMarker(MarkerTag.ClassTypeAlias_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.ClassTypeAlias_superclass);
-    node.superclass.accept(this);
-    _expectMarker(MarkerTag.ClassTypeAlias_withClause);
-    node.withClause.accept(this);
-    _expectMarker(MarkerTag.ClassTypeAlias_implementsClause);
-    node.implementsClause?.accept(this);
-    _expectMarker(MarkerTag.ClassTypeAlias_typeAlias);
-    _typeAlias(node);
-    _expectMarker(MarkerTag.ClassTypeAlias_end);
-
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitConditionalExpression(covariant ConditionalExpressionImpl node) {
-    _expectMarker(MarkerTag.ConditionalExpression_condition);
-    node.condition.accept(this);
-    _expectMarker(MarkerTag.ConditionalExpression_thenExpression);
-    node.thenExpression.accept(this);
-    _expectMarker(MarkerTag.ConditionalExpression_elseExpression);
-    node.elseExpression.accept(this);
-    _expression(node);
-  }
-
-  @override
-  void visitConfiguration(Configuration node) {
-    _expectMarker(MarkerTag.Configuration_name);
-    node.name.accept(this);
-    _expectMarker(MarkerTag.Configuration_value);
-    node.value?.accept(this);
-    _expectMarker(MarkerTag.Configuration_uri);
-    node.uri.accept(this);
-    _expectMarker(MarkerTag.Configuration_end);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    _assertNoLocalElements();
-    _pushEnclosingClassTypeParameters(node);
-
-    var element = node.declaredElement as ConstructorElementImpl;
-    _enclosingElements.add(element.enclosingElement);
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.ConstructorDeclaration_returnType);
-    node.returnType.accept(this);
-    _expectMarker(MarkerTag.ConstructorDeclaration_parameters);
-    node.parameters.accept(this);
-
-    for (var parameter in node.parameters.parameters) {
-      _localElements.add(parameter.declaredElement!);
-    }
-
-    _expectMarker(MarkerTag.ConstructorDeclaration_initializers);
-    node.initializers.accept(this);
-    _expectMarker(MarkerTag.ConstructorDeclaration_redirectedConstructor);
-    node.redirectedConstructor?.accept(this);
-    _expectMarker(MarkerTag.ConstructorDeclaration_classMember);
-    _classMember(node);
-    _expectMarker(MarkerTag.ConstructorDeclaration_end);
-
-    _enclosingElements.removeLast();
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    _expectMarker(MarkerTag.ConstructorFieldInitializer_fieldName);
-    node.fieldName.accept(this);
-    _expectMarker(MarkerTag.ConstructorFieldInitializer_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.ConstructorFieldInitializer_end);
-  }
-
-  @override
-  void visitConstructorName(covariant ConstructorNameImpl node) {
-    // Rewrite:
-    //   ConstructorName
-    //     type: TypeName
-    //       name: PrefixedIdentifier
-    //     name: null
-    // into:
-    //    ConstructorName
-    //      type: TypeName
-    //        name: SimpleIdentifier
-    //      name: SimpleIdentifier
-    var hasName = _resolution.readByte() != 0;
-    if (hasName && node.name == null) {
-      var typeName = node.type.name as PrefixedIdentifier;
-      NodeReplacer.replace(
-        node.type,
-        astFactory.typeName(typeName.prefix, null),
-      );
-      node.name = typeName.identifier;
-    }
-
-    _expectMarker(MarkerTag.ConstructorName_type);
-    node.type.accept(this);
-    _expectMarker(MarkerTag.ConstructorName_name);
-    node.name?.accept(this);
-    _expectMarker(MarkerTag.ConstructorName_staticElement);
-    node.staticElement = _nextElement() as ConstructorElement?;
-    _expectMarker(MarkerTag.ConstructorName_end);
-  }
-
-  @override
-  void visitDeclaredIdentifier(DeclaredIdentifier node) {
-    _expectMarker(MarkerTag.DeclaredIdentifier_type);
-    node.type?.accept(this);
-    _expectMarker(MarkerTag.DeclaredIdentifier_identifier);
-    // node.identifier.accept(this);
-    _expectMarker(MarkerTag.DeclaredIdentifier_declaration);
-    _declaration(node);
-    _expectMarker(MarkerTag.DeclaredIdentifier_end);
-  }
-
-  @override
-  visitDefaultFormalParameter(DefaultFormalParameter node) {
-    var nodeImpl = node as DefaultFormalParameterImpl;
-
-    var enclosing = _enclosingElements.last;
-    var name = node.identifier?.name ?? '';
-    var enclosingReference = enclosing.reference;
-    var reference = node.isNamed && enclosingReference != null
-        ? enclosingReference.getChild('@parameter').getChild(name)
-        : null;
-    ParameterElementImpl element;
-    if (node.parameter is FieldFormalParameter) {
-      element = DefaultFieldFormalParameterElementImpl.forLinkedNode(
-          enclosing, reference, node);
-    } else {
-      element =
-          DefaultParameterElementImpl.forLinkedNode(enclosing, reference, node);
-    }
-
-    var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
-    element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
-
-    _expectMarker(MarkerTag.DefaultFormalParameter_parameter);
-    node.parameter.accept(this);
-    _expectMarker(MarkerTag.DefaultFormalParameter_defaultValue);
-    node.defaultValue?.accept(this);
-    _expectMarker(MarkerTag.DefaultFormalParameter_end);
-  }
-
-  @override
-  void visitDottedName(DottedName node) {
-    node.components.accept(this);
-  }
-
-  @override
-  void visitDoubleLiteral(DoubleLiteral node) {
-    // TODO(scheglov) type?
-  }
-
-  @override
-  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    _expectMarker(MarkerTag.EnumConstantDeclaration_name);
-    _expectMarker(MarkerTag.EnumConstantDeclaration_declaration);
-    _declaration(node);
-    _expectMarker(MarkerTag.EnumConstantDeclaration_end);
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    _expectMarker(MarkerTag.EnumDeclaration_constants);
-    node.constants.accept(this);
-    _expectMarker(MarkerTag.EnumDeclaration_namedCompilationUnitMember);
-    _namedCompilationUnitMember(node);
-    _expectMarker(MarkerTag.EnumDeclaration_end);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    var elementImpl = node.element as ExportElementImpl;
-    _expectMarker(MarkerTag.ExportDirective_namespaceDirective);
-    _namespaceDirective(node);
-    _expectMarker(MarkerTag.ExportDirective_exportedLibrary);
-    elementImpl.exportedLibrary = _nextElement() as LibraryElement?;
-    _expectMarker(MarkerTag.ExportDirective_end);
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    node.expression.accept(this);
-  }
-
-  @override
-  visitExtendsClause(ExtendsClause node) {
-    _expectMarker(MarkerTag.ExtendsClause_superclass);
-    node.superclass.accept(this);
-    _expectMarker(MarkerTag.ExtendsClause_end);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    _assertNoLocalElements();
-
-    var element = node.declaredElement as ExtensionElementImpl;
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.ExtensionDeclaration_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.ExtensionDeclaration_extendedType);
-    node.extendedType.accept(this);
-    _expectMarker(MarkerTag.ExtensionDeclaration_compilationUnitMember);
-    _compilationUnitMember(node);
-    _expectMarker(MarkerTag.ExtensionDeclaration_end);
-
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitExtensionOverride(
-    ExtensionOverride node, {
-    bool readRewrite = true,
-  }) {
-    // Read possible rewrite of `MethodInvocation`.
-    // If we are here, we don't need it.
-    if (readRewrite) {
-      _resolution.readByte();
-    }
-
-    _expectMarker(MarkerTag.ExtensionOverride_extensionName);
-    node.extensionName.accept(this);
-    _expectMarker(MarkerTag.ExtensionOverride_typeArguments);
-    node.typeArguments?.accept(this);
-    _expectMarker(MarkerTag.ExtensionOverride_argumentList);
-    node.argumentList.accept(this);
-    _expectMarker(MarkerTag.ExtensionOverride_extendedType);
-    (node as ExtensionOverrideImpl).extendedType = _nextType();
-    _expectMarker(MarkerTag.ExtensionOverride_end);
-    // TODO(scheglov) typeArgumentTypes?
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    _assertNoLocalElements();
-    _pushEnclosingClassTypeParameters(node);
-
-    _expectMarker(MarkerTag.FieldDeclaration_fields);
-    node.fields.accept(this);
-    _expectMarker(MarkerTag.FieldDeclaration_classMember);
-    _classMember(node);
-    _expectMarker(MarkerTag.FieldDeclaration_end);
-  }
-
-  @override
-  void visitFieldFormalParameter(covariant FieldFormalParameterImpl node) {
-    if (node.declaredElement == null) {
-      assert(node.parent is! DefaultFormalParameter);
-      var enclosing = _enclosingElements.last;
-      var element =
-          FieldFormalParameterElementImpl.forLinkedNode(enclosing, null, node);
-      _normalFormalParameterNotDefault(node, element);
-    }
-
-    var localElementsLength = _localElements.length;
-
-    _expectMarker(MarkerTag.FieldFormalParameter_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.FieldFormalParameter_type);
-    node.type?.accept(this);
-    _expectMarker(MarkerTag.FieldFormalParameter_parameters);
-    node.parameters?.accept(this);
-    _expectMarker(MarkerTag.FieldFormalParameter_normalFormalParameter);
-    _normalFormalParameter(node);
-    _expectMarker(MarkerTag.FieldFormalParameter_end);
-
-    _localElements.length = localElementsLength;
-  }
-
-  @override
-  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
-    _expectMarker(MarkerTag.ForEachPartsWithDeclaration_loopVariable);
-    node.loopVariable.accept(this);
-    _expectMarker(MarkerTag.ForEachPartsWithDeclaration_forEachParts);
-    _forEachParts(node);
-    _expectMarker(MarkerTag.ForEachPartsWithDeclaration_end);
-  }
-
-  @override
-  void visitForElement(ForElement node) {
-    _expectMarker(MarkerTag.ForElement_forLoopParts);
-    node.forLoopParts.accept(this);
-    _expectMarker(MarkerTag.ForElement_body);
-    node.body.accept(this);
-    _expectMarker(MarkerTag.ForElement_end);
-  }
-
-  @override
-  visitFormalParameterList(FormalParameterList node) {
-    _expectMarker(MarkerTag.FormalParameterList_parameters);
-    node.parameters.accept(this);
-    _expectMarker(MarkerTag.FormalParameterList_end);
-  }
-
-  @override
-  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
-    for (var variable in node.variables.variables) {
-      variable as VariableDeclarationImpl;
-      var nameNode = variable.name;
-      nameNode.staticElement = LocalVariableElementImpl(
-        nameNode.name,
-        nameNode.offset,
-      );
-    }
-    _expectMarker(MarkerTag.ForPartsWithDeclarations_variables);
-    node.variables.accept(this);
-    _expectMarker(MarkerTag.ForPartsWithDeclarations_forParts);
-    _forParts(node);
-    _expectMarker(MarkerTag.ForPartsWithDeclarations_end);
-  }
-
-  @override
-  void visitForPartsWithExpression(ForPartsWithExpression node) {
-    _expectMarker(MarkerTag.ForPartsWithExpression_initialization);
-    node.initialization?.accept(this);
-    _expectMarker(MarkerTag.ForPartsWithExpression_forParts);
-    _forParts(node);
-    _expectMarker(MarkerTag.ForPartsWithExpression_end);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    _assertNoLocalElements();
-
-    var element = node.declaredElement as ExecutableElementImpl;
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.FunctionDeclaration_functionExpression);
-    node.functionExpression.accept(this);
-    _expectMarker(MarkerTag.FunctionDeclaration_returnType);
-    node.returnType?.accept(this);
-
-    _expectMarker(MarkerTag.FunctionDeclaration_namedCompilationUnitMember);
-    _namedCompilationUnitMember(node);
-    _expectMarker(MarkerTag.FunctionDeclaration_returnTypeType);
-    element.returnType = _nextType()!;
-    _expectMarker(MarkerTag.FunctionDeclaration_end);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    _expectMarker(MarkerTag.FunctionExpression_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.FunctionExpression_parameters);
-    node.parameters?.accept(this);
-    _expectMarker(MarkerTag.FunctionExpression_end);
-  }
-
-  @override
-  void visitFunctionExpressionInvocation(
-    covariant FunctionExpressionInvocationImpl node, {
-    bool readRewrite = true,
-  }) {
-    // Read possible rewrite of `MethodInvocation`.
-    // If we are here, we don't need it.
-    if (readRewrite) {
-      _resolution.readByte();
-    }
-
-    _expectMarker(MarkerTag.FunctionExpressionInvocation_function);
-    node.function.accept(this);
-    _expectMarker(MarkerTag.FunctionExpressionInvocation_invocationExpression);
-    _invocationExpression(node);
-    _expectMarker(MarkerTag.FunctionExpressionInvocation_end);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    _assertNoLocalElements();
-
-    var element = node.declaredElement as TypeAliasElementImpl;
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.FunctionTypeAlias_typeParameters);
-    node.typeParameters?.accept(this);
-
-    var function = element.aliasedElement as GenericFunctionTypeElementImpl;
-    _enclosingElements.add(function);
-
-    _expectMarker(MarkerTag.FunctionTypeAlias_returnType);
-    node.returnType?.accept(this);
-    _expectMarker(MarkerTag.FunctionTypeAlias_parameters);
-    node.parameters.accept(this);
-    _enclosingElements.removeLast();
-
-    _expectMarker(MarkerTag.FunctionTypeAlias_typeAlias);
-    _typeAlias(node);
-
-    _expectMarker(MarkerTag.FunctionTypeAlias_returnTypeType);
-    function.returnType = _nextType()!;
-    _expectMarker(MarkerTag.FunctionTypeAlias_flags);
-    element.isSimplyBounded = _resolution.readByte() != 0;
-    element.hasSelfReference = _resolution.readByte() != 0;
-    _expectMarker(MarkerTag.FunctionTypeAlias_end);
-
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitFunctionTypedFormalParameter(
-      covariant FunctionTypedFormalParameterImpl node) {
-    if (node.declaredElement == null) {
-      assert(node.parent is! DefaultFormalParameter);
-      var enclosing = _enclosingElements.last;
-      var element =
-          ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
-      _normalFormalParameterNotDefault(node, element);
-    }
-
-    var localElementsLength = _localElements.length;
-
-    _expectMarker(MarkerTag.FunctionTypedFormalParameter_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.FunctionTypedFormalParameter_returnType);
-    node.returnType?.accept(this);
-    _expectMarker(MarkerTag.FunctionTypedFormalParameter_parameters);
-    node.parameters.accept(this);
-    _expectMarker(MarkerTag.FunctionTypedFormalParameter_normalFormalParameter);
-    _normalFormalParameter(node);
-    _expectMarker(MarkerTag.FunctionTypedFormalParameter_end);
-
-    _localElements.length = localElementsLength;
-  }
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    var nodeImpl = node as GenericFunctionTypeImpl;
-    var localElementsLength = _localElements.length;
-
-    var element = nodeImpl.declaredElement as GenericFunctionTypeElementImpl?;
-    element ??= GenericFunctionTypeElementImpl.forLinkedNode(
-        _enclosingElements.last, null, node);
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.GenericFunctionType_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.GenericFunctionType_returnType);
-    node.returnType?.accept(this);
-    _expectMarker(MarkerTag.GenericFunctionType_parameters);
-    node.parameters.accept(this);
-    _expectMarker(MarkerTag.GenericFunctionType_type);
-    nodeImpl.type = _nextType();
-    _expectMarker(MarkerTag.GenericFunctionType_end);
-
-    _localElements.length = localElementsLength;
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    _assertNoLocalElements();
-
-    var element = node.declaredElement as TypeAliasElementImpl;
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.GenericTypeAlias_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.GenericTypeAlias_type);
-    node.type.accept(this);
-    _expectMarker(MarkerTag.GenericTypeAlias_typeAlias);
-    _typeAlias(node);
-    _expectMarker(MarkerTag.GenericTypeAlias_flags);
-    element.isSimplyBounded = _resolution.readByte() != 0;
-    element.hasSelfReference = _resolution.readByte() != 0;
-    _expectMarker(MarkerTag.GenericTypeAlias_end);
-
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    node.hiddenNames.accept(this);
-  }
-
-  @override
-  void visitIfElement(IfElement node) {
-    _expectMarker(MarkerTag.IfElement_condition);
-    node.condition.accept(this);
-    _expectMarker(MarkerTag.IfElement_thenElement);
-    node.thenElement.accept(this);
-    _expectMarker(MarkerTag.IfElement_elseElement);
-    node.elseElement?.accept(this);
-    _expectMarker(MarkerTag.IfElement_end);
-  }
-
-  @override
-  visitImplementsClause(ImplementsClause node) {
-    _expectMarker(MarkerTag.ImplementsClause_interfaces);
-    node.interfaces.accept(this);
-    _expectMarker(MarkerTag.ImplementsClause_end);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    _expectMarker(MarkerTag.ImportDirective_namespaceDirective);
-    _namespaceDirective(node);
-
-    var element = node.element as ImportElementImpl;
-    _expectMarker(MarkerTag.ImportDirective_importedLibrary);
-    element.importedLibrary = _nextElement() as LibraryElement?;
-
-    _expectMarker(MarkerTag.ImportDirective_end);
-  }
-
-  @override
-  void visitIndexExpression(covariant IndexExpressionImpl node) {
-    _expectMarker(MarkerTag.IndexExpression_target);
-    node.target?.accept(this);
-    _expectMarker(MarkerTag.IndexExpression_index);
-    node.index.accept(this);
-    _expectMarker(MarkerTag.IndexExpression_staticElement);
-    node.staticElement = _nextElement() as MethodElement?;
-    _expectMarker(MarkerTag.IndexExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.IndexExpression_end);
-  }
-
-  @override
-  void visitInstanceCreationExpression(
-    covariant InstanceCreationExpressionImpl node, {
-    bool readRewrite = true,
-  }) {
-    // Read possible rewrite of `MethodInvocation`.
-    // If we are here, we don't need it.
-    if (readRewrite) {
-      _resolution.readByte();
-    }
-
-    _expectMarker(MarkerTag.InstanceCreationExpression_constructorName);
-    node.constructorName.accept(this);
-    _expectMarker(MarkerTag.InstanceCreationExpression_argumentList);
-    node.argumentList.accept(this);
-    _expectMarker(MarkerTag.InstanceCreationExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.InstanceCreationExpression_end);
-    _resolveNamedExpressions(
-      node.constructorName.staticElement,
-      node.argumentList,
-    );
-  }
-
-  @override
-  void visitIntegerLiteral(covariant IntegerLiteralImpl node) {
-    _expression(node);
-  }
-
-  @override
-  void visitInterpolationExpression(InterpolationExpression node) {
-    node.expression.accept(this);
-  }
-
-  @override
-  void visitInterpolationString(InterpolationString node) {
-    // TODO(scheglov) type?
-  }
-
-  @override
-  void visitIsExpression(covariant IsExpressionImpl node) {
-    _expectMarker(MarkerTag.IsExpression_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.IsExpression_type);
-    node.type.accept(this);
-    _expectMarker(MarkerTag.IsExpression_expression2);
-    _expression(node);
-    _expectMarker(MarkerTag.IsExpression_end);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    node.name.accept(this);
-    _directive(node);
-  }
-
-  @override
-  void visitLibraryIdentifier(LibraryIdentifier node) {
-    node.components.accept(this);
-  }
-
-  @override
-  void visitListLiteral(covariant ListLiteralImpl node) {
-    _expectMarker(MarkerTag.ListLiteral_typeArguments);
-    node.typeArguments?.accept(this);
-    _expectMarker(MarkerTag.ListLiteral_elements);
-    node.elements.accept(this);
-    _expectMarker(MarkerTag.ListLiteral_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.ListLiteral_end);
-  }
-
-  @override
-  void visitMapLiteralEntry(MapLiteralEntry node) {
-    _expectMarker(MarkerTag.MapLiteralEntry_key);
-    node.key.accept(this);
-    _expectMarker(MarkerTag.MapLiteralEntry_value);
-    node.value.accept(this);
-  }
-
-  @override
-  visitMethodDeclaration(MethodDeclaration node) {
-    _assertNoLocalElements();
-    _pushEnclosingClassTypeParameters(node);
-
-    var element = node.declaredElement as ExecutableElementImpl;
-    _enclosingElements.add(element.enclosingElement as ElementImpl);
-    _enclosingElements.add(element);
-
-    try {
-      _expectMarker(MarkerTag.MethodDeclaration_typeParameters);
-      node.typeParameters?.accept(this);
-      _expectMarker(MarkerTag.MethodDeclaration_returnType);
-      node.returnType?.accept(this);
-      _expectMarker(MarkerTag.MethodDeclaration_parameters);
-      node.parameters?.accept(this);
-      _expectMarker(MarkerTag.MethodDeclaration_classMember);
-      _classMember(node);
-
-      _expectMarker(MarkerTag.MethodDeclaration_returnTypeType);
-      element.returnType = _nextType()!;
-      _expectMarker(MarkerTag.MethodDeclaration_inferenceError);
-      _setTopLevelInferenceError(element);
-      if (element is MethodElementImpl) {
-        _expectMarker(MarkerTag.MethodDeclaration_flags);
-        element.isOperatorEqualWithParameterTypeFromObject =
-            _resolution.readByte() != 0;
-      }
-      _expectMarker(MarkerTag.MethodDeclaration_end);
-    } catch (e, stackTrace) {
-      // TODO(scheglov) Remove after fixing http://dartbug.com/44449
-      var headerStr = _astCodeBeforeMarkerOrMaxLength(node, '{', 1000);
-      throw CaughtExceptionWithFiles(e, stackTrace, {
-        'state': '''
-element: ${element.reference}
-header: $headerStr
-resolution.bytes.length: ${_resolution.bytes.length}
-resolution.byteOffset: ${_resolution.byteOffset}
-''',
-      });
-    }
-
-    _enclosingElements.removeLast();
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitMethodInvocation(covariant MethodInvocationImpl node) {
-    var rewriteTag = _resolution.readByte();
-    if (rewriteTag == MethodInvocationRewriteTag.none) {
-      // No rewrite necessary.
-    } else if (rewriteTag == MethodInvocationRewriteTag.extensionOverride) {
-      Identifier identifier;
-      if (node.target == null) {
-        identifier = node.methodName;
-      } else {
-        identifier = astFactory.prefixedIdentifier(
-          node.target as SimpleIdentifier,
-          node.operator!,
-          node.methodName,
-        );
-      }
-      var replacement = astFactory.extensionOverride(
-        extensionName: identifier,
-        typeArguments: node.typeArguments,
-        argumentList: node.argumentList,
-      );
-      NodeReplacer.replace(node, replacement);
-      visitExtensionOverride(replacement, readRewrite: false);
-      return;
-    } else if (rewriteTag ==
-        MethodInvocationRewriteTag.functionExpressionInvocation) {
-      var target = node.target;
-      Expression expression;
-      if (target == null) {
-        expression = node.methodName;
-      } else {
-        expression = astFactory.propertyAccess(
-          target,
-          node.operator!,
-          node.methodName,
-        );
-      }
-      var replacement = astFactory.functionExpressionInvocation(
-        expression,
-        node.typeArguments,
-        node.argumentList,
-      );
-      NodeReplacer.replace(node, replacement);
-      visitFunctionExpressionInvocation(replacement, readRewrite: false);
-      return;
-    } else if (rewriteTag ==
-        MethodInvocationRewriteTag.instanceCreationExpression_withName) {
-      var replacement = astFactory.instanceCreationExpression(
-        null,
-        astFactory.constructorName(
-          astFactory.typeName(node.target as Identifier, null),
-          node.operator,
-          node.methodName,
-        ),
-        node.argumentList,
-      );
-      NodeReplacer.replace(node, replacement);
-      visitInstanceCreationExpression(replacement, readRewrite: false);
-      return;
-    } else if (rewriteTag ==
-        MethodInvocationRewriteTag.instanceCreationExpression_withoutName) {
-      var typeNameName = node.target == null
-          ? node.methodName
-          : astFactory.prefixedIdentifier(
-              node.target as SimpleIdentifier,
-              node.operator!,
-              node.methodName,
-            );
-      var replacement = astFactory.instanceCreationExpression(
-        null,
-        astFactory.constructorName(
-          astFactory.typeName(typeNameName, node.typeArguments),
-          null,
-          null,
-        ),
-        node.argumentList,
-      );
-      NodeReplacer.replace(node, replacement);
-      visitInstanceCreationExpression(replacement, readRewrite: false);
-      return;
-    } else {
-      throw StateError('[rewriteTag: $rewriteTag][node: $node]');
-    }
-
-    _expectMarker(MarkerTag.MethodInvocation_target);
-    node.target?.accept(this);
-    _expectMarker(MarkerTag.MethodInvocation_methodName);
-    node.methodName.accept(this);
-    _expectMarker(MarkerTag.MethodInvocation_invocationExpression);
-    _invocationExpression(node);
-    _expectMarker(MarkerTag.MethodInvocation_end);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    _assertNoLocalElements();
-    var element = node.declaredElement as MixinElementImpl;
-    element.isSimplyBounded = _resolution.readByte() != 0;
-    element.superInvokedNames = _resolution.readStringList();
-    _enclosingElements.add(element);
-
-    _expectMarker(MarkerTag.MixinDeclaration_typeParameters);
-    node.typeParameters?.accept(this);
-    _expectMarker(MarkerTag.MixinDeclaration_onClause);
-    node.onClause?.accept(this);
-    _expectMarker(MarkerTag.MixinDeclaration_implementsClause);
-    node.implementsClause?.accept(this);
-    _expectMarker(MarkerTag.MixinDeclaration_namedCompilationUnitMember);
-    _namedCompilationUnitMember(node);
-    _expectMarker(MarkerTag.MixinDeclaration_end);
-
-    _enclosingElements.removeLast();
-  }
-
-  @override
-  void visitNamedExpression(NamedExpression node) {
-    _expectMarker(MarkerTag.NamedExpression_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.NamedExpression_end);
-  }
-
-  @override
-  void visitNativeClause(NativeClause node) {
-    _expectMarker(MarkerTag.NativeClause_name);
-    node.name?.accept(this);
-    _expectMarker(MarkerTag.NativeClause_end);
-  }
-
-  @override
-  void visitNullLiteral(NullLiteral node) {
-    // TODO(scheglov) type?
-  }
-
-  @override
-  void visitOnClause(OnClause node) {
-    _expectMarker(MarkerTag.OnClause_superclassConstraints);
-    node.superclassConstraints.accept(this);
-    _expectMarker(MarkerTag.OnClause_end);
-  }
-
-  @override
-  void visitParenthesizedExpression(
-      covariant ParenthesizedExpressionImpl node) {
-    _expectMarker(MarkerTag.ParenthesizedExpression_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.ParenthesizedExpression_expression2);
-    _expression(node);
-    _expectMarker(MarkerTag.ParenthesizedExpression_end);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    _uriBasedDirective(node);
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    _expectMarker(MarkerTag.PartOfDirective_libraryName);
-    node.libraryName?.accept(this);
-    _expectMarker(MarkerTag.PartOfDirective_uri);
-    node.uri?.accept(this);
-    _expectMarker(MarkerTag.PartOfDirective_directive);
-    _directive(node);
-    _expectMarker(MarkerTag.PartOfDirective_end);
-  }
-
-  @override
-  void visitPostfixExpression(PostfixExpression node) {
-    var nodeImpl = node as PostfixExpressionImpl;
-    _expectMarker(MarkerTag.PostfixExpression_operand);
-    node.operand.accept(this);
-    _expectMarker(MarkerTag.PostfixExpression_staticElement);
-    node.staticElement = _nextElement() as MethodElement?;
-    if (node.operator.type.isIncrementOperator) {
-      _expectMarker(MarkerTag.PostfixExpression_readElement);
-      nodeImpl.readElement = _nextElement();
-      _expectMarker(MarkerTag.PostfixExpression_readType);
-      nodeImpl.readType = _nextType();
-      _expectMarker(MarkerTag.PostfixExpression_writeElement);
-      nodeImpl.writeElement = _nextElement();
-      _expectMarker(MarkerTag.PostfixExpression_writeType);
-      nodeImpl.writeType = _nextType();
-    }
-    _expectMarker(MarkerTag.PostfixExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.PostfixExpression_end);
-  }
-
-  @override
-  void visitPrefixedIdentifier(covariant PrefixedIdentifierImpl node) {
-    _expectMarker(MarkerTag.PrefixedIdentifier_prefix);
-    node.prefix.accept(this);
-    _expectMarker(MarkerTag.PrefixedIdentifier_identifier);
-    node.identifier.accept(this);
-    _expectMarker(MarkerTag.PrefixedIdentifier_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.PrefixedIdentifier_end);
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    var nodeImpl = node as PrefixExpressionImpl;
-    _expectMarker(MarkerTag.PrefixExpression_operand);
-    node.operand.accept(this);
-    _expectMarker(MarkerTag.PrefixExpression_staticElement);
-    node.staticElement = _nextElement() as MethodElement?;
-    if (node.operator.type.isIncrementOperator) {
-      _expectMarker(MarkerTag.PrefixExpression_readElement);
-      nodeImpl.readElement = _nextElement();
-      _expectMarker(MarkerTag.PrefixExpression_readType);
-      nodeImpl.readType = _nextType();
-      _expectMarker(MarkerTag.PrefixExpression_writeElement);
-      nodeImpl.writeElement = _nextElement();
-      _expectMarker(MarkerTag.PrefixExpression_writeType);
-      nodeImpl.writeType = _nextType();
-    }
-    _expectMarker(MarkerTag.PrefixExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.PrefixExpression_end);
-  }
-
-  @override
-  void visitPropertyAccess(covariant PropertyAccessImpl node) {
-    _expectMarker(MarkerTag.PropertyAccess_target);
-    node.target?.accept(this);
-    _expectMarker(MarkerTag.PropertyAccess_propertyName);
-    node.propertyName.accept(this);
-
-    _expectMarker(MarkerTag.PropertyAccess_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.PropertyAccess_end);
-  }
-
-  @override
-  void visitRedirectingConstructorInvocation(
-      covariant RedirectingConstructorInvocationImpl node) {
-    _expectMarker(MarkerTag.RedirectingConstructorInvocation_constructorName);
-    node.constructorName?.accept(this);
-    _expectMarker(MarkerTag.RedirectingConstructorInvocation_argumentList);
-    node.argumentList.accept(this);
-    _expectMarker(MarkerTag.RedirectingConstructorInvocation_staticElement);
-    node.staticElement = _nextElement() as ConstructorElement?;
-    _resolveNamedExpressions(node.staticElement, node.argumentList);
-    _expectMarker(MarkerTag.RedirectingConstructorInvocation_end);
-  }
-
-  @override
-  void visitSetOrMapLiteral(covariant SetOrMapLiteralImpl node) {
-    _expectMarker(MarkerTag.SetOrMapLiteral_flags);
-    var mapOrSetBits = _resolution.readByte();
-    if ((mapOrSetBits & 0x01) != 0) {
-      node.becomeMap();
-    } else if ((mapOrSetBits & 0x02) != 0) {
-      node.becomeSet();
-    }
-
-    _expectMarker(MarkerTag.SetOrMapLiteral_typeArguments);
-    node.typeArguments?.accept(this);
-    _expectMarker(MarkerTag.SetOrMapLiteral_elements);
-    node.elements.accept(this);
-    _expectMarker(MarkerTag.SetOrMapLiteral_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.SetOrMapLiteral_end);
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    node.shownNames.accept(this);
-  }
-
-  @override
-  visitSimpleFormalParameter(covariant SimpleFormalParameterImpl node) {
-    var element = node.declaredElement as ParameterElementImpl?;
-    if (element == null) {
-      assert(node.parent is! DefaultFormalParameter);
-      var enclosing = _enclosingElements.last;
-      element =
-          ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
-      _normalFormalParameterNotDefault(node, element);
-    }
-
-    _expectMarker(MarkerTag.SimpleFormalParameter_type);
-    node.type?.accept(this);
-    _expectMarker(MarkerTag.SimpleFormalParameter_normalFormalParameter);
-    _normalFormalParameter(node);
-
-    _expectMarker(MarkerTag.SimpleFormalParameter_flags);
-    element.inheritsCovariant = _resolution.readByte() != 0;
-    _expectMarker(MarkerTag.SimpleFormalParameter_end);
-  }
-
-  @override
-  visitSimpleIdentifier(covariant SimpleIdentifierImpl node) {
-    _expectMarker(MarkerTag.SimpleIdentifier_staticElement);
-    node.staticElement = _nextElement();
-    _expectMarker(MarkerTag.SimpleIdentifier_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.SimpleIdentifier_end);
-  }
-
-  @override
-  void visitSimpleStringLiteral(SimpleStringLiteral node) {
-    // TODO(scheglov) type?
-  }
-
-  @override
-  void visitSpreadElement(SpreadElement node) {
-    _expectMarker(MarkerTag.SpreadElement_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.SpreadElement_end);
-  }
-
-  @override
-  void visitStringInterpolation(StringInterpolation node) {
-    _expectMarker(MarkerTag.StringInterpolation_elements);
-    node.elements.accept(this);
-    _expectMarker(MarkerTag.StringInterpolation_end);
-    // TODO(scheglov) type?
-  }
-
-  @override
-  void visitSuperConstructorInvocation(
-      covariant SuperConstructorInvocationImpl node) {
-    _expectMarker(MarkerTag.SuperConstructorInvocation_constructorName);
-    node.constructorName?.accept(this);
-    _expectMarker(MarkerTag.SuperConstructorInvocation_argumentList);
-    node.argumentList.accept(this);
-    _expectMarker(MarkerTag.SuperConstructorInvocation_staticElement);
-    node.staticElement = _nextElement() as ConstructorElement?;
-    _resolveNamedExpressions(node.staticElement, node.argumentList);
-    _expectMarker(MarkerTag.SuperConstructorInvocation_end);
-  }
-
-  @override
-  void visitSuperExpression(covariant SuperExpressionImpl node) {
-    _expectMarker(MarkerTag.SuperExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.SuperExpression_end);
-  }
-
-  @override
-  void visitSymbolLiteral(covariant SymbolLiteralImpl node) {
-    _expression(node);
-  }
-
-  @override
-  void visitThisExpression(covariant ThisExpressionImpl node) {
-    _expectMarker(MarkerTag.ThisExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.ThisExpression_end);
-  }
-
-  @override
-  void visitThrowExpression(covariant ThrowExpressionImpl node) {
-    _expectMarker(MarkerTag.ThrowExpression_expression);
-    node.expression.accept(this);
-    _expectMarker(MarkerTag.ThrowExpression_expression2);
-    _expression(node);
-    _expectMarker(MarkerTag.ThrowExpression_end);
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _expectMarker(MarkerTag.TopLevelVariableDeclaration_variables);
-    node.variables.accept(this);
-    _expectMarker(MarkerTag.TopLevelVariableDeclaration_compilationUnitMember);
-    _compilationUnitMember(node);
-    _expectMarker(MarkerTag.TopLevelVariableDeclaration_end);
-  }
-
-  @override
-  visitTypeArgumentList(TypeArgumentList node) {
-    _expectMarker(MarkerTag.TypeArgumentList_arguments);
-    node.arguments.accept(this);
-    _expectMarker(MarkerTag.TypeArgumentList_end);
-  }
-
-  @override
-  visitTypeName(covariant TypeNameImpl node) {
-    _expectMarker(MarkerTag.TypeName_name);
-    node.name.accept(this);
-    _expectMarker(MarkerTag.TypeName_typeArguments);
-    node.typeArguments?.accept(this);
-
-    _expectMarker(MarkerTag.TypeName_type);
-    node.type = _nextType();
-
-    _expectMarker(MarkerTag.TypeName_end);
-  }
-
-  @override
-  visitTypeParameterList(TypeParameterList node) {
-    for (var typeParameter in node.typeParameters) {
-      typeParameter as TypeParameterImpl;
-      var element = TypeParameterElementImpl.forLinkedNode(
-        _enclosingElements.last,
-        typeParameter,
-      );
-      _localElements.add(element);
-    }
-
-    _expectMarker(MarkerTag.TypeParameterList_typeParameters);
-    for (var node in node.typeParameters) {
-      var nodeImpl = node as TypeParameterImpl;
-      var element = node.declaredElement as TypeParameterElementImpl;
-
-      var summaryData = nodeImpl.summaryData as SummaryDataForTypeParameter;
-      element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
-
-      _expectMarker(MarkerTag.TypeParameter_bound);
-      node.bound?.accept(this);
-      element.bound = node.bound?.type;
-
-      _expectMarker(MarkerTag.TypeParameter_declaration);
-      _declaration(node);
-      element.metadata = _buildAnnotations(
-        _unitContext.element,
-        node.metadata,
-      );
-
-      _expectMarker(MarkerTag.TypeParameter_variance);
-      element.variance = _decodeVariance(_resolution.readByte());
-      _expectMarker(MarkerTag.TypeParameter_defaultType);
-      element.defaultType = _nextType();
-      _expectMarker(MarkerTag.TypeParameter_end);
-
-      // TODO(scheglov) We used to do this with the previous elements impl.
-      // We probably still do this.
-      // But the code below is bad and incomplete.
-      // And why does this affect MethodMember(s)?
-      {
-        var parent = node.parent;
-        if (parent is ClassDeclaration) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        } else if (parent is ClassTypeAlias) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        } else if (parent is ExtensionDeclaration) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        } else if (parent is FunctionExpression) {
-          var parent2 = parent.parent;
-          if (parent2 is FunctionDeclaration) {
-            (parent2.declaredElement as ElementImpl).encloseElement(element);
-          }
-        } else if (parent is FunctionTypeAlias) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        } else if (parent is GenericTypeAlias) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        } else if (parent is MethodDeclaration) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        } else if (parent is MixinDeclaration) {
-          (parent.declaredElement as ElementImpl).encloseElement(element);
-        }
-      }
-    }
-    _expectMarker(MarkerTag.TypeParameterList_end);
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    var element = node.declaredElement as VariableElementImpl;
-    _expectMarker(MarkerTag.VariableDeclaration_type);
-    element.type = _nextType()!;
-    _expectMarker(MarkerTag.VariableDeclaration_inferenceError);
-    _setTopLevelInferenceError(element);
-    if (element is FieldElementImpl) {
-      _expectMarker(MarkerTag.VariableDeclaration_inheritsCovariant);
-      element.inheritsCovariant = _resolution.readByte() != 0;
-    }
-
-    _expectMarker(MarkerTag.VariableDeclaration_initializer);
-    node.initializer?.accept(this);
-    _expectMarker(MarkerTag.VariableDeclaration_end);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    _expectMarker(MarkerTag.VariableDeclarationList_type);
-    node.type?.accept(this);
-    _expectMarker(MarkerTag.VariableDeclarationList_variables);
-    node.variables.accept(this);
-    _expectMarker(MarkerTag.VariableDeclarationList_annotatedNode);
-    _annotatedNode(node);
-    _expectMarker(MarkerTag.VariableDeclarationList_end);
-  }
-
-  @override
-  void visitWithClause(WithClause node) {
-    _expectMarker(MarkerTag.WithClause_mixinTypes);
-    node.mixinTypes.accept(this);
-    _expectMarker(MarkerTag.WithClause_end);
-  }
-
-  void _annotatedNode(AnnotatedNode node) {
-    _expectMarker(MarkerTag.AnnotatedNode_metadata);
-    node.metadata.accept(this);
-    _expectMarker(MarkerTag.AnnotatedNode_end);
-  }
-
-  void _assertNoLocalElements() {
-    assert(_localElements.isEmpty);
-    assert(_enclosingElements.length == 1 &&
-        _enclosingElements.first is CompilationUnitElement);
-  }
-
-  /// Return annotations for the given [nodeList] in the [unit].
-  List<ElementAnnotation> _buildAnnotations(
-      CompilationUnitElementImpl unit, List<Annotation> nodeList) {
-    var length = nodeList.length;
-    if (length == 0) {
-      return const <ElementAnnotation>[];
-    }
-
-    return List.generate(length, (index) {
-      var ast = nodeList[index];
-      return ElementAnnotationImpl(unit)
-        ..annotationAst = ast
-        ..element = ast.element;
-    });
-  }
-
-  void _classMember(ClassMember node) {
-    _expectMarker(MarkerTag.ClassMember_declaration);
-    _declaration(node);
-  }
-
-  void _compilationUnitMember(CompilationUnitMember node) {
-    _declaration(node);
-  }
-
-  void _declaration(Declaration node) {
-    _annotatedNode(node);
-  }
-
-  void _directive(Directive node) {
-    _annotatedNode(node);
-  }
-
-  void _expectMarker(MarkerTag tag) {
-    if (enableDebugResolutionMarkers) {
-      var actualIndex = _resolution.readUInt30();
-      if (actualIndex != tag.index) {
-        if (actualIndex < MarkerTag.values.length) {
-          var actualTag = MarkerTag.values[actualIndex];
-          throw StateError('Expected $tag, found $actualIndex = $actualTag');
-        } else {
-          throw StateError('Expected $tag, found $actualIndex');
-        }
-      }
-    }
-  }
-
-  void _expression(ExpressionImpl node) {
-    _expectMarker(MarkerTag.Expression_staticType);
-    node.staticType = _nextType();
-  }
-
-  void _forEachParts(ForEachParts node) {
-    _expectMarker(MarkerTag.ForEachParts_iterable);
-    node.iterable.accept(this);
-    _expectMarker(MarkerTag.ForEachParts_forLoopParts);
-    _forLoopParts(node);
-    _expectMarker(MarkerTag.ForEachParts_end);
-  }
-
-  void _forLoopParts(ForLoopParts node) {}
-
-  void _formalParameter(FormalParameter node) {
-    _expectMarker(MarkerTag.FormalParameter_type);
-    (node.declaredElement as ParameterElementImpl).type = _nextType()!;
-  }
-
-  void _forParts(ForParts node) {
-    _expectMarker(MarkerTag.ForParts_condition);
-    node.condition?.accept(this);
-    _expectMarker(MarkerTag.ForParts_updaters);
-    node.updaters.accept(this);
-    _expectMarker(MarkerTag.ForParts_forLoopParts);
-    _forLoopParts(node);
-    _expectMarker(MarkerTag.ForParts_end);
-  }
-
-  void _invocationExpression(covariant InvocationExpressionImpl node) {
-    _expectMarker(MarkerTag.InvocationExpression_typeArguments);
-    node.typeArguments?.accept(this);
-    _expectMarker(MarkerTag.InvocationExpression_argumentList);
-    node.argumentList.accept(this);
-    _expectMarker(MarkerTag.InvocationExpression_expression);
-    _expression(node);
-    _expectMarker(MarkerTag.InvocationExpression_end);
-    // TODO(scheglov) typeArgumentTypes and staticInvokeType?
-    var nodeImpl = node;
-    nodeImpl.typeArgumentTypes = [];
-  }
-
-  void _namedCompilationUnitMember(NamedCompilationUnitMember node) {
-    _compilationUnitMember(node);
-  }
-
-  void _namespaceDirective(NamespaceDirective node) {
-    _expectMarker(MarkerTag.NamespaceDirective_combinators);
-    node.combinators.accept(this);
-    _expectMarker(MarkerTag.NamespaceDirective_configurations);
-    node.configurations.accept(this);
-    _expectMarker(MarkerTag.NamespaceDirective_uriBasedDirective);
-    _uriBasedDirective(node);
-    _expectMarker(MarkerTag.NamespaceDirective_end);
-  }
-
-  Element? _nextElement() {
-    return _resolution.nextElement();
-  }
-
-  DartType? _nextType() {
-    return _resolution.nextType();
-  }
-
-  void _normalFormalParameter(NormalFormalParameter node) {
-    _expectMarker(MarkerTag.NormalFormalParameter_metadata);
-    node.metadata.accept(this);
-    _expectMarker(MarkerTag.NormalFormalParameter_formalParameter);
-    _formalParameter(node);
-    _expectMarker(MarkerTag.NormalFormalParameter_end);
-  }
-
-  void _normalFormalParameterNotDefault(
-      NormalFormalParameter node, ParameterElementImpl element) {
-    var nodeImpl = node as NormalFormalParameterImpl;
-    var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
-    element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
-  }
-
-  /// TODO(scheglov) also enclosing elements
-  void _pushEnclosingClassTypeParameters(ClassMember node) {
-    var parent = node.parent;
-    if (parent is ClassOrMixinDeclaration) {
-      var classElement = parent.declaredElement!;
-      _localElements.addAll(classElement.typeParameters);
-    } else {
-      var extension = parent as ExtensionDeclaration;
-      var classElement = extension.declaredElement!;
-      _localElements.addAll(classElement.typeParameters);
-    }
-  }
-
-  TopLevelInferenceError? _readTopLevelInferenceError() {
-    var kindIndex = _resolution.readByte();
-    var kind = TopLevelInferenceErrorKind.values[kindIndex];
-    if (kind == TopLevelInferenceErrorKind.none) {
-      return null;
-    }
-    return TopLevelInferenceError(
-      kind: kind,
-      arguments: _resolution.readStringList(),
-    );
-  }
-
-  void _resolveNamedExpressions(
-    Element? executable,
-    ArgumentList argumentList,
-  ) {
-    for (var argument in argumentList.arguments) {
-      if (argument is NamedExpressionImpl) {
-        var nameNode = argument.name.label;
-        if (executable is ExecutableElement) {
-          var parameters = executable.parameters;
-          var name = nameNode.name;
-          nameNode.staticElement = parameters.firstWhereOrNull((e) {
-            return e.name == name;
-          });
-        }
-      }
-    }
-  }
-
-  void _setTopLevelInferenceError(ElementImpl element) {
-    if (element is MethodElementImpl) {
-      element.typeInferenceError = _readTopLevelInferenceError();
-    } else if (element is PropertyInducingElementImpl) {
-      element.typeInferenceError = _readTopLevelInferenceError();
-    }
-  }
-
-  void _typeAlias(TypeAlias node) {
-    _namedCompilationUnitMember(node);
-  }
-
-  void _uriBasedDirective(UriBasedDirective node) {
-    _expectMarker(MarkerTag.UriBasedDirective_uri);
-    node.uri.accept(this);
-    _expectMarker(MarkerTag.UriBasedDirective_directive);
-    _directive(node);
-    _expectMarker(MarkerTag.UriBasedDirective_end);
-  }
-
-  /// TODO(scheglov) Remove after fixing http://dartbug.com/44449
-  static String _astCodeBeforeMarkerOrMaxLength(
-      AstNode node, String marker, int maxLength) {
-    var nodeStr = '$node';
-    var indexOfBody = nodeStr.indexOf(marker);
-    if (indexOfBody == -1) {
-      indexOfBody = min(maxLength, nodeStr.length);
-    }
-    return nodeStr.substring(0, indexOfBody);
-  }
-
-  static Variance? _decodeVariance(int encoding) {
-    if (encoding == 0) {
-      return null;
-    } else if (encoding == 1) {
-      return Variance.unrelated;
-    } else if (encoding == 2) {
-      return Variance.covariant;
-    } else if (encoding == 3) {
-      return Variance.contravariant;
-    } else if (encoding == 4) {
-      return Variance.invariant;
-    } else {
-      throw UnimplementedError('encoding: $encoding');
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index ab2b7b2..a9db47d 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:typed_data';
-
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
@@ -16,18 +16,15 @@
 import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+import 'package:collection/collection.dart';
 
 /// Deserializer of ASTs.
 class AstBinaryReader {
-  static final _noDocumentationComment = Uint32List(0);
-
-  final UnitReader _unitReader;
-  final bool _withInformative;
+  final ResolutionReader _reader;
 
   AstBinaryReader({
-    required UnitReader reader,
-  })   : _unitReader = reader,
-        _withInformative = reader.withInformative;
+    required ResolutionReader reader,
+  }) : _reader = reader;
 
   AstNode readNode() {
     var tag = _readByte();
@@ -52,16 +49,10 @@
         return _readBooleanLiteral();
       case Tag.CascadeExpression:
         return _readCascadeExpression();
-      case Tag.Class:
-        return _readClassDeclaration();
-      case Tag.ClassTypeAlias:
-        return _readClassTypeAlias();
       case Tag.ConditionalExpression:
         return _readConditionalExpression();
       case Tag.Configuration:
         return _readConfiguration();
-      case Tag.ConstructorDeclaration:
-        return _readConstructorDeclaration();
       case Tag.ConstructorFieldInitializer:
         return _readConstructorFieldInitializer();
       case Tag.ConstructorName:
@@ -74,20 +65,8 @@
         return _readDottedName();
       case Tag.DoubleLiteral:
         return _readDoubleLiteral();
-      case Tag.EnumConstantDeclaration:
-        return _readEnumConstantDeclaration();
-      case Tag.EnumDeclaration:
-        return _readEnumDeclaration();
-      case Tag.ExportDirective:
-        return _readExportDirective();
-      case Tag.ExtendsClause:
-        return _readExtendsClause();
-      case Tag.ExtensionDeclaration:
-        return _readExtensionDeclaration();
       case Tag.ExtensionOverride:
         return _readExtensionOverride();
-      case Tag.FieldDeclaration:
-        return _readFieldDeclaration();
       case Tag.ForEachPartsWithDeclaration:
         return _readForEachPartsWithDeclaration();
       case Tag.ForElement:
@@ -100,22 +79,14 @@
         return _readFieldFormalParameter();
       case Tag.FormalParameterList:
         return _readFormalParameterList();
-      case Tag.FunctionDeclaration:
-        return _readFunctionDeclaration();
       case Tag.FunctionExpression:
         return _readFunctionExpression();
       case Tag.FunctionExpressionInvocation:
         return _readFunctionExpressionInvocation();
-      case Tag.FunctionTypeAlias:
-        return _readFunctionTypeAlias();
       case Tag.FunctionTypedFormalParameter:
         return _readFunctionTypedFormalParameter();
       case Tag.GenericFunctionType:
         return _readGenericFunctionType();
-      case Tag.GenericTypeAlias:
-        return _readGenericTypeAlias();
-      case Tag.HideCombinator:
-        return _readHideCombinator();
       case Tag.IfElement:
         return _readIfElement();
       case Tag.ImplementsClause:
@@ -138,16 +109,12 @@
         return _readInterpolationString();
       case Tag.IsExpression:
         return _readIsExpression();
-      case Tag.LibraryDirective:
-        return _readLibraryDirective();
-      case Tag.LibraryIdentifier:
-        return _readLibraryIdentifier();
+      case Tag.Label:
+        return _readLabel();
       case Tag.ListLiteral:
         return _readListLiteral();
       case Tag.MapLiteralEntry:
         return _readMapLiteralEntry();
-      case Tag.MethodDeclaration:
-        return _readMethodDeclaration();
       case Tag.MixinDeclaration:
         return _readMixinDeclaration();
       case Tag.MethodInvocation:
@@ -160,16 +127,10 @@
         return _readNullLiteral();
       case Tag.OnClause:
         return _readOnClause();
-      case Tag.ImportDirective:
-        return _readImportDirective();
       case Tag.InstanceCreationExpression:
         return _readInstanceCreationExpression();
       case Tag.ParenthesizedExpression:
         return _readParenthesizedExpression();
-      case Tag.PartDirective:
-        return _readPartDirective();
-      case Tag.PartOfDirective:
-        return _readPartOfDirective();
       case Tag.PostfixExpression:
         return _readPostfixExpression();
       case Tag.PrefixExpression:
@@ -182,8 +143,6 @@
         return _readRedirectingConstructorInvocation();
       case Tag.SetOrMapLiteral:
         return _readSetOrMapLiteral();
-      case Tag.ShowCombinator:
-        return _readShowCombinator();
       case Tag.SimpleFormalParameter:
         return _readSimpleFormalParameter();
       case Tag.SimpleIdentifier:
@@ -212,8 +171,6 @@
         return _readTypeParameter();
       case Tag.TypeParameterList:
         return _readTypeParameterList();
-      case Tag.TopLevelVariableDeclaration:
-        return _readTopLevelVariableDeclaration();
       case Tag.VariableDeclaration:
         return _readVariableDeclaration();
       case Tag.VariableDeclarationList:
@@ -227,10 +184,12 @@
 
   IntegerLiteral _createIntegerLiteral(int value) {
     // TODO(scheglov) Write token?
-    return astFactory.integerLiteral(
+    var node = astFactory.integerLiteral(
       TokenFactory.tokenFromTypeAndString(TokenType.INT, '$value'),
       value,
     );
+    _readExpressionResolution(node);
+    return node;
   }
 
   FunctionBody _functionBodyForFlags(int flags) {
@@ -261,7 +220,7 @@
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var constructorName = _readOptionalNode() as SimpleIdentifier?;
     var arguments = _readOptionalNode() as ArgumentList?;
-    return astFactory.annotation(
+    var node = astFactory.annotation(
       atSign: Tokens.AT,
       name: name,
       typeArguments: typeArguments,
@@ -269,6 +228,8 @@
       constructorName: constructorName,
       arguments: arguments,
     );
+    node.element = _reader.readElement();
+    return node;
   }
 
   ArgumentList _readArgumentList() {
@@ -284,7 +245,9 @@
   AsExpression _readAsExpression() {
     var expression = readNode() as Expression;
     var type = readNode() as TypeAnnotation;
-    return astFactory.asExpression(expression, Tokens.AS, type);
+    var node = astFactory.asExpression(expression, Tokens.AS, type);
+    _readExpressionResolution(node);
+    return node;
   }
 
   AssertInitializer _readAssertInitializer() {
@@ -304,11 +267,18 @@
     var leftHandSide = readNode() as Expression;
     var rightHandSide = readNode() as Expression;
     var operatorType = UnlinkedTokenType.values[_readByte()];
-    return astFactory.assignmentExpression(
+    var node = astFactory.assignmentExpression(
       leftHandSide,
       Tokens.fromType(operatorType),
       rightHandSide,
     );
+    node.staticElement = _reader.readElement() as MethodElement?;
+    node.readElement = _reader.readElement();
+    node.readType = _reader.readType();
+    node.writeElement = _reader.readElement();
+    node.writeType = _reader.readType();
+    _readExpressionResolution(node);
+    return node;
   }
 
   AwaitExpression _readAwaitExpression() {
@@ -320,110 +290,32 @@
     var leftOperand = readNode() as Expression;
     var rightOperand = readNode() as Expression;
     var operatorType = UnlinkedTokenType.values[_readByte()];
-    return astFactory.binaryExpression(
+    var node = astFactory.binaryExpression(
       leftOperand,
       Tokens.fromType(operatorType),
       rightOperand,
     );
+    node.staticElement = _reader.readElement() as MethodElement?;
+    _readExpressionResolution(node);
+    return node;
   }
 
   BooleanLiteral _readBooleanLiteral() {
     var value = _readByte() == 1;
-    // TODO(scheglov) type?
-    return AstTestFactory.booleanLiteral(value);
+    var node = AstTestFactory.booleanLiteral(value);
+    _readExpressionResolution(node);
+    return node;
   }
 
   int _readByte() {
-    return _unitReader.astReader.readByte();
+    return _reader.readByte();
   }
 
   CascadeExpression _readCascadeExpression() {
     var target = readNode() as Expression;
     var sections = _readNodeList<Expression>();
-    return astFactory.cascadeExpression(target, sections);
-  }
-
-  ClassDeclaration _readClassDeclaration() {
-    var flags = _readByte();
-
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var extendsClause = _readOptionalNode() as ExtendsClause?;
-    var withClause = _readOptionalNode() as WithClause?;
-    var implementsClause = _readOptionalNode() as ImplementsClause?;
-    var nativeClause = _readOptionalNode() as NativeClause?;
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.classDeclaration(
-      null,
-      metadata,
-      AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
-      Tokens.CLASS,
-      name,
-      typeParameters,
-      extendsClause,
-      withClause,
-      implementsClause,
-      Tokens.OPEN_CURLY_BRACKET,
-      const <ClassMember>[],
-      Tokens.CLOSE_CURLY_BRACKET,
-    );
-    node.nativeClause = nativeClause;
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      isClassWithConstConstructor: AstBinaryFlags.hasConstConstructor(flags),
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
-    return node;
-  }
-
-  ClassTypeAlias _readClassTypeAlias() {
-    var flags = _readByte();
-
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var superClass = readNode() as TypeName;
-    var withClause = readNode() as WithClause;
-    var implementsClause = _readOptionalNode() as ImplementsClause?;
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-    var documentationTokenIndexList = _readUint30List();
-
-    var node = astFactory.classTypeAlias(
-      null,
-      metadata,
-      Tokens.CLASS,
-      name,
-      typeParameters,
-      Tokens.EQ,
-      AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
-      superClass,
-      withClause,
-      implementsClause,
-      Tokens.SEMICOLON,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
+    var node = astFactory.cascadeExpression(target, sections);
+    node.staticType = target.staticType;
     return node;
   }
 
@@ -431,13 +323,15 @@
     var condition = readNode() as Expression;
     var thenExpression = readNode() as Expression;
     var elseExpression = readNode() as Expression;
-    return astFactory.conditionalExpression(
+    var node = astFactory.conditionalExpression(
       condition,
       Tokens.QUESTION,
       thenExpression,
       Tokens.COLON,
       elseExpression,
     );
+    _readExpressionResolution(node);
+    return node;
   }
 
   Configuration _readConfiguration() {
@@ -456,61 +350,6 @@
     );
   }
 
-  ConstructorDeclaration _readConstructorDeclaration() {
-    var flags = _readByte();
-
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var returnType = readNode() as SimpleIdentifier;
-
-    Token? period;
-    SimpleIdentifier? name;
-    if (AstBinaryFlags.hasName(flags)) {
-      var periodOffset = _readInformativeUint30();
-      period = Token(TokenType.PERIOD, periodOffset);
-      name = readNode() as SimpleIdentifier;
-    }
-
-    var parameters = readNode() as FormalParameterList;
-    var initializers = _readNodeList<ConstructorInitializer>();
-    var redirectedConstructor = _readOptionalNode() as ConstructorName?;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.constructorDeclaration(
-      null,
-      metadata,
-      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
-      AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
-      AstBinaryFlags.isFactory(flags) ? Tokens.FACTORY : null,
-      returnType,
-      period,
-      name,
-      parameters,
-      Tokens.choose(
-        AstBinaryFlags.hasSeparatorColon(flags),
-        Tokens.COLON,
-        AstBinaryFlags.hasSeparatorEquals(flags),
-        Tokens.EQ,
-      ),
-      initializers,
-      redirectedConstructor,
-      AstTestFactory.emptyFunctionBody(),
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
-    return node;
-  }
-
   ConstructorFieldInitializer _readConstructorFieldInitializer() {
     var flags = _readByte();
     var fieldName = readNode() as SimpleIdentifier;
@@ -529,17 +368,27 @@
     var type = readNode() as TypeName;
     var name = _readOptionalNode() as SimpleIdentifier?;
 
-    return astFactory.constructorName(
+    var node = astFactory.constructorName(
       type,
       name != null ? Tokens.PERIOD : null,
       name,
     );
+    node.staticElement = _reader.readElement() as ConstructorElement?;
+    return node;
+  }
+
+  SimpleIdentifier _readDeclarationName() {
+    var name = _reader.readStringReference();
+    var node = astFactory.simpleIdentifier(
+      StringToken(TokenType.STRING, name, -1),
+    );
+    return node;
   }
 
   DeclaredIdentifier _readDeclaredIdentifier() {
     var flags = _readByte();
     var type = _readOptionalNode() as TypeAnnotation?;
-    var identifier = readNode() as SimpleIdentifier;
+    var identifier = _readDeclarationName();
     var metadata = _readNodeList<Annotation>();
     return astFactory.declaredIdentifier(
       null,
@@ -559,8 +408,6 @@
 
   DefaultFormalParameter _readDefaultFormalParameter() {
     var flags = _readByte();
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
     var parameter = readNode() as NormalFormalParameter;
     var defaultValue = _readOptionalNode() as Expression?;
 
@@ -581,10 +428,6 @@
       AstBinaryFlags.hasInitializer(flags) ? Tokens.COLON : null,
       defaultValue,
     );
-    node.summaryData = SummaryDataForFormalParameter(
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-    );
 
     return node;
   }
@@ -595,174 +438,26 @@
   }
 
   DoubleLiteral _readDoubleLiteral() {
-    var value = _unitReader.astReader.readDouble();
-    return AstTestFactory.doubleLiteral(value);
-  }
-
-  EnumConstantDeclaration _readEnumConstantDeclaration() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.enumConstantDeclaration(null, metadata, name);
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
+    var value = _reader.readDouble();
+    var node = AstTestFactory.doubleLiteral(value);
+    _readExpressionResolution(node);
     return node;
   }
 
-  EnumDeclaration _readEnumDeclaration() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var constants = _readNodeList<EnumConstantDeclaration>();
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.enumDeclaration(
-      null,
-      metadata,
-      Tokens.ENUM,
-      name,
-      Tokens.OPEN_CURLY_BRACKET,
-      constants,
-      Tokens.CLOSE_CURLY_BRACKET,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
-    return node;
-  }
-
-  ExportDirective _readExportDirective() {
-    var combinators = _readNodeList<Combinator>();
-    var configurations = _readNodeList<Configuration>();
-    var uri = readNode() as StringLiteral;
-    var keywordOffset = _readInformativeUint30();
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.exportDirective(
-      null,
-      metadata,
-      KeywordToken(Keyword.EXPORT, keywordOffset),
-      uri,
-      configurations,
-      combinators,
-      Tokens.SEMICOLON,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: -1,
-      codeLength: 0,
-      documentationTokenIndexList: _noDocumentationComment,
-      resolutionIndex: _readUInt30(),
-    );
-
-    return node;
-  }
-
-  ExtendsClause _readExtendsClause() {
-    var type = readNode() as TypeName;
-    return astFactory.extendsClause(Tokens.EXTENDS, type);
-  }
-
-  ExtensionDeclaration _readExtensionDeclaration() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var extendedType = readNode() as TypeAnnotation;
-    var name = _readOptionalNode() as SimpleIdentifier?;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.extensionDeclaration(
-      comment: null,
-      metadata: metadata,
-      extensionKeyword: Tokens.EXTENSION,
-      name: name,
-      typeParameters: typeParameters,
-      onKeyword: Tokens.ON,
-      extendedType: extendedType,
-      leftBracket: Tokens.OPEN_CURLY_BRACKET,
-      members: const <ClassMember>[],
-      rightBracket: Tokens.CLOSE_CURLY_BRACKET,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
-    return node;
+  void _readExpressionResolution(ExpressionImpl node) {
+    node.staticType = _reader.readType();
   }
 
   ExtensionOverride _readExtensionOverride() {
     var extensionName = readNode() as Identifier;
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var argumentList = readNode() as ArgumentList;
-    return astFactory.extensionOverride(
+    var node = astFactory.extensionOverride(
       extensionName: extensionName,
       argumentList: argumentList,
       typeArguments: typeArguments,
     );
-  }
-
-  FieldDeclaration _readFieldDeclaration() {
-    var flags = _readByte();
-    var codeOffsetLengthList = _readInformativeUint30List();
-    var documentationTokenIndexList = _readUint30List();
-    var fields = readNode() as VariableDeclarationList;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.fieldDeclaration2(
-      comment: null,
-      abstractKeyword:
-          AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
-      covariantKeyword:
-          AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
-      externalKeyword:
-          AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
-      fieldList: fields,
-      metadata: metadata,
-      semicolon: Tokens.SEMICOLON,
-      staticKeyword: AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: -1,
-      codeLength: 0,
-      codeOffsetLengthList: codeOffsetLengthList,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
+    _readExpressionResolution(node);
     return node;
   }
 
@@ -771,8 +466,6 @@
     var type = _readOptionalNode() as TypeAnnotation?;
     var formalParameters = _readOptionalNode() as FormalParameterList?;
     var flags = _readByte();
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
     var metadata = _readNodeList<Annotation>();
     var identifier = readNode() as SimpleIdentifier;
     var node = astFactory.fieldFormalParameter2(
@@ -798,10 +491,6 @@
       requiredKeyword:
           AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
     );
-    node.summaryData = SummaryDataForFormalParameter(
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-    );
     return node;
   }
 
@@ -878,43 +567,6 @@
     );
   }
 
-  FunctionDeclaration _readFunctionDeclaration() {
-    var flags = _readByte();
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-    var functionExpression = readNode() as FunctionExpression;
-    var returnType = _readOptionalNode() as TypeAnnotation?;
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.functionDeclaration(
-      null,
-      metadata,
-      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
-      returnType,
-      Tokens.choose(
-        AstBinaryFlags.isGet(flags),
-        Tokens.GET,
-        AstBinaryFlags.isSet(flags),
-        Tokens.SET,
-      ),
-      name,
-      functionExpression,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
-    return node;
-  }
-
   FunctionExpression _readFunctionExpression() {
     var flags = _readByte();
     var typeParameters = _readOptionalNode() as TypeParameterList?;
@@ -932,44 +584,12 @@
     var function = readNode() as Expression;
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var arguments = readNode() as ArgumentList;
-    return astFactory.functionExpressionInvocation(
+    var node = astFactory.functionExpressionInvocation(
       function,
       typeArguments,
       arguments,
     );
-  }
-
-  FunctionTypeAlias _readFunctionTypeAlias() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var returnType = _readOptionalNode() as TypeAnnotation?;
-    var formalParameters = readNode() as FormalParameterList;
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.functionTypeAlias(
-      null,
-      metadata,
-      Tokens.TYPEDEF,
-      returnType,
-      name,
-      typeParameters,
-      formalParameters,
-      Tokens.SEMICOLON,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
+    _readExpressionResolution(node);
     return node;
   }
 
@@ -978,8 +598,6 @@
     var returnType = _readOptionalNode() as TypeAnnotation?;
     var formalParameters = readNode() as FormalParameterList;
     var flags = _readByte();
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
     var metadata = _readNodeList<Annotation>();
     var identifier = readNode() as SimpleIdentifier;
     var node = astFactory.functionTypedFormalParameter2(
@@ -994,69 +612,26 @@
       returnType: returnType,
       typeParameters: typeParameters,
     );
-    node.summaryData = SummaryDataForFormalParameter(
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-    );
     return node;
   }
 
   GenericFunctionType _readGenericFunctionType() {
     var flags = _readByte();
+    // TODO(scheglov) add type parameters to locals
     var typeParameters = _readOptionalNode() as TypeParameterList?;
     var returnType = _readOptionalNode() as TypeAnnotation?;
     var formalParameters = readNode() as FormalParameterList;
-
-    return astFactory.genericFunctionType(
+    var node = astFactory.genericFunctionType(
       returnType,
       Tokens.FUNCTION,
       typeParameters,
       formalParameters,
       question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
     );
-  }
-
-  GenericTypeAlias _readGenericTypeAlias() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var type = readNode() as TypeAnnotation;
-    var name = readNode() as SimpleIdentifier;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.genericTypeAlias(
-      null,
-      metadata,
-      Tokens.TYPEDEF,
-      name,
-      typeParameters,
-      Tokens.EQ,
-      type,
-      Tokens.SEMICOLON,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
+    node.type = _reader.readType();
     return node;
   }
 
-  HideCombinator _readHideCombinator() {
-    var keywordOffset = _readInformativeUint30();
-    return astFactory.hideCombinator(
-      KeywordToken(Keyword.HIDE, keywordOffset),
-      _readNodeList<SimpleIdentifier>(),
-    );
-  }
-
   IfElement _readIfElement() {
     var condition = readNode() as Expression;
     var thenElement = readNode() as CollectionElement;
@@ -1077,56 +652,14 @@
     return astFactory.implementsClause(Tokens.IMPLEMENTS, interfaces);
   }
 
-  ImportDirective _readImportDirective() {
-    var flags = _readByte();
-
-    SimpleIdentifier? prefixIdentifier;
-    if (AstBinaryFlags.hasPrefix(flags)) {
-      var prefixName = _readStringReference();
-      var prefixOffset = _readInformativeUint30();
-      prefixIdentifier = astFactory.simpleIdentifier(
-        StringToken(TokenType.STRING, prefixName, prefixOffset),
-      );
-    }
-
-    var combinators = _readNodeList<Combinator>();
-    var configurations = _readNodeList<Configuration>();
-    var uri = readNode() as StringLiteral;
-    var keywordOffset = _readInformativeUint30();
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.importDirective(
-      null,
-      metadata,
-      KeywordToken(Keyword.IMPORT, keywordOffset),
-      uri,
-      configurations,
-      AstBinaryFlags.isDeferred(flags) ? Tokens.DEFERRED : null,
-      Tokens.AS,
-      prefixIdentifier,
-      combinators,
-      Tokens.SEMICOLON,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: -1,
-      codeLength: 0,
-      documentationTokenIndexList: _noDocumentationComment,
-      resolutionIndex: _readUInt30(),
-    );
-
-    return node;
-  }
-
   IndexExpression _readIndexExpression() {
     var flags = _readByte();
     var target = _readOptionalNode() as Expression?;
     var index = readNode() as Expression;
     // TODO(scheglov) Is this clumsy?
+    IndexExpressionImpl node;
     if (target != null) {
-      return (astFactory.indexExpressionForTarget2(
+      node = (astFactory.indexExpressionForTarget2(
         target: target,
         question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
         leftBracket: Tokens.OPEN_SQUARE_BRACKET,
@@ -1136,7 +669,7 @@
         ..period =
             AstBinaryFlags.hasPeriod(flags) ? Tokens.PERIOD_PERIOD : null;
     } else {
-      return astFactory.indexExpressionForCascade2(
+      node = astFactory.indexExpressionForCascade2(
         period: Tokens.PERIOD_PERIOD,
         question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
         leftBracket: Tokens.OPEN_SQUARE_BRACKET,
@@ -1144,20 +677,9 @@
         rightBracket: Tokens.CLOSE_SQUARE_BRACKET,
       );
     }
-  }
-
-  int _readInformativeUint30() {
-    if (_withInformative) {
-      return _readUInt30();
-    }
-    return 0;
-  }
-
-  Uint32List? _readInformativeUint30List() {
-    if (_withInformative) {
-      return _readUint30List();
-    }
-    return null;
+    node.staticElement = _reader.readElement() as MethodElement?;
+    _readExpressionResolution(node);
+    return node;
   }
 
   InstanceCreationExpression _readInstanceCreationExpression() {
@@ -1165,7 +687,7 @@
     var constructorName = readNode() as ConstructorName;
     var argumentList = readNode() as ArgumentList;
 
-    return astFactory.instanceCreationExpression(
+    var node = astFactory.instanceCreationExpression(
       Tokens.choose(
         AstBinaryFlags.isConst(flags),
         Tokens.CONST,
@@ -1175,10 +697,16 @@
       constructorName,
       argumentList,
     );
+    _readExpressionResolution(node);
+    _resolveNamedExpressions(
+      node.constructorName.staticElement,
+      node.argumentList,
+    );
+    return node;
   }
 
   IntegerLiteral _readIntegerLiteralNegative() {
-    var value = (_readUint32() << 32) | _readUint32();
+    var value = (_readUInt32() << 32) | _readUInt32();
     return _createIntegerLiteral(-value);
   }
 
@@ -1189,14 +717,16 @@
 
   IntegerLiteral _readIntegerLiteralNull() {
     var lexeme = _readStringReference();
-    return astFactory.integerLiteral(
+    var node = astFactory.integerLiteral(
       TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
       null,
     );
+    _readExpressionResolution(node);
+    return node;
   }
 
   IntegerLiteral _readIntegerLiteralPositive() {
-    var value = (_readUint32() << 32) | _readUint32();
+    var value = (_readUInt32() << 32) | _readUInt32();
     return _createIntegerLiteral(value);
   }
 
@@ -1226,44 +756,29 @@
     );
   }
 
+  void _readInvocationExpression(InvocationExpressionImpl node) {
+    // TODO(scheglov) typeArgumentTypes and staticInvokeType?
+    node.typeArgumentTypes = [];
+    _readExpressionResolution(node);
+  }
+
   IsExpression _readIsExpression() {
     var flags = _readByte();
     var expression = readNode() as Expression;
     var type = readNode() as TypeAnnotation;
-    return astFactory.isExpression(
+    var node = astFactory.isExpression(
       expression,
       Tokens.IS,
       AstBinaryFlags.hasNot(flags) ? Tokens.BANG : null,
       type,
     );
-  }
-
-  LibraryDirective _readLibraryDirective() {
-    var documentationTokenIndexList = _readUint30List();
-    var name = readNode() as LibraryIdentifier;
-    var keywordOffset = _readInformativeUint30();
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.libraryDirective(
-      null,
-      metadata,
-      KeywordToken(Keyword.LIBRARY, keywordOffset),
-      name,
-      Tokens.SEMICOLON,
-    );
-    SummaryDataForLibraryDirective(
-      _unitReader,
-      node,
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
+    _readExpressionResolution(node);
     return node;
   }
 
-  LibraryIdentifier _readLibraryIdentifier() {
-    var components = _readNodeList<SimpleIdentifier>();
-    return astFactory.libraryIdentifier(
-      components,
-    );
+  Label _readLabel() {
+    var label = readNode() as SimpleIdentifier;
+    return astFactory.label(label, Tokens.COLON);
   }
 
   ListLiteral _readListLiteral() {
@@ -1271,13 +786,15 @@
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var elements = _readNodeList<CollectionElement>();
 
-    return astFactory.listLiteral(
+    var node = astFactory.listLiteral(
       AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
       typeArguments,
       Tokens.OPEN_SQUARE_BRACKET,
       elements,
       Tokens.CLOSE_SQUARE_BRACKET,
     );
+    _readExpressionResolution(node);
+    return node;
   }
 
   MapLiteralEntry _readMapLiteralEntry() {
@@ -1286,51 +803,6 @@
     return astFactory.mapLiteralEntry(key, Tokens.COLON, value);
   }
 
-  MethodDeclaration _readMethodDeclaration() {
-    var flags = _readUInt30();
-
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
-    var name = readNode() as SimpleIdentifier;
-    var typeParameters = _readOptionalNode() as TypeParameterList?;
-    var returnType = _readOptionalNode() as TypeAnnotation?;
-    var formalParameters = _readOptionalNode() as FormalParameterList?;
-    var metadata = _readNodeList<Annotation>();
-    var body = _functionBodyForFlags(flags);
-
-    var node = astFactory.methodDeclaration(
-      null,
-      metadata,
-      AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
-      AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
-      returnType,
-      Tokens.choose(
-        AstBinaryFlags.isGet(flags),
-        Tokens.GET,
-        AstBinaryFlags.isSet(flags),
-        Tokens.SET,
-      ),
-      AstBinaryFlags.isOperator(flags) ? Tokens.OPERATOR : null,
-      name,
-      typeParameters,
-      formalParameters,
-      body,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
-    return node;
-  }
-
   MethodInvocation _readMethodInvocation() {
     var flags = _readByte();
     var target = _readOptionalNode() as Expression?;
@@ -1338,7 +810,7 @@
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var arguments = readNode() as ArgumentList;
 
-    return astFactory.methodInvocation(
+    var node = astFactory.methodInvocation(
       target,
       Tokens.choose(
         AstBinaryFlags.hasPeriod(flags),
@@ -1350,13 +822,11 @@
       typeArguments,
       arguments,
     );
+    _readInvocationExpression(node);
+    return node;
   }
 
   MixinDeclaration _readMixinDeclaration() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var documentationTokenIndexList = _readUint30List();
-
     var typeParameters = _readOptionalNode() as TypeParameterList?;
     var onClause = _readOptionalNode() as OnClause?;
     var implementsClause = _readOptionalNode() as ImplementsClause?;
@@ -1376,30 +846,21 @@
       Tokens.CLOSE_CURLY_BRACKET,
     );
 
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
     return node;
   }
 
   NamedExpression _readNamedExpression() {
     var name = _readStringReference();
-    var offset = _readInformativeUint30();
     var nameNode = astFactory.label(
       astFactory.simpleIdentifier(
-        StringToken(TokenType.STRING, name, offset),
+        StringToken(TokenType.STRING, name, -1),
       ),
       Tokens.COLON,
     );
-
     var expression = readNode() as Expression;
-    return astFactory.namedExpression(nameNode, expression);
+    var node = astFactory.namedExpression(nameNode, expression);
+    node.staticType = expression.staticType;
+    return node;
   }
 
   NativeClause _readNativeClause() {
@@ -1408,7 +869,7 @@
   }
 
   List<T> _readNodeList<T>() {
-    var length = _readUInt30();
+    var length = _reader.readUInt30();
     return List.generate(length, (_) => readNode() as T);
   }
 
@@ -1444,70 +905,61 @@
 
   ParenthesizedExpression _readParenthesizedExpression() {
     var expression = readNode() as Expression;
-    return astFactory.parenthesizedExpression(
+    var node = astFactory.parenthesizedExpression(
       Tokens.OPEN_PAREN,
       expression,
       Tokens.CLOSE_PAREN,
     );
-  }
-
-  PartDirective _readPartDirective() {
-    var uri = readNode() as StringLiteral;
-    var keywordOffset = _readInformativeUint30();
-    var metadata = _readNodeList<Annotation>();
-
-    return astFactory.partDirective(
-      null,
-      metadata,
-      KeywordToken(Keyword.PART, keywordOffset),
-      uri,
-      Tokens.SEMICOLON,
-    );
-  }
-
-  PartOfDirective _readPartOfDirective() {
-    var libraryName = _readOptionalNode() as LibraryIdentifier?;
-    var uri = _readOptionalNode() as StringLiteral?;
-    var keywordOffset = _readInformativeUint30();
-    var metadata = _readNodeList<Annotation>();
-
-    return astFactory.partOfDirective(
-      null,
-      metadata,
-      KeywordToken(Keyword.PART, keywordOffset),
-      Tokens.OF,
-      uri,
-      libraryName,
-      Tokens.SEMICOLON,
-    );
+    _readExpressionResolution(node);
+    return node;
   }
 
   PostfixExpression _readPostfixExpression() {
     var operand = readNode() as Expression;
     var operatorType = UnlinkedTokenType.values[_readByte()];
-    return astFactory.postfixExpression(
+    var node = astFactory.postfixExpression(
       operand,
       Tokens.fromType(operatorType),
     );
+    node.staticElement = _reader.readElement() as MethodElement?;
+    if (node.operator.type.isIncrementOperator) {
+      node.readElement = _reader.readElement();
+      node.readType = _reader.readType();
+      node.writeElement = _reader.readElement();
+      node.writeType = _reader.readType();
+    }
+    _readExpressionResolution(node);
+    return node;
   }
 
   PrefixedIdentifier _readPrefixedIdentifier() {
     var prefix = readNode() as SimpleIdentifier;
     var identifier = readNode() as SimpleIdentifier;
-    return astFactory.prefixedIdentifier(
+    var node = astFactory.prefixedIdentifier(
       prefix,
       Tokens.PERIOD,
       identifier,
     );
+    _readExpressionResolution(node);
+    return node;
   }
 
   PrefixExpression _readPrefixExpression() {
     var operatorType = UnlinkedTokenType.values[_readByte()];
     var operand = readNode() as Expression;
-    return astFactory.prefixExpression(
+    var node = astFactory.prefixExpression(
       Tokens.fromType(operatorType),
       operand,
     );
+    node.staticElement = _reader.readElement() as MethodElement?;
+    if (node.operator.type.isIncrementOperator) {
+      node.readElement = _reader.readElement();
+      node.readType = _reader.readType();
+      node.writeElement = _reader.readElement();
+      node.writeType = _reader.readType();
+    }
+    _readExpressionResolution(node);
+    return node;
   }
 
   PropertyAccess _readPropertyAccess() {
@@ -1526,22 +978,28 @@
           : Tokens.PERIOD_PERIOD;
     }
 
-    return astFactory.propertyAccess(target, operator, propertyName);
+    var node = astFactory.propertyAccess(target, operator, propertyName);
+    _readExpressionResolution(node);
+    return node;
   }
 
   RedirectingConstructorInvocation _readRedirectingConstructorInvocation() {
     var constructorName = _readOptionalNode() as SimpleIdentifier?;
     var argumentList = readNode() as ArgumentList;
-    return astFactory.redirectingConstructorInvocation(
+    var node = astFactory.redirectingConstructorInvocation(
       Tokens.THIS,
       constructorName != null ? Tokens.PERIOD : null,
       constructorName,
       argumentList,
     );
+    node.staticElement = _reader.readElement() as ConstructorElement?;
+    _resolveNamedExpressions(node.staticElement, node.argumentList);
+    return node;
   }
 
   SetOrMapLiteral _readSetOrMapLiteral() {
     var flags = _readByte();
+    var isMapOrSetBits = _readByte();
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var elements = _readNodeList<CollectionElement>();
     var node = astFactory.setOrMapLiteral(
@@ -1551,25 +1009,25 @@
       typeArguments: typeArguments,
       rightBracket: Tokens.CLOSE_CURLY_BRACKET,
     );
-    return node;
-  }
 
-  ShowCombinator _readShowCombinator() {
-    var keywordOffset = _readInformativeUint30();
-    return astFactory.showCombinator(
-      KeywordToken(Keyword.SHOW, keywordOffset),
-      _readNodeList<SimpleIdentifier>(),
-    );
+    const isMapBit = 1 << 0;
+    const isSetBit = 1 << 1;
+    if ((isMapOrSetBits & isMapBit) != 0) {
+      node.becomeMap();
+    } else if ((isMapOrSetBits & isSetBit) != 0) {
+      node.becomeSet();
+    }
+
+    _readExpressionResolution(node);
+    return node;
   }
 
   SimpleFormalParameter _readSimpleFormalParameter() {
     var type = _readOptionalNode() as TypeAnnotation?;
     var flags = _readByte();
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
     var metadata = _readNodeList<Annotation>();
     var identifier =
-        AstBinaryFlags.hasName(flags) ? readNode() as SimpleIdentifier : null;
+        AstBinaryFlags.hasName(flags) ? _readDeclarationName() : null;
 
     var node = astFactory.simpleFormalParameter2(
       identifier: identifier,
@@ -1589,19 +1047,19 @@
       requiredKeyword:
           AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
     );
-    node.summaryData = SummaryDataForFormalParameter(
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-    );
+    _reader.readType(); // TODO(scheglov) actual type
+    _reader.readByte(); // TODO(scheglov) inherits covariant
     return node;
   }
 
   SimpleIdentifier _readSimpleIdentifier() {
     var name = _readStringReference();
-    var offset = _readInformativeUint30();
-    return astFactory.simpleIdentifier(
-      StringToken(TokenType.STRING, name, offset),
+    var node = astFactory.simpleIdentifier(
+      StringToken(TokenType.STRING, name, -1),
     );
+    node.staticElement = _reader.readElement();
+    _readExpressionResolution(node);
+    return node;
   }
 
   SimpleStringLiteral _readSimpleStringLiteral() {
@@ -1631,70 +1089,49 @@
   }
 
   String _readStringReference() {
-    return _unitReader.astReader.readStringReference();
+    return _reader.readStringReference();
   }
 
   SuperConstructorInvocation _readSuperConstructorInvocation() {
     var constructorName = _readOptionalNode() as SimpleIdentifier?;
     var argumentList = readNode() as ArgumentList;
-    return astFactory.superConstructorInvocation(
+    var node = astFactory.superConstructorInvocation(
       Tokens.SUPER,
       Tokens.PERIOD,
       constructorName,
       argumentList,
     );
+    node.staticElement = _reader.readElement() as ConstructorElement?;
+    _resolveNamedExpressions(node.staticElement, node.argumentList);
+    return node;
   }
 
   SuperExpression _readSuperExpression() {
-    return astFactory.superExpression(Tokens.SUPER);
+    var node = astFactory.superExpression(Tokens.SUPER);
+    _readExpressionResolution(node);
+    return node;
   }
 
   SymbolLiteral _readSymbolLiteral() {
-    var components = <Token>[];
-    var length = _readUInt30();
-    for (var i = 0; i < length; i++) {
-      var lexeme = _readStringReference();
-      var token = TokenFactory.tokenFromString(lexeme);
-      components.add(token);
-    }
-    return astFactory.symbolLiteral(Tokens.HASH, components);
+    var components = _reader
+        .readStringReferenceList()
+        .map(TokenFactory.tokenFromString)
+        .toList();
+    var node = astFactory.symbolLiteral(Tokens.HASH, components);
+    _readExpressionResolution(node);
+    return node;
   }
 
   ThisExpression _readThisExpression() {
-    return astFactory.thisExpression(Tokens.THIS);
+    var node = astFactory.thisExpression(Tokens.THIS);
+    _readExpressionResolution(node);
+    return node;
   }
 
   ThrowExpression _readThrowExpression() {
     var expression = readNode() as Expression;
-    return astFactory.throwExpression(Tokens.THROW, expression);
-  }
-
-  TopLevelVariableDeclaration _readTopLevelVariableDeclaration() {
-    var flags = _readByte();
-    var codeOffsetLengthList = _readInformativeUint30List();
-    var documentationTokenIndexList = _readUint30List();
-    var variableList = readNode() as VariableDeclarationList;
-    var metadata = _readNodeList<Annotation>();
-
-    var node = astFactory.topLevelVariableDeclaration(
-      null,
-      metadata,
-      variableList,
-      Tokens.SEMICOLON,
-      externalKeyword:
-          AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
-    );
-
-    node.linkedContext = LinkedContext(
-      _unitReader,
-      node,
-      codeOffset: -1,
-      codeLength: 0,
-      codeOffsetLengthList: codeOffsetLengthList,
-      resolutionIndex: _readUInt30(),
-      documentationTokenIndexList: documentationTokenIndexList,
-    );
-
+    var node = astFactory.throwExpression(Tokens.THROW, expression);
+    _readExpressionResolution(node);
     return node;
   }
 
@@ -1708,17 +1145,17 @@
     var name = readNode() as Identifier;
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
 
-    return astFactory.typeName(
+    var node = astFactory.typeName(
       name,
       typeArguments,
       question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
     );
+    node.type = _reader.readType();
+    return node;
   }
 
   TypeParameter _readTypeParameter() {
-    var codeOffset = _readInformativeUint30();
-    var codeLength = _readInformativeUint30();
-    var name = readNode() as SimpleIdentifier;
+    var name = _readDeclarationName();
     var bound = _readOptionalNode() as TypeAnnotation?;
     var metadata = _readNodeList<Annotation>();
 
@@ -1729,10 +1166,6 @@
       bound != null ? Tokens.EXTENDS : null,
       bound,
     );
-    node.summaryData = SummaryDataForTypeParameter(
-      codeOffset: codeOffset,
-      codeLength: codeLength,
-    );
 
     return node;
   }
@@ -1746,37 +1179,8 @@
     );
   }
 
-  int _readUInt30() {
-    var byte = _readByte();
-    if (byte & 0x80 == 0) {
-      // 0xxxxxxx
-      return byte;
-    } else if (byte & 0x40 == 0) {
-      // 10xxxxxx
-      return ((byte & 0x3F) << 8) | _readByte();
-    } else {
-      // 11xxxxxx
-      return ((byte & 0x3F) << 24) |
-          (_readByte() << 16) |
-          (_readByte() << 8) |
-          _readByte();
-    }
-  }
-
-  Uint32List _readUint30List() {
-    var length = _readUInt30();
-    var result = Uint32List(length);
-    for (var i = 0; i < length; ++i) {
-      result[i] = _readUInt30();
-    }
-    return result;
-  }
-
-  int _readUint32() {
-    return (_readByte() << 24) |
-        (_readByte() << 16) |
-        (_readByte() << 8) |
-        _readByte();
+  int _readUInt32() {
+    return _reader.readUInt32();
   }
 
   VariableDeclaration _readVariableDeclaration() {
@@ -1822,4 +1226,22 @@
     var mixins = _readNodeList<TypeName>();
     return astFactory.withClause(Tokens.WITH, mixins);
   }
+
+  void _resolveNamedExpressions(
+    Element? executable,
+    ArgumentList argumentList,
+  ) {
+    for (var argument in argumentList.arguments) {
+      if (argument is NamedExpressionImpl) {
+        var nameNode = argument.name.label;
+        if (executable is ExecutableElement) {
+          var parameters = executable.parameters;
+          var name = nameNode.name;
+          nameNode.staticElement = parameters.firstWhereOrNull((e) {
+            return e.name == name;
+          });
+        }
+      }
+    }
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index 933b12b..98809ef 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -2,328 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/// When debugging, these tags are written in resolution information to
-/// mark positions where we expect resolution for specific kinds of nodes.
-/// This might help us to be more confident that we are reading resolution
-/// data that corresponds to AST, and find places where they start
-/// diverging.
-enum MarkerTag {
-  AnnotatedNode_metadata,
-  AnnotatedNode_end,
-  Annotation_name,
-  Annotation_typeArguments,
-  Annotation_constructorName,
-  Annotation_arguments,
-  Annotation_element,
-  ArgumentList_arguments,
-  ArgumentList_end,
-  AsExpression_expression,
-  AsExpression_type,
-  AsExpression_expression2,
-  AsExpression_end,
-  AwaitExpression_expression,
-  AwaitExpression_expression2,
-  AwaitExpression_end,
-  Expression_staticType,
-  AssertInitializer_condition,
-  AssertInitializer_message,
-  AssertInitializer_end,
-  AssignmentExpression_leftHandSide,
-  AssignmentExpression_rightHandSide,
-  AssignmentExpression_staticElement,
-  AssignmentExpression_readElement,
-  AssignmentExpression_readType,
-  AssignmentExpression_writeElement,
-  AssignmentExpression_writeType,
-  AssignmentExpression_expression,
-  AssignmentExpression_end,
-  BinaryExpression_leftOperand,
-  BinaryExpression_rightOperand,
-  BinaryExpression_staticElement,
-  BinaryExpression_expression,
-  BinaryExpression_end,
-  CascadeExpression_target,
-  CascadeExpression_cascadeSections,
-  CascadeExpression_end,
-  ClassDeclaration_typeParameters,
-  ClassDeclaration_extendsClause,
-  ClassDeclaration_withClause,
-  ClassDeclaration_implementsClause,
-  ClassDeclaration_nativeClause,
-  ClassDeclaration_namedCompilationUnitMember,
-  ClassDeclaration_end,
-  ClassMember_declaration,
-  ClassMember_end,
-  ClassTypeAlias_typeParameters,
-  ClassTypeAlias_superclass,
-  ClassTypeAlias_withClause,
-  ClassTypeAlias_implementsClause,
-  ClassTypeAlias_typeAlias,
-  ClassTypeAlias_end,
-  ConditionalExpression_condition,
-  ConditionalExpression_thenExpression,
-  ConditionalExpression_elseExpression,
-  Configuration_name,
-  Configuration_value,
-  Configuration_uri,
-  Configuration_end,
-  ConstructorDeclaration_returnType,
-  ConstructorDeclaration_parameters,
-  ConstructorDeclaration_initializers,
-  ConstructorDeclaration_redirectedConstructor,
-  ConstructorDeclaration_classMember,
-  ConstructorDeclaration_end,
-  ConstructorFieldInitializer_fieldName,
-  ConstructorFieldInitializer_expression,
-  ConstructorFieldInitializer_end,
-  ConstructorName_type,
-  ConstructorName_name,
-  ConstructorName_staticElement,
-  ConstructorName_end,
-  DeclaredIdentifier_type,
-  DeclaredIdentifier_identifier,
-  DeclaredIdentifier_declaration,
-  DeclaredIdentifier_end,
-  DefaultFormalParameter_parameter,
-  DefaultFormalParameter_defaultValue,
-  DefaultFormalParameter_end,
-  EnumConstantDeclaration_name,
-  EnumConstantDeclaration_declaration,
-  EnumConstantDeclaration_end,
-  EnumDeclaration_constants,
-  EnumDeclaration_namedCompilationUnitMember,
-  EnumDeclaration_end,
-  ExportDirective_namespaceDirective,
-  ExportDirective_exportedLibrary,
-  ExportDirective_end,
-  ExtendsClause_superclass,
-  ExtendsClause_end,
-  ExtensionDeclaration_typeParameters,
-  ExtensionDeclaration_extendedType,
-  ExtensionDeclaration_compilationUnitMember,
-  ExtensionDeclaration_end,
-  ExtensionOverride_extensionName,
-  ExtensionOverride_typeArguments,
-  ExtensionOverride_argumentList,
-  ExtensionOverride_extendedType,
-  ExtensionOverride_end,
-  FieldDeclaration_fields,
-  FieldDeclaration_classMember,
-  FieldDeclaration_end,
-  FieldFormalParameter_typeParameters,
-  FieldFormalParameter_type,
-  FieldFormalParameter_parameters,
-  FieldFormalParameter_normalFormalParameter,
-  FieldFormalParameter_end,
-  ForEachParts_iterable,
-  ForEachParts_forLoopParts,
-  ForEachParts_end,
-  ForEachPartsWithDeclaration_loopVariable,
-  ForEachPartsWithDeclaration_forEachParts,
-  ForEachPartsWithDeclaration_end,
-  ForElement_forLoopParts,
-  ForElement_body,
-  ForElement_end,
-  FormalParameter_type,
-  ForParts_condition,
-  ForParts_updaters,
-  ForParts_forLoopParts,
-  ForParts_end,
-  FormalParameterList_parameters,
-  FormalParameterList_end,
-  ForPartsWithDeclarations_variables,
-  ForPartsWithDeclarations_forParts,
-  ForPartsWithDeclarations_end,
-  ForPartsWithExpression_initialization,
-  ForPartsWithExpression_forParts,
-  ForPartsWithExpression_end,
-  FunctionDeclaration_functionExpression,
-  FunctionDeclaration_returnType,
-  FunctionDeclaration_namedCompilationUnitMember,
-  FunctionDeclaration_returnTypeType,
-  FunctionDeclaration_end,
-  FunctionExpression_typeParameters,
-  FunctionExpression_parameters,
-  FunctionExpression_end,
-  FunctionExpressionInvocation_function,
-  FunctionExpressionInvocation_invocationExpression,
-  FunctionExpressionInvocation_end,
-  FunctionTypeAlias_typeParameters,
-  FunctionTypeAlias_returnType,
-  FunctionTypeAlias_parameters,
-  FunctionTypeAlias_typeAlias,
-  FunctionTypeAlias_returnTypeType,
-  FunctionTypeAlias_flags,
-  FunctionTypeAlias_end,
-  FunctionTypedFormalParameter_typeParameters,
-  FunctionTypedFormalParameter_returnType,
-  FunctionTypedFormalParameter_parameters,
-  FunctionTypedFormalParameter_normalFormalParameter,
-  FunctionTypedFormalParameter_end,
-  GenericFunctionType_typeParameters,
-  GenericFunctionType_returnType,
-  GenericFunctionType_parameters,
-  GenericFunctionType_type,
-  GenericFunctionType_end,
-  GenericTypeAlias_typeParameters,
-  GenericTypeAlias_type,
-  GenericTypeAlias_typeAlias,
-  GenericTypeAlias_flags,
-  GenericTypeAlias_end,
-  IfElement_condition,
-  IfElement_thenElement,
-  IfElement_elseElement,
-  IfElement_end,
-  ImplementsClause_interfaces,
-  ImplementsClause_end,
-  ImportDirective_namespaceDirective,
-  ImportDirective_importedLibrary,
-  ImportDirective_end,
-  IndexExpression_target,
-  IndexExpression_index,
-  IndexExpression_staticElement,
-  IndexExpression_expression,
-  IndexExpression_end,
-  InstanceCreationExpression_constructorName,
-  InstanceCreationExpression_argumentList,
-  InstanceCreationExpression_expression,
-  InstanceCreationExpression_end,
-  IsExpression_expression,
-  IsExpression_type,
-  IsExpression_expression2,
-  IsExpression_end,
-  InvocationExpression_typeArguments,
-  InvocationExpression_argumentList,
-  InvocationExpression_expression,
-  InvocationExpression_end,
-  ListLiteral_typeArguments,
-  ListLiteral_elements,
-  ListLiteral_expression,
-  ListLiteral_end,
-  MapLiteralEntry_key,
-  MapLiteralEntry_value,
-  MethodDeclaration_typeParameters,
-  MethodDeclaration_returnType,
-  MethodDeclaration_parameters,
-  MethodDeclaration_classMember,
-  MethodDeclaration_returnTypeType,
-  MethodDeclaration_inferenceError,
-  MethodDeclaration_flags,
-  MethodDeclaration_end,
-  MethodInvocation_target,
-  MethodInvocation_methodName,
-  MethodInvocation_invocationExpression,
-  MethodInvocation_end,
-  MixinDeclaration_typeParameters,
-  MixinDeclaration_onClause,
-  MixinDeclaration_implementsClause,
-  MixinDeclaration_namedCompilationUnitMember,
-  MixinDeclaration_end,
-  NamedExpression_expression,
-  NamedExpression_end,
-  NamespaceDirective_combinators,
-  NamespaceDirective_configurations,
-  NamespaceDirective_uriBasedDirective,
-  NamespaceDirective_end,
-  NativeClause_name,
-  NativeClause_end,
-  NormalFormalParameter_metadata,
-  NormalFormalParameter_formalParameter,
-  NormalFormalParameter_end,
-  OnClause_superclassConstraints,
-  OnClause_end,
-  ParenthesizedExpression_expression,
-  ParenthesizedExpression_expression2,
-  ParenthesizedExpression_end,
-  PartOfDirective_libraryName,
-  PartOfDirective_uri,
-  PartOfDirective_directive,
-  PartOfDirective_end,
-  PostfixExpression_operand,
-  PostfixExpression_staticElement,
-  PostfixExpression_readElement,
-  PostfixExpression_readType,
-  PostfixExpression_writeElement,
-  PostfixExpression_writeType,
-  PostfixExpression_expression,
-  PostfixExpression_end,
-  PrefixedIdentifier_prefix,
-  PrefixedIdentifier_identifier,
-  PrefixedIdentifier_expression,
-  PrefixedIdentifier_end,
-  PrefixExpression_operand,
-  PrefixExpression_staticElement,
-  PrefixExpression_readElement,
-  PrefixExpression_readType,
-  PrefixExpression_writeElement,
-  PrefixExpression_writeType,
-  PrefixExpression_expression,
-  PrefixExpression_end,
-  PropertyAccess_target,
-  PropertyAccess_propertyName,
-  PropertyAccess_expression,
-  PropertyAccess_end,
-  RedirectingConstructorInvocation_constructorName,
-  RedirectingConstructorInvocation_argumentList,
-  RedirectingConstructorInvocation_staticElement,
-  RedirectingConstructorInvocation_end,
-  SetOrMapLiteral_flags,
-  SetOrMapLiteral_typeArguments,
-  SetOrMapLiteral_elements,
-  SetOrMapLiteral_expression,
-  SetOrMapLiteral_end,
-  SimpleFormalParameter_type,
-  SimpleFormalParameter_normalFormalParameter,
-  SimpleFormalParameter_flags,
-  SimpleFormalParameter_end,
-  SimpleIdentifier_staticElement,
-  SimpleIdentifier_expression,
-  SimpleIdentifier_end,
-  SpreadElement_expression,
-  SpreadElement_end,
-  StringInterpolation_elements,
-  StringInterpolation_end,
-  SuperConstructorInvocation_constructorName,
-  SuperConstructorInvocation_argumentList,
-  SuperConstructorInvocation_staticElement,
-  SuperConstructorInvocation_end,
-  SuperExpression_expression,
-  SuperExpression_end,
-  ThisExpression_expression,
-  ThisExpression_end,
-  ThrowExpression_expression,
-  ThrowExpression_expression2,
-  ThrowExpression_end,
-  TopLevelVariableDeclaration_variables,
-  TopLevelVariableDeclaration_compilationUnitMember,
-  TopLevelVariableDeclaration_end,
-  TypeArgumentList_arguments,
-  TypeArgumentList_end,
-  TypeName_name,
-  TypeName_typeArguments,
-  TypeName_type,
-  TypeName_end,
-  TypeParameter_bound,
-  TypeParameter_declaration,
-  TypeParameter_variance,
-  TypeParameter_defaultType,
-  TypeParameter_end,
-  TypeParameterList_typeParameters,
-  TypeParameterList_end,
-  UriBasedDirective_uri,
-  UriBasedDirective_directive,
-  UriBasedDirective_end,
-  VariableDeclaration_type,
-  VariableDeclaration_inferenceError,
-  VariableDeclaration_inheritsCovariant,
-  VariableDeclaration_initializer,
-  VariableDeclaration_end,
-  VariableDeclarationList_type,
-  VariableDeclarationList_variables,
-  VariableDeclarationList_annotatedNode,
-  VariableDeclarationList_end,
-  WithClause_mixinTypes,
-  WithClause_end,
+class AliasedElementTag {
+  static const int nothing = 0;
+  static const int genericFunctionElement = 1;
 }
 
 /// A `MethodInvocation` in unresolved AST might be rewritten later as
@@ -350,43 +31,30 @@
   static const int BinaryExpression = 52;
   static const int BooleanLiteral = 4;
   static const int CascadeExpression = 95;
-  static const int Class = 5;
-  static const int ClassTypeAlias = 44;
   static const int ConditionalExpression = 51;
   static const int Configuration = 46;
-  static const int ConstructorDeclaration = 6;
   static const int ConstructorFieldInitializer = 50;
   static const int ConstructorName = 7;
   static const int DeclaredIdentifier = 90;
   static const int DefaultFormalParameter = 8;
   static const int DottedName = 47;
   static const int DoubleLiteral = 9;
-  static const int EnumConstantDeclaration = 10;
-  static const int EnumDeclaration = 11;
-  static const int ExportDirective = 12;
-  static const int ExtendsClause = 13;
-  static const int ExtensionDeclaration = 14;
   static const int ExtensionOverride = 87;
-  static const int FieldDeclaration = 15;
   static const int FieldFormalParameter = 16;
   static const int ForEachPartsWithDeclaration = 89;
   static const int ForElement = 88;
   static const int ForPartsWithDeclarations = 91;
   static const int ForPartsWithExpression = 99;
   static const int FormalParameterList = 17;
-  static const int FunctionDeclaration = 18;
   static const int FunctionDeclaration_getter = 57;
   static const int FunctionDeclaration_setter = 58;
   static const int FunctionExpression = 19;
   static const int FunctionExpressionInvocation = 93;
-  static const int FunctionTypeAlias = 55;
   static const int FunctionTypedFormalParameter = 20;
   static const int GenericFunctionType = 21;
-  static const int GenericTypeAlias = 22;
   static const int HideCombinator = 48;
   static const int IfElement = 63;
   static const int ImplementsClause = 23;
-  static const int ImportDirective = 24;
   static const int IndexExpression = 98;
   static const int InstanceCreationExpression = 25;
   static const int IntegerLiteralNegative = 73;
@@ -398,11 +66,8 @@
   static const int InterpolationString = 78;
   static const int IsExpression = 83;
   static const int Label = 61;
-  static const int LibraryDirective = 27;
-  static const int LibraryIdentifier = 28;
   static const int ListLiteral = 56;
   static const int MapLiteralEntry = 66;
-  static const int MethodDeclaration = 29;
   static const int MethodDeclaration_getter = 85;
   static const int MethodDeclaration_setter = 86;
   static const int MethodInvocation = 59;
@@ -412,8 +77,6 @@
   static const int OnClause = 68;
   static const int NullLiteral = 49;
   static const int ParenthesizedExpression = 53;
-  static const int PartDirective = 30;
-  static const int PartOfDirective = 31;
   static const int PostfixExpression = 94;
   static const int PrefixExpression = 79;
   static const int PrefixedIdentifier = 32;
@@ -431,7 +94,6 @@
   static const int SymbolLiteral = 74;
   static const int ThisExpression = 70;
   static const int ThrowExpression = 81;
-  static const int TopLevelVariableDeclaration = 37;
   static const int TypeArgumentList = 38;
   static const int TypeName = 39;
   static const int TypeParameter = 40;
@@ -461,3 +123,11 @@
   static const int TypeParameterType = 10;
   static const int VoidType = 11;
 }
+
+enum TypeParameterVarianceTag {
+  legacy,
+  unrelated,
+  covariant,
+  contravariant,
+  invariant,
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index e4ff4f3..c2573f6 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -2,52 +2,28 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
 import 'package:analyzer/src/summary2/ast_binary_tag.dart';
 import 'package:analyzer/src/summary2/bundle_writer.dart';
-import 'package:analyzer/src/summary2/data_writer.dart';
 import 'package:analyzer/src/summary2/tokens_writer.dart';
-import 'package:analyzer/src/task/inference_error.dart';
-import 'package:analyzer/src/util/either.dart';
 
 /// Serializer of fully resolved ASTs.
 class AstBinaryWriter extends ThrowingAstVisitor<void> {
-  final bool _withInformative;
-  final BufferedSink _sink;
+  final ResolutionSink _sink;
   final StringIndexer _stringIndexer;
-  final int Function() _getNextResolutionIndex;
-  final ResolutionSink? _resolutionSink;
-
-  /// TODO(scheglov) Keep it private, and write here, similarly as we do
-  /// for [_classMemberIndexItems]?
-  final List<_UnitMemberIndexItem> unitMemberIndexItems = [];
-  final List<_ClassMemberIndexItem> _classMemberIndexItems = [];
-  bool _shouldStoreVariableInitializers = false;
-  bool _hasConstConstructor = false;
-  int _nextUnnamedExtensionId = 0;
 
   AstBinaryWriter({
-    required bool withInformative,
-    required BufferedSink sink,
+    required ResolutionSink sink,
     required StringIndexer stringIndexer,
-    required int Function() getNextResolutionIndex,
-    required ResolutionSink? resolutionSink,
-  })   : _withInformative = withInformative,
-        _sink = sink,
-        _stringIndexer = stringIndexer,
-        _getNextResolutionIndex = getNextResolutionIndex,
-        _resolutionSink = resolutionSink;
+  })  : _sink = sink,
+        _stringIndexer = stringIndexer;
 
   @override
   void visitAdjacentStrings(AdjacentStrings node) {
@@ -59,14 +35,10 @@
   void visitAnnotation(Annotation node) {
     _writeByte(Tag.Annotation);
 
-    _writeMarker(MarkerTag.Annotation_name);
     _writeNode(node.name);
-    _writeMarker(MarkerTag.Annotation_typeArguments);
     _writeOptionalNode(node.typeArguments);
-    _writeMarker(MarkerTag.Annotation_constructorName);
     _writeOptionalNode(node.constructorName);
 
-    _writeMarker(MarkerTag.Annotation_arguments);
     var arguments = node.arguments;
     if (arguments != null) {
       if (!arguments.arguments.every(_isSerializableExpression)) {
@@ -75,112 +47,74 @@
     }
     _writeOptionalNode(arguments);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.Annotation_element);
-      resolutionSink.writeElement(node.element);
-    }
+    _sink.writeElement(node.element);
   }
 
   @override
   void visitArgumentList(ArgumentList node) {
     _writeByte(Tag.ArgumentList);
-    _writeMarker(MarkerTag.ArgumentList_arguments);
     _writeNodeList(node.arguments);
-    _writeMarker(MarkerTag.ArgumentList_end);
   }
 
   @override
   void visitAsExpression(AsExpression node) {
     _writeByte(Tag.AsExpression);
 
-    _writeMarker(MarkerTag.AsExpression_expression);
     _writeNode(node.expression);
 
-    _writeMarker(MarkerTag.AsExpression_type);
     _writeNode(node.type);
 
-    _writeMarker(MarkerTag.AsExpression_expression2);
     _storeExpression(node);
-
-    _writeMarker(MarkerTag.AsExpression_end);
   }
 
   @override
   void visitAssertInitializer(AssertInitializer node) {
     _writeByte(Tag.AssertInitializer);
-    _writeMarker(MarkerTag.AssertInitializer_condition);
     _writeNode(node.condition);
-    _writeMarker(MarkerTag.AssertInitializer_message);
     _writeOptionalNode(node.message);
-    _writeMarker(MarkerTag.AssertInitializer_end);
   }
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
     _writeByte(Tag.AssignmentExpression);
 
-    _writeMarker(MarkerTag.AssignmentExpression_leftHandSide);
     _writeNode(node.leftHandSide);
-    _writeMarker(MarkerTag.AssignmentExpression_rightHandSide);
     _writeNode(node.rightHandSide);
 
     var operatorToken = node.operator.type;
     var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
     _writeByte(binaryToken.index);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.AssignmentExpression_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-      _writeMarker(MarkerTag.AssignmentExpression_readElement);
-      resolutionSink.writeElement(node.readElement);
-      _writeMarker(MarkerTag.AssignmentExpression_readType);
-      resolutionSink.writeType(node.readType);
-      _writeMarker(MarkerTag.AssignmentExpression_writeElement);
-      resolutionSink.writeElement(node.writeElement);
-      _writeMarker(MarkerTag.AssignmentExpression_writeType);
-      resolutionSink.writeType(node.writeType);
-    }
-    _writeMarker(MarkerTag.AssignmentExpression_expression);
+    _sink.writeElement(node.staticElement);
+    _sink.writeElement(node.readElement);
+    _sink.writeType(node.readType);
+    _sink.writeElement(node.writeElement);
+    _sink.writeType(node.writeType);
     _storeExpression(node);
-    _writeMarker(MarkerTag.AssignmentExpression_end);
   }
 
   @override
   void visitAwaitExpression(AwaitExpression node) {
     _writeByte(Tag.AwaitExpression);
 
-    _writeMarker(MarkerTag.AwaitExpression_expression);
     _writeNode(node.expression);
 
-    _writeMarker(MarkerTag.AsExpression_expression2);
     _storeExpression(node);
-
-    _writeMarker(MarkerTag.AwaitExpression_end);
   }
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
     _writeByte(Tag.BinaryExpression);
 
-    _writeMarker(MarkerTag.BinaryExpression_leftOperand);
     _writeNode(node.leftOperand);
-    _writeMarker(MarkerTag.BinaryExpression_rightOperand);
     _writeNode(node.rightOperand);
 
     var operatorToken = node.operator.type;
     var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
     _writeByte(binaryToken.index);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.BinaryExpression_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-    }
-    _writeMarker(MarkerTag.BinaryExpression_expression);
+    _sink.writeElement(node.staticElement);
     _storeExpression(node);
-    _writeMarker(MarkerTag.BinaryExpression_end);
   }
 
   @override
@@ -193,151 +127,15 @@
   @override
   void visitCascadeExpression(CascadeExpression node) {
     _writeByte(Tag.CascadeExpression);
-    _writeMarker(MarkerTag.CascadeExpression_target);
     _writeNode(node.target);
-    _writeMarker(MarkerTag.CascadeExpression_cascadeSections);
     _writeNodeList(node.cascadeSections);
-    _writeMarker(MarkerTag.CascadeExpression_end);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    var classOffset = _sink.offset;
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _hasConstConstructor = false;
-    for (var member in node.members) {
-      if (member is ConstructorDeclaration && member.constKeyword != null) {
-        _hasConstConstructor = true;
-        break;
-      }
-    }
-
-    _writeByte(Tag.Class);
-    _writeByte(
-      AstBinaryFlags.encode(
-        hasConstConstructor: _hasConstConstructor,
-        isAbstract: node.abstractKeyword != null,
-      ),
-    );
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as ClassElementImpl;
-      resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
-    }
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    _pushScopeTypeParameters(node.typeParameters);
-
-    _writeMarker(MarkerTag.ClassDeclaration_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.ClassDeclaration_extendsClause);
-    _writeOptionalNode(node.extendsClause);
-    _writeMarker(MarkerTag.ClassDeclaration_withClause);
-    _writeOptionalNode(node.withClause);
-    _writeMarker(MarkerTag.ClassDeclaration_implementsClause);
-    _writeOptionalNode(node.implementsClause);
-    _writeMarker(MarkerTag.ClassDeclaration_nativeClause);
-    _writeOptionalNode(node.nativeClause);
-    _writeMarker(MarkerTag.ClassDeclaration_namedCompilationUnitMember);
-    _storeNamedCompilationUnitMember(node);
-    _writeMarker(MarkerTag.ClassDeclaration_end);
-    _writeUInt30(resolutionIndex);
-
-    _classMemberIndexItems.clear();
-    _writeNodeList(node.members);
-    _hasConstConstructor = false;
-
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
-
-    // TODO(scheglov) write member index
-    var classIndexOffset = _sink.offset;
-    _writeClassMemberIndex();
-
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: classOffset,
-        tag: Tag.Class,
-        name: Either2.t1(node.name.name),
-        classIndexOffset: classIndexOffset,
-      ),
-    );
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.ClassTypeAlias,
-        name: Either2.t1(node.name.name),
-      ),
-    );
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _writeByte(Tag.ClassTypeAlias);
-    _writeByte(
-      AstBinaryFlags.encode(
-        isAbstract: node.abstractKeyword != null,
-      ),
-    );
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as ClassElementImpl;
-      resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
-    }
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _pushScopeTypeParameters(node.typeParameters);
-    _writeMarker(MarkerTag.ClassTypeAlias_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.ClassTypeAlias_superclass);
-    _writeNode(node.superclass);
-    _writeMarker(MarkerTag.ClassTypeAlias_withClause);
-    _writeNode(node.withClause);
-    _writeMarker(MarkerTag.ClassTypeAlias_implementsClause);
-    _writeOptionalNode(node.implementsClause);
-    _writeMarker(MarkerTag.ClassTypeAlias_typeAlias);
-    _storeTypeAlias(node);
-    _writeMarker(MarkerTag.ClassTypeAlias_end);
-    _writeDocumentationCommentString(node.documentationComment);
-    _writeUInt30(resolutionIndex);
-
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
-  }
-
-  @override
-  void visitCompilationUnit(CompilationUnit node) {
-    var nodeImpl = node as CompilationUnitImpl;
-    _writeLanguageVersion(nodeImpl.languageVersion!);
-    _writeFeatureSet(node.featureSet);
-    _writeLineInfo(node.lineInfo!);
-    _writeUInt30(_withInformative ? node.length : 0);
-    _writeNodeList(node.directives);
-    for (var declaration in node.declarations) {
-      declaration.accept(this);
-    }
   }
 
   @override
   void visitConditionalExpression(ConditionalExpression node) {
     _writeByte(Tag.ConditionalExpression);
-    _writeMarker(MarkerTag.ConditionalExpression_condition);
     _writeNode(node.condition);
-    _writeMarker(MarkerTag.ConditionalExpression_thenExpression);
     _writeNode(node.thenExpression);
-    _writeMarker(MarkerTag.ConditionalExpression_elseExpression);
     _writeNode(node.elseExpression);
     _storeExpression(node);
   }
@@ -352,83 +150,9 @@
       ),
     );
 
-    _writeMarker(MarkerTag.Configuration_name);
     _writeNode(node.name);
-    _writeMarker(MarkerTag.Configuration_value);
     _writeOptionalNode(node.value);
-    _writeMarker(MarkerTag.Configuration_uri);
     _writeNode(node.uri);
-    _writeMarker(MarkerTag.Configuration_end);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    _classMemberIndexItems.add(
-      _ClassMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.ConstructorDeclaration,
-        name: node.name?.name ?? '',
-      ),
-    );
-
-    _writeByte(Tag.ConstructorDeclaration);
-
-    _writeByte(
-      AstBinaryFlags.encode(
-        hasName: node.name != null,
-        hasSeparatorColon: node.separator?.type == TokenType.COLON,
-        hasSeparatorEquals: node.separator?.type == TokenType.EQ,
-        isAbstract: node.body is EmptyFunctionBody,
-        isConst: node.constKeyword != null,
-        isExternal: node.externalKeyword != null,
-        isFactory: node.factoryKeyword != null,
-      ),
-    );
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-    _writeMarker(MarkerTag.ConstructorDeclaration_returnType);
-    _writeNode(node.returnType);
-
-    var period = node.period;
-    if (period != null) {
-      _writeInformativeUint30(period.offset);
-      _writeDeclarationName(node.name!);
-    }
-
-    _writeMarker(MarkerTag.ConstructorDeclaration_parameters);
-    _writeNode(node.parameters);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.localElements.pushScope();
-      for (var parameter in node.parameters.parameters) {
-        resolutionSink.localElements.declare(parameter.declaredElement!);
-      }
-    }
-
-    // TODO(scheglov) Not nice, we skip both resolution and AST.
-    // But eventually we want to store full AST, and partial resolution.
-    _writeMarker(MarkerTag.ConstructorDeclaration_initializers);
-    if (node.constKeyword != null) {
-      _writeNodeList(node.initializers);
-    } else {
-      _writeNodeList(const <ConstructorInitializer>[]);
-    }
-
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
-
-    _writeMarker(MarkerTag.ConstructorDeclaration_redirectedConstructor);
-    _writeOptionalNode(node.redirectedConstructor);
-    _writeMarker(MarkerTag.ConstructorDeclaration_classMember);
-    _storeClassMember(node);
-    _writeMarker(MarkerTag.ConstructorDeclaration_end);
-    _writeUInt30(resolutionIndex);
   }
 
   @override
@@ -441,37 +165,24 @@
       ),
     );
 
-    _writeMarker(MarkerTag.ConstructorFieldInitializer_fieldName);
     _writeNode(node.fieldName);
-    _writeMarker(MarkerTag.ConstructorFieldInitializer_expression);
     _writeNode(node.expression);
-    _writeMarker(MarkerTag.ConstructorFieldInitializer_end);
   }
 
   @override
   void visitConstructorName(ConstructorName node) {
     _writeByte(Tag.ConstructorName);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      // When we parse `C() = A.named` we don't know that `A` is a class name.
-      // We parse it as a `TypeName(PrefixedIdentifier)`.
-      // But when we resolve, we rewrite it.
-      // We need to inform the applier about the right shape of the AST.
-      resolutionSink.writeByte(node.name != null ? 1 : 0);
-    }
+    // When we parse `C() = A.named` we don't know that `A` is a class name.
+    // We parse it as a `TypeName(PrefixedIdentifier)`.
+    // But when we resolve, we rewrite it.
+    // We need to inform the applier about the right shape of the AST.
+    // _sink.writeByte(node.name != null ? 1 : 0);
 
-    _writeMarker(MarkerTag.ConstructorName_type);
     _writeNode(node.type);
-    _writeMarker(MarkerTag.ConstructorName_name);
     _writeOptionalNode(node.name);
 
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.ConstructorName_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-    }
-
-    _writeMarker(MarkerTag.ConstructorName_end);
+    _sink.writeElement(node.staticElement);
   }
 
   @override
@@ -484,13 +195,9 @@
         isVar: node.keyword?.keyword == Keyword.VAR,
       ),
     );
-    _writeMarker(MarkerTag.DeclaredIdentifier_type);
     _writeOptionalNode(node.type);
-    _writeMarker(MarkerTag.DeclaredIdentifier_identifier);
     _writeDeclarationName(node.identifier);
-    _writeMarker(MarkerTag.DeclaredIdentifier_declaration);
     _storeDeclaration(node);
-    _writeMarker(MarkerTag.DeclaredIdentifier_end);
   }
 
   @override
@@ -505,19 +212,13 @@
       ),
     );
 
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-
-    _writeMarker(MarkerTag.DefaultFormalParameter_parameter);
     _writeNode(node.parameter);
 
     var defaultValue = node.defaultValue;
     if (!_isSerializableExpression(defaultValue)) {
       defaultValue = null;
     }
-    _writeMarker(MarkerTag.DefaultFormalParameter_defaultValue);
     _writeOptionalNode(defaultValue);
-    _writeMarker(MarkerTag.DefaultFormalParameter_end);
   }
 
   @override
@@ -530,240 +231,49 @@
   void visitDoubleLiteral(DoubleLiteral node) {
     _writeByte(Tag.DoubleLiteral);
     _writeDouble(node.value);
-  }
-
-  @override
-  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    var resolutionIndex = _getNextResolutionIndex();
-    _writeByte(Tag.EnumConstantDeclaration);
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    _writeMarker(MarkerTag.EnumConstantDeclaration_name);
-    _writeDeclarationName(node.name);
-    _writeMarker(MarkerTag.EnumConstantDeclaration_declaration);
-    _storeDeclaration(node);
-    _writeMarker(MarkerTag.EnumConstantDeclaration_end);
-    _writeUInt30(resolutionIndex);
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    var resolutionIndex = _getNextResolutionIndex();
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.EnumDeclaration,
-        name: Either2.t1(node.name.name),
-      ),
-    );
-
-    _writeByte(Tag.EnumDeclaration);
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    _writeMarker(MarkerTag.EnumDeclaration_constants);
-    _writeNodeList(node.constants);
-    _writeMarker(MarkerTag.EnumDeclaration_namedCompilationUnitMember);
-    _storeNamedCompilationUnitMember(node);
-    _writeMarker(MarkerTag.EnumDeclaration_end);
-    _writeUInt30(resolutionIndex);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _writeByte(Tag.ExportDirective);
-    _writeMarker(MarkerTag.ExportDirective_namespaceDirective);
-    _storeNamespaceDirective(node);
-    _writeUInt30(resolutionIndex);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.ExportDirective_exportedLibrary);
-      resolutionSink.writeElement(
-        (node.element as ExportElementImpl).exportedLibrary,
-      );
-    }
-
-    _writeMarker(MarkerTag.ExportDirective_end);
-  }
-
-  @override
-  void visitExtendsClause(ExtendsClause node) {
-    _writeByte(Tag.ExtendsClause);
-    _writeMarker(MarkerTag.ExtendsClause_superclass);
-    _writeNode(node.superclass);
-    _writeMarker(MarkerTag.ExtendsClause_end);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    var classOffset = _sink.offset;
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _writeByte(Tag.ExtensionDeclaration);
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    _pushScopeTypeParameters(node.typeParameters);
-    _writeMarker(MarkerTag.ExtensionDeclaration_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.ExtensionDeclaration_extendedType);
-    _writeNode(node.extendedType);
-    _writeOptionalDeclarationName(node.name);
-    _writeMarker(MarkerTag.ExtensionDeclaration_compilationUnitMember);
-    _storeCompilationUnitMember(node);
-    _writeMarker(MarkerTag.ExtensionDeclaration_end);
-    _writeUInt30(resolutionIndex);
-
-    _classMemberIndexItems.clear();
-    _writeNodeList(node.members);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
-
-    // TODO(scheglov) write member index
-    var classIndexOffset = _sink.offset;
-    _writeClassMemberIndex();
-
-    var nameIdentifier = node.name;
-    var indexName = nameIdentifier != null
-        ? nameIdentifier.name
-        : 'extension-${_nextUnnamedExtensionId++}';
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: classOffset,
-        tag: Tag.ExtensionDeclaration,
-        name: Either2.t1(indexName),
-        classIndexOffset: classIndexOffset,
-      ),
-    );
+    _storeExpression(node);
   }
 
   @override
   void visitExtensionOverride(ExtensionOverride node) {
     _writeByte(Tag.ExtensionOverride);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.writeByte(MethodInvocationRewriteTag.extensionOverride);
-    }
-
-    _writeMarker(MarkerTag.ExtensionOverride_extensionName);
     _writeNode(node.extensionName);
-    _writeMarker(MarkerTag.ExtensionOverride_typeArguments);
     _writeOptionalNode(node.typeArguments);
-    _writeMarker(MarkerTag.ExtensionOverride_argumentList);
     _writeNode(node.argumentList);
-    _writeMarker(MarkerTag.ExtensionOverride_extendedType);
 
-    if (resolutionSink != null) {
-      resolutionSink.writeType(node.extendedType);
-    }
+    _sink.writeType(node.extendedType);
 
-    _writeMarker(MarkerTag.ExtensionOverride_end);
     // TODO(scheglov) typeArgumentTypes?
   }
 
   @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    _classMemberIndexItems.add(
-      _ClassMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.FieldDeclaration,
-        fieldNames: node.fields.variables.map((e) => e.name.name).toList(),
-      ),
-    );
-
-    _writeByte(Tag.FieldDeclaration);
-    _writeByte(
-      AstBinaryFlags.encode(
-        isAbstract: node.abstractKeyword != null,
-        isCovariant: node.covariantKeyword != null,
-        isExternal: node.externalKeyword != null,
-        isStatic: node.staticKeyword != null,
-      ),
-    );
-
-    _writeInformativeVariableCodeRanges(node.offset, node.fields);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _shouldStoreVariableInitializers = node.fields.isConst ||
-        _hasConstConstructor && node.fields.isFinal && !node.isStatic;
-    try {
-      _writeMarker(MarkerTag.FieldDeclaration_fields);
-      _writeNode(node.fields);
-    } finally {
-      _shouldStoreVariableInitializers = false;
-    }
-
-    _writeMarker(MarkerTag.FieldDeclaration_classMember);
-    _storeClassMember(node);
-    _writeMarker(MarkerTag.FieldDeclaration_end);
-
-    _writeUInt30(resolutionIndex);
-  }
-
-  @override
   void visitFieldFormalParameter(FieldFormalParameter node) {
     _writeByte(Tag.FieldFormalParameter);
 
     _pushScopeTypeParameters(node.typeParameters);
-    _writeMarker(MarkerTag.FieldFormalParameter_typeParameters);
     _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.FieldFormalParameter_type);
     _writeOptionalNode(node.type);
-    _writeMarker(MarkerTag.FieldFormalParameter_parameters);
     _writeOptionalNode(node.parameters);
-    _writeMarker(MarkerTag.FieldFormalParameter_normalFormalParameter);
     _storeNormalFormalParameter(
       node,
       node.keyword,
       hasQuestion: node.question != null,
     );
-    _writeMarker(MarkerTag.FieldFormalParameter_end);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
+    _sink.localElements.popScope();
   }
 
   @override
   void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
     _writeByte(Tag.ForEachPartsWithDeclaration);
-    _writeMarker(MarkerTag.ForEachPartsWithDeclaration_loopVariable);
     _writeNode(node.loopVariable);
-    _writeMarker(MarkerTag.ForEachPartsWithDeclaration_forEachParts);
     _storeForEachParts(node);
-    _writeMarker(MarkerTag.ForEachPartsWithDeclaration_end);
   }
 
   @override
   void visitForElement(ForElement node) {
-    _writeByte(Tag.ForElement);
-    _writeByte(
-      AstBinaryFlags.encode(
-        hasAwait: node.awaitKeyword != null,
-      ),
-    );
-    _writeMarker(MarkerTag.ForElement_forLoopParts);
-    _writeNode(node.forLoopParts);
-    _writeMarker(MarkerTag.ForElement_body);
-    _writeNode(node.body);
-    _writeMarker(MarkerTag.ForElement_end);
+    _writeNotSerializableExpression();
   }
 
   @override
@@ -778,169 +288,34 @@
       ),
     );
 
-    _writeMarker(MarkerTag.FormalParameterList_parameters);
     _writeNodeList(node.parameters);
-    _writeMarker(MarkerTag.FormalParameterList_end);
   }
 
   @override
   void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
     _writeByte(Tag.ForPartsWithDeclarations);
-    _writeMarker(MarkerTag.ForPartsWithDeclarations_variables);
     _writeNode(node.variables);
-    _writeMarker(MarkerTag.ForPartsWithDeclarations_forParts);
     _storeForParts(node);
-    _writeMarker(MarkerTag.ForPartsWithDeclarations_end);
   }
 
   @override
   void visitForPartsWithExpression(ForPartsWithExpression node) {
     _writeByte(Tag.ForPartsWithExpression);
-    _writeMarker(MarkerTag.ForPartsWithExpression_initialization);
     _writeOptionalNode(node.initialization);
-    _writeMarker(MarkerTag.ForPartsWithExpression_forParts);
     _storeForParts(node);
-    _writeMarker(MarkerTag.ForPartsWithExpression_end);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    var indexTag = Tag.FunctionDeclaration;
-    if (node.isGetter) {
-      indexTag = Tag.FunctionDeclaration_getter;
-    } else if (node.isSetter) {
-      indexTag = Tag.FunctionDeclaration_setter;
-    }
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: _sink.offset,
-        tag: indexTag,
-        name: Either2.t1(node.name.name),
-      ),
-    );
-
-    _writeByte(Tag.FunctionDeclaration);
-
-    _writeByte(
-      AstBinaryFlags.encode(
-        isExternal: node.externalKeyword != null,
-        isGet: node.isGetter,
-        isSet: node.isSetter,
-      ),
-    );
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _pushScopeTypeParameters(node.functionExpression.typeParameters);
-
-    _writeMarker(MarkerTag.FunctionDeclaration_functionExpression);
-    _writeNode(node.functionExpression);
-    _writeMarker(MarkerTag.FunctionDeclaration_returnType);
-    _writeOptionalNode(node.returnType);
-    _writeMarker(MarkerTag.FunctionDeclaration_namedCompilationUnitMember);
-    _storeNamedCompilationUnitMember(node);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as ExecutableElementImpl;
-      _writeMarker(MarkerTag.FunctionDeclaration_returnTypeType);
-      _writeActualReturnType(resolutionSink, element.returnType);
-      resolutionSink.localElements.popScope();
-    }
-
-    _writeMarker(MarkerTag.FunctionDeclaration_end);
-
-    _writeUInt30(resolutionIndex);
   }
 
   @override
   void visitFunctionExpression(FunctionExpression node) {
-    _writeByte(Tag.FunctionExpression);
-
-    var body = node.body;
-    _writeByte(
-      AstBinaryFlags.encode(
-        isAsync: body.isAsynchronous,
-        isGenerator: body.isGenerator,
-      ),
-    );
-
-    _writeMarker(MarkerTag.FunctionExpression_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.FunctionExpression_parameters);
-    _writeOptionalNode(node.parameters);
-    _writeMarker(MarkerTag.FunctionExpression_end);
+    _writeNotSerializableExpression();
   }
 
   @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     _writeByte(Tag.FunctionExpressionInvocation);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.writeByte(
-        MethodInvocationRewriteTag.functionExpressionInvocation,
-      );
-    }
-
-    _writeMarker(MarkerTag.FunctionExpressionInvocation_function);
     _writeNode(node.function);
-    _writeMarker(MarkerTag.FunctionExpressionInvocation_invocationExpression);
     _storeInvocationExpression(node);
-    _writeMarker(MarkerTag.FunctionExpressionInvocation_end);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.FunctionTypeAlias,
-        name: Either2.t1(node.name.name),
-      ),
-    );
-
-    _writeByte(Tag.FunctionTypeAlias);
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _pushScopeTypeParameters(node.typeParameters);
-
-    _writeMarker(MarkerTag.FunctionTypeAlias_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.FunctionTypeAlias_returnType);
-    _writeOptionalNode(node.returnType);
-    _writeMarker(MarkerTag.FunctionTypeAlias_parameters);
-    _writeNode(node.parameters);
-
-    _writeMarker(MarkerTag.FunctionTypeAlias_typeAlias);
-    _storeTypeAlias(node);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as TypeAliasElementImpl;
-      var function = element.aliasedElement as GenericFunctionTypeElement;
-      _writeMarker(MarkerTag.FunctionTypeAlias_returnTypeType);
-      _writeActualReturnType(resolutionSink, function.returnType);
-      // TODO(scheglov) pack into one byte
-      _writeMarker(MarkerTag.FunctionTypeAlias_flags);
-      resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
-      resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
-
-      resolutionSink.localElements.popScope();
-    }
-
-    _writeMarker(MarkerTag.FunctionTypeAlias_end);
-
-    _writeUInt30(resolutionIndex);
   }
 
   @override
@@ -948,20 +323,12 @@
     _writeByte(Tag.FunctionTypedFormalParameter);
 
     _pushScopeTypeParameters(node.typeParameters);
-    _writeMarker(MarkerTag.FunctionTypedFormalParameter_typeParameters);
     _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.FunctionTypedFormalParameter_returnType);
     _writeOptionalNode(node.returnType);
-    _writeMarker(MarkerTag.FunctionTypedFormalParameter_parameters);
     _writeNode(node.parameters);
-    _writeMarker(MarkerTag.FunctionTypedFormalParameter_normalFormalParameter);
     _storeNormalFormalParameter(node, null);
-    _writeMarker(MarkerTag.FunctionTypedFormalParameter_end);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
+    _sink.localElements.popScope();
   }
 
   @override
@@ -976,123 +343,26 @@
 
     _pushScopeTypeParameters(node.typeParameters);
 
-    _writeMarker(MarkerTag.GenericFunctionType_typeParameters);
     _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.GenericFunctionType_returnType);
     _writeOptionalNode(node.returnType);
-    _writeMarker(MarkerTag.GenericFunctionType_parameters);
     _writeNode(node.parameters);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.GenericFunctionType_type);
-      resolutionSink.writeType(node.type);
-      resolutionSink.localElements.popScope();
-    }
-
-    _writeMarker(MarkerTag.GenericFunctionType_end);
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.GenericTypeAlias,
-        name: Either2.t1(node.name.name),
-      ),
-    );
-
-    _writeByte(Tag.GenericTypeAlias);
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _pushScopeTypeParameters(node.typeParameters);
-
-    _writeMarker(MarkerTag.GenericTypeAlias_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.GenericTypeAlias_type);
-    _writeNode(node.type);
-    _writeMarker(MarkerTag.GenericTypeAlias_typeAlias);
-    _storeTypeAlias(node);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as TypeAliasElementImpl;
-      // TODO(scheglov) pack into one byte
-      _writeMarker(MarkerTag.GenericTypeAlias_flags);
-      resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
-      resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
-      resolutionSink.localElements.popScope();
-    }
-
-    _writeMarker(MarkerTag.GenericTypeAlias_end);
-
-    _writeUInt30(resolutionIndex);
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    _writeByte(Tag.HideCombinator);
-    _writeInformativeUint30(node.keyword.offset);
-    _writeNodeList(node.hiddenNames);
+    _sink.writeType(node.type);
+    _sink.localElements.popScope();
   }
 
   @override
   void visitIfElement(IfElement node) {
     _writeByte(Tag.IfElement);
-    _writeMarker(MarkerTag.IfElement_condition);
     _writeNode(node.condition);
-    _writeMarker(MarkerTag.IfElement_thenElement);
     _writeNode(node.thenElement);
-    _writeMarker(MarkerTag.IfElement_elseElement);
     _writeOptionalNode(node.elseElement);
-    _writeMarker(MarkerTag.IfElement_end);
   }
 
   @override
   void visitImplementsClause(ImplementsClause node) {
     _writeByte(Tag.ImplementsClause);
-    _writeMarker(MarkerTag.ImplementsClause_interfaces);
     _writeNodeList(node.interfaces);
-    _writeMarker(MarkerTag.ImplementsClause_end);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _writeByte(Tag.ImportDirective);
-
-    var prefix = node.prefix;
-    _writeByte(
-      AstBinaryFlags.encode(
-        hasPrefix: prefix != null,
-        isDeferred: node.deferredKeyword != null,
-      ),
-    );
-
-    if (prefix != null) {
-      _writeStringReference(prefix.name);
-      _writeInformativeUint30(prefix.offset);
-    }
-
-    _writeMarker(MarkerTag.ImportDirective_namespaceDirective);
-    _storeNamespaceDirective(node);
-    _writeUInt30(resolutionIndex);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.element as ImportElementImpl;
-      _writeMarker(MarkerTag.ImportDirective_importedLibrary);
-      resolutionSink.writeElement(element.importedLibrary);
-    }
-
-    _writeMarker(MarkerTag.ImportDirective_end);
   }
 
   @override
@@ -1104,39 +374,18 @@
         hasQuestion: node.question != null,
       ),
     );
-    _writeMarker(MarkerTag.IndexExpression_target);
     _writeOptionalNode(node.target);
-    _writeMarker(MarkerTag.IndexExpression_index);
     _writeNode(node.index);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.IndexExpression_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-    }
+    _sink.writeElement(node.staticElement);
 
-    _writeMarker(MarkerTag.IndexExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.IndexExpression_end);
   }
 
   @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
     _writeByte(Tag.InstanceCreationExpression);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      if (node.constructorName.name != null) {
-        resolutionSink.writeByte(
-          MethodInvocationRewriteTag.instanceCreationExpression_withName,
-        );
-      } else {
-        resolutionSink.writeByte(
-          MethodInvocationRewriteTag.instanceCreationExpression_withoutName,
-        );
-      }
-    }
-
     _writeByte(
       AstBinaryFlags.encode(
         isConst: node.keyword?.type == Keyword.CONST,
@@ -1144,13 +393,9 @@
       ),
     );
 
-    _writeMarker(MarkerTag.InstanceCreationExpression_constructorName);
     _writeNode(node.constructorName);
-    _writeMarker(MarkerTag.InstanceCreationExpression_argumentList);
     _writeNode(node.argumentList);
-    _writeMarker(MarkerTag.InstanceCreationExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.InstanceCreationExpression_end);
   }
 
   @override
@@ -1212,27 +457,15 @@
         hasNot: node.notOperator != null,
       ),
     );
-    _writeMarker(MarkerTag.IsExpression_expression);
     _writeNode(node.expression);
-    _writeMarker(MarkerTag.IsExpression_type);
     _writeNode(node.type);
-    _writeMarker(MarkerTag.IsExpression_expression2);
     _storeExpression(node);
-    _writeMarker(MarkerTag.IsExpression_end);
   }
 
   @override
-  void visitLibraryDirective(LibraryDirective node) {
-    _writeByte(Tag.LibraryDirective);
-    _writeDocumentationCommentString(node.documentationComment);
-    visitLibraryIdentifier(node.name);
-    _storeDirective(node);
-  }
-
-  @override
-  void visitLibraryIdentifier(LibraryIdentifier node) {
-    _writeByte(Tag.LibraryIdentifier);
-    _writeNodeList(node.components);
+  void visitLabel(Label node) {
+    _writeByte(Tag.Label);
+    _writeNode(node.label);
   }
 
   @override
@@ -1245,173 +478,32 @@
       ),
     );
 
-    _writeMarker(MarkerTag.ListLiteral_typeArguments);
     _writeOptionalNode(node.typeArguments);
-    _writeMarker(MarkerTag.ListLiteral_elements);
     _writeNodeList(node.elements);
 
-    _writeMarker(MarkerTag.ListLiteral_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.ListLiteral_end);
   }
 
   @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     _writeByte(Tag.MapLiteralEntry);
-    _writeMarker(MarkerTag.MapLiteralEntry_key);
     _writeNode(node.key);
-    _writeMarker(MarkerTag.MapLiteralEntry_value);
     _writeNode(node.value);
   }
 
   @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    var indexTag = Tag.MethodDeclaration;
-    if (node.isGetter) {
-      indexTag = Tag.MethodDeclaration_getter;
-    } else if (node.isSetter) {
-      indexTag = Tag.MethodDeclaration_setter;
-    }
-    _classMemberIndexItems.add(
-      _ClassMemberIndexItem(
-        offset: _sink.offset,
-        tag: indexTag,
-        name: node.name.name,
-      ),
-    );
-
-    _writeByte(Tag.MethodDeclaration);
-
-    _writeUInt30(
-      AstBinaryFlags.encode(
-        isAbstract: node.body is EmptyFunctionBody,
-        isAsync: node.body.isAsynchronous,
-        isExternal: node.externalKeyword != null,
-        isGenerator: node.body.isGenerator,
-        isGet: node.isGetter,
-        isNative: node.body is NativeFunctionBody,
-        isOperator: node.operatorKeyword != null,
-        isSet: node.isSetter,
-        isStatic: node.isStatic,
-      ),
-    );
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _pushScopeTypeParameters(node.typeParameters);
-
-    _writeDeclarationName(node.name);
-    _writeMarker(MarkerTag.MethodDeclaration_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.MethodDeclaration_returnType);
-    _writeOptionalNode(node.returnType);
-    _writeMarker(MarkerTag.MethodDeclaration_parameters);
-    _writeOptionalNode(node.parameters);
-
-    _writeMarker(MarkerTag.MethodDeclaration_classMember);
-    _storeClassMember(node);
-
-    _writeUInt30(resolutionIndex);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as ExecutableElementImpl;
-      _writeMarker(MarkerTag.MethodDeclaration_returnTypeType);
-      _writeActualReturnType(resolutionSink, element.returnType);
-      _writeMarker(MarkerTag.MethodDeclaration_inferenceError);
-      _writeTopLevelInferenceError(resolutionSink, element);
-      // TODO(scheglov) move this flag into ClassElementImpl?
-      if (element is MethodElementImpl) {
-        _writeMarker(MarkerTag.MethodDeclaration_flags);
-        resolutionSink.writeByte(
-          element.isOperatorEqualWithParameterTypeFromObject ? 1 : 0,
-        );
-      }
-      resolutionSink.localElements.popScope();
-    }
-
-    _writeMarker(MarkerTag.MethodDeclaration_end);
-  }
-
-  @override
   void visitMethodInvocation(MethodInvocation node) {
     _writeByte(Tag.MethodInvocation);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      resolutionSink.writeByte(MethodInvocationRewriteTag.none);
-    }
-
     _writeByte(
       AstBinaryFlags.encode(
         hasPeriod: node.operator?.type == TokenType.PERIOD,
         hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
       ),
     );
-    _writeMarker(MarkerTag.MethodInvocation_target);
     _writeOptionalNode(node.target);
-    _writeMarker(MarkerTag.MethodInvocation_methodName);
     _writeNode(node.methodName);
-    _writeMarker(MarkerTag.MethodInvocation_invocationExpression);
     _storeInvocationExpression(node);
-    _writeMarker(MarkerTag.MethodInvocation_end);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    var classOffset = _sink.offset;
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _writeByte(Tag.MixinDeclaration);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as MixinElementImpl;
-      resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
-      resolutionSink.writeStringList(element.superInvokedNames);
-    }
-
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    _pushScopeTypeParameters(node.typeParameters);
-
-    _writeMarker(MarkerTag.MixinDeclaration_typeParameters);
-    _writeOptionalNode(node.typeParameters);
-    _writeMarker(MarkerTag.MixinDeclaration_onClause);
-    _writeOptionalNode(node.onClause);
-    _writeMarker(MarkerTag.MixinDeclaration_implementsClause);
-    _writeOptionalNode(node.implementsClause);
-    _writeMarker(MarkerTag.MixinDeclaration_namedCompilationUnitMember);
-    _storeNamedCompilationUnitMember(node);
-    _writeMarker(MarkerTag.MixinDeclaration_end);
-    _writeUInt30(resolutionIndex);
-
-    _classMemberIndexItems.clear();
-    _writeNodeList(node.members);
-    _hasConstConstructor = false;
-
-    if (resolutionSink != null) {
-      resolutionSink.localElements.popScope();
-    }
-
-    // TODO(scheglov) write member index
-    var classIndexOffset = _sink.offset;
-    _writeClassMemberIndex();
-
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: classOffset,
-        tag: Tag.MixinDeclaration,
-        name: Either2.t1(node.name.name),
-        classIndexOffset: classIndexOffset,
-      ),
-    );
   }
 
   @override
@@ -1420,19 +512,14 @@
 
     var nameNode = node.name.label;
     _writeStringReference(nameNode.name);
-    _writeInformativeUint30(nameNode.offset);
 
-    _writeMarker(MarkerTag.NamedExpression_expression);
     _writeNode(node.expression);
-    _writeMarker(MarkerTag.NamedExpression_end);
   }
 
   @override
   void visitNativeClause(NativeClause node) {
     _writeByte(Tag.NativeClause);
-    _writeMarker(MarkerTag.NativeClause_name);
     _writeOptionalNode(node.name);
-    _writeMarker(MarkerTag.NativeClause_end);
   }
 
   @override
@@ -1443,82 +530,44 @@
   @override
   void visitOnClause(OnClause node) {
     _writeByte(Tag.OnClause);
-    _writeMarker(MarkerTag.OnClause_superclassConstraints);
     _writeNodeList(node.superclassConstraints);
-    _writeMarker(MarkerTag.OnClause_end);
   }
 
   @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     _writeByte(Tag.ParenthesizedExpression);
-    _writeMarker(MarkerTag.ParenthesizedExpression_expression);
     _writeNode(node.expression);
-    _writeMarker(MarkerTag.ParenthesizedExpression_expression2);
     _storeExpression(node);
-    _writeMarker(MarkerTag.ParenthesizedExpression_end);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    _writeByte(Tag.PartDirective);
-    _storeUriBasedDirective(node);
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    _writeByte(Tag.PartOfDirective);
-    _writeMarker(MarkerTag.PartOfDirective_libraryName);
-    _writeOptionalNode(node.libraryName);
-    _writeMarker(MarkerTag.PartOfDirective_uri);
-    _writeOptionalNode(node.uri);
-    _writeMarker(MarkerTag.PartOfDirective_directive);
-    _storeDirective(node);
-    _writeMarker(MarkerTag.PartOfDirective_end);
   }
 
   @override
   void visitPostfixExpression(PostfixExpression node) {
     _writeByte(Tag.PostfixExpression);
 
-    _writeMarker(MarkerTag.PostfixExpression_operand);
     _writeNode(node.operand);
 
     var operatorToken = node.operator.type;
     var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
     _writeByte(binaryToken.index);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.PostfixExpression_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-      if (operatorToken.isIncrementOperator) {
-        _writeMarker(MarkerTag.PostfixExpression_readElement);
-        resolutionSink.writeElement(node.readElement);
-        _writeMarker(MarkerTag.PostfixExpression_readType);
-        resolutionSink.writeType(node.readType);
-        _writeMarker(MarkerTag.PostfixExpression_writeElement);
-        resolutionSink.writeElement(node.writeElement);
-        _writeMarker(MarkerTag.PostfixExpression_writeType);
-        resolutionSink.writeType(node.writeType);
-      }
+    _sink.writeElement(node.staticElement);
+    if (operatorToken.isIncrementOperator) {
+      _sink.writeElement(node.readElement);
+      _sink.writeType(node.readType);
+      _sink.writeElement(node.writeElement);
+      _sink.writeType(node.writeType);
     }
-    _writeMarker(MarkerTag.PostfixExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.PostfixExpression_end);
   }
 
   @override
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
     _writeByte(Tag.PrefixedIdentifier);
-    _writeMarker(MarkerTag.PrefixedIdentifier_prefix);
     _writeNode(node.prefix);
-    _writeMarker(MarkerTag.PrefixedIdentifier_identifier);
     _writeNode(node.identifier);
 
     // TODO(scheglov) In actual prefixed identifier, the type of the identifier.
-    _writeMarker(MarkerTag.PrefixedIdentifier_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.PrefixedIdentifier_end);
   }
 
   @override
@@ -1529,28 +578,17 @@
     var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
     _writeByte(binaryToken.index);
 
-    _writeMarker(MarkerTag.PrefixExpression_operand);
     _writeNode(node.operand);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.PrefixExpression_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-      if (operatorToken.isIncrementOperator) {
-        _writeMarker(MarkerTag.PrefixExpression_readElement);
-        resolutionSink.writeElement(node.readElement);
-        _writeMarker(MarkerTag.PrefixExpression_readType);
-        resolutionSink.writeType(node.readType);
-        _writeMarker(MarkerTag.PrefixExpression_writeElement);
-        resolutionSink.writeElement(node.writeElement);
-        _writeMarker(MarkerTag.PrefixExpression_writeType);
-        resolutionSink.writeType(node.writeType);
-      }
+    _sink.writeElement(node.staticElement);
+    if (operatorToken.isIncrementOperator) {
+      _sink.writeElement(node.readElement);
+      _sink.writeType(node.readType);
+      _sink.writeElement(node.writeElement);
+      _sink.writeType(node.writeType);
     }
 
-    _writeMarker(MarkerTag.PrefixExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.PrefixExpression_end);
   }
 
   @override
@@ -1569,14 +607,10 @@
       ),
     );
 
-    _writeMarker(MarkerTag.PropertyAccess_target);
     _writeOptionalNode(node.target);
-    _writeMarker(MarkerTag.PropertyAccess_propertyName);
     _writeNode(node.propertyName);
     // TODO(scheglov) Get from the property?
-    _writeMarker(MarkerTag.PropertyAccess_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.PropertyAccess_end);
   }
 
   @override
@@ -1584,18 +618,10 @@
       RedirectingConstructorInvocation node) {
     _writeByte(Tag.RedirectingConstructorInvocation);
 
-    _writeMarker(MarkerTag.RedirectingConstructorInvocation_constructorName);
     _writeOptionalNode(node.constructorName);
-    _writeMarker(MarkerTag.RedirectingConstructorInvocation_argumentList);
     _writeNode(node.argumentList);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.RedirectingConstructorInvocation_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-    }
-
-    _writeMarker(MarkerTag.RedirectingConstructorInvocation_end);
+    _sink.writeElement(node.staticElement);
   }
 
   @override
@@ -1608,66 +634,35 @@
       ),
     );
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var isMapBit = node.isMap ? (1 << 0) : 0;
-      var isSetBit = node.isSet ? (1 << 1) : 0;
-      _writeMarker(MarkerTag.SetOrMapLiteral_flags);
-      resolutionSink.writeByte(isMapBit | isSetBit);
-    }
+    var isMapBit = node.isMap ? (1 << 0) : 0;
+    var isSetBit = node.isSet ? (1 << 1) : 0;
+    _sink.writeByte(isMapBit | isSetBit);
 
-    _writeMarker(MarkerTag.SetOrMapLiteral_typeArguments);
     _writeOptionalNode(node.typeArguments);
-    _writeMarker(MarkerTag.SetOrMapLiteral_elements);
     _writeNodeList(node.elements);
 
-    _writeMarker(MarkerTag.SetOrMapLiteral_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.SetOrMapLiteral_end);
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    _writeByte(Tag.ShowCombinator);
-    _writeInformativeUint30(node.keyword.offset);
-    _writeNodeList(node.shownNames);
   }
 
   @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     _writeByte(Tag.SimpleFormalParameter);
 
-    _writeMarker(MarkerTag.SimpleFormalParameter_type);
     _writeOptionalNode(node.type);
-    _writeMarker(MarkerTag.SimpleFormalParameter_normalFormalParameter);
     _storeNormalFormalParameter(node, node.keyword);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as ParameterElementImpl;
-      _writeMarker(MarkerTag.SimpleFormalParameter_flags);
-      resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
-    }
-
-    _writeMarker(MarkerTag.SimpleFormalParameter_end);
+    var element = node.declaredElement as ParameterElementImpl;
+    _sink.writeByte(element.inheritsCovariant ? 1 : 0);
   }
 
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     _writeByte(Tag.SimpleIdentifier);
     _writeStringReference(node.name);
-    _writeInformativeUint30(node.offset);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.SimpleIdentifier_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-      // TODO(scheglov) It is inefficient to write many null types.
-    }
+    _sink.writeElement(node.staticElement);
 
-    _writeMarker(MarkerTag.SimpleIdentifier_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.SimpleIdentifier_end);
   }
 
   @override
@@ -1686,43 +681,29 @@
             node.spreadOperator.type == TokenType.PERIOD_PERIOD_PERIOD_QUESTION,
       ),
     );
-    _writeMarker(MarkerTag.SpreadElement_expression);
     _writeNode(node.expression);
-    _writeMarker(MarkerTag.SpreadElement_end);
   }
 
   @override
   void visitStringInterpolation(StringInterpolation node) {
     _writeByte(Tag.StringInterpolation);
-    _writeMarker(MarkerTag.StringInterpolation_elements);
     _writeNodeList(node.elements);
-    _writeMarker(MarkerTag.StringInterpolation_end);
   }
 
   @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     _writeByte(Tag.SuperConstructorInvocation);
 
-    _writeMarker(MarkerTag.SuperConstructorInvocation_constructorName);
     _writeOptionalNode(node.constructorName);
-    _writeMarker(MarkerTag.SuperConstructorInvocation_argumentList);
     _writeNode(node.argumentList);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.SuperConstructorInvocation_staticElement);
-      resolutionSink.writeElement(node.staticElement);
-    }
-
-    _writeMarker(MarkerTag.SuperConstructorInvocation_end);
+    _sink.writeElement(node.staticElement);
   }
 
   @override
   void visitSuperExpression(SuperExpression node) {
     _writeByte(Tag.SuperExpression);
-    _writeMarker(MarkerTag.SuperExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.SuperExpression_end);
   }
 
   @override
@@ -1740,68 +721,20 @@
   @override
   void visitThisExpression(ThisExpression node) {
     _writeByte(Tag.ThisExpression);
-    _writeMarker(MarkerTag.ThisExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.ThisExpression_end);
   }
 
   @override
   void visitThrowExpression(ThrowExpression node) {
     _writeByte(Tag.ThrowExpression);
-    _writeMarker(MarkerTag.ThrowExpression_expression);
     _writeNode(node.expression);
-    _writeMarker(MarkerTag.ThrowExpression_expression2);
     _storeExpression(node);
-    _writeMarker(MarkerTag.ThrowExpression_end);
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    unitMemberIndexItems.add(
-      _UnitMemberIndexItem(
-        offset: _sink.offset,
-        tag: Tag.TopLevelVariableDeclaration,
-        name: Either2.t2(
-          node.variables.variables
-              .map((variable) => variable.name.name)
-              .toList(),
-        ),
-      ),
-    );
-
-    _writeByte(Tag.TopLevelVariableDeclaration);
-    _writeByte(
-      AstBinaryFlags.encode(
-        isExternal: node.externalKeyword != null,
-      ),
-    );
-
-    _writeInformativeVariableCodeRanges(node.offset, node.variables);
-    _writeDocumentationCommentString(node.documentationComment);
-
-    var resolutionIndex = _getNextResolutionIndex();
-
-    _shouldStoreVariableInitializers = node.variables.isConst;
-    try {
-      _writeMarker(MarkerTag.TopLevelVariableDeclaration_variables);
-      _writeNode(node.variables);
-    } finally {
-      _shouldStoreVariableInitializers = false;
-    }
-
-    _writeMarker(MarkerTag.TopLevelVariableDeclaration_compilationUnitMember);
-    _storeCompilationUnitMember(node);
-    _writeMarker(MarkerTag.TopLevelVariableDeclaration_end);
-
-    _writeUInt30(resolutionIndex);
   }
 
   @override
   void visitTypeArgumentList(TypeArgumentList node) {
     _writeByte(Tag.TypeArgumentList);
-    _writeMarker(MarkerTag.TypeArgumentList_arguments);
     _writeNodeList(node.arguments);
-    _writeMarker(MarkerTag.TypeArgumentList_end);
   }
 
   @override
@@ -1815,87 +748,24 @@
       ),
     );
 
-    _writeMarker(MarkerTag.TypeName_name);
     _writeNode(node.name);
-    _writeMarker(MarkerTag.TypeName_typeArguments);
     _writeOptionalNode(node.typeArguments);
 
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.TypeName_type);
-      resolutionSink.writeType(node.type);
-    }
-
-    _writeMarker(MarkerTag.TypeName_end);
+    _sink.writeType(node.type);
   }
 
   @override
   void visitTypeParameter(TypeParameter node) {
     _writeByte(Tag.TypeParameter);
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
     _writeDeclarationName(node.name);
-    _writeMarker(MarkerTag.TypeParameter_bound);
     _writeOptionalNode(node.bound);
-    _writeMarker(MarkerTag.TypeParameter_declaration);
     _storeDeclaration(node);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as TypeParameterElementImpl;
-      _writeMarker(MarkerTag.TypeParameter_variance);
-      resolutionSink.writeByte(
-        _encodeVariance(element),
-      );
-      _writeMarker(MarkerTag.TypeParameter_defaultType);
-      resolutionSink.writeType(element.defaultType);
-    }
-
-    _writeMarker(MarkerTag.TypeParameter_end);
   }
 
   @override
   void visitTypeParameterList(TypeParameterList node) {
     _writeByte(Tag.TypeParameterList);
-    _writeMarker(MarkerTag.TypeParameterList_typeParameters);
     _writeNodeList(node.typeParameters);
-    _writeMarker(MarkerTag.TypeParameterList_end);
-  }
-
-  @override
-  void visitVariableDeclaration(VariableDeclaration node) {
-    _writeByte(Tag.VariableDeclaration);
-    _writeByte(
-      AstBinaryFlags.encode(
-        hasInitializer: node.initializer != null,
-      ),
-    );
-    _writeDeclarationName(node.name);
-
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      // TODO(scheglov) Enforce not null, remove `?` in `?.type` below.
-      var element = node.declaredElement as VariableElementImpl;
-      _writeMarker(MarkerTag.VariableDeclaration_type);
-      _writeActualType(resolutionSink, element.type);
-      _writeMarker(MarkerTag.VariableDeclaration_inferenceError);
-      _writeTopLevelInferenceError(resolutionSink, element);
-      if (element is FieldElementImpl) {
-        _writeMarker(MarkerTag.VariableDeclaration_inheritsCovariant);
-        resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
-      }
-    }
-
-    Expression? initializerToWrite;
-    if (_shouldStoreVariableInitializers) {
-      var initializer = node.initializer;
-      if (_isSerializableExpression(initializer)) {
-        initializerToWrite = initializer;
-      }
-    }
-    _writeMarker(MarkerTag.VariableDeclaration_initializer);
-    _writeOptionalNode(initializerToWrite);
-    _writeMarker(MarkerTag.VariableDeclaration_end);
   }
 
   @override
@@ -1909,127 +779,66 @@
         isVar: node.keyword?.keyword == Keyword.VAR,
       ),
     );
-    _writeMarker(MarkerTag.VariableDeclarationList_type);
     _writeOptionalNode(node.type);
-    _writeMarker(MarkerTag.VariableDeclarationList_variables);
     _writeNodeList(node.variables);
-    _writeMarker(MarkerTag.VariableDeclarationList_annotatedNode);
     _storeAnnotatedNode(node);
-    _writeMarker(MarkerTag.VariableDeclarationList_end);
   }
 
   @override
   void visitWithClause(WithClause node) {
     _writeByte(Tag.WithClause);
-    _writeMarker(MarkerTag.WithClause_mixinTypes);
     _writeNodeList(node.mixinTypes);
-    _writeMarker(MarkerTag.WithClause_end);
   }
 
   void _pushScopeTypeParameters(TypeParameterList? node) {
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink == null) {
-      return;
-    }
-
-    resolutionSink.localElements.pushScope();
+    _sink.localElements.pushScope();
 
     if (node == null) {
       return;
     }
 
     for (var typeParameter in node.typeParameters) {
-      resolutionSink.localElements.declare(typeParameter.declaredElement!);
+      _sink.localElements.declare(typeParameter.declaredElement!);
     }
   }
 
   void _storeAnnotatedNode(AnnotatedNode node) {
-    _writeMarker(MarkerTag.AnnotatedNode_metadata);
     _writeNodeList(node.metadata);
-    _writeMarker(MarkerTag.AnnotatedNode_end);
-  }
-
-  void _storeClassMember(ClassMember node) {
-    _writeMarker(MarkerTag.ClassMember_declaration);
-    _storeDeclaration(node);
-  }
-
-  void _storeCompilationUnitMember(CompilationUnitMember node) {
-    _storeDeclaration(node);
   }
 
   void _storeDeclaration(Declaration node) {
     _storeAnnotatedNode(node);
   }
 
-  void _storeDirective(Directive node) {
-    _writeInformativeUint30(node.keyword.offset);
-    _storeAnnotatedNode(node);
-  }
-
   void _storeExpression(Expression node) {
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      _writeMarker(MarkerTag.Expression_staticType);
-      resolutionSink.writeType(node.staticType);
-    }
+    _sink.writeType(node.staticType);
   }
 
   void _storeForEachParts(ForEachParts node) {
-    _writeMarker(MarkerTag.ForEachParts_iterable);
     _writeNode(node.iterable);
-    _writeMarker(MarkerTag.ForEachParts_forLoopParts);
     _storeForLoopParts(node);
-    _writeMarker(MarkerTag.ForEachParts_end);
   }
 
   void _storeForLoopParts(ForLoopParts node) {}
 
   void _storeFormalParameter(FormalParameter node) {
-    var resolutionSink = _resolutionSink;
-    if (resolutionSink != null) {
-      var element = node.declaredElement as ParameterElementImpl;
-      _writeMarker(MarkerTag.FormalParameter_type);
-      _writeActualType(resolutionSink, element.type);
-    }
+    var element = node.declaredElement as ParameterElementImpl;
+    _writeActualType(_sink, element.type);
   }
 
   void _storeForParts(ForParts node) {
-    _writeMarker(MarkerTag.ForParts_condition);
     _writeOptionalNode(node.condition);
-    _writeMarker(MarkerTag.ForParts_updaters);
     _writeNodeList(node.updaters);
-    _writeMarker(MarkerTag.ForParts_forLoopParts);
     _storeForLoopParts(node);
-    _writeMarker(MarkerTag.ForParts_end);
   }
 
   void _storeInvocationExpression(InvocationExpression node) {
-    _writeMarker(MarkerTag.InvocationExpression_typeArguments);
     _writeOptionalNode(node.typeArguments);
-    _writeMarker(MarkerTag.InvocationExpression_argumentList);
     _writeNode(node.argumentList);
-    _writeMarker(MarkerTag.InvocationExpression_expression);
     _storeExpression(node);
-    _writeMarker(MarkerTag.InvocationExpression_end);
     // TODO(scheglov) typeArgumentTypes and staticInvokeType?
   }
 
-  void _storeNamedCompilationUnitMember(NamedCompilationUnitMember node) {
-    _writeDeclarationName(node.name);
-    _storeCompilationUnitMember(node);
-  }
-
-  void _storeNamespaceDirective(NamespaceDirective node) {
-    _writeMarker(MarkerTag.NamespaceDirective_combinators);
-    _writeNodeList(node.combinators);
-    _writeMarker(MarkerTag.NamespaceDirective_configurations);
-    _writeNodeList(node.configurations);
-    _writeMarker(MarkerTag.NamespaceDirective_uriBasedDirective);
-    _storeUriBasedDirective(node);
-    _writeMarker(MarkerTag.NamespaceDirective_end);
-  }
-
   void _storeNormalFormalParameter(
     NormalFormalParameter node,
     Token? keyword, {
@@ -2047,34 +856,11 @@
       ),
     );
 
-    // TODO(scheglov) Don't store when in DefaultFormalParameter?
-    _writeInformativeUint30(node.offset);
-    _writeInformativeUint30(node.length);
-
-    _writeMarker(MarkerTag.NormalFormalParameter_metadata);
     _writeNodeList(node.metadata);
     if (node.identifier != null) {
       _writeDeclarationName(node.identifier!);
     }
-    _writeMarker(MarkerTag.NormalFormalParameter_formalParameter);
     _storeFormalParameter(node);
-    _writeMarker(MarkerTag.NormalFormalParameter_end);
-  }
-
-  void _storeTypeAlias(TypeAlias node) {
-    _storeNamedCompilationUnitMember(node);
-  }
-
-  void _storeUriBasedDirective(UriBasedDirective node) {
-    _writeMarker(MarkerTag.UriBasedDirective_uri);
-    _writeNode(node.uri);
-    _writeMarker(MarkerTag.UriBasedDirective_directive);
-    _storeDirective(node);
-    _writeMarker(MarkerTag.UriBasedDirective_end);
-  }
-
-  void _writeActualReturnType(ResolutionSink resolutionSink, DartType type) {
-    resolutionSink.writeType(type);
   }
 
   void _writeActualType(ResolutionSink resolutionSink, DartType type) {
@@ -2086,106 +872,14 @@
     _sink.addByte(byte);
   }
 
-  void _writeClassMemberIndex() {
-    _writeUInt30(_classMemberIndexItems.length);
-    for (var declaration in _classMemberIndexItems) {
-      _writeUInt30(declaration.offset);
-      _writeByte(declaration.tag);
-      if (declaration.name != null) {
-        _writeStringReference(declaration.name!);
-      } else {
-        _writeUInt30(declaration.fieldNames!.length);
-        for (var name in declaration.fieldNames!) {
-          _writeStringReference(name);
-        }
-      }
-    }
-  }
-
   void _writeDeclarationName(SimpleIdentifier node) {
-    _writeByte(Tag.SimpleIdentifier);
     _writeStringReference(node.name);
-    _writeInformativeUint30(node.offset);
-  }
-
-  /// We write tokens as a list, so this must be the last entity written.
-  void _writeDocumentationCommentString(Comment? node) {
-    if (node != null && _withInformative) {
-      var tokens = node.tokens;
-      _writeUInt30(tokens.length);
-      for (var token in tokens) {
-        _writeStringReference(token.lexeme);
-      }
-    } else {
-      _writeUInt30(0);
-    }
   }
 
   _writeDouble(double value) {
     _sink.addDouble(value);
   }
 
-  void _writeFeatureSet(FeatureSet featureSet) {
-    var experimentStatus = featureSet as ExperimentStatus;
-    var encoded = experimentStatus.toStorage();
-    _writeUint8List(encoded);
-  }
-
-  void _writeInformativeUint30(int value) {
-    if (_withInformative) {
-      _writeUInt30(value);
-    }
-  }
-
-  void _writeInformativeVariableCodeRanges(
-    int firstOffset,
-    VariableDeclarationList node,
-  ) {
-    if (_withInformative) {
-      var variables = node.variables;
-      _writeUInt30(variables.length * 2);
-      var isFirst = true;
-      for (var variable in variables) {
-        var offset = isFirst ? firstOffset : variable.offset;
-        var end = variable.end;
-        _writeUInt30(offset);
-        _writeUInt30(end - offset);
-        isFirst = false;
-      }
-    }
-  }
-
-  void _writeLanguageVersion(LibraryLanguageVersion languageVersion) {
-    _writeUInt30(languageVersion.package.major);
-    _writeUInt30(languageVersion.package.minor);
-
-    var override = languageVersion.override;
-    if (override != null) {
-      _writeUInt30(override.major + 1);
-      _writeUInt30(override.minor + 1);
-    } else {
-      _writeUInt30(0);
-      _writeUInt30(0);
-    }
-  }
-
-  void _writeLineInfo(LineInfo lineInfo) {
-    if (_withInformative) {
-      _writeUint30List(lineInfo.lineStarts);
-    } else {
-      _writeUint30List(const <int>[0]);
-    }
-  }
-
-  void _writeMarker(MarkerTag tag) {
-    if (enableDebugResolutionMarkers) {
-      var resolutionSink = _resolutionSink;
-      if (resolutionSink != null) {
-        resolutionSink.writeUInt30(tag.index);
-      }
-    }
-  }
-
   void _writeNode(AstNode node) {
     node.accept(this);
   }
@@ -2197,13 +891,11 @@
     }
   }
 
-  void _writeOptionalDeclarationName(SimpleIdentifier? node) {
-    if (node == null) {
-      _writeByte(Tag.Nothing);
-    } else {
-      _writeByte(Tag.Something);
-      _writeDeclarationName(node);
-    }
+  void _writeNotSerializableExpression() {
+    var node = astFactory.simpleIdentifier(
+      StringToken(TokenType.STRING, '_notSerializableExpression', -1),
+    );
+    node.accept(this);
   }
 
   void _writeOptionalNode(AstNode? node) {
@@ -2220,72 +912,16 @@
     _writeUInt30(index);
   }
 
-  void _writeTopLevelInferenceError(
-    ResolutionSink resolutionSink,
-    ElementImpl element,
-  ) {
-    TopLevelInferenceError? error;
-    if (element is MethodElementImpl) {
-      error = element.typeInferenceError;
-    } else if (element is PropertyInducingElementImpl) {
-      error = element.typeInferenceError;
-    } else {
-      return;
-    }
-
-    if (error != null) {
-      resolutionSink.writeByte(error.kind.index);
-      resolutionSink.writeStringList(error.arguments);
-    } else {
-      resolutionSink.writeByte(TopLevelInferenceErrorKind.none.index);
-    }
-  }
-
   @pragma("vm:prefer-inline")
   void _writeUInt30(int value) {
     _sink.writeUInt30(value);
   }
 
-  void _writeUint30List(List<int> values) {
-    var length = values.length;
-    _writeUInt30(length);
-    for (var i = 0; i < length; i++) {
-      _writeUInt30(values[i]);
-    }
-  }
-
   void _writeUInt32(int value) {
     _sink.addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF,
         (value >> 8) & 0xFF, value & 0xFF);
   }
 
-  void _writeUint8List(List<int> values) {
-    var length = values.length;
-    _writeUInt30(length);
-    for (var i = 0; i < length; i++) {
-      _writeByte(values[i]);
-    }
-  }
-
-  static int _encodeVariance(TypeParameterElementImpl element) {
-    if (element.isLegacyCovariant) {
-      return 0;
-    }
-
-    var variance = element.variance;
-    if (variance == Variance.unrelated) {
-      return 1;
-    } else if (variance == Variance.covariant) {
-      return 2;
-    } else if (variance == Variance.contravariant) {
-      return 3;
-    } else if (variance == Variance.invariant) {
-      return 4;
-    } else {
-      throw UnimplementedError('$variance');
-    }
-  }
-
   /// Return `true` if the expression might be successfully serialized.
   ///
   /// This does not mean that the expression is constant, it just means that
@@ -2301,21 +937,6 @@
   }
 }
 
-/// An item in the class index, used to read only requested class members.
-class _ClassMemberIndexItem {
-  final int offset;
-  final int tag;
-  final String? name;
-  final List<String>? fieldNames;
-
-  _ClassMemberIndexItem({
-    required this.offset,
-    required this.tag,
-    this.name,
-    this.fieldNames,
-  });
-}
-
 class _IsSerializableExpressionVisitor extends RecursiveAstVisitor<void> {
   bool result = true;
 
@@ -2324,20 +945,3 @@
     result = false;
   }
 }
-
-/// An item in the unit index, used to read only requested unit members.
-class _UnitMemberIndexItem {
-  final int offset;
-  final int tag;
-  final Either2<String, List<String>> name;
-
-  /// The absolute offset of the index of class members, `0` if not a class.
-  final int classIndexOffset;
-
-  _UnitMemberIndexItem({
-    required this.offset,
-    required this.tag,
-    required this.name,
-    this.classIndexOffset = 0,
-  });
-}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 38a0e91..761f314 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -4,581 +4,1363 @@
 
 import 'dart:typed_data';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary2/apply_resolution.dart';
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 import 'package:analyzer/src/summary2/ast_binary_tag.dart';
-import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:pub_semver/pub_semver.dart';
 
-Map<String, LibraryReader> createLibraryReadersWithAstBytes({
-  required LinkedElementFactory elementFactory,
-  required Uint8List resolutionBytes,
-  required Map<String, Map<String, Uint8List>> uriToLibrary_uriToUnitAstBytes,
-}) {
-  var _resolutionReader = SummaryDataReader(resolutionBytes);
-
-  _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
-  var resolutionLibrariesOffset = _resolutionReader.readUint32();
-  var resolutionReferencesOffset = _resolutionReader.readUint32();
-  var resolutionStringsOffset = _resolutionReader.readUint32();
-  _resolutionReader.createStringTable(resolutionStringsOffset);
-
-  var referenceReader = _ReferenceReader(
-    elementFactory,
-    _resolutionReader,
-    resolutionReferencesOffset,
-  );
-
-  _resolutionReader.offset = resolutionLibrariesOffset;
-  var resolutionLibraryOffsets = _resolutionReader.readUint30List();
-
-  assert(
-    uriToLibrary_uriToUnitAstBytes.length == resolutionLibraryOffsets.length,
-  );
-
-  // TODO(scheglov) Don't read anything, we know URIs.
-  var libraryMap = <String, LibraryReader>{};
-  for (var i = 0; i < resolutionLibraryOffsets.length; i++) {
-    _resolutionReader.offset = resolutionLibraryOffsets[i];
-    var libraryUriStr = _resolutionReader.readStringReference();
-    var resolutionUnitOffsets = _resolutionReader.readUint30List();
-    var exportsIndexList = _resolutionReader.readUint30List();
-
-    var uriToUnitAstBytes = uriToLibrary_uriToUnitAstBytes[libraryUriStr]!;
-
-    var reference = elementFactory.rootReference.getChild(libraryUriStr);
-    var libraryReader = LibraryReaderForAstBytes._(
-      elementFactory,
-      uriToUnitAstBytes,
-      _resolutionReader,
-      referenceReader,
-      reference,
-      resolutionUnitOffsets,
-      exportsIndexList,
-    );
-    libraryMap[libraryUriStr] = libraryReader;
-  }
-
-  return libraryMap;
-}
-
 class BundleReader {
-  final SummaryDataReader _astReader;
-  final SummaryDataReader _resolutionReader;
-
-  bool _withInformative = false;
+  final SummaryDataReader _reader;
+  final Map<Uri, Uint8List> _unitsInformativeBytes;
 
   final Map<String, LibraryReader> libraryMap = {};
 
+  /// TODO(scheglov) Remove [astBytes].
   BundleReader({
     required LinkedElementFactory elementFactory,
-    required Uint8List astBytes,
+    Uint8List? astBytes, // ignore: avoid_unused_constructor_parameters
     required Uint8List resolutionBytes,
-  })   : _astReader = SummaryDataReader(astBytes),
-        _resolutionReader = SummaryDataReader(resolutionBytes) {
-    _astReader.offset = 0;
-    _withInformative = _astReader.readByte() == 1;
-
-    _astReader.offset = _astReader.bytes.length - 4 * 2;
-    var astLibrariesOffset = _astReader.readUint32();
-    var astStringsOffset = _astReader.readUint32();
-    _astReader.createStringTable(astStringsOffset);
-
-    _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
-    var resolutionLibrariesOffset = _resolutionReader.readUint32();
-    var resolutionReferencesOffset = _resolutionReader.readUint32();
-    var resolutionStringsOffset = _resolutionReader.readUint32();
-    _resolutionReader.createStringTable(resolutionStringsOffset);
+    Map<Uri, Uint8List> unitsInformativeBytes = const {},
+  })  : _reader = SummaryDataReader(resolutionBytes),
+        _unitsInformativeBytes = unitsInformativeBytes {
+    _reader.offset = _reader.bytes.length - 4 * 4;
+    var baseResolutionOffset = _reader.readUInt32();
+    var librariesOffset = _reader.readUInt32();
+    var referencesOffset = _reader.readUInt32();
+    var stringsOffset = _reader.readUInt32();
+    _reader.createStringTable(stringsOffset);
 
     var referenceReader = _ReferenceReader(
       elementFactory,
-      _resolutionReader,
-      resolutionReferencesOffset,
+      _reader,
+      referencesOffset,
     );
 
-    _astReader.offset = astLibrariesOffset;
-    var astLibraryOffsets = _astReader.readUint30List();
-
-    _resolutionReader.offset = resolutionLibrariesOffset;
-    var resolutionLibraryOffsets = _resolutionReader.readUint30List();
-
-    assert(astLibraryOffsets.length == resolutionLibraryOffsets.length);
-
-    for (var i = 0; i < astLibraryOffsets.length; i++) {
-      _astReader.offset = astLibraryOffsets[i];
-      var name = _astReader.readStringReference();
-      var nameOffset = _astReader.readUInt30() - 1;
-      var nameLength = _astReader.readUInt30();
-      var hasPartOfDirective = _astReader.readByte() != 0;
-      var astUnitOffsets = _astReader.readUint30List();
-
-      _resolutionReader.offset = resolutionLibraryOffsets[i];
-      var libraryUriStr = _resolutionReader.readStringReference();
-      var resolutionUnitOffsets = _resolutionReader.readUint30List();
-      assert(astUnitOffsets.length == resolutionUnitOffsets.length);
-      var exportsIndexList = _resolutionReader.readUint30List();
-
-      var reference = elementFactory.rootReference.getChild(libraryUriStr);
-      var libraryReader = LibraryReaderFromBundle._(
-        elementFactory,
-        _withInformative,
-        _astReader,
-        _resolutionReader,
-        referenceReader,
-        reference,
-        name,
-        nameOffset,
-        nameLength,
-        hasPartOfDirective,
-        astUnitOffsets,
-        resolutionUnitOffsets,
-        exportsIndexList,
+    _reader.offset = librariesOffset;
+    var libraryHeaderList = _reader.readTypedList(() {
+      return _LibraryHeader(
+        uriStr: _reader.readStringReference(),
+        offset: _reader.readUInt30(),
+        classMembersLengths: _reader.readUInt30List(),
       );
-      libraryMap[libraryUriStr] = libraryReader;
+    });
+
+    for (var libraryHeader in libraryHeaderList) {
+      _reader.offset = libraryHeader.offset;
+      var uriStr = libraryHeader.uriStr;
+      var reference = elementFactory.rootReference.getChild(uriStr);
+      libraryMap[uriStr] = LibraryReader._(
+        elementFactory: elementFactory,
+        reader: _reader,
+        unitsInformativeBytes: _unitsInformativeBytes,
+        baseResolutionOffset: baseResolutionOffset,
+        referenceReader: referenceReader,
+        reference: reference,
+        offset: _reader.offset,
+        classMembersLengths: libraryHeader.classMembersLengths,
+      );
+    }
+  }
+}
+
+class ClassElementLinkedData extends ElementLinkedData<ClassElementImpl> {
+  void Function()? _readMembers;
+  void Function()? applyInformativeDataToMembers;
+
+  ClassElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  /// Ensure that all members of the [element] are available. This includes
+  /// being able to ask them for example using [ClassElement.methods], and
+  /// as well access them through their [Reference]s. For a class declaration
+  /// this means reading them, for a named mixin application this means
+  /// computing constructors.
+  void readMembers(ClassElementImpl element) {
+    if (element.isMixinApplication) {
+      element.constructors;
+    } else {
+      _readMembers?.call();
+      _readMembers = null;
+
+      applyInformativeDataToMembers?.call();
+      applyInformativeDataToMembers = null;
     }
   }
 
-  LibraryReader getLibrary(String uriStr) {
-    return libraryMap[uriStr]!;
+  @override
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    _readTypeParameters(reader, element.typeParameters);
+    element.supertype = reader._readOptionalInterfaceType();
+    element.mixins = reader._readInterfaceTypeList();
+    element.interfaces = reader._readInterfaceTypeList();
   }
 }
 
-class ClassReader {
-  final int membersOffset;
+class CompilationUnitElementLinkedData
+    extends ElementLinkedData<CompilationUnitElementImpl> {
+  CompilationUnitElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
 
-  ClassReader(this.membersOffset);
+  @override
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+  }
 }
 
-abstract class LibraryReader {
-  final LinkedElementFactory _elementFactory;
-  final SummaryDataReader _resolutionReader;
-  final _ReferenceReader _referenceReader;
+class ConstructorElementLinkedData
+    extends ElementLinkedData<ConstructorElementImpl> {
+  ConstructorElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  @override
+  void _read(element, reader) {
+    _addEnclosingElementTypeParameters(reader, element);
+
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    reader._addFormalParameters(element.parameters);
+    _readFormalParameters(reader, element.parameters);
+    if (element.isConst || element.isFactory) {
+      element.redirectedConstructor =
+          reader.readElement() as ConstructorElement?;
+      element.constantInitializers = reader._readNodeList();
+    }
+  }
+}
+
+/// Lazy reader of resolution information.
+abstract class ElementLinkedData<E extends ElementImpl> {
   final Reference reference;
+  final LibraryReader _libraryReader;
+  final CompilationUnitElementImpl unitElement;
 
-  final Uint32List _resolutionUnitOffsets;
-  final Uint32List _exportsIndexList;
-  List<Reference>? _exports;
+  /// When this object is created, this offset is the offset of the resolution
+  /// information in the [_libraryReader]. After reading is done, this offset
+  /// is set to `-1`.
+  int _offset;
 
-  List<UnitReader>? _units;
+  ElementLinkedData(
+      this.reference, LibraryReader libraryReader, this.unitElement, int offset)
+      : _libraryReader = libraryReader,
+        _offset = offset;
 
-  LibraryReader._(
-    this._elementFactory,
-    this._resolutionReader,
-    this._referenceReader,
-    this.reference,
-    this._resolutionUnitOffsets,
-    this._exportsIndexList,
-  );
+  void read(ElementImpl element) {
+    if (_offset == -1) {
+      return null;
+    }
 
-  List<Reference> get exports {
-    return _exports ??= _exportsIndexList
+    var dataReader = _libraryReader._reader.fork(_offset);
+    _offset = -1;
+
+    var reader = ResolutionReader(
+      _libraryReader._elementFactory,
+      _libraryReader._referenceReader,
+      dataReader,
+    );
+
+    _read(element as E, reader);
+  }
+
+  void _addEnclosingElementTypeParameters(
+    ResolutionReader reader,
+    ElementImpl element,
+  ) {
+    var enclosing = element.enclosingElement;
+    if (enclosing is ClassElement) {
+      reader._addTypeParameters(enclosing.typeParameters);
+    } else if (enclosing is CompilationUnitElement) {
+      // Nothing.
+    } else if (enclosing is ExtensionElement) {
+      reader._addTypeParameters(enclosing.typeParameters);
+    } else {
+      throw UnimplementedError('${enclosing.runtimeType}');
+    }
+  }
+
+  void _read(E element, ResolutionReader reader);
+
+  void _readFormalParameters(
+    ResolutionReader reader,
+    List<ParameterElement> parameters,
+  ) {
+    for (var parameter in parameters) {
+      parameter as ParameterElementImpl;
+      parameter.metadata = reader._readAnnotationList(
+        unitElement: unitElement,
+      );
+      _readTypeParameters(reader, parameter.typeParameters);
+      _readFormalParameters(reader, parameter.parameters);
+      parameter.type = reader.readRequiredType();
+      if (parameter is ConstVariableElement) {
+        var defaultParameter = parameter as ConstVariableElement;
+        var initializer = reader._readOptionalExpression();
+        if (initializer != null) {
+          defaultParameter.constantInitializer = initializer;
+          ExpressionImpl.inConstContextWithoutParent[initializer] = true;
+        }
+      }
+      if (parameter is FieldFormalParameterElementImpl) {
+        parameter.field = reader.readElement() as FieldElement?;
+      }
+    }
+  }
+
+  void _readTypeParameters(
+    ResolutionReader reader,
+    List<TypeParameterElement> typeParameters,
+  ) {
+    reader._addTypeParameters(typeParameters);
+    for (var typeParameter in typeParameters) {
+      typeParameter as TypeParameterElementImpl;
+      typeParameter.metadata = reader._readAnnotationList(
+        unitElement: unitElement,
+      );
+      typeParameter.bound = reader.readType();
+      typeParameter.defaultType = reader.readType();
+    }
+  }
+}
+
+class EnumElementLinkedData extends ElementLinkedData<EnumElementImpl> {
+  EnumElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  @override
+  void _read(element, reader) {
+    var typeProvider = element.library.typeProvider;
+
+    element.metadata = reader._readAnnotationList(
+      unitElement: element.enclosingElement,
+    );
+
+    var indexField = element.getField('index') as FieldElementImpl;
+    indexField.type = typeProvider.intType;
+
+    var toStringMethod = element.getMethod('toString') as MethodElementImpl;
+    toStringMethod.returnType = typeProvider.stringType;
+
+    for (var constant in element.constants) {
+      constant as FieldElementImpl;
+      constant.metadata = reader._readAnnotationList(
+        unitElement: element.enclosingElement,
+      );
+    }
+  }
+}
+
+class ExtensionElementLinkedData
+    extends ElementLinkedData<ExtensionElementImpl> {
+  ExtensionElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  @override
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: element.enclosingElement,
+    );
+    _readTypeParameters(reader, element.typeParameters);
+    element.extendedType = reader.readRequiredType();
+  }
+}
+
+class FieldElementLinkedData extends ElementLinkedData<FieldElementImpl> {
+  FieldElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  @override
+  void _read(element, reader) {
+    _addEnclosingElementTypeParameters(reader, element);
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    element.type = reader.readRequiredType();
+    if (element is ConstFieldElementImpl) {
+      var initializer = reader._readOptionalExpression();
+      if (initializer != null) {
+        element.constantInitializer = initializer;
+        ExpressionImpl.inConstContextWithoutParent[initializer] = true;
+      }
+    }
+  }
+}
+
+class FunctionElementLinkedData extends ElementLinkedData<FunctionElementImpl> {
+  FunctionElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  @override
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    _readTypeParameters(reader, element.typeParameters);
+    element.returnType = reader.readRequiredType();
+    _readFormalParameters(reader, element.parameters);
+  }
+}
+
+class LibraryElementLinkedData extends ElementLinkedData<LibraryElementImpl> {
+  LibraryElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  LinkedElementFactory get elementFactory {
+    return _libraryReader._elementFactory;
+  }
+
+  @override
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+
+    for (var import in element.imports) {
+      import as ImportElementImpl;
+      import.metadata = reader._readAnnotationList(
+        unitElement: unitElement,
+      );
+      import.importedLibrary = reader.readElement() as LibraryElementImpl?;
+    }
+
+    for (var export in element.exports) {
+      export as ExportElementImpl;
+      export.metadata = reader._readAnnotationList(
+        unitElement: unitElement,
+      );
+      export.exportedLibrary = reader.readElement() as LibraryElementImpl?;
+    }
+
+    element.entryPoint = reader.readElement() as FunctionElement?;
+  }
+}
+
+class LibraryReader {
+  final LinkedElementFactory _elementFactory;
+  final SummaryDataReader _reader;
+  final Map<Uri, Uint8List> _unitsInformativeBytes;
+  final int _baseResolutionOffset;
+  final _ReferenceReader _referenceReader;
+  final Reference _reference;
+  final int _offset;
+
+  final Uint32List _classMembersLengths;
+  int _classMembersLengthsIndex = 0;
+
+  late List<Reference> exports;
+  var nextUnnamedExtensionId = 0;
+
+  LibraryReader._({
+    required LinkedElementFactory elementFactory,
+    required SummaryDataReader reader,
+    required Map<Uri, Uint8List> unitsInformativeBytes,
+    required int baseResolutionOffset,
+    required _ReferenceReader referenceReader,
+    required Reference reference,
+    required int offset,
+    required Uint32List classMembersLengths,
+  })  : _elementFactory = elementFactory,
+        _reader = reader,
+        _unitsInformativeBytes = unitsInformativeBytes,
+        _baseResolutionOffset = baseResolutionOffset,
+        _referenceReader = referenceReader,
+        _reference = reference,
+        _offset = offset,
+        _classMembersLengths = classMembersLengths;
+
+  LibraryElementImpl readElement({required Source librarySource}) {
+    var analysisContext = _elementFactory.analysisContext;
+    var analysisSession = _elementFactory.analysisSession;
+    var sourceFactory = analysisContext.sourceFactory;
+
+    _reader.offset = _offset;
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+
+    var name = _reader.readStringReference();
+    var featureSet = _readFeatureSet();
+
+    var libraryElement = LibraryElementImpl(
+        analysisContext, analysisSession, name, -1, 0, featureSet);
+    _reference.element = libraryElement;
+    libraryElement.reference = _reference;
+
+    libraryElement.languageVersion = _readLanguageVersion();
+    libraryElement.imports = _reader.readTypedList(_readImportElement);
+    libraryElement.exports = _reader.readTypedList(_readExportElement);
+
+    libraryElement.hasExtUri = _reader.readBool();
+    libraryElement.hasPartOfDirective = _reader.readBool();
+    libraryElement.isSynthetic = _reader.readBool();
+
+    var unitContainerRef = _reference.getChild('@unit');
+    var unitCount = _reader.readUInt30();
+    var units = <CompilationUnitElementImpl>[];
+    for (var i = 0; i < unitCount; i++) {
+      var unitElement = _readUnitElement(
+        sourceFactory: sourceFactory,
+        unitContainerRef: unitContainerRef,
+        libraryElement: libraryElement,
+        librarySource: librarySource,
+      );
+      units.add(unitElement);
+    }
+
+    var exportsIndexList = _reader.readUInt30List();
+    exports = exportsIndexList
         .map((index) => _referenceReader.referenceOfIndex(index))
         .toList();
-  }
 
-  /// Is `true` if the defining unit has [PartOfDirective].
-  bool get hasPartOfDirective;
+    libraryElement.definingCompilationUnit = units[0];
+    libraryElement.parts = units.skip(1).toList();
 
-  String get name;
-
-  int get nameLength;
-
-  int get nameOffset;
-
-  List<UnitReader> get units;
-
-  bool get withInformative;
-}
-
-/// Implementation of [LibraryReader] that reads ASTs for units from separate
-/// byte buffers.
-class LibraryReaderForAstBytes extends LibraryReader {
-  final Map<String, Uint8List> _uriToUnitAstBytes;
-
-  bool _hasNameRead = false;
-  late final bool _withInformative;
-  late final String _name;
-  late final int _nameOffset;
-  late final int _nameLength;
-  late final bool _hasPartOfDirective;
-
-  LibraryReaderForAstBytes._(
-    LinkedElementFactory elementFactory,
-    Map<String, Uint8List> uriToUnitAstBytes,
-    SummaryDataReader resolutionReader,
-    _ReferenceReader referenceReader,
-    Reference reference,
-    Uint32List resolutionUnitOffsets,
-    Uint32List exportsIndexList,
-  )   : _uriToUnitAstBytes = uriToUnitAstBytes,
-        super._(
-          elementFactory,
-          resolutionReader,
-          referenceReader,
-          reference,
-          resolutionUnitOffsets,
-          exportsIndexList,
-        ) {
-    // TODO(scheglov) This fails when there are invalid URIs.
-    // assert(_uriToUnitAstBytes.length == _resolutionUnitOffsets.length);
-  }
-
-  @override
-  bool get hasPartOfDirective {
-    _readName();
-    return _hasPartOfDirective;
-  }
-
-  @override
-  String get name {
-    _readName();
-    return _name;
-  }
-
-  @override
-  int get nameLength {
-    _readName();
-    return _nameLength;
-  }
-
-  @override
-  int get nameOffset {
-    _readName();
-    return _nameOffset;
-  }
-
-  @override
-  List<UnitReader> get units {
-    if (_units != null) return _units!;
-    _units = [];
-
-    for (var i = 0; i < _resolutionUnitOffsets.length; i++) {
-      _resolutionReader.offset = _resolutionUnitOffsets[i];
-      var unitUriStr = _resolutionReader.readStringReference();
-      var isSynthetic = _resolutionReader.readByte() != 0;
-      var isPart = _resolutionReader.readByte() != 0;
-      String? partUriStr = _resolutionReader.readStringReference();
-      if (!isPart) {
-        partUriStr = null;
-      }
-      var resolutionDirectivesOffset = _resolutionReader.readUInt30();
-      var resolutionDeclarationOffsets = _resolutionReader.readUint30List();
-
-      // TODO(scheglov) Is this right?
-      if (unitUriStr.isEmpty) {
-        unitUriStr = 'null';
-      }
-
-      var astBytes = _uriToUnitAstBytes[unitUriStr]!;
-      var astReader = SummaryDataReader(astBytes);
-      astReader.offset = astBytes.length - 4 * 4;
-      var headerOffset = astReader.readUint32();
-      var indexOffset = astReader.readUint32();
-      astReader.readUint32(); // library data
-      var astStringsOffset = astReader.readUint32();
-      astReader.createStringTable(astStringsOffset);
-
-      _units!.add(
-        UnitReader._(
-          this,
-          resolutionDirectivesOffset,
-          resolutionDeclarationOffsets,
-          reference.getChild('@unit').getChild(unitUriStr),
-          isSynthetic,
-          partUriStr,
-          astReader,
-          headerOffset,
-          indexOffset,
-        ),
-      );
-    }
-
-    return _units!;
-  }
-
-  @override
-  bool get withInformative {
-    _readName();
-    return _withInformative;
-  }
-
-  void _readName() {
-    if (_hasNameRead) return;
-    _hasNameRead = true;
-
-    var uriStr = reference.name;
-    var definingUnitBytes = _uriToUnitAstBytes[uriStr]!;
-    var reader = SummaryDataReader(definingUnitBytes);
-    reader.offset = definingUnitBytes.length - 4 * 2;
-    var libraryDataOffset = reader.readUint32();
-    var astStringsOffset = reader.readUint32();
-    reader.createStringTable(astStringsOffset);
-
-    reader.offset = libraryDataOffset;
-    _name = reader.readStringReference();
-    _nameOffset = reader.readUInt30() - 1;
-    _nameLength = reader.readUInt30();
-    _hasPartOfDirective = reader.readByte() != 0;
-    _withInformative = reader.readByte() != 0;
-  }
-}
-
-class LibraryReaderFromBundle extends LibraryReader {
-  final SummaryDataReader _astReader;
-  final Uint32List _astUnitOffsets;
-
-  @override
-  final String name;
-
-  @override
-  final int nameOffset;
-
-  @override
-  final int nameLength;
-
-  @override
-  final bool hasPartOfDirective;
-
-  @override
-  final bool withInformative;
-
-  LibraryReaderFromBundle._(
-    LinkedElementFactory elementFactory,
-    this.withInformative,
-    SummaryDataReader astReader,
-    SummaryDataReader resolutionReader,
-    _ReferenceReader referenceReader,
-    Reference reference,
-    this.name,
-    this.nameOffset,
-    this.nameLength,
-    this.hasPartOfDirective,
-    Uint32List astUnitOffsets,
-    Uint32List resolutionUnitOffsets,
-    Uint32List exportsIndexList,
-  )   : _astReader = astReader,
-        _astUnitOffsets = astUnitOffsets,
-        super._(
-          elementFactory,
-          resolutionReader,
-          referenceReader,
-          reference,
-          resolutionUnitOffsets,
-          exportsIndexList,
-        ) {
-    assert(_astUnitOffsets.length == _resolutionUnitOffsets.length);
-  }
-
-  @override
-  List<UnitReader> get units {
-    if (_units != null) return _units!;
-    _units = [];
-
-    for (var i = 0; i < _astUnitOffsets.length; i++) {
-      var astUnitOffset = _astUnitOffsets[i];
-      var resolutionUnitOffset = _resolutionUnitOffsets[i];
-
-      _astReader.offset = astUnitOffset;
-      var headerOffset = _astReader.readUInt30();
-      var indexOffset = _astReader.offset;
-
-      _resolutionReader.offset = resolutionUnitOffset;
-      var unitUriStr = _resolutionReader.readStringReference();
-      var isSynthetic = _resolutionReader.readByte() != 0;
-      var isPart = _resolutionReader.readByte() != 0;
-      String? partUriStr = _resolutionReader.readStringReference();
-      if (!isPart) {
-        partUriStr = null;
-      }
-      var resolutionDirectivesOffset = _resolutionReader.readUInt30();
-      var resolutionDeclarationOffsets = _resolutionReader.readUint30List();
-
-      _units!.add(
-        UnitReader._(
-          this,
-          resolutionDirectivesOffset,
-          resolutionDeclarationOffsets,
-          reference.getChild('@unit').getChild(unitUriStr),
-          isSynthetic,
-          partUriStr,
-          _astReader,
-          headerOffset,
-          indexOffset,
-        ),
-      );
-    }
-
-    return _units!;
-  }
-}
-
-class LinkedContext implements AstLinkedContext {
-  final UnitReader _unitReader;
-  final AstNode _node;
-  final int _resolutionIndex;
-  final Uint32List? _codeOffsetLengthList;
-  final Uint32List _documentationTokenIndexList;
-
-  @override
-  final int codeOffset;
-
-  @override
-  final int codeLength;
-
-  @override
-  final bool isClassWithConstConstructor;
-
-  bool _isApplied = false;
-
-  bool _hasDocumentationComment = false;
-
-  late final _UnitMemberReader _reader;
-
-  LinkedContext(
-    this._unitReader,
-    this._node, {
-    required this.codeOffset,
-    required this.codeLength,
-    this.isClassWithConstConstructor = false,
-    Uint32List? codeOffsetLengthList,
-    required int resolutionIndex,
-    required Uint32List documentationTokenIndexList,
-  })   : _resolutionIndex = resolutionIndex,
-        _codeOffsetLengthList = codeOffsetLengthList,
-        _documentationTokenIndexList = documentationTokenIndexList;
-
-  @override
-  List<ClassMember> get classMembers {
-    var reader = _reader;
-    if (reader is _ClassReader) {
-      return reader.classMembers;
-    } else if (_node is ClassTypeAlias) {
-      return const <ClassMember>[];
-    } else {
-      throw UnimplementedError();
-    }
-  }
-
-  @override
-  // TODO: implement unitDirectives
-  List<Directive> get unitDirectives => throw UnimplementedError();
-
-  @override
-  void applyResolution(LinkedUnitContext unitContext) {
-    if (_isApplied) {
-      return;
-    }
-    _isApplied = true;
-
-    var localElements = <Element>[];
-    var resolutionReader = LinkedResolutionReader(
-      _unitReader,
-      localElements,
-      _unitReader._resolutionDeclarationsOffset[_resolutionIndex],
+    libraryElement.linkedData = LibraryElementLinkedData(
+      reference: _reference,
+      libraryReader: this,
+      unitElement: units[0],
+      offset: resolutionOffset,
     );
-    _node.accept(
-      ApplyResolutionVisitor(
-        unitContext,
-        localElements,
-        resolutionReader,
+
+    InformativeDataApplier(_elementFactory, _unitsInformativeBytes)
+        .applyTo(libraryElement);
+
+    return libraryElement;
+  }
+
+  ClassElementImpl _readClassElement(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readStringReference();
+    var reference = unitReference.getChild('@class').getChild(name);
+
+    var element = ClassElementImpl(name, -1);
+
+    var linkedData = ClassElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    element.isAbstract = _reader.readBool();
+    element.isMixinApplication = _reader.readBool();
+    element.isSimplyBounded = _reader.readBool();
+
+    element.typeParameters = _readTypeParameters();
+
+    if (!element.isMixinApplication) {
+      var membersOffset = _reader.offset;
+      linkedData._readMembers = () {
+        _reader.offset = membersOffset;
+        _readClassElementMembers(unitElement, element, reference);
+      };
+      _reader.offset += _classMembersLengths[_classMembersLengthsIndex++];
+    }
+
+    return element;
+  }
+
+  void _readClassElementMembers(
+    CompilationUnitElementImpl unitElement,
+    ClassElementImpl element,
+    Reference reference,
+  ) {
+    var accessors = <PropertyAccessorElementImpl>[];
+    var fields = <FieldElement>[];
+    _readFields(unitElement, element, reference, accessors, fields);
+    _readPropertyAccessors(
+        unitElement, element, reference, accessors, fields, '@field');
+    element.fields = fields;
+    element.accessors = accessors;
+
+    element.constructors = _readConstructors(unitElement, element, reference);
+    element.methods = _readMethods(unitElement, element, reference);
+  }
+
+  void _readClasses(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var length = _reader.readUInt30();
+    unitElement.types = List.generate(length, (index) {
+      return _readClassElement(unitElement, unitReference);
+    });
+  }
+
+  List<ConstructorElementImpl> _readConstructors(
+    CompilationUnitElementImpl unitElement,
+    ClassElementImpl classElement,
+    Reference classReference,
+  ) {
+    var containerRef = classReference.getChild('@constructor');
+    var length = _reader.readUInt30();
+    return List.generate(length, (_) {
+      var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+      var name = _reader.readStringReference();
+      var reference = containerRef.getChild(name);
+      var element = ConstructorElementImpl(name, -1);
+      var linkedData = ConstructorElementLinkedData(
+        reference: reference,
+        libraryReader: this,
+        unitElement: unitElement,
+        offset: resolutionOffset,
+      );
+      element.setLinkedData(reference, linkedData);
+      element.isConst = _reader.readBool();
+      element.isExternal = _reader.readBool();
+      element.isFactory = _reader.readBool();
+      element.isSynthetic = _reader.readBool();
+      element.parameters = _readParameters(element, reference);
+      return element;
+    });
+  }
+
+  EnumElementImpl _readEnumElement(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readStringReference();
+    var reference = unitReference.getChild('@enum').getChild(name);
+
+    var element = EnumElementImpl(name, -1);
+
+    var linkedData = EnumElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    var fields = <FieldElement>[];
+    var getters = <PropertyAccessorElement>[];
+
+    // Build the 'index' field.
+    {
+      var field = FieldElementImpl('index', -1)
+        ..enclosingElement = element
+        ..isSynthetic = true
+        ..isFinal = true;
+      fields.add(field);
+      getters.add(
+        PropertyAccessorElementImpl_ImplicitGetter(field,
+            reference: reference.getChild('@getter').getChild('index'))
+          ..enclosingElement = element,
+      );
+    }
+
+    // Build the 'values' field.
+    {
+      var field = ConstFieldElementImpl_EnumValues(element);
+      fields.add(field);
+      getters.add(
+        PropertyAccessorElementImpl_ImplicitGetter(field,
+            reference: reference.getChild('@getter').getChild('values'))
+          ..enclosingElement = element,
+      );
+    }
+
+    // Build fields for all enum constants.
+    var containerRef = reference.getChild('@constant');
+    var constantCount = _reader.readUInt30();
+    for (var i = 0; i < constantCount; i++) {
+      var constantName = _reader.readStringReference();
+      var field = ConstFieldElementImpl_EnumValue(element, constantName, i);
+      var constantRef = containerRef.getChild(name);
+      field.reference = constantRef;
+      constantRef.element = field;
+      fields.add(field);
+      getters.add(
+        PropertyAccessorElementImpl_ImplicitGetter(field,
+            reference: reference.getChild('@getter').getChild(constantName))
+          ..enclosingElement = element,
+      );
+    }
+
+    element.fields = fields;
+    element.accessors = getters;
+    element.createToStringMethodElement();
+
+    return element;
+  }
+
+  void _readEnums(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var count = _reader.readUInt30();
+    unitElement.enums = List.generate(count, (_) {
+      return _readEnumElement(unitElement, unitReference);
+    });
+  }
+
+  ExportElementImpl _readExportElement() {
+    var element = ExportElementImpl(-1);
+    element.uri = _reader.readOptionalStringReference();
+    element.combinators = _reader.readTypedList(_readNamespaceCombinator);
+    return element;
+  }
+
+  ExtensionElementImpl _readExtensionElement(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readOptionalStringReference();
+    var refName = name ?? 'extension-${nextUnnamedExtensionId++}';
+    var reference = unitReference.getChild('@extension').getChild(refName);
+
+    var element = ExtensionElementImpl(name, -1);
+    element.setLinkedData(
+      reference,
+      ExtensionElementLinkedData(
+        reference: reference,
+        libraryReader: this,
+        unitElement: unitElement,
+        offset: resolutionOffset,
       ),
     );
+
+    element.typeParameters = _readTypeParameters();
+
+    var accessors = <PropertyAccessorElement>[];
+    var fields = <FieldElement>[];
+    _readPropertyAccessors(
+        unitElement, element, reference, accessors, fields, '@field');
+    _readFields(unitElement, element, reference, accessors, fields);
+    element.accessors = accessors;
+    element.fields = fields;
+
+    element.methods = _readMethods(unitElement, element, reference);
+
+    return element;
   }
 
-  @override
-  int getVariableDeclarationCodeLength(VariableDeclaration node) {
-    var variableList = node.parent as VariableDeclarationList;
-    var variables = variableList.variables;
-    for (var i = 0; i < variables.length; i++) {
-      if (identical(variables[i], node)) {
-        return _codeOffsetLengthList![2 * i + 1];
+  void _readExtensions(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var count = _reader.readUInt30();
+    unitElement.extensions = List.generate(count, (_) {
+      return _readExtensionElement(unitElement, unitReference);
+    });
+  }
+
+  FeatureSet _readFeatureSet() {
+    var featureSetEncoded = _reader.readUint8List();
+    return ExperimentStatus.fromStorage(featureSetEncoded);
+  }
+
+  FieldElementImpl _readFieldElement(
+    CompilationUnitElementImpl unitElement,
+    ElementImpl classElement,
+    Reference classReference,
+    Reference containerRef,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readStringReference();
+    var isConstElement = _reader.readBool();
+    var reference = containerRef.getChild(name);
+
+    FieldElementImpl element;
+    if (isConstElement) {
+      element = ConstFieldElementImpl(name, -1);
+    } else {
+      element = FieldElementImpl(name, -1);
+    }
+
+    var linkedData = FieldElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    element.hasImplicitType = _reader.readBool();
+    element.hasInitializer = _reader.readBool();
+    element.inheritsCovariant = _reader.readBool();
+    element.isAbstract = _reader.readBool();
+    element.isConst = _reader.readBool();
+    element.isCovariant = _reader.readBool();
+    element.isExternal = _reader.readBool();
+    element.isFinal = _reader.readBool();
+    element.isLate = _reader.readBool();
+    element.isStatic = _reader.readBool();
+    element.typeInferenceError = _readTopLevelInferenceError();
+    element.createImplicitAccessors(classReference, name);
+
+    return element;
+  }
+
+  void _readFields(
+    CompilationUnitElementImpl unitElement,
+    ElementImpl classElement,
+    Reference classReference,
+    List<PropertyAccessorElement> accessors,
+    List<FieldElement> variables,
+  ) {
+    var containerRef = classReference.getChild('@field');
+    var createdElements = <FieldElement>[];
+    var variableElementCount = _reader.readUInt30();
+    for (var i = 0; i < variableElementCount; i++) {
+      var variable = _readFieldElement(
+          unitElement, classElement, classReference, containerRef);
+      createdElements.add(variable);
+      variables.add(variable);
+
+      var getter = variable.getter;
+      if (getter is PropertyAccessorElementImpl) {
+        accessors.add(getter);
+      }
+
+      var setter = variable.setter;
+      if (setter is PropertyAccessorElementImpl) {
+        accessors.add(setter);
       }
     }
-    throw StateError('No |$node| in: $variableList');
   }
 
-  @override
-  int getVariableDeclarationCodeOffset(VariableDeclaration node) {
-    var variableList = node.parent as VariableDeclarationList;
-    var variables = variableList.variables;
-    for (var i = 0; i < variables.length; i++) {
-      if (identical(variables[i], node)) {
-        return _codeOffsetLengthList![2 * i + 0];
+  void _readFunctions(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var count = _reader.readUInt30();
+    unitElement.functions = List.generate(count, (_) {
+      var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+      var name = _reader.readStringReference();
+      var reference = unitReference.getChild('@function').getChild(name);
+
+      var element = FunctionElementImpl(name, -1);
+
+      var linkedData = FunctionElementLinkedData(
+        reference: reference,
+        libraryReader: this,
+        unitElement: unitElement,
+        offset: resolutionOffset,
+      );
+      element.setLinkedData(reference, linkedData);
+
+      element.hasImplicitReturnType = _reader.readBool();
+      element.isAsynchronous = _reader.readBool();
+      element.isExternal = _reader.readBool();
+      element.isGenerator = _reader.readBool();
+
+      element.typeParameters = _readTypeParameters();
+      element.parameters = _readParameters(element, reference);
+
+      return element;
+    });
+  }
+
+  ImportElementImpl _readImportElement() {
+    var element = ImportElementImpl(-1);
+    element.isDeferred = _reader.readBool();
+    element.isSynthetic = _reader.readBool();
+    element.uri = _reader.readOptionalStringReference();
+    var prefixName = _reader.readOptionalStringReference();
+    if (prefixName != null) {
+      var reference = _reference.getChild('@prefix').getChild(prefixName);
+      var prefixElement =
+          PrefixElementImpl(prefixName, -1, reference: reference);
+      element.prefix = prefixElement;
+    }
+    element.combinators = _reader.readTypedList(_readNamespaceCombinator);
+    return element;
+  }
+
+  LibraryLanguageVersion _readLanguageVersion() {
+    var packageMajor = _reader.readUInt30();
+    var packageMinor = _reader.readUInt30();
+    var package = Version(packageMajor, packageMinor, 0);
+
+    Version? override;
+    if (_reader.readBool()) {
+      var overrideMajor = _reader.readUInt30();
+      var overrideMinor = _reader.readUInt30();
+      override = Version(overrideMajor, overrideMinor, 0);
+    }
+
+    return LibraryLanguageVersion(package: package, override: override);
+  }
+
+  List<MethodElementImpl> _readMethods(
+    CompilationUnitElementImpl unitElement,
+    ElementImpl enclosingElement,
+    Reference enclosingReference,
+  ) {
+    var containerRef = enclosingReference.getChild('@method');
+    var length = _reader.readUInt30();
+    return List.generate(length, (_) {
+      var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+      var name = _reader.readStringReference();
+      var reference = containerRef.getChild(name);
+      var element = MethodElementImpl(name, -1);
+      var linkedData = MethodElementLinkedData(
+        reference: reference,
+        libraryReader: this,
+        unitElement: unitElement,
+        offset: resolutionOffset,
+      );
+      element.setLinkedData(reference, linkedData);
+      element.hasImplicitReturnType = _reader.readBool();
+      element.isAbstract = _reader.readBool();
+      element.isAsynchronous = _reader.readBool();
+      element.isExternal = _reader.readBool();
+      element.isGenerator = _reader.readBool();
+      element.isStatic = _reader.readBool();
+
+      element.typeParameters = _readTypeParameters();
+      element.parameters = _readParameters(element, reference);
+      element.typeInferenceError = _readTopLevelInferenceError();
+      return element;
+    });
+  }
+
+  MixinElementImpl _readMixinElement(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readStringReference();
+    var reference = unitReference.getChild('@mixin').getChild(name);
+
+    var element = MixinElementImpl(name, -1);
+
+    var linkedData = MixinElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    element.typeParameters = _readTypeParameters();
+
+    var accessors = <PropertyAccessorElement>[];
+    var fields = <FieldElement>[];
+    _readPropertyAccessors(
+        unitElement, element, reference, accessors, fields, '@field');
+    _readFields(unitElement, element, reference, accessors, fields);
+    element.accessors = accessors;
+    element.fields = fields;
+
+    element.constructors = _readConstructors(unitElement, element, reference);
+    element.methods = _readMethods(unitElement, element, reference);
+    element.superInvokedNames = _reader.readStringReferenceList();
+
+    return element;
+  }
+
+  void _readMixins(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var length = _reader.readUInt30();
+    unitElement.mixins = List.generate(length, (index) {
+      return _readMixinElement(unitElement, unitReference);
+    });
+  }
+
+  NamespaceCombinator _readNamespaceCombinator() {
+    var tag = _reader.readByte();
+    if (tag == Tag.HideCombinator) {
+      var combinator = HideElementCombinatorImpl();
+      combinator.hiddenNames = _reader.readStringReferenceList();
+      return combinator;
+    } else if (tag == Tag.ShowCombinator) {
+      var combinator = ShowElementCombinatorImpl();
+      combinator.shownNames = _reader.readStringReferenceList();
+      return combinator;
+    } else {
+      throw UnimplementedError('tag: $tag');
+    }
+  }
+
+  List<ParameterElementImpl> _readParameters(
+    ElementImpl enclosingElement,
+    Reference enclosingReference,
+  ) {
+    var containerRef = enclosingReference.getChild('@parameter');
+    var length = _reader.readUInt30();
+    return List.generate(length, (_) {
+      var name = _reader.readStringReference();
+      var isInitializingFormal = _reader.readBool();
+      var reference = containerRef.getChild(name);
+
+      var kindIndex = _reader.readByte();
+      var kind = ResolutionReader._formalParameterKind(kindIndex);
+
+      ParameterElementImpl element;
+      if (kind.isRequiredPositional) {
+        if (isInitializingFormal) {
+          element = FieldFormalParameterElementImpl(name, -1);
+        } else {
+          element = ParameterElementImpl(name, -1);
+        }
+      } else {
+        if (isInitializingFormal) {
+          element = DefaultFieldFormalParameterElementImpl(name, -1);
+        } else {
+          element = DefaultParameterElementImpl(name, -1);
+        }
+        element.reference = reference;
+        reference.element = element;
+      }
+      element.parameterKind = kind;
+
+      element.hasImplicitType = _reader.readBool();
+      element.inheritsCovariant = _reader.readBool();
+      element.isExplicitlyCovariant = _reader.readBool();
+      element.isFinal = _reader.readBool();
+      element.typeParameters = _readTypeParameters();
+      element.parameters = _readParameters(element, reference);
+      return element;
+    });
+  }
+
+  PropertyAccessorElementImpl _readPropertyAccessorElement(
+    CompilationUnitElementImpl unitElement,
+    ElementImpl classElement,
+    Reference classReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+
+    var name = _reader.readStringReference();
+    var isGetter = _reader.readBool();
+    var isSetter = _reader.readBool();
+    var reference = classReference
+        .getChild(isGetter ? '@getter' : '@setter')
+        .getChild(name);
+
+    var element = PropertyAccessorElementImpl(name, -1);
+
+    var linkedData = PropertyAccessorElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    element.hasImplicitReturnType = _reader.readBool();
+    element.isAbstract = _reader.readBool();
+    element.isAsynchronous = _reader.readBool();
+    element.isExternal = _reader.readBool();
+    element.isGenerator = _reader.readBool();
+    element.isGetter = isGetter;
+    element.isSetter = isSetter;
+    element.isStatic = _reader.readBool();
+    element.parameters = _readParameters(element, reference);
+    return element;
+  }
+
+  void _readPropertyAccessors(
+    CompilationUnitElementImpl unitElement,
+    ElementImpl enclosingElement,
+    Reference enclosingReference,
+    List<PropertyAccessorElement> accessors,
+    List<PropertyInducingElement> properties,
+    String containerRefName,
+  ) {
+    var containerRef = enclosingReference.getChild(containerRefName);
+
+    var accessorCount = _reader.readUInt30();
+    for (var i = 0; i < accessorCount; i++) {
+      var accessor = _readPropertyAccessorElement(
+        unitElement,
+        enclosingElement,
+        enclosingReference,
+      );
+      accessors.add(accessor);
+
+      var name = accessor.displayName;
+      var isGetter = accessor.isGetter;
+
+      var reference = containerRef.getChild(name);
+
+      PropertyInducingElementImpl property;
+      if (enclosingElement is CompilationUnitElementImpl) {
+        var existing = reference.element;
+        if (existing is TopLevelVariableElementImpl) {
+          property = existing;
+        } else {
+          var field = TopLevelVariableElementImpl(name, -1);
+          field.isFinal = true;
+          property = field;
+        }
+      } else {
+        var existing = reference.element;
+        if (existing is FieldElementImpl) {
+          property = existing;
+        } else {
+          var field = FieldElementImpl(name, -1);
+          field.isFinal = true;
+          field.isStatic = accessor.isStatic;
+          property = field;
+        }
+      }
+
+      if (reference.element == null) {
+        reference.element = property;
+        properties.add(property);
+
+        property.enclosingElement = enclosingElement;
+        property.isSynthetic = true;
+      }
+
+      accessor.variable = property;
+      if (isGetter) {
+        property.getter = accessor;
+      } else {
+        property.setter = accessor;
+        if (property.isSynthetic) {
+          property.isFinal = false;
+        }
       }
     }
-    throw StateError('No |$node| in: $variableList');
   }
 
+  TopLevelInferenceError? _readTopLevelInferenceError() {
+    var kindIndex = _reader.readByte();
+    var kind = TopLevelInferenceErrorKind.values[kindIndex];
+    if (kind == TopLevelInferenceErrorKind.none) {
+      return null;
+    }
+    return TopLevelInferenceError(
+      kind: kind,
+      arguments: _reader.readStringReferenceList(),
+    );
+  }
+
+  TopLevelVariableElementImpl _readTopLevelVariableElement(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readStringReference();
+    var isConst = _reader.readBool();
+    var reference = unitReference.getChild('@variable').getChild(name);
+
+    TopLevelVariableElementImpl element;
+    if (isConst) {
+      element = ConstTopLevelVariableElementImpl(name, -1);
+    } else {
+      element = TopLevelVariableElementImpl(name, -1);
+    }
+
+    var linkedData = TopLevelVariableElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    element.isConst = isConst;
+    element.hasImplicitType = _reader.readBool();
+    element.hasInitializer = _reader.readBool();
+    element.isExternal = _reader.readBool();
+    element.isFinal = _reader.readBool();
+    element.isLate = _reader.readBool();
+    element.typeInferenceError = _readTopLevelInferenceError();
+    element.createImplicitAccessors(unitReference, name);
+
+    return element;
+  }
+
+  void _readTopLevelVariables(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+    List<PropertyAccessorElementImpl> accessors,
+    List<TopLevelVariableElementImpl> variables,
+  ) {
+    var variableElementCount = _reader.readUInt30();
+    for (var i = 0; i < variableElementCount; i++) {
+      var variable = _readTopLevelVariableElement(unitElement, unitReference);
+      variables.add(variable);
+
+      var getter = variable.getter;
+      if (getter is PropertyAccessorElementImpl) {
+        accessors.add(getter);
+      }
+
+      var setter = variable.setter;
+      if (setter is PropertyAccessorElementImpl) {
+        accessors.add(setter);
+      }
+    }
+  }
+
+  TypeAliasElementImpl _readTypeAliasElement(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var name = _reader.readStringReference();
+    var reference = unitReference.getChild('@typeAlias').getChild(name);
+
+    var isFunctionTypeAliasBased = _reader.readBool();
+
+    TypeAliasElementImpl element;
+    if (isFunctionTypeAliasBased) {
+      element =
+          // ignore: deprecated_member_use_from_same_package
+          FunctionTypeAliasElementImpl(name, -1);
+    } else {
+      element = TypeAliasElementImpl(name, -1);
+    }
+
+    var linkedData = TypeAliasElementLinkedData(
+      reference: reference,
+      libraryReader: this,
+      unitElement: unitElement,
+      offset: resolutionOffset,
+    );
+    element.setLinkedData(reference, linkedData);
+
+    element.isFunctionTypeAliasBased = isFunctionTypeAliasBased;
+    element.hasSelfReference = _reader.readBool();
+    element.isSimplyBounded = _reader.readBool();
+
+    element.typeParameters = _readTypeParameters();
+
+    return element;
+  }
+
+  void _readTypeAliases(
+    CompilationUnitElementImpl unitElement,
+    Reference unitReference,
+  ) {
+    var length = _reader.readUInt30();
+    unitElement.typeAliases = List.generate(length, (_) {
+      return _readTypeAliasElement(unitElement, unitReference);
+    });
+  }
+
+  List<TypeParameterElementImpl> _readTypeParameters() {
+    var length = _reader.readUInt30();
+    return List.generate(length, (_) {
+      var name = _reader.readStringReference();
+      var varianceEncoding = _reader.readByte();
+      var variance = _decodeVariance(varianceEncoding);
+      var element = TypeParameterElementImpl(name, -1);
+      element.variance = variance;
+      return element;
+    });
+  }
+
+  CompilationUnitElementImpl _readUnitElement({
+    required SourceFactory sourceFactory,
+    required Reference unitContainerRef,
+    required LibraryElementImpl libraryElement,
+    required Source librarySource,
+  }) {
+    var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
+    var unitUriStr = _reader.readStringReference();
+    var unitUri = Uri.parse(unitUriStr);
+    var unitSource = sourceFactory.forUri2(unitUri)!;
+
+    var unitElement = CompilationUnitElementImpl();
+    unitElement.source = unitSource;
+    unitElement.librarySource = librarySource;
+
+    var unitReference = unitContainerRef.getChild(unitUriStr);
+    unitElement.setLinkedData(
+      unitReference,
+      CompilationUnitElementLinkedData(
+        reference: unitReference,
+        libraryReader: this,
+        unitElement: unitElement,
+        offset: resolutionOffset,
+      ),
+    );
+
+    unitElement.uri = _reader.readOptionalStringReference();
+    unitElement.isSynthetic = _reader.readBool();
+
+    nextUnnamedExtensionId = 0;
+    _readClasses(unitElement, unitReference);
+    _readEnums(unitElement, unitReference);
+    _readExtensions(unitElement, unitReference);
+    _readFunctions(unitElement, unitReference);
+    _readMixins(unitElement, unitReference);
+    _readTypeAliases(unitElement, unitReference);
+
+    var accessors = <PropertyAccessorElementImpl>[];
+    var variables = <TopLevelVariableElementImpl>[];
+    _readTopLevelVariables(unitElement, unitReference, accessors, variables);
+    _readPropertyAccessors(unitElement, unitElement, unitReference, accessors,
+        variables, '@variable');
+    unitElement.accessors = accessors;
+    unitElement.topLevelVariables = variables;
+    return unitElement;
+  }
+
+  static Variance? _decodeVariance(int index) {
+    var tag = TypeParameterVarianceTag.values[index];
+    switch (tag) {
+      case TypeParameterVarianceTag.legacy:
+        return null;
+      case TypeParameterVarianceTag.unrelated:
+        return Variance.unrelated;
+      case TypeParameterVarianceTag.covariant:
+        return Variance.covariant;
+      case TypeParameterVarianceTag.contravariant:
+        return Variance.contravariant;
+      case TypeParameterVarianceTag.invariant:
+        return Variance.invariant;
+    }
+  }
+}
+
+class MethodElementLinkedData extends ElementLinkedData<MethodElementImpl> {
+  MethodElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
   @override
-  void readDocumentationComment() {
-    if (_hasDocumentationComment) {
-      return;
-    }
-    _hasDocumentationComment = true;
+  void _read(element, reader) {
+    _addEnclosingElementTypeParameters(reader, element);
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    _readTypeParameters(reader, element.typeParameters);
+    _readFormalParameters(reader, element.parameters);
+    element.returnType = reader.readRequiredType();
+  }
+}
 
-    if (_documentationTokenIndexList.isEmpty) {
-      return;
-    }
+class MixinElementLinkedData extends ElementLinkedData<MixinElementImpl> {
+  MixinElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
 
-    var tokens = <Token>[];
-    for (var lexemeIndex in _documentationTokenIndexList) {
-      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
-      var token = TokenFactory.tokenFromString(lexeme);
-      tokens.add(token);
-    }
+  @override
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: element.enclosingElement,
+    );
+    _readTypeParameters(reader, element.typeParameters);
+    element.superclassConstraints = reader._readInterfaceTypeList();
+    element.interfaces = reader._readInterfaceTypeList();
+  }
+}
 
-    var comment = astFactory.documentationComment(tokens);
-    (_node as AnnotatedNodeImpl).documentationComment = comment;
+class PropertyAccessorElementLinkedData
+    extends ElementLinkedData<PropertyAccessorElementImpl> {
+  PropertyAccessorElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
+
+  @override
+  void _read(element, reader) {
+    _addEnclosingElementTypeParameters(reader, element);
+
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+
+    element.returnType = reader.readRequiredType();
+    _readFormalParameters(reader, element.parameters);
   }
 }
 
 /// Helper for reading elements and types from their binary encoding.
-class LinkedResolutionReader {
-  final UnitReader _unitReader;
+class ResolutionReader {
+  final LinkedElementFactory _elementFactory;
+  final _ReferenceReader _referenceReader;
+  final SummaryDataReader _reader;
 
   /// The stack of [TypeParameterElement]s and [ParameterElement] that are
-  /// available in the scope of [nextElement] and [nextType].
+  /// available in the scope of [readElement] and [readType].
   ///
   /// This stack is shared with the client of the reader, and update mostly
   /// by the client. However it is also updated during [_readFunctionType].
-  final List<Element> _localElements;
+  final List<Element> _localElements = [];
 
-  /// The offset in [_Reader.bytes] from which we read resolution now.
-  int _byteOffset = 0;
-
-  LinkedResolutionReader(
-    this._unitReader,
-    this._localElements,
-    this._byteOffset,
+  ResolutionReader(
+    this._elementFactory,
+    this._referenceReader,
+    this._reader,
   );
 
-  /// TODO(scheglov) Remove after fixing http://dartbug.com/44449
-  int get byteOffset => _byteOffset;
+  int readByte() {
+    return _reader.readByte();
+  }
 
-  /// TODO(scheglov) Remove after fixing http://dartbug.com/44449
-  Uint8List get bytes => _unitReader._resolutionReader.bytes;
+  double readDouble() {
+    return _reader.readDouble();
+  }
 
-  Element? nextElement() {
-    var memberFlags = readByte();
+  Element? readElement() {
+    var memberFlags = _reader.readByte();
     var element = _readRawElement();
 
     if (element == null) {
@@ -614,13 +1396,20 @@
     throw UnimplementedError('memberFlags: $memberFlags');
   }
 
-  String nextString() {
-    var index = _readUInt30();
-    return _unitReader._resolutionReader.stringOfIndex(index);
+  DartType readRequiredType() {
+    return readType()!;
   }
 
-  DartType? nextType() {
-    var tag = readByte();
+  String readStringReference() {
+    return _reader.readStringReference();
+  }
+
+  List<String> readStringReferenceList() {
+    return _reader.readStringReferenceList();
+  }
+
+  DartType? readType() {
+    var tag = _reader.readByte();
     if (tag == Tag.NullType) {
       return null;
     } else if (tag == Tag.DynamicType) {
@@ -630,7 +1419,7 @@
       var type = _readFunctionType();
       return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType) {
-      var element = nextElement() as ClassElement;
+      var element = readElement() as ClassElement;
       var typeArguments = _readTypeList();
       var nullability = _readNullability();
       var type = InterfaceTypeImpl(
@@ -640,7 +1429,7 @@
       );
       return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_none) {
-      var element = nextElement() as ClassElement;
+      var element = readElement() as ClassElement;
       var type = InterfaceTypeImpl(
         element: element,
         typeArguments: const <DartType>[],
@@ -648,7 +1437,7 @@
       );
       return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_question) {
-      var element = nextElement() as ClassElement;
+      var element = readElement() as ClassElement;
       var type = InterfaceTypeImpl(
         element: element,
         typeArguments: const <DartType>[],
@@ -656,7 +1445,7 @@
       );
       return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_star) {
-      var element = nextElement() as ClassElement;
+      var element = readElement() as ClassElement;
       var type = InterfaceTypeImpl(
         element: element,
         typeArguments: const <DartType>[],
@@ -668,7 +1457,7 @@
       var type = NeverTypeImpl.instance.withNullability(nullability);
       return _readAliasElementArguments(type);
     } else if (tag == Tag.TypeParameterType) {
-      var element = nextElement() as TypeParameterElement;
+      var element = readElement() as TypeParameterElement;
       var nullability = _readNullability();
       var type = TypeParameterTypeImpl(
         element: element,
@@ -683,34 +1472,50 @@
     }
   }
 
-  int readByte() {
-    return _unitReader._resolutionReader.bytes[_byteOffset++];
-  }
-
-  List<String> readStringList() {
-    var values = <String>[];
-    var length = _readUInt30();
-    for (var i = 0; i < length; i++) {
-      var value = _readStringReference();
-      values.add(value);
-    }
-    return values;
+  List<T> readTypedList<T>(T Function() read) {
+    var length = readUInt30();
+    return List<T>.generate(length, (_) {
+      return read();
+    });
   }
 
   int readUInt30() {
-    var byte = readByte();
-    if (byte & 0x80 == 0) {
-      // 0xxxxxxx
-      return byte;
-    } else if (byte & 0x40 == 0) {
-      // 10xxxxxx
-      return ((byte & 0x3F) << 8) | readByte();
+    return _reader.readUInt30();
+  }
+
+  int readUInt32() {
+    return _reader.readUInt32();
+  }
+
+  void _addFormalParameters(List<ParameterElement> parameters) {
+    for (var parameter in parameters) {
+      _localElements.add(parameter);
+    }
+  }
+
+  void _addTypeParameters(List<TypeParameterElement> typeParameters) {
+    for (var typeParameter in typeParameters) {
+      _localElements.add(typeParameter);
+    }
+  }
+
+  ElementImpl? _readAliasedElement(CompilationUnitElementImpl unitElement) {
+    var tag = _reader.readByte();
+    if (tag == AliasedElementTag.nothing) {
+      return null;
+    } else if (tag == AliasedElementTag.genericFunctionElement) {
+      var typeParameters = _readTypeParameters();
+      var formalParameters = _readFormalParameters(unitElement);
+      var returnType = readRequiredType();
+
+      _localElements.length -= typeParameters.length;
+
+      return GenericFunctionTypeElementImpl.forOffset(-1)
+        ..typeParameters = typeParameters
+        ..parameters = formalParameters
+        ..returnType = returnType;
     } else {
-      // 11xxxxxx
-      return ((byte & 0x3F) << 24) |
-          (readByte() << 16) |
-          (readByte() << 8) |
-          readByte();
+      throw UnimplementedError('tag: $tag');
     }
   }
 
@@ -755,42 +1560,77 @@
     return type;
   }
 
+  List<ElementAnnotationImpl> _readAnnotationList({
+    required CompilationUnitElementImpl unitElement,
+  }) {
+    var length = _reader.readUInt30();
+    if (length == 0) {
+      return const <ElementAnnotationImpl>[];
+    }
+    return List.generate(length, (_) {
+      var ast = _readRequiredNode() as Annotation;
+      return ElementAnnotationImpl(unitElement)
+        ..annotationAst = ast
+        ..element = ast.element;
+    });
+  }
+
+  List<ParameterElementImpl> _readFormalParameters(
+    CompilationUnitElementImpl? unitElement,
+  ) {
+    var formalParameterCount = _reader.readUInt30();
+    return List.generate(formalParameterCount, (_) {
+      var kindIndex = _reader.readByte();
+      var kind = _formalParameterKind(kindIndex);
+      var isInitializingFormal = _reader.readBool();
+      var typeParameters = _readTypeParameters();
+      var type = readRequiredType();
+      var name = readStringReference();
+      if (kind.isRequiredPositional) {
+        ParameterElementImpl element;
+        if (isInitializingFormal) {
+          element = FieldFormalParameterElementImpl(name, -1)
+            ..parameterKind = kind
+            ..type = type;
+        } else {
+          element = ParameterElementImpl(name, -1)
+            ..parameterKind = kind
+            ..type = type;
+        }
+        element.typeParameters = typeParameters;
+        element.parameters = _readFormalParameters(unitElement);
+        // TODO(scheglov) reuse for formal parameters
+        _localElements.length -= typeParameters.length;
+        if (unitElement != null) {
+          element.metadata = _readAnnotationList(unitElement: unitElement);
+        }
+        return element;
+      } else {
+        var element = DefaultParameterElementImpl(name, -1)
+          ..parameterKind = kind
+          ..type = type;
+        element.typeParameters = typeParameters;
+        element.parameters = _readFormalParameters(unitElement);
+        // TODO(scheglov) reuse for formal parameters
+        _localElements.length -= typeParameters.length;
+        if (unitElement != null) {
+          element.metadata = _readAnnotationList(unitElement: unitElement);
+        }
+        return element;
+      }
+    });
+  }
+
   /// TODO(scheglov) Optimize for write/read of types without type parameters.
   FunctionType _readFunctionType() {
-    var typeParameters = <TypeParameterElement>[];
-    var typeParametersLength = _readUInt30();
-    for (var i = 0; i < typeParametersLength; i++) {
-      var name = _readStringReference();
-      var element = TypeParameterElementImpl.synthetic(name);
-      typeParameters.add(element);
-      _localElements.add(element);
-    }
-    for (var i = 0; i < typeParametersLength; i++) {
-      var element = typeParameters[i] as TypeParameterElementImpl;
-      var bound = nextType();
-      element.bound = bound;
-    }
-
-    var returnType = nextType()!;
-
-    var formalParameters = <ParameterElement>[];
-    var formalParametersLength = _readUInt30();
-    for (var i = 0; i < formalParametersLength; i++) {
-      var kindIndex = readByte();
-      var type = nextType()!;
-      var name = nextString();
-      formalParameters.add(
-        ParameterElementImpl.synthetic(
-          name,
-          type,
-          _formalParameterKind(kindIndex),
-        ),
-      );
-    }
+    // TODO(scheglov) reuse for formal parameters
+    var typeParameters = _readTypeParameters();
+    var returnType = readRequiredType();
+    var formalParameters = _readFormalParameters(null);
 
     var nullability = _readNullability();
 
-    _localElements.length -= typeParametersLength;
+    _localElements.length -= typeParameters.length;
 
     return FunctionTypeImpl(
       typeFormals: typeParameters,
@@ -800,56 +1640,92 @@
     );
   }
 
+  InterfaceType _readInterfaceType() {
+    var element = _readRawElement() as ClassElement;
+    var typeArguments = _readTypeList();
+    var nullability = _readNullability();
+    var type = InterfaceTypeImpl(
+      element: element,
+      typeArguments: typeArguments,
+      nullabilitySuffix: nullability,
+    );
+    return type;
+  }
+
+  List<InterfaceType> _readInterfaceTypeList() {
+    var length = _reader.readUInt30();
+    if (length == 0) {
+      return const <InterfaceType>[];
+    }
+    return List.generate(length, (_) => _readInterfaceType());
+  }
+
+  List<T> _readNodeList<T>() {
+    var length = _reader.readUInt30();
+    return List<T>.generate(length, (_) {
+      return _readRequiredNode() as T;
+    });
+  }
+
   NullabilitySuffix _readNullability() {
-    var index = readByte();
+    var index = _reader.readByte();
     return NullabilitySuffix.values[index];
   }
 
+  Expression? _readOptionalExpression() {
+    if (_reader.readBool()) {
+      return _readRequiredNode() as Expression;
+    }
+  }
+
+  InterfaceType? _readOptionalInterfaceType() {
+    var hasSuperType = _reader.readByte() != 0;
+    if (hasSuperType) {
+      return _readInterfaceType();
+    }
+  }
+
   Element? _readRawElement() {
-    var index = _readUInt30();
+    var index = _reader.readUInt30();
 
     if ((index & 0x1) == 0x1) {
       return _localElements[index >> 1];
     }
 
     var referenceIndex = index >> 1;
-    var referenceReader = _unitReader._referenceReader;
-    var reference = referenceReader.referenceOfIndex(referenceIndex);
+    var reference = _referenceReader.referenceOfIndex(referenceIndex);
 
-    var elementFactory = _unitReader.elementFactory;
-    return elementFactory.elementOfReference(reference);
+    return _elementFactory.elementOfReference(reference);
   }
 
-  String _readStringReference() {
-    var index = _readUInt30();
-    return _unitReader._resolutionReader.stringOfIndex(index);
+  AstNode _readRequiredNode() {
+    var astReader = AstBinaryReader(reader: this);
+    return astReader.readNode();
   }
 
   List<DartType> _readTypeList() {
     var types = <DartType>[];
-    var length = _readUInt30();
+    var length = _reader.readUInt30();
     for (var i = 0; i < length; i++) {
-      var argument = nextType()!;
+      var argument = readType()!;
       types.add(argument);
     }
     return types;
   }
 
-  int _readUInt30() {
-    var byte = readByte();
-    if (byte & 0x80 == 0) {
-      // 0xxxxxxx
-      return byte;
-    } else if (byte & 0x40 == 0) {
-      // 10xxxxxx
-      return ((byte & 0x3F) << 8) | readByte();
-    } else {
-      // 11xxxxxx
-      return ((byte & 0x3F) << 24) |
-          (readByte() << 16) |
-          (readByte() << 8) |
-          readByte();
+  List<TypeParameterElementImpl> _readTypeParameters() {
+    var typeParameterCount = _reader.readUInt30();
+    var typeParameters = List.generate(typeParameterCount, (_) {
+      var name = readStringReference();
+      var typeParameter = TypeParameterElementImpl(name, -1);
+      _localElements.add(typeParameter);
+      return typeParameter;
+    });
+
+    for (var typeParameter in typeParameters) {
+      typeParameter.bound = readType();
     }
+    return typeParameters;
   }
 
   static ParameterKind _formalParameterKind(int encoding) {
@@ -867,480 +1743,71 @@
   }
 }
 
-class SummaryDataForCompilationUnit {
-  final int codeLength;
-
-  SummaryDataForCompilationUnit(this.codeLength);
-}
-
-class SummaryDataForFormalParameter {
-  final int codeOffset;
-  final int codeLength;
-
-  SummaryDataForFormalParameter({
-    required this.codeOffset,
-    required this.codeLength,
-  });
-}
-
-class SummaryDataForLibraryDirective {
-  final UnitReader _unitReader;
-  final LibraryDirectiveImpl _node;
-  final Uint32List _documentationTokenIndexList;
-  bool _hasDocumentationComment = false;
-
-  SummaryDataForLibraryDirective(
-    this._unitReader,
-    this._node, {
-    required Uint32List documentationTokenIndexList,
-  }) : _documentationTokenIndexList = documentationTokenIndexList {
-    _node.summaryData = this;
-  }
-
-  void readDocumentationComment() {
-    if (_hasDocumentationComment) {
-      return;
-    }
-    _hasDocumentationComment = true;
-
-    if (_documentationTokenIndexList.isEmpty) {
-      return;
-    }
-
-    var tokens = <Token>[];
-    for (var lexemeIndex in _documentationTokenIndexList) {
-      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
-      var token = TokenFactory.tokenFromString(lexeme);
-      tokens.add(token);
-    }
-
-    var comment = astFactory.documentationComment(tokens);
-    _node.documentationComment = comment;
-  }
-}
-
-class SummaryDataForTypeParameter {
-  final int codeOffset;
-  final int codeLength;
-
-  SummaryDataForTypeParameter({
-    required this.codeOffset,
-    required this.codeLength,
-  });
-}
-
-class UnitReader implements ReferenceNodeAccessor {
-  final LibraryReader libraryReader;
-
-  final Reference reference;
-
-  final bool isSynthetic;
-
-  /// If a part, the URI that is used in the [PartDirective].
-  /// Or `null` for the defining unit.
-  final String? partUriStr;
-
-  final int _directivesResolutionOffset;
-  bool _isDirectivesResolutionApplied = false;
-
-  final Uint32List _resolutionDeclarationsOffset;
-
-  final SummaryDataReader astReader;
-
-  late final int _directivesOffset;
-  final List<_UnitMemberReader> _memberReaders = [];
-
-  late final CompilationUnitImpl _unit;
-  bool _hasDirectives = false;
-  bool _hasDeclarations = false;
-
-  UnitReader._(
-    this.libraryReader,
-    this._directivesResolutionOffset,
-    this._resolutionDeclarationsOffset,
-    this.reference,
-    this.isSynthetic,
-    this.partUriStr,
-    this.astReader,
-    int headerOffset,
-    int indexOffset,
-  ) {
-    reference.nodeAccessor = this;
-
-    astReader.offset = headerOffset;
-    var languageVersion = _readLanguageVersion();
-    var featureSetEncoded = astReader.readUint8List();
-    var lineInfo = _readLineInfo();
-    var codeLength = astReader.readUInt30();
-    var featureSet = ExperimentStatus.fromStorage(featureSetEncoded);
-    _directivesOffset = astReader.offset;
-
-    _unit = astFactory.compilationUnit(
-      beginToken: Tokens.BANG,
-      // TODO(scheglov)
-      // scriptTag: _readNode(data.compilationUnit_scriptTag),
-      directives: [],
-      declarations: [],
-      endToken: Tokens.BANG,
-      featureSet: featureSet,
-    );
-    _unit.languageVersion = languageVersion;
-    _unit.lineInfo = lineInfo;
-    _unit.summaryData = SummaryDataForCompilationUnit(codeLength);
-
-    astReader.offset = indexOffset;
-    _readIndex2();
-  }
-
-  LinkedElementFactory get elementFactory => libraryReader._elementFactory;
-
-  /// TODO(scheglov)
-  /// This methods breaks lazy loading, and loads everything eagerly.
-  /// We use it because of `unitElement.types` for example, when we are
-  /// explicitly asked for all [ClassDeclaration]s and [ClassTypeAlias]s.
-  @Deprecated('review it')
-  @override
-  CompilationUnit get node {
-    readDirectives();
-    readDeclarations();
-    return _unit;
-  }
-
-  CompilationUnit get unit => _unit;
-
-  String get uriStr => reference.name;
-
-  bool get withInformative => libraryReader.withInformative;
-
-  _ReferenceReader get _referenceReader => libraryReader._referenceReader;
-
-  SummaryDataReader get _resolutionReader => libraryReader._resolutionReader;
-
-  /// Apply resolution to directives.
-  void applyDirectivesResolution(LinkedUnitContext unitContext) {
-    if (_isDirectivesResolutionApplied) {
-      return;
-    }
-    _isDirectivesResolutionApplied = true;
-
-    var localElements = <Element>[];
-    var resolutionReader = LinkedResolutionReader(
-      this,
-      localElements,
-      _directivesResolutionOffset,
-    );
-    for (var directive in _unit.directives) {
-      directive.accept(
-        ApplyResolutionVisitor(
-          unitContext,
-          localElements,
-          resolutionReader,
-        ),
-      );
-    }
-  }
-
-  void readDeclarations() {
-    if (!_hasDeclarations) {
-      _hasDeclarations = true;
-      for (var reader in _memberReaders) {
-        reader.node;
-      }
-    }
-  }
-
-  /// Ensure that directives are read in this unit.
-  void readDirectives() {
-    if (!_hasDirectives) {
-      _hasDirectives = true;
-      astReader.offset = _directivesOffset;
-      var length = astReader.readUInt30();
-      for (var i = 0; i < length; i++) {
-        var astReader = AstBinaryReader(
-          reader: this,
-        );
-        var directive = astReader.readNode() as Directive;
-        _unit.directives.add(directive);
-      }
-    }
-  }
-
-  @override
-  void readIndex() {}
-
-  /// Read the index of declarations in this unit, and add `null`s into
-  /// [CompilationUnit.declarations] as placeholders.
-  ///
-  /// TODO(scheglov) we don't need both this method, and [readIndex].
-  void _readIndex2() {
-    var unitReference = reference;
-    var length = astReader.readUInt30();
-    for (var i = 0; i < length; i++) {
-      var offset = astReader.readUInt30();
-      var tag = astReader.readByte();
-      if (tag == Tag.Class) {
-        var name = astReader.readStringReference();
-        var indexOffset = astReader.readUInt30();
-        var reference = unitReference.getChild('@class').getChild(name);
-        _memberReaders.add(
-          _ClassReader(
-            unitReader: this,
-            reference: reference,
-            offset: offset,
-            unit: _unit,
-            indexOffset: indexOffset,
-          ),
-        );
-      } else if (tag == Tag.ClassTypeAlias) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        unitReference.getChild('@class').getChild(name).nodeAccessor = reader;
-      } else if (tag == Tag.EnumDeclaration) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        unitReference.getChild('@enum').getChild(name).nodeAccessor = reader;
-      } else if (tag == Tag.ExtensionDeclaration) {
-        var name = astReader.readStringReference();
-        var indexOffset = astReader.readUInt30();
-        var reference = unitReference.getChild('@extension').getChild(name);
-        _memberReaders.add(
-          _ClassReader(
-            unitReader: this,
-            reference: reference,
-            offset: offset,
-            unit: _unit,
-            indexOffset: indexOffset,
-          ),
-        );
-      } else if (tag == Tag.FunctionDeclaration) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        var containerRef = unitReference.getChild('@function');
-        containerRef.getChild(name).nodeAccessor = reader;
-      } else if (tag == Tag.FunctionDeclaration_getter) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        var getterRef = unitReference.getChild('@getter');
-        getterRef.getChild(name).nodeAccessor = reader;
-        var variableRef = unitReference.getChild('@variable');
-        variableRef.getChild(name).nodeAccessor ??= reader;
-      } else if (tag == Tag.FunctionDeclaration_setter) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        var setterRef = unitReference.getChild('@setter');
-        setterRef.getChild(name).nodeAccessor = reader;
-        var variableRef = unitReference.getChild('@variable');
-        variableRef.getChild(name).nodeAccessor ??= reader;
-      } else if (tag == Tag.GenericTypeAlias) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
-            reader;
-      } else if (tag == Tag.FunctionTypeAlias) {
-        var name = astReader.readStringReference();
-        var reader = _UnitMemberReader(this, offset, _unit);
-        _memberReaders.add(reader);
-        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
-            reader;
-      } else if (tag == Tag.MixinDeclaration) {
-        var name = astReader.readStringReference();
-        var indexOffset = astReader.readUInt30();
-        var reference = unitReference.getChild('@mixin').getChild(name);
-        _memberReaders.add(
-          _ClassReader(
-            unitReader: this,
-            reference: reference,
-            offset: offset,
-            unit: _unit,
-            indexOffset: indexOffset,
-          ),
-        );
-      } else if (tag == Tag.TopLevelVariableDeclaration) {
-        var reader = _UnitMemberReader(this, offset, _unit);
-        var length = astReader.readUInt30();
-        for (var i = 0; i < length; i++) {
-          var name = astReader.readStringReference();
-          _memberReaders.add(reader);
-          unitReference.getChild('@getter').getChild(name).nodeAccessor =
-              reader;
-          // TODO(scheglov) only if not final/const
-          // Crash in language_2/export/local_export_test.dart
-          unitReference.getChild('@setter').getChild(name).nodeAccessor =
-              reader;
-        }
-      } else {
-        // TODO(scheglov) implement
-      }
-    }
-  }
-
-  LibraryLanguageVersion _readLanguageVersion() {
-    var packageMajor = astReader.readUInt30();
-    var packageMinor = astReader.readUInt30();
-    var overrideMajor = astReader.readUInt30();
-    var overrideMinor = astReader.readUInt30();
-    return LibraryLanguageVersion(
-      package: Version(packageMajor, packageMinor, 0),
-      override: overrideMajor > 0
-          ? Version(overrideMajor - 1, overrideMinor - 1, 0)
-          : null,
-    );
-  }
-
-  LineInfo _readLineInfo() {
-    var lineStarts = astReader.readUint30List();
-    return LineInfo(lineStarts);
-  }
-}
-
-class _ClassMemberMock extends AstNodeImpl implements ClassMemberImpl {
-  static final instance = _ClassMemberMock();
-
-  @override
-  AstNode? parent;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class _ClassMemberReader implements ReferenceNodeAccessor {
-  final UnitReader unitReader;
-  final int offset;
-  final List<ClassMember> _members;
-  final int _membersIndex;
-  ClassMemberImpl? _node;
-
-  _ClassMemberReader(this.unitReader, this.offset, this._members)
-      : _membersIndex = _members.length {
-    _members.add(_ClassMemberMock.instance);
-  }
-
-  @override
-  AstNode get node {
-    if (_node == null) {
-      var astReader = AstBinaryReader(
-        reader: unitReader,
-      );
-      unitReader.astReader.offset = offset;
-      _node = astReader.readNode() as ClassMemberImpl;
-      _members[_membersIndex] = _node!;
-    }
-    return _node!;
-  }
-
-  @override
-  void readIndex() {}
-}
-
-class _ClassReader extends _UnitMemberReader {
-  final Reference reference;
-  final int indexOffset;
-
-  bool _hasIndex = false;
-  final List<_ClassMemberReader> _classMemberReaders = [];
-  late final List<ClassMember> _classMembers;
-
-  _ClassReader({
-    required this.reference,
-    required UnitReader unitReader,
+class TopLevelVariableElementLinkedData
+    extends ElementLinkedData<TopLevelVariableElementImpl> {
+  TopLevelVariableElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
     required int offset,
-    required CompilationUnitImpl unit,
-    required this.indexOffset,
-  }) : super(unitReader, offset, unit) {
-    reference.nodeAccessor ??= this;
-  }
-
-  List<_ClassMemberReader> get classMemberReaders {
-    readIndex();
-    return _classMemberReaders;
-  }
-
-  List<ClassMember> get classMembers {
-    return classMemberReaders.map((e) => e.node as ClassMember).toList();
-  }
+  }) : super(reference, libraryReader, unitElement, offset);
 
   @override
-  void readIndex() {
-    if (_hasIndex) return;
-    _hasIndex = true;
-
-    var node = _node;
-    if (node == null) {
-      throw StateError('The class node must be read before reading members.');
-    }
-
-    if (node is ClassDeclarationImpl) {
-      _classMembers = node.members;
-    } else if (node is ExtensionDeclarationImpl) {
-      _classMembers = node.members;
-    } else if (node is MixinDeclarationImpl) {
-      _classMembers = node.members;
-    } else {
-      throw StateError('(${node.runtimeType}) $node');
-    }
-
-    unitReader.astReader.offset = indexOffset;
-
-    var length = unitReader.astReader.readUInt30();
-    for (var i = 0; i < length; i++) {
-      var offset = unitReader.astReader.readUInt30();
-      var tag = unitReader.astReader.readByte();
-      if (tag == Tag.ConstructorDeclaration) {
-        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
-        _classMemberReaders.add(reader);
-        var name = unitReader.astReader.readStringReference();
-        var reference = this.reference.getChild('@constructor').getChild(name);
-        reference.nodeAccessor ??= reader;
-      } else if (tag == Tag.MethodDeclaration) {
-        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
-        _classMemberReaders.add(reader);
-        var name = unitReader.astReader.readStringReference();
-        var reference = this.reference.getChild('@method').getChild(name);
-        reference.nodeAccessor ??= reader;
-      } else if (tag == Tag.MethodDeclaration_getter) {
-        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
-        _classMemberReaders.add(reader);
-        var name = unitReader.astReader.readStringReference();
-        var reference = this.reference.getChild('@getter').getChild(name);
-        reference.nodeAccessor ??= reader;
-      } else if (tag == Tag.MethodDeclaration_setter) {
-        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
-        _classMemberReaders.add(reader);
-        var name = unitReader.astReader.readStringReference();
-        var reference = this.reference.getChild('@setter').getChild(name);
-        reference.nodeAccessor ??= reader;
-      } else if (tag == Tag.FieldDeclaration) {
-        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
-        _classMemberReaders.add(reader);
-        var length = unitReader.astReader.readUInt30();
-        for (var i = 0; i < length; i++) {
-          var name = unitReader.astReader.readStringReference();
-          var fieldRef = reference.getChild('@field').getChild(name);
-          fieldRef.nodeAccessor ??= reader;
-          var getterRef = reference.getChild('@getter').getChild(name);
-          getterRef.nodeAccessor ??= reader;
-          var setterRef = reference.getChild('@setter').getChild(name);
-          setterRef.nodeAccessor ??= reader;
-        }
-      } else {
-        throw UnimplementedError('tag: $tag');
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    element.type = reader.readRequiredType();
+    if (element is ConstTopLevelVariableElementImpl) {
+      var initializer = reader._readOptionalExpression();
+      if (initializer != null) {
+        element.constantInitializer = initializer;
+        ExpressionImpl.inConstContextWithoutParent[initializer] = true;
       }
     }
   }
 }
 
-class _CompilationUnitMemberMock extends AstNodeImpl
-    implements CompilationUnitMemberImpl {
-  static final instance = _CompilationUnitMemberMock();
+class TypeAliasElementLinkedData
+    extends ElementLinkedData<TypeAliasElementImpl> {
+  TypeAliasElementLinkedData({
+    required Reference reference,
+    required LibraryReader libraryReader,
+    required CompilationUnitElementImpl unitElement,
+    required int offset,
+  }) : super(reference, libraryReader, unitElement, offset);
 
   @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  void _read(element, reader) {
+    element.metadata = reader._readAnnotationList(
+      unitElement: unitElement,
+    );
+    _readTypeParameters(reader, element.typeParameters);
+    element.aliasedElement = reader._readAliasedElement(unitElement);
+    element.aliasedType = reader.readRequiredType();
+  }
+}
+
+/// Information that we need to know about each library before reading it,
+/// and without reading it.
+///
+/// Specifically, the [offset] allows us to know the location of each library,
+/// so that when we need to read this library, we know where it starts without
+/// reading previous libraries.
+class _LibraryHeader {
+  final String uriStr;
+  final int offset;
+
+  /// We don't read class members when reading libraries, by performance
+  /// reasons - in many cases only some classes of a library are used. But
+  /// we need to know how much data to skip for each class.
+  final Uint32List classMembersLengths;
+
+  _LibraryHeader({
+    required this.uriStr,
+    required this.offset,
+    required this.classMembersLengths,
+  });
 }
 
 class _ReferenceReader {
@@ -1352,8 +1819,8 @@
 
   _ReferenceReader(this.elementFactory, this._reader, int offset) {
     _reader.offset = offset;
-    _parents = _reader.readUint30List();
-    _names = _reader.readUint30List();
+    _parents = _reader.readUInt30List();
+    _names = _reader.readUInt30List();
     assert(_parents.length == _names.length);
 
     _references = List.filled(_names.length, null);
@@ -1383,36 +1850,3 @@
     return reference;
   }
 }
-
-class _UnitMemberReader implements ReferenceNodeAccessor {
-  final UnitReader unitReader;
-  final int offset;
-  final CompilationUnitImpl _unit;
-  final int _index;
-  CompilationUnitMemberImpl? _node;
-
-  _UnitMemberReader(this.unitReader, this.offset, this._unit)
-      : _index = _unit.declarations.length {
-    _unit.declarations.add(_CompilationUnitMemberMock.instance);
-  }
-
-  @override
-  AstNode get node {
-    if (_node == null) {
-      var astReader = AstBinaryReader(
-        reader: unitReader,
-      );
-      unitReader.astReader.offset = offset;
-      _node = astReader.readNode() as CompilationUnitMemberImpl;
-      _unit.declarations[_index] = _node!;
-
-      var hasLinkedContext = _node as HasAstLinkedContext;
-      var linkedContext = hasLinkedContext.linkedContext as LinkedContext;
-      linkedContext._reader = this;
-    }
-    return _node!;
-  }
-
-  @override
-  void readIndex() {}
-}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index ba30eb0..b3f5a5a 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -4,310 +4,400 @@
 
 import 'dart:typed_data';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/summary2/ast_binary_tag.dart';
 import 'package:analyzer/src/summary2/ast_binary_writer.dart';
-import 'package:analyzer/src/summary2/binary_format_doc.dart';
 import 'package:analyzer/src/summary2/data_writer.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/task/inference_error.dart';
 import 'package:collection/collection.dart';
 
-Uint8List writeUnitToBytes({required CompilationUnit unit}) {
-  var byteSink = ByteSink();
-  var sink = BufferedSink(byteSink);
-  var stringIndexer = StringIndexer();
-
-  var headerOffset = sink.offset;
-  var nextResolutionIndex = 0;
-  var unitWriter = AstBinaryWriter(
-    withInformative: true,
-    sink: sink,
-    stringIndexer: stringIndexer,
-    getNextResolutionIndex: () => nextResolutionIndex++,
-    resolutionSink: null,
-  );
-  unit.accept(unitWriter);
-
-  void _writeStringReference(String string) {
-    var index = stringIndexer[string];
-    sink.writeUInt30(index);
-  }
-
-  var indexOffset = sink.offset;
-  sink.writeUInt30(unitWriter.unitMemberIndexItems.length);
-  for (var declaration in unitWriter.unitMemberIndexItems) {
-    sink.writeUInt30(declaration.offset);
-    sink.writeByte(declaration.tag);
-    declaration.name.map((name) {
-      _writeStringReference(name);
-    }, (variableNames) {
-      sink.writeList(variableNames, _writeStringReference);
-    });
-    if (declaration.classIndexOffset != 0) {
-      sink.writeUInt30(declaration.classIndexOffset);
-    }
-  }
-
-  var libraryDataOffset = sink.offset;
-  {
-    var name = '';
-    var nameOffset = -1;
-    var nameLength = 0;
-    for (var directive in unit.directives) {
-      if (directive is LibraryDirective) {
-        name = directive.name.components.map((e) => e.name).join('.');
-        nameOffset = directive.name.offset;
-        nameLength = directive.name.length;
-        break;
-      }
-    }
-
-    var hasPartOfDirective = false;
-    for (var directive in unit.directives) {
-      if (directive is PartOfDirective) {
-        hasPartOfDirective = true;
-        break;
-      }
-    }
-    _writeStringReference(name);
-    sink.writeUInt30(nameOffset + 1);
-    sink.writeUInt30(nameLength);
-    sink.writeByte(hasPartOfDirective ? 1 : 0);
-    sink.writeByte(1); // withInformative
-  }
-
-  var stringTableOffset = stringIndexer.write(sink);
-
-  sink.writeUInt32(headerOffset);
-  sink.writeUInt32(indexOffset);
-  sink.writeUInt32(libraryDataOffset);
-  sink.writeUInt32(stringTableOffset);
-
-  sink.flushAndDestroy();
-  return byteSink.builder.takeBytes();
-}
-
 class BundleWriter {
-  final bool withInformative;
-  late final BundleWriterAst _astWriter;
-  late final BundleWriterResolution _resolutionWriter;
-
-  BundleWriter(this.withInformative, Reference dynamicReference) {
-    _astWriter = BundleWriterAst(withInformative);
-    _resolutionWriter = BundleWriterResolution(dynamicReference);
-  }
-
-  void addLibraryAst(LibraryToWriteAst library) {
-    var astUnitOffsets = <int>[];
-    for (var unit in library.units) {
-      var offset = _astWriter.writeUnit(unit.node);
-      astUnitOffsets.add(offset);
-    }
-    _astWriter.writeLibrary(library.units[0].node, astUnitOffsets);
-  }
-
-  void addLibraryResolution(LibraryToWriteResolution library) {
-    var resolutionLibrary = _resolutionWriter.enterLibrary(library);
-    for (var unit in library.units) {
-      var resolutionUnit = resolutionLibrary.enterUnit(unit);
-      // TODO(scheglov) Is it better to have a throwaway Object, or null?
-      var notUsedSink = BufferedSink(ByteSink());
-      var notUsedStringIndexer = StringIndexer();
-      var unitWriter = AstBinaryWriter(
-        withInformative: withInformative,
-        sink: notUsedSink,
-        stringIndexer: notUsedStringIndexer,
-        getNextResolutionIndex: resolutionUnit.enterDeclaration,
-        resolutionSink: resolutionUnit.library.sink,
-      );
-      unit.node.accept(unitWriter);
-    }
-  }
-
-  BundleWriterResult finish() {
-    var astBytes = _astWriter.finish();
-    var resolutionBytes = _resolutionWriter.finish();
-    return BundleWriterResult(
-      astBytes: astBytes,
-      resolutionBytes: resolutionBytes,
-    );
-  }
-}
-
-class BundleWriterAst {
-  final bool withInformative;
-  final ByteSink _byteSink = ByteSink();
-  late final BufferedSink sink;
-  final StringIndexer stringIndexer = StringIndexer();
-
-  final List<int> _libraryOffsets = [];
-
-  BundleWriterAst(this.withInformative) {
-    sink = BufferedSink(_byteSink);
-    sink.writeByte(withInformative ? 1 : 0);
-  }
-
-  Uint8List finish() {
-    var librariesOffset = sink.offset;
-    sink.writeUint30List(_libraryOffsets);
-
-    var stringTableOffset = stringIndexer.write(sink);
-
-    sink.writeUInt32(librariesOffset);
-    sink.writeUInt32(stringTableOffset);
-
-    sink.flushAndDestroy();
-    return _byteSink.builder.takeBytes();
-  }
-
-  /// Write the library name and offset, and pointers to [unitOffsets].
-  void writeLibrary(CompilationUnit definingUnit, List<int> unitOffsets) {
-    _libraryOffsets.add(sink.offset);
-
-    var name = '';
-    var nameOffset = -1;
-    var nameLength = 0;
-    for (var directive in definingUnit.directives) {
-      if (directive is LibraryDirective) {
-        name = directive.name.components.map((e) => e.name).join('.');
-        nameOffset = directive.name.offset;
-        nameLength = directive.name.length;
-        break;
-      }
-    }
-
-    var hasPartOfDirective = false;
-    for (var directive in definingUnit.directives) {
-      if (directive is PartOfDirective) {
-        hasPartOfDirective = true;
-        break;
-      }
-    }
-
-    _writeStringReference(name);
-    sink.writeUInt30(1 + nameOffset);
-    sink.writeUInt30(nameLength);
-    sink.writeByte(hasPartOfDirective ? 1 : 0);
-    sink.writeUint30List(unitOffsets);
-  }
-
-  /// Write the [node] into the [sink].
-  ///
-  /// Return the pointer at [AstUnitFormat.headerOffset].
-  ///
-  /// TODO(scheglov) looks very similar to [writeUnitToBytes]
-  int writeUnit(CompilationUnit node) {
-    var headerOffset = sink.offset;
-
-    var nextResolutionIndex = 0;
-    var unitWriter = AstBinaryWriter(
-      withInformative: withInformative,
-      sink: sink,
-      stringIndexer: stringIndexer,
-      getNextResolutionIndex: () => nextResolutionIndex++,
-      resolutionSink: null,
-    );
-    node.accept(unitWriter);
-
-    var indexOffset = sink.offset;
-    sink.writeUInt30(headerOffset);
-
-    sink.writeUInt30(unitWriter.unitMemberIndexItems.length);
-    for (var declaration in unitWriter.unitMemberIndexItems) {
-      sink.writeUInt30(declaration.offset);
-      sink.writeByte(declaration.tag);
-      declaration.name.map((name) {
-        _writeStringReference(name);
-      }, (variableNames) {
-        sink.writeList(variableNames, _writeStringReference);
-      });
-      if (declaration.classIndexOffset != 0) {
-        sink.writeUInt30(declaration.classIndexOffset);
-      }
-    }
-
-    return indexOffset;
-  }
-
-  void _writeStringReference(String string) {
-    var index = stringIndexer[string];
-    sink.writeUInt30(index);
-  }
-}
-
-class BundleWriterResolution {
   late final _BundleWriterReferences _references;
-  final ByteSink _byteSink = ByteSink();
-  late final BufferedSink _sink;
-  late final ResolutionSink _resolutionSink;
+
+  /// The declaration sink - any data that can be read without a need to
+  /// have any other elements to be available. For example declarations of
+  /// classes, methods, functions, etc. But not supertypes of classes, or
+  /// return types of methods - these might reference other classes that we
+  /// have not read yet. Such resolution data is stored into [_resolutionSink].
+  ///
+  /// Some resolution data is still written into this sink, if it does not
+  /// require any other declaration read it later. For example type inference
+  /// errors, or whether a parameter inherits `covariant`, or a class is
+  /// simply bounded.
+  late final _SummaryDataWriter _sink = _SummaryDataWriter(
+    sink: ByteSink(),
+    stringIndexer: _stringIndexer,
+  );
+
+  /// The resolution sink - any data that references elements, so can only
+  /// be read after elements are created and available via its [Reference]s.
+  late final ResolutionSink _resolutionSink = ResolutionSink(
+    sink: ByteSink(),
+    stringIndexer: _stringIndexer,
+    references: _references,
+  );
+
+  /// [_writeClassElement] remembers the length of data written into [_sink]
+  /// while writing members. So, when we read, we can skip members initially,
+  /// and read them later on demand.
+  List<int> _classMembersLengths = [];
 
   final StringIndexer _stringIndexer = StringIndexer();
 
-  final List<_ResolutionLibrary> _libraries = [];
+  final List<_Library> _libraries = [];
 
-  BundleWriterResolution(Reference dynamicReference) {
+  BundleWriter(Reference dynamicReference) {
     _references = _BundleWriterReferences(dynamicReference);
-
-    _sink = BufferedSink(_byteSink);
-    _resolutionSink = ResolutionSink(
-      stringIndexer: _stringIndexer,
-      sink: _sink,
-      references: _references,
-    );
   }
 
-  _ResolutionLibrary enterLibrary(LibraryToWriteResolution libraryToWrite) {
-    var library = _ResolutionLibrary(
-      sink: _resolutionSink,
-      library: libraryToWrite,
-    );
-    _libraries.add(library);
-    return library;
-  }
-
-  Uint8List finish() {
-    var libraryOffsets = <int>[];
-    for (var library in _libraries) {
-      var unitOffsets = <int>[];
-      for (var unit in library.units) {
-        unitOffsets.add(_sink.offset);
-        _writeStringReference(unit.unit.uriStr);
-        _sink.writeByte(unit.unit.isSynthetic ? 1 : 0);
-        _sink.writeByte(unit.unit.partUriStr != null ? 1 : 0);
-        _writeStringReference(unit.unit.partUriStr ?? '');
-        _sink.writeUInt30(unit.directivesOffset);
-        _sink.writeUint30List(unit.offsets);
-      }
-      libraryOffsets.add(_sink.offset);
-      _writeStringReference(library.library.uriStr);
-      _sink.writeUint30List(unitOffsets);
-      _writeReferences(library.library.exports);
-    }
-
-    _references._clearIndexes();
+  BundleWriterResult finish() {
+    var baseResolutionOffset = _sink.offset;
+    _sink.addBytes(_resolutionSink.flushAndTake());
 
     var librariesOffset = _sink.offset;
-    _sink.writeUint30List(libraryOffsets);
+    _sink.writeList<_Library>(_libraries, (library) {
+      _sink._writeStringReference(library.uriStr);
+      _sink.writeUInt30(library.offset);
+      _sink.writeUint30List(library.classMembersOffsets);
+    });
 
     var referencesOffset = _sink.offset;
     _sink.writeUint30List(_references._referenceParents);
-    _writeStringList(_references._referenceNames);
+    _sink._writeStringList(_references._referenceNames);
+    _references._clearIndexes();
 
     var stringTableOffset = _stringIndexer.write(_sink);
 
     // Write as Uint32 so that we know where it is.
+    _sink.writeUInt32(baseResolutionOffset);
     _sink.writeUInt32(librariesOffset);
     _sink.writeUInt32(referencesOffset);
     _sink.writeUInt32(stringTableOffset);
 
-    _sink.flushAndDestroy();
-    return _byteSink.builder.takeBytes();
+    var bytes = _sink.flushAndTake();
+    return BundleWriterResult(
+      astBytes: Uint8List(0),
+      resolutionBytes: bytes,
+    );
+  }
+
+  void writeLibraryElement(
+    LibraryElementImpl libraryElement,
+    List<Reference> exports,
+  ) {
+    var libraryOffset = _sink.offset;
+    _classMembersLengths = <int>[];
+
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(libraryElement.name!);
+    _writeFeatureSet(libraryElement.featureSet);
+    _writeLanguageVersion(libraryElement.languageVersion);
+    _resolutionSink._writeAnnotationList(libraryElement.metadata);
+    _writeList(libraryElement.imports, _writeImportElement);
+    _writeList(libraryElement.exports, _writeExportElement);
+    _resolutionSink.writeElement(libraryElement.entryPoint);
+    _sink.writeBool(libraryElement.hasExtUri);
+    _sink.writeBool(libraryElement.hasPartOfDirective);
+    _sink.writeBool(libraryElement.isSynthetic);
+    _sink.writeUInt30(libraryElement.units.length);
+    for (var unitElement in libraryElement.units) {
+      _writeUnitElement(unitElement);
+    }
+    _writeReferences(exports);
+
+    _libraries.add(
+      _Library(
+        uriStr: '${libraryElement.source.uri}',
+        offset: libraryOffset,
+        classMembersOffsets: _classMembersLengths,
+      ),
+    );
+  }
+
+  void _writeClassElement(ClassElement element) {
+    _sink.writeUInt30(_resolutionSink.offset);
+
+    _sink._writeStringReference(element.name);
+    // TODO(scheglov) pack flags
+    _sink.writeBool(element.isAbstract);
+    _sink.writeBool(element.isMixinApplication);
+    _sink.writeBool(element.isSimplyBounded);
+
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _resolutionSink.writeOptionalInterfaceType(element.supertype);
+      _resolutionSink._writeInterfaceTypeList(element.mixins);
+      _resolutionSink._writeInterfaceTypeList(element.interfaces);
+
+      if (!element.isMixinApplication) {
+        var membersOffset = _sink.offset;
+        _writeList(
+          element.fields.where((e) => !e.isSynthetic).toList(),
+          _writeFieldElement,
+        );
+        _writeList(
+          element.accessors.where((e) => !e.isSynthetic).toList(),
+          _writePropertyAccessorElement,
+        );
+        _writeList(element.constructors, _writeConstructorElement);
+        _writeList(element.methods, _writeMethodElement);
+        _classMembersLengths.add(_sink.offset - membersOffset);
+      }
+    });
+  }
+
+  void _writeConstructorElement(ConstructorElement element) {
+    element as ConstructorElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.name);
+    // TODO(scheglov) pack flags
+    _sink.writeBool(element.isConst);
+    _sink.writeBool(element.isExternal);
+    _sink.writeBool(element.isFactory);
+    _sink.writeBool(element.isSynthetic);
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _resolutionSink.localElements.pushScope();
+    _resolutionSink.localElements.declareAll(element.parameters);
+    try {
+      _writeList(element.parameters, _writeParameterElement);
+      if (element.isConst || element.isFactory) {
+        _resolutionSink.writeElement(element.redirectedConstructor);
+        _resolutionSink._writeNodeList(element.constantInitializers);
+      }
+    } finally {
+      _resolutionSink.localElements.popScope();
+    }
+  }
+
+  void _writeEnumElement(ClassElement element) {
+    element as EnumElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.name);
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    var constants = element.fields.where((e) => !e.isSynthetic).toList();
+    _writeList<FieldElement>(constants, (field) {
+      _sink._writeStringReference(field.name);
+      _resolutionSink._writeAnnotationList(field.metadata);
+    });
+  }
+
+  void _writeExportElement(ExportElement element) {
+    _sink._writeOptionalStringReference(element.uri);
+    _sink.writeList(element.combinators, _writeNamespaceCombinator);
+    _resolutionSink._writeAnnotationList(element.metadata);
+    _resolutionSink.writeElement(element.exportedLibrary);
+  }
+
+  void _writeExtensionElement(ExtensionElement element) {
+    _sink.writeUInt30(_resolutionSink.offset);
+
+    _sink._writeOptionalStringReference(element.name);
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _resolutionSink.writeType(element.extendedType);
+
+      _writeList(
+        element.accessors.where((e) => !e.isSynthetic).toList(),
+        _writePropertyAccessorElement,
+      );
+      _writeList(
+        element.fields.where((e) => !e.isSynthetic).toList(),
+        _writeFieldElement,
+      );
+      _writeList(element.methods, _writeMethodElement);
+    });
+  }
+
+  void _writeFeatureSet(FeatureSet featureSet) {
+    var experimentStatus = featureSet as ExperimentStatus;
+    var encoded = experimentStatus.toStorage();
+    _sink.writeUint8List(encoded);
+  }
+
+  void _writeFieldElement(FieldElement element) {
+    element as FieldElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.name);
+    _sink.writeBool(element is ConstFieldElementImpl);
+    _sink.writeBool(element.hasImplicitType);
+    _sink.writeBool(element.hasInitializer);
+    _sink.writeBool(element.inheritsCovariant);
+    _sink.writeBool(element.isAbstract);
+    _sink.writeBool(element.isConst);
+    _sink.writeBool(element.isCovariant);
+    _sink.writeBool(element.isExternal);
+    _sink.writeBool(element.isFinal);
+    _sink.writeBool(element.isLate);
+    _sink.writeBool(element.isStatic);
+    _sink._writeTopLevelInferenceError(element.typeInferenceError);
+    _resolutionSink._writeAnnotationList(element.metadata);
+    _resolutionSink.writeType(element.type);
+    _resolutionSink._writeOptionalNode(element.constantInitializer);
+  }
+
+  void _writeFunctionElement(FunctionElement element) {
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.name);
+    _sink.writeBool(element.hasImplicitReturnType);
+    _sink.writeBool(element.isAsynchronous);
+    _sink.writeBool(element.isExternal);
+    _sink.writeBool(element.isGenerator);
+
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _resolutionSink.writeType(element.returnType);
+      _writeList(element.parameters, _writeParameterElement);
+    });
+  }
+
+  void _writeImportElement(ImportElement element) {
+    _sink.writeBool(element.isDeferred);
+    _sink.writeBool(element.isSynthetic);
+    _sink._writeOptionalStringReference(element.uri);
+    _sink._writeOptionalStringReference(element.prefix?.name);
+    _sink.writeList(element.combinators, _writeNamespaceCombinator);
+    _resolutionSink._writeAnnotationList(element.metadata);
+    _resolutionSink.writeElement(element.importedLibrary);
+  }
+
+  void _writeLanguageVersion(LibraryLanguageVersion version) {
+    _sink.writeUInt30(version.package.major);
+    _sink.writeUInt30(version.package.minor);
+
+    var override = version.override;
+    if (override != null) {
+      _sink.writeBool(true);
+      _sink.writeUInt30(override.major);
+      _sink.writeUInt30(override.minor);
+    } else {
+      _sink.writeBool(false);
+    }
+  }
+
+  void _writeList<T>(List<T> elements, void Function(T) writeElement) {
+    _sink.writeUInt30(elements.length);
+    for (var element in elements) {
+      writeElement(element);
+    }
+  }
+
+  void _writeMethodElement(MethodElement element) {
+    element as MethodElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.name);
+    _sink.writeBool(element.hasImplicitReturnType);
+    _sink.writeBool(element.isAbstract);
+    _sink.writeBool(element.isAsynchronous);
+    _sink.writeBool(element.isExternal);
+    _sink.writeBool(element.isGenerator);
+    _sink.writeBool(element.isStatic);
+
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _writeList(element.parameters, _writeParameterElement);
+      _sink._writeTopLevelInferenceError(element.typeInferenceError);
+      _resolutionSink.writeType(element.returnType);
+    });
+  }
+
+  void _writeMixinElement(ClassElement element) {
+    element as MixinElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+
+    _sink._writeStringReference(element.name);
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _resolutionSink._writeInterfaceTypeList(element.superclassConstraints);
+      _resolutionSink._writeInterfaceTypeList(element.interfaces);
+
+      _writeList(
+        element.accessors.where((e) => !e.isSynthetic).toList(),
+        _writePropertyAccessorElement,
+      );
+      _writeList(
+        element.fields.where((e) => !e.isSynthetic).toList(),
+        _writeFieldElement,
+      );
+      _writeList(element.constructors, _writeConstructorElement);
+      _writeList(element.methods, _writeMethodElement);
+      _sink._writeStringList(element.superInvokedNames);
+    });
+  }
+
+  void _writeNamespaceCombinator(NamespaceCombinator combinator) {
+    if (combinator is HideElementCombinator) {
+      _sink.writeByte(Tag.HideCombinator);
+      _sink.writeList<String>(combinator.hiddenNames, (name) {
+        _sink._writeStringReference(name);
+      });
+    } else if (combinator is ShowElementCombinator) {
+      _sink.writeByte(Tag.ShowCombinator);
+      _sink.writeList<String>(combinator.shownNames, (name) {
+        _sink._writeStringReference(name);
+      });
+    } else {
+      throw UnimplementedError('${combinator.runtimeType}');
+    }
+  }
+
+  void _writeParameterElement(ParameterElement element) {
+    element as ParameterElementImpl;
+    _sink._writeStringReference(element.name);
+    _sink.writeBool(element.isInitializingFormal);
+    _sink._writeFormalParameterKind(element);
+    _sink.writeBool(element.hasImplicitType);
+    _sink.writeBool(element.inheritsCovariant);
+    _sink.writeBool(element.isExplicitlyCovariant);
+    _sink.writeBool(element.isFinal);
+
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _writeList(element.parameters, _writeParameterElement);
+      _resolutionSink.writeType(element.type);
+
+      if (element is ConstVariableElement) {
+        var constElement = element as ConstVariableElement;
+        _resolutionSink._writeOptionalNode(constElement.constantInitializer);
+      }
+      if (element is FieldFormalParameterElementImpl) {
+        _resolutionSink.writeElement(element.field);
+      }
+    });
+  }
+
+  void _writePropertyAccessorElement(PropertyAccessorElement element) {
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.displayName);
+    _sink.writeBool(element.isGetter);
+    _sink.writeBool(element.isSetter);
+    _sink.writeBool(element.hasImplicitReturnType);
+    _sink.writeBool(element.isAbstract);
+    _sink.writeBool(element.isAsynchronous);
+    _sink.writeBool(element.isExternal);
+    _sink.writeBool(element.isGenerator);
+    _sink.writeBool(element.isStatic);
+
+    _resolutionSink._writeAnnotationList(element.metadata);
+    _resolutionSink.writeType(element.returnType);
+    _writeList(element.parameters, _writeParameterElement);
   }
 
   void _writeReferences(List<Reference> references) {
@@ -320,16 +410,109 @@
     }
   }
 
-  void _writeStringList(List<String> values) {
-    _sink.writeUInt30(values.length);
-    for (var value in values) {
-      _writeStringReference(value);
+  void _writeTopLevelVariableElement(TopLevelVariableElement element) {
+    element as TopLevelVariableElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+    _sink._writeStringReference(element.name);
+    _sink.writeBool(element.isConst);
+    _sink.writeBool(element.hasImplicitType);
+    _sink.writeBool(element.hasInitializer);
+    _sink.writeBool(element.isExternal);
+    _sink.writeBool(element.isFinal);
+    _sink.writeBool(element.isLate);
+    _sink._writeTopLevelInferenceError(element.typeInferenceError);
+    _resolutionSink._writeAnnotationList(element.metadata);
+    _resolutionSink.writeType(element.type);
+    _resolutionSink._writeOptionalNode(element.constantInitializer);
+  }
+
+  void _writeTypeAliasElement(TypeAliasElement element) {
+    element as TypeAliasElementImpl;
+    _sink.writeUInt30(_resolutionSink.offset);
+
+    _sink._writeStringReference(element.name);
+    // TODO(scheglov) pack flags
+    _sink.writeBool(element.isFunctionTypeAliasBased);
+    _sink.writeBool(element.hasSelfReference);
+    _sink.writeBool(element.isSimplyBounded);
+
+    _resolutionSink._writeAnnotationList(element.metadata);
+
+    _writeTypeParameters(element.typeParameters, () {
+      _resolutionSink._writeAliasedElement(element.aliasedElement);
+      _resolutionSink.writeType(element.aliasedType);
+    });
+  }
+
+  void _writeTypeParameterElement(TypeParameterElement typeParameter) {
+    typeParameter as TypeParameterElementImpl;
+    _sink._writeStringReference(typeParameter.name);
+    _sink.writeByte(_encodeVariance(typeParameter).index);
+    _resolutionSink._writeAnnotationList(typeParameter.metadata);
+    _resolutionSink.writeType(typeParameter.bound);
+    _resolutionSink.writeType(typeParameter.defaultType);
+  }
+
+  /// Add [typeParameters] to the indexing scope, so make them available
+  /// when writing types that might reference them, and write the elements.
+  void _writeTypeParameters(
+    List<TypeParameterElement> typeParameters,
+    void Function() f,
+  ) {
+    _resolutionSink.localElements.pushScope();
+    _resolutionSink.localElements.declareAll(typeParameters);
+    try {
+      _sink.writeList(typeParameters, _writeTypeParameterElement);
+      f();
+    } finally {
+      _resolutionSink.localElements.popScope();
     }
   }
 
-  void _writeStringReference(String string) {
-    var index = _stringIndexer[string];
-    _sink.writeUInt30(index);
+  void _writeUnitElement(CompilationUnitElement unitElement) {
+    _sink.writeUInt30(_resolutionSink.offset);
+
+    _sink._writeStringReference('${unitElement.source.uri}');
+    _sink._writeOptionalStringReference(unitElement.uri);
+    _sink.writeBool(unitElement.isSynthetic);
+    _resolutionSink._writeAnnotationList(unitElement.metadata);
+    _writeList(unitElement.types, _writeClassElement);
+    _writeList(unitElement.enums, _writeEnumElement);
+    _writeList(unitElement.extensions, _writeExtensionElement);
+    _writeList(unitElement.functions, _writeFunctionElement);
+    _writeList(unitElement.mixins, _writeMixinElement);
+    _writeList(unitElement.typeAliases, _writeTypeAliasElement);
+
+    _writeList(
+      unitElement.topLevelVariables
+          .where((element) => !element.isSynthetic)
+          .toList(),
+      _writeTopLevelVariableElement,
+    );
+    _writeList(
+      unitElement.accessors.where((e) => !e.isSynthetic).toList(),
+      _writePropertyAccessorElement,
+    );
+  }
+
+  static TypeParameterVarianceTag _encodeVariance(
+      TypeParameterElementImpl element) {
+    if (element.isLegacyCovariant) {
+      return TypeParameterVarianceTag.legacy;
+    }
+
+    var variance = element.variance;
+    if (variance == Variance.unrelated) {
+      return TypeParameterVarianceTag.unrelated;
+    } else if (variance == Variance.covariant) {
+      return TypeParameterVarianceTag.covariant;
+    } else if (variance == Variance.contravariant) {
+      return TypeParameterVarianceTag.contravariant;
+    } else if (variance == Variance.invariant) {
+      return TypeParameterVarianceTag.invariant;
+    } else {
+      throw UnimplementedError('$variance');
+    }
   }
 }
 
@@ -343,46 +526,19 @@
   });
 }
 
-class LibraryToWriteAst {
-  final List<UnitToWriteAst> units;
-
-  LibraryToWriteAst({
-    required this.units,
-  });
-}
-
-class LibraryToWriteResolution {
-  final String uriStr;
-  final List<Reference> exports;
-  final List<UnitToWriteResolution> units;
-
-  LibraryToWriteResolution({
-    required this.uriStr,
-    required this.exports,
-    required this.units,
-  });
-}
-
-class ResolutionSink {
-  final StringIndexer _stringIndexer;
-  final BufferedSink _sink;
-  final _BundleWriterReferences _references2;
+class ResolutionSink extends _SummaryDataWriter {
+  final _BundleWriterReferences _references;
   final _LocalElementIndexer localElements = _LocalElementIndexer();
 
   ResolutionSink({
+    required ByteSink sink,
     required StringIndexer stringIndexer,
-    required BufferedSink sink,
     required _BundleWriterReferences references,
-  })  : _stringIndexer = stringIndexer,
-        _sink = sink,
-        _references2 = references;
-
-  int get offset => _sink.offset;
-
-  void writeByte(int byte) {
-    assert((byte & 0xFF) == byte);
-    _sink.addByte(byte);
-  }
+  })  : _references = references,
+        super(
+          sink: sink,
+          stringIndexer: stringIndexer,
+        );
 
   /// TODO(scheglov) Triage places where we write elements.
   /// Some of then cannot be members, e.g. type names.
@@ -402,24 +558,30 @@
             : Tag.MemberWithTypeArguments,
       );
 
-      writeElement0(declaration);
+      _writeElement(declaration);
       _writeTypeList(typeArguments);
     } else {
       writeByte(Tag.RawElement);
-      writeElement0(element);
+      _writeElement(element);
     }
   }
 
-  void writeElement0(Element? element) {
-    assert(element is! Member, 'Use writeMemberOrElement()');
-    var elementIndex = _indexOfElement(element);
-    _sink.writeUInt30(elementIndex);
+  void writeInterfaceType(InterfaceType type) {
+    _writeElement(type.element);
+    var typeArguments = type.typeArguments;
+    writeUInt30(typeArguments.length);
+    for (var i = 0; i < typeArguments.length; ++i) {
+      writeType(typeArguments[i]);
+    }
+    _writeNullabilitySuffix(type.nullabilitySuffix);
   }
 
-  void writeStringList(List<String> values) {
-    _sink.writeUInt30(values.length);
-    for (var value in values) {
-      _writeStringReference(value);
+  void writeOptionalInterfaceType(InterfaceType? type) {
+    if (type != null) {
+      writeByte(1);
+      writeInterfaceType(type);
+    } else {
+      writeByte(0);
     }
   }
 
@@ -449,7 +611,7 @@
         writeByte(Tag.InterfaceType);
         // TODO(scheglov) Write raw
         writeElement(type.element);
-        _sink.writeUInt30(typeArguments.length);
+        writeUInt30(typeArguments.length);
         for (var i = 0; i < typeArguments.length; ++i) {
           writeType(typeArguments[i]);
         }
@@ -473,10 +635,6 @@
     }
   }
 
-  void writeUInt30(int value) {
-    _sink.writeUInt30(value);
-  }
-
   int _indexOfElement(Element? element) {
     if (element == null) return 0;
     if (element is MultiplyDefinedElement) return 0;
@@ -495,24 +653,60 @@
     }
 
     if (identical(element, DynamicElementImpl.instance)) {
-      return _references2._indexOfReference(_references2.dynamicReference) << 1;
+      return _references._indexOfReference(_references.dynamicReference) << 1;
     }
 
     var reference = (element as ElementImpl).reference;
-    return _references2._indexOfReference(reference) << 1;
+    return _references._indexOfReference(reference) << 1;
   }
 
-  void _writeFormalParameterKind(ParameterElement p) {
-    if (p.isRequiredPositional) {
-      writeByte(Tag.ParameterKindRequiredPositional);
-    } else if (p.isOptionalPositional) {
-      writeByte(Tag.ParameterKindOptionalPositional);
-    } else if (p.isRequiredNamed) {
-      writeByte(Tag.ParameterKindRequiredNamed);
-    } else if (p.isOptionalNamed) {
-      writeByte(Tag.ParameterKindOptionalNamed);
+  void _writeAliasedElement(Element? element) {
+    if (element == null) {
+      writeByte(AliasedElementTag.nothing);
+    } else if (element is GenericFunctionTypeElement) {
+      writeByte(AliasedElementTag.genericFunctionElement);
+      _writeTypeParameters(element.typeParameters, () {
+        _writeFormalParameters(element.parameters, withAnnotations: true);
+        writeType(element.returnType);
+      });
     } else {
-      throw StateError('Unexpected parameter kind: $p');
+      throw UnimplementedError('${element.runtimeType}');
+    }
+  }
+
+  void _writeAnnotationList(List<ElementAnnotation> annotations) {
+    writeUInt30(annotations.length);
+    for (var annotation in annotations) {
+      annotation as ElementAnnotationImpl;
+      _writeNode(annotation.annotationAst);
+    }
+  }
+
+  void _writeElement(Element? element) {
+    assert(element is! Member, 'Use writeMemberOrElement()');
+    var elementIndex = _indexOfElement(element);
+    writeUInt30(elementIndex);
+  }
+
+  void _writeFormalParameters(
+    List<ParameterElement> parameters, {
+    required bool withAnnotations,
+  }) {
+    writeUInt30(parameters.length);
+    for (var parameter in parameters) {
+      _writeFormalParameterKind(parameter);
+      writeBool(parameter.isInitializingFormal);
+      _writeTypeParameters(parameter.typeParameters, () {
+        writeType(parameter.type);
+        _writeStringReference(parameter.name);
+        _writeFormalParameters(
+          parameter.parameters,
+          withAnnotations: withAnnotations,
+        );
+      });
+      if (withAnnotations) {
+        _writeAnnotationList(parameter.metadata);
+      }
     }
   }
 
@@ -521,61 +715,83 @@
 
     writeByte(Tag.FunctionType);
 
-    localElements.pushScope();
-
-    var typeParameters = type.typeFormals;
-    for (var typeParameter in type.typeFormals) {
-      localElements.declare(typeParameter);
-    }
-
-    _sink.writeUInt30(typeParameters.length);
-    for (var typeParameter in type.typeFormals) {
-      _writeStringReference(typeParameter.name);
-    }
-    for (var typeParameter in type.typeFormals) {
-      writeType(typeParameter.bound);
-    }
-
-    writeType(type.returnType);
-
-    var parameters = type.parameters;
-    _sink.writeUInt30(parameters.length);
-    for (var parameter in parameters) {
-      _writeFormalParameterKind(parameter);
-      writeType(parameter.type);
-      // TODO(scheglov) Don't write names of positional parameters
-      _writeStringReference(parameter.name);
-    }
-
+    _writeTypeParameters(type.typeFormals, () {
+      writeType(type.returnType);
+      _writeFormalParameters(type.parameters, withAnnotations: false);
+    });
     _writeNullabilitySuffix(type.nullabilitySuffix);
+  }
 
-    localElements.popScope();
+  void _writeInterfaceTypeList(List<InterfaceType> types) {
+    writeUInt30(types.length);
+    for (var type in types) {
+      writeInterfaceType(type);
+    }
+  }
+
+  void _writeNode(AstNode node) {
+    var astWriter = AstBinaryWriter(
+      sink: this,
+      stringIndexer: _stringIndexer,
+    );
+    node.accept(astWriter);
+  }
+
+  void _writeNodeList(List<AstNode> nodes) {
+    writeUInt30(nodes.length);
+    for (var node in nodes) {
+      _writeNode(node);
+    }
   }
 
   void _writeNullabilitySuffix(NullabilitySuffix suffix) {
     writeByte(suffix.index);
   }
 
-  void _writeStringReference(String string) {
-    var index = _stringIndexer[string];
-    _sink.writeUInt30(index);
+  void _writeOptionalNode(Expression? node) {
+    if (node != null) {
+      writeBool(true);
+      _writeNode(node);
+    } else {
+      writeBool(false);
+    }
   }
 
   void _writeTypeAliasElementArguments(DartType type) {
     var aliasElement = type.aliasElement;
-    writeElement0(aliasElement);
+    _writeElement(aliasElement);
     if (aliasElement != null) {
       _writeTypeList(type.aliasArguments!);
     }
   }
 
   void _writeTypeList(List<DartType> types) {
-    _sink.writeUInt30(types.length);
+    writeUInt30(types.length);
     for (var type in types) {
       writeType(type);
     }
   }
 
+  void _writeTypeParameters(
+    List<TypeParameterElement> typeParameters,
+    void Function() f,
+  ) {
+    localElements.pushScope();
+    localElements.declareAll(typeParameters);
+    try {
+      writeUInt30(typeParameters.length);
+      for (var typeParameter in typeParameters) {
+        _writeStringReference(typeParameter.name);
+      }
+      for (var typeParameter in typeParameters) {
+        writeType(typeParameter.bound);
+      }
+      f();
+    } finally {
+      localElements.popScope();
+    }
+  }
+
   static List<DartType> _enclosingClassTypeArguments(
     Element declaration,
     Map<TypeParameterElement, DartType> substitution,
@@ -620,32 +836,6 @@
   }
 }
 
-class ResolutionUnit {
-  final _ResolutionLibrary library;
-  final UnitToWriteResolution unit;
-
-  /// The offset of the resolution data for directives.
-  final int directivesOffset;
-
-  /// The offsets of resolution data for each declaration - class, method, etc.
-  final List<int> offsets = [];
-
-  ResolutionUnit({
-    required this.library,
-    required this.unit,
-    required this.directivesOffset,
-  });
-
-  /// Should be called on enter into a new declaration on which level
-  /// resolution is stored, e.g. [ClassDeclaration] (header), or
-  /// [MethodDeclaration] (header), or [FieldDeclaration] (all).
-  int enterDeclaration() {
-    var index = offsets.length;
-    offsets.add(library.sink.offset);
-    return index;
-  }
-}
-
 class StringIndexer {
   final Map<String, int> _index = {};
 
@@ -728,20 +918,6 @@
   });
 }
 
-class UnitToWriteResolution {
-  final String uriStr;
-  final String? partUriStr;
-  final CompilationUnit node;
-  final bool isSynthetic;
-
-  UnitToWriteResolution({
-    required this.uriStr,
-    required this.partUriStr,
-    required this.node,
-    required this.isSynthetic,
-  });
-}
-
 class _BundleWriterReferences {
   /// The `dynamic` class is declared in `dart:core`, but is not a class.
   /// Also, it is static, so we cannot set `reference` for it.
@@ -786,6 +962,18 @@
   }
 }
 
+class _Library {
+  final String uriStr;
+  final int offset;
+  final List<int> classMembersOffsets;
+
+  _Library({
+    required this.uriStr,
+    required this.offset,
+    required this.classMembersOffsets,
+  });
+}
+
 class _LocalElementIndexer {
   final Map<Element, int> _index = Map.identity();
   final List<int> _scopes = [];
@@ -800,6 +988,12 @@
     _index[element] = _stackHeight++;
   }
 
+  void declareAll(List<Element> elements) {
+    for (var element in elements) {
+      declare(element);
+    }
+  }
+
   void popScope() {
     _stackHeight = _scopes.removeLast();
   }
@@ -809,23 +1003,56 @@
   }
 }
 
-class _ResolutionLibrary {
-  final ResolutionSink sink;
-  final LibraryToWriteResolution library;
-  final List<ResolutionUnit> units = [];
+class _SummaryDataWriter extends BufferedSink {
+  final StringIndexer _stringIndexer;
 
-  _ResolutionLibrary({
-    required this.sink,
-    required this.library,
-  });
+  _SummaryDataWriter({
+    required ByteSink sink,
+    required StringIndexer stringIndexer,
+  })  : _stringIndexer = stringIndexer,
+        super(sink);
 
-  ResolutionUnit enterUnit(UnitToWriteResolution unitToWrite) {
-    var unit = ResolutionUnit(
-      library: this,
-      unit: unitToWrite,
-      directivesOffset: sink.offset,
-    );
-    units.add(unit);
-    return unit;
+  void _writeFormalParameterKind(ParameterElement p) {
+    if (p.isRequiredPositional) {
+      writeByte(Tag.ParameterKindRequiredPositional);
+    } else if (p.isOptionalPositional) {
+      writeByte(Tag.ParameterKindOptionalPositional);
+    } else if (p.isRequiredNamed) {
+      writeByte(Tag.ParameterKindRequiredNamed);
+    } else if (p.isOptionalNamed) {
+      writeByte(Tag.ParameterKindOptionalNamed);
+    } else {
+      throw StateError('Unexpected parameter kind: $p');
+    }
+  }
+
+  void _writeOptionalStringReference(String? value) {
+    if (value != null) {
+      writeBool(true);
+      _writeStringReference(value);
+    } else {
+      writeBool(false);
+    }
+  }
+
+  void _writeStringList(List<String> values) {
+    writeUInt30(values.length);
+    for (var value in values) {
+      _writeStringReference(value);
+    }
+  }
+
+  void _writeStringReference(String string) {
+    var index = _stringIndexer[string];
+    writeUInt30(index);
+  }
+
+  void _writeTopLevelInferenceError(TopLevelInferenceError? error) {
+    if (error != null) {
+      writeByte(error.kind.index);
+      _writeStringList(error.arguments);
+    } else {
+      writeByte(TopLevelInferenceErrorKind.none.index);
+    }
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
index be1e522..787029e 100644
--- a/pkg/analyzer/lib/src/summary2/data_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -21,6 +21,20 @@
     _stringTable = _StringTable(bytes: bytes, startOffset: offset);
   }
 
+  /// Create a new instance with the given [offset].
+  /// It shares the same bytes and string reader.
+  SummaryDataReader fork(int offset) {
+    var result = SummaryDataReader(bytes);
+    result.offset = offset;
+    result._stringTable = _stringTable;
+    return result;
+  }
+
+  @pragma("vm:prefer-inline")
+  bool readBool() {
+    return readByte() != 0;
+  }
+
   @pragma("vm:prefer-inline")
   int readByte() {
     return bytes[offset++];
@@ -40,15 +54,38 @@
     return _doubleBuffer[0];
   }
 
+  String? readOptionalStringReference() {
+    if (readBool()) {
+      return readStringReference();
+    }
+  }
+
+  int? readOptionalUInt30() {
+    if (readBool()) {
+      return readUInt30();
+    }
+  }
+
   String readStringReference() {
     return _stringTable[readUInt30()];
   }
 
+  List<String> readStringReferenceList() {
+    return readTypedList(readStringReference);
+  }
+
   String readStringUtf8() {
     var bytes = readUint8List();
     return utf8.decode(bytes);
   }
 
+  List<T> readTypedList<T>(T Function() read) {
+    var length = readUInt30();
+    return List<T>.generate(length, (_) {
+      return read();
+    });
+  }
+
   int readUInt30() {
     var byte = readByte();
     if (byte & 0x80 == 0) {
@@ -66,7 +103,7 @@
     }
   }
 
-  Uint32List readUint30List() {
+  Uint32List readUInt30List() {
     var length = readUInt30();
     var result = Uint32List(length);
     for (var i = 0; i < length; ++i) {
@@ -75,18 +112,18 @@
     return result;
   }
 
-  int readUint32() {
+  int readUInt32() {
     return (readByte() << 24) |
         (readByte() << 16) |
         (readByte() << 8) |
         readByte();
   }
 
-  Uint32List readUint32List() {
-    var length = readUint32();
+  Uint32List readUInt32List() {
+    var length = readUInt32();
     var result = Uint32List(length);
     for (var i = 0; i < length; ++i) {
-      result[i] = readUint32();
+      result[i] = readUInt32();
     }
     return result;
   }
@@ -119,15 +156,15 @@
   _StringTable({
     required Uint8List bytes,
     required int startOffset,
-  })   : _bytes = bytes,
+  })  : _bytes = bytes,
         _byteOffset = startOffset {
-    var offset = startOffset - _readUInt();
-    var length = _readUInt();
+    var offset = startOffset - _readUInt30();
+    var length = _readUInt30();
 
     _offsets = Uint32List(length);
     _lengths = Uint32List(length);
     for (var i = 0; i < length; i++) {
-      var stringLength = _readUInt();
+      var stringLength = _readUInt30();
       _offsets[i] = offset;
       _lengths[i] = stringLength;
       offset += stringLength;
@@ -161,7 +198,7 @@
     return String.fromCharCodes(_bytes, start, end);
   }
 
-  int _readUInt() {
+  int _readUInt30() {
     var byte = _readByte();
     if (byte & 0x80 == 0) {
       // 0xxxxxxx
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart
index 2f4fd40..18fdf73 100644
--- a/pkg/analyzer/lib/src/summary2/data_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -11,7 +11,7 @@
   static const int SAFE_SIZE = SIZE - 5;
   static const int SMALL = 10000;
 
-  final Sink<List<int>> _sink;
+  final ByteSink _sink;
 
   int flushedLength = 0;
 
@@ -105,8 +105,14 @@
     length = 0;
   }
 
-  void flushAndDestroy() {
+  Uint8List flushAndTake() {
     _sink.add(_buffer.sublist(0, length));
+    return _sink.builder.takeBytes();
+  }
+
+  @pragma("vm:prefer-inline")
+  void writeBool(bool value) {
+    writeByte(value ? 1 : 0);
   }
 
   @pragma("vm:prefer-inline")
@@ -122,6 +128,24 @@
     }
   }
 
+  /// Write [items] filtering them by [T].
+  void writeList2<T>(List<Object> items, void Function(T x) writeItem) {
+    var typedItems = items.whereType<T>().toList();
+    writeUInt30(typedItems.length);
+    for (var i = 0; i < typedItems.length; i++) {
+      writeItem(typedItems[i]);
+    }
+  }
+
+  void writeOptionalUInt30(int? value) {
+    if (value != null) {
+      writeBool(true);
+      writeUInt30(value);
+    } else {
+      writeBool(false);
+    }
+  }
+
   /// Write the [value] as UTF8 encoded byte array.
   void writeStringUtf8(String value) {
     var bytes = utf8.encode(value);
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 8657fc7..4fc32d1 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -241,21 +241,23 @@
           void recurseParameters(List<TypeParameterElement> parameters) {
             for (var parameter in parameters) {
               var parameterImpl = parameter as TypeParameterElementImpl;
-              var parameterNode = parameterImpl.linkedNode as TypeParameter;
+              var parameterNode = parameterImpl.linkedNode;
               // TODO(scheglov) How to we skip already linked?
-              var bound = parameterNode.bound;
-              if (bound != null) {
-                var tails = _findRawTypePathsToDeclaration(
-                  parameterNode,
-                  bound.typeOrThrow,
-                  end,
-                  visited,
-                );
-                for (var tail in tails) {
-                  paths.add(<_CycleElement>[
-                    _CycleElement(startParameter, startType),
-                    ...tail,
-                  ]);
+              if (parameterNode is TypeParameter) {
+                var bound = parameterNode.bound;
+                if (bound != null) {
+                  var tails = _findRawTypePathsToDeclaration(
+                    parameterNode,
+                    bound.typeOrThrow,
+                    end,
+                    visited,
+                  );
+                  for (var tail in tails) {
+                    paths.add(<_CycleElement>[
+                      _CycleElement(startParameter, startType),
+                      ...tail,
+                    ]);
+                  }
                 }
               }
             }
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -0,0 +1,1277 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/util/comment.dart';
+import 'package:collection/collection.dart';
+
+Uint8List writeUnitInformative(CompilationUnit unit) {
+  var byteSink = ByteSink();
+  var sink = BufferedSink(byteSink);
+  _InformativeDataWriter(sink).write(unit);
+  return sink.flushAndTake();
+}
+
+class InformativeDataApplier {
+  final LinkedElementFactory _elementFactory;
+  final Map<Uri, Uint8List> _unitsInformativeBytes2;
+
+  InformativeDataApplier(
+    this._elementFactory,
+    this._unitsInformativeBytes2,
+  );
+
+  void applyTo(LibraryElementImpl libraryElement) {
+    if (_elementFactory.isApplyingInformativeData) {
+      throw StateError('Unexpected recursion.');
+    }
+    _elementFactory.isApplyingInformativeData = true;
+
+    var unitElements = libraryElement.units;
+    for (var i = 0; i < unitElements.length; i++) {
+      var unitElement = unitElements[i] as CompilationUnitElementImpl;
+      var unitUri = unitElement.source.uri;
+      var unitInfoBytes = _unitsInformativeBytes2[unitUri];
+      if (unitInfoBytes != null) {
+        var unitReader = SummaryDataReader(unitInfoBytes);
+        var unitInfo = _InfoUnit(unitReader);
+
+        if (i == 0) {
+          _applyToLibrary(libraryElement, unitInfo);
+        }
+
+        unitElement.setCodeRange(unitInfo.codeOffset, unitInfo.codeLength);
+        unitElement.lineInfo = LineInfo(unitInfo.lineStarts);
+
+        _applyToAccessors(unitElement.accessors, unitInfo.accessors);
+
+        _forEach2(
+          unitElement.types
+              .where((element) => !element.isMixinApplication)
+              .toList(),
+          unitInfo.classDeclarations,
+          _applyToClassDeclaration,
+        );
+
+        _forEach2(
+          unitElement.types
+              .where((element) => element.isMixinApplication)
+              .toList(),
+          unitInfo.classTypeAliases,
+          _applyToClassTypeAlias,
+        );
+
+        _forEach2(unitElement.enums, unitInfo.enums, _applyToEnumDeclaration);
+
+        _forEach2(unitElement.extensions, unitInfo.extensions,
+            _applyToExtensionDeclaration);
+
+        _forEach2(unitElement.functions, unitInfo.functions,
+            _applyToFunctionDeclaration);
+
+        _forEach2(unitElement.mixins, unitInfo.mixinDeclarations,
+            _applyToMixinDeclaration);
+
+        _forEach2(unitElement.topLevelVariables, unitInfo.topLevelVariable,
+            _applyToTopLevelVariable);
+
+        _forEach2(
+          unitElement.typeAliases
+              .cast<TypeAliasElementImpl>()
+              .where((e) => e.isFunctionTypeAliasBased)
+              .toList(),
+          unitInfo.functionTypeAliases,
+          _applyToFunctionTypeAlias,
+        );
+
+        _forEach2(
+          unitElement.typeAliases
+              .cast<TypeAliasElementImpl>()
+              .where((e) => !e.isFunctionTypeAliasBased)
+              .toList(),
+          unitInfo.genericTypeAliases,
+          _applyToGenericTypeAlias,
+        );
+      }
+    }
+
+    _elementFactory.isApplyingInformativeData = false;
+  }
+
+  void _applyToAccessors(
+    List<PropertyAccessorElement> elementList,
+    List<_InfoMethodDeclaration> infoList,
+  ) {
+    _forEach2<PropertyAccessorElement, _InfoMethodDeclaration>(
+      elementList.notSynthetic,
+      infoList,
+      (element, info) {
+        element as PropertyAccessorElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.nameOffset = info.nameOffset;
+        element.documentationComment = info.documentationComment;
+        _applyToFormalParameters(
+          element.parameters_unresolved,
+          info.parameters,
+        );
+      },
+    );
+  }
+
+  void _applyToClassDeclaration(
+    ClassElement element,
+    _InfoClassDeclaration info,
+  ) {
+    element as ClassElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+
+    var linkedData = element.linkedData as ClassElementLinkedData;
+    linkedData.applyInformativeDataToMembers = () {
+      _applyToConstructors(element.constructors, info.constructors);
+      _applyToFields(element.fields, info.fields);
+      _applyToAccessors(element.accessors, info.accessors);
+      _applyToMethods(element.methods, info.methods);
+    };
+  }
+
+  void _applyToClassTypeAlias(
+    ClassElement element,
+    _InfoClassTypeAlias info,
+  ) {
+    element as ClassElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+  }
+
+  void _applyToCombinators(
+    List<NamespaceCombinator> elementList,
+    List<_InfoCombinator> infoList,
+  ) {
+    _forEach2<NamespaceCombinator, _InfoCombinator>(
+      elementList,
+      infoList,
+      (element, info) {
+        if (element is ShowElementCombinatorImpl) {
+          element.offset = info.offset;
+          element.end = info.end;
+        }
+      },
+    );
+  }
+
+  void _applyToConstructors(
+    List<ConstructorElement> elementList,
+    List<_InfoConstructorDeclaration> infoList,
+  ) {
+    _forEach2<ConstructorElement, _InfoConstructorDeclaration>(
+      elementList,
+      infoList,
+      (element, info) {
+        element as ConstructorElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.periodOffset = info.periodOffset;
+        element.nameOffset = info.nameOffset;
+        element.nameEnd = info.nameEnd;
+        element.documentationComment = info.documentationComment;
+        _applyToFormalParameters(
+          element.parameters_unresolved,
+          info.parameters,
+        );
+      },
+    );
+  }
+
+  void _applyToEnumDeclaration(
+    ClassElement element,
+    _InfoEnumDeclaration info,
+  ) {
+    element as EnumElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+
+    _forEach2<FieldElement, _InfoEnumConstantDeclaration>(
+      element.constants_unresolved,
+      info.constants,
+      (element, info) {
+        element as FieldElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.nameOffset = info.nameOffset;
+        element.documentationComment = info.documentationComment;
+      },
+    );
+  }
+
+  void _applyToExtensionDeclaration(
+    ExtensionElement element,
+    _InfoClassDeclaration info,
+  ) {
+    element as ExtensionElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+    _applyToFields(element.fields, info.fields);
+    _applyToAccessors(element.accessors, info.accessors);
+    _applyToMethods(element.methods, info.methods);
+  }
+
+  void _applyToFields(
+    List<FieldElement> elementList,
+    List<_InfoFieldDeclaration> infoList,
+  ) {
+    _forEach2<FieldElement, _InfoFieldDeclaration>(
+      elementList.notSynthetic,
+      infoList,
+      (element, info) {
+        element as FieldElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.nameOffset = info.nameOffset;
+        (element.getter as PropertyAccessorElementImpl?)?.nameOffset =
+            info.nameOffset;
+        (element.setter as PropertyAccessorElementImpl?)?.nameOffset =
+            info.nameOffset;
+        element.documentationComment = info.documentationComment;
+      },
+    );
+  }
+
+  void _applyToFormalParameters(
+    List<ParameterElement> parameters,
+    List<_InfoFormalParameter> infoList,
+  ) {
+    _forEach2<ParameterElement, _InfoFormalParameter>(
+      parameters,
+      infoList,
+      (element, info) {
+        element as ParameterElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.nameOffset = info.nameOffset;
+        _applyToTypeParameters(element.typeParameters, info.typeParameters);
+        _applyToFormalParameters(element.parameters, info.parameters);
+      },
+    );
+  }
+
+  void _applyToFunctionDeclaration(
+    FunctionElement element,
+    _InfoFunctionDeclaration info,
+  ) {
+    element as FunctionElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+    _applyToFormalParameters(
+      element.parameters_unresolved,
+      info.parameters,
+    );
+  }
+
+  void _applyToFunctionTypeAlias(
+    TypeAliasElement element,
+    _InfoFunctionTypeAlias info,
+  ) {
+    element as TypeAliasElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+  }
+
+  void _applyToGenericTypeAlias(
+    TypeAliasElement element,
+    _InfoGenericTypeAlias info,
+  ) {
+    element as TypeAliasElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+  }
+
+  void _applyToLibrary(LibraryElementImpl element, _InfoUnit info) {
+    element.nameOffset = info.libraryName.offset;
+    element.nameLength = info.libraryName.length;
+
+    if (info.docComment.isNotEmpty) {
+      element.documentationComment = info.docComment;
+    }
+
+    _forEach2<ImportElement, _InfoImport>(
+      element.imports_unresolved,
+      info.imports,
+      (element, info) {
+        element as ImportElementImpl;
+        element.nameOffset = info.nameOffset;
+        element.prefixOffset = info.prefixOffset;
+
+        var prefix = element.prefix;
+        if (prefix is PrefixElementImpl) {
+          prefix.nameOffset = info.prefixOffset;
+        }
+
+        _applyToCombinators(element.combinators, info.combinators);
+      },
+    );
+
+    _forEach2<ExportElement, _InfoExport>(
+      element.exports_unresolved,
+      info.exports,
+      (element, info) {
+        element as ExportElementImpl;
+        element.nameOffset = info.nameOffset;
+        _applyToCombinators(element.combinators, info.combinators);
+      },
+    );
+  }
+
+  void _applyToMethods(
+    List<MethodElement> elementList,
+    List<_InfoMethodDeclaration> infoList,
+  ) {
+    _forEach2<MethodElement, _InfoMethodDeclaration>(
+      elementList,
+      infoList,
+      (element, info) {
+        element as MethodElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.nameOffset = info.nameOffset;
+        element.documentationComment = info.documentationComment;
+        _applyToTypeParameters(
+          element.typeParameters_unresolved,
+          info.typeParameters,
+        );
+        _applyToFormalParameters(
+          element.parameters_unresolved,
+          info.parameters,
+        );
+      },
+    );
+  }
+
+  void _applyToMixinDeclaration(
+    ClassElement element,
+    _InfoClassDeclaration info,
+  ) {
+    element as MixinElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    element.documentationComment = info.documentationComment;
+    _applyToTypeParameters(
+      element.typeParameters_unresolved,
+      info.typeParameters,
+    );
+    _applyToConstructors(element.constructors, info.constructors);
+    _applyToFields(element.fields, info.fields);
+    _applyToAccessors(element.accessors, info.accessors);
+    _applyToMethods(element.methods, info.methods);
+  }
+
+  void _applyToTopLevelVariable(
+    TopLevelVariableElement element,
+    _InfoTopLevelVariable info,
+  ) {
+    element as TopLevelVariableElementImpl;
+    element.setCodeRange(info.codeOffset, info.codeLength);
+    element.nameOffset = info.nameOffset;
+    (element.getter as PropertyAccessorElementImpl?)?.nameOffset =
+        info.nameOffset;
+    (element.setter as PropertyAccessorElementImpl?)?.nameOffset =
+        info.nameOffset;
+    element.documentationComment = info.documentationComment;
+  }
+
+  void _applyToTypeParameters(
+    List<TypeParameterElement> elementList,
+    List<_InfoTypeParameter> infoList,
+  ) {
+    _forEach2<TypeParameterElement, _InfoTypeParameter>(
+      elementList,
+      infoList,
+      (element, info) {
+        element as TypeParameterElementImpl;
+        element.setCodeRange(info.codeOffset, info.codeLength);
+        element.nameOffset = info.nameOffset;
+      },
+    );
+  }
+
+  static void _forEach2<T1, T2>(
+    List<T1> list1,
+    List<T2> list2,
+    void Function(T1, T2) f,
+  ) {
+    var i1 = list1.iterator;
+    var i2 = list2.iterator;
+    while (i1.moveNext() && i2.moveNext()) {
+      f(i1.current, i2.current);
+    }
+  }
+}
+
+class _InfoClassDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoTypeParameter> typeParameters;
+  final List<_InfoConstructorDeclaration> constructors;
+  final List<_InfoFieldDeclaration> fields;
+  final List<_InfoMethodDeclaration> accessors;
+  final List<_InfoMethodDeclaration> methods;
+
+  factory _InfoClassDeclaration(SummaryDataReader reader,
+      {int nameOffsetDelta = 0}) {
+    return _InfoClassDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30() - nameOffsetDelta,
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+      constructors: reader.readTypedList(
+        () => _InfoConstructorDeclaration(reader),
+      ),
+      fields: reader.readTypedList(
+        () => _InfoFieldDeclaration(reader),
+      ),
+      accessors: reader.readTypedList(
+        () => _InfoMethodDeclaration(reader),
+      ),
+      methods: reader.readTypedList(
+        () => _InfoMethodDeclaration(reader),
+      ),
+    );
+  }
+
+  _InfoClassDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.typeParameters,
+    required this.constructors,
+    required this.fields,
+    required this.accessors,
+    required this.methods,
+  });
+}
+
+class _InfoClassTypeAlias {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoTypeParameter> typeParameters;
+
+  factory _InfoClassTypeAlias(SummaryDataReader reader) {
+    return _InfoClassTypeAlias._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+    );
+  }
+
+  _InfoClassTypeAlias._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.typeParameters,
+  });
+}
+
+class _InfoCombinator {
+  final int offset;
+  final int end;
+
+  factory _InfoCombinator(SummaryDataReader reader) {
+    return _InfoCombinator._(
+      offset: reader.readUInt30(),
+      end: reader.readUInt30(),
+    );
+  }
+
+  _InfoCombinator._({
+    required this.offset,
+    required this.end,
+  });
+}
+
+class _InfoConstructorDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int? periodOffset;
+  final int nameOffset;
+  final int nameEnd;
+  final String? documentationComment;
+  final List<_InfoFormalParameter> parameters;
+
+  factory _InfoConstructorDeclaration(SummaryDataReader reader) {
+    return _InfoConstructorDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      periodOffset: reader.readOptionalUInt30(),
+      nameOffset: reader.readUInt30(),
+      nameEnd: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      parameters: reader.readTypedList(
+        () => _InfoFormalParameter(reader),
+      ),
+    );
+  }
+
+  _InfoConstructorDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.periodOffset,
+    required this.nameOffset,
+    required this.nameEnd,
+    required this.documentationComment,
+    required this.parameters,
+  });
+}
+
+class _InfoEnumConstantDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+
+  factory _InfoEnumConstantDeclaration(SummaryDataReader reader) {
+    return _InfoEnumConstantDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+    );
+  }
+
+  _InfoEnumConstantDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+  });
+}
+
+class _InfoEnumDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoEnumConstantDeclaration> constants;
+
+  factory _InfoEnumDeclaration(SummaryDataReader reader) {
+    return _InfoEnumDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      constants: reader.readTypedList(
+        () => _InfoEnumConstantDeclaration(reader),
+      ),
+    );
+  }
+
+  _InfoEnumDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.constants,
+  });
+}
+
+class _InfoExport {
+  final int nameOffset;
+  final List<_InfoCombinator> combinators;
+
+  factory _InfoExport(SummaryDataReader reader) {
+    return _InfoExport._(
+      nameOffset: reader.readUInt30(),
+      combinators: reader.readTypedList(
+        () => _InfoCombinator(reader),
+      ),
+    );
+  }
+
+  _InfoExport._({
+    required this.nameOffset,
+    required this.combinators,
+  });
+}
+
+class _InfoFieldDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+
+  factory _InfoFieldDeclaration(SummaryDataReader reader) {
+    return _InfoFieldDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+    );
+  }
+
+  _InfoFieldDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+  });
+}
+
+class _InfoFormalParameter {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final List<_InfoTypeParameter> typeParameters;
+  final List<_InfoFormalParameter> parameters;
+
+  factory _InfoFormalParameter(SummaryDataReader reader) {
+    return _InfoFormalParameter._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30() - 1,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+      parameters: reader.readTypedList(
+        () => _InfoFormalParameter(reader),
+      ),
+    );
+  }
+
+  _InfoFormalParameter._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.typeParameters,
+    required this.parameters,
+  });
+}
+
+class _InfoFunctionDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoTypeParameter> typeParameters;
+  final List<_InfoFormalParameter> parameters;
+
+  factory _InfoFunctionDeclaration(SummaryDataReader reader) {
+    return _InfoFunctionDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+      parameters: reader.readTypedList(
+        () => _InfoFormalParameter(reader),
+      ),
+    );
+  }
+
+  _InfoFunctionDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.typeParameters,
+    required this.parameters,
+  });
+}
+
+class _InfoFunctionTypeAlias {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoTypeParameter> typeParameters;
+  final List<_InfoFormalParameter> parameters;
+
+  factory _InfoFunctionTypeAlias(SummaryDataReader reader) {
+    return _InfoFunctionTypeAlias._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+      parameters: reader.readTypedList(
+        () => _InfoFormalParameter(reader),
+      ),
+    );
+  }
+
+  _InfoFunctionTypeAlias._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.typeParameters,
+    required this.parameters,
+  });
+}
+
+class _InfoGenericTypeAlias {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoTypeParameter> typeParameters;
+
+  factory _InfoGenericTypeAlias(SummaryDataReader reader) {
+    return _InfoGenericTypeAlias._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+    );
+  }
+
+  _InfoGenericTypeAlias._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.typeParameters,
+  });
+}
+
+class _InfoImport {
+  final int nameOffset;
+  final int prefixOffset;
+  final List<_InfoCombinator> combinators;
+
+  factory _InfoImport(SummaryDataReader reader) {
+    return _InfoImport._(
+      nameOffset: reader.readUInt30(),
+      prefixOffset: reader.readUInt30() - 1,
+      combinators: reader.readTypedList(
+        () => _InfoCombinator(reader),
+      ),
+    );
+  }
+
+  _InfoImport._({
+    required this.nameOffset,
+    required this.prefixOffset,
+    required this.combinators,
+  });
+}
+
+class _InfoLibraryName {
+  final int offset;
+  final int length;
+
+  factory _InfoLibraryName(SummaryDataReader reader) {
+    return _InfoLibraryName._(
+      offset: reader.readUInt30() - 1,
+      length: reader.readUInt30(),
+    );
+  }
+
+  _InfoLibraryName._({
+    required this.offset,
+    required this.length,
+  });
+}
+
+class _InfoMethodDeclaration {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+  final List<_InfoTypeParameter> typeParameters;
+  final List<_InfoFormalParameter> parameters;
+
+  factory _InfoMethodDeclaration(SummaryDataReader reader) {
+    return _InfoMethodDeclaration._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+      typeParameters: reader.readTypedList(
+        () => _InfoTypeParameter(reader),
+      ),
+      parameters: reader.readTypedList(
+        () => _InfoFormalParameter(reader),
+      ),
+    );
+  }
+
+  _InfoMethodDeclaration._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+    required this.typeParameters,
+    required this.parameters,
+  });
+}
+
+class _InformativeDataWriter {
+  final BufferedSink sink;
+
+  _InformativeDataWriter(this.sink);
+
+  void write(CompilationUnit unit) {
+    sink.writeUInt30(unit.offset);
+    sink.writeUInt30(unit.length);
+
+    sink.writeUint30List(unit.lineInfo?.lineStarts ?? [0]);
+
+    _writeLibraryName(unit);
+
+    var firstDirective = unit.directives.firstOrNull;
+    _writeDocumentationCommentNode(firstDirective?.documentationComment);
+
+    sink.writeList2<ImportDirective>(unit.directives, (directive) {
+      sink.writeUInt30(directive.keyword.offset);
+      sink.writeUInt30(1 + (directive.prefix?.offset ?? -1));
+      _writeCombinators(directive.combinators);
+    });
+
+    sink.writeList2<ExportDirective>(unit.directives, (directive) {
+      sink.writeUInt30(directive.keyword.offset);
+      _writeCombinators(directive.combinators);
+    });
+
+    sink.writeList2<ClassDeclaration>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.typeParameters);
+      _writeConstructors(node.members);
+      _writeFields(node.members);
+      _writeGettersSetters(node.members);
+      _writeMethods(node.members);
+    });
+
+    sink.writeList2<ClassTypeAlias>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.typeParameters);
+    });
+
+    sink.writeList2<EnumDeclaration>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      sink.writeList2<EnumConstantDeclaration>(node.constants, (node) {
+        sink.writeUInt30(node.offset);
+        sink.writeUInt30(node.length);
+        sink.writeUInt30(node.name.offset);
+        _writeDocumentationComment(node);
+      });
+    });
+
+    sink.writeList2<ExtensionDeclaration>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(1 + (node.name?.offset ?? -1));
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.typeParameters);
+      _writeConstructors(node.members);
+      _writeFields(node.members);
+      _writeGettersSetters(node.members);
+      _writeMethods(node.members);
+    });
+
+    sink.writeList2<FunctionDeclaration>(
+      unit.declarations
+          .whereType<FunctionDeclaration>()
+          .where((e) => e.isGetter || e.isSetter)
+          .toList(),
+      (node) {
+        sink.writeUInt30(node.offset);
+        sink.writeUInt30(node.length);
+        sink.writeUInt30(node.name.offset);
+        _writeDocumentationComment(node);
+        _writeTypeParameters(node.functionExpression.typeParameters);
+        _writeFormalParameters(node.functionExpression.parameters);
+      },
+    );
+
+    sink.writeList2<FunctionDeclaration>(
+        unit.declarations
+            .whereType<FunctionDeclaration>()
+            .where((e) => !(e.isGetter || e.isSetter))
+            .toList(), (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.functionExpression.typeParameters);
+      _writeFormalParameters(node.functionExpression.parameters);
+    });
+
+    sink.writeList2<FunctionTypeAlias>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.typeParameters);
+      _writeFormalParameters(node.parameters);
+    });
+
+    sink.writeList2<GenericTypeAlias>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.typeParameters);
+    });
+
+    sink.writeList2<MixinDeclaration>(unit.declarations, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+      _writeDocumentationComment(node);
+      _writeTypeParameters(node.typeParameters);
+      _writeConstructors(node.members);
+      _writeFields(node.members);
+      _writeGettersSetters(node.members);
+      _writeMethods(node.members);
+    });
+
+    sink.writeList<VariableDeclaration>(
+      unit.declarations
+          .whereType<TopLevelVariableDeclaration>()
+          .expand((declaration) => declaration.variables.variables)
+          .toList(),
+      (node) {
+        var codeOffset = _codeOffsetForVariable(node);
+        sink.writeUInt30(codeOffset);
+        sink.writeUInt30(node.end - codeOffset);
+        sink.writeUInt30(node.name.offset);
+        _writeDocumentationComment(node);
+      },
+    );
+  }
+
+  int _codeOffsetForVariable(VariableDeclaration node) {
+    var codeOffset = node.offset;
+    var variableList = node.parent as VariableDeclarationList;
+    if (variableList.variables[0] == node) {
+      codeOffset = variableList.parent!.offset;
+    }
+    return codeOffset;
+  }
+
+  void _writeCombinators(List<Combinator> combinators) {
+    sink.writeList<Combinator>(combinators, (combinator) {
+      sink.writeUInt30(combinator.offset);
+      sink.writeUInt30(combinator.end);
+    });
+  }
+
+  void _writeConstructors(List<ClassMember> members) {
+    sink.writeList2<ConstructorDeclaration>(members, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeOptionalUInt30(node.period?.offset);
+      var nameNode = node.name ?? node.returnType;
+      sink.writeUInt30(nameNode.offset);
+      sink.writeUInt30(nameNode.end);
+      _writeDocumentationComment(node);
+      _writeFormalParameters(node.parameters);
+    });
+  }
+
+  void _writeDocumentationComment(AnnotatedNode node) {
+    _writeDocumentationCommentNode(node.documentationComment);
+  }
+
+  void _writeDocumentationCommentNode(Comment? commentNode) {
+    var commentText = getCommentNodeRawText(commentNode);
+    sink.writeStringUtf8(commentText ?? '');
+  }
+
+  void _writeFields(List<ClassMember> members) {
+    sink.writeList<VariableDeclaration>(
+      members
+          .whereType<FieldDeclaration>()
+          .expand((declaration) => declaration.fields.variables)
+          .toList(),
+      (node) {
+        var codeOffset = _codeOffsetForVariable(node);
+        sink.writeUInt30(codeOffset);
+        sink.writeUInt30(node.end - codeOffset);
+        sink.writeUInt30(node.name.offset);
+        _writeDocumentationComment(node);
+      },
+    );
+  }
+
+  void _writeFormalParameters(FormalParameterList? parameterList) {
+    var parameters = parameterList?.parameters ?? <FormalParameter>[];
+    sink.writeList<FormalParameter>(parameters, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(1 + (node.identifier?.offset ?? -1));
+
+      var notDefault = node.notDefault;
+      if (notDefault is FunctionTypedFormalParameter) {
+        _writeTypeParameters(notDefault.typeParameters);
+        _writeFormalParameters(notDefault.parameters);
+      } else {
+        _writeTypeParameters(null);
+        _writeFormalParameters(null);
+      }
+    });
+  }
+
+  void _writeGettersSetters(List<ClassMember> members) {
+    sink.writeList<MethodDeclaration>(
+      members
+          .whereType<MethodDeclaration>()
+          .where((e) => e.isGetter || e.isSetter)
+          .toList(),
+      (node) {
+        sink.writeUInt30(node.offset);
+        sink.writeUInt30(node.length);
+        sink.writeUInt30(node.name.offset);
+        _writeDocumentationComment(node);
+        _writeTypeParameters(node.typeParameters);
+        _writeFormalParameters(node.parameters);
+      },
+    );
+  }
+
+  void _writeLibraryName(CompilationUnit unit) {
+    var nameOffset = -1;
+    var nameLength = 0;
+    for (var directive in unit.directives) {
+      if (directive is LibraryDirective) {
+        nameOffset = directive.name.offset;
+        nameLength = directive.name.length;
+        break;
+      }
+    }
+    sink.writeUInt30(1 + nameOffset);
+    sink.writeUInt30(nameLength);
+  }
+
+  void _writeMethods(List<ClassMember> members) {
+    sink.writeList<MethodDeclaration>(
+      members
+          .whereType<MethodDeclaration>()
+          .where((e) => !(e.isGetter || e.isSetter))
+          .toList(),
+      (node) {
+        sink.writeUInt30(node.offset);
+        sink.writeUInt30(node.length);
+        sink.writeUInt30(node.name.offset);
+        _writeDocumentationComment(node);
+        _writeTypeParameters(node.typeParameters);
+        _writeFormalParameters(node.parameters);
+      },
+    );
+  }
+
+  void _writeTypeParameters(TypeParameterList? parameterList) {
+    var parameters = parameterList?.typeParameters ?? <TypeParameter>[];
+    sink.writeList<TypeParameter>(parameters, (node) {
+      sink.writeUInt30(node.offset);
+      sink.writeUInt30(node.length);
+      sink.writeUInt30(node.name.offset);
+    });
+  }
+}
+
+class _InfoTopLevelVariable {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+  final String? documentationComment;
+
+  factory _InfoTopLevelVariable(SummaryDataReader reader) {
+    return _InfoTopLevelVariable._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+      documentationComment: reader.readStringUtf8().nullIfEmpty,
+    );
+  }
+
+  _InfoTopLevelVariable._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+    required this.documentationComment,
+  });
+}
+
+class _InfoTypeParameter {
+  final int codeOffset;
+  final int codeLength;
+  final int nameOffset;
+
+  factory _InfoTypeParameter(SummaryDataReader reader) {
+    return _InfoTypeParameter._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      nameOffset: reader.readUInt30(),
+    );
+  }
+
+  _InfoTypeParameter._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.nameOffset,
+  });
+}
+
+class _InfoUnit {
+  final int codeOffset;
+  final int codeLength;
+  final List<int> lineStarts;
+  final _InfoLibraryName libraryName;
+  final String docComment;
+  final List<_InfoImport> imports;
+  final List<_InfoExport> exports;
+  final List<_InfoClassDeclaration> classDeclarations;
+  final List<_InfoClassTypeAlias> classTypeAliases;
+  final List<_InfoEnumDeclaration> enums;
+  final List<_InfoClassDeclaration> extensions;
+  final List<_InfoMethodDeclaration> accessors;
+  final List<_InfoFunctionDeclaration> functions;
+  final List<_InfoFunctionTypeAlias> functionTypeAliases;
+  final List<_InfoGenericTypeAlias> genericTypeAliases;
+  final List<_InfoClassDeclaration> mixinDeclarations;
+  final List<_InfoTopLevelVariable> topLevelVariable;
+
+  factory _InfoUnit(SummaryDataReader reader) {
+    return _InfoUnit._(
+      codeOffset: reader.readUInt30(),
+      codeLength: reader.readUInt30(),
+      lineStarts: reader.readUInt30List(),
+      libraryName: _InfoLibraryName(reader),
+      docComment: reader.readStringUtf8(),
+      imports: reader.readTypedList(
+        () => _InfoImport(reader),
+      ),
+      exports: reader.readTypedList(
+        () => _InfoExport(reader),
+      ),
+      classDeclarations: reader.readTypedList(
+        () => _InfoClassDeclaration(reader),
+      ),
+      classTypeAliases: reader.readTypedList(
+        () => _InfoClassTypeAlias(reader),
+      ),
+      enums: reader.readTypedList(
+        () => _InfoEnumDeclaration(reader),
+      ),
+      extensions: reader.readTypedList(
+        () => _InfoClassDeclaration(reader, nameOffsetDelta: 1),
+      ),
+      accessors: reader.readTypedList(
+        () => _InfoMethodDeclaration(reader),
+      ),
+      functions: reader.readTypedList(
+        () => _InfoFunctionDeclaration(reader),
+      ),
+      functionTypeAliases: reader.readTypedList(
+        () => _InfoFunctionTypeAlias(reader),
+      ),
+      genericTypeAliases: reader.readTypedList(
+        () => _InfoGenericTypeAlias(reader),
+      ),
+      mixinDeclarations: reader.readTypedList(
+        () => _InfoClassDeclaration(reader),
+      ),
+      topLevelVariable: reader.readTypedList(
+        () => _InfoTopLevelVariable(reader),
+      ),
+    );
+  }
+
+  _InfoUnit._({
+    required this.codeOffset,
+    required this.codeLength,
+    required this.lineStarts,
+    required this.libraryName,
+    required this.docComment,
+    required this.imports,
+    required this.exports,
+    required this.classDeclarations,
+    required this.classTypeAliases,
+    required this.enums,
+    required this.extensions,
+    required this.accessors,
+    required this.functions,
+    required this.functionTypeAliases,
+    required this.genericTypeAliases,
+    required this.mixinDeclarations,
+    required this.topLevelVariable,
+  });
+}
+
+extension on String {
+  String? get nullIfEmpty {
+    return isNotEmpty ? this : null;
+  }
+}
+
+extension _ListOfElement<T extends Element> on List<T> {
+  List<T> get notSynthetic {
+    return where((e) => !e.isSynthetic).toList();
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 246a0f3..d874003 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -46,7 +46,7 @@
 
   void addExporters() {
     var unitContext = context.definingUnit;
-    for (var directive in unitContext.unit!.directives) {
+    for (var directive in unitContext.unit.directives) {
       if (directive is ast.ExportDirective) {
         Uri? uri;
         try {
@@ -101,7 +101,7 @@
       var setterRef = unitRef.getChild('@setter');
       var variableRef = unitRef.getChild('@variable');
       var nextUnnamedExtensionId = 0;
-      for (var node in linkingUnit.unit!.declarations) {
+      for (var node in linkingUnit.unit.declarations) {
         if (node is ast.ClassDeclaration) {
           var name = node.name.name;
           var reference = classRef.getChild(name);
@@ -178,10 +178,11 @@
           reference.node ??= node;
           localScope.declare(name, reference);
 
-          TypeAliasElementImpl.forLinkedNodeFactory(
+          var element = TypeAliasElementImpl.forLinkedNodeFactory(
               linkingUnit.reference.element as CompilationUnitElementImpl,
               reference,
               node);
+          element.isFunctionTypeAliasBased = true;
         } else if (node is ast.GenericTypeAlias) {
           var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
@@ -210,10 +211,18 @@
             var reference = variableRef.getChild(name);
             reference.node ??= node;
 
-            TopLevelVariableElementImpl.forLinkedNode(
-                linkingUnit.reference.element as CompilationUnitElementImpl,
-                reference,
-                variable);
+            if (variable.isConst) {
+              var element = ConstTopLevelVariableElementImpl.forLinkedNode(
+                  linkingUnit.reference.element as CompilationUnitElementImpl,
+                  reference,
+                  variable);
+              element.constantInitializer = variable.initializer;
+            } else {
+              TopLevelVariableElementImpl.forLinkedNode(
+                  linkingUnit.reference.element as CompilationUnitElementImpl,
+                  reference,
+                  variable);
+            }
 
             var getter = getterRef.getChild(name);
             localScope.declare(name, getter);
@@ -258,7 +267,7 @@
     // Store elements only for the defining unit of the library.
     var isDefiningUnit = true;
     for (var unitContext in context.units) {
-      for (var node in unitContext.unit!.directives) {
+      for (var node in unitContext.unit.directives) {
         if (node is ast.ExportDirectiveImpl) {
           var exportElement = ExportElementImpl.forLinkedNode(element, node);
           if (isDefiningUnit) {
@@ -268,8 +277,14 @@
           var importElement = ImportElementImpl.forLinkedNode(element, node);
           if (isDefiningUnit) {
             imports.add(importElement);
-            hasCoreImport |= importElement.importedLibrary?.isDartCore ?? false;
+            if (!hasCoreImport) {
+              if (node.uri.stringValue == 'dart:core') {
+                hasCoreImport = true;
+              }
+            }
           }
+        } else if (isDefiningUnit && node is ast.PartOfDirective) {
+          element.hasPartOfDirective = true;
         }
       }
       isDefiningUnit = false;
@@ -306,7 +321,7 @@
 
   void collectMixinSuperInvokedNames() {
     for (var unitContext in context.units) {
-      for (var declaration in unitContext.unit!.declarations) {
+      for (var declaration in unitContext.unit.declarations) {
         if (declaration is ast.MixinDeclaration) {
           var names = <String>{};
           var collector = MixinSuperInvokedNamesCollector(names);
@@ -347,16 +362,16 @@
         linker.elementFactory,
         element,
         unitReference,
-        unitContext.unit!.featureSet.isEnabled(Feature.non_nullable),
+        unitContext.unit.featureSet.isEnabled(Feature.non_nullable),
         scope,
       );
-      unitContext.unit!.accept(resolver);
+      unitContext.unit.accept(resolver);
     }
   }
 
   void resolveUriDirectives() {
     var unitContext = context.units[0];
-    for (var directive in unitContext.unit!.directives) {
+    for (var directive in unitContext.unit.directives) {
       if (directive is ast.NamespaceDirective) {
         try {
           var uri = _selectAbsoluteUri(directive);
@@ -435,7 +450,6 @@
           reference,
           inputUnit.isSynthetic,
           unit: inputUnit.unit,
-          unitReader: null,
         ),
       );
     }
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 67797c4..e47b901 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -23,12 +23,13 @@
 var timerLinkingLinkingBundle = Stopwatch();
 var timerLinkingRemoveBundle = Stopwatch();
 
+/// TODO(scheglov) deprecate `withInformative`.
 LinkResult link(
   LinkedElementFactory elementFactory,
-  List<LinkInputLibrary> inputLibraries,
-  bool withInformative,
-) {
-  var linker = Linker(elementFactory, withInformative);
+  List<LinkInputLibrary> inputLibraries, [
+  bool? withInformative,
+]) {
+  var linker = Linker(elementFactory);
   linker.link(inputLibraries);
   return LinkResult(
     astBytes: linker.astBytes,
@@ -38,18 +39,16 @@
 
 class Linker {
   final LinkedElementFactory elementFactory;
-  final bool withInformative;
 
   /// Libraries that are being linked.
   final Map<Uri, LibraryBuilder> builders = {};
 
   late InheritanceManager3 inheritance; // TODO(scheglov) cache it
 
-  late BundleWriter bundleWriter;
   late Uint8List astBytes;
   late Uint8List resolutionBytes;
 
-  Linker(this.elementFactory, this.withInformative);
+  Linker(this.elementFactory);
 
   AnalysisContextImpl get analysisContext {
     return elementFactory.analysisContext;
@@ -62,12 +61,6 @@
   Reference get rootReference => elementFactory.rootReference;
 
   void link(List<LinkInputLibrary> inputLibraries) {
-    bundleWriter = BundleWriter(
-      withInformative,
-      elementFactory.dynamicRef,
-    );
-    _writeAst(inputLibraries);
-
     for (var inputLibrary in inputLibraries) {
       LibraryBuilder.build(this, inputLibrary);
     }
@@ -75,7 +68,7 @@
     _buildOutlines();
 
     timerLinkingLinkingBundle.start();
-    _writeResolution();
+    _writeLibraries();
     timerLinkingLinkingBundle.stop();
 
     timerLinkingRemoveBundle.start();
@@ -215,35 +208,15 @@
     TypesBuilder().build(nodesToBuildType);
   }
 
-  void _writeAst(List<LinkInputLibrary> inputLibraries) {
-    for (var inputLibrary in inputLibraries) {
-      bundleWriter.addLibraryAst(
-        LibraryToWriteAst(
-          units: inputLibrary.units.map((e) {
-            return UnitToWriteAst(
-              node: e.unit,
-            );
-          }).toList(),
-        ),
-      );
-    }
-  }
+  void _writeLibraries() {
+    var bundleWriter = BundleWriter(
+      elementFactory.dynamicRef,
+    );
 
-  void _writeResolution() {
     for (var builder in builders.values) {
-      bundleWriter.addLibraryResolution(
-        LibraryToWriteResolution(
-          uriStr: '${builder.uri}',
-          exports: builder.exports,
-          units: builder.context.units.map((e) {
-            return UnitToWriteResolution(
-              uriStr: e.uriStr,
-              partUriStr: e.partUriStr,
-              node: e.unit!,
-              isSynthetic: e.isSynthetic,
-            );
-          }).toList(),
-        ),
+      bundleWriter.writeLibraryElement(
+        builder.element,
+        builder.exports,
       );
     }
 
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 92e167b..edf31e0 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -12,7 +12,6 @@
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/linked_library_context.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 
 class LinkedElementFactory {
@@ -22,6 +21,8 @@
   final Map<String, List<Reference>> linkingExports = {};
   final Map<String, LibraryReader> libraryReaders = {};
 
+  bool isApplyingInformativeData = false;
+
   LinkedElementFactory(
     this.analysisContext,
     this.analysisSession,
@@ -80,7 +81,7 @@
     if (librarySource == null) return null;
 
     var definingUnitContext = libraryContext.units[0];
-    var definingUnitNode = definingUnitContext.unit!;
+    var definingUnitNode = definingUnitContext.unit;
 
     // TODO(scheglov) Do we need this?
     var name = '';
@@ -104,6 +105,7 @@
       definingUnitContext,
       libraryContext.reference,
       definingUnitNode,
+      definingUnitNode.featureSet,
     );
     _setLibraryTypeSystem(libraryElement);
 
@@ -151,66 +153,10 @@
       );
     }
 
-    var libraryContext = LinkedLibraryContext(this, uriStr, reader.reference);
-    var unitContainerRef = reader.reference.getChild('@unit');
-
-    var unitContexts = <LinkedUnitContext>[];
-    var indexInLibrary = 0;
-    var unitReaders = reader.units;
-    for (var unitReader in unitReaders) {
-      var unitReference = unitContainerRef.getChild(unitReader.uriStr);
-      var unitContext = LinkedUnitContext(
-        libraryContext,
-        indexInLibrary++,
-        unitReader.partUriStr,
-        unitReader.uriStr,
-        unitReference,
-        unitReader.isSynthetic,
-        unit: unitReader.unit,
-        unitReader: unitReader,
-      );
-      unitContexts.add(unitContext);
-      libraryContext.units.add(unitContext);
-    }
-
-    var definingUnitContext = unitContexts[0];
-    var libraryElement = LibraryElementImpl.forLinkedNode(
-      analysisContext,
-      analysisSession,
-      reader.name,
-      reader.nameOffset,
-      reader.nameLength,
-      definingUnitContext,
-      reader.reference,
-      unitReaders.first.unit,
+    var libraryElement = reader.readElement(
+      librarySource: librarySource,
     );
     _setLibraryTypeSystem(libraryElement);
-
-    var units = <CompilationUnitElementImpl>[];
-    for (var unitContext in unitContexts) {
-      var unitNode = unitContext.unit as CompilationUnitImpl;
-
-      var unitSource = sourceFactory.forUri(unitContext.uriStr);
-      if (unitSource == null) continue;
-
-      var unitElement = CompilationUnitElementImpl.forLinkedNode(
-        libraryElement,
-        unitContext,
-        unitContext.reference,
-        unitNode,
-      );
-      unitElement.lineInfo = unitNode.lineInfo;
-      unitElement.source = unitSource;
-      unitElement.librarySource = librarySource;
-      unitElement.uri = unitContext.partUriStr;
-      units.add(unitElement);
-      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
-    }
-
-    libraryElement.definingCompilationUnit = units[0];
-    libraryElement.parts = units.skip(1).toList();
-    reader.reference.element = libraryElement;
-
     return libraryElement;
   }
 
@@ -261,141 +207,18 @@
     var parent = reference.parent!.parent!;
     var parentElement = elementOfReference(parent);
 
-    // Named formal parameters are created when we apply resolution to the
-    // executable declaration, e.g. a constructor, or a method.
-    if (reference.isParameter) {
-      (parentElement as ExecutableElement).parameters;
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    // The default constructor might be synthetic, and has no node.
-    // TODO(scheglov) We resynthesize all constructors here.
-    if (reference.isConstructor && reference.name == '') {
-      return (parentElement as ClassElement).unnamedConstructor;
-    }
-
-    if (parentElement is EnumElementImpl) {
-      parentElement.constants;
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    if (reference.element != null) {
-      return reference.element;
-    }
-
-    if (reference.isUnit) {
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    if (reference.isPrefix) {
-      (parentElement as LibraryElement).prefixes;
-      assert(reference.element != null);
-      return reference.element;
-    }
-
-    // For class, mixin, extension - index members.
-    var parentNodeAccessor = parent.nodeAccessor;
-    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44841
-    if (parentNodeAccessor == null) {
-      var parentNodeCode = '<unknown>';
-      try {
-        parentNodeCode = '${parent.node}';
-      } catch (_) {}
-      throw '[reference: $reference]'
-          '[parent: $parent]'
-          '[parentNodeCode: $parentNodeCode]';
-    } else {
-      parentNodeAccessor.readIndex();
-    }
-
-    // For any element - class, method, etc - read the node.
-    var node = reference.nodeAccessor!.node;
-
-    if (node is ClassDeclaration) {
-      ClassElementImpl.forLinkedNode(
-          parentElement as CompilationUnitElementImpl, reference, node);
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is ClassTypeAlias) {
-      ClassElementImpl.forLinkedNode(
-          parentElement as CompilationUnitElementImpl, reference, node);
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is ConstructorDeclarationImpl) {
-      ConstructorElementImpl.forLinkedNode(
-          parentElement as ClassElementImpl, reference, node);
-      var element = reference.element as ConstructorElementImpl;
-      return element;
-    } else if (node is EnumDeclarationImpl) {
-      EnumElementImpl.forLinkedNode(
-          parentElement as CompilationUnitElementImpl, reference, node);
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is ExtensionDeclarationImpl) {
-      ExtensionElementImpl.forLinkedNode(
-          parentElement as CompilationUnitElementImpl, reference, node);
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is FieldDeclaration) {
-      var variable = _variableDeclaration(node.fields, reference.name);
-      if (variable.isConst) {
-        ConstFieldElementImpl.forLinkedNode(
-            parentElement as ElementImpl, reference, variable);
-      } else {
-        FieldElementImpl.forLinkedNodeFactory(
-            parentElement as ElementImpl, reference, variable);
+    if (parentElement is ClassElementImpl) {
+      var linkedData = parentElement.linkedData;
+      if (linkedData is ClassElementLinkedData) {
+        linkedData.readMembers(parentElement);
       }
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is FunctionDeclarationImpl) {
-      if (node.propertyKeyword != null) {
-        _topLevelPropertyAccessor(parent,
-            parentElement as CompilationUnitElementImpl, reference, node);
-      } else {
-        FunctionElementImpl.forLinkedNode(
-            parentElement as CompilationUnitElementImpl, reference, node);
-      }
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is FunctionTypeAlias || node is GenericTypeAlias) {
-      TypeAliasElementImpl.forLinkedNodeFactory(
-          parentElement as CompilationUnitElementImpl,
-          reference,
-          node as TypeAlias);
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is MethodDeclarationImpl) {
-      if (node.propertyKeyword != null) {
-        _classPropertyAccessor(
-            parent, parentElement as ElementImpl, reference, node);
-      } else {
-        MethodElementImpl.forLinkedNode(
-            parentElement as TypeParameterizedElementMixin, reference, node);
-      }
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is MixinDeclarationImpl) {
-      MixinElementImpl.forLinkedNode(
-          parentElement as CompilationUnitElementImpl, reference, node);
-      assert(reference.element != null);
-      return reference.element;
-    } else if (node is TopLevelVariableDeclaration) {
-      var variable = _variableDeclaration(node.variables, reference.name);
-      if (variable.isConst) {
-        ConstTopLevelVariableElementImpl.forLinkedNode(
-            parentElement as ElementImpl, reference, variable);
-      } else {
-        TopLevelVariableElementImpl.forLinkedNode(
-            parentElement as CompilationUnitElementImpl, reference, variable);
-      }
-      assert(reference.element != null);
-      return reference.element;
     }
 
-    throw UnimplementedError('$reference');
+    var element = reference.element;
+    if (element == null) {
+      throw StateError('Expected existing element: $reference');
+    }
+    return element;
   }
 
   List<Reference> exportsOfLibrary(String uriStr) {
@@ -414,11 +237,6 @@
     return libraryReaders[uriStr] != null;
   }
 
-  bool isLibraryUri(String uriStr) {
-    var libraryContext = libraryReaders[uriStr]!;
-    return !libraryContext.hasPartOfDirective;
-  }
-
   LibraryElementImpl? libraryOfUri(String uriStr) {
     var reference = rootReference.getChild(uriStr);
     return elementOfReference(reference) as LibraryElementImpl?;
@@ -471,42 +289,6 @@
     analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
   }
 
-  void _classPropertyAccessor(
-    Reference parentReference,
-    ElementImpl parentElement,
-    Reference reference,
-    MethodDeclaration node,
-  ) {
-    var accessor = PropertyAccessorElementImpl.forLinkedNode(
-        parentElement, reference, node);
-
-    var name = reference.name;
-    var fieldRef = parentReference.getChild('@field').getChild(name);
-    var field = fieldRef.element as FieldElementImpl?;
-    if (field == null) {
-      field = FieldElementImpl(name, -1);
-      fieldRef.element = field;
-      field.enclosingElement = parentElement;
-      field.isSynthetic = true;
-      field.isFinal = node.isGetter;
-      field.isStatic = accessor.isStatic;
-    } else {
-      field.isFinal = false;
-    }
-
-    var isSetter = node.isSetter;
-    if (isSetter) {
-      field.isFinal = false;
-    }
-
-    accessor.variable = field;
-    if (isSetter) {
-      field.setter = accessor;
-    } else {
-      field.getter = accessor;
-    }
-  }
-
   void _declareDartCoreDynamicNever() {
     var dartCoreRef = rootReference.getChild('dart:core');
     dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
@@ -532,49 +314,4 @@
 
     libraryElement.createLoadLibraryFunction();
   }
-
-  void _topLevelPropertyAccessor(
-    Reference parentReference,
-    CompilationUnitElementImpl parentElement,
-    Reference reference,
-    FunctionDeclaration node,
-  ) {
-    var accessor = PropertyAccessorElementImpl.forLinkedNode(
-        parentElement, reference, node);
-
-    var name = reference.name;
-    var fieldRef = parentReference.getChild('@field').getChild(name);
-    var field = fieldRef.element as TopLevelVariableElementImpl?;
-    if (field == null) {
-      field = TopLevelVariableElementImpl(name, -1);
-      fieldRef.element = field;
-      field.enclosingElement = parentElement;
-      field.isFinal = true;
-      field.isSynthetic = true;
-    }
-
-    var isSetter = node.isSetter;
-    if (isSetter) {
-      field.isFinal = false;
-    }
-
-    accessor.variable = field;
-    if (isSetter) {
-      field.setter = accessor;
-    } else {
-      field.getter = accessor;
-    }
-  }
-
-  static VariableDeclaration _variableDeclaration(
-    VariableDeclarationList variableList,
-    String name,
-  ) {
-    for (var variable in variableList.variables) {
-      if (variable.name.name == name) {
-        return variable;
-      }
-    }
-    throw StateError('No "$name" in: $variableList');
-  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 2888aa1..9e5d5ca 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/linked_library_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -22,14 +21,11 @@
   final String uriStr;
   final Reference reference;
   final bool isSynthetic;
-  final CompilationUnit? unit;
-  final UnitReader? unitReader;
-
-  bool _hasDirectivesRead = false;
+  final CompilationUnit unit;
 
   LinkedUnitContext(this.libraryContext, this.indexInLibrary, this.partUriStr,
       this.uriStr, this.reference, this.isSynthetic,
-      {required this.unit, required this.unitReader});
+      {required this.unit});
 
   CompilationUnitElementImpl get element {
     return reference.element as CompilationUnitElementImpl;
@@ -38,7 +34,7 @@
   LinkedElementFactory get elementFactory => libraryContext.elementFactory;
 
   bool get hasPartOfDirective {
-    for (var directive in unit_withDirectives.directives) {
+    for (var directive in unit.directives) {
       if (directive is PartOfDirective) {
         return true;
       }
@@ -47,7 +43,7 @@
   }
 
   /// Return `true` if this unit is a part of a bundle that is being linked.
-  bool get isLinking => unitReader == null;
+  bool get isLinking => true;
 
   TypeProvider get typeProvider {
     var libraryReference = libraryContext.reference;
@@ -55,45 +51,6 @@
     return libraryElement.typeProvider;
   }
 
-  CompilationUnit get unit_withDeclarations {
-    unitReader?.readDeclarations();
-    return unit!;
-  }
-
-  /// Ensure that [unit] has directives ready (because we are linking,
-  /// and so always have full AST, or, if we are reading, we make sure
-  /// that we have them read).
-  CompilationUnit get unit_withDirectives {
-    if (unitReader != null && !_hasDirectivesRead) {
-      _hasDirectivesRead = true;
-      unitReader!.readDirectives();
-      var libraryElement =
-          libraryContext.reference.element as LibraryElementImpl;
-      for (var directive in unit!.directives) {
-        if (directive is ExportDirectiveImpl) {
-          if (directive.element == null) {
-            ExportElementImpl.forLinkedNode(libraryElement, directive);
-          }
-        } else if (directive is ImportDirectiveImpl) {
-          if (directive.element == null) {
-            ImportElementImpl.forLinkedNode(libraryElement, directive);
-          }
-        }
-      }
-    }
-    return unit!;
-  }
-
-  void applyResolution(AstNode node) {
-    if (node is VariableDeclaration) {
-      node = node.parent!.parent!;
-    }
-    if (node is HasAstLinkedContext) {
-      var astLinkedContext = (node as HasAstLinkedContext).linkedContext;
-      astLinkedContext?.applyResolution(this);
-    }
-  }
-
   void createGenericFunctionTypeElement(int id, GenericFunctionTypeImpl node) {
     var containerRef = this.reference.getChild('@genericFunctionType');
     var reference = containerRef.getChild('$id');
@@ -105,55 +62,6 @@
     node.declaredElement = element;
   }
 
-  int getCodeLength(AstNode node) {
-    if (node is HasAstLinkedContext) {
-      var linked = (node as HasAstLinkedContext).linkedContext;
-      return linked != null ? linked.codeLength : node.length;
-    }
-
-    if (node is CompilationUnitImpl) {
-      var data = node.summaryData as SummaryDataForCompilationUnit?;
-      if (data != null) {
-        return data.codeLength;
-      } else {
-        return node.length;
-      }
-    } else if (node is EnumConstantDeclaration) {
-      return node.length;
-    } else if (node is FormalParameter) {
-      return node.length;
-    } else if (node is TypeParameter) {
-      return node.length;
-    } else if (node is VariableDeclaration) {
-      var parent2 = node.parent!.parent!;
-      var linked = (parent2 as HasAstLinkedContext).linkedContext!;
-      return linked.getVariableDeclarationCodeLength(node);
-    }
-    throw UnimplementedError('${node.runtimeType}');
-  }
-
-  int getCodeOffset(AstNode node) {
-    if (node is HasAstLinkedContext) {
-      var linked = (node as HasAstLinkedContext).linkedContext;
-      return linked != null ? linked.codeOffset : node.offset;
-    }
-
-    if (node is CompilationUnit) {
-      return 0;
-    } else if (node is EnumConstantDeclaration) {
-      return node.offset;
-    } else if (node is FormalParameter) {
-      return node.offset;
-    } else if (node is TypeParameter) {
-      return node.offset;
-    } else if (node is VariableDeclaration) {
-      var parent2 = node.parent!.parent!;
-      var linked = (parent2 as HasAstLinkedContext).linkedContext!;
-      return linked.getVariableDeclarationCodeOffset(node);
-    }
-    throw UnimplementedError('${node.runtimeType}');
-  }
-
   List<ConstructorInitializer> getConstructorInitializers(
     ConstructorDeclaration node,
   ) {
@@ -177,18 +85,6 @@
     return node.keyword.offset;
   }
 
-  Comment? getDocumentationComment(AstNode node) {
-    if (node is HasAstLinkedContext) {
-      var linkedContext = (node as HasAstLinkedContext).linkedContext;
-      linkedContext?.readDocumentationComment();
-      return (node as AnnotatedNode).documentationComment;
-    } else if (node is VariableDeclaration) {
-      return getDocumentationComment(node.parent!.parent!);
-    } else {
-      throw UnimplementedError('${node.runtimeType}');
-    }
-  }
-
   String getFieldFormalParameterName(AstNode node) {
     if (node is DefaultFormalParameter) {
       return getFieldFormalParameterName(node.parameter);
@@ -274,21 +170,8 @@
     return (node as CompilationUnitImpl).languageVersion!;
   }
 
-  Comment? getLibraryDocumentationComment() {
-    for (var directive in unit_withDirectives.directives) {
-      if (directive is LibraryDirectiveImpl) {
-        var data = directive.summaryData as SummaryDataForLibraryDirective;
-        data.readDocumentationComment();
-        return directive.documentationComment;
-      }
-    }
-    return null;
-  }
-
   List<Annotation> getLibraryMetadata() {
-    unit_withDirectives;
-    unitReader!.applyDirectivesResolution(this);
-    for (var directive in unit!.directives) {
+    for (var directive in unit.directives) {
       if (directive is LibraryDirective) {
         return directive.metadata;
       }
@@ -649,18 +532,10 @@
       if (variableList.isFinal) {
         var class_ = fieldDeclaration.parent;
         if (class_ is ClassDeclaration) {
-          var hasLinkedContext = class_ as HasAstLinkedContext;
-          var linkedContext = hasLinkedContext.linkedContext;
-          // TODO(scheglov) Get rid of this check, exists only for linking.
-          // Maybe we should pre-create all elements before linking.
-          if (linkedContext != null) {
-            return linkedContext.isClassWithConstConstructor;
-          } else {
-            for (var member in class_.members) {
-              if (member is ConstructorDeclaration &&
-                  member.constKeyword != null) {
-                return true;
-              }
+          for (var member in class_.members) {
+            if (member is ConstructorDeclaration &&
+                member.constKeyword != null) {
+              return true;
             }
           }
         }
@@ -682,27 +557,22 @@
   List<ClassMember> _getClassOrExtensionOrMixinMembers(
     CompilationUnitMember node,
   ) {
-    var linkedContext = (node as HasAstLinkedContext).linkedContext;
-    if (linkedContext != null) {
-      return linkedContext.classMembers;
+    if (node is ClassDeclaration) {
+      return node.members;
+    } else if (node is ClassTypeAlias) {
+      return <ClassMember>[];
+    } else if (node is ExtensionDeclaration) {
+      return node.members;
+    } else if (node is MixinDeclaration) {
+      return node.members;
     } else {
-      if (node is ClassDeclaration) {
-        return node.members;
-      } else if (node is ClassTypeAlias) {
-        return <ClassMember>[];
-      } else if (node is ExtensionDeclaration) {
-        return node.members;
-      } else if (node is MixinDeclaration) {
-        return node.members;
-      } else {
-        throw StateError('${node.runtimeType}');
-      }
+      throw StateError('${node.runtimeType}');
     }
   }
 
   NodeList<Annotation> _getPartDirectiveAnnotation() {
     var definingContext = libraryContext.definingUnit;
-    var definingUnit = definingContext.unit_withDirectives;
+    var definingUnit = definingContext.unit;
     var partDirectiveIndex = 0;
     for (var directive in definingUnit.directives) {
       if (directive is PartDirective) {
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index cc431c9..2e5eb2f 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -251,7 +251,7 @@
     // If the element is not being linked, there is no reason (or a way,
     // because the linked node might be read only partially) to go through
     // its node - all its types have already been built.
-    if (!element.linkedContext!.isLinking) {
+    if (element.linkedContext == null) {
       return element.aliasedType;
     }
 
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_format.dart b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
index c876e47..6c964cc 100644
--- a/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
@@ -46,8 +46,7 @@
     sink.writeUint8List(astBytes);
     sink.writeUint8List(resolutionBytes);
 
-    sink.flushAndDestroy();
-    return byteSink.builder.takeBytes();
+    return sink.flushAndTake();
   }
 }
 
@@ -62,7 +61,6 @@
 class PackageBundleReader {
   final List<PackageBundleLibrary> libraries = [];
   late final PackageBundleSdk? _sdk;
-  late final Uint8List _astBytes;
   late final Uint8List _resolutionBytes;
 
   PackageBundleReader(Uint8List bytes) {
@@ -86,11 +84,12 @@
       );
     }
 
-    _astBytes = reader.readUint8List();
+    reader.readUint8List(); // astBytes
     _resolutionBytes = reader.readUint8List();
   }
 
-  Uint8List get astBytes => _astBytes;
+  @Deprecated('The linker does not need it anymore')
+  Uint8List get astBytes => Uint8List(0);
 
   Uint8List get resolutionBytes => _resolutionBytes;
 
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index c420b45..170307e 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -90,6 +90,11 @@
             contextType: typeNode.type);
       }
     }
+
+    if (element is ConstVariableElement) {
+      var constElement = element as ConstVariableElement;
+      constElement.constantInitializer = variable.initializer;
+    }
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index 6309bb5..da7f48e 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -11,7 +11,7 @@
   void perform(Linker linker) {
     for (var builder in linker.builders.values) {
       for (var unitContext in builder.context.units) {
-        for (var node in unitContext.unit!.declarations) {
+        for (var node in unitContext.unit.declarations) {
           if (node is FunctionTypeAlias) {
             var finder = _Finder(node);
             finder.functionTypeAlias(node);
@@ -86,8 +86,10 @@
 
     if (node is TypeName) {
       var element = node.name.staticElement;
+      // TODO(scheglov) We have `linkedContext` only during linking.
       if (element is ElementImpl &&
           element.enclosingElement != null &&
+          element.linkedContext != null &&
           element.linkedContext!.isLinking) {
         var typeNode = element.linkedNode;
         if (typeNode == self) {
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index af20893..5555eaa 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -367,6 +367,7 @@
       _MixinInference(element, featureSet).perform(withClause);
     } finally {
       element.linkedMixinInferenceCallback = null;
+      element.resetAfterMixinInference();
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/variance_builder.dart b/pkg/analyzer/lib/src/summary2/variance_builder.dart
index edae4df..517aa4a 100644
--- a/pkg/analyzer/lib/src/summary2/variance_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/variance_builder.dart
@@ -19,7 +19,7 @@
   void perform(Linker linker) {
     for (var builder in linker.builders.values) {
       for (var unitContext in builder.context.units) {
-        for (var node in unitContext.unit!.declarations) {
+        for (var node in unitContext.unit.declarations) {
           if (node is FunctionTypeAlias) {
             _pending.add(node);
           } else if (node is GenericTypeAlias) {
@@ -31,7 +31,7 @@
 
     for (var builder in linker.builders.values) {
       for (var unitContext in builder.context.units) {
-        for (var node in unitContext.unit!.declarations) {
+        for (var node in unitContext.unit.declarations) {
           if (node is ClassTypeAlias) {
             _typeParameters(node.typeParameters);
           } else if (node is ClassDeclaration) {
@@ -218,7 +218,9 @@
 
   void _typeAliasElement(TypeAliasElementImpl element) {
     var node = element.linkedNode;
-    if (node is GenericTypeAlias) {
+    if (node == null) {
+      // Not linking.
+    } else if (node is GenericTypeAlias) {
       _genericTypeAlias(node);
     } else if (node is FunctionTypeAlias) {
       _functionTypeAlias(node);
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index ce22e20..19b6f2b 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -312,7 +312,6 @@
 ''');
   }
 
-  @FailingTest(reason: 'We should set the type of v')
   test_fuzz_38953() async {
     // When we enter a directive, we should stop using the element walker
     // of the unit, just like when we enter a method body. Even though using
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 5a0883d..c319cc9 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -7612,6 +7612,9 @@
     _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
   }
 
+  @FailingTest(
+    reason: 'No nameOffset for formal parameters',
+  )
   test_top_functionTypeAlias() async {
     String content = r'''
 typedef int F<T>(bool a, T b);
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
index fc8a498..1507f47 100644
--- a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -232,6 +232,34 @@
 ''');
   }
 
+  test_class_documentation_add() async {
+    assertSameSignature(r'''
+class C {}
+''', r'''
+/// foo
+class C {}
+''');
+  }
+
+  test_class_documentation_change() async {
+    assertSameSignature(r'''
+/// foo
+class C {}
+''', r'''
+/// bar bar
+class C {}
+''');
+  }
+
+  test_class_documentation_remove() async {
+    assertSameSignature(r'''
+/// foo
+class C {}
+''', r'''
+class C {}
+''');
+  }
+
   test_class_extends() {
     assertNotSameSignature(r'''
 class A {}
@@ -904,6 +932,54 @@
 ''');
   }
 
+  test_directive_library_add() {
+    assertNotSameSignature(r'''
+class A {}
+''', r'''
+library foo;
+class A {}
+''');
+  }
+
+  test_directive_library_change_name() {
+    assertNotSameSignature(r'''
+library foo;
+class A {}
+''', r'''
+library bar;
+class A {}
+''');
+  }
+
+  test_directive_library_change_name_length() {
+    assertSameSignature(r'''
+library foo.bar;
+class A {}
+''', r'''
+library foo. bar;
+class A {}
+''');
+  }
+
+  test_directive_library_change_name_offset() {
+    assertSameSignature(r'''
+library foo;
+class A {}
+''', r'''
+library  foo;
+class A {}
+''');
+  }
+
+  test_directive_library_remove() {
+    assertNotSameSignature(r'''
+library foo;
+class A {}
+''', r'''
+class A {}
+''');
+  }
+
   test_featureSet_add() async {
     assertNotSameSignature(r'''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
index 59e92f4..9a5e9bf 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
@@ -177,8 +177,8 @@
     await assertNoErrorsInCode(r'''
 class A {
   A.c1(int a);
-  A.c2(int a, [int b = 0, int c = 0]);
-  A.c3(int a, {int b = 0, int c = 0});
+  A.c2(int a, [int? b, int c = 0]);
+  A.c3(int a, {int? b, int c = 0});
 }
 
 class M {}
@@ -190,8 +190,8 @@
       findElement.class_('C'),
       [
         'C C.c1(int a)',
-        'C C.c2(int a, [int b, int c])',
-        'C C.c3(int a, {int b, int c})'
+        'C C.c2(int a, [int b, int c = 0])',
+        'C C.c3(int a, {int b, int c = 0})'
       ],
     );
   }
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart
index 5f0614c..01a7d14 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart
@@ -60,6 +60,30 @@
     ]);
   }
 
+  /// See `10.6.1 Generative Constructors`.
+  ///
+  /// Each initializing formal in the formal parameter list introduces a final
+  /// local variable into the formal parameter initializer scope, but not into
+  /// the formal parameter scope; every other formal parameter introduces a
+  /// local variable into both the formal parameter scope and the formal
+  /// parameter initializer scope.
+  ///
+  /// Note that it says 'final local variable', regardless whether the instance
+  /// variable is final.
+  test_parameter_fieldFormal() async {
+    await assertErrorsInCode('''
+class A {
+  int x;
+  final Object y;
+  A(this.x) : y = (() {
+    x = 0;
+  });
+}
+''', [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 65, 1),
+    ]);
+  }
+
   test_postfixMinusMinus() async {
     await assertErrorsInCode('''
 f() {
diff --git a/pkg/analyzer/test/src/diagnostics/private_collision_in_mixin_application_test.dart b/pkg/analyzer/test/src/diagnostics/private_collision_in_mixin_application_test.dart
index de4ef80..4ded8b3 100644
--- a/pkg/analyzer/test/src/diagnostics/private_collision_in_mixin_application_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/private_collision_in_mixin_application_test.dart
@@ -71,6 +71,26 @@
     ]);
   }
 
+  test_class_mixinAndMixin_withoutExtends() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  void _foo() {}
+}
+
+class B {
+  void _foo() {}
+}
+''');
+
+    await assertErrorsInCode('''
+import 'a.dart';
+
+class C with A, B {}
+''', [
+      error(CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, 34, 1),
+    ]);
+  }
+
   test_class_staticAndInstanceElement() async {
     newFile('$testPackageLibPath/a.dart', content: r'''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
index a5453bd..072b733 100644
--- a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
@@ -107,6 +107,17 @@
 ''');
   }
 
+  test_none_asyncStar_null_to_streamInt() async {
+    var errors = expectedErrorsByNullability(nullable: [
+      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 33, 4),
+    ], legacy: []);
+    await assertErrorsInCode('''
+Stream<int> f() async* {
+  yield null;
+}
+''', errors);
+  }
+
   test_none_syncStar_dynamic_to_iterableInt() async {
     await assertErrorsInCode(
         '''
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index b1bfca5..624b416 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -283,10 +283,21 @@
     buffer.write(e.enclosingElement.name);
     if (e.name.isNotEmpty) {
       buffer.write('.');
-      writeName(e);
+      buffer.write(e.displayName);
     }
     if (!e.isSynthetic) {
       writeCodeRange(e);
+      if (withOffsets) {
+        var periodOffset = e.periodOffset;
+        var nameEnd = e.nameEnd;
+        if (periodOffset != null && nameEnd != null) {
+          buffer.write('[periodOffset: $periodOffset]');
+          buffer.write('[nameOffset: ${e.nameOffset}]');
+          buffer.write('[nameEnd: $nameEnd]');
+        } else {
+          buffer.write('[nameOffset: ${e.nameOffset}]');
+        }
+      }
     }
 
     writeParameterElements(e.parameters);
@@ -838,6 +849,12 @@
     writeCodeRange(e);
 
     if (!withFullyResolvedAst) {
+      if (e.typeParameters.isNotEmpty) {
+        buffer.write('/*');
+        writeTypeParameterElements(e.typeParameters, withDefault: false);
+        buffer.write('*/');
+      }
+
       if (e.parameters.isNotEmpty) {
         buffer.write('/*');
         writeList('(', ')', e.parameters, ', ', writeParameterElement);
@@ -873,7 +890,17 @@
     if (!e.isSynthetic) {
       PropertyInducingElement variable = e.variable;
       expect(variable, isNotNull);
-      expect(variable.isSynthetic, isTrue);
+
+      if (e.isGetter) {
+        // Usually we have a synthetic property for a non-synthetic accessor.
+        expect(variable.isSynthetic, isTrue);
+      } else {
+        // But it is possible to have a non-synthetic property.
+        // class A {
+        //   final int foo;
+        //   set foo(int newValue) {}
+        // }
+      }
 
       var variableEnclosing = variable.enclosingElement;
       if (variableEnclosing is CompilationUnitElement) {
@@ -921,15 +948,13 @@
 
     writeName(e);
 
+    expect(e.typeParameters, isEmpty);
+
     if (e.isSetter || e.parameters.isNotEmpty) {
       writeParameterElements(e.parameters);
     }
 
-    expect(e.typeParameters, isEmpty);
-
-    expect(e.isSynchronous, isTrue);
-    expect(e.isAsynchronous, isFalse);
-    expect(e.isGenerator, isFalse);
+    writeBodyModifiers(e);
 
     if (e.isAbstract || e.isExternal) {
       buffer.writeln(';');
@@ -1152,7 +1177,17 @@
   /// the same enclosing element as the [property].
   void _assertSyntheticAccessorEnclosing(
       PropertyInducingElement property, PropertyAccessorElement accessor) {
-    expect(accessor.isSynthetic, isTrue);
+    if (accessor.isSynthetic) {
+      // Usually we have a non-synthetic property, and a synthetic accessor.
+    } else {
+      // But it is possible to have a non-synthetic setter.
+      // class A {
+      //   final int foo;
+      //   set foo(int newValue) {}
+      // }
+      assert(accessor.isSetter, isTrue);
+    }
+
     expect(accessor.variable, same(property));
 
     var propertyEnclosing = property.enclosingElement;
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index cc3104a..b07b6f8 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -90,6 +91,16 @@
     var inputLibraries = <LinkInputLibrary>[];
     _addNonDartLibraries({}, inputLibraries, source);
 
+    var unitsInformativeBytes = <Uri, Uint8List>{};
+    for (var inputLibrary in inputLibraries) {
+      for (var inputUnit in inputLibrary.units) {
+        var informativeBytes = writeUnitInformative(inputUnit.unit);
+        // TODO(scheglov) store Uri, don't parse
+        var uri = Uri.parse(inputUnit.uriStr);
+        unitsInformativeBytes[uri] = informativeBytes;
+      }
+    }
+
     var analysisContext = AnalysisContextImpl(
       SynchronousSession(
         AnalysisOptionsImpl()..contextFeatures = featureSet,
@@ -106,7 +117,7 @@
     elementFactory.addBundle(
       BundleReader(
         elementFactory: elementFactory,
-        astBytes: sdkBundle.astBytes,
+        unitsInformativeBytes: {},
         resolutionBytes: sdkBundle.resolutionBytes,
       ),
     );
@@ -116,7 +127,7 @@
     elementFactory.addBundle(
       BundleReader(
         elementFactory: elementFactory,
-        astBytes: linkResult.astBytes,
+        unitsInformativeBytes: unitsInformativeBytes,
         resolutionBytes: linkResult.resolutionBytes,
       ),
     );
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 44718305..72c3a4f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -375,13 +375,13 @@
   synthetic MixinApp.positionalArg([bool x = true]) : super.
         positionalArg/*location: a.dart;Base;positionalArg*/(
         x/*location: test.dart;MixinApp;positionalArg;x*/);
-  synthetic MixinApp.positionalArg2([bool x = true]) : super.
+  synthetic MixinApp.positionalArg2([final bool x = true]) : super.
         positionalArg2/*location: a.dart;Base;positionalArg2*/(
         x/*location: test.dart;MixinApp;positionalArg2;x*/);
   synthetic MixinApp.namedArg({int x: 42}) : super.
         namedArg/*location: a.dart;Base;namedArg*/(
         x/*location: test.dart;MixinApp;namedArg;x*/);
-  synthetic MixinApp.namedArg2({bool x: true}) : super.
+  synthetic MixinApp.namedArg2({final bool x: true}) : super.
         namedArg2/*location: a.dart;Base;namedArg2*/(
         x/*location: test.dart;MixinApp;namedArg2;x*/);
 }
@@ -528,7 +528,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(dynamic this.x);
+  C(final dynamic this.x);
 }
 ''');
   }
@@ -538,7 +538,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(int this.x);
+  C(final int this.x);
 }
 ''');
   }
@@ -548,7 +548,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(dynamic this.x);
+  C(final dynamic this.x);
 }
 ''');
   }
@@ -563,7 +563,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(dynamic Function(double) this.x/*(double b)*/);
+  C(final dynamic Function(double) this.x/*(double b)*/);
 }
 ''');
   }
@@ -578,7 +578,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(int Function(double) this.x/*(double b)*/);
+  C(final int Function(double) this.x/*(double b)*/);
 }
 ''');
   }
@@ -593,7 +593,7 @@
     checkElementText(library, r'''
 class C {
   dynamic Function() f;
-  C(List<U> Function<T, U>(T) this.f/*(T t)*/);
+  C(final List<U> Function<T, U>(T) this.f/*<T, U>*//*(T t)*/);
 }
 ''');
   }
@@ -606,7 +606,7 @@
 class C {
   int x;
   String x;
-  C(int this.x);
+  C(final int this.x);
 }
 ''');
   }
@@ -617,7 +617,7 @@
         await checkLibrary('class C { C(this.x); }', allowErrors: true);
     checkElementText(library, r'''
 class C {
-  C(dynamic this.x);
+  C(final dynamic this.x);
 }
 ''');
   }
@@ -628,7 +628,7 @@
     checkElementText(library, r'''
 class C {
   num x;
-  C(dynamic this.x);
+  C(final dynamic this.x);
 }
 ''');
   }
@@ -638,7 +638,7 @@
     checkElementText(library, r'''
 class C {
   num x;
-  C(int this.x);
+  C(final int this.x);
 }
 ''');
   }
@@ -648,7 +648,7 @@
     checkElementText(library, r'''
 class C {
   num x;
-  C(num this.x);
+  C(final num this.x);
 }
 ''');
   }
@@ -658,7 +658,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(dynamic this.x);
+  C(final dynamic this.x);
 }
 ''');
   }
@@ -668,7 +668,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(int this.x);
+  C(final int this.x);
 }
 ''');
   }
@@ -678,7 +678,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C(dynamic this.x);
+  C(final dynamic this.x);
 }
 ''');
   }
@@ -688,7 +688,7 @@
     checkElementText(library, r'''
 class C {
   int x;
-  C({int this.x});
+  C({final int this.x});
 }
 ''');
   }
@@ -698,7 +698,7 @@
     checkElementText(library, r'''
 class C {
   int x;
-  C({int this.x: 42});
+  C({final int this.x: 42});
 }
 ''');
   }
@@ -708,7 +708,7 @@
     checkElementText(library, r'''
 class C {
   int x;
-  C([int this.x]);
+  C([final int this.x]);
 }
 ''');
   }
@@ -718,7 +718,7 @@
     checkElementText(library, r'''
 class C {
   int x;
-  C([int this.x = 42]);
+  C([final int this.x = 42]);
 }
 ''');
   }
@@ -986,6 +986,28 @@
 ''');
   }
 
+  test_class_field_final_withSetter() async {
+    var library = await checkLibrary(r'''
+class A {
+  final int foo;
+  A(this.foo);
+  set foo(int newValue) {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  final int foo;
+  synthetic int get foo {}
+  void set foo(int newValue) {}
+  A(final int this.foo);
+}
+''',
+        withSyntheticFields: true,
+        withSyntheticAccessors: true);
+  }
+
   test_class_field_implicit_type() async {
     var library = await checkLibrary('class C { var x; }');
     checkElementText(library, r'''
@@ -2992,8 +3014,8 @@
     checkElementText(library, '''
 class C<T> {
   final T t;
-  const C(T this.t);
-  const C.named(T this.t);
+  const C(final T this.t);
+  const C.named(final T this.t);
 }
 const Object x = const
         C/*location: test.dart;C*/(0);
@@ -3871,7 +3893,7 @@
     checkElementText(library, r'''
 class C {
   final dynamic x;
-  const C({dynamic this.x:
+  const C({final dynamic this.x:
         foo/*location: test.dart;foo*/});
 }
 int foo() {}
@@ -3888,7 +3910,7 @@
     checkElementText(library, r'''
 class C {
   final dynamic x;
-  const C({dynamic this.x: 1 + 2});
+  const C({final dynamic this.x: 1 + 2});
 }
 ''');
   }
@@ -3903,7 +3925,7 @@
     checkElementText(library, r'''
 class C {
   final dynamic x;
-  const C([dynamic this.x = 1 + 2]);
+  const C([final dynamic this.x = 1 + 2]);
 }
 ''');
   }
@@ -3991,6 +4013,65 @@
     );
   }
 
+  test_const_prefixExpression_class_unaryMinus() async {
+    var library = await checkLibrary(r'''
+const a = 0;
+const b = -a;
+''');
+    checkElementText(
+      library,
+      r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+const int b;
+  constantInitializer
+    PrefixExpression
+      operand: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: int
+        token: a
+      operator: -
+      staticElement: dart:core::@class::int::@method::unary-
+      staticType: int
+''',
+      withFullyResolvedAst: true,
+    );
+  }
+
+  test_const_prefixExpression_extension_unaryMinus() async {
+    testFile = convertPath('/home/test/lib/test.dart');
+    addLibrarySource('/home/test/lib/a.dart', r'''
+extension E on Object {
+  int operator -() => 0;
+}
+const a = const Object();
+''');
+    var library = await checkLibrary('''
+import 'a.dart';
+const b = -a;
+''');
+    checkElementText(
+      library,
+      r'''
+import 'package:test/a.dart';
+const int b;
+  constantInitializer
+    PrefixExpression
+      operand: SimpleIdentifier
+        staticElement: package:test/a.dart::@getter::a
+        staticType: Object
+        token: a
+      operator: -
+      staticElement: package:test/a.dart::@extension::E::@method::unary-
+      staticType: int
+''',
+      withFullyResolvedAst: true,
+    );
+  }
+
   test_const_prefixExpression_increment() async {
     var library = await checkLibrary(r'''
 const a = 0;
@@ -4991,7 +5072,7 @@
       ConstructorFieldInitializer
         equals: =
         expression: SimpleIdentifier
-          staticElement: f@41
+          staticElement: self::@class::A::@constructor::•::@parameter::f
           staticType: int
           token: f
         fieldName: SimpleIdentifier
@@ -5853,7 +5934,7 @@
 typedef F<T> = void Function(T v);
 class X {
   final void Function(dynamic) f;
-  const X({void Function(dynamic) this.f:
+  const X({final void Function(dynamic) this.f:
         defaultF/*location: test.dart;defaultF*/});
 }
 void defaultF<T>(T v) {}
@@ -7030,7 +7111,7 @@
     checkElementText(library, r'''
 class C extends D {
   int v;
-  C(int this.v);
+  C(final int this.v);
 }
 abstract class D {
   int get v;
@@ -7851,6 +7932,26 @@
 ''');
   }
 
+  test_getter_async() async {
+    var library = await checkLibrary(r'''
+Future<int> get foo async => 0;
+''');
+    checkElementText(library, r'''
+Future<int> get foo async {}
+''');
+  }
+
+  test_getter_asyncStar() async {
+    var library = await checkLibrary(r'''
+import 'dart:async';
+Stream<int> get foo async* {}
+''');
+    checkElementText(library, r'''
+import 'dart:async';
+Stream<int> get foo async* {}
+''');
+  }
+
   test_getter_documented() async {
     var library = await checkLibrary('''
 // Extra comment so doc comment offset != 0
@@ -7886,6 +7987,15 @@
 ''');
   }
 
+  test_getter_syncStar() async {
+    var library = await checkLibrary(r'''
+Iterator<int> get foo sync* {}
+''');
+    checkElementText(library, r'''
+Iterator<int> get foo sync* {}
+''');
+  }
+
   test_getters() async {
     var library = await checkLibrary('int get x => null; get y => null;');
     checkElementText(library, r'''
@@ -7905,7 +8015,7 @@
     checkElementText(library, r'''
 class C {
   final Object x;
-  const C.named(Object this.x);
+  const C.named(final Object this.x);
 }
 const C x =
         C/*location: test.dart;C*/.
@@ -8050,6 +8160,16 @@
     expect(typeA.element.source.shortName, 'foo_html.dart');
   }
 
+  test_import_dartCore_explicit() async {
+    var library = await checkLibrary('''
+import 'dart:core';
+import 'dart:math';
+''');
+    expect(library.imports, hasLength(2));
+    expect(library.imports[0].uri, 'dart:core');
+    expect(library.imports[1].uri, 'dart:math');
+  }
+
   test_import_dartCore_implicit() async {
     var library = await checkLibrary('''
 import 'dart:math';
@@ -9295,7 +9415,7 @@
     checkElementText(library, r'''
 class C {
   int foo;
-  void set bar(dynamic this.foo) {}
+  void set bar(final dynamic this.foo) {}
 }
 ''');
   }
@@ -9308,7 +9428,7 @@
 ''');
     checkElementText(library, r'''
 class C {
-  void set x(dynamic this.x) {}
+  void set x(final dynamic this.x) {}
 }
 ''');
   }
@@ -9634,6 +9754,41 @@
 ''');
   }
 
+  test_metadata_class_field_first() async {
+    var library = await checkLibrary(r'''
+const a = 0;
+class C {
+  @a
+  int x = 0;
+}
+''');
+    // Check metadata without asking any other properties.
+    var x = _elementOfDefiningUnit(library, ['@class', 'C', '@field', 'x'])
+        as FieldElement;
+    expect(x.metadata, hasLength(1));
+    // Check details.
+    checkElementText(
+        library,
+        r'''
+class C {
+  int x;
+    metadata
+      Annotation
+        element: self::@getter::a
+        name: SimpleIdentifier
+          staticElement: self::@getter::a
+          staticType: null
+          token: a
+}
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_class_scope() async {
     var library = await checkLibrary(r'''
 const foo = 0;
@@ -10544,7 +10699,7 @@
 }
 class A {
   final dynamic value;
-  const A(dynamic this.value);
+  const A(final dynamic this.value);
 }
 ''',
         withFullyResolvedAst: true);
@@ -10688,7 +10843,7 @@
 class C {
   dynamic x;
   C(@
-        a/*location: test.dart;a?*/ dynamic this.x);
+        a/*location: test.dart;a?*/ final dynamic this.x);
 }
 const dynamic a = null;
 ''');
@@ -10701,7 +10856,7 @@
 class C {
   dynamic x;
   C([@
-        a/*location: test.dart;a?*/ dynamic this.x = null]);
+        a/*location: test.dart;a?*/ final dynamic this.x = null]);
 }
 const dynamic a = null;
 ''');
@@ -11156,6 +11311,37 @@
 ''');
   }
 
+  test_metadata_unit_topLevelVariable_first() async {
+    var library = await checkLibrary(r'''
+const a = 0;
+@a
+int x = 0;
+''');
+    // Check metadata without asking any other properties.
+    var x = _elementOfDefiningUnit(library, ['@variable', 'x'])
+        as TopLevelVariableElement;
+    expect(x.metadata, hasLength(1));
+    // Check details.
+    checkElementText(
+        library,
+        r'''
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+int x;
+  metadata
+    Annotation
+      element: self::@getter::a
+      name: SimpleIdentifier
+        staticElement: self::@getter::a
+        staticType: null
+        token: a
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_value_class_staticField() async {
     testFile = convertPath('/home/test/lib/test.dart');
     var library = await checkLibrary('''
@@ -11733,6 +11919,218 @@
 ''');
   }
 
+  test_nameOffset_class_constructor() async {
+    var library = await checkLibrary(r'''
+class A {
+  A();
+  A.named();
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6 {
+  A[nameOffset: 12]();
+  A.named[periodOffset: 20][nameOffset: 21][nameEnd: 26]();
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_class_constructor_parameter() async {
+    var library = await checkLibrary(r'''
+class A {
+  A(int a);
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6 {
+  A[nameOffset: 12](int a@18);
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_class_field() async {
+    var library = await checkLibrary(r'''
+class A {
+  int foo = 0;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6 {
+  int foo@16;
+  synthetic int get foo@16 {}
+  synthetic void set foo@16(int _foo@16) {}
+}
+''',
+        withOffsets: true,
+        withSyntheticAccessors: true);
+  }
+
+  test_nameOffset_class_getter() async {
+    var library = await checkLibrary(r'''
+class A {
+  int get foo => 0;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6 {
+  int get foo@20 {}
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_class_method() async {
+    var library = await checkLibrary(r'''
+class A {
+  void foo<T>(int a) {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6 {
+  void foo@17<T@21>(int a@28) {}
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_class_setter() async {
+    var library = await checkLibrary(r'''
+class A {
+  set foo(int x) {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6 {
+  void set foo@16(int x@24) {}
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_class_typeParameter() async {
+    var library = await checkLibrary(r'''
+class A<T> {}
+''');
+    checkElementText(
+        library,
+        r'''
+class A@6<T@8> {
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_extension_typeParameter() async {
+    var library = await checkLibrary(r'''
+extension E<T> on int {}
+''');
+    checkElementText(
+        library,
+        r'''
+extension E@10<T@12> on int {
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_function_functionTypedFormal_parameter() async {
+    var library = await checkLibrary(r'''
+void f(void f<U>(int a)) {}
+''');
+    checkElementText(
+        library,
+        r'''
+void f@5(void Function<U>(int) f@12/*<U@14>*//*(int a@21)*/) {}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_function_functionTypedFormal_parameter2() async {
+    var library = await checkLibrary(r'''
+void f({required void f<U>(int a)}) {}
+''');
+    checkElementText(
+        library,
+        r'''
+void f@5({void Function<U>(int) f@22/*<U@24>*//*(int a@31)*/}) {}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_function_typeParameter() async {
+    var library = await checkLibrary(r'''
+void f<T>() {}
+''');
+    checkElementText(
+        library,
+        r'''
+void f@5<T@7>() {}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_functionTypeAlias_typeParameter() async {
+    var library = await checkLibrary(r'''
+typedef void F<T>();
+''');
+    checkElementText(
+        library,
+        r'''
+typedef F@13<T@15> = void Function();
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_genericTypeAlias_typeParameter() async {
+    var library = await checkLibrary(r'''
+typedef F<T> = void Function();
+''');
+    checkElementText(
+        library,
+        r'''
+typedef F@8<T@10> = void Function();
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_mixin_typeParameter() async {
+    var library = await checkLibrary(r'''
+mixin M<T> {}
+''');
+    checkElementText(
+        library,
+        r'''
+mixin M@6<T@8> on Object {
+}
+''',
+        withOffsets: true);
+  }
+
+  test_nameOffset_unit_getter() async {
+    var library = await checkLibrary(r'''
+int get foo => 0;
+''');
+    checkElementText(
+        library,
+        r'''
+int get foo@8 {}
+''',
+        withOffsets: true);
+  }
+
   test_nested_generic_functions_in_generic_class_with_function_typed_params() async {
     var library = await checkLibrary('''
 class C<T, U> {
@@ -12102,6 +12500,15 @@
 ''');
   }
 
+  test_parameter_typeParameters() async {
+    var library = await checkLibrary(r'''
+void f(T a<T, U>(U u)) {}
+''');
+    checkElementText(library, r'''
+void f(T Function<T, U>(U) a/*<T, U>*//*(U u)*/) {}
+''');
+  }
+
   test_parameterTypeNotInferred_constructor() async {
     // Strong mode doesn't do type inference on constructor parameters, so it's
     // ok that we don't store inferred type info for them in summaries.
@@ -12132,8 +12539,8 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C.positional([dynamic this.x = 1]);
-  C.named({dynamic this.x: 1});
+  C.positional([final dynamic this.x = 1]);
+  C.named({final dynamic this.x: 1});
 }
 ''');
   }
@@ -12540,7 +12947,7 @@
     checkElementText(library, r'''
 class A<T> {
   T value;
-  A(T this.value);
+  A(final T this.value);
 }
 class B {
   A<String> a;
@@ -12558,7 +12965,7 @@
     checkElementText(library, r'''
 class A<T> {
   int f;
-  A(int this.f);
+  A(final int this.f);
 }
 ''');
   }
@@ -12645,7 +13052,7 @@
 }
 class C<T extends A = A> {
   final T f;
-  const C(T this.f);
+  const C(final T this.f);
 }
 final B b;
 final C<B> c;
@@ -13076,6 +13483,18 @@
 ''');
   }
 
+  test_typeAlias_parameter_typeParameters() async {
+    var library = await checkLibrary(r'''
+typedef void F(T a<T, U>(U u));
+''');
+    checkElementText(
+        library,
+        r'''
+typedef F = void Function(T Function<T, U>(U) a/*<covariant T, covariant U>*//*(U u)*/);
+''',
+        withTypeParameterVariance: true);
+  }
+
   test_typeAlias_typeParameters_variance_function_contravariant() async {
     var library = await checkLibrary(r'''
 typedef F<T> = void Function(T);
@@ -14508,7 +14927,7 @@
     expect(variable.isFinal, isTrue);
     expect(variable.getter, same(getter));
     expect('${variable.type}', 'int');
-    expect(variable, same(_elementOfDefiningUnit(library, ['@field', 'x'])));
+    expect(variable, same(_elementOfDefiningUnit(library, ['@variable', 'x'])));
   }
 
   test_variable_implicit_type() async {
@@ -14773,8 +15192,7 @@
     var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
     var reference = unit.reference!;
     names.forEach((name) => reference = reference.getChild(name));
-
-    var elementFactory = unit.linkedContext!.elementFactory;
+    var elementFactory = library.linkedData!.elementFactory;
     return elementFactory.elementOfReference(reference)!;
   }
 }
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index d7828d1..906d2c1 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -1486,7 +1486,7 @@
     checkElementText(library, r'''
 class A {
   int f;
-  A([int this.f = 'hello']);
+  A([final int this.f = 'hello']);
 }
 ''');
   }
diff --git a/tools/VERSION b/tools/VERSION
index 876a727..60d5468 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 101
+PRERELEASE 102
 PRERELEASE_PATCH 0
\ No newline at end of file