diff --git a/pkg/analysis_services/lib/search/search_engine.dart b/pkg/analysis_services/lib/search/search_engine.dart
index a2579dd..3aac8ba 100644
--- a/pkg/analysis_services/lib/search/search_engine.dart
+++ b/pkg/analysis_services/lib/search/search_engine.dart
@@ -9,6 +9,8 @@
 
 import 'dart:async';
 
+import 'package:analysis_services/index/index.dart';
+import 'package:analysis_services/src/search/search_engine.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -27,278 +29,271 @@
 
 
 /**
+ * Returns a new [SearchEngine] instance based on the given [Index].
+ */
+SearchEngine createSearchEngine(Index index) {
+  return new SearchEngineImpl(index);
+}
+
+
+/**
  * Instances of the enum [MatchKind] represent the kind of reference that was
  * found when a match represents a reference to an element.
  */
-class MatchKind extends Enum<MatchKind> {
+class MatchKind {
   /**
    * A reference to an Angular element.
    */
-  static const MatchKind ANGULAR_REFERENCE = const MatchKind(
-      'ANGULAR_REFERENCE', 0);
+  static const MatchKind ANGULAR_REFERENCE =
+      const MatchKind('ANGULAR_REFERENCE');
 
   /**
    * A reference to an Angular element.
    */
-  static const MatchKind ANGULAR_CLOSING_TAG_REFERENCE = const MatchKind(
-      'ANGULAR_CLOSING_TAG_REFERENCE', 1);
+  static const MatchKind ANGULAR_CLOSING_TAG_REFERENCE =
+      const MatchKind('ANGULAR_CLOSING_TAG_REFERENCE');
 
   /**
    * A declaration of a class.
    */
-  static const MatchKind CLASS_DECLARATION = const MatchKind(
-      'CLASS_DECLARATION', 2);
+  static const MatchKind CLASS_DECLARATION =
+      const MatchKind('CLASS_DECLARATION');
 
   /**
    * A declaration of a class alias.
    */
-  static const MatchKind CLASS_ALIAS_DECLARATION = const MatchKind(
-      'CLASS_ALIAS_DECLARATION', 3);
+  static const MatchKind CLASS_ALIAS_DECLARATION =
+      const MatchKind('CLASS_ALIAS_DECLARATION');
 
   /**
    * A declaration of a constructor.
    */
-  static const MatchKind CONSTRUCTOR_DECLARATION = const MatchKind(
-      'CONSTRUCTOR_DECLARATION', 4);
+  static const MatchKind CONSTRUCTOR_DECLARATION =
+      const MatchKind('CONSTRUCTOR_DECLARATION');
 
   /**
    * A reference to a constructor in which the constructor is being referenced.
    */
-  static const MatchKind CONSTRUCTOR_REFERENCE = const MatchKind(
-      'CONSTRUCTOR_REFERENCE', 5);
+  static const MatchKind CONSTRUCTOR_REFERENCE =
+      const MatchKind('CONSTRUCTOR_REFERENCE');
 
   /**
    * A reference to a type in which the type was extended.
    */
-  static const MatchKind EXTENDS_REFERENCE = const MatchKind(
-      'EXTENDS_REFERENCE', 6);
+  static const MatchKind EXTENDS_REFERENCE =
+      const MatchKind('EXTENDS_REFERENCE');
 
   /**
    * A reference to a field in which the field's value is being invoked.
    */
-  static const MatchKind FIELD_INVOCATION = const MatchKind('FIELD_INVOCATION',
-      7);
+  static const MatchKind FIELD_INVOCATION = const MatchKind('FIELD_INVOCATION');
 
   /**
    * A reference to a field (from field formal parameter).
    */
-  static const MatchKind FIELD_REFERENCE = const MatchKind('FIELD_REFERENCE',
-      8);
+  static const MatchKind FIELD_REFERENCE = const MatchKind('FIELD_REFERENCE');
 
   /**
    * A reference to a field in which the field's value is being read.
    */
-  static const MatchKind FIELD_READ = const MatchKind('FIELD_READ', 9);
+  static const MatchKind FIELD_READ = const MatchKind('FIELD_READ');
 
   /**
    * A reference to a field in which the field's value is being written.
    */
-  static const MatchKind FIELD_WRITE = const MatchKind('FIELD_WRITE', 10);
+  static const MatchKind FIELD_WRITE = const MatchKind('FIELD_WRITE');
 
   /**
    * A declaration of a function.
    */
-  static const MatchKind FUNCTION_DECLARATION = const MatchKind(
-      'FUNCTION_DECLARATION', 11);
+  static const MatchKind FUNCTION_DECLARATION =
+      const MatchKind('FUNCTION_DECLARATION');
 
   /**
    * A reference to a function in which the function is being executed.
    */
-  static const MatchKind FUNCTION_EXECUTION = const MatchKind(
-      'FUNCTION_EXECUTION', 12);
+  static const MatchKind FUNCTION_EXECUTION =
+      const MatchKind('FUNCTION_EXECUTION');
 
   /**
    * A reference to a function in which the function is being referenced.
    */
-  static const MatchKind FUNCTION_REFERENCE = const MatchKind(
-      'FUNCTION_REFERENCE', 13);
+  static const MatchKind FUNCTION_REFERENCE =
+      const MatchKind('FUNCTION_REFERENCE');
 
   /**
    * A declaration of a function type.
    */
-  static const MatchKind FUNCTION_TYPE_DECLARATION = const MatchKind(
-      'FUNCTION_TYPE_DECLARATION', 14);
+  static const MatchKind FUNCTION_TYPE_DECLARATION =
+      const MatchKind('FUNCTION_TYPE_DECLARATION');
 
   /**
    * A reference to a function type.
    */
-  static const MatchKind FUNCTION_TYPE_REFERENCE = const MatchKind(
-      'FUNCTION_TYPE_REFERENCE', 15);
+  static const MatchKind FUNCTION_TYPE_REFERENCE =
+      const MatchKind('FUNCTION_TYPE_REFERENCE');
 
   /**
    * A reference to a type in which the type was implemented.
    */
-  static const MatchKind IMPLEMENTS_REFERENCE = const MatchKind(
-      'IMPLEMENTS_REFERENCE', 16);
+  static const MatchKind IMPLEMENTS_REFERENCE =
+      const MatchKind('IMPLEMENTS_REFERENCE');
 
   /**
    * A reference to a [ImportElement].
    */
-  static const MatchKind IMPORT_REFERENCE = const MatchKind('IMPORT_REFERENCE',
-      17);
+  static const MatchKind IMPORT_REFERENCE = const MatchKind('IMPORT_REFERENCE');
 
   /**
    * A reference to a class that is implementing a specified type.
    */
-  static const MatchKind INTERFACE_IMPLEMENTED = const MatchKind(
-      'INTERFACE_IMPLEMENTED', 18);
+  static const MatchKind INTERFACE_IMPLEMENTED =
+      const MatchKind('INTERFACE_IMPLEMENTED');
 
   /**
    * A reference to a [LibraryElement].
    */
-  static const MatchKind LIBRARY_REFERENCE = const MatchKind(
-      'LIBRARY_REFERENCE', 19);
+  static const MatchKind LIBRARY_REFERENCE =
+      const MatchKind('LIBRARY_REFERENCE');
 
   /**
    * A reference to a method in which the method is being invoked.
    */
-  static const MatchKind METHOD_INVOCATION = const MatchKind(
-      'METHOD_INVOCATION', 20);
+  static const MatchKind METHOD_INVOCATION =
+      const MatchKind('METHOD_INVOCATION');
 
   /**
    * A reference to a method in which the method is being referenced.
    */
-  static const MatchKind METHOD_REFERENCE = const MatchKind('METHOD_REFERENCE',
-      21);
+  static const MatchKind METHOD_REFERENCE = const MatchKind('METHOD_REFERENCE');
 
   /**
    * A declaration of a name.
    */
-  static const MatchKind NAME_DECLARATION = const MatchKind('NAME_DECLARATION',
-      22);
+  static const MatchKind NAME_DECLARATION = const MatchKind('NAME_DECLARATION');
 
   /**
    * A reference to a name, resolved.
    */
-  static const MatchKind NAME_REFERENCE_RESOLVED = const MatchKind(
-      'NAME_REFERENCE_RESOLVED', 23);
+  static const MatchKind NAME_REFERENCE_RESOLVED =
+      const MatchKind('NAME_REFERENCE_RESOLVED');
 
   /**
    * An invocation of a name, resolved.
    */
-  static const MatchKind NAME_INVOCATION_RESOLVED = const MatchKind(
-      'NAME_INVOCATION_RESOLVED', 24);
+  static const MatchKind NAME_INVOCATION_RESOLVED =
+      const MatchKind('NAME_INVOCATION_RESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read.
    */
-  static const MatchKind NAME_READ_RESOLVED = const MatchKind(
-      'NAME_READ_RESOLVED', 25);
+  static const MatchKind NAME_READ_RESOLVED =
+      const MatchKind('NAME_READ_RESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read and written.
    */
-  static const MatchKind NAME_READ_WRITE_RESOLVED = const MatchKind(
-      'NAME_READ_WRITE_RESOLVED', 26);
+  static const MatchKind NAME_READ_WRITE_RESOLVED =
+      const MatchKind('NAME_READ_WRITE_RESOLVED');
 
   /**
    * A reference to a name in which the name's value is being written.
    */
-  static const MatchKind NAME_WRITE_RESOLVED = const MatchKind(
-      'NAME_WRITE_RESOLVED', 27);
+  static const MatchKind NAME_WRITE_RESOLVED =
+      const MatchKind('NAME_WRITE_RESOLVED');
 
   /**
    * An invocation of a name, unresolved.
    */
-  static const MatchKind NAME_INVOCATION_UNRESOLVED = const MatchKind(
-      'NAME_INVOCATION_UNRESOLVED', 28);
+  static const MatchKind NAME_INVOCATION_UNRESOLVED =
+      const MatchKind('NAME_INVOCATION_UNRESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read.
    */
-  static const MatchKind NAME_READ_UNRESOLVED = const MatchKind(
-      'NAME_READ_UNRESOLVED', 29);
+  static const MatchKind NAME_READ_UNRESOLVED =
+      const MatchKind('NAME_READ_UNRESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read and written.
    */
-  static const MatchKind NAME_READ_WRITE_UNRESOLVED = const MatchKind(
-      'NAME_READ_WRITE_UNRESOLVED', 30);
+  static const MatchKind NAME_READ_WRITE_UNRESOLVED =
+      const MatchKind('NAME_READ_WRITE_UNRESOLVED');
 
   /**
    * A reference to a name in which the name's value is being written.
    */
-  static const MatchKind NAME_WRITE_UNRESOLVED = const MatchKind(
-      'NAME_WRITE_UNRESOLVED', 31);
+  static const MatchKind NAME_WRITE_UNRESOLVED =
+      const MatchKind('NAME_WRITE_UNRESOLVED');
 
   /**
    * A reference to a name, unresolved.
    */
-  static const MatchKind NAME_REFERENCE_UNRESOLVED = const MatchKind(
-      'NAME_REFERENCE_UNRESOLVED', 32);
+  static const MatchKind NAME_REFERENCE_UNRESOLVED =
+      const MatchKind('NAME_REFERENCE_UNRESOLVED');
 
   /**
    * A reference to a named parameter in invocation.
    */
-  static const MatchKind NAMED_PARAMETER_REFERENCE = const MatchKind(
-      'NAMED_PARAMETER_REFERENCE', 33);
+  static const MatchKind NAMED_PARAMETER_REFERENCE =
+      const MatchKind('NAMED_PARAMETER_REFERENCE');
 
   /**
    * A reference to a property accessor.
    */
-  static const MatchKind PROPERTY_ACCESSOR_REFERENCE = const MatchKind(
-      'PROPERTY_ACCESSOR_REFERENCE', 34);
+  static const MatchKind PROPERTY_ACCESSOR_REFERENCE =
+      const MatchKind('PROPERTY_ACCESSOR_REFERENCE');
 
   /**
    * A reference to a type.
    */
-  static const MatchKind TYPE_REFERENCE = const MatchKind('TYPE_REFERENCE', 35);
+  static const MatchKind TYPE_REFERENCE = const MatchKind('TYPE_REFERENCE');
 
   /**
    * A reference to a type parameter.
    */
-  static const MatchKind TYPE_PARAMETER_REFERENCE = const MatchKind(
-      'TYPE_PARAMETER_REFERENCE', 36);
+  static const MatchKind TYPE_PARAMETER_REFERENCE =
+      const MatchKind('TYPE_PARAMETER_REFERENCE');
 
   /**
    * A reference to a [CompilationUnitElement].
    */
-  static const MatchKind UNIT_REFERENCE = const MatchKind('UNIT_REFERENCE', 37);
+  static const MatchKind UNIT_REFERENCE = const MatchKind('UNIT_REFERENCE');
 
   /**
    * A declaration of a variable.
    */
-  static const MatchKind VARIABLE_DECLARATION = const MatchKind(
-      'VARIABLE_DECLARATION', 38);
+  static const MatchKind VARIABLE_DECLARATION =
+      const MatchKind('VARIABLE_DECLARATION');
 
   /**
    * A reference to a variable in which the variable's value is being read.
    */
-  static const MatchKind VARIABLE_READ = const MatchKind('VARIABLE_READ', 39);
+  static const MatchKind VARIABLE_READ = const MatchKind('VARIABLE_READ');
 
   /**
    * A reference to a variable in which the variable's value is being both read
    * and write.
    */
-  static const MatchKind VARIABLE_READ_WRITE = const MatchKind(
-      'VARIABLE_READ_WRITE', 40);
+  static const MatchKind VARIABLE_READ_WRITE =
+      const MatchKind('VARIABLE_READ_WRITE');
 
   /**
    * A reference to a variable in which the variables's value is being written.
    */
-  static const MatchKind VARIABLE_WRITE = const MatchKind('VARIABLE_WRITE', 41);
+  static const MatchKind VARIABLE_WRITE = const MatchKind('VARIABLE_WRITE');
 
   /**
    * A reference to a type in which the type was mixed in.
    */
-  static const MatchKind WITH_REFERENCE = const MatchKind('WITH_REFERENCE', 42);
+  static const MatchKind WITH_REFERENCE = const MatchKind('WITH_REFERENCE');
 
-  static const List<MatchKind> values = const [ANGULAR_REFERENCE,
-      ANGULAR_CLOSING_TAG_REFERENCE, CLASS_DECLARATION, CLASS_ALIAS_DECLARATION,
-      CONSTRUCTOR_DECLARATION, CONSTRUCTOR_REFERENCE, EXTENDS_REFERENCE,
-      FIELD_INVOCATION, FIELD_REFERENCE, FIELD_READ, FIELD_WRITE,
-      FUNCTION_DECLARATION, FUNCTION_EXECUTION, FUNCTION_REFERENCE,
-      FUNCTION_TYPE_DECLARATION, FUNCTION_TYPE_REFERENCE, IMPLEMENTS_REFERENCE,
-      IMPORT_REFERENCE, INTERFACE_IMPLEMENTED, LIBRARY_REFERENCE, METHOD_INVOCATION,
-      METHOD_REFERENCE, NAME_DECLARATION, NAME_REFERENCE_RESOLVED,
-      NAME_INVOCATION_RESOLVED, NAME_READ_RESOLVED, NAME_READ_WRITE_RESOLVED,
-      NAME_WRITE_RESOLVED, NAME_INVOCATION_UNRESOLVED, NAME_READ_UNRESOLVED,
-      NAME_READ_WRITE_UNRESOLVED, NAME_WRITE_UNRESOLVED, NAME_REFERENCE_UNRESOLVED,
-      NAMED_PARAMETER_REFERENCE, PROPERTY_ACCESSOR_REFERENCE, TYPE_REFERENCE,
-      TYPE_PARAMETER_REFERENCE, UNIT_REFERENCE, VARIABLE_DECLARATION, VARIABLE_READ,
-      VARIABLE_READ_WRITE, VARIABLE_WRITE, WITH_REFERENCE];
+  final String name;
 
-  const MatchKind(String name, int ordinal) : super(name, ordinal);
+  const MatchKind(this.name);
+
+  @override
+  String toString() => name;
 }
 
 
@@ -307,13 +302,6 @@
  * to search for various pieces of information.
  */
 abstract class SearchEngine {
-//  /**
-//   * Returns types assigned to the given field or top-level variable.
-//   *
-//   * [variable] - the field or top-level variable to find assigned types for.
-//   */
-//  Future<Set<DartType>> searchAssignedTypes(PropertyInducingElement variable);
-
   /**
    * Returns declarations of class members with the given name.
    *
@@ -380,9 +368,10 @@
   /**
    * Is `true` if field or method access is done using qualifier.
    */
-  bool qualified = false;
+  final bool isQualified;
 
-  SearchMatch(this.kind, this.element, this.sourceRange, this.isResolved);
+  SearchMatch(this.kind, this.element, this.sourceRange, this.isResolved,
+      this.isQualified);
 
   @override
   int get hashCode => JavaArrays.makeHashCode([element, sourceRange, kind]);
@@ -393,9 +382,11 @@
       return true;
     }
     if (object is SearchMatch) {
-      return kind == object.kind && isResolved == object.isResolved && qualified
-          == object.qualified && sourceRange == object.sourceRange && element ==
-          object.element;
+      return kind == object.kind &&
+          isResolved == object.isResolved &&
+          isQualified == object.isQualified &&
+          sourceRange == object.sourceRange &&
+          element == object.element;
     }
     return false;
   }
@@ -405,14 +396,14 @@
     StringBuffer buffer = new StringBuffer();
     buffer.write("SearchMatch(kind=");
     buffer.write(kind);
-    buffer.write(", isResolved=");
-    buffer.write(isResolved);
     buffer.write(", element=");
     buffer.write(element.displayName);
     buffer.write(", range=");
     buffer.write(sourceRange);
-    buffer.write(", qualified=");
-    buffer.write(qualified);
+    buffer.write(", isResolved=");
+    buffer.write(isResolved);
+    buffer.write(", isQualified=");
+    buffer.write(isQualified);
     buffer.write(")");
     return buffer.toString();
   }
diff --git a/pkg/analysis_services/lib/src/index/index_contributor.dart b/pkg/analysis_services/lib/src/index/index_contributor.dart
index 0444183..3a1c97e 100644
--- a/pkg/analysis_services/lib/src/index/index_contributor.dart
+++ b/pkg/analysis_services/lib/src/index/index_contributor.dart
@@ -656,6 +656,10 @@
     }
     // prepare information
     Element element = node.bestElement;
+    // TODO(scheglov) fix resolver to resolve to Field, not an accessor
+    if (node.parent is Combinator && element is PropertyAccessorElement) {
+      element = (element as PropertyAccessorElement).variable;
+    }
     // qualified name reference
     _recordQualifiedMemberReference(node, element, nameElement, location);
     // stop if already handled
@@ -688,9 +692,11 @@
         FunctionTypeAliasElement || element is LabelElement || element is
         TypeParameterElement) {
       recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
-    } else if (element is FieldElement) {
+    } else if (element is PropertyInducingElement) {
       location = _getLocationWithInitializerType(node, location);
-      recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+      recordRelationship(element,
+          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+          location);
     } else if (element is FieldFormalParameterElement) {
       FieldFormalParameterElement fieldParameter = element;
       FieldElement field = fieldParameter.field;
diff --git a/pkg/analysis_services/lib/src/index/store/codec.dart b/pkg/analysis_services/lib/src/index/store/codec.dart
index 9153e69..108f936 100644
--- a/pkg/analysis_services/lib/src/index/store/codec.dart
+++ b/pkg/analysis_services/lib/src/index/store/codec.dart
@@ -19,14 +19,14 @@
   /**
    * A table mapping contexts to their unique indices.
    */
-  Map<AnalysisContext, int> _contextToIndex = new HashMap<AnalysisContext, int>(
-      );
+  Map<AnalysisContext, int> _contextToIndex =
+      new HashMap<AnalysisContext, int>();
 
   /**
    * A table mapping indices to the corresponding contexts.
    */
-  Map<int, AnalysisContext> _indexToContext = new HashMap<int, AnalysisContext>(
-      );
+  Map<int, AnalysisContext> _indexToContext =
+      new HashMap<int, AnalysisContext>();
 
   /**
    * The next id to assign.
@@ -92,7 +92,8 @@
     List<int> path = _indexToPath[index];
     List<String> components = _getLocationComponents(path);
     ElementLocation location = new ElementLocationImpl.con3(components);
-    return context.getElement(location);
+    Element element = context.getElement(location);
+    return element;
   }
 
   /**
diff --git a/pkg/analysis_services/lib/src/search/search_engine.dart b/pkg/analysis_services/lib/src/search/search_engine.dart
index b9419b9..def5e32 100644
--- a/pkg/analysis_services/lib/src/search/search_engine.dart
+++ b/pkg/analysis_services/lib/src/search/search_engine.dart
@@ -7,1222 +7,451 @@
 
 library services.src.search.search_engine;
 
-///**
-// * Instances of the class <code>AndSearchPattern</code> implement a search pattern that matches
-// * elements that match all of several other search patterns.
-// */
-//class AndSearchPattern implements SearchPattern {
-//  /**
-//   * The patterns used to determine whether this pattern matches an element.
-//   */
-//  final List<SearchPattern> _patterns;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements that match all of several other
-//   * search patterns.
-//   *
-//   * @param patterns the patterns used to determine whether this pattern matches an element
-//   */
-//  AndSearchPattern(this._patterns);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    MatchQuality highestQuality = null;
-//    for (SearchPattern pattern in _patterns) {
-//      MatchQuality quality = pattern.matches(element);
-//      if (quality == null) {
-//        return null;
-//      }
-//      if (highestQuality == null) {
-//        highestQuality = quality;
-//      } else {
-//        highestQuality = highestQuality.max(quality);
-//      }
-//    }
-//    return highestQuality;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>CamelCaseSearchPattern</code> implement a search pattern that
-// * matches elements whose name matches a partial identifier where camel case conventions are used to
-// * perform what is essentially multiple prefix matches.
-// */
-//class CamelCaseSearchPattern implements SearchPattern {
-//  /**
-//   * The pattern that matching elements must match.
-//   */
-//  List<int> _pattern;
-//
-//  /**
-//   * A flag indicating whether the pattern and the name being matched must have exactly the same
-//   * number of parts (i.e. the same number of uppercase characters).
-//   */
-//  final bool _samePartCount;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names match the given
-//   * camel-case pattern.
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param samePartCount `true` if the pattern and the name being matched must have
-//   *          exactly the same number of parts (i.e. the same number of uppercase characters)
-//   */
-//  CamelCaseSearchPattern(String pattern, this._samePartCount) {
-//    this._pattern = pattern.toCharArray();
-//  }
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (CharOperation.camelCaseMatch(_pattern, name.toCharArray(), _samePartCount)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class `CountingSearchListener` listen for search results, passing those
-// * results on to a wrapped listener, but ensure that the wrapped search listener receives only one
-// * notification that the search is complete.
-// */
-//class CountingSearchListener implements SearchListener {
-//  /**
-//   * The number of times that this listener expects to be told that the search is complete before
-//   * passing the information along to the wrapped listener.
-//   */
-//  int _completionCount = 0;
-//
-//  /**
-//   * The listener that will be notified as results are received and when the given number of search
-//   * complete notifications have been received.
-//   */
-//  final SearchListener _wrappedListener;
-//
-//  /**
-//   * Initialize a newly created search listener to pass search results on to the given listener and
-//   * to notify the given listener that the search is complete after getting the given number of
-//   * notifications.
-//   *
-//   * @param completionCount the number of times that this listener expects to be told that the
-//   *          search is complete
-//   * @param wrappedListener the listener that will be notified as results are received
-//   */
-//  CountingSearchListener(int completionCount, this._wrappedListener) {
-//    this._completionCount = completionCount;
-//    if (completionCount == 0) {
-//      _wrappedListener.searchComplete();
-//    }
-//  }
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    _wrappedListener.matchFound(match);
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    _completionCount--;
-//    if (_completionCount <= 0) {
-//      _wrappedListener.searchComplete();
-//    }
-//  }
-//}
-//
-///**
-// * Instances of the class <code>ExactSearchPattern</code> implement a search pattern that matches
-// * elements whose name matches a specified identifier exactly.
-// */
-//class ExactSearchPattern implements SearchPattern {
-//  /**
-//   * The identifier that matching elements must be equal to.
-//   */
-//  final String _identifier;
-//
-//  /**
-//   * A flag indicating whether a case sensitive match is to be performed.
-//   */
-//  final bool _caseSensitive;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param identifier the identifier that matching elements must be equal to
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  ExactSearchPattern(this._identifier, this._caseSensitive);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (_caseSensitive && name == _identifier) {
-//      return MatchQuality.EXACT;
-//    }
-//    if (!_caseSensitive && javaStringEqualsIgnoreCase(name, _identifier)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>FilteredSearchListener</code> implement a search listener that
-// * delegates to another search listener after removing matches that do not pass a given filter.
-// */
-//class FilteredSearchListener extends WrappedSearchListener {
-//  /**
-//   * The filter used to filter the matches.
-//   */
-//  final SearchFilter _filter;
-//
-//  /**
-//   * Initialize a newly created search listener to pass on any matches that pass the given filter to
-//   * the given listener.
-//   *
-//   * @param filter the filter used to filter the matches
-//   * @param listener the search listener being wrapped
-//   */
-//  FilteredSearchListener(this._filter, SearchListener listener) : super(listener);
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    if (_filter.passes(match)) {
-//      propagateMatch(match);
-//    }
-//  }
-//}
-//
-///**
-// * [SearchListener] used by [SearchEngineImpl] internally to gather asynchronous results
-// * and return them synchronously.
-// */
-//class GatheringSearchListener implements SearchListener {
-//  /**
-//   * A list containing the matches that have been found so far.
-//   */
-//  List<SearchMatch> _matches = [];
-//
-//  /**
-//   * A flag indicating whether the search is complete.
-//   */
-//  bool _isComplete = false;
-//
-//  /**
-//   * @return the the matches that have been found.
-//   */
-//  List<SearchMatch> get matches {
-//    _matches.sort(SearchMatch.SORT_BY_ELEMENT_NAME);
-//    return _matches;
-//  }
-//
-//  /**
-//   * Return `true` if the search is complete.
-//   *
-//   * @return `true` if the search is complete
-//   */
-//  bool get isComplete => _isComplete;
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    _matches.add(match);
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    _isComplete = true;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>LibrarySearchScope</code> implement a search scope that encompasses
-// * everything in a given collection of libraries.
-// */
-//class LibrarySearchScope implements SearchScope {
-//  /**
-//   * The libraries defining which elements are included in the scope.
-//   */
-//  final List<LibraryElement> libraries;
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given libraries.
-//   *
-//   * @param libraries the libraries defining which elements are included in the scope
-//   */
-//  LibrarySearchScope.con1(Iterable<LibraryElement> libraries) : this.con2(new List.from(libraries));
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given libraries.
-//   *
-//   * @param libraries the libraries defining which elements are included in the scope
-//   */
-//  LibrarySearchScope.con2(this.libraries);
-//
-//  @override
-//  bool encloses(Element element) {
-//    LibraryElement elementLibrary = element.getAncestor((element) => element is LibraryElement);
-//    return ArrayUtils.contains(libraries, elementLibrary);
-//  }
-//}
-//
-///**
-// * Instances of the class <code>NameMatchingSearchListener</code> implement a search listener that
-// * delegates to another search listener after removing matches that do not match a given pattern.
-// */
-//class NameMatchingSearchListener extends WrappedSearchListener {
-//  /**
-//   * The pattern used to filter the matches.
-//   */
-//  final SearchPattern _pattern;
-//
-//  /**
-//   * Initialize a newly created search listener to pass on any matches that match the given pattern
-//   * to the given listener.
-//   *
-//   * @param pattern the pattern used to filter the matches
-//   * @param listener the search listener being wrapped
-//   */
-//  NameMatchingSearchListener(this._pattern, SearchListener listener) : super(listener);
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    if (_pattern.matches(match.element) != null) {
-//      propagateMatch(match);
-//    }
-//  }
-//}
-//
-///**
-// * Instances of the class <code>OrSearchPattern</code> implement a search pattern that matches
-// * elements that match any one of several other search patterns.
-// */
-//class OrSearchPattern implements SearchPattern {
-//  /**
-//   * The patterns used to determine whether this pattern matches an element.
-//   */
-//  final List<SearchPattern> _patterns;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements that match any one of several other
-//   * search patterns.
-//   *
-//   * @param patterns the patterns used to determine whether this pattern matches an element
-//   */
-//  OrSearchPattern(this._patterns);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    // Do we want to return the highest quality of match rather than stopping
-//    // after the first match? Doing so would be more accurate, but slower.
-//    for (SearchPattern pattern in _patterns) {
-//      MatchQuality quality = pattern.matches(element);
-//      if (quality != null) {
-//        return quality;
-//      }
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>PrefixSearchPattern</code> implement a search pattern that matches
-// * elements whose name has a given prefix.
-// */
-//class PrefixSearchPattern implements SearchPattern {
-//  /**
-//   * The prefix that matching elements must start with.
-//   */
-//  final String _prefix;
-//
-//  /**
-//   * A flag indicating whether a case sensitive match is to be performed.
-//   */
-//  final bool _caseSensitive;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param prefix the prefix that matching elements must start with
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  PrefixSearchPattern(this._prefix, this._caseSensitive);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    if (element == null) {
-//      return null;
-//    }
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (_caseSensitive && startsWith(name, _prefix)) {
-//      return MatchQuality.EXACT;
-//    }
-//    if (!_caseSensitive && startsWithIgnoreCase(name, _prefix)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>RegularExpressionSearchPattern</code> implement a search pattern
-// * that matches elements whose name matches a given regular expression.
-// */
-//class RegularExpressionSearchPattern implements SearchPattern {
-//  /**
-//   * The regular expression pattern that matching elements must match.
-//   */
-//  RegExp _pattern;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param regularExpression the regular expression that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  RegularExpressionSearchPattern(String regularExpression, bool caseSensitive) {
-//    _pattern = new RegExp(regularExpression);
-//  }
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    if (element == null) {
-//      return null;
-//    }
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (new JavaPatternMatcher(_pattern, name).matches()) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Factory for [SearchEngine].
-// */
-//class SearchEngineFactory {
-//  /**
-//   * @return the new [SearchEngine] instance based on the given [Index].
-//   */
-//  static SearchEngine createSearchEngine(Index index) => new SearchEngineImpl(index);
-//}
+import 'dart:async';
 
-///**
-// * Implementation of [SearchEngine].
-// */
-//class SearchEngineImpl implements SearchEngine {
-//  /**
-//   * Apply the given filter to the given listener.
-//   *
-//   * @param filter the filter to be used before passing matches on to the listener, or `null`
-//   *          if all matches should be passed on
-//   * @param listener the listener that will only be given matches that pass the filter
-//   * @return a search listener that will pass to the given listener any matches that pass the given
-//   *         filter
-//   */
-//  static SearchListener _applyFilter(SearchFilter filter, SearchListener listener) {
-//    if (filter == null) {
-//      return listener;
-//    }
-//    return new FilteredSearchListener(filter, listener);
-//  }
-//
-//  /**
-//   * Apply the given pattern to the given listener.
-//   *
-//   * @param pattern the pattern to be used before passing matches on to the listener, or
-//   *          `null` if all matches should be passed on
-//   * @param listener the listener that will only be given matches that match the pattern
-//   * @return a search listener that will pass to the given listener any matches that match the given
-//   *         pattern
-//   */
-//  static SearchListener _applyPattern(SearchPattern pattern, SearchListener listener) {
-//    if (pattern == null) {
-//      return listener;
-//    }
-//    return new NameMatchingSearchListener(pattern, listener);
-//  }
-//
-//  static List<Element> _createElements(SearchScope scope) {
-//    if (scope is LibrarySearchScope) {
-//      return scope.libraries;
-//    }
-//    return <Element> [IndexConstants.UNIVERSE];
-//  }
-//
-//  static RelationshipCallback _newCallback(MatchKind matchKind, SearchScope scope, SearchListener listener) => new SearchEngineImpl_RelationshipCallbackImpl(scope, matchKind, listener);
-//
-//  /**
-//   * The index used to respond to the search requests.
-//   */
-//  final Index _index;
-//
-//  /**
-//   * Initialize a newly created search engine to use the given index.
-//   *
-//   * @param index the index used to respond to the search requests
-//   */
-//  SearchEngineImpl(this._index);
-//
-//  @override
-//  Set<DartType> searchAssignedTypes(PropertyInducingElement variable, SearchScope scope) {
-//    PropertyAccessorElement setter = variable.setter;
-//    int numRequests = (setter != null ? 2 : 0) + 2;
-//    // find locations
-//    List<Location> locations = [];
-//    CountDownLatch latch = new CountDownLatch(numRequests);
-//    if (setter != null) {
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, new Callback());
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, new Callback());
-//    }
-//    _index.getRelationships(variable, IndexConstants.IS_REFERENCED_BY, new Callback());
-//    _index.getRelationships(variable, IndexConstants.IS_DEFINED_BY, new Callback());
-//    Uninterruptibles.awaitUninterruptibly(latch);
-//    // get types from locations
-//    Set<DartType> types = new Set();
-//    for (Location location in locations) {
-//      // check scope
-//      if (scope != null) {
-//        Element targetElement = location.element;
-//        if (!scope.encloses(targetElement)) {
-//          continue;
-//        }
-//      }
-//      // we need data
-//      if (location is! LocationWithData) {
-//        continue;
-//      }
-//      LocationWithData locationWithData = location as LocationWithData;
-//      // add type
-//      Object data = locationWithData.data;
-//      if (data is DartType) {
-//        DartType type = data as DartType;
-//        types.add(type);
-//      }
-//    }
-//    // done
-//    return types;
-//  }
-//
-//  @override
-//  List<SearchMatch> searchDeclarations(String name, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchDeclarations(this, name, scope, filter));
-//
-//  @override
-//  void searchDeclarations2(String name, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_DEFINED_BY, _newCallback(MatchKind.NAME_DECLARATION, scope, listener));
-//  }
-//
-//  @override
-//  List<SearchMatch> searchFunctionDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchFunctionDeclarations(this, scope, pattern, filter));
-//
-//  @override
-//  void searchFunctionDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    List<Element> elements = _createElements(scope);
-//    listener = _applyPattern(pattern, listener);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(elements.length, listener);
-//    for (Element element in elements) {
-//      _index.getRelationships(element, IndexConstants.DEFINES_FUNCTION, _newCallback(MatchKind.FUNCTION_DECLARATION, scope, listener));
-//    }
-//  }
-//
-//  @override
-//  List<SearchMatch> searchQualifiedMemberReferences(String name, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences(this, name, scope, filter));
-//
-//  @override
-//  void searchQualifiedMemberReferences2(String name, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(10, listener);
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _newCallback(MatchKind.NAME_REFERENCE_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _newCallback(MatchKind.NAME_REFERENCE_UNRESOLVED, scope, listener));
-//    // granular resolved operations
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_INVOKED_BY_RESOLVED, _newCallback(MatchKind.NAME_INVOCATION_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_BY_RESOLVED, _newCallback(MatchKind.NAME_READ_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED, _newCallback(MatchKind.NAME_READ_WRITE_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED, _newCallback(MatchKind.NAME_WRITE_RESOLVED, scope, listener));
-//    // granular unresolved operations
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED, _newCallback(MatchKind.NAME_INVOCATION_UNRESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _newCallback(MatchKind.NAME_READ_UNRESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED, _newCallback(MatchKind.NAME_READ_WRITE_UNRESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED, _newCallback(MatchKind.NAME_WRITE_UNRESOLVED, scope, listener));
-//  }
-//
-//  @override
-//  List<SearchMatch> searchReferences(Element element, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchReferences(this, element, scope, filter));
-//
-//  @override
-//  void searchReferences2(Element element, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    if (element == null) {
-//      listener.searchComplete();
-//      return;
-//    }
-//    if (element is Member) {
-//      element = (element as Member).baseElement;
-//    }
-//    while (true) {
-//      if (element.kind == ElementKind.ANGULAR_COMPONENT || element.kind == ElementKind.ANGULAR_CONTROLLER || element.kind == ElementKind.ANGULAR_FORMATTER || element.kind == ElementKind.ANGULAR_PROPERTY || element.kind == ElementKind.ANGULAR_SCOPE_PROPERTY || element.kind == ElementKind.ANGULAR_SELECTOR) {
-//        _searchReferences(element as AngularElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.CLASS) {
-//        _searchReferences2(element as ClassElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.COMPILATION_UNIT) {
-//        _searchReferences3(element as CompilationUnitElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.CONSTRUCTOR) {
-//        _searchReferences4(element as ConstructorElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.FIELD || element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
-//        _searchReferences12(element as PropertyInducingElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.FUNCTION) {
-//        _searchReferences5(element as FunctionElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.GETTER || element.kind == ElementKind.SETTER) {
-//        _searchReferences11(element as PropertyAccessorElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.IMPORT) {
-//        _searchReferences7(element as ImportElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.LIBRARY) {
-//        _searchReferences8(element as LibraryElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
-//        _searchReferences14(element as LocalVariableElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.METHOD) {
-//        _searchReferences9(element as MethodElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.PARAMETER) {
-//        _searchReferences10(element as ParameterElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
-//        _searchReferences6(element as FunctionTypeAliasElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.TYPE_PARAMETER) {
-//        _searchReferences13(element as TypeParameterElement, scope, filter, listener);
-//        return;
-//      } else {
-//        listener.searchComplete();
-//        return;
-//      }
-//      break;
-//    }
-//  }
-//
-//  @override
-//  List<SearchMatch> searchSubtypes(ClassElement type, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchSubtypes(this, type, scope, filter));
-//
-//  @override
-//  void searchSubtypes2(ClassElement type, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(3, listener);
-//    _index.getRelationships(type, IndexConstants.IS_EXTENDED_BY, _newCallback(MatchKind.EXTENDS_REFERENCE, scope, listener));
-//    _index.getRelationships(type, IndexConstants.IS_MIXED_IN_BY, _newCallback(MatchKind.WITH_REFERENCE, scope, listener));
-//    _index.getRelationships(type, IndexConstants.IS_IMPLEMENTED_BY, _newCallback(MatchKind.IMPLEMENTS_REFERENCE, scope, listener));
-//  }
-//
-//  @override
-//  List<SearchMatch> searchTypeDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchTypeDeclarations(this, scope, pattern, filter));
-//
-//  @override
-//  void searchTypeDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    List<Element> elements = _createElements(scope);
-//    listener = _applyPattern(pattern, listener);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(elements.length * 3, listener);
-//    for (Element element in elements) {
-//      _index.getRelationships(element, IndexConstants.DEFINES_CLASS, _newCallback(MatchKind.CLASS_DECLARATION, scope, listener));
-//      _index.getRelationships(element, IndexConstants.DEFINES_CLASS_ALIAS, _newCallback(MatchKind.CLASS_ALIAS_DECLARATION, scope, listener));
-//      _index.getRelationships(element, IndexConstants.DEFINES_FUNCTION_TYPE, _newCallback(MatchKind.FUNCTION_TYPE_DECLARATION, scope, listener));
-//    }
-//  }
-//
-//  @override
-//  List<SearchMatch> searchVariableDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchVariableDeclarations(this, scope, pattern, filter));
-//
-//  @override
-//  void searchVariableDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    List<Element> elements = _createElements(scope);
-//    listener = _applyPattern(pattern, listener);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(elements.length, listener);
-//    for (Element element in elements) {
-//      _index.getRelationships(element, IndexConstants.DEFINES_VARIABLE, _newCallback(MatchKind.VARIABLE_DECLARATION, scope, listener));
-//    }
-//  }
-//
-//  /**
-//   * Use the given runner to perform the given number of asynchronous searches, then wait until the
-//   * search has completed and return the results that were produced.
-//   *
-//   * @param runner the runner used to perform an asynchronous search
-//   * @return the results that were produced @ if the results of at least one of the searched could
-//   *         not be computed
-//   */
-//  List<SearchMatch> _gatherResults(SearchEngineImpl_SearchRunner runner) {
-//    GatheringSearchListener listener = new GatheringSearchListener();
-//    runner.performSearch(listener);
-//    while (!listener.isComplete) {
-//      Thread.yield();
-//    }
-//    return listener.matches;
-//  }
-//
-//  void _searchReferences(AngularElement element, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(element, IndexConstants.ANGULAR_REFERENCE, _newCallback(MatchKind.ANGULAR_REFERENCE, scope, listener));
-//    _index.getRelationships(element, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, _newCallback(MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences2(ClassElement type, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(type, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.TYPE_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences3(CompilationUnitElement unit, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(unit, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.UNIT_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences4(ConstructorElement constructor, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(constructor, IndexConstants.IS_DEFINED_BY, _newCallback(MatchKind.CONSTRUCTOR_DECLARATION, scope, listener));
-//    _index.getRelationships(constructor, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.CONSTRUCTOR_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences5(FunctionElement function, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(function, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FUNCTION_REFERENCE, scope, listener));
-//    _index.getRelationships(function, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
-//  }
-//
-//  void _searchReferences6(FunctionTypeAliasElement alias, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(alias, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FUNCTION_TYPE_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences7(ImportElement imp, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(imp, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.IMPORT_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences8(LibraryElement library, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(library, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.LIBRARY_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences9(MethodElement method, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    // TODO(scheglov) use "5" when add named matches
-//    listener = new CountingSearchListener(4, listener);
-//    // exact matches
-//    _index.getRelationships(method, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _newCallback(MatchKind.METHOD_INVOCATION, scope, listener));
-//    _index.getRelationships(method, IndexConstants.IS_INVOKED_BY_QUALIFIED, _newCallback(MatchKind.METHOD_INVOCATION, scope, listener));
-//    _index.getRelationships(method, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.METHOD_REFERENCE, scope, listener));
-//    _index.getRelationships(method, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.METHOD_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences10(ParameterElement parameter, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(5, listener);
-//    _index.getRelationships(parameter, IndexConstants.IS_READ_BY, _newCallback(MatchKind.VARIABLE_READ, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_READ_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_WRITE, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.NAMED_PARAMETER_REFERENCE, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
-//  }
-//
-//  void _searchReferences11(PropertyAccessorElement accessor, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener));
-//    _index.getRelationships(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences12(PropertyInducingElement field, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    PropertyAccessorElement getter = field.getter;
-//    PropertyAccessorElement setter = field.setter;
-//    int numRequests = (getter != null ? 4 : 0) + (setter != null ? 2 : 0) + 2;
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(numRequests, listener);
-//    if (getter != null) {
-//      _index.getRelationships(getter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_READ, scope, listener));
-//      _index.getRelationships(getter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_READ, scope, listener));
-//      _index.getRelationships(getter, IndexConstants.IS_INVOKED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_INVOCATION, scope, listener));
-//      _index.getRelationships(getter, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_INVOCATION, scope, listener));
-//    }
-//    if (setter != null) {
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_WRITE, scope, listener));
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_WRITE, scope, listener));
-//    }
-//    _index.getRelationships(field, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FIELD_REFERENCE, scope, listener));
-//    _index.getRelationships(field, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences13(TypeParameterElement typeParameter, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(typeParameter, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.TYPE_PARAMETER_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences14(VariableElement variable, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(4, listener);
-//    _index.getRelationships(variable, IndexConstants.IS_READ_BY, _newCallback(MatchKind.VARIABLE_READ, scope, listener));
-//    _index.getRelationships(variable, IndexConstants.IS_READ_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener));
-//    _index.getRelationships(variable, IndexConstants.IS_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_WRITE, scope, listener));
-//    _index.getRelationships(variable, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
-//  }
-//}
-//
-///**
-// * Instances of the class <code>RelationshipCallbackImpl</code> implement a callback that can be
-// * used to report results to a search listener.
-// */
-//class SearchEngineImpl_RelationshipCallbackImpl implements RelationshipCallback {
-//  final SearchScope _scope;
-//
-//  /**
-//   * The kind of matches that are represented by the results that will be provided to this
-//   * callback.
-//   */
-//  final MatchKind _matchKind;
-//
-//  /**
-//   * The search listener that should be notified when results are found.
-//   */
-//  final SearchListener _listener;
-//
-//  /**
-//   * Initialize a newly created callback to report matches of the given kind to the given listener
-//   * when results are found.
-//   *
-//   * @param scope the [SearchScope] to return matches from, may be `null` to return
-//   *          all matches
-//   * @param matchKind the kind of matches that are represented by the results
-//   * @param listener the search listener that should be notified when results are found
-//   */
-//  SearchEngineImpl_RelationshipCallbackImpl(this._scope, this._matchKind, this._listener);
-//
-//  @override
-//  void hasRelationships(Element element, Relationship relationship, List<Location> locations) {
-//    for (Location location in locations) {
-//      Element targetElement = location.element;
-//      // check scope
-//      if (_scope != null && !_scope.encloses(targetElement)) {
-//        continue;
-//      }
-//      SourceRange range = new SourceRange(location.offset, location.length);
-//      // TODO(scheglov) IndexConstants.DYNAMIC for MatchQuality.NAME
-//      MatchQuality quality = MatchQuality.EXACT;
-//      //          MatchQuality quality = element.getResource() != IndexConstants.DYNAMIC
-//      //              ? MatchQuality.EXACT : MatchQuality.NAME;
-//      SearchMatch match = new SearchMatch(quality, _matchKind, targetElement, range);
-//      match.qualified = identical(relationship, IndexConstants.IS_REFERENCED_BY_QUALIFIED) || identical(relationship, IndexConstants.IS_INVOKED_BY_QUALIFIED);
-//      _listener.matchFound(match);
-//    }
-//    _listener.searchComplete();
-//  }
-//}
-//
-///**
-// * The interface <code>SearchRunner</code> defines the behavior of objects that can be used to
-// * perform an asynchronous search.
-// */
-//abstract class SearchEngineImpl_SearchRunner {
-//  /**
-//   * Perform an asynchronous search, passing the results to the given listener.
-//   *
-//   * @param listener the listener to which search results should be passed @ if the results could
-//   *          not be computed
-//   */
-//  void performSearch(SearchListener listener);
-//}
-//
-///**
-// * The interface <code>SearchListener</code> defines the behavior of objects that are listening for
-// * the results of a search.
-// */
-//abstract class SearchListener {
-//  /**
-//   * Record the fact that the given match was found.
-//   *
-//   * @param match the match that was found
-//   */
-//  void matchFound(SearchMatch match);
-//
-//  /**
-//   * This method is invoked when the search is complete and no additional matches will be found.
-//   */
-//  void searchComplete();
-//}
+import 'package:analysis_services/index/index.dart';
+import 'package:analysis_services/search/search_engine.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
 
-///**
-// * The class <code>SearchPatternFactory</code> defines utility methods that can be used to create
-// * search patterns.
-// */
-//class SearchPatternFactory {
-//  /**
-//   * Create a pattern that will match any element that is matched by all of the given patterns. If
-//   * no patterns are given, then the resulting pattern will not match any elements.
-//   *
-//   * @param patterns the patterns that must all be matched in order for the new pattern to be
-//   *          matched
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createAndPattern(List<SearchPattern> patterns) {
-//    if (patterns.length == 1) {
-//      return patterns[0];
-//    }
-//    return new AndSearchPattern(patterns);
-//  }
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a partial identifier where
-//   * camel case conventions are used to perform what is essentially multiple prefix matches.
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param samePartCount `true` if the pattern and the name being matched must have
-//   *          exactly the same number of parts (i.e. the same number of uppercase characters)
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createCamelCasePattern(String prefix, bool samePartCount) => new CamelCaseSearchPattern(prefix, samePartCount);
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a specified identifier exactly.
-//   *
-//   * @param identifier the identifier that matching elements must be equal to
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createExactPattern(String identifier, bool caseSensitive) => new ExactSearchPattern(identifier, caseSensitive);
-//
-//  /**
-//   * Create a pattern that will match any element that is matched by at least one of the given
-//   * patterns. If no patterns are given, then the resulting pattern will not match any elements.
-//   *
-//   * @param patterns the patterns used to determine whether the new pattern is matched
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createOrPattern(List<SearchPattern> patterns) {
-//    if (patterns.length == 1) {
-//      return patterns[0];
-//    }
-//    return new OrSearchPattern(patterns);
-//  }
-//
-//  /**
-//   * Create a pattern that will match any element whose name starts with the given prefix.
-//   *
-//   * @param prefix the prefix of names that match the pattern
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createPrefixPattern(String prefix, bool caseSensitive) => new PrefixSearchPattern(prefix, caseSensitive);
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a regular expression.
-//   *
-//   * @param regularExpression the regular expression that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createRegularExpressionPattern(String regularExpression, bool caseSensitive) => new RegularExpressionSearchPattern(regularExpression, caseSensitive);
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a pattern containing wildcard
-//   * characters. The wildcard characters that are currently supported are '?' (to match any single
-//   * character) and '*' (to match zero or more characters).
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createWildcardPattern(String pattern, bool caseSensitive) => new WildcardSearchPattern(pattern, caseSensitive);
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  String name;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchDeclarations(this.SearchEngineImpl_this, this.name, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchDeclarations2(name, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchFunctionDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  SearchScope scope;
-//
-//  SearchPattern pattern;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchFunctionDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchFunctionDeclarations2(scope, pattern, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  String name;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences(this.SearchEngineImpl_this, this.name, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchQualifiedMemberReferences2(name, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchReferences implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  Element element;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchReferences(this.SearchEngineImpl_this, this.element, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchReferences2(element, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchSubtypes implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  ClassElement type;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchSubtypes(this.SearchEngineImpl_this, this.type, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchSubtypes2(type, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchTypeDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  SearchScope scope;
-//
-//  SearchPattern pattern;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchTypeDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchTypeDeclarations2(scope, pattern, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchVariableDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  SearchScope scope;
-//
-//  SearchPattern pattern;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchVariableDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchVariableDeclarations2(scope, pattern, filter, listener);
-//  }
-//}
-//
-///**
-// * The class <code>SearchScopeFactory</code> defines utility methods that can be used to create
-// * search scopes.
-// */
-//class SearchScopeFactory {
-//  /**
-//   * A search scope that encompasses everything in the "universe". Because it does not hold any
-//   * state there is no reason not to share a single instance.
-//   */
-//  static SearchScope _UNIVERSE_SCOPE = new UniverseSearchScope();
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given library.
-//   *
-//   * @param library the library defining which elements are included in the scope
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createLibraryScope(Iterable<LibraryElement> libraries) => new LibrarySearchScope.con1(libraries);
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given libraries.
-//   *
-//   * @param libraries the libraries defining which elements are included in the scope
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createLibraryScope2(List<LibraryElement> libraries) => new LibrarySearchScope.con2(libraries);
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given library.
-//   *
-//   * @param library the library defining which elements are included in the scope
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createLibraryScope3(LibraryElement library) => new LibrarySearchScope.con2([library]);
-//
-//  /**
-//   * Create a search scope that encompasses everything in the universe.
-//   *
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createUniverseScope() => _UNIVERSE_SCOPE;
-//}
-//
-///**
-// * The [SearchScope] that encompasses everything in the universe.
-// */
-//class UniverseSearchScope implements SearchScope {
-//  @override
-//  bool encloses(Element element) => true;
-//}
-//
-///**
-// * Instances of the class <code>WildcardSearchPattern</code> implement a search pattern that matches
-// * elements whose name matches a pattern with wildcard characters. The wildcard characters that are
-// * currently supported are '?' (to match any single character) and '*' (to match zero or more
-// * characters).
-// */
-//class WildcardSearchPattern implements SearchPattern {
-//  /**
-//   * The pattern that matching elements must match.
-//   */
-//  List<int> _pattern;
-//
-//  /**
-//   * A flag indicating whether a case sensitive match is to be performed.
-//   */
-//  final bool _caseSensitive;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  WildcardSearchPattern(String pattern, this._caseSensitive) {
-//    this._pattern = _caseSensitive ? pattern.toCharArray() : pattern.toLowerCase().toCharArray();
-//  }
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    if (element == null) {
-//      return null;
-//    }
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (CharOperation.match(_pattern, name.toCharArray(), _caseSensitive)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>ScopedSearchListener</code> implement a search listener that
-// * delegates to another search listener after removing matches that are outside a given scope.
-// */
-//abstract class WrappedSearchListener implements SearchListener {
-//  /**
-//   * The listener being wrapped.
-//   */
-//  SearchListener _baseListener;
-//
-//  /**
-//   * Initialize a newly created search listener to wrap the given listener.
-//   *
-//   * @param listener the search listener being wrapped
-//   */
-//  WrappedSearchListener(SearchListener listener) {
-//    _baseListener = listener;
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    _baseListener.searchComplete();
-//  }
-//
-//  /**
-//   * Pass the given match on to the wrapped listener.
-//   *
-//   * @param match the match to be propagated
-//   */
-//  void propagateMatch(SearchMatch match) {
-//    _baseListener.matchFound(match);
-//  }
-//}
+
+/**
+ * A [SearchEngine] implementation.
+ */
+class SearchEngineImpl implements SearchEngine {
+  final Index _index;
+
+  SearchEngineImpl(this._index);
+
+  @override
+  Future<List<SearchMatch>> searchMemberDeclarations(String name) {
+    NameElement element = new NameElement(name);
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        element,
+        IndexConstants.IS_DEFINED_BY,
+        MatchKind.NAME_DECLARATION);
+    return requestor.merge().then((matches) {
+      return matches.where((match) {
+        return match.element.enclosingElement is ClassElement;
+      }).toList();
+    });
+  }
+
+  @override
+  Future<List<SearchMatch>> searchMemberReferences(String name) {
+    NameElement element = new NameElement(name);
+    _Requestor requestor = new _Requestor(_index);
+    // rought
+//    requestor.add(
+//        element,
+//        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+//        MatchKind.NAME_REFERENCE_RESOLVED);
+//    requestor.add(
+//        element,
+//        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+//        MatchKind.NAME_REFERENCE_UNRESOLVED,
+//        isResolved: false);
+    // granular resolved operations
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED,
+        MatchKind.NAME_INVOCATION_RESOLVED);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_BY_RESOLVED,
+        MatchKind.NAME_READ_RESOLVED);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED,
+        MatchKind.NAME_READ_WRITE_RESOLVED);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED,
+        MatchKind.NAME_WRITE_RESOLVED);
+    // granular unresolved operations
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED,
+        MatchKind.NAME_INVOCATION_UNRESOLVED,
+        isResolved: false);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
+        MatchKind.NAME_READ_UNRESOLVED,
+        isResolved: false);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED,
+        MatchKind.NAME_READ_WRITE_UNRESOLVED,
+        isResolved: false);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED,
+        MatchKind.NAME_WRITE_UNRESOLVED,
+        isResolved: false);
+    // done
+    return requestor.merge();
+  }
+
+  @override
+  Future<List<SearchMatch>> searchReferences(Element element) {
+    if (element.kind == ElementKind.ANGULAR_COMPONENT ||
+        element.kind == ElementKind.ANGULAR_CONTROLLER ||
+        element.kind == ElementKind.ANGULAR_FORMATTER ||
+        element.kind == ElementKind.ANGULAR_PROPERTY ||
+        element.kind == ElementKind.ANGULAR_SCOPE_PROPERTY ||
+        element.kind == ElementKind.ANGULAR_SELECTOR) {
+      return _searchReferences_Angular(element as AngularElement);
+    } else if (element.kind == ElementKind.CLASS) {
+      return _searchReferences_Class(element as ClassElement);
+    } else if (element.kind == ElementKind.COMPILATION_UNIT) {
+      return _searchReferences_CompilationUnit(
+          element as CompilationUnitElement);
+    } else if (element.kind == ElementKind.CONSTRUCTOR) {
+      return _searchReferences_Constructor(element as ConstructorElement);
+    } else if (element.kind == ElementKind.FIELD ||
+        element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
+      return _searchReferences_Field(element as PropertyInducingElement);
+    } else if (element.kind == ElementKind.FUNCTION) {
+      return _searchReferences_Function(element as FunctionElement);
+    } else if (element.kind == ElementKind.GETTER ||
+        element.kind == ElementKind.SETTER) {
+      return _searchReferences_PropertyAccessor(
+          element as PropertyAccessorElement);
+    } else if (element.kind == ElementKind.IMPORT) {
+      return _searchReferences_Import(element as ImportElement);
+    } else if (element.kind == ElementKind.LIBRARY) {
+      return _searchReferences_Library(element as LibraryElement);
+    } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
+      return _searchReferences_LocalVariable(element as LocalVariableElement);
+    } else if (element.kind == ElementKind.METHOD) {
+      return _searchReferences_Method(element as MethodElement);
+    } else if (element.kind == ElementKind.PARAMETER) {
+      return _searchReferences_Parameter(element as ParameterElement);
+    } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
+      return _searchReferences_FunctionTypeAlias(
+          element as FunctionTypeAliasElement);
+    } else if (element.kind == ElementKind.TYPE_PARAMETER) {
+      return _searchReferences_TypeParameter(element as TypeParameterElement);
+    }
+    return new Future.value(<SearchMatch>[]);
+  }
+
+  @override
+  Future<List<SearchMatch>> searchSubtypes(ClassElement type) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        type,
+        IndexConstants.IS_EXTENDED_BY,
+        MatchKind.EXTENDS_REFERENCE);
+    requestor.add(
+        type,
+        IndexConstants.IS_MIXED_IN_BY,
+        MatchKind.WITH_REFERENCE);
+    requestor.add(
+        type,
+        IndexConstants.IS_IMPLEMENTED_BY,
+        MatchKind.IMPLEMENTS_REFERENCE);
+    return requestor.merge();
+  }
+
+  @override
+  Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) {
+    UniverseElement universe = UniverseElement.INSTANCE;
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_CLASS,
+        MatchKind.CLASS_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_CLASS_ALIAS,
+        MatchKind.CLASS_ALIAS_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_FUNCTION_TYPE,
+        MatchKind.FUNCTION_TYPE_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_FUNCTION,
+        MatchKind.FUNCTION_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_VARIABLE,
+        MatchKind.VARIABLE_DECLARATION);
+    RegExp regExp = new RegExp(pattern);
+    return requestor.merge().then((List<SearchMatch> matches) {
+      return matches.where((SearchMatch match) {
+        String name = match.element.displayName;
+        return regExp.hasMatch(name);
+      }).toList();
+    });
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Angular(AngularElement element) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        element,
+        IndexConstants.ANGULAR_REFERENCE,
+        MatchKind.ANGULAR_REFERENCE);
+    requestor.add(
+        element,
+        IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
+        MatchKind.ANGULAR_CLOSING_TAG_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Class(ClassElement clazz) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        clazz,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.TYPE_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_CompilationUnit(CompilationUnitElement unit) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        unit,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.UNIT_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Constructor(ConstructorElement constructor) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        constructor,
+        IndexConstants.IS_DEFINED_BY,
+        MatchKind.CONSTRUCTOR_DECLARATION);
+    requestor.add(
+        constructor,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.CONSTRUCTOR_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Field(PropertyInducingElement field) {
+    PropertyAccessorElement getter = field.getter;
+    PropertyAccessorElement setter = field.setter;
+    _Requestor requestor = new _Requestor(_index);
+    // field itself
+    requestor.add(
+        field,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.FIELD_REFERENCE);
+    requestor.add(
+        field,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        MatchKind.FIELD_REFERENCE);
+    // getter
+    if (getter != null) {
+      requestor.add(
+          getter,
+          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+          MatchKind.FIELD_READ);
+      requestor.add(
+          getter,
+          IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+          MatchKind.FIELD_READ);
+      requestor.add(
+          getter,
+          IndexConstants.IS_INVOKED_BY_QUALIFIED,
+          MatchKind.FIELD_INVOCATION);
+      requestor.add(
+          getter,
+          IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
+          MatchKind.FIELD_INVOCATION);
+    }
+    // setter
+    if (setter != null) {
+      requestor.add(
+          setter,
+          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+          MatchKind.FIELD_WRITE);
+      requestor.add(
+          setter,
+          IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+          MatchKind.FIELD_WRITE);
+    }
+    // done
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Function(FunctionElement function) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        function,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.FUNCTION_REFERENCE);
+    requestor.add(
+        function,
+        IndexConstants.IS_INVOKED_BY,
+        MatchKind.FUNCTION_EXECUTION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_FunctionTypeAlias(FunctionTypeAliasElement alias) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        alias,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.FUNCTION_TYPE_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Import(ImportElement imp) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        imp,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.IMPORT_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Library(LibraryElement library) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        library,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.LIBRARY_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_LocalVariable(LocalVariableElement variable) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(variable, IndexConstants.IS_READ_BY, MatchKind.VARIABLE_READ);
+    requestor.add(
+        variable,
+        IndexConstants.IS_READ_WRITTEN_BY,
+        MatchKind.VARIABLE_READ_WRITE);
+    requestor.add(
+        variable,
+        IndexConstants.IS_WRITTEN_BY,
+        MatchKind.VARIABLE_WRITE);
+    requestor.add(
+        variable,
+        IndexConstants.IS_INVOKED_BY,
+        MatchKind.FUNCTION_EXECUTION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) {
+    _Requestor requestor = new _Requestor(_index);
+    if (method is MethodMember) {
+      method = (method as MethodMember).baseElement;
+    }
+    requestor.add(
+        method,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        MatchKind.METHOD_REFERENCE);
+    requestor.add(
+        method,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        MatchKind.METHOD_REFERENCE);
+    requestor.add(
+        method,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        MatchKind.METHOD_INVOCATION);
+    requestor.add(
+        method,
+        IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
+        MatchKind.METHOD_INVOCATION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Parameter(ParameterElement parameter) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_READ_BY,
+        MatchKind.VARIABLE_READ);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_READ_WRITTEN_BY,
+        MatchKind.VARIABLE_READ_WRITE);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_WRITTEN_BY,
+        MatchKind.VARIABLE_WRITE);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.NAMED_PARAMETER_REFERENCE);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_INVOKED_BY,
+        MatchKind.FUNCTION_EXECUTION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_PropertyAccessor(PropertyAccessorElement accessor) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        accessor,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        MatchKind.PROPERTY_ACCESSOR_REFERENCE);
+    requestor.add(
+        accessor,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        MatchKind.PROPERTY_ACCESSOR_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_TypeParameter(TypeParameterElement typeParameter) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        typeParameter,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.TYPE_PARAMETER_REFERENCE);
+    return requestor.merge();
+  }
+}
+
+
+class _Requestor {
+  final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[];
+  final Index index;
+
+  _Requestor(this.index);
+
+  void add(Element element2, Relationship relationship, MatchKind kind,
+      {bool isResolved: true}) {
+    Future relationsFuture = index.getRelationships(element2, relationship);
+    Future matchesFuture = relationsFuture.then((List<Location> locations) {
+      bool isQualified =
+          relationship == IndexConstants.IS_REFERENCED_BY_QUALIFIED ||
+          relationship == IndexConstants.IS_INVOKED_BY_QUALIFIED;
+      List<SearchMatch> matches = <SearchMatch>[];
+      for (Location location in locations) {
+        Element element = location.element;
+        matches.add(
+            new SearchMatch(
+                kind,
+                element,
+                new SourceRange(location.offset, location.length),
+                isResolved,
+                isQualified));
+      }
+      return matches;
+    });
+    futures.add(matchesFuture);
+  }
+
+  Future<List<SearchMatch>> merge() {
+    return Future.wait(futures).then((List<List<SearchMatch>> matchesList) {
+      return matchesList.expand((matches) => matches).toList();
+    });
+  }
+}
diff --git a/pkg/analysis_services/pubspec.yaml b/pkg/analysis_services/pubspec.yaml
index 66e9ac2..194caf2 100644
--- a/pkg/analysis_services/pubspec.yaml
+++ b/pkg/analysis_services/pubspec.yaml
@@ -1,12 +1,12 @@
 name: analysis_services
