Reland #13918 (#14023)

* Revert "Reverting package changes until I can figure out how to fix Windows. (#14007)"

This reverts commit 6fda8ee821dd2e63e7949e57b10efde84bb0a3cc.

* Make prepare_package run on Windows
diff --git a/dev/automated_tests/pubspec.yaml b/dev/automated_tests/pubspec.yaml
index 845daea..5fbb2c3 100644
--- a/dev/automated_tests/pubspec.yaml
+++ b/dev/automated_tests/pubspec.yaml
@@ -7,7 +7,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -16,7 +16,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/benchmarks/complex_layout/pubspec.yaml b/dev/benchmarks/complex_layout/pubspec.yaml
index ed170d5..136922a 100644
--- a/dev/benchmarks/complex_layout/pubspec.yaml
+++ b/dev/benchmarks/complex_layout/pubspec.yaml
@@ -19,7 +19,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -29,7 +29,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/benchmarks/microbenchmarks/pubspec.yaml b/dev/benchmarks/microbenchmarks/pubspec.yaml
index bed82f7..dd00dde 100644
--- a/dev/benchmarks/microbenchmarks/pubspec.yaml
+++ b/dev/benchmarks/microbenchmarks/pubspec.yaml
@@ -11,7 +11,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -21,7 +21,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   dart_style: 1.0.9 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/bots/prepare_package.dart b/dev/bots/prepare_package.dart
index b9621cc..023d00d 100644
--- a/dev/bots/prepare_package.dart
+++ b/dev/bots/prepare_package.dart
@@ -2,28 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:typed_data';
 
 import 'package:args/args.dart';
+import 'package:http/http.dart' as http;
 import 'package:path/path.dart' as path;
+import 'package:process/process.dart';
 
 const String CHROMIUM_REPO =
     'https://chromium.googlesource.com/external/github.com/flutter/flutter';
 const String GITHUB_REPO = 'https://github.com/flutter/flutter.git';
-
-/// The type of the process runner function.  This allows us to
-/// inject a fake process runner into the ArchiveCreator for tests.
-typedef ProcessResult ProcessRunner(
-  String executable,
-  List<String> arguments, {
-  String workingDirectory,
-  Map<String, String> environment,
-  bool includeParentEnvironment,
-  bool runInShell,
-  Encoding stdoutEncoding,
-  Encoding stderrEncoding,
-});
+const String MINGIT_FOR_WINDOWS_URL = 'https://storage.googleapis.com/flutter_infra/mingit/'
+    '603511c649b00bbef0a6122a827ac419b656bc19/mingit.zip';
 
 /// Error class for when a process fails to run, so we can catch
 /// it and provide something more readable than a stack trace.
