anchor.diff:          }
         }
       }
  -
  -    final totalCompletionCount = includedCount + notIncludedCount;
  -    final percentIncluded = includedCount / totalCompletionCount;
  -    final percentNotIncluded = 1 - percentIncluded;
  -
  -    completionMissedTokenCounter.printCounterValues();
  -    print('');
  -
  -    completionKindCounter.printCounterValues();
  -    print('');
  -
  -    completionElementKindCounter.printCounterValues();
  -    print('');
  -
  -    mRRComputer.printMean();
  -    print('');
  -
  -    print('Summary for $_rootPath:');
  -    print('Total number of completion tests   = $totalCompletionCount');
  -    print(
  -        'Number of successful completions   = $includedCount (${printPercentage(percentIncluded)})');
  -    print(
  -        'Number of unsuccessful completions = $notIncludedCount (${printPercentage(percentNotIncluded)})');
  -
  -    if (_relevanceAnalyzers.isNotEmpty) {
  -      print('\nRelevance Analysis:');
  -      _relevanceAnalyzers.forEach((analyzer) => analyzer
  -        ..printData()
  -        ..clear());
  -    }
  -
  -    includedCount = 0;
  -    notIncludedCount = 0;
  -    completionMissedTokenCounter.clear();
  -    completionKindCounter.clear();
  -    completionElementKindCounter.clear();
  -    mRRComputer.clear();
  -  }
  +    printAndClearComputers();
  +  }
  +
  +  /// Overridden by each subclass, this method gathers some set of data from
  +  /// each [ExpectedCompletion], and each [CompletionSuggestion] list (if
  +  /// [doComputeCompletionsFromAnalysisServer] is set to true.)
  +  void forEachExpectedCompletion(ExpectedCompletion expectedCompletion,
  +      List<CompletionSuggestion> suggestions);
  +
  +  /// This method is called to print a summary of the data collected.
  +  void printAndClearComputers();
   
     Future<List<CompletionSuggestion>> _computeCompletionSuggestions(
         ResolvedUnitResult resolvedUnitResult, int offset,
  
positive.code: 
    /// Given some [ResolvedUnitResult] return the first error of high severity
    /// if such an error exists, null otherwise.
    err.AnalysisError _getFirstErrorOrNull(
        ResolvedUnitResult resolvedUnitResult) {
      for (var error in resolvedUnitResult.errors) {
        if (error.severity == Severity.error) {
  
negative.code:     );
  
      for (var context in collection.contexts) {
        // Set the DeclarationsTracker, only call doWork to build up the available
        // suggestions if doComputeCompletionsFromAnalysisServer is true.
        var declarationsTracker = DeclarationsTracker(
            MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
        declarationsTracker.addContext(context);
        if (doComputeCompletionsFromAnalysisServer) {
          while (declarationsTracker.hasWork) {
            declarationsTracker.doWork();
          }
        }
  
        // Loop through each file, resolve the file and call
        // forEachExpectedCompletion
        for (var filePath in context.contextRoot.analyzedFiles()) {
          if (AnalysisEngine.isDartFileName(filePath)) {
            _currentFilePath = filePath;
            try {
              _resolvedUnitResult =
                  await context.currentSession.getResolvedUnit(filePath);
  
              var error = getFirstErrorOrNull(resolvedUnitResult);
              if (error != null) {
                print('File $filePath skipped due to errors such as:');
                print('  ${error.toString()}');
  