-version: 0.1.0
+version: 0.2.0
 author: Dart Team <misc@dartlang.org>
 description: A set of services on top of Analysis Engine
 homepage: http://www.dartlang.org
 environment:
   sdk: '>=1.0.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.21.0 <1.0.0'
+  analyzer: '>=0.21.1 <1.0.0'
 dev_dependencies:
-  analysis_testing: '>=0.2.0 <1.0.0'
+  analysis_testing: '>=0.3.0 <1.0.0'
   unittest: '>=0.10.0 <0.12.0'
diff --git a/pkg/analysis_services/test/index/abstract_single_unit.dart b/pkg/analysis_services/test/index/abstract_single_unit.dart
new file mode 100644
index 0000000..7dc112d
--- /dev/null
+++ b/pkg/analysis_services/test/index/abstract_single_unit.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2014, 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.
+
+library test.services.src.index.abstract_single_file;
+
+import 'package:analysis_testing/abstract_context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:unittest/unittest.dart';
+
+
+class AbstractSingleUnitTest extends AbstractContextTest {
+  bool verifyNoTestUnitErrors = true;
+
+  String testCode;
+  Source testSource;
+  CompilationUnit testUnit;
+  CompilationUnitElement testUnitElement;
+  LibraryElement testLibraryElement;
+
+  void assertNoErrorsInSource(Source source) {
+    List<AnalysisError> errors = context.getErrors(source).errors;
+    expect(errors, isEmpty);
+  }
+
+  Element findElement(String name, [ElementKind kind]) {
+    return findChildElement(testUnitElement, name, kind);
+  }
+
+  AstNode findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
+    AstNode result = new NodeLocator.con1(offset).searchWithin(testUnit);
+    if (result != null && predicate != null) {
+      result = result.getAncestor(predicate);
+    }
+    return result;
+  }
+
+  AstNode findNodeAtString(String search, [Predicate<AstNode> predicate]) {
+    int offset = findOffset(search);
+    return findNodeAtOffset(offset, predicate);
+  }
+
+  Element findNodeElementAtString(String search,
+      [Predicate<AstNode> predicate]) {
+    AstNode node = findNodeAtString(search, predicate);
+    if (node == null) {
+      return null;
+    }
+    return ElementLocator.locate(node);
+  }
+
+  int findOffset(String search) {
+    int offset = testCode.indexOf(search);
+    expect(offset, isNonNegative, reason: "Not found '$search' in\n$testCode");
+    return offset;
+  }
+
+  int getLeadingIdentifierLength(String search) {
+    int length = 0;
+    while (length < search.length) {
+      int c = search.codeUnitAt(length);
+      if (c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0)) {
+        length++;
+        continue;
+      }
+      if (c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0)) {
+        length++;
+        continue;
+      }
+      if (c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0)) {
+        length++;
+        continue;
+      }
+      break;
+    }
+    return length;
+  }
+
+  void resolveTestUnit(String code) {
+    testCode = code;
+    testSource = addSource('/test.dart', code);
+    testUnit = resolveLibraryUnit(testSource);
+    if (verifyNoTestUnitErrors) {
+      assertNoErrorsInSource(testSource);
+    }
+    testUnitElement = testUnit.element;
+    testLibraryElement = testUnitElement.library;
+  }
+}
diff --git a/pkg/analysis_services/test/index/dart_index_contributor_test.dart b/pkg/analysis_services/test/index/dart_index_contributor_test.dart
index 3892d5d..b5087b6 100644
--- a/pkg/analysis_services/test/index/dart_index_contributor_test.dart
+++ b/pkg/analysis_services/test/index/dart_index_contributor_test.dart
@@ -7,16 +7,15 @@
 import 'package:analysis_services/index/index.dart';
 import 'package:analysis_services/index/index_store.dart';
 import 'package:analysis_services/src/index/index_contributor.dart';