@@ -39,64 +32,95 @@
 
 /// Creates a pre-populated Flutter archive from a git repo.
 class ArchiveCreator {
-  /// [tempDir] is the directory to use for creating the archive.  Will place
-  /// several GiB of data there, so it should have available space.
-  /// [outputFile] is the name of the output archive. It should end in either
-  /// ".tar.xz" or ".zip".
-  /// The runner argument is used to inject a mock of [Process.runSync] for
+  /// [_tempDir] is the directory to use for creating the archive.  The script
+  /// will place several GiB of data there, so it should have available space.
+  ///
+  /// The processManager argument is used to inject a mock of [ProcessManager] for
   /// testing purposes.
-  ArchiveCreator(this.tempDir, this.outputFile, {ProcessRunner runner})
-      : assert(outputFile.path.toLowerCase().endsWith('.zip') ||
-            outputFile.path.toLowerCase().endsWith('.tar.xz')),
-        flutterRoot = new Directory(path.join(tempDir.path, 'flutter')),
-        _runner = runner ?? Process.runSync {
-    flutter = path.join(
-      flutterRoot.absolute.path,
+  ///
+  /// If subprocessOutput is true, then output from processes invoked during
+  /// archive creation is echoed to stderr and stdout.
+  ArchiveCreator(this._tempDir, {ProcessManager processManager, bool subprocessOutput: true})
+      : _flutterRoot = new Directory(path.join(_tempDir.path, 'flutter')),
+        _processManager = processManager ?? const LocalProcessManager(),
+        _subprocessOutput = subprocessOutput {
+    _flutter = path.join(
+      _flutterRoot.absolute.path,
       'bin',
-      Platform.isWindows ? 'flutter.bat' : 'flutter',
+      'flutter',
     );
-    environment = new Map<String, String>.from(Platform.environment);
-    environment['PUB_CACHE'] = path.join(flutterRoot.absolute.path, '.pub-cache');
+    _environment = new Map<String, String>.from(Platform.environment);
+    _environment['PUB_CACHE'] = path.join(_flutterRoot.absolute.path, '.pub-cache');
   }
 
-  final Directory flutterRoot;
-  final Directory tempDir;
-  final File outputFile;
-  final ProcessRunner _runner;
-  String flutter;
-  final String git = Platform.isWindows ? 'git.bat' : 'git';
-  final String zip = Platform.isWindows ? '7za.exe' : 'zip';
-  final String tar = Platform.isWindows ? 'tar.exe' : 'tar';
-  Map<String, String> environment;
+  final Directory _flutterRoot;
+  final Directory _tempDir;
+  final bool _subprocessOutput;
+  final ProcessManager _processManager;
+  String _flutter;
+  final Uri _minGitUri = Uri.parse(MINGIT_FOR_WINDOWS_URL);
+  Map<String, String> _environment;
+
+  /// Returns a default archive name when given a Git revision.
+  /// Used when an output filename is not given.
+  static String defaultArchiveName(String revision) {
+    final String os = Platform.operatingSystem.toLowerCase();
+    final String id = revision.length > 10 ? revision.substring(0, 10) : revision;
+    final String suffix = Platform.isWindows ? 'zip' : 'tar.xz';
+    return 'flutter_${os}_$id.$suffix';
+  }
+
+  /// Performs all of the steps needed to create an archive.
+  Future<File> createArchive(String revision, File outputFile) async {
+    await _checkoutFlutter(revision);
+    await _installMinGitIfNeeded();
+    await _populateCaches();
+    await _archiveFiles(outputFile);
+    return outputFile;
+  }
 
   /// Clone the Flutter repo and make sure that the git environment is sane
   /// for when the user will unpack it.
-  void checkoutFlutter(String revision) {
+  Future<Null> _checkoutFlutter(String revision) async {
     // We want the user to start out the in the 'master' branch instead of a
     // detached head. To do that, we need to make sure master points at the
     // desired revision.
-    runGit(<String>['clone', '-b', 'master', CHROMIUM_REPO], workingDirectory: tempDir);
-    runGit(<String>['reset', '--hard', revision]);
+    await _runGit(<String>['clone', '-b', 'master', CHROMIUM_REPO], workingDirectory: _tempDir);
+    await _runGit(<String>['reset', '--hard', revision]);
 
     // Make the origin point to github instead of the chromium mirror.
-    runGit(<String>['remote', 'remove', 'origin']);
-    runGit(<String>['remote', 'add', 'origin', GITHUB_REPO]);
+    await _runGit(<String>['remote', 'remove', 'origin']);
+    await _runGit(<String>['remote', 'add', 'origin', GITHUB_REPO]);
+  }
+
+  /// Retrieve the MinGit executable from storage and unpack it.
+  Future<Null> _installMinGitIfNeeded() async {
+    if (!Platform.isWindows) {
+      return;
+    }
+    final Uint8List data = await http.readBytes(_minGitUri);
+    final File gitFile = new File(path.join(_tempDir.path, 'mingit.zip'));
+    await gitFile.writeAsBytes(data, flush: true);
+
+    final Directory minGitPath = new Directory(path.join(_flutterRoot.path, 'bin', 'mingit'));
+    await minGitPath.create(recursive: true);
+    await _unzipArchive(gitFile, currentDirectory: minGitPath);
   }
 
   /// Prepare the archive repo so that it has all of the caches warmed up and
-  /// is configured for the user to being working.
-  void prepareArchive() {
-    runFlutter(<String>['doctor']);
-    runFlutter(<String>['update-packages']);
-    runFlutter(<String>['precache']);
-    runFlutter(<String>['ide-config']);
+  /// is configured for the user to begin working.
+  Future<Null> _populateCaches() async {
+    await _runFlutter(<String>['doctor']);
+    await _runFlutter(<String>['update-packages']);
+    await _runFlutter(<String>['precache']);
+    await _runFlutter(<String>['ide-config']);
 
-    // Create each of the templates, since they will call pub get on
+    // Create each of the templates, since they will call 'pub get' on
     // themselves when created, and this will warm the cache with their
     // dependencies too.
     for (String template in <String>['app', 'package', 'plugin']) {
-      final String createName = path.join(tempDir.path, 'create_$template');
-      runFlutter(
+      final String createName = path.join(_tempDir.path, 'create_$template');
+      await _runFlutter(
         <String>['create', '--template=$template', createName],
       );
     }
@@ -104,88 +128,128 @@
     // Yes, we could just skip all .packages files when constructing
     // the archive, but some are checked in, and we don't want to skip
     // those.
-    runGit(<String>['clean', '-f', '-X', '**/.packages']);
+    await _runGit(<String>['clean', '-f', '-X', '**/.packages']);
   }
 
-  /// Create the archive into the given output file.
-  void createArchive() {
+  /// Write the archive to the given output file.
+  Future<Null> _archiveFiles(File outputFile) async {
     if (outputFile.path.toLowerCase().endsWith('.zip')) {
-      createZipArchive(outputFile, flutterRoot);
+      await _createZipArchive(outputFile, _flutterRoot);
     } else if (outputFile.path.toLowerCase().endsWith('.tar.xz')) {
-      createTarArchive(outputFile, flutterRoot);
+      await _createTarArchive(outputFile, _flutterRoot);
     }
   }
 
-  String _runProcess(String executable, List<String> args, {Directory workingDirectory}) {
-    workingDirectory ??= flutterRoot;
-    stderr.write('Running "$executable ${args.join(' ')}" in ${workingDirectory.path}.\n');
-    ProcessResult result;
-    try {
-      result = _runner(
-        executable,
-        args,
-        workingDirectory: workingDirectory.absolute.path,
-        environment: environment,
-        includeParentEnvironment: false,
-      );
-    } on ProcessException catch (e) {
-      final String message = 'Running "$executable ${args.join(' ')}" in ${workingDirectory.path} '
-          'failed with:\n${e.toString()}\n  PATH: ${environment['PATH']}';
-      throw new ProcessFailedException(message, -1);
-    } catch (e) {
-      rethrow;
-    }
-    stdout.write(result.stdout);
-    stderr.write(result.stderr);
-    if (result.exitCode != 0) {
-      final String message = 'Running "$executable ${args.join(' ')}" in ${workingDirectory.path} '
-          'failed with ${result.exitCode}.';
-      throw new ProcessFailedException(message, result.exitCode);
-    }
-    return result.stdout.trim();
+  Future<String> _runFlutter(List<String> args) => _runProcess(<String>[_flutter]..addAll(args));
+
+  Future<String> _runGit(List<String> args, {Directory workingDirectory}) {
+    return _runProcess(<String>['git']..addAll(args), workingDirectory: workingDirectory);
   }
 
-  String runFlutter(List<String> args) {
-    return _runProcess(flutter, args);
+  /// Unpacks the given zip file into the currentDirectory (if set), or the
+  /// same directory as the archive.
+  ///
+  /// May only be run on Windows (since 7Zip is not available on other platforms).
+  Future<String> _unzipArchive(File archive, {Directory currentDirectory}) {
+    assert(Platform.isWindows);  // 7Zip is only available on Windows.
+    currentDirectory ??= new Directory(path.dirname(archive.absolute.path));
+    final List<String> commandLine = <String>['7za', 'x', archive.absolute.path];
+    return _runProcess(commandLine, workingDirectory: currentDirectory);
   }
 
-  String runGit(List<String> args, {Directory workingDirectory}) {
-    return _runProcess(git, args, workingDirectory: workingDirectory);
-  }
-
-  void createZipArchive(File output, Directory source) {
-    final List<String> args = <String>[];
-    if (Platform.isWindows) {
-      // We use 7-Zip on Windows, which has different args.
-      args.addAll(<String>['a', '-tzip', '-mx=9']);
-    } else {
-      args.addAll(<String>['-r', '-9', '-q']);
-    }
-    args.addAll(<String>[
-      output.absolute.path,
-      path.basename(source.absolute.path),
-    ]);
-
-    _runProcess(zip, args,
-        workingDirectory: new Directory(path.dirname(source.absolute.path)));
-  }
-
-  void createTarArchive(File output, Directory source) {
-    final List<String> args = <String>[
-      'cJf',
+  /// Create a zip archive from the directory source.
+  ///
+  /// May only be run on Windows (since 7Zip is not available on other platforms).
+  Future<String> _createZipArchive(File output, Directory source) {
+    assert(Platform.isWindows);  // 7Zip is only available on Windows.
+    final List<String> commandLine = <String>[
+      '7za',
+      'a',
+      '-tzip',
+      '-mx=9',
       output.absolute.path,
       path.basename(source.absolute.path),
     ];
-    _runProcess(tar, args,
+    return _runProcess(commandLine,
         workingDirectory: new Directory(path.dirname(source.absolute.path)));
   }
+
+  /// Create a tar archive from the directory source.
+  Future<String> _createTarArchive(File output, Directory source) {
+    return _runProcess(<String>[
+      'tar',
+      'cJf',
+      output.absolute.path,
+      path.basename(source.absolute.path),
+    ], workingDirectory: new Directory(path.dirname(source.absolute.path)));
+  }
+
+  /// Run the command and arguments in commandLine as a sub-process from
+  /// workingDirectory if set, or the current directory if not.
+  Future<String> _runProcess(List<String> commandLine, {Directory workingDirectory}) async {
+    workingDirectory ??= _flutterRoot;
+    if (_subprocessOutput) {
+      stderr.write('Running "${commandLine.join(' ')}" in ${workingDirectory.path}.\n');
+    }
+    final List<int> output = <int>[];
+    final Completer<Null> stdoutComplete = new Completer<Null>();
+    final Completer<Null> stderrComplete = new Completer<Null>();
+    Process process;
+    Future<int> allComplete() async {
+      await stderrComplete.future;
+      await stdoutComplete.future;
+      return process.exitCode;
+    }
+
+    try {
+      process = await _processManager.start(
+        commandLine,
+        workingDirectory: workingDirectory.absolute.path,
+        environment: _environment,
+      );
+      process.stdout.listen(
+        (List<int> event) {
+          output.addAll(event);
+          if (_subprocessOutput) {
+            stdout.add(event);
+          }
+        },
+        onDone: () async => stdoutComplete.complete(),
+      );
+      if (_subprocessOutput) {
+        process.stderr.listen(
+          (List<int> event) {
+            stderr.add(event);
+          },
+          onDone: () async => stderrComplete.complete(),
+        );
+      } else {
+        stderrComplete.complete();
+      }
+    } on ProcessException catch (e) {
+      final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} '
+          'failed with:\n${e.toString()}';
+      throw new ProcessFailedException(message, -1);
+    }
+
+    final int exitCode = await allComplete();
+    if (exitCode != 0) {
+      final String message = 'Running "${commandLine.join(' ')}" in ${workingDirectory.path} '
+          'failed with $exitCode.';
+      throw new ProcessFailedException(message, exitCode);
+    }
+    return UTF8.decoder.convert(output).trim();
+  }
 }
 
 /// Prepares a flutter git repo to be packaged up for distribution.
 /// It mainly serves to populate the .pub-cache with any appropriate Dart
 /// packages, and the flutter cache in bin/cache with the appropriate
 /// dependencies and snapshots.
-void main(List<String> argList) {
+///
+/// Note that archives contain the executables and customizations for the
+/// platform that they are created on.
+Future<Null> main(List<String> argList) async {
   final ArgParser argParser = new ArgParser();
   argParser.addOption(
     'temp_dir',
@@ -203,9 +267,11 @@
   argParser.addOption(
     'output',
     defaultsTo: null,
-    help: 'The path where the output archive should be written. '
-        'The suffix determines the output format: .tar.xz or .zip are the '
-        'only formats supported.',
+    help: 'The path to the file where the output archive should be '
+        'written. The output file must end in ".tar.xz" on Linux and Mac, '
+        'and ".zip" on Windows. If --output is not specified, the archive will '
+        "be written to the current directory. If the output directory doesn't "
+        'exist, it, and the path to it, will be created.',
   );
   final ArgResults args = argParser.parse(argList);
 
@@ -219,47 +285,51 @@
     errorExit('Invalid argument: --revision must be specified.');
   }
 
-  Directory tmpDir;
+  Directory tempDir;
   bool removeTempDir = false;
   if (args['temp_dir'] == null || args['temp_dir'].isEmpty) {
-    tmpDir = Directory.systemTemp.createTempSync('flutter_');
+    tempDir = Directory.systemTemp.createTempSync('flutter_');
     removeTempDir = true;
   } else {
-    tmpDir = new Directory(args['temp_dir']);
-    if (!tmpDir.existsSync()) {
+    tempDir = new Directory(args['temp_dir']);
+    if (!tempDir.existsSync()) {
       errorExit("Temporary directory ${args['temp_dir']} doesn't exist.");
     }
   }
 
-  String outputFileString = args['output'];
-  if (outputFileString == null || outputFileString.isEmpty) {
-    final String suffix = Platform.isWindows ? '.zip' : '.tar.xz';
-    outputFileString = path.join(tmpDir.path, 'flutter_${args['revision']}$suffix');
-  } else if (!outputFileString.toLowerCase().endsWith('.zip') &&
-      !outputFileString.toLowerCase().endsWith('.tar.xz')) {
-    errorExit('Output file has unsupported suffix. It should be either ".zip" or ".tar.xz".');
+  final String output = (args['output'] == null || args['output'].isEmpty)
+      ? path.join(path.current, ArchiveCreator.defaultArchiveName(args['revision']))
+      : args['output'];
+
+  /// Sanity check the output filename.
+  final String outputFilename = path.basename(output);
+  if (Platform.isWindows) {
+    if (!outputFilename.endsWith('.zip')) {
+      errorExit('The argument to --output must end in .zip on Windows.');
+    }
+  } else {
+    if (!outputFilename.endsWith('.tar.xz')) {
+      errorExit('The argument to --output must end in .tar.xz on Linux and Mac.');
+    }
   }
 
-  final File outputFile = new File(outputFileString);
-  if (outputFile.existsSync()) {
-    errorExit('Output file ${outputFile.absolute.path} already exists.');
+  final Directory outputDirectory = new Directory(path.dirname(output));
+  if (!outputDirectory.existsSync()) {
+    outputDirectory.createSync(recursive: true);
   }
+  final File outputFile = new File(path.join(outputDirectory.absolute.path, outputFilename));
 
-  final ArchiveCreator preparer = new ArchiveCreator(tmpDir, outputFile);
+  final ArchiveCreator preparer = new ArchiveCreator(tempDir);
   int exitCode = 0;
   String message;
   try {
-    preparer.checkoutFlutter(args['revision']);
-    preparer.prepareArchive();
-    preparer.createArchive();
+    await preparer.createArchive(args['revision'], outputFile);
   } on ProcessFailedException catch (e) {
     exitCode = e.exitCode;
     message = e.message;
-  } catch (e) {
-    rethrow;
   } finally {
     if (removeTempDir) {
-      tmpDir.deleteSync(recursive: true);
+      tempDir.deleteSync(recursive: true);
     }
     if (exitCode != 0) {
       errorExit(message, exitCode: exitCode);
diff --git a/dev/bots/pubspec.yaml b/dev/bots/pubspec.yaml
index 000b366..4914df2 100644
--- a/dev/bots/pubspec.yaml
+++ b/dev/bots/pubspec.yaml
@@ -4,13 +4,14 @@
 dependencies:
   path: 1.5.1
   args: 0.13.7
+  process: 2.0.7
 
 dev_dependencies:
   test: 0.12.26
   mockito: 2.2.1
 
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -18,11 +19,13 @@
   convert: 2.0.1 # TRANSITIVE DEPENDENCY
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
+  file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
+  intl: 0.15.2 # TRANSITIVE DEPENDENCY
   io: 0.3.1 # TRANSITIVE DEPENDENCY
   isolate: 1.1.0 # TRANSITIVE DEPENDENCY
   js: 0.6.1 # TRANSITIVE DEPENDENCY
@@ -33,6 +36,7 @@
   node_preamble: 1.4.0 # TRANSITIVE DEPENDENCY
   package_config: 1.0.3 # TRANSITIVE DEPENDENCY
   package_resolver: 1.0.2 # TRANSITIVE DEPENDENCY
+  platform: 2.1.1 # TRANSITIVE DEPENDENCY
   plugin: 0.2.0+2 # TRANSITIVE DEPENDENCY
   pool: 1.3.4 # TRANSITIVE DEPENDENCY
   pub_semver: 1.3.2 # TRANSITIVE DEPENDENCY
diff --git a/dev/bots/test/prepare_package_test.dart b/dev/bots/test/prepare_package_test.dart
index 2cfe44b..7b9b68d 100644
--- a/dev/bots/test/prepare_package_test.dart
+++ b/dev/bots/test/prepare_package_test.dart
@@ -2,12 +2,13 @@
 // 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:async';
 import 'dart:io';
 
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 import 'package:path/path.dart' as path;
+import 'package:process/process.dart';
 
 import '../prepare_package.dart';
 
@@ -17,131 +18,100 @@
     Directory tmpDir;
     Directory flutterDir;
     File outputFile;
-    MockProcessRunner runner;
-    List<MockProcessResult> results;
+    MockProcessManager processManager;
+    List<MockProcess> results = <MockProcess>[];
     final List<List<String>> args = <List<String>>[];
     final List<Map<Symbol, dynamic>> namedArgs = <Map<Symbol, dynamic>>[];
-    final String zipExe = Platform.isWindows ? '7za.exe' : 'zip';
-    final String tarExe = Platform.isWindows ? 'tar.exe' : 'tar';
-    final String gitExe = Platform.isWindows ? 'git.bat' : 'git';
     String flutterExe;
 
     void _verifyCommand(List<dynamic> args, String expected) {
       final List<String> expectedList = expected.split(' ');
-      final String executable = expectedList.removeAt(0);
-      expect(args[0], executable);
-      expect(args[1], orderedEquals(expectedList));
+      expect(args[0], orderedEquals(expectedList));
     }
 
-    ProcessResult _nextResult(Invocation invocation) {
+    Future<Process> _nextResult(Invocation invocation) async {
       args.add(invocation.positionalArguments);
       namedArgs.add(invocation.namedArguments);
-      return results.isEmpty ? new MockProcessResult('', '', 0) : results.removeAt(0);
+      final Process result = results.isEmpty ? new MockProcess('', '', 0) : results.removeAt(0);
+      return new Future<Process>.value(result);
     }
 
     void _answerWithResults() {
       when(
-        runner.call(
-          typed(captureAny),
+        processManager.start(
           typed(captureAny),
           environment: typed(captureAny, named: 'environment'),
           workingDirectory: typed(captureAny, named: 'workingDirectory'),
-          includeParentEnvironment: typed(captureAny, named: 'includeParentEnvironment'),
         ),
       ).thenAnswer(_nextResult);
     }
 
     setUp(() async {
-      runner = new MockProcessRunner();
+      processManager = new MockProcessManager();
       args.clear();
       namedArgs.clear();
       tmpDir = await Directory.systemTemp.createTemp('flutter_');
+      outputFile =
+          new File(path.join(tmpDir.absolute.path, ArchiveCreator.defaultArchiveName('master')));
       flutterDir = new Directory(path.join(tmpDir.path, 'flutter'));
+      flutterDir.createSync(recursive: true);
       flutterExe =
-          path.join(flutterDir.path, 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter');
+          path.join(flutterDir.path, 'bin', 'flutter');
     });
 
     tearDown(() async {
-      await tmpDir.delete(recursive: true);
+      // On Windows, the directory is locked and not able to be deleted, because it is a
+      // temporary directory. So we just leave some (very small, because we're not actually
+      // building archives here) trash around to be deleted at the next reboot.
+      if (!Platform.isWindows) {
+        await tmpDir.delete(recursive: true);
+      }
     });
 
     test('sets PUB_CACHE properly', () async {
-      outputFile = new File(path.join(tmpDir.absolute.path, 'flutter_master.tar.xz'));
-      preparer = new ArchiveCreator(tmpDir, outputFile, runner: runner);
+      preparer =
+          new ArchiveCreator(tmpDir, processManager: processManager, subprocessOutput: false);
       _answerWithResults();
-      results = <MockProcessResult>[new MockProcessResult('deadbeef\n', '', 0)];
-      preparer.checkoutFlutter('master');
-      preparer.prepareArchive();
-      preparer.createArchive();
+      await preparer.createArchive('master', outputFile);
       expect(
-        verify(runner.call(
-          captureAny,
+        verify(processManager.start(
           captureAny,
           workingDirectory: captureAny,
           environment: captureAny,
-          includeParentEnvironment: typed(captureAny, named: 'includeParentEnvironment'),
-        )).captured[2]['PUB_CACHE'],
+        )).captured[1]['PUB_CACHE'],
         endsWith(path.join('flutter', '.pub-cache')),
       );
     });
 
-    test('calls the right commands for tar output', () async {
-      outputFile = new File(path.join(tmpDir.absolute.path, 'flutter_master.tar.xz'));
-      preparer = new ArchiveCreator(tmpDir, outputFile, runner: runner);
+    test('calls the right commands for archive output', () async {
+      preparer =
+          new ArchiveCreator(tmpDir, processManager: processManager, subprocessOutput: false);
       _answerWithResults();
-      results = <MockProcessResult>[new MockProcessResult('deadbeef\n', '', 0)];
-      preparer.checkoutFlutter('master');
-      preparer.prepareArchive();
-      preparer.createArchive();
+      await preparer.createArchive('master', outputFile);
       final List<String> commands = <String>[
-        '$gitExe clone -b master https://chromium.googlesource.com/external/github.com/flutter/flutter',
-        '$gitExe reset --hard master',
-        '$gitExe remote remove origin',
-        '$gitExe remote add origin https://github.com/flutter/flutter.git',
-        '$flutterExe doctor',
-        '$flutterExe update-packages',
-        '$flutterExe precache',
-        '$flutterExe ide-config',
-        '$flutterExe create --template=app ${path.join(tmpDir.path, 'create_app')}',
-        '$flutterExe create --template=package ${path.join(tmpDir.path, 'create_package')}',
-        '$flutterExe create --template=plugin ${path.join(tmpDir.path, 'create_plugin')}',
-        '$gitExe clean -f -X **/.packages',
-        '$tarExe cJf ${path.join(tmpDir.path, 'flutter_master.tar.xz')} flutter',
-      ];
-      int step = 0;
-      for (String command in commands) {
-        _verifyCommand(args[step++], command);
-      }
-    });
-
-    test('calls the right commands for zip output', () async {
-      outputFile = new File(path.join(tmpDir.absolute.path, 'flutter_master.zip'));
-      preparer = new ArchiveCreator(tmpDir, outputFile, runner: runner);
-      _answerWithResults();
-      results = <MockProcessResult>[new MockProcessResult('deadbeef\n', '', 0)];
-      preparer.checkoutFlutter('master');
-      preparer.prepareArchive();
-      preparer.createArchive();
-      final List<String> commands = <String>[
-        '$gitExe clone -b master https://chromium.googlesource.com/external/github.com/flutter/flutter',
-        '$gitExe reset --hard master',
-        '$gitExe remote remove origin',
-        '$gitExe remote add origin https://github.com/flutter/flutter.git',
-        '$flutterExe doctor',
-        '$flutterExe update-packages',
-        '$flutterExe precache',
-        '$flutterExe ide-config',
-        '$flutterExe create --template=app ${path.join(tmpDir.path, 'create_app')}',
-        '$flutterExe create --template=package ${path.join(tmpDir.path, 'create_package')}',
-        '$flutterExe create --template=plugin ${path.join(tmpDir.path, 'create_plugin')}',
-        '$gitExe clean -f -X **/.packages',
+        'git clone -b master https://chromium.googlesource.com/external/github.com/flutter/flutter',
+        'git reset --hard master',
+        'git remote remove origin',
+        'git remote add origin https://github.com/flutter/flutter.git',
       ];
       if (Platform.isWindows) {
-        commands.add('$zipExe a -tzip -mx=9 ${path.join(tmpDir.path, 'flutter_master.zip')} flutter');
-      } else {
-        commands.add('$zipExe -r -9 -q ${path.join(tmpDir.path, 'flutter_master.zip')} flutter');
+        commands.add('7za x ${path.join(tmpDir.path, 'mingit.zip')}');
       }
-
+      commands.addAll(<String>[
+        '$flutterExe doctor',
+        '$flutterExe update-packages',
+        '$flutterExe precache',
+        '$flutterExe ide-config',
+        '$flutterExe create --template=app ${path.join(tmpDir.path, 'create_app')}',
+        '$flutterExe create --template=package ${path.join(tmpDir.path, 'create_package')}',
+        '$flutterExe create --template=plugin ${path.join(tmpDir.path, 'create_plugin')}',
+        'git clean -f -X **/.packages',
+      ]);
+      if (Platform.isWindows) {
+        commands.add('7za a -tzip -mx=9 ${outputFile.absolute.path} flutter');
+      } else {
+        commands.add('tar cJf ${outputFile.absolute.path} flutter');
+      }
       int step = 0;
       for (String command in commands) {
         _verifyCommand(args[step++], command);
@@ -149,50 +119,37 @@
     });
 
     test('throws when a command errors out', () async {
-      outputFile = new File(path.join(tmpDir.absolute.path, 'flutter.tar.xz'));
-      preparer = new ArchiveCreator(
-        tmpDir,
-        outputFile,
-        runner: runner,
-      );
+      preparer =
+          new ArchiveCreator(tmpDir, processManager: processManager, subprocessOutput: false);
 
-      results = <MockProcessResult>[
-        new MockProcessResult('', '', 0),
-        new MockProcessResult('OMG! OMG! an ERROR!\n', '', -1)
+      results = <MockProcess>[
+        new MockProcess('', '', 0),
+        new MockProcess('', "Don't panic.\n", -1)
       ];
       _answerWithResults();
-      expect(() => preparer.checkoutFlutter('master'),
+      expect(expectAsync2<Null, String, File>(preparer.createArchive)('master', new File('foo')),
           throwsA(const isInstanceOf<ProcessFailedException>()));
-      expect(args.length, 2);
-      _verifyCommand(args[0],
-          '$gitExe clone -b master https://chromium.googlesource.com/external/github.com/flutter/flutter');
-      _verifyCommand(args[1], '$gitExe reset --hard master');
     });
   });
 }
 
-class MockProcessRunner extends Mock implements Function {
-  ProcessResult call(
-    String executable,
-    List<String> arguments, {
-    String workingDirectory,
-    Map<String, String> environment,
-    bool includeParentEnvironment,
-    bool runInShell,
-    Encoding stdoutEncoding,
-    Encoding stderrEncoding,
-  });
-}
+class MockProcessManager extends Mock implements ProcessManager {}
 
-class MockProcessResult extends Mock implements ProcessResult {
-  MockProcessResult(this.stdout, [this.stderr = '', this.exitCode = 0]);
+class MockProcess extends Mock implements Process {
+  MockProcess(this._stdout, [this._stderr, this._exitCode]);
+
+  String _stdout;
+  String _stderr;
+  int _exitCode;
 
   @override
-  dynamic stdout = '';
+  Stream<List<int>> get stdout =>
+      new Stream<List<int>>.fromIterable(<List<int>>[_stdout.codeUnits]);
 
   @override
-  dynamic stderr;
+  Stream<List<int>> get stderr =>
+      new Stream<List<int>>.fromIterable(<List<int>>[_stderr.codeUnits]);
 
   @override
-  int exitCode;
+  Future<int> get exitCode => new Future<int>.value(_exitCode);
 }
diff --git a/dev/devicelab/pubspec.yaml b/dev/devicelab/pubspec.yaml
index 71e1b6a..fa26054 100644
--- a/dev/devicelab/pubspec.yaml
+++ b/dev/devicelab/pubspec.yaml
@@ -24,7 +24,7 @@
 
   archive: 1.0.33 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   browser: 0.10.0+2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
@@ -34,7 +34,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/integration_tests/channels/pubspec.yaml b/dev/integration_tests/channels/pubspec.yaml
index 1de59ae..cbd05b5 100644
--- a/dev/integration_tests/channels/pubspec.yaml
+++ b/dev/integration_tests/channels/pubspec.yaml
@@ -9,7 +9,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -19,7 +19,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/integration_tests/external_ui/pubspec.yaml b/dev/integration_tests/external_ui/pubspec.yaml
index ade871a..e564cfd 100644
--- a/dev/integration_tests/external_ui/pubspec.yaml
+++ b/dev/integration_tests/external_ui/pubspec.yaml
@@ -9,7 +9,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -19,7 +19,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/integration_tests/flavors/pubspec.yaml b/dev/integration_tests/flavors/pubspec.yaml
index da06bed..4dba44a 100644
--- a/dev/integration_tests/flavors/pubspec.yaml
+++ b/dev/integration_tests/flavors/pubspec.yaml
@@ -9,7 +9,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -19,7 +19,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/integration_tests/platform_interaction/pubspec.yaml b/dev/integration_tests/platform_interaction/pubspec.yaml
index eddbd14..7783339 100644
--- a/dev/integration_tests/platform_interaction/pubspec.yaml
+++ b/dev/integration_tests/platform_interaction/pubspec.yaml
@@ -9,7 +9,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -19,7 +19,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/integration_tests/ui/pubspec.yaml b/dev/integration_tests/ui/pubspec.yaml
index 65feeeb..4d68e7a 100644
--- a/dev/integration_tests/ui/pubspec.yaml
+++ b/dev/integration_tests/ui/pubspec.yaml
@@ -16,7 +16,7 @@
   archive: 1.0.33 # TRANSITIVE DEPENDENCY
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   browser: 0.10.0+2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
@@ -27,7 +27,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/manual_tests/pubspec.yaml b/dev/manual_tests/pubspec.yaml
index 42372a9..7b358df 100644
--- a/dev/manual_tests/pubspec.yaml
+++ b/dev/manual_tests/pubspec.yaml
@@ -10,7 +10,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -19,7 +19,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/dev/tools/vitool/pubspec.yaml b/dev/tools/vitool/pubspec.yaml
index 326de17..317ccdc 100644
--- a/dev/tools/vitool/pubspec.yaml
+++ b/dev/tools/vitool/pubspec.yaml
@@ -16,7 +16,7 @@
   test: 0.12.26
 
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -25,7 +25,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/catalog/pubspec.yaml b/examples/catalog/pubspec.yaml
index fd549f8..631dd12 100644
--- a/examples/catalog/pubspec.yaml
+++ b/examples/catalog/pubspec.yaml
@@ -13,7 +13,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -23,7 +23,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/flutter_gallery/pubspec.yaml b/examples/flutter_gallery/pubspec.yaml
index 201d6cc..24e5121 100644
--- a/examples/flutter_gallery/pubspec.yaml
+++ b/examples/flutter_gallery/pubspec.yaml
@@ -25,7 +25,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -34,7 +34,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/flutter_view/pubspec.yaml b/examples/flutter_view/pubspec.yaml
index 85793e9..f443d5d 100644
--- a/examples/flutter_view/pubspec.yaml
+++ b/examples/flutter_view/pubspec.yaml
@@ -7,7 +7,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -16,7 +16,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/hello_world/pubspec.yaml b/examples/hello_world/pubspec.yaml
index 0ee1429..e7ed336 100644
--- a/examples/hello_world/pubspec.yaml
+++ b/examples/hello_world/pubspec.yaml
@@ -10,7 +10,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -19,7 +19,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/layers/pubspec.yaml b/examples/layers/pubspec.yaml
index 81071e7..ff6c713 100644
--- a/examples/layers/pubspec.yaml
+++ b/examples/layers/pubspec.yaml
@@ -9,7 +9,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -18,7 +18,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/platform_channel/pubspec.yaml b/examples/platform_channel/pubspec.yaml
index fa97a36..e78f66f 100644
--- a/examples/platform_channel/pubspec.yaml
+++ b/examples/platform_channel/pubspec.yaml
@@ -12,7 +12,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -22,7 +22,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/platform_channel_swift/pubspec.yaml b/examples/platform_channel_swift/pubspec.yaml
index db84f35..bf4e975 100644
--- a/examples/platform_channel_swift/pubspec.yaml
+++ b/examples/platform_channel_swift/pubspec.yaml
@@ -12,7 +12,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -22,7 +22,7 @@
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/platform_view/pubspec.yaml b/examples/platform_view/pubspec.yaml
index 8c4e2d8..9007973 100644
--- a/examples/platform_view/pubspec.yaml
+++ b/examples/platform_view/pubspec.yaml
@@ -6,7 +6,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -15,7 +15,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/examples/stocks/pubspec.yaml b/examples/stocks/pubspec.yaml
index b5cc0f1..dfafbed 100644
--- a/examples/stocks/pubspec.yaml
+++ b/examples/stocks/pubspec.yaml
@@ -17,7 +17,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -28,7 +28,7 @@
   dart_style: 1.0.9 # TRANSITIVE DEPENDENCY
   file: 2.3.5 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
   io: 0.3.1 # TRANSITIVE DEPENDENCY
diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml
index 5cba8e9..babcb14 100644
--- a/packages/flutter/pubspec.yaml
+++ b/packages/flutter/pubspec.yaml
@@ -22,7 +22,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -30,7 +30,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
   io: 0.3.1 # TRANSITIVE DEPENDENCY
diff --git a/packages/flutter_driver/pubspec.yaml b/packages/flutter_driver/pubspec.yaml
index ca332ed..c2640f3 100644
--- a/packages/flutter_driver/pubspec.yaml
+++ b/packages/flutter_driver/pubspec.yaml
@@ -26,7 +26,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -35,7 +35,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/packages/flutter_localizations/pubspec.yaml b/packages/flutter_localizations/pubspec.yaml
index 897e984..2b66dd7 100644
--- a/packages/flutter_localizations/pubspec.yaml
+++ b/packages/flutter_localizations/pubspec.yaml
@@ -14,7 +14,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -23,7 +23,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http: 0.11.3+14 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
diff --git a/packages/flutter_test/pubspec.yaml b/packages/flutter_test/pubspec.yaml
index 7ac123b..79ba19e 100644
--- a/packages/flutter_test/pubspec.yaml
+++ b/packages/flutter_test/pubspec.yaml
@@ -27,7 +27,7 @@
 
   args: 0.13.7 # TRANSITIVE DEPENDENCY
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   cli_util: 0.1.2+1 # TRANSITIVE DEPENDENCY
@@ -36,7 +36,7 @@
   crypto: 2.0.2+1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
   io: 0.3.1 # TRANSITIVE DEPENDENCY
diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml
index b02c028..94b6a54 100644
--- a/packages/flutter_tools/pubspec.yaml
+++ b/packages/flutter_tools/pubspec.yaml
@@ -48,13 +48,13 @@
   mockito: 2.2.1
 
   async: 1.13.3 # TRANSITIVE DEPENDENCY
-  barback: 0.15.2+13 # TRANSITIVE DEPENDENCY
+  barback: 0.15.2+14 # TRANSITIVE DEPENDENCY
   boolean_selector: 1.0.2 # TRANSITIVE DEPENDENCY
   charcode: 1.1.1 # TRANSITIVE DEPENDENCY
   convert: 2.0.1 # TRANSITIVE DEPENDENCY
   csslib: 0.14.1 # TRANSITIVE DEPENDENCY
   glob: 1.1.5 # TRANSITIVE DEPENDENCY
-  html: 0.13.2+1 # TRANSITIVE DEPENDENCY
+  html: 0.13.2+2 # TRANSITIVE DEPENDENCY
   http_multi_server: 2.0.4 # TRANSITIVE DEPENDENCY
   http_parser: 3.1.1 # TRANSITIVE DEPENDENCY
   io: 0.3.1 # TRANSITIVE DEPENDENCY