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