-import 'package:analysis_testing/abstract_context.dart';
 import 'package:analysis_testing/reflective_tests.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
+import 'abstract_single_unit.dart';
+
 
 main() {
   groupSep = ' | ';
@@ -30,7 +29,10 @@
  * Returns `true` if the [actual] location the same properties as [expected].
  */
 bool _equalsLocation(Location actual, ExpectedLocation expected) {
-  return _equalsLocationProperties(actual, expected.element, expected.offset,
+  return _equalsLocationProperties(
+      actual,
+      expected.element,
+      expected.offset,
       expected.length);
 }
 
@@ -40,7 +42,8 @@
  */
 bool _equalsLocationProperties(Location actual, Element expectedElement,
     int expectedOffset, int expectedLength) {
-  return expectedElement == actual.element && expectedOffset == actual.offset &&
+  return expectedElement == actual.element &&
+      expectedOffset == actual.offset &&
       expectedLength == actual.length;
 }
 
@@ -48,53 +51,29 @@
 bool _equalsRecordedRelation(RecordedRelation recordedRelation,
     Element expectedElement, Relationship expectedRelationship,
     ExpectedLocation expectedLocation) {
-  return expectedElement == recordedRelation.element && expectedRelationship ==
-      recordedRelation.relationship && (expectedLocation == null || _equalsLocation(
-      recordedRelation.location, expectedLocation));
+  return expectedElement == recordedRelation.element &&
+      expectedRelationship == recordedRelation.relationship &&
+      (expectedLocation == null ||
+          _equalsLocation(recordedRelation.location, expectedLocation));
 }
 
 
-int _getLeadingIdentifierLength(String search) {
-  int length = 0;
-  while (length < search.length) {
-    int c = search.codeUnitAt(length);
-    if (c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0)) {
-      length++;
-      continue;
-    }
-    if (c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0)) {
-      length++;
-      continue;
-    }
-    if (c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0)) {
-      length++;
-      continue;
-    }
-    break;
-  }
-  return length;
-}
-
 @ReflectiveTestCase()
