anchor.diff:  // for details. All rights reserved. Use of this source code is governed by a
   // BSD-style license that can be found in the LICENSE file.
   
  +import 'dart:convert';
   import 'dart:io';
   
   import 'package:html/parser.dart' show parse;
   import 'package:http/http.dart' as http;
  +import 'package:path/path.dart' as path;
   
   /// Generate or update corpus data.
   /// Input is a list of directories, or a file containing such a list.
  -/// Output is produced in a relative `third_party/download` directory.
  +/// Output is produced in a `~/completion_metrics/third_party/apps` directory.
   Future<void> main(List<String> args) async {
     if (args.isEmpty) {
       print('A file name or list of directories is required.');
  
positive.code:   }
  }
  
  const _downloadDir = 'third_party/download';
  final _client = http.Client();
  
  Future<CloneResult> _clone(String repo) async {
    final name = repo.split('https://github.com/').last.replaceAll('/', '_');
    final cloneDir = '$_downloadDir/$name';
    var result;
    if (Directory(cloneDir).existsSync()) {
      print('Repository "$name" exists -- pulling to update');
  
negative.code: 
  Future<ProcessResult> _runPub(String dir) async =>
      await Process.run('flutter', ['pub', 'get'], workingDirectory: dir);
  
  String _trimName(String name) {
    while (name.endsWith('/')) {
      name = name.substring(0, name.length - 1);
    }
    return name;
  }
  
  class CloneResult {
    final String directory;
  