diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/library_builder.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/library_builder.dart
new file mode 100644
index 0000000..5acbdc4
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/library_builder.dart
@@ -0,0 +1,667 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/dart/analysis/dependency/node.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+
+/// Build [Library] that describes nodes and dependencies of the library
+/// with the given [uri] and [units].
+///
+/// If the [units] are just parsed, then only token signatures and referenced
+/// names of nodes can be computed. If the [units] are fully resolved, then
+/// also class member references can be recorded.
+Library buildLibrary(
+  Uri uri,
+  List<CompilationUnit> units,
+  ReferenceCollector referenceCollector,
+) {
+  return _LibraryBuilder(uri, units, referenceCollector).build();
+}
+
+/// The `show` or `hide` namespace combinator.
+class Combinator {
+  final bool isShow;
+  final List<String> names;
+
+  Combinator(this.isShow, this.names);
+
+  @override
+  String toString() {
+    if (isShow) {
+      return 'show ' + names.join(', ');
+    } else {
+      return 'hide ' + names.join(', ');
+    }
+  }
+}
+
+/// The `export` directive.
+class Export {
+  /// The absolute URI of the exported library.
+  final Uri uri;
+
+  /// The list of namespace combinators to apply, not `null`.
+  final List<Combinator> combinators;
+
+  Export(this.uri, this.combinators);
+
+  @override
+  String toString() {
+    return 'Export(uri: $uri, combinators: $combinators)';
+  }
+}
+
+/// The `import` directive.
+class Import {
+  /// The absolute URI of the imported library.
+  final Uri uri;
+
+  /// The import prefix, or `null` if not specified.
+  final String prefix;
+
+  /// The list of namespace combinators to apply, not `null`.
+  final List<Combinator> combinators;
+
+  Import(this.uri, this.prefix, this.combinators);
+
+  @override
+  String toString() {
+    return 'Import(uri: $uri, prefix: $prefix, combinators: $combinators)';
+  }
+}
+
+/// The collection of imports, exports, and top-level nodes.
+class Library {
+  /// The absolute URI of the library.
+  final Uri uri;
+
+  /// The list of imports in this library.
+  final List<Import> imports;
+
+  /// The list of exports in this library.
+  final List<Export> exports;
+
+  /// The list of libraries that correspond to the [imports].
+  List<Library> importedLibraries;
+
+  /// The list of top-level nodes defined in the library.
+  ///
+  /// This list is sorted.
+  final List<DependencyNode> declaredNodes;
+
+  /// The map of [declaredNodes], used for fast search.
+  /// TODO(scheglov) consider using binary search instead.
+  final Map<DependencyName, DependencyNode> declaredNodeMap = {};
+
+  /// The list of nodes exported from this library, either using `export`
+  /// directives, or declared in this library.
+  ///
+  /// This list is sorted.
+  List<DependencyNode> exportedNodes;
+
+  /// The map of nodes that are visible in the library, either imported,
+  /// or declared in this library.
+  ///
+  /// TODO(scheglov) support for imports with prefixes
+  Map<String, DependencyNode> libraryScope;
+
+  Library(this.uri, this.imports, this.exports, this.declaredNodes) {
+    for (var node in declaredNodes) {
+      declaredNodeMap[node.name] = node;
+    }
+  }
+
+  @override
+  String toString() => '$uri';
+}
+
+/// The interface for a class that collects information about external nodes
+/// referenced by a node.
+///
+/// The workflow for using it is that the library builder creates a new
+/// instance, fills it with names of import prefixes using [addImportPrefix].
+/// Then for each node defined in the library, methods `appendXyz` called
+/// zero or more times to record references to external names to record API or
+/// implementation dependencies. When all dependencies of a node are appended,
+/// [finish] is invoked to construct the full [DependencyNodeDependencies].
+/// TODO(scheglov) In following CLs we will provide single implementation.
+abstract class ReferenceCollector {
+  final Uri libraryUri;
+
+  ReferenceCollector(this.libraryUri);
+
+  /// Record that the [name] is a name of an import prefix.
+  ///
+  /// So, when we see code like `prefix.foo` we know that `foo` should be
+  /// resolved in the import scope that corresponds to `prefix` (unless the
+  /// name `prefix` is shadowed by a local declaration).
+  void addImportPrefix(String name);
+
+  /// Collect external nodes referenced from the given [node].
+  void appendExpression(Expression node);
+
+  /// Collect external nodes referenced from the given [node].
+  void appendFormalParameters(FormalParameterList node);
+
+  /// Collect external nodes referenced from the given [node].
+  void appendFunctionBody(FunctionBody node);
+
+  /// Collect external nodes referenced from the given [node].
+  void appendTypeAnnotation(TypeAnnotation node);
+
+  /// Construct and return a new [DependencyNodeDependencies] with the given
+  /// [tokenSignature] and all recorded references to external nodes. Clear
+  /// data structures with recorded references and be ready to start recording
+  /// references for a new node.
+  DependencyNodeDependencies finish(List<int> tokenSignature);
+}
+
+class _LibraryBuilder {
+  /// The URI of the library.
+  final Uri uri;
+
+  /// The units of the library, parsed or fully resolved.
+  final List<CompilationUnit> units;
+
+  /// The instance of the referenced names, class members collector.
+  final ReferenceCollector referenceCollector;
+
+  /// The list of imports in the library.
+  final List<Import> imports = [];
+
+  /// The list of exports in the library.
+  final List<Export> exports = [];
+
+  /// The top-level nodes declared in the library.
+  final List<DependencyNode> declaredNodes = [];
+
+  _LibraryBuilder(this.uri, this.units, this.referenceCollector);
+
+  Library build() {
+    _addImports();
+    _addExports();
+
+    // TODO(scheglov) import prefixes are shadowed by class members
+
+    for (var unit in units) {
+      _addUnit(unit);
+    }
+    declaredNodes.sort(DependencyNode.compare);
+
+    return Library(uri, imports, exports, declaredNodes);
+  }
+
+  void _addClassOrMixin(ClassOrMixinDeclaration node) {
+    var hasConstConstructor = node.members.any(
+      (m) => m is ConstructorDeclaration && m.constKeyword != null,
+    );
+
+    List<DependencyNode> classTypeParameters;
+    if (node.typeParameters != null) {
+      classTypeParameters = <DependencyNode>[];
+      for (var typeParameter in node.typeParameters.typeParameters) {
+        classTypeParameters.add(DependencyNode(
+          DependencyName(uri, typeParameter.name.name),
+          DependencyNodeKind.TYPE_PARAMETER,
+          _computeApiDependencies(
+            _computeNodeTokenSignature(typeParameter),
+            typeParameter,
+          ),
+          DependencyNodeDependencies.none,
+        ));
+      }
+      classTypeParameters.sort(DependencyNode.compare);
+    }
+
+    var classMembers = <DependencyNode>[];
+    var hasConstructor = false;
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration) {
+        hasConstructor = true;
+        _addConstructor(classMembers, member);
+      } else if (member is FieldDeclaration) {
+        _addVariables(
+          classMembers,
+          member.metadata,
+          member.fields,
+          hasConstConstructor,
+        );
+      } else if (member is MethodDeclaration) {
+        _addMethod(classMembers, member);
+      } else {
+        throw UnimplementedError('(${member.runtimeType}) $member');
+      }
+    }
+
+    if (!hasConstructor && node is ClassDeclaration) {
+      classMembers.add(DependencyNode(
+        DependencyName(uri, ''),
+        DependencyNodeKind.CONSTRUCTOR,
+        DependencyNodeDependencies.none,
+        DependencyNodeDependencies.none,
+      ));
+    }
+
+    var classTokenSignature = _computeTokenSignature(
+      node.beginToken,
+      node.leftBracket,
+    );
+    // TODO(scheglov) add library URI
+
+    var classNode = DependencyNode(
+      DependencyName(uri, node.name.name),
+      node is MixinDeclaration
+          ? DependencyNodeKind.MIXIN
+          : DependencyNodeKind.CLASS,
+      _computeApiDependencies(classTokenSignature, node),
+      DependencyNodeDependencies.none,
+      classTypeParameters: classTypeParameters,
+    );
+
+    classMembers.sort(DependencyNode.compare);
+    classNode.setClassMembers(classMembers);
+
+    declaredNodes.add(classNode);
+  }
+
+  void _addClassTypeAlias(ClassTypeAlias node) {
+    var tokenSignature = _computeNodeTokenSignature(node);
+    declaredNodes.add(DependencyNode(
+      DependencyName(uri, node.name.name),
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      _computeApiDependencies(tokenSignature, node),
+      DependencyNodeDependencies.none,
+    ));
+  }
+
+  void _addConstructor(
+      List<DependencyNode> classMembers, ConstructorDeclaration node) {
+    var signature = ApiSignature();
+    _appendMetadataTokens(signature, node.metadata);
+    _appendFormalParametersTokens(signature, node.parameters);
+    var tokenSignature = signature.toByteList();
+
+    classMembers.add(DependencyNode(
+      DependencyName(uri, node.name?.name ?? ''),
+      DependencyNodeKind.CONSTRUCTOR,
+      _computeApiDependencies(tokenSignature, node),
+      DependencyNodeDependencies.none,
+    ));
+  }
+
+  void _addEnum(EnumDeclaration node) {
+    var classMembers = <DependencyNode>[];
+    for (var constant in node.constants) {
+      classMembers.add(DependencyNode(
+        DependencyName(uri, constant.name.name),
+        DependencyNodeKind.GETTER,
+        DependencyNodeDependencies.none,
+        DependencyNodeDependencies.none,
+      ));
+    }
+    classMembers.add(DependencyNode(
+      DependencyName(uri, 'index'),
+      DependencyNodeKind.GETTER,
+      DependencyNodeDependencies.none,
+      DependencyNodeDependencies.none,
+    ));
+    classMembers.add(DependencyNode(
+      DependencyName(uri, 'values'),
+      DependencyNodeKind.GETTER,
+      DependencyNodeDependencies.none,
+      DependencyNodeDependencies.none,
+    ));
+    classMembers.sort(DependencyNode.compare);
+
+    var enumNode = DependencyNode(
+      DependencyName(uri, node.name.name),
+      DependencyNodeKind.ENUM,
+      DependencyNodeDependencies.none,
+      DependencyNodeDependencies.none,
+    );
+    enumNode.setClassMembers(classMembers);
+
+    declaredNodes.add(enumNode);
+  }
+
+  /// Fill [exports] with information about exports.
+  void _addExports() {
+    for (var directive in units.first.directives) {
+      if (directive is ExportDirective) {
+        var refUri = directive.uri.stringValue;
+        var importUri = uri.resolve(refUri);
+        var combinators = _getCombinators(directive);
+        exports.add(Export(importUri, combinators));
+      }
+    }
+  }
+
+  void _addFunction(FunctionDeclaration node) {
+    var functionExpression = node.functionExpression;
+
+    var signature = ApiSignature();
+    _appendMetadataTokens(signature, node.metadata);
+    _appendNodeTokens(signature, node.returnType);
+    _appendNodeTokens(signature, functionExpression.typeParameters);
+    _appendFormalParametersTokens(signature, functionExpression.parameters);
+    var tokenSignature = signature.toByteList();
+
+    var rawName = node.name.name;
+    var name = DependencyName(uri, node.isSetter ? '$rawName=' : rawName);
+
+    DependencyNodeKind kind;
+    if (node.isGetter) {
+      kind = DependencyNodeKind.GETTER;
+    } else if (node.isSetter) {
+      kind = DependencyNodeKind.SETTER;
+    } else {
+      kind = DependencyNodeKind.FUNCTION;
+    }
+
+    referenceCollector.appendTypeAnnotation(node.returnType);
+    referenceCollector.appendFormalParameters(
+      node.functionExpression.parameters,
+    );
+    var api = referenceCollector.finish(tokenSignature);
+
+    var bodyNode = node.functionExpression.body;
+    var implTokenSignature = _computeNodeTokenSignature(bodyNode);
+    referenceCollector.appendFunctionBody(bodyNode);
+    var impl = referenceCollector.finish(implTokenSignature);
+
+    declaredNodes.add(DependencyNode(name, kind, api, impl));
+  }
+
+  void _addFunctionTypeAlias(FunctionTypeAlias node) {
+    var signature = ApiSignature();
+    _appendMetadataTokens(signature, node.metadata);
+    _appendNodeTokens(signature, node.typeParameters);
+    _appendNodeTokens(signature, node.returnType);
+    _appendFormalParametersTokens(signature, node.parameters);
+    var tokenSignature = signature.toByteList();
+
+    declaredNodes.add(DependencyNode(
+      DependencyName(uri, node.name.name),
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      _computeApiDependencies(tokenSignature, node),
+      DependencyNodeDependencies.none,
+    ));
+  }
+
+  void _addGenericTypeAlias(GenericTypeAlias node) {
+    var functionType = node.functionType;
+
+    var signature = ApiSignature();
+    _appendMetadataTokens(signature, node.metadata);
+    _appendNodeTokens(signature, node.typeParameters);
+    _appendNodeTokens(signature, functionType.returnType);
+    _appendNodeTokens(signature, functionType.typeParameters);
+    _appendFormalParametersTokens(signature, functionType.parameters);
+    var tokenSignature = signature.toByteList();
+
+    declaredNodes.add(DependencyNode(
+      DependencyName(uri, node.name.name),
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      _computeApiDependencies(tokenSignature, node),
+      DependencyNodeDependencies.none,
+    ));
+  }
+
+  /// Fill [imports] with information about imports.
+  void _addImports() {
+    var hasDartCoreImport = false;
+    for (var directive in units.first.directives) {
+      if (directive is ImportDirective) {
+        var refUri = directive.uri.stringValue;
+        var importUri = uri.resolve(refUri);
+
+        if (importUri.toString() == 'dart:core') {
+          hasDartCoreImport = true;
+        }
+
+        var combinators = _getCombinators(directive);
+
+        imports.add(Import(importUri, directive.prefix?.name, combinators));
+
+        if (directive.prefix != null) {
+          referenceCollector.addImportPrefix(directive.prefix.name);
+        }
+      }
+    }
+
+    if (!hasDartCoreImport) {
+      imports.add(Import(Uri.parse('dart:core'), null, []));
+    }
+  }
+
+  void _addMethod(List<DependencyNode> classMembers, MethodDeclaration node) {
+    var signature = ApiSignature();
+    _appendMetadataTokens(signature, node.metadata);
+    _appendNodeTokens(signature, node.returnType);
+    _appendNodeTokens(signature, node.typeParameters);
+    _appendFormalParametersTokens(signature, node.parameters);
+    var tokenSignature = signature.toByteList();
+
+    DependencyNodeKind kind;
+    if (node.isGetter) {
+      kind = DependencyNodeKind.GETTER;
+    } else if (node.isSetter) {
+      kind = DependencyNodeKind.SETTER;
+    } else {
+      kind = DependencyNodeKind.METHOD;
+    }
+
+    referenceCollector.appendTypeAnnotation(node.returnType);
+    referenceCollector.appendFormalParameters(node.parameters);
+    var api = referenceCollector.finish(tokenSignature);
+
+    var implTokenSignature = _computeNodeTokenSignature(node.body);
+    referenceCollector.appendFunctionBody(node.body);
+    var impl = referenceCollector.finish(implTokenSignature);
+
+    classMembers.add(
+        DependencyNode(DependencyName(uri, node.name.name), kind, api, impl));
+  }
+
+  void _addUnit(CompilationUnit unit) {
+    for (var declaration in unit.declarations) {
+      if (declaration is ClassOrMixinDeclaration) {
+        _addClassOrMixin(declaration);
+      } else if (declaration is ClassTypeAlias) {
+        _addClassTypeAlias(declaration);
+      } else if (declaration is EnumDeclaration) {
+        _addEnum(declaration);
+      } else if (declaration is FunctionDeclaration) {
+        _addFunction(declaration);
+      } else if (declaration is FunctionTypeAlias) {
+        _addFunctionTypeAlias(declaration);
+      } else if (declaration is GenericTypeAlias) {
+        _addGenericTypeAlias(declaration);
+      } else if (declaration is TopLevelVariableDeclaration) {
+        _addVariables(
+          declaredNodes,
+          declaration.metadata,
+          declaration.variables,
+          false,
+        );
+      } else {
+        throw UnimplementedError('(${declaration.runtimeType}) $declaration');
+      }
+    }
+  }
+
+  void _addVariables(
+      List<DependencyNode> variableNodes,
+      List<Annotation> metadata,
+      VariableDeclarationList variables,
+      bool appendInitializerToApi) {
+    if (variables.isConst || variables.type == null) {
+      appendInitializerToApi = true;
+    }
+
+    for (var variable in variables.variables) {
+      var signature = ApiSignature();
+      signature.addInt(variables.isConst ? 1 : 0); // const flag
+      _appendMetadataTokens(signature, metadata);
+
+      _appendNodeTokens(signature, variables.type);
+      referenceCollector.appendTypeAnnotation(variables.type);
+
+      if (appendInitializerToApi) {
+        _appendNodeTokens(signature, variable.initializer);
+        referenceCollector.appendExpression(variable.initializer);
+      }
+
+      var tokenSignature = signature.toByteList();
+      var api = referenceCollector.finish(tokenSignature);
+
+      var rawName = variable.name.name;
+      variableNodes.add(
+        DependencyNode(
+          DependencyName(uri, rawName),
+          DependencyNodeKind.GETTER,
+          api,
+          DependencyNodeDependencies.none,
+        ),
+      );
+      if (!variables.isConst && !variables.isFinal) {
+        variableNodes.add(
+          DependencyNode(
+            DependencyName(uri, '$rawName='),
+            DependencyNodeKind.SETTER,
+            api,
+            DependencyNodeDependencies.none,
+          ),
+        );
+      }
+    }
+  }
+
+  /// Append tokens of the given [parameters] to the [signature].
+  static void _appendFormalParametersTokens(
+      ApiSignature signature, FormalParameterList parameters) {
+    if (parameters == null) return;
+
+    for (var parameter in parameters.parameters) {
+      if (parameter.isRequired) {
+        signature.addInt(1);
+      } else if (parameter.isOptionalPositional) {
+        signature.addInt(2);
+      } else {
+        signature.addInt(3);
+      }
+
+      // If a simple not named parameter, we don't need its name.
+      // We should be careful to include also annotations.
+      if (parameter is SimpleFormalParameter && parameter.type != null) {
+        _appendTokens(
+          signature,
+          parameter.beginToken,
+          parameter.type.endToken,
+        );
+        continue;
+      }
+
+      // We don't know anything better than adding the whole parameter.
+      _appendNodeTokens(signature, parameter);
+    }
+  }
+
+  static void _appendMetadataTokens(
+      ApiSignature signature, List<Annotation> metadata) {
+    if (metadata != null) {
+      for (var annotation in metadata) {
+        _appendNodeTokens(signature, annotation);
+      }
+    }
+  }
+
+  /// Append tokens of the given [node] to the [signature].
+  static void _appendNodeTokens(ApiSignature signature, AstNode node) {
+    if (node != null) {
+      _appendTokens(signature, node.beginToken, node.endToken);
+    }
+  }
+
+  /// Append tokens from [begin] to [end] (both including) to the [signature].
+  static void _appendTokens(ApiSignature signature, Token begin, Token end) {
+    if (begin is CommentToken) {
+      begin = (begin as CommentToken).parent;
+    }
+
+    Token token = begin;
+    while (token != null) {
+      signature.addString(token.lexeme);
+
+      if (token == end) {
+        break;
+      }
+
+      var nextToken = token.next;
+      if (nextToken == token) {
+        break;
+      }
+
+      token = nextToken;
+    }
+  }
+
+  /// TODO(scheglov) Replace all uses with [referenceCollector].
+  static DependencyNodeDependencies _computeApiDependencies(
+      List<int> tokenSignature, AstNode node,
+      [AstNode node2]) {
+    List<String> importPrefixes = [];
+    List<String> unprefixedReferencedNames = [];
+    List<List<String>> importPrefixedReferencedNames = [];
+    return DependencyNodeDependencies(
+      tokenSignature,
+      unprefixedReferencedNames,
+      importPrefixes,
+      importPrefixedReferencedNames,
+      const [],
+    );
+  }
+
+  /// Return the signature for all tokens of the [node].
+  static List<int> _computeNodeTokenSignature(AstNode node) {
+    if (node == null) {
+      return const <int>[];
+    }
+    return _computeTokenSignature(node.beginToken, node.endToken);
+  }
+
+  /// Return the signature for tokens from [begin] to [end] (both including).
+  static List<int> _computeTokenSignature(Token begin, Token end) {
+    var signature = ApiSignature();
+    _appendTokens(signature, begin, end);
+    return signature.toByteList();
+  }
+
+  /// Return [Combinator]s for the given import or export [directive].
+  static List<Combinator> _getCombinators(NamespaceDirective directive) {
+    var combinators = <Combinator>[];
+    for (var combinator in directive.combinators) {
+      if (combinator is ShowCombinator) {
+        combinators.add(
+          Combinator(
+            true,
+            combinator.shownNames.map((id) => id.name).toList(),
+          ),
+        );
+      }
+      if (combinator is HideCombinator) {
+        combinators.add(
+          Combinator(
+            false,
+            combinator.hiddenNames.map((id) => id.name).toList(),
+          ),
+        );
+      }
+    }
+    return combinators;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/node.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/node.dart
new file mode 100644
index 0000000..e3de954
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/node.dart
@@ -0,0 +1,248 @@
+// Copyright (c) 2018, 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/src/generated/utilities_general.dart';
+import 'package:convert/convert.dart';
+
+/// The reference to a class member.
+class ClassMemberReference {
+  /// The target class name.
+  ///
+  /// This is different from the class that actually turned out to define
+  /// the referenced member at the time of recording this reference. So, we
+  /// will notice added overrides in the target class, or anywhere in between.
+  final DependencyName target;
+
+  /// Whether the explicit `super` was used as the target.
+  /// The [target] is the enclosing class.
+  final bool targetSuper;
+
+  /// The name referenced in the [target].
+  final String name;
+
+  @override
+  final int hashCode;
+
+  ClassMemberReference(this.target, this.targetSuper, this.name)
+      : hashCode = JenkinsSmiHash.hash2(target.hashCode, name.hashCode);
+
+  @override
+  bool operator ==(other) {
+    return other is ClassMemberReference &&
+        other.target == target &&
+        other.targetSuper == targetSuper &&
+        other.name == name;
+  }
+
+  @override
+  String toString() {
+    return '($target, $name, super: $targetSuper)';
+  }
+
+  static int compare(ClassMemberReference first, ClassMemberReference second) {
+    var result = DependencyName.compare(first.target, second.target);
+    if (result != 0) return result;
+
+    if (first.targetSuper && !second.targetSuper) return -1;
+    if (!first.targetSuper && second.targetSuper) return 1;
+
+    return first.name.compareTo(second.name);
+  }
+}
+
+/// A name qualified by a library URI.
+class DependencyName {
+  /// The URI of the defining library.
+  /// Not `null`.
+  final Uri libraryUri;
+
+  /// The name of this name object.
+  /// If the name starts with `_`, then the name is private.
+  /// Names of setters end with `=`.
+  final String name;
+
+  /// Whether this name is private, and its [name] starts with `_`.
+  final bool isPrivate;
+
+  /// The cached, pre-computed hash code.
+  @override
+  final int hashCode;
+
+  factory DependencyName(Uri libraryUri, String name) {
+    var isPrivate = name.startsWith('_');
+    var hashCode = JenkinsSmiHash.hash2(libraryUri.hashCode, name.hashCode);
+    return DependencyName._internal(libraryUri, name, isPrivate, hashCode);
+  }
+
+  DependencyName._internal(
+      this.libraryUri, this.name, this.isPrivate, this.hashCode);
+
+  @override
+  bool operator ==(Object other) {
+    return other is DependencyName &&
+        other.hashCode == hashCode &&
+        name == other.name &&
+        libraryUri == other.libraryUri;
+  }
+
+  /// Whether this name us accessible for the library with the given
+  /// [libraryUri], i.e. when the name is public, or is defined in a library
+  /// with the same URI.
+  bool isAccessibleFor(Uri libraryUri) {
+    return !isPrivate || this.libraryUri == libraryUri;
+  }
+
+  @override
+  String toString() => '$libraryUri::$name';
+
+  /// Compare given names by their raw names.
+  ///
+  /// This method should be used only for sorting, it does not follow the
+  /// complete semantics of [==] and [hashCode].
+  static int compare(DependencyName first, DependencyName second) {
+    return first.name.compareTo(second.name);
+  }
+}
+
+/// A dependency node - anything that has a name, and can be referenced.
+class DependencyNode {
+  /// The API or implementation signature used in [DependencyNodeDependencies]
+  /// as a marker that this node is changed, explicitly because its token
+  /// signature changed, or implicitly - because it references a changed node.
+  static final changedSignature = Uint8List.fromList([0xDE, 0xAD, 0xBE, 0xEF]);
+
+  final DependencyName name;
+  final DependencyNodeKind kind;
+
+  /// Dependencies that affect the API of the node, so affect API or
+  /// implementation dependencies of the nodes that use this node.
+  final DependencyNodeDependencies api;
+
+  /// Additional (to the [api]) dependencies that affect only the
+  /// "implementation" of the node, e.g. the body of a method, but are not
+  /// visible outside of the node, and so don't affect any other nodes.
+  final DependencyNodeDependencies impl;
+
+  /// If the node is a class member, the node of the enclosing class.
+  /// Otherwise `null`.
+  final DependencyNode enclosingClass;
+
+  /// If the node is a class, the nodes of its type parameters.
+  /// Otherwise `null`.
+  final List<DependencyNode> classTypeParameters;
+
+  /// If the node is a class, the sorted list of members in this class.
+  /// Otherwise `null`.
+  List<DependencyNode> classMembers;
+
+  DependencyNode(
+    this.name,
+    this.kind,
+    this.api,
+    this.impl, {
+    this.enclosingClass,
+    this.classTypeParameters,
+  });
+
+  /// Return the node that can be referenced by the given [name] from the
+  /// library with the given [libraryUri].
+  DependencyNode getClassMember(Uri libraryUri, String name) {
+    // TODO(scheglov) The list is sorted, use this fact to search faster.
+    // TODO(scheglov) Collect superclass members here or outside.
+    for (var i = 0; i < classMembers.length; ++i) {
+      var member = classMembers[i];
+      var memberName = member.name;
+      if (memberName.name == name && memberName.isAccessibleFor(libraryUri)) {
+        return member;
+      }
+    }
+    return null;
+  }
+
+  /// Set new class members for this class.
+  void setClassMembers(List<DependencyNode> newClassMembers) {
+    classMembers = newClassMembers;
+  }
+
+  @override
+  String toString() {
+    if (enclosingClass != null) {
+      return '$enclosingClass::${name.name}';
+    }
+    return name.toString();
+  }
+
+  /// Compare given nodes by their names.
+  static int compare(DependencyNode first, DependencyNode second) {
+    return DependencyName.compare(first.name, second.name);
+  }
+}
+
+/// The dependencies of the API or implementation portion of a node.
+class DependencyNodeDependencies {
+  static final none = DependencyNodeDependencies([], [], [], [], []);
+
+  /// The token signature of this portion of the node. It depends on all
+  /// tokens that might affect the node API or implementation resolution.
+  final List<int> tokenSignature;
+
+  /// The names that appear unprefixed in this portion of the node, and are
+  /// not defined locally in the node. Locally defined names themselves
+  /// depend on some non-local nodes, which will also recorded here.
+  ///
+  /// This list is sorted.
+  final List<String> unprefixedReferencedNames;
+
+  /// The names of import prefixes used to reference names in this node.
+  ///
+  /// This list is sorted.
+  final List<String> importPrefixes;
+
+  /// The names referenced by this node with the import prefix at the
+  /// corresponding index in [importPrefixes].
+  ///
+  /// This list is sorted.
+  final List<List<String>> importPrefixedReferencedNames;
+
+  /// The class members referenced in this portion of the node.
+  ///
+  /// This list is sorted.
+  final List<ClassMemberReference> classMemberReferences;
+
+  /// All referenced nodes, computed from [unprefixedReferencedNames],
+  /// [importPrefixedReferencedNames], and [classMemberReferences].
+  List<DependencyNode> referencedNodes;
+
+  /// The transitive signature of this portion of the node, computed using
+  /// the [tokenSignature] of this node, and API signatures of the
+  /// [referencedNodes].
+  List<int> transitiveSignature;
+
+  DependencyNodeDependencies(
+      this.tokenSignature,
+      this.unprefixedReferencedNames,
+      this.importPrefixes,
+      this.importPrefixedReferencedNames,
+      this.classMemberReferences);
+
+  String get tokenSignatureHex => hex.encode(tokenSignature);
+}
+
+/// Kinds of nodes.
+enum DependencyNodeKind {
+  CLASS,
+  CLASS_TYPE_ALIAS,
+  CONSTRUCTOR,
+  ENUM,
+  FUNCTION,
+  FUNCTION_TYPE_ALIAS,
+  GENERIC_TYPE_ALIAS,
+  GETTER,
+  METHOD,
+  MIXIN,
+  SETTER,
+  TYPE_PARAMETER,
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/dependency/base.dart b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
new file mode 100644
index 0000000..8df8a047
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/dependency/library_builder.dart';
+import 'package:analyzer/src/dart/analysis/dependency/node.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+import '../../resolution/driver_resolution.dart';
+
+class BaseDependencyTest extends DriverResolutionTest {
+//  DependencyTracker tracker;
+  String a;
+  String b;
+  String c;
+  Uri aUri;
+  Uri bUri;
+  Uri cUri;
+
+  bool hasDartCore = false;
+
+  void assertNodes(
+    List<DependencyNode> actualNodes,
+    List<ExpectedNode> expectedNodes,
+  ) {
+    expect(actualNodes, hasLength(expectedNodes.length));
+    for (var expectedNode in expectedNodes) {
+      var topNode = _getNode(
+        actualNodes,
+        uri: expectedNode.uri,
+        name: expectedNode.name,
+        kind: expectedNode.kind,
+      );
+
+      if (expectedNode.classMembers != null) {
+        assertNodes(topNode.classMembers, expectedNode.classMembers);
+      } else {
+        expect(topNode.classMembers, isNull);
+      }
+
+      if (expectedNode.classTypeParameters != null) {
+        assertNodes(
+          topNode.classTypeParameters,
+          expectedNode.classTypeParameters,
+        );
+      } else {
+        expect(topNode.classTypeParameters, isNull);
+      }
+    }
+  }
+
+  Future<Library> buildTestLibrary(String path, String content) async {
+//    if (!hasDartCore) {
+//      hasDartCore = true;
+//      await _addLibraryByUri('dart:core');
+//      await _addLibraryByUri('dart:async');
+//      await _addLibraryByUri('dart:math');
+//      await _addLibraryByUri('dart:_internal');
+//    }
+
+    newFile(path, content: content);
+    driver.changeFile(path);
+
+    var units = await _resolveLibrary(path);
+    var uri = units.first.declaredElement.source.uri;
+
+    return buildLibrary(uri, units, _ReferenceCollector());
+
+//    tracker.addLibrary(uri, units);
+//
+//    var library = tracker.libraries[uri];
+//    expect(library, isNotNull);
+//
+//    return library;
+  }
+
+  DependencyNode getNode(Library library,
+      {@required Uri uri,
+      @required String name,
+      DependencyNodeKind kind,
+      String memberOf,
+      String typeParameterOf}) {
+    var nodes = library.declaredNodes;
+    if (memberOf != null) {
+      var class_ = _getNode(nodes, uri: aUri, name: memberOf);
+      expect(class_.kind,
+          anyOf(DependencyNodeKind.CLASS, DependencyNodeKind.MIXIN));
+      nodes = class_.classMembers;
+    } else if (typeParameterOf != null) {
+      var class_ = _getNode(nodes, uri: aUri, name: typeParameterOf);
+      expect(class_.kind,
+          anyOf(DependencyNodeKind.CLASS, DependencyNodeKind.MIXIN));
+      nodes = class_.classTypeParameters;
+    }
+    return _getNode(nodes, uri: aUri, name: name, kind: kind);
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+//    var logger = PerformanceLog(null);
+//    tracker = DependencyTracker(logger);
+    a = convertPath('/test/lib/a.dart');
+    b = convertPath('/test/lib/b.dart');
+    c = convertPath('/test/lib/c.dart');
+    aUri = Uri.parse('package:test/a.dart');
+    bUri = Uri.parse('package:test/b.dart');
+    cUri = Uri.parse('package:test/c.dart');
+  }
+
+//  Future _addLibraryByUri(String uri) async {
+//    var path = driver.sourceFactory.forUri(uri).fullName;
+//    var unitResult = await driver.getUnitElement(path);
+//
+//    var signature = ApiSignature();
+//    signature.addString(unitResult.signature);
+//    var signatureBytes = signature.toByteList();
+//
+//    tracker.addLibraryElement(unitResult.element.library, signatureBytes);
+//  }
+
+  DependencyNode _getNode(List<DependencyNode> nodes,
+      {@required Uri uri, @required String name, DependencyNodeKind kind}) {
+    var nameObj = DependencyName(uri, name);
+    for (var node in nodes) {
+      if (node.name == nameObj) {
+        if (kind != null && node.kind != kind) {
+          fail('Expected $kind "$name", found ${node.kind}');
+        }
+        return node;
+      }
+    }
+    fail('Expected to find $uri::$name in:\n    ${nodes.join('\n    ')}');
+  }
+
+  Future<List<CompilationUnit>> _resolveLibrary(String libraryPath) async {
+    var resolvedLibrary = await driver.getResolvedLibrary(libraryPath);
+    return resolvedLibrary.units.map((ru) => ru.unit).toList();
+  }
+}
+
+class ExpectedNode {
+  final Uri uri;
+  final String name;
+  final DependencyNodeKind kind;
+  final List<ExpectedNode> classMembers;
+  final List<ExpectedNode> classTypeParameters;
+
+  ExpectedNode(
+    this.uri,
+    this.name,
+    this.kind, {
+    this.classMembers,
+    this.classTypeParameters,
+  });
+}
+
+/// TODO(scheglov) remove it once we get actual implementation
+class _ReferenceCollector implements ReferenceCollector {
+  @override
+  Uri get libraryUri => null;
+
+  @override
+  void addImportPrefix(String name) {}
+
+  @override
+  void appendExpression(Expression node) {}
+
+  @override
+  void appendFormalParameters(FormalParameterList formalParameterList) {}
+
+  @override
+  void appendFunctionBody(FunctionBody node) {}
+
+  @override
+  void appendTypeAnnotation(TypeAnnotation node) {}
+
+  @override
+  DependencyNodeDependencies finish(List<int> tokenSignature) {
+    return DependencyNodeDependencies(tokenSignature, [], [], [], []);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/dependency/declared_nodes_test.dart b/pkg/analyzer/test/src/dart/analysis/dependency/declared_nodes_test.dart
new file mode 100644
index 0000000..fec1f34
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/dependency/declared_nodes_test.dart
@@ -0,0 +1,1709 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/dependency/library_builder.dart'
+    hide buildLibrary;
+import 'package:analyzer/src/dart/analysis/dependency/node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DeclaredNodesTest);
+  });
+}
+
+@reflectiveTest
+class DeclaredNodesTest extends BaseDependencyTest {
+  test_class_constructor() async {
+    var library = await buildTestLibrary(a, r'''
+class C {
+  C();
+  C.named();
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'C',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'named', DependencyNodeKind.CONSTRUCTOR),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_constructor_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo();  }',
+      'class X {  @deprecated X.foo();  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_api_tokens_notSame_parameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo();  }',
+      'class X {  X.foo(int a);  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_api_tokens_notSame_parameter_name_edit_named() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo({int a});  }',
+      'class X {  X.foo({int b});  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_api_tokens_notSame_parameter_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo(int a);  }',
+      'class X {  X.foo(double a);  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo() { print(1); }  }',
+      'class X {  X.foo() { print(2); }  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_api_tokens_same_body_add() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo();  }',
+      'class X {  X.foo() {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_api_tokens_same_parameter_name_edit_required() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.CONSTRUCTOR,
+      'class X {  X.foo(int a);  }',
+      'class X {  X.foo(int b);  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_constructor_default() async {
+    var library = await buildTestLibrary(a, r'''
+class C {}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'C',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_field() async {
+    var library = await buildTestLibrary(a, r'''
+class C {
+  int a = 1;
+  int b = 2, c = 3;
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'C',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'a', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'b', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'c', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'a=', DependencyNodeKind.SETTER),
+          ExpectedNode(aUri, 'b=', DependencyNodeKind.SETTER),
+          ExpectedNode(aUri, 'c=', DependencyNodeKind.SETTER),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_field_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  int foo = 0;  }',
+      'class X {  @deprecated int foo = 0;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_api_tokens_notSame_const() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  int foo = 0;  }',
+      'class X {  const int foo = 0;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_api_tokens_same_final() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  int foo = 0;  }',
+      'class X {  final int foo = 0;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_api_tokens_typed_notSame_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  int foo = 0;  }',
+      'class X {  num foo = 1;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_api_tokens_typed_same_initializer() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  int foo = 0;  }',
+      'class X {  int foo = 1;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_api_tokens_untyped_notSame_initializer() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  var foo = 0;  }',
+      'class X {  var foo = 1.0;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_const() async {
+    var library = await buildTestLibrary(a, r'''
+class X {
+  const foo = 1;
+  const bar = 2;
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'X',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_field_const_api_tokens_typed_notSame_initializer() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  const int foo = 0;  }',
+      'class X {  const int foo = 1;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_final() async {
+    var library = await buildTestLibrary(a, r'''
+class X {
+  final foo = 1;
+  final bar = 2;
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'X',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_field_final_api_tokens_typed_notSame_initializer_constClass() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  final int foo = 0;  const X();  }',
+      'class X {  final int foo = 1;  const X();  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_final_api_tokens_typed_same_initializer() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  final int foo = 0;  }',
+      'class X {  final int foo = 1;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_field_final_api_tokens_untyped_notSame_initializer() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  final foo = 0;  }',
+      'class X {  final foo = 1.0;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_getter() async {
+    var library = await buildTestLibrary(a, r'''
+class C {
+  int get foo => 0;
+  int get bar => 0;
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'C',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_getter_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'class X {  int get foo => null;  }',
+      'class X {  double get foo => null;  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method() async {
+    var library = await buildTestLibrary(a, r'''
+class C {
+  void foo() {}
+  void bar() {}
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'C',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'foo', DependencyNodeKind.METHOD),
+          ExpectedNode(aUri, 'bar', DependencyNodeKind.METHOD),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_method_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo() {}  }',
+      'class X {  @deprecated void foo() {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_notSame_parameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo() {}  }',
+      'class X {  void foo(int a) {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_notSame_parameter_name_edit_named() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo({int a}) {}  }',
+      'class X {  void foo({int b}) {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_notSame_parameter_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo(int a) {}  }',
+      'class X {  void foo(double a) {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  int foo() {}  }',
+      'class X {  double foo() {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo() {}  }',
+      'class X {  void foo<T>() {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo<T>() {}  }',
+      'class X {  void foo<T extends num>() {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_same_async_add() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  foo() {}  }',
+      'class X {  foo() async {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo() { print(1); }  }',
+      'class X {  void foo() { print(2); }  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_method_api_tokens_same_parameter_name_edit_required() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.METHOD,
+      'class X {  void foo(int a) {}  }',
+      'class X {  void foo(int b) {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_setter() async {
+    var library = await buildTestLibrary(a, r'''
+class C {
+  set foo(_) {}
+  set bar(_) {}
+}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'C',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+          ExpectedNode(aUri, 'foo', DependencyNodeKind.SETTER),
+          ExpectedNode(aUri, 'bar', DependencyNodeKind.SETTER),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_setter_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.SETTER,
+      'class X {  set foo(int a) {}  }',
+      'class X {  set foo(double a) {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_setter_api_tokens_same_parameter_name() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.SETTER,
+      'class X {  set foo(int a) {}  }',
+      'class X {  set foo(int b) {}  }',
+      memberOf: 'X',
+    );
+  }
+
+  test_class_typeParameter() async {
+    var library = await buildTestLibrary(a, r'''
+class A<T> {}
+class B<T, U> {}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'A',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+        ],
+        classTypeParameters: [
+          ExpectedNode(aUri, 'T', DependencyNodeKind.TYPE_PARAMETER),
+        ],
+      ),
+      ExpectedNode(
+        aUri,
+        'B',
+        DependencyNodeKind.CLASS,
+        classMembers: [
+          ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+        ],
+        classTypeParameters: [
+          ExpectedNode(aUri, 'T', DependencyNodeKind.TYPE_PARAMETER),
+          ExpectedNode(aUri, 'U', DependencyNodeKind.TYPE_PARAMETER),
+        ],
+      ),
+    ]);
+  }
+
+  test_class_typeParameter_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'T',
+      DependencyNodeKind.TYPE_PARAMETER,
+      'class X<T> {}',
+      'class X<@deprecate T> {}',
+      typeParameterOf: 'X',
+    );
+  }
+
+  test_class_typeParameter_api_tokens_notSame_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'T',
+      DependencyNodeKind.TYPE_PARAMETER,
+      'class X<T> {}',
+      'class X<T extends num> {}',
+      typeParameterOf: 'X',
+    );
+  }
+
+  test_class_typeParameter_api_tokens_notSame_bound_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'T',
+      DependencyNodeKind.TYPE_PARAMETER,
+      'class X<T extends num> {}',
+      'class X<T extends int> {}',
+      typeParameterOf: 'X',
+    );
+  }
+
+  test_library_export() async {
+    var library = await buildTestLibrary(a, r'''
+export 'dart:math';
+export 'package:aaa/aaa.dart';
+export 'package:bbb/bbb.dart' show b1, b2 hide b3;
+''');
+    _assertExports(library, [
+      Export(Uri.parse('dart:math'), []),
+      Export(Uri.parse('package:aaa/aaa.dart'), []),
+      Export(Uri.parse('package:bbb/bbb.dart'), [
+        Combinator(true, ['b1', 'b2']),
+        Combinator(false, ['b3']),
+      ]),
+    ]);
+  }
+
+  test_library_import() async {
+    var library = await buildTestLibrary(a, r'''
+import 'dart:math';
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart' as b;
+import 'package:ccc/ccc.dart' show c1, c2 hide c3;
+''');
+    _assertImports(library, [
+      Import(Uri.parse('dart:math'), null, []),
+      Import(Uri.parse('package:aaa/aaa.dart'), null, []),
+      Import(Uri.parse('package:bbb/bbb.dart'), 'b', []),
+      Import(Uri.parse('package:ccc/ccc.dart'), null, [
+        Combinator(true, ['c1', 'c2']),
+        Combinator(false, ['c3']),
+      ]),
+      Import(Uri.parse('dart:core'), null, []),
+    ]);
+  }
+
+  test_library_import_core_explicit() async {
+    var library = await buildTestLibrary(a, r'''
+import 'dart:core' hide List;
+''');
+    _assertImports(library, [
+      Import(Uri.parse('dart:core'), null, [
+        Combinator(false, ['List']),
+      ]),
+    ]);
+  }
+
+  test_library_import_core_implicit() async {
+    var library = await buildTestLibrary(a, '');
+    _assertImports(library, [
+      Import(Uri.parse('dart:core'), null, []),
+    ]);
+  }
+
+  test_unit_class() async {
+    var library = await buildTestLibrary(a, r'''
+class Foo {}
+class Bar {}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'Foo', DependencyNodeKind.CLASS, classMembers: [
+        ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+      ]),
+      ExpectedNode(aUri, 'Bar', DependencyNodeKind.CLASS, classMembers: [
+        ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+      ]),
+    ]);
+  }
+
+  test_unit_class_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X {}',
+      '@deprecated class X {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_extends_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X {}',
+      'class X extends A {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_extends_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X extends A {}',
+      'class X extends B {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_extends_replace() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X extends A {}',
+      'class X implements A {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_extends_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X extends A {}',
+      'class X extends A<int> {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_implements_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X {}',
+      'class X implements A {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_implements_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X implements A {}',
+      'class X implements B {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_implements_remove() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X implements A {}',
+      'class X {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_implements_remove2() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X implements A, B {}',
+      'class X implements B {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_implements_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X implements A {}',
+      'class X implements A<int> {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X {}',
+      'class X<T> {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_typeParameter_add2() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X<T> {}',
+      'class X<T, U> {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X<T> {}',
+      'class X<T extends num> {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_with_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X extends A {}',
+      'class X extends A with B {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_with_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X extends A with B {}',
+      'class X extends A with C {}',
+    );
+  }
+
+  test_unit_class_api_tokens_notSame_with_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X extends A with B {}',
+      'class X extends A with B<int> {}',
+    );
+  }
+
+  test_unit_class_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'X',
+      DependencyNodeKind.CLASS,
+      'class X {  }',
+      'class X { void foo() {} }',
+    );
+  }
+
+  test_unit_classTypeAlias() async {
+    var library = await buildTestLibrary(a, r'''
+class X = Object with M;
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'X', DependencyNodeKind.CLASS_TYPE_ALIAS),
+    ]);
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_implements_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X = A with M implements I;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_implements_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M implements I;',
+      'class X = A with M implements J;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_implements_remove() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M implements I;',
+      'class X = A with M;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_implements_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M implements I;',
+      'class X = A with M implements I<int>;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_super() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X = B with M;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_super_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X = A<int> with M;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X<T> = A with M;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_typeParameter_add2() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X<T> = A with M;',
+      'class X<T, U> = A with M;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X<T> = A with M;',
+      'class X<T extends num> = A with M;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_with_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X = A with M, N;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_with_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X = A with N;',
+    );
+  }
+
+  test_unit_classTypeAlias_api_tokens_notSame_with_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.CLASS_TYPE_ALIAS,
+      'class X = A with M;',
+      'class X = A with M<int>;',
+    );
+  }
+
+  test_unit_enumDeclaration() async {
+    var library = await buildTestLibrary(a, r'''
+enum Foo {a, b, c}
+enum Bar {d, e, f}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(
+        aUri,
+        'Foo',
+        DependencyNodeKind.ENUM,
+        classMembers: [
+          ExpectedNode(aUri, 'a', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'b', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'c', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'index', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'values', DependencyNodeKind.GETTER),
+        ],
+      ),
+      ExpectedNode(
+        aUri,
+        'Bar',
+        DependencyNodeKind.ENUM,
+        classMembers: [
+          ExpectedNode(aUri, 'd', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'e', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'f', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'index', DependencyNodeKind.GETTER),
+          ExpectedNode(aUri, 'values', DependencyNodeKind.GETTER),
+        ],
+      ),
+    ]);
+  }
+
+  test_unit_function() async {
+    var library = await buildTestLibrary(a, r'''
+void foo() {}
+void bar() {}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'foo', DependencyNodeKind.FUNCTION),
+      ExpectedNode(aUri, 'bar', DependencyNodeKind.FUNCTION),
+    ]);
+  }
+
+  test_unit_function_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo() {}',
+      '@deprecated void foo() {}',
+    );
+  }
+
+  test_unit_function_api_tokens_notSame_parameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo() {}',
+      'void foo(int a) {}',
+    );
+  }
+
+  test_unit_function_api_tokens_notSame_parameter_name_edit_named() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo({int a}) {}',
+      'void foo({int b}) {}',
+    );
+  }
+
+  test_unit_function_api_tokens_notSame_parameter_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo(int a) {}',
+      'void foo(double a) {}',
+    );
+  }
+
+  test_unit_function_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'int foo() {}',
+      'num foo() {}',
+    );
+  }
+
+  test_unit_function_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo() {}',
+      'void foo<T>() {}',
+    );
+  }
+
+  test_unit_function_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo<T>() {}',
+      'void foo<T extends num>() {}',
+    );
+  }
+
+  test_unit_function_api_tokens_same_async_add() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'foo() {}',
+      'foo() async {}',
+    );
+  }
+
+  test_unit_function_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo() { print(1); }',
+      'void foo() { print(2); }',
+    );
+  }
+
+  test_unit_function_api_tokens_same_parameter_name_edit_required() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'void foo(int a) {}',
+      'void foo(int b) {}',
+    );
+  }
+
+  test_unit_function_api_tokens_same_syncStar_add() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.FUNCTION,
+      'foo() {}',
+      'foo() sync* {}',
+    );
+  }
+
+  test_unit_functionTypeAlias() async {
+    var library = await buildTestLibrary(a, r'''
+typedef void Foo();
+typedef void Bar();
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'Foo', DependencyNodeKind.FUNCTION_TYPE_ALIAS),
+      ExpectedNode(aUri, 'Bar', DependencyNodeKind.FUNCTION_TYPE_ALIAS),
+    ]);
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo();',
+      '@deprecated typedef void Foo();',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_parameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo();',
+      'typedef void Foo(int a);',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_parameter_name_edit_named() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo({int a});',
+      'typedef void Foo({int b});',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_parameter_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo(int a);',
+      'typedef void Foo(double a);',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef int Foo();',
+      'typedef num Foo();',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo();',
+      'typedef void Foo<T>();',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo<T>();',
+      'typedef void Foo<T extends num>();',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_same_comment() async {
+    await _assertApiTokenSignatureSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef int Foo();',
+      '/* text */ typedef int Foo();',
+    );
+  }
+
+  test_unit_functionTypeAlias_api_tokens_same_parameter_name_edit_required() async {
+    await _assertApiTokenSignatureSame(
+      'Foo',
+      DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+      'typedef void Foo(int a);',
+      'typedef void Foo(int b);',
+    );
+  }
+
+  test_unit_genericTypeAlias() async {
+    var library = await buildTestLibrary(a, r'''
+typedef Foo = void Function();
+typedef Bar = void Function();
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'Foo', DependencyNodeKind.GENERIC_TYPE_ALIAS),
+      ExpectedNode(aUri, 'Bar', DependencyNodeKind.GENERIC_TYPE_ALIAS),
+    ]);
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function();',
+      '@deprecated typedef Foo = void Function();',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_parameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function();',
+      'typedef Foo = void Function(int);',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_parameter_kind() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function(int a);',
+      'typedef Foo = void Function([int a]);',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_parameter_name_add_positional() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function([int]);',
+      'typedef Foo = void Function([int a]);',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_parameter_name_edit_named() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function({int a});',
+      'typedef Foo = void Function({int b});',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_parameter_name_edit_positional() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function([int]);',
+      'typedef Foo = void Function([int a]);',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = int Function();',
+      'typedef Foo = double Function();',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_typeParameter2_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function();',
+      'typedef Foo = void Function<T>();',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_typeParameter2_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function<T>();',
+      'typedef Foo = void Function<T extends num>();',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function();',
+      'typedef Foo<T> = void Function();',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo<T> = void Function();',
+      'typedef Foo<T extends num> = void Function();',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_same_parameter_name_add_required() async {
+    await _assertApiTokenSignatureSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function(int);',
+      'typedef Foo = void Function(int a);',
+    );
+  }
+
+  test_unit_genericTypeAlias_api_tokens_same_parameter_name_edit_required() async {
+    await _assertApiTokenSignatureSame(
+      'Foo',
+      DependencyNodeKind.GENERIC_TYPE_ALIAS,
+      'typedef Foo = void Function(int a);',
+      'typedef Foo = void Function(int b);',
+    );
+  }
+
+  test_unit_getter() async {
+    var library = await buildTestLibrary(a, r'''
+int get foo => 0;
+int get bar => 0;
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+    ]);
+  }
+
+  test_unit_getter_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int get foo => 0;',
+      '@deprecated int get foo => 0;',
+    );
+  }
+
+  test_unit_getter_api_tokens_notSame_returnType() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int get foo => 0;',
+      'num get foo => 0;',
+    );
+  }
+
+  test_unit_getter_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int get foo => 0;',
+      'int get foo => 1;',
+    );
+  }
+
+  test_unit_mixin() async {
+    var library = await buildTestLibrary(a, r'''
+mixin Foo {}
+mixin Bar {}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'Foo', DependencyNodeKind.MIXIN,
+          classMembers: const []),
+      ExpectedNode(aUri, 'Bar', DependencyNodeKind.MIXIN,
+          classMembers: const []),
+    ]);
+  }
+
+  test_unit_mixin_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X {}',
+      '@deprecated mixin X {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_implements_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X {}',
+      'mixin X implements A {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_implements_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X implements A {}',
+      'mixin X implements B {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_implements_remove() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X implements A {}',
+      'mixin X {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_implements_remove2() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X implements A, B {}',
+      'mixin X implements B {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_implements_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X implements A {}',
+      'mixin X implements A<int> {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_on_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X {}',
+      'mixin X on A {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_on_add2() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X on A {}',
+      'mixin X on A, B {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_on_edit() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X on A {}',
+      'mixin X on B {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_on_replace() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X on A {}',
+      'mixin X implements A {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_on_typeArgument() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X on A {}',
+      'mixin X on A<int> {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_typeParameter_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X {}',
+      'mixin X<T> {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_typeParameter_add2() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X<T> {}',
+      'mixin X<T, U> {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_notSame_typeParameter_bound_add() async {
+    await _assertApiTokenSignatureNotSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X<T> {}',
+      'mixin X<T extends num> {}',
+    );
+  }
+
+  test_unit_mixin_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'X',
+      DependencyNodeKind.MIXIN,
+      'mixin X {  }',
+      'mixin X { void foo() {} }',
+    );
+  }
+
+  test_unit_setter() async {
+    var library = await buildTestLibrary(a, r'''
+void set foo(_) {}
+void set bar(_) {}
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'foo=', DependencyNodeKind.SETTER),
+      ExpectedNode(aUri, 'bar=', DependencyNodeKind.SETTER),
+    ]);
+  }
+
+  test_unit_setter_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo=',
+      DependencyNodeKind.SETTER,
+      'set foo(int a) {}',
+      '@deprecated set foo(int a) {}',
+    );
+  }
+
+  test_unit_setter_api_tokens_notSame_parameter_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo=',
+      DependencyNodeKind.SETTER,
+      'set foo(int a) {}',
+      'set foo(num a) {}',
+    );
+  }
+
+  test_unit_setter_api_tokens_same_body() async {
+    await _assertApiTokenSignatureSame(
+      'foo=',
+      DependencyNodeKind.SETTER,
+      'set foo(int a) { print(0); }',
+      'set foo(int a) { print(1); }',
+    );
+  }
+
+  test_unit_variable() async {
+    var library = await buildTestLibrary(a, r'''
+int a = 1;
+int b = 2, c = 3;
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'a', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'b', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'c', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'a=', DependencyNodeKind.SETTER),
+      ExpectedNode(aUri, 'b=', DependencyNodeKind.SETTER),
+      ExpectedNode(aUri, 'c=', DependencyNodeKind.SETTER),
+    ]);
+  }
+
+  test_unit_variable_api_tokens_notSame_annotation() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int foo = 0;',
+      '@deprecated int foo = 0;',
+    );
+  }
+
+  test_unit_variable_api_tokens_notSame_const() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int foo = 0;',
+      'const int foo = 0;',
+    );
+  }
+
+  test_unit_variable_api_tokens_same_final() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int foo = 0;',
+      'final int foo = 0;',
+    );
+  }
+
+  test_unit_variable_api_tokens_typed_notSame_type() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int foo = 0;',
+      'num foo = 1;',
+    );
+  }
+
+  test_unit_variable_api_tokens_typed_same_initializer() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'int foo = 0;',
+      'int foo = 1;',
+    );
+  }
+
+  test_unit_variable_api_tokens_untyped_notSame_initializer() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'var foo = 0;',
+      'var foo = 1.0;',
+    );
+  }
+
+  test_unit_variable_const() async {
+    var library = await buildTestLibrary(a, r'''
+const foo = 1;
+const bar = 2;
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+    ]);
+  }
+
+  test_unit_variable_const_api_tokens_typed_notSame_initializer() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'const int foo = 0;',
+      'const int foo = 1;',
+    );
+  }
+
+  test_unit_variable_final() async {
+    var library = await buildTestLibrary(a, r'''
+final foo = 1;
+final bar = 2;
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+    ]);
+  }
+
+  test_unit_variable_final_api_tokens_typed_same_initializer() async {
+    await _assertApiTokenSignatureSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'final int foo = 0;',
+      'final int foo = 1;',
+    );
+  }
+
+  test_unit_variable_final_api_tokens_untyped_notSame_initializer() async {
+    await _assertApiTokenSignatureNotSame(
+      'foo',
+      DependencyNodeKind.GETTER,
+      'final foo = 0;',
+      'final foo = 1.0;',
+    );
+  }
+
+  test_unit_variable_final_withoutValue() async {
+    var library = await buildTestLibrary(a, r'''
+final foo;
+final bar;
+''');
+    assertNodes(library.declaredNodes, [
+      ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+      ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+    ]);
+  }
+
+  Future<void> _assertApiTokenSignatureNotSame(
+      String name, DependencyNodeKind kind, String codeBefore, String codeAfter,
+      {String memberOf, String typeParameterOf}) async {
+    DependencyNode getNodeA(Library library) {
+      return getNode(
+        library,
+        uri: aUri,
+        name: name,
+        kind: kind,
+        memberOf: memberOf,
+        typeParameterOf: typeParameterOf,
+      );
+    }
+
+    var libraryBefore = await buildTestLibrary(a, codeBefore);
+    var nodeBefore = getNodeA(libraryBefore);
+
+    var libraryAfter = await buildTestLibrary(a, codeAfter);
+    var nodeAfter = getNodeA(libraryAfter);
+
+    expect(
+      nodeAfter.api.tokenSignatureHex,
+      isNot(nodeBefore.api.tokenSignatureHex),
+    );
+  }
+
+  Future<void> _assertApiTokenSignatureSame(
+      String name, DependencyNodeKind kind, String codeBefore, String codeAfter,
+      {String memberOf, String typeParameterOf}) async {
+    DependencyNode getNodeA(Library library) {
+      return getNode(
+        library,
+        uri: aUri,
+        name: name,
+        kind: kind,
+        memberOf: memberOf,
+        typeParameterOf: typeParameterOf,
+      );
+    }
+
+    var libraryBefore = await buildTestLibrary(a, codeBefore);
+    var nodeBefore = getNodeA(libraryBefore);
+
+    var libraryAfter = await buildTestLibrary(a, codeAfter);
+    var nodeAfter = getNodeA(libraryAfter);
+
+    expect(
+      nodeAfter.api.tokenSignatureHex,
+      nodeBefore.api.tokenSignatureHex,
+    );
+  }
+
+  static void _assertExports(Library library, List<Export> expectedExports) {
+    var actualExports = library.exports;
+    expect(actualExports, hasLength(expectedExports.length));
+    for (var i = 0; i < actualExports.length; ++i) {
+      var actual = actualExports[i];
+      var expected = expectedExports[i];
+      if (actual.uri != expected.uri ||
+          !_equalCombinators(actual.combinators, expected.combinators)) {
+        fail('Expected: $expected\nActual: $actual');
+      }
+    }
+  }
+
+  static void _assertImports(Library library, List<Import> expectedImports) {
+    var actualImports = library.imports;
+    expect(actualImports, hasLength(expectedImports.length));
+    for (var i = 0; i < actualImports.length; ++i) {
+      var actual = actualImports[i];
+      var expected = expectedImports[i];
+      if (actual.uri != expected.uri ||
+          actual.prefix != expected.prefix ||
+          !_equalCombinators(actual.combinators, expected.combinators)) {
+        fail('Expected: $expected\nActual: $actual');
+      }
+    }
+  }
+
+  static bool _equalCombinators(List<Combinator> actualCombinators,
+      List<Combinator> expectedCombinators) {
+    if (actualCombinators.length != expectedCombinators.length) {
+      return false;
+    }
+
+    for (var i = 0; i < actualCombinators.length; i++) {
+      var actualCombinator = actualCombinators[i];
+      var expectedCombinator = expectedCombinators[i];
+      if (actualCombinator.isShow != expectedCombinator.isShow) {
+        return false;
+      }
+
+      var actualNames = actualCombinator.names;
+      var expectedNames = expectedCombinator.names;
+      if (actualNames.length != expectedNames.length) {
+        return false;
+      }
+      for (var j = 0; j < actualNames.length; j++) {
+        if (actualNames[j] != expectedNames[j]) {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+}