-class DartUnitContributorTest extends AbstractContextTest {
+class DartUnitContributorTest extends AbstractSingleUnitTest {
   IndexStore store = new MockIndexStore();
   List<RecordedRelation> recordedRelations = <RecordedRelation>[];
 
-  bool verifyNoTestUnitErrors = true;
-
-  String testCode;
-  Source testSource;
-  CompilationUnit testUnit;
-  CompilationUnitElement testUnitElement;
-  LibraryElement testLibraryElement;
-
   void setUp() {
     super.setUp();
     when(store.aboutToIndexDart(context, anyObject)).thenReturn(true);
-    when(store.recordRelationship(anyObject, anyObject, anyObject)).thenInvoke(
-        (Element element, Relationship relationship, Location location) {
-      recordedRelations.add(new RecordedRelation(element, relationship,
-          location));
+    when(
+        store.recordRelationship(
+            anyObject,
+            anyObject,
+            anyObject)).thenInvoke(
+                (Element element, Relationship relationship, Location location) {
+      recordedRelations.add(
+          new RecordedRelation(element, relationship, location));
     });
   }
 
@@ -107,21 +86,23 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FieldElement fieldElement = _findElement("myField");
+    Element mainElement = findElement("main");
+    FieldElement fieldElement = findElement("myField");
     PropertyAccessorElement getterElement = fieldElement.getter;
     // verify
-    _assertRecordedRelation(getterElement,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'myField);'));
+    _assertRecordedRelation(
+        getterElement,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'myField);'));
   }
 
   void test_definesClass() {
     _indexTestUnit('class A {}');
     // prepare elements
-    ClassElement classElement = _findElement("A");
+    ClassElement classElement = findElement("A");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_CLASS,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_CLASS,
         _expectedLocation(classElement, 'A {}'));
   }
 
@@ -130,27 +111,30 @@
 class Mix {}
 class MyClass = Object with Mix;''');
     // prepare elements
-    Element classElement = _findElement("MyClass");
+    Element classElement = findElement("MyClass");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_CLASS_ALIAS,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_CLASS_ALIAS,
         _expectedLocation(classElement, 'MyClass ='));
   }
 
   void test_definesFunction() {
     _indexTestUnit('myFunction() {}');
     // prepare elements
-    FunctionElement functionElement = _findElement("myFunction");
+    FunctionElement functionElement = findElement("myFunction");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_FUNCTION,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_FUNCTION,
         _expectedLocation(functionElement, 'myFunction() {}'));
   }
 
   void test_definesFunctionType() {
     _indexTestUnit('typedef MyFunction(int p);');
     // prepare elements
-    FunctionTypeAliasElement typeAliasElement = _findElement("MyFunction");
+    FunctionTypeAliasElement typeAliasElement = findElement("MyFunction");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_FUNCTION_TYPE,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_FUNCTION_TYPE,
         _expectedLocation(typeAliasElement, 'MyFunction(int p);'));
   }
 
@@ -158,9 +142,10 @@
   void test_definesVariable() {
     _indexTestUnit('var myVar = 42;');
     // prepare elements
-    VariableElement varElement = _findElement("myVar");
+    VariableElement varElement = findElement("myVar");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_VARIABLE,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_VARIABLE,
         _expectedLocation(varElement, 'myVar = 42;'));
   }
 
@@ -171,10 +156,12 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    VariableElement variableElement = _findElement("v");
+    Element mainElement = findElement("main");
+    VariableElement variableElement = findElement("v");
     // verify
-    _assertNoRecordedRelation(variableElement, IndexConstants.IS_READ_BY,
+    _assertNoRecordedRelation(
+        variableElement,
+        IndexConstants.IS_READ_BY,
         _expectedLocation(mainElement, 'v in []'));
   }
 
@@ -185,15 +172,19 @@
   A.foo() {}
 }''');
     // prepare elements
-    ClassElement classA = _findElement("A");
-    ConstructorElement consA = _findNodeElementAtString("A()", (node) => node is
-        ConstructorDeclaration);
-    ConstructorElement consA_foo = _findNodeElementAtString("A.foo()", (node) =>
-        node is ConstructorDeclaration);
+    ClassElement classA = findElement("A");
+    ConstructorElement consA =
+        findNodeElementAtString("A()", (node) => node is ConstructorDeclaration);
+    ConstructorElement consA_foo =
+        findNodeElementAtString("A.foo()", (node) => node is ConstructorDeclaration);
     // verify
-    _assertRecordedRelation(consA, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(classA, '() {}'));
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(classA, '.foo() {}', '.foo'.length));
   }
 
@@ -203,10 +194,12 @@
   m() {}
 }''');
     // prepare elements
-    Element methodElement = _findElement("m");
+    Element methodElement = findElement("m");
     Element nameElement = new NameElement("m");
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(methodElement, 'm() {}'));
   }
 
@@ -217,10 +210,12 @@
   operator +(o) {}
 }''');
     // prepare elements
-    Element methodElement = _findElement("+");
+    Element methodElement = findElement("+");
     Element nameElement = new NameElement("+");
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(methodElement, '+(o) {}', 1));
   }
 
@@ -230,10 +225,12 @@
 class B extends A {} // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_EXTENDED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_EXTENDED_BY,
         _expectedLocation(classElementB, 'A {} // 2'));
   }
 
@@ -242,10 +239,12 @@
 class A {} // 1
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
+    ClassElement classElementA = findElement("A");
     ClassElement classElementObject = classElementA.supertype.element;
     // verify
-    _assertRecordedRelation(classElementObject, IndexConstants.IS_EXTENDED_BY,
+    _assertRecordedRelation(
+        classElementObject,
+        IndexConstants.IS_EXTENDED_BY,
         _expectedLocation(classElementA, 'A {}', 0));
   }
 
@@ -256,10 +255,12 @@
 class C = A with B; // 3
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementC = _findElement("C");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementC = findElement("C");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_EXTENDED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_EXTENDED_BY,
         _expectedLocation(classElementC, 'A with'));
   }
 
@@ -269,10 +270,12 @@
 class B implements A {} // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_IMPLEMENTED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_IMPLEMENTED_BY,
         _expectedLocation(classElementB, 'A {} // 2'));
   }
 
@@ -283,10 +286,12 @@
 class C = Object with A implements B; // 3
 ''');
     // prepare elements
-    ClassElement classElementB = _findElement("B");
-    ClassElement classElementC = _findElement("C");
+    ClassElement classElementB = findElement("B");
+    ClassElement classElementC = findElement("C");
     // verify
-    _assertRecordedRelation(classElementB, IndexConstants.IS_IMPLEMENTED_BY,
+    _assertRecordedRelation(
+        classElementB,
+        IndexConstants.IS_IMPLEMENTED_BY,
         _expectedLocation(classElementC, 'B; // 3'));
   }
 
@@ -300,13 +305,14 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FieldElement fieldElement = _findElement("field");
+    Element mainElement = findElement("main");
+    FieldElement fieldElement = findElement("field");
     PropertyAccessorElement getterElement = fieldElement.getter;
     // verify
-    _assertRecordedRelation(getterElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'field();'));
+    _assertRecordedRelation(
+        getterElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'field();'));
   }
 
 
@@ -319,14 +325,18 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element methodElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    Element methodElement = findElement("foo");
     // verify
     var location = _expectedLocation(mainElement, 'foo();');
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-    _assertNoRecordedRelation(methodElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        location);
+    _assertNoRecordedRelation(
+        methodElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        location);
   }
 
   void test_isInvokedByQualified_MethodElement_propagatedType() {
@@ -340,12 +350,13 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element methodElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    Element methodElement = findElement("foo");
     // verify
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'foo();'));
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'foo();'));
   }
 
   void test_isInvokedByUnqualified_MethodElement() {
@@ -357,12 +368,13 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element methodElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    Element methodElement = findElement("foo");
     // verify
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'foo();'));
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'foo();'));
   }
 
   void test_isInvokedBy_FunctionElement() {
@@ -372,10 +384,12 @@
   foo();
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FunctionElement functionElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    FunctionElement functionElement = findElement("foo");
     // verify
-    _assertRecordedRelation(functionElement, IndexConstants.IS_INVOKED_BY,
+    _assertRecordedRelation(
+        functionElement,
+        IndexConstants.IS_INVOKED_BY,
         _expectedLocation(mainElement, 'foo();'));
   }
 
@@ -386,10 +400,12 @@
   v();
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element element = _findElement("v");
+    Element mainElement = findElement("main");
+    Element element = findElement("v");
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY,
         _expectedLocation(mainElement, 'v();'));
   }
 
@@ -399,10 +415,12 @@
   p();
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element element = _findElement("p");
+    Element mainElement = findElement("main");
+    Element element = findElement("p");
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY,
         _expectedLocation(mainElement, 'p();'));
   }
 
@@ -412,10 +430,12 @@
 class B extends Object with A {} // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_MIXED_IN_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_MIXED_IN_BY,
         _expectedLocation(classElementB, 'A {} // 2'));
   }
 
@@ -425,10 +445,12 @@
 class B = Object with A; // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_MIXED_IN_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_MIXED_IN_BY,
         _expectedLocation(classElementB, 'A; // 2'));
   }
 
@@ -439,10 +461,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element parameterElement = _findElement("p");
+    Element mainElement = findElement("main");
+    Element parameterElement = findElement("p");
     // verify
-    _assertRecordedRelation(parameterElement, IndexConstants.IS_READ_BY,
+    _assertRecordedRelation(
+        parameterElement,
+        IndexConstants.IS_READ_BY,
         _expectedLocation(mainElement, 'p);'));
   }
 
@@ -454,10 +478,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element variableElement = _findElement("v");
+    Element mainElement = findElement("main");
+    Element variableElement = findElement("v");
     // verify
-    _assertRecordedRelation(variableElement, IndexConstants.IS_READ_BY,
+    _assertRecordedRelation(
+        variableElement,
+        IndexConstants.IS_READ_BY,
         _expectedLocation(mainElement, 'v);'));
   }
 
@@ -468,10 +494,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element parameterElement = _findElement("p");
+    Element mainElement = findElement("main");
+    Element parameterElement = findElement("p");
     // verify
-    _assertRecordedRelation(parameterElement, IndexConstants.IS_READ_WRITTEN_BY,
+    _assertRecordedRelation(
+        parameterElement,
+        IndexConstants.IS_READ_WRITTEN_BY,
         _expectedLocation(mainElement, 'p += 1'));
   }
 
@@ -483,10 +511,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element variableElement = _findElement("v");
+    Element mainElement = findElement("main");
+    Element variableElement = findElement("v");
     // verify
-    _assertRecordedRelation(variableElement, IndexConstants.IS_READ_WRITTEN_BY,
+    _assertRecordedRelation(
+        variableElement,
+        IndexConstants.IS_READ_WRITTEN_BY,
         _expectedLocation(mainElement, 'v += 1'));
   }
 
@@ -500,12 +530,13 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     Element nameElement = new NameElement('field');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, 'field);'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, 'field);'));
   }
 
   void test_isReferencedByQualifiedResolved_NameElement_method() {
@@ -518,12 +549,13 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     Element nameElement = new NameElement('method');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, 'method();'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, 'method();'));
   }
 
   void test_isReferencedByQualifiedResolved_NameElement_operator() {
@@ -546,34 +578,42 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // binary
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '+ 5', '+'.length));
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '+= 5', '+='.length));
-    _assertRecordedRelation(new NameElement('=='),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '== 5', '=='.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '+ 5', '+'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '+= 5', '+='.length));
+    _assertRecordedRelation(
+        new NameElement('=='),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '== 5', '=='.length));
     // prefix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '++a', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '--a', '--'.length));
-    _assertRecordedRelation(new NameElement('~'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '~a', '~'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '++a', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '--a', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('~'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '~a', '~'.length));
     // postfix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '++;', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '--;', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '++;', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '--;', '--'.length));
   }
 
   void test_isReferencedByQualifiedUnresolved_NameElement_field() {
@@ -586,15 +626,18 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    FieldElement fieldElement = _findElement('field');
+    Element mainElement = findElement('main');
+    FieldElement fieldElement = findElement('field');
     Element nameElement = new NameElement('field');
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(fieldElement, 'field;'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, 'field);'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, 'field);'));
   }
 
   void test_isReferencedByQualifiedUnresolved_NameElement_method() {
@@ -607,15 +650,18 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    MethodElement methodElement = _findElement('method');
+    Element mainElement = findElement('main');
+    MethodElement methodElement = findElement('method');
     Element nameElement = new NameElement('method');
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(methodElement, 'method() {}'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, 'method();'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, 'method();'));
   }
 
   void test_isReferencedByQualifiedUnresolved_NameElement_operator() {
@@ -638,34 +684,42 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // binary
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '+ 5', '+'.length));
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '+= 5', '+='.length));
-    _assertRecordedRelation(new NameElement('=='),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '== 5', '=='.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '+ 5', '+'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '+= 5', '+='.length));
+    _assertRecordedRelation(
+        new NameElement('=='),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '== 5', '=='.length));
     // prefix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '++a', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '--a', '--'.length));
-    _assertRecordedRelation(new NameElement('~'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '~a', '~'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '++a', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '--a', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('~'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '~a', '~'.length));
     // postfix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '++;', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '--;', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '++;', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '--;', '--'.length));
   }
 
   void test_isReferencedByQualified_ConstructorElement() {
@@ -685,27 +739,37 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     var isConstructor = (node) => node is ConstructorDeclaration;
-    ConstructorElement consA = _findNodeElementAtString("A()", isConstructor);
-    ConstructorElement consA_foo = _findNodeElementAtString("A.foo()",
-        isConstructor);
-    ConstructorElement consB = _findNodeElementAtString("B()", isConstructor);
-    ConstructorElement consB_foo = _findNodeElementAtString("B.foo()",
-        isConstructor);
-    ConstructorElement consB_bar = _findNodeElementAtString("B.bar()",
-        isConstructor);
+    ConstructorElement consA = findNodeElementAtString("A()", isConstructor);
+    ConstructorElement consA_foo =
+        findNodeElementAtString("A.foo()", isConstructor);
+    ConstructorElement consB = findNodeElementAtString("B()", isConstructor);
+    ConstructorElement consB_foo =
+        findNodeElementAtString("B.foo()", isConstructor);
+    ConstructorElement consB_bar =
+        findNodeElementAtString("B.bar()", isConstructor);
     // A()
-    _assertRecordedRelation(consA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(consB, '(); // marker-1', 0));
-    _assertRecordedRelation(consA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '(); // marker-main-1', 0));
     // A.foo()
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(consB_foo, '.foo(); // marker-2', '.foo'.length));
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(consB_bar, '.foo; // marker-3', '.foo'.length));
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '.foo(); // marker-main-2', '.foo'.length));
   }
 
@@ -723,15 +787,19 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     var isConstructor = (node) => node is ConstructorDeclaration;
-    ConstructorElement consA = _findNodeElementAtString("A()", isConstructor);
-    ConstructorElement consA_named = _findNodeElementAtString("A.named()",
-        isConstructor);
+    ConstructorElement consA = findNodeElementAtString("A()", isConstructor);
+    ConstructorElement consA_named =
+        findNodeElementAtString("A.named()", isConstructor);
     // verify
-    _assertRecordedRelation(consA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '(); // marker-main-1', 0));
-    _assertRecordedRelation(consA_named, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_named,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '.named(); // marker-main-2', '.named'.length));
   }
 
@@ -745,13 +813,14 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    FieldElement fieldElement = _findElement('field');
+    Element mainElement = findElement('main');
+    FieldElement fieldElement = findElement('field');
     PropertyAccessorElement setterElement = fieldElement.setter;
     // verify
-    _assertRecordedRelation(setterElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'field = 1'));
+    _assertRecordedRelation(
+        setterElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'field = 1'));
   }
 
   void test_isReferencedByQualified_MethodElement() {
@@ -764,12 +833,13 @@
 }
 ''');
     // prepare elements
-    Element fooElement = _findElement('foo');
-    Element mainElement = _findElement('main');
+    Element fooElement = findElement('foo');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(fooElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'foo);'));
+    _assertRecordedRelation(
+        fooElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'foo);'));
   }
 
   void test_isReferencedByQualified_MethodElement_operator_binary() {
@@ -785,16 +855,24 @@
 }
 ''');
     // prepare elements
-    Element element = _findElement('+');
-    Element mainElement = _findElement('main');
+    Element element = findElement('+');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '+ 1', "+".length));
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '+= 2', "+=".length));
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '++a;', "++".length));
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '++;', "++".length));
   }
 
@@ -810,15 +888,18 @@
 }
 ''');
     // prepare elements
-    MethodElement readElement = _findElement("[]");
-    MethodElement writeElement = _findElement("[]=");
-    Element mainElement = _findElement('main');
+    MethodElement readElement = findElement("[]");
+    MethodElement writeElement = findElement("[]=");
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(readElement, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        readElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '[0]', "[".length));
-    _assertRecordedRelation(writeElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, _expectedLocation(mainElement, '[1] =',
-        "[".length));
+    _assertRecordedRelation(
+        writeElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        _expectedLocation(mainElement, '[1] =', "[".length));
   }
 
   void test_isReferencedByQualified_MethodElement_operator_prefix() {
@@ -831,10 +912,12 @@
 }
 ''');
     // prepare elements
-    MethodElement element = _findElement("~");
-    Element mainElement = _findElement('main');
+    MethodElement element = findElement("~");
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '~a', "~".length));
   }
 
@@ -848,10 +931,12 @@
 }
 ''');
     // prepare elements
-    PropertyAccessorElement element = _findNodeElementAtString('foo =>');
-    Element mainElement = _findElement('main');
+    PropertyAccessorElement element = findNodeElementAtString('foo =>');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'foo);'));
     _assertNoRecordedRelation(element, IndexConstants.IS_REFERENCED_BY, null);
   }
@@ -866,10 +951,12 @@
 }
 ''');
     // prepare elements
-    PropertyAccessorElement element = _findNodeElementAtString('foo(x)');
-    Element mainElement = _findElement('main');
+    PropertyAccessorElement element = findNodeElementAtString('foo(x)');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'foo = 42;'));
     _assertNoRecordedRelation(element, IndexConstants.IS_REFERENCED_BY, null);
   }
@@ -887,7 +974,7 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     ImportElement importElement = testLibraryElement.imports[0];
     CompilationUnitElement impUnit =
         importElement.importedLibrary.definingCompilationUnit;
@@ -895,9 +982,13 @@
     PropertyAccessorElement getter = myVar.getter;
     PropertyAccessorElement setter = myVar.setter;
     // verify
-    _assertRecordedRelation(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        setter,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'myVar = 1'));
-    _assertRecordedRelation(getter, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        getter,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'myVar);'));
   }
 
@@ -911,14 +1002,18 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FieldElement fieldElement = _findElement("field");
+    Element mainElement = findElement("main");
+    FieldElement fieldElement = findElement("field");
     PropertyAccessorElement getter = fieldElement.getter;
     PropertyAccessorElement setter = fieldElement.setter;
     // verify
-    _assertRecordedRelation(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+    _assertRecordedRelation(
+        setter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
         _expectedLocation(mainElement, 'field = 5'));
-    _assertRecordedRelation(getter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+    _assertRecordedRelation(
+        getter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
         _expectedLocation(mainElement, 'field);'));
   }
 
@@ -931,13 +1026,16 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    MethodElement methodElement = _findElement("method");
+    Element mainElement = findElement("main");
+    MethodElement methodElement = findElement("method");
     // verify
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'method);'));
-    _assertNoRecordedRelation(methodElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'method);'));
+    _assertNoRecordedRelation(
+        methodElement,
+        IndexConstants.IS_REFERENCED_BY,
         null);
   }
 
@@ -949,15 +1047,17 @@
   print(topVariable);
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    TopLevelVariableElement variableElement = _findElement("topVariable");
+    Element mainElement = findElement("main");
+    TopLevelVariableElement variableElement = findElement("topVariable");
     // verify
-    _assertRecordedRelation(variableElement.setter,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'topVariable = 5'));
-    _assertRecordedRelation(variableElement.getter,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'topVariable);'));
+    _assertRecordedRelation(
+        variableElement.setter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'topVariable = 5'));
+    _assertRecordedRelation(
+        variableElement.getter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'topVariable);'));
   }
 
   void test_isReferencedBy_ClassElement() {
@@ -973,20 +1073,30 @@
 }
 ''');
     // prepare elements
