anchor.diff:    String get exampleAndroidPath => path.join(examplePath, 'android');
     String get debugApkPath => path.join(examplePath, 'build', 'app', 'outputs', 'apk', 'debug', 'app-debug.apk');
   
  -  Future<Null> runGradleTask(String task) async {
  -    return _runGradleTask(workingDirectory: exampleAndroidPath, task: task);
  +  Future<Null> runGradleTask(String task, {List<String> options}) async {
  +    return _runGradleTask(workingDirectory: exampleAndroidPath, task: task, options: options);
     }
   
     bool get hasDebugApk => new File(debugApkPath).existsSync();
   }
   
  -Future<Null> _runGradleTask({String workingDirectory, String task}) async {
  -  final ProcessResult result = await _resultOfGradleTask(workingDirectory: workingDirectory, task: task);
  +Future<Null> _runGradleTask({String workingDirectory, String task, List<String> options}) async {
  +  final ProcessResult result = await _resultOfGradleTask(
  +      workingDirectory: workingDirectory,
  +      task: task,
  +      options: options);
     if (result.exitCode != 0) {
       print('stdout:');
       print(result.stdout);
  
positive.code:     await buildScript.writeAsString((await buildScript.readAsString()).replaceAll('buildTypes', 'builTypes'));
    }
  
    Future<Null> runGradleTask(String task) async {
      return _runGradleTask(workingDirectory: androidPath, task: task);
    }
  
    Future<ProcessResult> resultOfGradleTask(String task) {
      return _resultOfGradleTask(workingDirectory: androidPath, task: task);
    }
  
    Future<ProcessResult> resultOfFlutterCommand(String command, List<String> options) {
  
negative.code:     throw 'Gradle exited with error';
  }
  
  Future<ProcessResult> _resultOfGradleTask({String workingDirectory, String task,
      List<String> options}) {
    final List<String> args = <String>['app:$task'];
    if (options != null) {
      args.addAll(options);
    }
    return Process.run(
      './gradlew',
      args,
      workingDirectory: workingDirectory,
      environment: <String, String>{ 'JAVA_HOME': javaHome }
    );
  }
  
  class _Dependencies {
    String target;
    Set<String> dependencies;
    _Dependencies(String depfilePath) {
      final RegExp _separatorExpr = new RegExp(r'([^\\]) ');
      final RegExp _escapeExpr = new RegExp(r'\\(.)');
  
      // Depfile format:
      // outfile1 outfile2 : file1.dart file2.dart file3.dart file\ 4.dart
      final String contents = new File(depfilePath).readAsStringSync();
      final List<String> colonSeparated = contents.split(': ');
      target = colonSeparated[0].trim();
      dependencies = colonSeparated[1]
          // Put every file on right-hand side on the separate line
          .replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
          .split('\n')
          // Expand escape sequences, so that '\ ', for example,ß becomes ' '
          .map((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim())
          .where((String path) => path.isNotEmpty)
          .toSet();
    }
  }
  
  /// Returns [null] if target matches [expectedTarget], otherwise returns an error message.
  String _validateSnapshotDependency(FlutterProject project, String expectedTarget) {
    final _Dependencies deps = new _Dependencies(
        path.join(project.rootPath, 'build', 'app', 'intermediates',
            'flutter', 'debug', 'snapshot_blob.bin.d'));
    return deps.target == expectedTarget ? null :
      'Dependency file should have $expectedTarget as target. Instead has ${deps.target}';
  }
  