anchor.diff:      return columnWidths;
     }
   
  -  List<String> _computeRootPaths(String rootPath, bool corpus) {
  -    var roots = <String>[];
  -    if (!corpus) {
  -      roots.add(rootPath);
  -    } else {
  -      for (var child in io.Directory(rootPath).listSync()) {
  -        if (child is io.Directory) {
  -          roots.add(path.join(rootPath, child.path));
  -        }
  -      }
  -    }
  -    return roots;
  +  /// Compute the metrics for the files in the context [root], creating a
  +  /// separate context collection to prevent accumulating memory. The metrics
  +  /// should be captured in the [collector]. Include additional details in the
  +  /// output if [verbose] is `true`.
  +  void _computeInContext(ContextRoot root, RelevanceDataCollector collector,
  +      {@required bool verbose}) async {
  +    // Create a new collection to avoid consuming large quantities of memory.
  +    final collection = AnalysisContextCollection(
  +      includedPaths: root.includedPaths.toList(),
  +      excludedPaths: root.excludedPaths.toList(),
  +      resourceProvider: PhysicalResourceProvider.INSTANCE,
  +    );
  +    var context = collection.contexts[0];
  +    for (var filePath in context.contextRoot.analyzedFiles()) {
  +      if (AnalysisEngine.isDartFileName(filePath)) {
  +        try {
  +          ResolvedUnitResult resolvedUnitResult =
  +              await context.currentSession.getResolvedUnit(filePath);
  +          //
  +          // Check for errors that cause the file to be skipped.
  +          //
  +          if (resolvedUnitResult == null) {
  +            print('File $filePath skipped because resolved unit was null.');
  +            if (verbose) {
  +              print('');
  +            }
  +            continue;
  +          } else if (resolvedUnitResult.state != ResultState.VALID) {
  +            print('File $filePath skipped because it could not be analyzed.');
  +            if (verbose) {
  +              print('');
  +            }
  +            continue;
  +          } else if (hasError(resolvedUnitResult)) {
  +            if (verbose) {
  +              print('File $filePath skipped due to errors:');
  +              for (var error in resolvedUnitResult.errors
  +                  .where((e) => e.severity == Severity.error)) {
  +                print('  ${error.toString()}');
  +              }
  +              print('');
  +            } else {
  +              print('File $filePath skipped due to analysis errors.');
  +            }
  +            continue;
  +          }
  +
  +          collector.initializeFrom(resolvedUnitResult);
  +          resolvedUnitResult.unit.accept(collector);
  +        } catch (exception, stacktrace) {
  +          print('Exception caught analyzing: "$filePath"');
  +          print(exception);
  +          print(stacktrace);
  +        }
  +      }
  +    }
     }
   
     Iterable<List<String>> _convertColumnsToRows(
  
positive.code: import 'package:analyzer/src/generated/engine.dart';
  import 'package:args/args.dart';
  import 'package:meta/meta.dart';
  import 'package:path/path.dart' as path;
  
  /// Compute metrics to determine whether they should be used to compute a
  /// relevance score for completion suggestions.
  
negative.code:   /// Compute the metrics for the file(s) in the [rootPath].
    /// If [corpus] is true, treat rootPath as a container of packages, creating
    /// a new context collection for each subdirectory.
    void compute(String rootPath, {@required bool verbose}) async {
      final collection = AnalysisContextCollection(
        includedPaths: [rootPath],
        resourceProvider: PhysicalResourceProvider.INSTANCE,
      );
      final collector = RelevanceDataCollector(data);
      for (var context in collection.contexts) {
        await _computeInContext(context.contextRoot, collector, verbose: verbose);
      }
    }
  
  