-    ClassElement aElement = _findElement("A");
-    Element mainElement = _findElement("main");
-    ParameterElement pElement = _findElement("p");
-    VariableElement vElement = _findElement("v");
+    ClassElement aElement = findElement("A");
+    Element mainElement = findElement("main");
+    ParameterElement pElement = findElement("p");
+    VariableElement vElement = findElement("v");
     // verify
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(pElement, 'A p) {'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(vElement, 'A v;'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'A(); // 2'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'A.field = 1;'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'A.field); // 3'));
   }
 
@@ -999,13 +1109,17 @@
 }
 ''');
     // prepare elements
-    ClassElement bElement = _findElement("B");
-    ParameterElement pElement = _findElement("p");
-    VariableElement vElement = _findElement("v");
+    ClassElement bElement = findElement("B");
+    ParameterElement pElement = findElement("p");
+    VariableElement vElement = findElement("v");
     // verify
-    _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        bElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(pElement, 'B p) {'));
-    _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        bElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(vElement, 'B v;'));
   }
 
@@ -1018,7 +1132,9 @@
     // prepare elements
     CompilationUnitElement myUnitElement = testLibraryElement.parts[0];
     // verify
-    _assertRecordedRelation(myUnitElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        myUnitElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "'my_unit.dart';", "'my_unit.dart'".length));
   }
 
@@ -1030,11 +1146,13 @@
 }
 ''');
     // prepare elements
-    ConstructorElement constructorElement = _findNodeElementAtString("A()",
-        (node) => node is ConstructorDeclaration);
-    FieldElement fieldElement = _findElement("field");
+    ConstructorElement constructorElement =
+        findNodeElementAtString("A()", (node) => node is ConstructorDeclaration);
+    FieldElement fieldElement = findElement("field");
     // verify
-    _assertRecordedRelation(fieldElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        fieldElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(constructorElement, 'field = 5'));
   }
 
@@ -1046,12 +1164,32 @@
 }
 ''');
     // prepare elements
-    FieldElement fieldElement = _findElement("field");
-    Element fieldParameterElement = _findNodeElementAtString("field);");
+    FieldElement fieldElement = findElement("field");
+    Element fieldParameterElement = findNodeElementAtString("field);");
     // verify
-    _assertRecordedRelation(fieldElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, _expectedLocation(
-        fieldParameterElement, 'field);'));
+    _assertRecordedRelation(
+        fieldElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(fieldParameterElement, 'field);'));
+  }
+
+  void test_isReferencedBy_TopLevelVariableElement() {
+    addSource('/lib.dart', '''
+library lib;
+var V;
+''');
+    _indexTestUnit('''
+import 'lib.dart' show V; // imp
+''');
+    // prepare elements
+    var libElement = testLibraryElement.imports[0].importedLibrary;
+    var libUnit = libElement.definingCompilationUnit;
+    TopLevelVariableElement fieldElement = libUnit.topLevelVariables[0];
+    // verify
+    _assertRecordedRelation(
+        fieldElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(testUnitElement, 'V; // imp'));
   }
 
   void test_isReferencedBy_FunctionElement() {
@@ -1063,16 +1201,22 @@
 }
 ''');
     // prepare elements
-    FunctionElement element = _findElement("foo");
-    Element mainElement = _findElement("main");
+    FunctionElement element = findElement("foo");
+    Element mainElement = findElement("main");
     // "referenced" here
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'foo);'));
     // only "invoked", but not "referenced"
     {
-      _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY,
+      _assertRecordedRelation(
+          element,
+          IndexConstants.IS_INVOKED_BY,
           _expectedLocation(mainElement, 'foo());'));
-      _assertNoRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+      _assertNoRecordedRelation(
+          element,
+          IndexConstants.IS_REFERENCED_BY,
           _expectedLocation(mainElement, 'foo());'));
     }
   }
@@ -1084,10 +1228,12 @@
 }
 ''');
     // prepare elements
-    Element aElement = _findElement('A');
-    Element pElement = _findElement('p');
+    Element aElement = findElement('A');
+    Element pElement = findElement('p');
     // verify
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(pElement, 'A p) {'));
   }
 
@@ -1108,20 +1254,32 @@
 ''');
     // prepare elements
     ImportElement importElement = testLibraryElement.imports[0];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'myVar = 1;', 0));
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'myFunction();', 0));
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'print(0);', 0));
     // no references from import combinators
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'myVar, ', 0));
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'myFunction hide', 0));
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'myToHide;', 0));
   }
 
@@ -1145,11 +1303,15 @@
     // prepare elements
     ImportElement importElementA = testLibraryElement.imports[0];
     ImportElement importElementB = testLibraryElement.imports[1];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElementA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.myVar = 1;', 'pref.'.length));
-    _assertRecordedRelation(importElementB, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementB,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.MyClass();', 'pref.'.length));
   }
 
@@ -1172,11 +1334,15 @@
     // prepare elements
     ImportElement importElementA = testLibraryElement.imports[0];
     ImportElement importElementB = testLibraryElement.imports[1];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElementA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.A();', 'pref.'.length));
-    _assertRecordedRelation(importElementB, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementB,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.B();', 'pref.'.length));
   }
 
@@ -1193,9 +1359,11 @@
 ''');
     // prepare elements
     ImportElement importElement = testLibraryElement.imports[0];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.myFunc();', 'pref.'.length));
   }
 
@@ -1213,9 +1381,11 @@
 ''');
     // prepare elements
     ImportElement importElement = testLibraryElement.imports[0];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.A();', 'pref.'.length));
   }
 
@@ -1260,10 +1430,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    Element element = _findElement('L');
+    Element mainElement = findElement('main');
+    Element element = findElement('L');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'L;'));
   }
 
@@ -1278,7 +1450,9 @@
     LibraryElement libElement = testLibraryElement.exportedLibraries[0];
     CompilationUnitElement libUnitElement = libElement.definingCompilationUnit;
     // verify
-    _assertRecordedRelation(libUnitElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        libUnitElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "'lib.dart'", "'lib.dart'".length));
   }
 
@@ -1293,7 +1467,9 @@
     LibraryElement libElement = testLibraryElement.imports[0].importedLibrary;
     CompilationUnitElement libUnitElement = libElement.definingCompilationUnit;
     // verify
-    _assertRecordedRelation(libUnitElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        libUnitElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "'lib.dart'", "'lib.dart'".length));
   }
 
@@ -1305,10 +1481,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    Element element = _findElement('p');
+    Element mainElement = findElement('main');
+    Element element = findElement('p');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'p: 1'));
   }
 
@@ -1322,17 +1500,23 @@
 }
 ''');
     // prepare elements
-    Element typeParameterElement = _findElement('T');
-    Element fieldElement = _findElement('f');
-    Element parameterElement = _findElement('p');
-    Element variableElement = _findElement('v');
+    Element typeParameterElement = findElement('T');
+    Element fieldElement = findElement('f');
+    Element parameterElement = findElement('p');
+    Element variableElement = findElement('v');
     // verify
-    _assertRecordedRelation(typeParameterElement,
-        IndexConstants.IS_REFERENCED_BY, _expectedLocation(fieldElement, 'T f'));
-    _assertRecordedRelation(typeParameterElement,
-        IndexConstants.IS_REFERENCED_BY, _expectedLocation(parameterElement, 'T p'));
-    _assertRecordedRelation(typeParameterElement,
-        IndexConstants.IS_REFERENCED_BY, _expectedLocation(variableElement, 'T v'));
+    _assertRecordedRelation(
+        typeParameterElement,
+        IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(fieldElement, 'T f'));
+    _assertRecordedRelation(
+        typeParameterElement,
+        IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(parameterElement, 'T p'));
+    _assertRecordedRelation(
+        typeParameterElement,
+        IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(variableElement, 'T v'));
   }
 
   /**
@@ -1349,12 +1533,16 @@
 var myVariable = null;
 ''');
     // prepare elements
-    Element aElement = _findElement('A');
-    Element variableElement = _findElement('myVariable');
+    Element aElement = findElement('A');
+    Element variableElement = findElement('myVariable');
     // verify
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'A] text'));
-    _assertNoRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(variableElement, 'A] text'));
   }
 
@@ -1370,7 +1558,9 @@
     testLibraryElement = testUnitElement.library;
     indexDartUnit(store, context, testUnit);
     // verify
-    _assertRecordedRelation(testLibraryElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        testLibraryElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "lib;"));
   }
 
