anchor.diff:    runCommandSync(context, 'rm -rf build/chrome-app/spark/spark_test.dart');
   
     // zip spark.zip . -r -q -x .*
  -  Directory.current = 'build/chrome-app/spark';
  -  runCommandSync(context, 'zip ../../../dist/spark.zip . -qr -x .*');
  -  Directory.current = '../../..';
  +  runCommandSync(context, 'zip ../../../dist/spark.zip . -qr -x .*',
  +      cwd: 'build/chrome-app/spark');
     printSize(context, new File('dist/spark.zip'));
   }
   
  
positive.code: 
  // It will output a file web/spark.html_bootstrap.dart and a spark.html
  // without HTML imports.
  Future<bool> asyncPolymerBuild(GrinderContext context,
                                 String entryPoint,
                                 String outputDir) {
    var args = ['--out', outputDir, '--deploy'];
    var options = polymer.parseOptions(args);
    return polymer.build(entryPoints: [entryPoint], options: options).then((_) {
      context.log("polymer build done");
      return true;
    });
  }
  
  // Transpile dart sources to JS.
  // It will create spark.html_bootstrap.dart.precompiled.js.
  void dart2JSBuild(GrinderContext context) {
    // We remove the symlink and replace it with a copy.
    runCommandSync(context, 'rm -rf web/packages');
    copyDirectory(
        joinDir(Directory.current, ['packages']),
        joinDir(Directory.current, ['web', 'packages']));
  
    // We tell dart2js to compile to spark.dart.js; it also outputs a CSP
    // version (spark.dart.precompiled.js), which is what we actually use.
    runProcess(context, 'dart2js', arguments: [
        'web/spark.html_bootstrap.dart',
        '--out=web/spark.html_bootstrap.dart.js']);
  
    // Support for old version of dart2js: they generate precompiled.js file.
    if (new File('web/precompiled.js').existsSync()) {
      new File('web/precompiled.js').renameSync(
          'web/spark.html_bootstrap.dart.precompiled.js');
    }
  
    printSize(context,  new File('web/spark.html_bootstrap.dart.precompiled.js'));
  }
  
  Future compile(GrinderContext context) {
    prepareBuild(context);
  
    Directory.current = 'build';
    return Future.wait([asyncPolymerBuild(context, 'web/spark.html',
                                          'polymer-build').then((bool success) {
      Directory.current = 'polymer-build';
      dart2JSBuild(context);
      context.log('result has been written to build/polymer-build/web/');
      Directory.current = '../..';
    })]);
  }
  
  void analyze(GrinderContext context) {
  
negative.code: void clean(GrinderContext context) {
    // delete the sdk directory
    runCommandSync(context, 'rm -rf app/sdk/lib');
    runCommandSync(context, 'rm -f app/sdk/version');
  
    // delete any compiled js output
    runCommandSync(context, 'rm -f app/*.dart.js');
    runCommandSync(context, 'rm -f app/*.dart.precompiled.js');
    runCommandSync(context, 'rm -f app/*.js.map');
    runCommandSync(context, 'rm -f app/*.js.deps');
  
    // TODO: delete the build/ dir?
  
  