@@ -1380,10 +1570,12 @@
 A myVariable = null;
 ''');
     // prepare elements
-    Element classElementA = _findElement('A');
-    Element variableElement = _findElement('myVariable');
+    Element classElementA = findElement('A');
+    Element variableElement = findElement('myVariable');
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(variableElement, 'A myVariable'));
   }
 
@@ -1393,10 +1585,12 @@
   p = 1;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    ParameterElement pElement = _findElement("p");
+    Element mainElement = findElement("main");
+    ParameterElement pElement = findElement("p");
     // verify
-    _assertRecordedRelation(pElement, IndexConstants.IS_WRITTEN_BY,
+    _assertRecordedRelation(
+        pElement,
+        IndexConstants.IS_WRITTEN_BY,
         _expectedLocation(mainElement, 'p = 1'));
   }
 
@@ -1407,10 +1601,12 @@
   v = 1;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    LocalVariableElement vElement = _findElement("v");
+    Element mainElement = findElement("main");
+    LocalVariableElement vElement = findElement("v");
     // verify
-    _assertRecordedRelation(vElement, IndexConstants.IS_WRITTEN_BY,
+    _assertRecordedRelation(
+        vElement,
+        IndexConstants.IS_WRITTEN_BY,
         _expectedLocation(mainElement, 'v = 1'));
   }
 
@@ -1424,18 +1620,21 @@
   p.test(2);
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED, _expectedLocation(mainElement,
-        'test(1)'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test(2)'));
-    _assertNoRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test(2)'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test(1)'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test(2)'));
+    _assertNoRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test(2)'));
   }
 
   void test_nameIsReadBy() {
@@ -1448,15 +1647,17 @@
   print(p.test); // p
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_BY_RESOLVED, _expectedLocation(mainElement,
-        'test); // a'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test); // p'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test); // a'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test); // p'));
   }
 
   void test_nameIsReadWrittenBy() {
@@ -1469,15 +1670,17 @@
   p.test += 2;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED, _expectedLocation(mainElement,
-        'test += 1'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED, _expectedLocation(
-        mainElement, 'test += 2'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test += 1'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test += 2'));
   }
 
   void test_nameIsWrittenBy() {
@@ -1490,15 +1693,17 @@
   p.test = 2;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED, _expectedLocation(mainElement,
-        'test = 1'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test = 2'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test = 1'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test = 2'));
   }
 
   void test_nullUnit() {
@@ -1513,25 +1718,25 @@
   void _assertDefinesTopLevelElement(Relationship relationship,
       ExpectedLocation expectedLocation) {
     _assertRecordedRelation(testLibraryElement, relationship, expectedLocation);
-    _assertRecordedRelation(UniverseElement.INSTANCE, relationship,
+    _assertRecordedRelation(
+        UniverseElement.INSTANCE,
+        relationship,
         expectedLocation);
   }
 
-  void _assertNoErrorsInSource() {
-    List<AnalysisError> errors = context.getErrors(testSource).errors;
-    expect(errors, isEmpty);
-  }
-
   /**
    * Asserts that [recordedRelations] has no item with the specified properties.
    */
   void _assertNoRecordedRelation(Element element, Relationship relationship,
       ExpectedLocation location) {
     for (RecordedRelation recordedRelation in recordedRelations) {
-      if (_equalsRecordedRelation(recordedRelation, element, relationship,
+      if (_equalsRecordedRelation(
+          recordedRelation,
+          element,
+          relationship,
           location)) {
-        fail('not expected: ${recordedRelation} in\n' + recordedRelations.join(
-            '\n'));
+        fail(
+            'not expected: ${recordedRelation} in\n' + recordedRelations.join('\n'));
       }
     }
   }
@@ -1542,66 +1747,32 @@
   Location _assertRecordedRelation(Element expectedElement,
       Relationship expectedRelationship, ExpectedLocation expectedLocation) {
     for (RecordedRelation recordedRelation in recordedRelations) {
-      if (_equalsRecordedRelation(recordedRelation, expectedElement,
-          expectedRelationship, expectedLocation)) {
+      if (_equalsRecordedRelation(
+          recordedRelation,
+          expectedElement,
+          expectedRelationship,
+          expectedLocation)) {
         return recordedRelation.location;
       }
     }
-    fail("not found\n$expectedElement $expectedRelationship "
-        "in $expectedLocation in\n" + recordedRelations.join('\n'));
+    fail(
+        "not found\n$expectedElement $expectedRelationship " "in $expectedLocation in\n"
+            +
+            recordedRelations.join('\n'));
     return null;
   }
 
   ExpectedLocation _expectedLocation(Element element, String search, [int length
       = -1]) {
-    int offset = _findOffset(search);
+    int offset = findOffset(search);
     if (length == -1) {
-      length = _getLeadingIdentifierLength(search);
+      length = getLeadingIdentifierLength(search);
     }
     return new ExpectedLocation(element, offset, length);
   }
 
-  Element _findElement(String name, [ElementKind kind]) {
-    return findChildElement(testUnitElement, name, kind);
-  }
-
-  AstNode _findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
-    AstNode result = new NodeLocator.con1(offset).searchWithin(testUnit);
-    if (result != null && predicate != null) {
-      result = result.getAncestor(predicate);
-    }
-    return result;
-  }
-
-  AstNode _findNodeAtString(String search, [Predicate<AstNode> predicate]) {
-    int offset = _findOffset(search);
-    return _findNodeAtOffset(offset, predicate);
-  }
-
-  Element _findNodeElementAtString(String search,
-      [Predicate<AstNode> predicate]) {
-    AstNode node = _findNodeAtString(search, predicate);
-    if (node == null) {
-      return null;
-    }
-    return ElementLocator.locate(node);
-  }
-
-  int _findOffset(String search) {
-    int offset = testCode.indexOf(search);
-    expect(offset, isNonNegative, reason: "Not found '$search' in\n$testCode");
-    return offset;
-  }
-
   void _indexTestUnit(String code) {
-    testCode = code;
-    testSource = addSource('/test.dart', code);
-    testUnit = resolveLibraryUnit(testSource);
-    if (verifyNoTestUnitErrors) {
-      _assertNoErrorsInSource();
-    }
-    testUnitElement = testUnit.element;
-    testLibraryElement = testUnitElement.library;
+    resolveTestUnit(code);
     indexDartUnit(store, context, testUnit);
   }
 }
diff --git a/pkg/analysis_services/test/index/store/codec_test.dart b/pkg/analysis_services/test/index/store/codec_test.dart
index 1b4dc6a..c72cb60 100644
--- a/pkg/analysis_services/test/index/store/codec_test.dart
+++ b/pkg/analysis_services/test/index/store/codec_test.dart
@@ -10,9 +10,10 @@
 import 'package:analysis_testing/reflective_tests.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
+import '../abstract_single_unit.dart';
+
 
 main() {
   groupSep = ' | ';
@@ -71,78 +72,115 @@
 
 
 @ReflectiveTestCase()
-class _ElementCodecTest {
+class _ElementCodecTest extends AbstractSingleUnitTest {
   ElementCodec codec;
   AnalysisContext context = new MockAnalysisContext('context');
   StringCodec stringCodec = new StringCodec();
 
   void setUp() {
+    super.setUp();
     codec = new ElementCodec(stringCodec);
   }
 
+  void test_field() {
+    resolveTestUnit('''
+class A {
+  int field;
+}
+''');
+    FieldElement field = findElement('field', ElementKind.FIELD);
+    PropertyAccessorElement getter = field.getter;
+    PropertyAccessorElement setter = field.setter;
+    {
+      int id = codec.encode(getter);
+      expect(codec.decode(context, id), getter);
+    }
+    {
+      int id = codec.encode(setter);
+      expect(codec.decode(context, id), setter);
+    }
+    {
+      int id = codec.encode(field);
+      expect(codec.decode(context, id), field);
+    }
+  }
+
   void test_localLocalVariable() {
+    resolveTestUnit('''
+main() {
+  {
+    foo() {
+      int bar; // A
+    }
+  }
+  {
+    foo() {
+      int bar; // B
+    }
+  }
+}
+''');
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main', 'foo@1',
-          'bar@2']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('bar; // A', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main', 'foo@10',
-          'bar@20']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('bar; // B', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
-    // check strings, "foo" as a single string, no "foo@1" or "foo@10"
-    expect(stringCodec.nameToIndex, hasLength(3));
-    expect(stringCodec.nameToIndex, containsPair('main', 0));
-    expect(stringCodec.nameToIndex, containsPair('foo', 1));
-    expect(stringCodec.nameToIndex, containsPair('bar', 2));
+    // check strings, "foo" as a single string, no "foo@17" or "bar@35"
+    expect(stringCodec.nameToIndex, hasLength(4));
+    expect(stringCodec.nameToIndex, containsPair('f/test.dart', 0));
+    expect(stringCodec.nameToIndex, containsPair('main', 1));
+    expect(stringCodec.nameToIndex, containsPair('foo', 2));
+    expect(stringCodec.nameToIndex, containsPair('bar', 3));
   }
 
   void test_localVariable() {
+    resolveTestUnit('''
+main() {
+  {
+    int foo; // A
+  }
+  {
+    int foo; // B
+  }
+}
+''');
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main',
-          'foo@42']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('foo; // A', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main',
-          'foo@4200']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('foo; // B', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
-    // check strings, "foo" as a single string, no "foo@42" or "foo@4200"
-    expect(stringCodec.nameToIndex, hasLength(2));
-    expect(stringCodec.nameToIndex, containsPair('main', 0));
-    expect(stringCodec.nameToIndex, containsPair('foo', 1));
+    // check strings, "foo" as a single string, no "foo@21" or "foo@47"
+    expect(stringCodec.nameToIndex, hasLength(3));
+    expect(stringCodec.nameToIndex, containsPair('f/test.dart', 0));
+    expect(stringCodec.nameToIndex, containsPair('main', 1));
+    expect(stringCodec.nameToIndex, containsPair('foo', 2));
   }
 
   void test_notLocal() {
-    Element element = new MockElement();
-    ElementLocation location = new ElementLocationImpl.con3(['foo', 'bar']);
-    when(element.location).thenReturn(location);
-    when(context.getElement(location)).thenReturn(element);
+    resolveTestUnit('''
+main() {
+  int foo;
+}
+''');
+    LocalVariableElement element = findElement('foo');
     int id = codec.encode(element);
     expect(codec.encode(element), id);
     expect(codec.decode(context, id), element);
     // check strings
-    expect(stringCodec.nameToIndex, hasLength(2));
-    expect(stringCodec.nameToIndex, containsPair('foo', 0));
-    expect(stringCodec.nameToIndex, containsPair('bar', 1));
+    expect(stringCodec.nameToIndex, hasLength(3));
+    expect(stringCodec.nameToIndex, containsPair('f/test.dart', 0));
+    expect(stringCodec.nameToIndex, containsPair('main', 1));
+    expect(stringCodec.nameToIndex, containsPair('foo', 2));
   }
 }
 
diff --git a/pkg/analysis_services/test/search/search_engine_test.dart b/pkg/analysis_services/test/search/search_engine_test.dart
index db896c9..f6d02de9 100644
--- a/pkg/analysis_services/test/search/search_engine_test.dart
+++ b/pkg/analysis_services/test/search/search_engine_test.dart
@@ -5,2144 +5,659 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
-library engine.search_engine_test;
+library services.src.search.search_engine_test;
+
+import 'dart:async';
+
+import 'package:analysis_services/index/index.dart';
+import 'package:analysis_services/index/local_memory_index.dart';
+import 'package:analysis_services/search/search_engine.dart';
+import 'package:analysis_services/src/search/search_engine.dart';
+import 'package:analysis_testing/mocks.dart';
+import 'package:analysis_testing/reflective_tests.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:typed_mock/typed_mock.dart';
+import 'package:unittest/unittest.dart';
+
+import '../index/abstract_single_unit.dart';
 
 
 main() {
+  groupSep = ' | ';
+  group('SearchEngineImplTest', () {
+    runReflectiveTests(SearchEngineImplTest);
+  });
+}
+
+class ExpectedMatch {
+  final Element element;
+  final MatchKind kind;
+  SourceRange range;
+  final bool isResolved;
+  final bool isQualified;
+
+  ExpectedMatch(this.element, this.kind, int offset, int length,
+      {this.isResolved: true, this.isQualified: false}) {
+    this.range = new SourceRange(offset, length);
+  }
+
+  bool operator ==(SearchMatch match) {
+    return match.element == this.element &&
+        match.kind == this.kind &&
+        match.isResolved == this.isResolved &&
+        match.isQualified == this.isQualified &&
+        match.sourceRange == this.range;
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("ExpectedMatch(kind=");
+    buffer.write(kind);
+    buffer.write(", element=");
+    buffer.write(element != null ? element.displayName : 'null');
+    buffer.write(", range=");
+    buffer.write(range);
+    buffer.write(", isResolved=");
+    buffer.write(isResolved);
+    buffer.write(", isQualified=");
+    buffer.write(isQualified);
+    buffer.write(")");
+    return buffer.toString();
+  }
 }
 
 
-//class AndSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  SearchPattern _patternA = mock(SearchPattern);
-//
-//  SearchPattern _patternB = mock(SearchPattern);
-//
-//  AndSearchPattern _pattern = new AndSearchPattern([_patternA, _patternB]);
-//
-//  void test_allExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
+class MockAngularComponentElement extends TypedMock implements
+    AngularComponentElement {
+  final kind = ElementKind.ANGULAR_COMPONENT;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockAngularControllerElement extends TypedMock implements
+    AngularControllerElement {
+  final kind = ElementKind.ANGULAR_CONTROLLER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockAngularFormatterElement extends TypedMock implements
+    AngularFormatterElement {
+  final kind = ElementKind.ANGULAR_FORMATTER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockIndex extends TypedMock implements Index {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+@ReflectiveTestCase()
+class SearchEngineImplTest extends AbstractSingleUnitTest {
+  Index index;
+  SearchEngineImpl searchEngine;
+
+//  void mockLocation(Element element, Relationship relationship,
+//      Location location) {
+//    mockLocations(element, relationship, [location]);
 //  }
 //
-//  void test_ExactName() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.NAME);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
+//  void mockLocations(Element element, Relationship relationship,
+//      List<Location> locations) {
+//    index.getRelationships(element, relationship);
+//    when(null).thenReturn(new Future.value(locations));
 //  }
-//
-//  void test_NameExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.NAME);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
-//  }
-//
-//  void test_oneNull() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, _pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('AndSearchPatternTest', () {
-//      _ut.test('test_ExactName', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_ExactName);
-//      });
-//      _ut.test('test_NameExact', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_NameExact);
-//      });
-//      _ut.test('test_allExact', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_allExact);
-//      });
-//      _ut.test('test_oneNull', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_oneNull);
-//      });
-//    });
-//  }
-//}
-//
-//class CamelCaseSearchPatternTest extends EngineTestCase {
-//  void test_matchExact_samePartCount() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("HashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HM", true);
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(element));
-//  }
-//
-//  void test_matchExact_withLowerCase() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("HashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HaMa", true);
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(element));
-//  }
-//
-//  void test_matchNot_nullName() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn(null);
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HM", true);
-//    JUnitTestCase.assertSame(null, pattern.matches(element));
-//  }
-//
-//  void test_matchNot_samePartCount() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("LinkedHashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("LH", true);
-//    JUnitTestCase.assertSame(null, pattern.matches(element));
-//  }
-//
-//  void test_matchNot_withLowerCase() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("HashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HaMu", true);
-//    JUnitTestCase.assertSame(null, pattern.matches(element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('CamelCaseSearchPatternTest', () {
-//      _ut.test('test_matchExact_samePartCount', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchExact_samePartCount);
-//      });
-//      _ut.test('test_matchExact_withLowerCase', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchExact_withLowerCase);
-//      });
-//      _ut.test('test_matchNot_nullName', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchNot_nullName);
-//      });
-//      _ut.test('test_matchNot_samePartCount', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchNot_samePartCount);
-//      });
-//      _ut.test('test_matchNot_withLowerCase', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchNot_withLowerCase);
-//      });
-//    });
-//  }
-//}
-//
-//class CountingSearchListenerTest extends EngineTestCase {
-//  void test_matchFound() {
-//    SearchListener listener = mock(SearchListener);
-//    SearchMatch match = mock(SearchMatch);
-//    SearchListener countingListener = new CountingSearchListener(2, listener);
-//    // "match" should be passed to "listener"
-//    countingListener.matchFound(match);
-//    verify(listener).matchFound(match);
-//    verifyNoMoreInteractions(listener);
-//  }
-//
-//  void test_searchComplete() {
-//    SearchListener listener = mock(SearchListener);
-//    SearchListener countingListener = new CountingSearchListener(2, listener);
-//    // complete 2 -> 1
-//    countingListener.searchComplete();
-//    verifyZeroInteractions(listener);
-//    // complete 2 -> 0
-//    countingListener.searchComplete();
-//    verify(listener).searchComplete();
-//  }
-//
-//  void test_searchComplete_zero() {
-//    SearchListener listener = mock(SearchListener);
-//    new CountingSearchListener(0, listener);
-//    // complete at 0
-//    verify(listener).searchComplete();
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('CountingSearchListenerTest', () {
-//      _ut.test('test_matchFound', () {
-//        final __test = new CountingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound);
-//      });
-//      _ut.test('test_searchComplete', () {
-//        final __test = new CountingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete);
-//      });
-//      _ut.test('test_searchComplete_zero', () {
-//        final __test = new CountingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete_zero);
-//      });
-//    });
-//  }
-//}
-//
-//class ExactSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_false() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_true() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMap", false);
-//    when(_element.displayName).thenReturn("HashMaP");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMa", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_true() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMap", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMap", true);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('ExactSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_false', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_false);
-//      });
-//      _ut.test('test_caseInsensitive_true', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_true);
-//      });
-//      _ut.test('test_caseSensitive_false', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false);
-//      });
-//      _ut.test('test_caseSensitive_true', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_true);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//class FilterSearchListenerTest extends EngineTestCase {
-//  SearchListener _listener = mock(SearchListener);
-//
-//  SearchMatch _match = mock(SearchMatch);
-//
-//  SearchFilter _filter = mock(SearchFilter);
-//
-//  SearchListener _filteredListener = new FilteredSearchListener(_filter, _listener);
-//
-//  void test_matchFound_filterFalse() {
-//    when(_filter.passes(_match)).thenReturn(false);
-//    // "match" should be passed to "listener"
-//    _filteredListener.matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  void test_matchFound_filterTrue() {
-//    when(_filter.passes(_match)).thenReturn(true);
-//    // "match" should be passed to "listener"
-//    _filteredListener.matchFound(_match);
-//    verify(_listener).matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  void test_searchComplete() {
-//    _filteredListener.searchComplete();
-//    verify(_listener).searchComplete();
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('FilterSearchListenerTest', () {
-//      _ut.test('test_matchFound_filterFalse', () {
-//        final __test = new FilterSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_filterFalse);
-//      });
-//      _ut.test('test_matchFound_filterTrue', () {
-//        final __test = new FilterSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_filterTrue);
-//      });
-//      _ut.test('test_searchComplete', () {
-//        final __test = new FilterSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete);
-//      });
-//    });
-//  }
-//}
-//
-//class GatheringSearchListenerTest extends EngineTestCase {
-//  SearchMatch _matchA = mock(SearchMatch);
-//
-//  SearchMatch _matchB = mock(SearchMatch);
-//
-//  GatheringSearchListener _gatheringListener = new GatheringSearchListener();
-//
-//  void test_matchFound() {
-//    Element elementA = mock(Element);
-//    Element elementB = mock(Element);
-//    when(elementA.displayName).thenReturn("A");
-//    when(elementB.displayName).thenReturn("B");
-//    when(_matchA.element).thenReturn(elementA);
-//    when(_matchB.element).thenReturn(elementB);
-//    // matchB
-//    _gatheringListener.matchFound(_matchB);
-//    JUnitTestCase.assertFalse(_gatheringListener.isComplete);
-//    assertThat(_gatheringListener.matches).containsExactly(_matchB);
-//    // matchA
-//    _gatheringListener.matchFound(_matchA);
-//    JUnitTestCase.assertFalse(_gatheringListener.isComplete);
-//    assertThat(_gatheringListener.matches).containsExactly(_matchA, _matchB);
-//  }
-//
-//  void test_searchComplete() {
-//    JUnitTestCase.assertFalse(_gatheringListener.isComplete);
-//    // complete
-//    _gatheringListener.searchComplete();
-//    JUnitTestCase.assertTrue(_gatheringListener.isComplete);
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('GatheringSearchListenerTest', () {
-//      _ut.test('test_matchFound', () {
-//        final __test = new GatheringSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound);
-//      });
-//      _ut.test('test_searchComplete', () {
-//        final __test = new GatheringSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete);
-//      });
-//    });
-//  }
-//}
-//
-//class LibrarySearchScopeTest extends EngineTestCase {
-//  LibraryElement _libraryA = mock(LibraryElement);
-//
-//  LibraryElement _libraryB = mock(LibraryElement);
-//
-//  Element _element = mock(Element);
-//
-//  void test_arrayConstructor_inA_false() {
-//    when(_element.getAncestor((element) => element is LibraryElement)).thenReturn(_libraryB);
-//    LibrarySearchScope scope = new LibrarySearchScope.con2([_libraryA]);
-//    assertThat(scope.libraries).containsOnly(_libraryA);
-//    JUnitTestCase.assertFalse(scope.encloses(_element));
-//  }
-//
-//  void test_arrayConstructor_inA_true() {
-//    when(_element.getAncestor((element) => element is LibraryElement)).thenReturn(_libraryA);
-//    LibrarySearchScope scope = new LibrarySearchScope.con2([_libraryA, _libraryB]);
-//    assertThat(scope.libraries).containsOnly(_libraryA, _libraryB);
-//    JUnitTestCase.assertTrue(scope.encloses(_element));
-//  }
-//
-//  void test_collectionConstructor_inB() {
-//    when(_element.getAncestor((element) => element is LibraryElement)).thenReturn(_libraryB);
-//    LibrarySearchScope scope = new LibrarySearchScope.con1(ImmutableSet.of(_libraryA, _libraryB));
-//    assertThat(scope.libraries).containsOnly(_libraryA, _libraryB);
-//    JUnitTestCase.assertTrue(scope.encloses(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('LibrarySearchScopeTest', () {
-//      _ut.test('test_arrayConstructor_inA_false', () {
-//        final __test = new LibrarySearchScopeTest();
-//        runJUnitTest(__test, __test.test_arrayConstructor_inA_false);
-//      });
-//      _ut.test('test_arrayConstructor_inA_true', () {
-//        final __test = new LibrarySearchScopeTest();
-//        runJUnitTest(__test, __test.test_arrayConstructor_inA_true);
-//      });
-//      _ut.test('test_collectionConstructor_inB', () {
-//        final __test = new LibrarySearchScopeTest();
-//        runJUnitTest(__test, __test.test_collectionConstructor_inB);
-//      });
-//    });
-//  }
-//}
-//
-//class NameMatchingSearchListenerTest extends EngineTestCase {
-//  SearchListener _listener = mock(SearchListener);
-//
-//  Element _element = mock(Element);
-//
-//  SearchMatch _match = mock(SearchMatch);
-//
-//  SearchPattern _pattern = mock(SearchPattern);
-//
-//  SearchListener _nameMatchingListener = new NameMatchingSearchListener(_pattern, _listener);
-//
-//  void test_matchFound_patternFalse() {
-//    when(_pattern.matches(_element)).thenReturn(null);
-//    // verify
-//    _nameMatchingListener.matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  void test_matchFound_patternTrue() {
-//    when(_pattern.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // verify
-//    _nameMatchingListener.matchFound(_match);
-//    verify(_listener).matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  @override
-//  void setUp() {
-//    super.setUp();
-//    when(_match.element).thenReturn(_element);
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('NameMatchingSearchListenerTest', () {
-//      _ut.test('test_matchFound_patternFalse', () {
-//        final __test = new NameMatchingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_patternFalse);
-//      });
-//      _ut.test('test_matchFound_patternTrue', () {
-//        final __test = new NameMatchingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_patternTrue);
-//      });
-//    });
-//  }
-//}
-//
-//class OrSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  SearchPattern _patternA = mock(SearchPattern);
-//
-//  SearchPattern _patternB = mock(SearchPattern);
-//
-//  SearchPattern _pattern = new OrSearchPattern([_patternA, _patternB]);
-//
-//  void test_allExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
-//  }
-//
-//  void test_ExactName() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.NAME);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
-//  }
-//
-//  void test_NameExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.NAME);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.NAME, _pattern.matches(_element));
-//  }
-//
-//  void test_NullNull() {
-//    when(_patternA.matches(_element)).thenReturn(null);
-//    when(_patternB.matches(_element)).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, _pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('OrSearchPatternTest', () {
-//      _ut.test('test_ExactName', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_ExactName);
-//      });
-//      _ut.test('test_NameExact', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_NameExact);
-//      });
-//      _ut.test('test_NullNull', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_NullNull);
-//      });
-//      _ut.test('test_allExact', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_allExact);
-//      });
-//    });
-//  }
-//}
-//
-//class PrefixSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_contentMatch_caseMatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_contentMatch_caseMismatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HaSHMa", false);
-//    when(_element.displayName).thenReturn("hashMaP");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_contentMismatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn("HashTable");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_contentMatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_contentMismatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", true);
-//    when(_element.displayName).thenReturn("HashTable");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_nullElement() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(null));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('PrefixSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_contentMatch_caseMatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_contentMatch_caseMatch);
-//      });
-//      _ut.test('test_caseInsensitive_contentMatch_caseMismatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_contentMatch_caseMismatch);
-//      });
-//      _ut.test('test_caseInsensitive_contentMismatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_contentMismatch);
-//      });
-//      _ut.test('test_caseSensitive_contentMatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_contentMatch);
-//      });
-//      _ut.test('test_caseSensitive_contentMismatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_contentMismatch);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//class RegularExpressionSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_false_contentMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*Map", false);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_true_caseMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*MaP", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_caseMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*MaP", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_contentMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*Map", true);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_true() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H.*Map", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_nullElement() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H.*Map", true);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(null));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H.*Map", true);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('RegularExpressionSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_false_contentMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseInsensitive_true_caseMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_true_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_caseMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_contentMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseSensitive_true', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_true);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//class SearchEngineImplTest extends EngineTestCase {
-//  static void _assertMatches(List<SearchMatch> matches, List<SearchEngineImplTest_ExpectedMatch> expectedMatches) {
-//    assertThat(matches).hasSize(expectedMatches.length);
-//    for (SearchMatch match in matches) {
-//      bool found = false;
-//      String msg = match.toString();
-//      for (SearchEngineImplTest_ExpectedMatch expectedMatch in expectedMatches) {
-//        if (match.element == expectedMatch._element && match.kind == expectedMatch._kind && match.quality == expectedMatch._quality && match.sourceRange == expectedMatch._range && match.isQualified == expectedMatch._qualified) {
-//          found = true;
-//          break;
-//        }
-//      }
-//      if (!found) {
-//        JUnitTestCase.fail("Not found: ${msg}");
-//      }
-//    }
-//  }
-//
-//  IndexStore _indexStore = IndexFactory.newSplitIndexStore(new MemoryNodeManager());
-//
-//  static AnalysisContext _CONTEXT = mock(AnalysisContext);
-//
-//  int _nextLocationId = 0;
-//
-//  SearchScope _scope;
-//
-//  SearchPattern _pattern = null;
-//
-//  SearchFilter _filter = null;
-//
-//  Source _source = mock(Source);
-//
-//  CompilationUnitElement _unitElement = mock(CompilationUnitElement);
-//
-//  LibraryElement _libraryElement = mock(LibraryElement);
-//
-//  Element _elementA = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementB = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementC = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementD = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementE = _mockElement(Element, ElementKind.CLASS);
-//
-//  void fail_searchAssignedTypes_assignments() {
-//    // TODO(scheglov) does not work - new split index store cannot store types (yet?)
-//    PropertyAccessorElement setterElement = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    when(fieldElement.setter).thenReturn(setterElement);
-//    DartType typeA = mock(DartType);
-//    DartType typeB = mock(DartType);
-//    DartType typeC = mock(DartType);
-//    _indexStore.aboutToIndexDart(_CONTEXT, _unitElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      location = new LocationWithData<DartType>.con1(location, typeA);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      location = new LocationWithData<DartType>.con1(location, typeB);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    // will be filtered by scope
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      location = new LocationWithData<DartType>.con1(location, typeC);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    // not LocationWithData
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // ask types
-//    Set<DartType> types = _runSearch(new SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_assignments(fieldElement));
-//    assertThat(types).containsOnly(typeA, typeB);
-//  }
-//
-//  void fail_searchAssignedTypes_initializers() {
-//    // TODO(scheglov) does not work - new split index store cannot store types (yet?)
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    DartType typeA = mock(DartType);
-//    DartType typeB = mock(DartType);
-//    {
-//      Location location = new Location(_elementA, 10, 1);
-//      location = new LocationWithData<DartType>.con1(location, typeA);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_DEFINED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 20, 1);
-//      location = new LocationWithData<DartType>.con1(location, typeB);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // ask types
-//    Set<DartType> types = _runSearch(new SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_initializers(fieldElement));
-//    assertThat(types).containsOnly(typeA, typeB);
-//  }
-//
-//  void test_searchDeclarations_String() {
-//    Element referencedElement = new NameElementImpl("test");
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_DEFINED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_DEFINED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _runSearch(new SearchRunner_SearchEngineImplTest_test_searchDeclarations_String(this));
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.NAME_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.NAME_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations_async() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchFunctionDeclarationsAsync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations_inUniverse() {
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(IndexConstants.UNIVERSE, IndexConstants.DEFINES_FUNCTION, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(IndexConstants.UNIVERSE, IndexConstants.DEFINES_FUNCTION, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = SearchScopeFactory.createUniverseScope();
-//    // search matches
-//    List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations_useFilter() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search "elementA"
-//    {
-//      _filter = new SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter_2(this);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2)]);
-//    }
-//    // search "elementB"
-//    {
-//      _filter = new SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter(this);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//    }
-//  }
-//
-//  void test_searchFunctionDeclarations_usePattern() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search "A"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("A", true);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2)]);
-//    }
-//    // search "B"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("B", true);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//    }
-//  }
-//
-//  void test_searchReferences_AngularComponentElement() {
-//    AngularComponentElement referencedElement = _mockElement(AngularComponentElement, ElementKind.ANGULAR_COMPONENT);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularControllerElement() {
-//    AngularControllerElement referencedElement = _mockElement(AngularControllerElement, ElementKind.ANGULAR_CONTROLLER);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularFilterElement() {
-//    AngularFormatterElement referencedElement = _mockElement(AngularFormatterElement, ElementKind.ANGULAR_FORMATTER);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularPropertyElement() {
-//    AngularPropertyElement referencedElement = _mockElement(AngularPropertyElement, ElementKind.ANGULAR_PROPERTY);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularScopePropertyElement() {
-//    AngularScopePropertyElement referencedElement = _mockElement(AngularScopePropertyElement, ElementKind.ANGULAR_SCOPE_PROPERTY);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularSelectorElement() {
-//    AngularSelectorElement referencedElement = _mockElement(AngularSelectorElement, ElementKind.ANGULAR_SELECTOR);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_ClassElement() {
-//    ClassElement referencedElement = _mockElement(ClassElement, ElementKind.CLASS);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.TYPE_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.TYPE_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_ClassElement_useScope() {
-//    LibraryElement libraryA = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    LibraryElement libraryB = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    ClassElement referencedElement = _mockElement(ClassElement, ElementKind.CLASS);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(libraryA);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      when(_elementB.getAncestor((element) => element is LibraryElement)).thenReturn(libraryB);
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches, in "libraryA"
-//    _scope = SearchScopeFactory.createLibraryScope3(libraryA);
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.TYPE_REFERENCE, 1, 2)]);
-//  }
-//
-//  void test_searchReferences_CompilationUnitElement() {
-//    CompilationUnitElement referencedElement = _mockElement(CompilationUnitElement, ElementKind.COMPILATION_UNIT);
-//    {
-//      Location location = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.UNIT_REFERENCE, 1, 2)]);
-//  }
-//
-//  void test_searchReferences_ConstructorElement() {
-//    ConstructorElement referencedElement = _mockElement(ConstructorElement, ElementKind.CONSTRUCTOR);
-//    {
-//      Location location = new Location(_elementA, 10, 1);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_DEFINED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 20, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 30, 3);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CONSTRUCTOR_DECLARATION, 10, 1),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.CONSTRUCTOR_REFERENCE, 20, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.CONSTRUCTOR_REFERENCE, 30, 3)]);
-//  }
-//
-//  void test_searchReferences_Element_unknown() {
-//    List<SearchMatch> matches = _searchReferencesSync(Element, null);
-//    assertThat(matches).isEmpty();
-//  }
-//
-//  void test_searchReferences_FieldElement() {
-//    PropertyAccessorElement getterElement = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    PropertyAccessorElement setterElement = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    when(fieldElement.getter).thenReturn(getterElement);
-//    when(fieldElement.setter).thenReturn(setterElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, fieldElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_READ, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.FIELD_READ, 2, 20, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.FIELD_WRITE, 3, 30, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementD, MatchKind.FIELD_WRITE, 4, 40, true)]);
-//  }
-//
-//  void test_searchReferences_FieldElement_invocation() {
-//    PropertyAccessorElement getterElement = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    when(fieldElement.getter).thenReturn(getterElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, fieldElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_INVOCATION, 1, 10, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.FIELD_INVOCATION, 2, 20, false)]);
-//  }
-//
-//  void test_searchReferences_FieldElement2() {
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, fieldElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_REFERENCE, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.FIELD_REFERENCE, 2, 20, true)]);
-//  }
-//
-//  void test_searchReferences_FunctionElement() {
-//    FunctionElement referencedElement = _mockElement(FunctionElement, ElementKind.FUNCTION);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_EXECUTION, 1, 10),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_REFERENCE, 2, 20)]);
-//  }
-//
-//  void test_searchReferences_ImportElement() {
-//    ImportElement referencedElement = _mockElement(ImportElement, ElementKind.IMPORT);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 0);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.IMPORT_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.IMPORT_REFERENCE, 10, 0)]);
-//  }
-//
-//  void test_searchReferences_LibraryElement() {
-//    LibraryElement referencedElement = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      Location location = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.LIBRARY_REFERENCE, 1, 2)]);
-//  }
-//
-//  void test_searchReferences_MethodElement() {
-//    MethodElement referencedElement = _mockElement(MethodElement, ElementKind.METHOD);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.METHOD_INVOCATION, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.METHOD_INVOCATION, 2, 20, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.METHOD_REFERENCE, 3, 30, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementD, MatchKind.METHOD_REFERENCE, 4, 40, true)]);
-//  }
-//
-//  void test_searchReferences_MethodMember() {
-//    MethodElement referencedElement = _mockElement(MethodElement, ElementKind.METHOD);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    MethodMember referencedMember = new MethodMember(referencedElement, null);
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedMember);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.METHOD_INVOCATION, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.METHOD_INVOCATION, 2, 20, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.METHOD_REFERENCE, 3, 30, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementD, MatchKind.METHOD_REFERENCE, 4, 40, true)]);
-//  }
-//
-//  void test_searchReferences_notSupported() {
-//    Element referencedElement = _mockElement(Element, ElementKind.UNIVERSE);
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    assertThat(matches).isEmpty();
-//  }
-//
-//  void test_searchReferences_ParameterElement() {
-//    ParameterElement referencedElement = _mockElement(ParameterElement, ElementKind.PARAMETER);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 5, 50);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    // TODO(scheglov) why no MatchKind.FIELD_READ_WRITE ?
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_READ, 1, 10),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_WRITE, 2, 20),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.VARIABLE_READ_WRITE, 3, 30),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementD, MatchKind.NAMED_PARAMETER_REFERENCE, 4, 40),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementD, MatchKind.FUNCTION_EXECUTION, 5, 50)]);
-//  }
-//
-//  void test_searchReferences_PropertyAccessorElement_getter() {
-//    PropertyAccessorElement accessor = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, accessor);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 2, 20, true)]);
-//  }
-//
-//  void test_searchReferences_PropertyAccessorElement_setter() {
-//    PropertyAccessorElement accessor = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, accessor);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 2, 20, true)]);
-//  }
-//
-//  void test_searchReferences_TopLevelVariableElement() {
-//    PropertyAccessorElement getterElement = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    PropertyAccessorElement setterElement = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    TopLevelVariableElement topVariableElement = _mockElement(TopLevelVariableElement, ElementKind.TOP_LEVEL_VARIABLE);
-//    when(topVariableElement.getter).thenReturn(getterElement);
-//    when(topVariableElement.setter).thenReturn(setterElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 2, 20);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, topVariableElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_READ, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.FIELD_WRITE, 2, 20, false)]);
-//  }
-//
-//  void test_searchReferences_TypeAliasElement() {
-//    FunctionTypeAliasElement referencedElement = _mockElement(FunctionTypeAliasElement, ElementKind.FUNCTION_TYPE_ALIAS);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_TYPE_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_TYPE_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_TypeParameterElement() {
-//    TypeParameterElement referencedElement = _mockElement(TypeParameterElement, ElementKind.TYPE_PARAMETER);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.TYPE_PARAMETER_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.TYPE_PARAMETER_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_VariableElement() {
-//    LocalVariableElement referencedElement = _mockElement(LocalVariableElement, ElementKind.LOCAL_VARIABLE);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_READ, 1, 10),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_WRITE, 2, 20),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.VARIABLE_READ_WRITE, 3, 30),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementD, MatchKind.FUNCTION_EXECUTION, 4, 40)]);
-//  }
-//
-//  void test_searchSubtypes() {
-//    ClassElement referencedElement = _mockElement(ClassElement, ElementKind.CLASS);
-//    {
-//      Location locationA = new Location(_elementA, 10, 1);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_EXTENDED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 20, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_MIXED_IN_BY, locationB);
-//    }
-//    {
-//      Location locationC = new Location(_elementC, 30, 3);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_IMPLEMENTED_BY, locationC);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _runSearch(new SearchRunner_SearchEngineImplTest_test_searchSubtypes(this, referencedElement));
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.EXTENDS_REFERENCE, 10, 1),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.WITH_REFERENCE, 20, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.IMPLEMENTS_REFERENCE, 30, 3)]);
-//  }
-//
-//  void test_searchTypeDeclarations_async() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_CLASS, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsAsync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CLASS_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchTypeDeclarations_class() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_CLASS, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CLASS_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchTypeDeclarations_classAlias() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_CLASS_ALIAS, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CLASS_ALIAS_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchTypeDeclarations_functionType() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_FUNCTION_TYPE, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_TYPE_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchUnresolvedQualifiedReferences() {
-//    Element referencedElement = new NameElementImpl("test");
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync2("searchQualifiedMemberReferences", String, "test");
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.NAME_REFERENCE_RESOLVED, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.NAME_REFERENCE_UNRESOLVED, 10, 20)]);
-//  }
-//
-//  void test_searchVariableDeclarations() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineVariablesAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchVariableDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchVariableDeclarations_async() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineVariablesAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchVariableDeclarationsAsync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchVariableDeclarations_usePattern() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineVariablesAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search "A"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("A", true);
-//      List<SearchMatch> matches = _searchVariableDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_DECLARATION, 1, 2)]);
-//    }
-//    // search "B"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("B", true);
-//      List<SearchMatch> matches = _searchVariableDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_DECLARATION, 10, 20)]);
-//    }
-//  }
-//
-//  @override
-//  void setUp() {
-//    super.setUp();
-//    // library
-//    when(_unitElement.library).thenReturn(_libraryElement);
-//    when(_libraryElement.definingCompilationUnit).thenReturn(_unitElement);
-//    when(_unitElement.source).thenReturn(_source);
-//    when(_libraryElement.source).thenReturn(_source);
-//    when(_libraryElement.parts).thenReturn(new List<CompilationUnitElement>(0));
-//    // elements
-//    when(_elementA.toString()).thenReturn("A");
-//    when(_elementB.toString()).thenReturn("B");
-//    when(_elementC.toString()).thenReturn("C");
-//    when(_elementD.toString()).thenReturn("D");
-//    when(_elementE.toString()).thenReturn("E");
-//    when(_elementA.displayName).thenReturn("A");
-//    when(_elementB.displayName).thenReturn("B");
-//    when(_elementC.displayName).thenReturn("C");
-//    when(_elementD.displayName).thenReturn("D");
-//    when(_elementE.displayName).thenReturn("E");
-//    when(_elementA.source).thenReturn(_source);
-//    when(_elementB.source).thenReturn(_source);
-//    when(_elementC.source).thenReturn(_source);
-//    when(_elementD.source).thenReturn(_source);
-//    when(_elementE.source).thenReturn(_source);
-//    when(_elementA.context).thenReturn(_CONTEXT);
-//    when(_elementB.context).thenReturn(_CONTEXT);
-//    when(_elementC.context).thenReturn(_CONTEXT);
-//    when(_elementD.context).thenReturn(_CONTEXT);
-//    when(_elementE.context).thenReturn(_CONTEXT);
-//    when(_CONTEXT.getElement(_elementA.location)).thenReturn(_elementA);
-//    when(_CONTEXT.getElement(_elementB.location)).thenReturn(_elementB);
-//    when(_CONTEXT.getElement(_elementC.location)).thenReturn(_elementC);
-//    when(_CONTEXT.getElement(_elementD.location)).thenReturn(_elementD);
-//    when(_CONTEXT.getElement(_elementE.location)).thenReturn(_elementE);
-//    // start indexing
-//    JUnitTestCase.assertTrue(_indexStore.aboutToIndexDart(_CONTEXT, _unitElement));
-//  }
-//
-//  void _defineFunctionsAB(LibraryElement library) {
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_FUNCTION, locationA);
-//    }
-//    {
-//      when(_elementB.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_FUNCTION, locationB);
-//    }
-//    _indexStore.doneIndex();
-//  }
-//
-//  void _defineVariablesAB(LibraryElement library) {
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_VARIABLE, locationA);
-//    }
-//    {
-//      when(_elementB.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_VARIABLE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//  }
-//
-//  Element _mockElement(Type clazz, ElementKind kind) {
-//    Element element = mock(clazz);
-//    when(element.context).thenReturn(_CONTEXT);
-//    when(element.source).thenReturn(_source);
-//    when(element.kind).thenReturn(kind);
-//    ElementLocation elementLocation = new ElementLocationImpl.con2("mockLocation${_nextLocationId++}");
-//    when(element.location).thenReturn(elementLocation);
-//    when(_CONTEXT.getElement(element.location)).thenReturn(element);
-//    return element;
-//  }
-//
-//  Object _runSearch(SearchEngineImplTest_SearchRunner runner) {
-//    OperationQueue queue = new OperationQueue();
-//    OperationProcessor processor = new OperationProcessor(queue);
-//    Index index = new IndexImpl(_indexStore, queue, processor);
-//    SearchEngine engine = SearchEngineFactory.createSearchEngine(index);
-//    try {
-//      new Thread_SearchEngineImplTest_runSearch(processor).start();
-//      processor.waitForRunning();
-//      return runner.run(queue, processor, index, engine);
-//    } finally {
-//      processor.stop(false);
-//    }
-//  }
-//
-//  List<SearchMatch> _searchDeclarationsAsync(String methodName) => _runSearch(new SearchRunner_SearchEngineImplTest_searchDeclarationsAsync(this, methodName, this, matches, latch));
-//
-//  List<SearchMatch> _searchDeclarationsSync(String methodName) => _runSearch(new SearchRunner_SearchEngineImplTest_searchDeclarationsSync(this, methodName));
-//
-//  List<SearchMatch> _searchFunctionDeclarationsAsync() => _searchDeclarationsAsync("searchFunctionDeclarations");
-//
-//  List<SearchMatch> _searchFunctionDeclarationsSync() => _searchDeclarationsSync("searchFunctionDeclarations");
-//
-//  List<SearchMatch> _searchReferencesSync(Type clazz, Object element) => _searchReferencesSync2("searchReferences", clazz, element);
-//
-//  List<SearchMatch> _searchReferencesSync2(String methodName, Type clazz, Object element) => _runSearch(new SearchRunner_SearchEngineImplTest_searchReferencesSync(this, methodName, clazz, element));
-//
-//  List<SearchMatch> _searchTypeDeclarationsAsync() => _searchDeclarationsAsync("searchTypeDeclarations");
-//
-//  List<SearchMatch> _searchTypeDeclarationsSync() => _searchDeclarationsSync("searchTypeDeclarations");
-//
-//  List<SearchMatch> _searchVariableDeclarationsAsync() => _searchDeclarationsAsync("searchVariableDeclarations");
-//
-//  List<SearchMatch> _searchVariableDeclarationsSync() => _searchDeclarationsSync("searchVariableDeclarations");
-//
-//  static dartSuite() {
-//    _ut.group('SearchEngineImplTest', () {
-//      _ut.test('test_searchDeclarations_String', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchDeclarations_String);
-//      });
-//      _ut.test('test_searchFunctionDeclarations', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_async', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_async);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_inUniverse', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_inUniverse);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_useFilter', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_useFilter);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_usePattern', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_usePattern);
-//      });
-//      _ut.test('test_searchReferences_AngularComponentElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularComponentElement);
-//      });
-//      _ut.test('test_searchReferences_AngularControllerElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularControllerElement);
-//      });
-//      _ut.test('test_searchReferences_AngularFilterElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularFilterElement);
-//      });
-//      _ut.test('test_searchReferences_AngularPropertyElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularPropertyElement);
-//      });
-//      _ut.test('test_searchReferences_AngularScopePropertyElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularScopePropertyElement);
-//      });
-//      _ut.test('test_searchReferences_AngularSelectorElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularSelectorElement);
-//      });
-//      _ut.test('test_searchReferences_ClassElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ClassElement);
-//      });
-//      _ut.test('test_searchReferences_ClassElement_useScope', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ClassElement_useScope);
-//      });
-//      _ut.test('test_searchReferences_CompilationUnitElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_CompilationUnitElement);
-//      });
-//      _ut.test('test_searchReferences_ConstructorElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ConstructorElement);
-//      });
-//      _ut.test('test_searchReferences_Element_unknown', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_Element_unknown);
-//      });
-//      _ut.test('test_searchReferences_FieldElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FieldElement);
-//      });
-//      _ut.test('test_searchReferences_FieldElement2', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FieldElement2);
-//      });
-//      _ut.test('test_searchReferences_FieldElement_invocation', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FieldElement_invocation);
-//      });
-//      _ut.test('test_searchReferences_FunctionElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FunctionElement);
-//      });
-//      _ut.test('test_searchReferences_ImportElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ImportElement);
-//      });
-//      _ut.test('test_searchReferences_LibraryElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_LibraryElement);
-//      });
-//      _ut.test('test_searchReferences_MethodElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_MethodElement);
-//      });
-//      _ut.test('test_searchReferences_MethodMember', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_MethodMember);
-//      });
-//      _ut.test('test_searchReferences_ParameterElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ParameterElement);
-//      });
-//      _ut.test('test_searchReferences_PropertyAccessorElement_getter', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_PropertyAccessorElement_getter);
-//      });
-//      _ut.test('test_searchReferences_PropertyAccessorElement_setter', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_PropertyAccessorElement_setter);
-//      });
-//      _ut.test('test_searchReferences_TopLevelVariableElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_TopLevelVariableElement);
-//      });
-//      _ut.test('test_searchReferences_TypeAliasElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_TypeAliasElement);
-//      });
-//      _ut.test('test_searchReferences_TypeParameterElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_TypeParameterElement);
-//      });
-//      _ut.test('test_searchReferences_VariableElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_VariableElement);
-//      });
-//      _ut.test('test_searchReferences_notSupported', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_notSupported);
-//      });
-//      _ut.test('test_searchSubtypes', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchSubtypes);
-//      });
-//      _ut.test('test_searchTypeDeclarations_async', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_async);
-//      });
-//      _ut.test('test_searchTypeDeclarations_class', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_class);
-//      });
-//      _ut.test('test_searchTypeDeclarations_classAlias', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_classAlias);
-//      });
-//      _ut.test('test_searchTypeDeclarations_functionType', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_functionType);
-//      });
-//      _ut.test('test_searchUnresolvedQualifiedReferences', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchUnresolvedQualifiedReferences);
-//      });
-//      _ut.test('test_searchVariableDeclarations', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchVariableDeclarations);
-//      });
-//      _ut.test('test_searchVariableDeclarations_async', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchVariableDeclarations_async);
-//      });
-//      _ut.test('test_searchVariableDeclarations_usePattern', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchVariableDeclarations_usePattern);
-//      });
-//    });
-//  }
-//}
-//
-//class SearchEngineImplTest_ExpectedMatch {
-//  final Element _element;
-//
-//  final MatchKind _kind;
-//
-//  final MatchQuality _quality;
-//
-//  SourceRange _range;
-//
-//  final bool _qualified;
-//
-//  SearchEngineImplTest_ExpectedMatch.con1(Element element, MatchKind kind, int offset, int length) : this.con3(element, kind, MatchQuality.EXACT, offset, length);
-//
-//  SearchEngineImplTest_ExpectedMatch.con2(Element element, MatchKind kind, int offset, int length, bool qualified) : this.con4(element, kind, MatchQuality.EXACT, offset, length, qualified);
-//
-//  SearchEngineImplTest_ExpectedMatch.con3(Element element, MatchKind kind, MatchQuality quality, int offset, int length) : this.con4(element, kind, quality, offset, length, false);
-//
-//  SearchEngineImplTest_ExpectedMatch.con4(this._element, this._kind, this._quality, int offset, int length, this._qualified) {
-//    this._range = new SourceRange(offset, length);
-//  }
-//}
-//
-//abstract class SearchEngineImplTest_SearchRunner<T> {
-//  T run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine);
-//}
-//
-//class SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter implements SearchFilter {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter(this.SearchEngineImplTest_this);
-//
-//  @override
-//  bool passes(SearchMatch match) => identical(match.element, SearchEngineImplTest_this._elementB);
-//}
-//
-//class SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter_2 implements SearchFilter {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter_2(this.SearchEngineImplTest_this);
-//
-//  @override
-//  bool passes(SearchMatch match) => identical(match.element, SearchEngineImplTest_this._elementA);
-//}
-//
-//class SearchListener_SearchRunner_117_run implements SearchListener {
-//  List<SearchMatch> matches;
-//
-//  CountDownLatch latch;
-//
-//  SearchListener_SearchRunner_117_run(this.matches, this.latch);
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    matches.add(match);
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    latch.countDown();
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_assignments implements SearchEngineImplTest_SearchRunner {
-//  FieldElement fieldElement;
-//
-//  SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_assignments(this.fieldElement, this.fieldElement);
-//
-//  @override
-//  Set<DartType> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchAssignedTypes(fieldElement, new SearchScope_SearchRunner_109_run());
-//}
-//
-//class SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_initializers implements SearchEngineImplTest_SearchRunner {
-//  FieldElement fieldElement;
-//
-//  SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_initializers(this.fieldElement);
-//
-//  @override
-//  Set<DartType> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchAssignedTypes(fieldElement, null);
-//}
-//
-//class SearchRunner_SearchEngineImplTest_searchDeclarationsAsync implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  String methodName;
-//
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  List<SearchMatch> matches;
-//
-//  CountDownLatch latch;
-//
-//  SearchRunner_SearchEngineImplTest_searchDeclarationsAsync(this.SearchEngineImplTest_this, this.methodName, this.SearchEngineImplTest_this, this.matches, this.latch, this.SearchEngineImplTest_this, this.methodName, this.SearchEngineImplTest_this, this.matches, this.latch);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) {
-//    CountDownLatch latch = new CountDownLatch(1);
-//    List<SearchMatch> matches = [];
-//    engine.runtimeType.getMethod(methodName, [SearchScope, SearchPattern, SearchFilter, SearchListener]).invoke(engine, [
-//        SearchEngineImplTest_this._scope,
-//        SearchEngineImplTest_this._pattern,
-//        SearchEngineImplTest_this._filter,
-//        new SearchListener_SearchRunner_117_run(matches, latch)]);
-//    latch.await(30, TimeUnit.SECONDS);
-//    return matches;
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImplTest_searchDeclarationsSync implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  String methodName;
-//
-//  SearchRunner_SearchEngineImplTest_searchDeclarationsSync(this.SearchEngineImplTest_this, this.methodName);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.runtimeType.getMethod(methodName, [SearchScope, SearchPattern, SearchFilter]).invoke(engine, [
-//      SearchEngineImplTest_this._scope,
-//      SearchEngineImplTest_this._pattern,
-//      SearchEngineImplTest_this._filter]) as List<SearchMatch>;
-//}
-//
-//class SearchRunner_SearchEngineImplTest_searchReferencesSync implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  String methodName;
-//
-//  Type clazz;
-//
-//  Object element;
-//
-//  SearchRunner_SearchEngineImplTest_searchReferencesSync(this.SearchEngineImplTest_this, this.methodName, this.clazz, this.element);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) {
-//    // pass some operation to wait if search will not call processor
-//    queue.enqueue(mock(IndexOperation));
-//    // run actual search
-//    return engine.runtimeType.getMethod(methodName, [clazz, SearchScope, SearchFilter]).invoke(engine, [
-//        element,
-//        SearchEngineImplTest_this._scope,
-//        SearchEngineImplTest_this._filter]) as List<SearchMatch>;
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImplTest_test_searchDeclarations_String implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  SearchRunner_SearchEngineImplTest_test_searchDeclarations_String(this.SearchEngineImplTest_this);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchDeclarations("test", SearchEngineImplTest_this._scope, SearchEngineImplTest_this._filter);
-//}
-//
-//class SearchRunner_SearchEngineImplTest_test_searchSubtypes implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  ClassElement referencedElement;
-//
-//  SearchRunner_SearchEngineImplTest_test_searchSubtypes(this.SearchEngineImplTest_this, this.referencedElement);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchSubtypes(referencedElement, SearchEngineImplTest_this._scope, SearchEngineImplTest_this._filter);
-//}
-//
-//class SearchScope_SearchRunner_109_run implements SearchScope {
-//  @override
-//  bool encloses(Element element) => !identical(element, _elementC);
-//}
-//
-//class Thread_SearchEngineImplTest_runSearch extends Thread {
-//  OperationProcessor processor;
-//
-//  Thread_SearchEngineImplTest_runSearch(this.processor) : super();
-//
-//  @override
-//  void run() {
-//    processor.run();
-//  }
-//}
-//
-//class UniverseSearchScopeTest extends EngineTestCase {
-//  SearchScope _scope = new UniverseSearchScope();
-//
-//  Element _element = mock(Element);
-//
-//  void test_anyElement() {
-//    JUnitTestCase.assertTrue(_scope.encloses(_element));
-//  }
-//
-//  void test_nullElement() {
-//    JUnitTestCase.assertTrue(_scope.encloses(null));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('UniverseSearchScopeTest', () {
-//      _ut.test('test_anyElement', () {
-//        final __test = new UniverseSearchScopeTest();
-//        runJUnitTest(__test, __test.test_anyElement);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new UniverseSearchScopeTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//    });
-//  }
-//}
-//
-//class WildcardSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_false_contentMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_true_caseMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*MaP", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_caseMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*MaP", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_contentMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_true() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Ma?", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_nullElement() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(null));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('WildcardSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_false_contentMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseInsensitive_true_caseMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_true_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_caseMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_contentMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseSensitive_true', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_true);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//main() {
-//  CountingSearchListenerTest.dartSuite();
-//  FilterSearchListenerTest.dartSuite();
-//  GatheringSearchListenerTest.dartSuite();
-//  NameMatchingSearchListenerTest.dartSuite();
-//  LibrarySearchScopeTest.dartSuite();
-//  UniverseSearchScopeTest.dartSuite();
-//  SearchEngineImplTest.dartSuite();
-//  AndSearchPatternTest.dartSuite();
-//  CamelCaseSearchPatternTest.dartSuite();
-//  ExactSearchPatternTest.dartSuite();
-//  OrSearchPatternTest.dartSuite();
-//  PrefixSearchPatternTest.dartSuite();
-//  RegularExpressionSearchPatternTest.dartSuite();
-//  WildcardSearchPatternTest.dartSuite();
-//}
+
+  void setUp() {
+    super.setUp();
+    index = createLocalMemoryIndex();
+    searchEngine = new SearchEngineImpl(index);
+  }
+
+  Future test_searchMemberDeclarations() {
+    _indexTestUnit('''
+class A {
+  test() {}
+}
+class B {
+  int test = 42;
+}
+''');
+    NameElement element = new NameElement('test');
+    ClassElement elementA = findElement('A');
+    ClassElement elementB = findElement('B');
+    var expected = [
+        _expectId(elementA.methods[0], MatchKind.NAME_DECLARATION, 'test() {}'),
+        _expectId(elementB.fields[0], MatchKind.NAME_DECLARATION, 'test = 42;')];
+    return searchEngine.searchMemberDeclarations('test').then((matches) {
+      _assertMatches(matches, expected);
+    });
+  }
+
+  Future test_searchReferences_AngularComponentElement() {
+    // use mocks
+    index = new MockIndex();
+    searchEngine = new SearchEngineImpl(index);
+    Element elementA = new MockElement('A');
+    Element elementB = new MockElement('B');
+    // fill mocks
+    AngularComponentElement element = new MockAngularComponentElement();
+    void mockLocation(Element element, Relationship relationship,
+        Location location) {
+      index.getRelationships(element, relationship);
+      when(null).thenReturn(new Future.value([location]));
+    }
+    mockLocation(
+        element,
+        IndexConstants.ANGULAR_REFERENCE,
+        new Location(elementA, 1, 10));
+    mockLocation(
+        element,
+        IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
+        new Location(elementB, 2, 20));
+    var expected = [
+        new ExpectedMatch(elementA, MatchKind.ANGULAR_REFERENCE, 1, 10),
+        new ExpectedMatch(elementB, MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, 2, 20)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ClassElement() {
+    _indexTestUnit('''
+class A {}
+main(A p) {
+  A v;
+}
+''');
+    ClassElement element = findElement('A');
+    Element pElement = findElement('p');
+    Element vElement = findElement('v');
+    var expected = [
+        _expectId(pElement, MatchKind.TYPE_REFERENCE, 'A p'),
+        _expectId(vElement, MatchKind.TYPE_REFERENCE, 'A v')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_CompilationUnitElement() {
+    addSource('/my_part.dart', '''
+part of lib;
+''');
+    _indexTestUnit('''
+library lib;
+part 'my_part.dart';
+''');
+    CompilationUnitElement element = testLibraryElement.parts[0];
+    var expected = [
+        _expectId(
+            testUnitElement,
+            MatchKind.UNIT_REFERENCE,
+            "'my_part.dart'",
+            length: "'my_part.dart'".length)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ConstructorElement() {
+    _indexTestUnit('''
+class A {
+  A.named() {}
+}
+main() {
+  new A.named();
+}
+''');
+    ConstructorElement element = findElement('named');
+    ClassElement elementA = findElement('A');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(
+            elementA,
+            MatchKind.CONSTRUCTOR_DECLARATION,
+            '.named() {}',
+            length: 6),
+        _expectId(
+            mainElement,
+            MatchKind.CONSTRUCTOR_REFERENCE,
+            '.named();',
+            length: 6)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_Element_unknown() {
+    return _verifyReferences(UniverseElement.INSTANCE, []);
+  }
+
+  Future test_searchReferences_FieldElement() {
+    _indexTestUnit('''
+class A {
+  var field;
+  A({this.field});
+  main() {
+    new A(field: 1);
+    // getter
+    print(field); // ref-nq
+    print(this.field); // ref-q
+    field(); // inv-nq
+    this.field(); // inv-q
+    // setter
+    field = 2; // ref-nq;
+    this.field = 3; // ref-q;
+  }
+}
+''');
+    FieldElement element = findElement('field');
+    Element main = findElement('main');
+    Element fieldParameter = findElement('field', ElementKind.PARAMETER);
+    var expected = [
+        _expectIdQ(fieldParameter, MatchKind.FIELD_REFERENCE, 'field}'),
+        _expectIdQ(main, MatchKind.FIELD_REFERENCE, 'field: 1'),
+        _expectId(main, MatchKind.FIELD_READ, 'field); // ref-nq'),
+        _expectIdQ(main, MatchKind.FIELD_READ, 'field); // ref-q'),
+        _expectId(main, MatchKind.FIELD_INVOCATION, 'field(); // inv-nq'),
+        _expectIdQ(main, MatchKind.FIELD_INVOCATION, 'field(); // inv-q'),
+        _expectId(main, MatchKind.FIELD_WRITE, 'field = 2; // ref-nq'),
+        _expectIdQ(main, MatchKind.FIELD_WRITE, 'field = 3; // ref-q')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_FunctionElement() {
+    _indexTestUnit('''
+test() {}
+main() {
+  test();
+  print(test);
+}
+''');
+    FunctionElement element = findElement('test');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.FUNCTION_EXECUTION, 'test();'),
+        _expectId(mainElement, MatchKind.FUNCTION_REFERENCE, 'test);')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_FunctionTypeAliasElement() {
+    _indexTestUnit('''
+typedef Test();
+main() {
+  Test a;
+  Test b;
+}
+''');
+    FunctionTypeAliasElement element = findElement('Test');
+    Element aElement = findElement('a');
+    Element bElement = findElement('b');
+    var expected = [
+        _expectId(aElement, MatchKind.FUNCTION_TYPE_REFERENCE, 'Test a;'),
+        _expectId(bElement, MatchKind.FUNCTION_TYPE_REFERENCE, 'Test b;')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ImportElement_noPrefix() {
+    _indexTestUnit('''
+import 'dart:math';
+main() {
+  print(E);
+}
+''');
+    ImportElement element = testLibraryElement.imports[0];
+    Element mainElement = findElement('main');
+    var kind = MatchKind.IMPORT_REFERENCE;
+    var expected = [_expectId(mainElement, kind, 'E);', length: 0)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ImportElement_withPrefix() {
+    _indexTestUnit('''
+import 'dart:math' as math;
+main() {
+  print(math.PI);
+}
+''');
+    ImportElement element = testLibraryElement.imports[0];
+    Element mainElement = findElement('main');
+    var kind = MatchKind.IMPORT_REFERENCE;
+    var expected = [
+        _expectId(mainElement, kind, 'math.PI);', length: 'math.'.length)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_LibraryElement() {
+    var codeA = 'part of lib; // A';
+    var codeB = 'part of lib; // B';
+    var sourceA = addSource('/unitA.dart', codeA);
+    var sourceB = addSource('/unitB.dart', codeB);
+    _indexTestUnit('''
+library lib;
+part 'unitA.dart';
+part 'unitB.dart';
+''');
+    LibraryElement element = testLibraryElement;
+    CompilationUnitElement elementA = element.parts[0];
+    CompilationUnitElement elementB = element.parts[1];
+    index.indexUnit(context, elementA.node);
+    index.indexUnit(context, elementB.node);
+    Element mainElement = findElement('main');
+    var expected = [
+        new ExpectedMatch(
+            elementA,
+            MatchKind.LIBRARY_REFERENCE,
+            codeA.indexOf('lib; // A'),
+            'lib'.length),
+        new ExpectedMatch(
+            elementB,
+            MatchKind.LIBRARY_REFERENCE,
+            codeB.indexOf('lib; // B'),
+            'lib'.length),];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_LocalVariableElement() {
+    _indexTestUnit('''
+main() {
+  var v;
+  v = 1;
+  v += 2;
+  print(v);
+  v();
+}
+''');
+    LocalVariableElement element = findElement('v');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.VARIABLE_WRITE, 'v = 1;'),
+        _expectId(mainElement, MatchKind.VARIABLE_READ_WRITE, 'v += 2;'),
+        _expectId(mainElement, MatchKind.VARIABLE_READ, 'v);'),
+        _expectId(mainElement, MatchKind.FUNCTION_EXECUTION, 'v();')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_MethodElement() {
+    _indexTestUnit('''
+class A {
+  m() {}
+  main() {
+    m(); // 1
+    this.m(); // 2
+    print(m); // 3
+    print(this.m); // 4
+  }
+}
+''');
+    MethodElement method = findElement('m');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.METHOD_INVOCATION, 'm(); // 1'),
+        _expectIdQ(mainElement, MatchKind.METHOD_INVOCATION, 'm(); // 2'),
+        _expectId(mainElement, MatchKind.METHOD_REFERENCE, 'm); // 3'),
+        _expectIdQ(mainElement, MatchKind.METHOD_REFERENCE, 'm); // 4')];
+    return _verifyReferences(method, expected);
+  }
+
+  Future test_searchReferences_MethodMember() {
+    _indexTestUnit('''
+class A<T> {
+  T m() => null;
+}
+main(A<int> a) {
+  a.m(); // ref
+}
+''');
+    MethodMember method = findNodeElementAtString('m(); // ref');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectIdQ(mainElement, MatchKind.METHOD_INVOCATION, 'm(); // ref')];
+    return _verifyReferences(method, expected);
+  }
+
+  Future test_searchReferences_ParameterElement() {
+    _indexTestUnit('''
+foo({p}) {
+  p = 1;
+  p += 2;
+  print(p);
+  p();
+}
+main() {
+  foo(p: 42);
+}
+''');
+    ParameterElement element = findElement('p');
+    Element fooElement = findElement('foo');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(fooElement, MatchKind.VARIABLE_WRITE, 'p = 1;'),
+        _expectId(fooElement, MatchKind.VARIABLE_READ_WRITE, 'p += 2;'),
+        _expectId(fooElement, MatchKind.VARIABLE_READ, 'p);'),
+        _expectId(fooElement, MatchKind.FUNCTION_EXECUTION, 'p();'),
+        _expectId(mainElement, MatchKind.NAMED_PARAMETER_REFERENCE, 'p: 42')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_PropertyAccessorElement_getter() {
+    _indexTestUnit('''
+class A {
+  get g => null;
+  main() {
+    g; // 1
+    this.g; // 2
+  }
+}
+''');
+    PropertyAccessorElement element = findElement('g', ElementKind.GETTER);
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 'g; // 1'),
+        _expectIdQ(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 'g; // 2')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_PropertyAccessorElement_setter() {
+    _indexTestUnit('''
+class A {
+  set s(x) {}
+  main() {
+    s = 1;
+    this.s = 2;
+  }
+}
+''');
+    PropertyAccessorElement element = findElement('s=');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 's = 1'),
+        _expectIdQ(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 's = 2')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_TopLevelVariableElement() {
+    addSource('/lib.dart', '''
+library lib;
+var V;
+''');
+    _indexTestUnit('''
+import 'lib.dart' show V; // imp
+import 'lib.dart' as pref;
+main() {
+  V = 1;
+  print(V);
+  V();
+}
+mainQ() {
+  pref.V = 1; // Q
+  print(pref.V); // Q
+  pref.V(); // Q
+}
+''');
+    ImportElement importElement = testLibraryElement.imports[0];
+    CompilationUnitElement impUnit =
+        importElement.importedLibrary.definingCompilationUnit;
+    TopLevelVariableElement variable = impUnit.topLevelVariables[0];
+    Element main = findElement('main');
+    Element mainQ = findElement('mainQ');
+    var expected = [
+        _expectIdQ(testUnitElement, MatchKind.FIELD_REFERENCE, 'V; // imp'),
+        _expectId(main, MatchKind.FIELD_WRITE, 'V = 1;'),
+        _expectId(main, MatchKind.FIELD_READ, 'V);'),
+        _expectId(main, MatchKind.FIELD_INVOCATION, 'V();'),
+        _expectIdQ(mainQ, MatchKind.FIELD_WRITE, 'V = 1; // Q'),
+        _expectIdQ(mainQ, MatchKind.FIELD_READ, 'V); // Q'),
+        _expectIdQ(mainQ, MatchKind.FIELD_INVOCATION, 'V(); // Q')];
+    return _verifyReferences(variable, expected);
+  }
+
+  Future test_searchReferences_TypeParameterElement() {
+    _indexTestUnit('''
+class A<T> {
+  main(T a, T b) {}
+}
+''');
+    TypeParameterElement element = findElement('T');
+    Element aElement = findElement('a');
+    Element bElement = findElement('b');
+    var expected = [
+        _expectId(aElement, MatchKind.TYPE_PARAMETER_REFERENCE, 'T a'),
+        _expectId(bElement, MatchKind.TYPE_PARAMETER_REFERENCE, 'T b')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchSubtypes() {
+    _indexTestUnit('''
+class T {}
+class A extends T {} // A
+class B = Object with T; // B
+class C implements T {} // C
+''');
+    ClassElement element = findElement('T');
+    ClassElement elementA = findElement('A');
+    ClassElement elementB = findElement('B');
+    ClassElement elementC = findElement('C');
+    var expected = [
+        _expectId(elementA, MatchKind.EXTENDS_REFERENCE, 'T {} // A'),
+        _expectId(elementB, MatchKind.WITH_REFERENCE, 'T; // B'),
+        _expectId(elementC, MatchKind.IMPLEMENTS_REFERENCE, 'T {} // C')];
+    return searchEngine.searchSubtypes(element).then((matches) {
+      _assertMatches(matches, expected);
+    });
+  }
+
+  Future test_searchMemberReferences() {
+    _indexTestUnit('''
+class A {
+  var test; // A
+  mainA() {
+    test(); // a-inv-r-nq
+    test = 1; // a-write-r-nq
+    test += 2; // a-read-write-r-nq
+    print(test); // a-read-r-nq
+  }
+}
+main(A a, p) {
+  a.test(); // a-inv-r-q
+  a.test = 1; // a-write-r-q
+  a.test += 2; // a-read-write-r-q
+  print(a.test); // a-read-r-q
+  p.test(); // p-inv-ur-q
+  p.test = 1; // p-write-ur-q
+  p.test += 2; // p-read-write-ur-q
+  print(p.test); // p-read-ur-q
+}
+''');
+    ClassElement elementA = findElement('A');
+    ClassElement elementB = findElement('B');
+    Element mainA = findElement('mainA');
+    Element main = findElement('main');
+    var expected = [
+        _expectId(mainA, MatchKind.NAME_INVOCATION_RESOLVED, 'test(); // a-inv-r-nq'),
+        _expectId(mainA, MatchKind.NAME_WRITE_RESOLVED, 'test = 1; // a-write-r-nq'),
+        _expectId(mainA, MatchKind.NAME_READ_WRITE_RESOLVED, 'test += 2; // a-read-write-r-nq'),
+        _expectId(mainA, MatchKind.NAME_READ_RESOLVED, 'test); // a-read-r-nq'),
+        _expectId(main, MatchKind.NAME_INVOCATION_RESOLVED, 'test(); // a-inv-r-q'),
+        _expectId(main, MatchKind.NAME_WRITE_RESOLVED, 'test = 1; // a-write-r-q'),
+        _expectId(main, MatchKind.NAME_READ_WRITE_RESOLVED, 'test += 2; // a-read-write-r-q'),
+        _expectId(main, MatchKind.NAME_READ_RESOLVED, 'test); // a-read-r-q'),
+        _expectIdU(main, MatchKind.NAME_INVOCATION_UNRESOLVED, 'test(); // p-inv-ur-q'),
+        _expectIdU(main, MatchKind.NAME_WRITE_UNRESOLVED, 'test = 1; // p-write-ur-q'),
+        _expectIdU(main, MatchKind.NAME_READ_WRITE_UNRESOLVED, 'test += 2; // p-read-write-ur-q'),
+        _expectIdU(main, MatchKind.NAME_READ_UNRESOLVED, 'test); // p-read-ur-q'),
+        ];
+    return searchEngine.searchMemberReferences('test').then((matches) {
+      _assertMatches(matches, expected);
+    });
+  }
+
+  Future test_searchTopLevelDeclarations() {
+    _indexTestUnit('''
+class A {} // A
+class B = Object with A;
+typedef C();
+D() {}
+var E = null;
+class NoMatchABCDE {}
+''');
+    NameElement element = new NameElement('test');
+    Element topA = findElement('A');
+    Element topB = findElement('B');
+    Element topC = findElement('C');
+    Element topD = findElement('D');
+    Element topE = findElement('E');
+    Element topNoMatch = new MockElement('NoMatchABCDE');
+    var expected = [
+        _expectId(topA, MatchKind.CLASS_DECLARATION, 'A {} // A'),
+        _expectId(topB, MatchKind.CLASS_ALIAS_DECLARATION, 'B ='),
+        _expectId(topC, MatchKind.FUNCTION_TYPE_DECLARATION, 'C()'),
+        _expectId(topD, MatchKind.FUNCTION_DECLARATION, 'D() {}'),
+        _expectId(topE, MatchKind.VARIABLE_DECLARATION, 'E = null')];
+    return _verifyTopLevelDeclarations('^[A-E]\$', expected);
+  }
+
+  ExpectedMatch _expectId(Element element, MatchKind kind, String search,
+      {int length, bool isResolved: true, bool isQualified: false}) {
+    int offset = findOffset(search);
+    if (length == null) {
+      length = getLeadingIdentifierLength(search);
+    }
+    return new ExpectedMatch(
+        element,
+        kind,
+        offset,
+        length,
+        isResolved: isResolved,
+        isQualified: isQualified);
+  }
+
+  ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search) {
+    return _expectId(element, kind, search, isQualified: true);
+  }
+
+  ExpectedMatch _expectIdU(Element element, MatchKind kind, String search) {
+    return _expectId(element, kind, search, isResolved: false);
+  }
+
+  void _indexTestUnit(String code) {
+    resolveTestUnit(code);
+    index.indexUnit(context, testUnit);
+  }
+
+  Future _verifyReferences(Element element,
+      List<ExpectedMatch> expectedMatches) {
+    return searchEngine.searchReferences(
+        element).then((List<SearchMatch> matches) {
+      _assertMatches(matches, expectedMatches);
+    });
+  }
+
+  Future _verifyTopLevelDeclarations(String pattern,
+      List<ExpectedMatch> expectedMatches) {
+    return searchEngine.searchTopLevelDeclarations(
+        pattern).then((List<SearchMatch> matches) {
+      _assertMatches(matches, expectedMatches);
+    });
+  }
+
+  static void _assertMatches(List<SearchMatch> matches,
+      List<ExpectedMatch> expectedMatches) {
+    expect(matches, unorderedEquals(expectedMatches));
+  }
+}
diff --git a/pkg/analysis_services/test/search/test_all.dart b/pkg/analysis_services/test/search/test_all.dart
new file mode 100644
index 0000000..fad272d
--- /dev/null
+++ b/pkg/analysis_services/test/search/test_all.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, 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.
+
+library test.services.src.scheglov.all;
+
+import 'package:unittest/unittest.dart';
+
+import 'search_engine_test.dart' as search_engine_test;
+
+
+/**
+ * Utility for manually running all tests.
+ */
+main() {
+  groupSep = ' | ';
+  group('search', () {
+    search_engine_test.main();
+  });
+}
\ No newline at end of file
diff --git a/pkg/analysis_services/test/test_all.dart b/pkg/analysis_services/test/test_all.dart
index ee8b415..6f0df28 100644
--- a/pkg/analysis_services/test/test_all.dart
+++ b/pkg/analysis_services/test/test_all.dart
@@ -5,9 +5,11 @@
 import 'package:unittest/unittest.dart';
 
 import 'index/test_all.dart' as index_all;
+import 'search/test_all.dart' as search_all;
 
 /// Utility for manually running all tests.
 main() {
   groupSep = ' | ';
   index_all.main();
+  search_all.main();
 }
\ No newline at end of file
diff --git a/pkg/analysis_testing/lib/mock_sdk.dart b/pkg/analysis_testing/lib/mock_sdk.dart
index 05251ab..89de9b6 100644
--- a/pkg/analysis_testing/lib/mock_sdk.dart
+++ b/pkg/analysis_testing/lib/mock_sdk.dart
@@ -64,6 +64,8 @@
 
       "/lib/math/math.dart": '''
           library dart.math;
+          const double E = 2.718281828459045;
+          const double PI = 3.1415926535897932;
           '''
     };
 
diff --git a/pkg/analysis_testing/lib/mocks.dart b/pkg/analysis_testing/lib/mocks.dart
index 80aed86..aa1edef 100644
--- a/pkg/analysis_testing/lib/mocks.dart
+++ b/pkg/analysis_testing/lib/mocks.dart
@@ -16,24 +16,78 @@
 }
 
 
+class MockClassElement extends TypedMock implements ClassElement {
+  final ElementKind kind = ElementKind.CLASS;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
 class MockCompilationUnitElement extends TypedMock implements
     CompilationUnitElement {
+  final ElementKind kind = ElementKind.COMPILATION_UNIT;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockConstructorElement extends TypedMock implements ConstructorElement {
+  final kind = ElementKind.CONSTRUCTOR;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
 class MockElement extends StringTypedMock implements Element {
   MockElement([String name = '<element>']) : super(name);
+
+  @override
+  String get displayName => _toString;
+
+  @override
+  String get name => _toString;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockFieldElement extends TypedMock implements FieldElement {
+  final ElementKind kind = ElementKind.FIELD;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockFunctionElement extends TypedMock implements FunctionElement {
+  final ElementKind kind = ElementKind.FUNCTION;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockFunctionTypeAliasElement extends TypedMock implements
+    FunctionTypeAliasElement {
+  final ElementKind kind = ElementKind.FUNCTION_TYPE_ALIAS;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
 class MockHtmlElement extends TypedMock implements HtmlElement {
+  final ElementKind kind = ElementKind.HTML;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockImportElement extends TypedMock implements ImportElement {
+  final ElementKind kind = ElementKind.IMPORT;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
 class MockLibraryElement extends TypedMock implements LibraryElement {
+  final ElementKind kind = ElementKind.LIBRARY;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockLocalVariableElement extends TypedMock implements LocalVariableElement
+    {
+  final ElementKind kind = ElementKind.LOCAL_VARIABLE;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
@@ -43,12 +97,47 @@
 }
 
 
+class MockMethodElement extends StringTypedMock implements MethodElement {
+  final kind = ElementKind.METHOD;
+  MockMethodElement([String name = 'method']) : super(name);
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockParameterElement extends TypedMock implements ParameterElement {
+  final ElementKind kind = ElementKind.PARAMETER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockPropertyAccessorElement extends TypedMock implements
+    PropertyAccessorElement {
+  final ElementKind kind;
+  MockPropertyAccessorElement(this.kind);
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
 class MockSource extends StringTypedMock implements Source {
   MockSource([String name = 'mocked.dart']) : super(name);
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
+class MockTopLevelVariableElement extends TypedMock implements
+    TopLevelVariableElement {
+  final ElementKind kind = ElementKind.TOP_LEVEL_VARIABLE;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockTypeParameterElement extends TypedMock implements TypeParameterElement
+    {
+  final ElementKind kind = ElementKind.TYPE_PARAMETER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
 class StringTypedMock extends TypedMock {
   String _toString;
 
diff --git a/pkg/analysis_testing/pubspec.yaml b/pkg/analysis_testing/pubspec.yaml
index f064788..84c6630 100644
--- a/pkg/analysis_testing/pubspec.yaml
+++ b/pkg/analysis_testing/pubspec.yaml
@@ -1,11 +1,11 @@
 name: analysis_testing
-version: 0.2.0
+version: 0.3.0
 author: Dart Team <misc@dartlang.org>
 description: A set of libraries for testing Analysis services and server
 homepage: http://www.dartlang.org
 environment:
   sdk: '>=1.0.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.21.0 <1.0.0'
+  analyzer: '>=0.21.1 <1.0.0'
   typed_mock: '>=0.0.4 <1.0.0'
   unittest: '>=0.10.0 <0.12.0'
