anchor.diff:    Directory distDir = new Directory('dist');
     distDir.createSync();
   
  +  // Create a build/chrome-app/spark directory to prepare the content of the
  +  // Chrome App.
  +  copyDirectory(
  +      joinDir(Directory.current, ['build', 'polymer-build', 'web']),
  +      joinDir(Directory.current, ['build', 'chrome-app', 'spark']));
  +  runCommandSync(
  +      context,
  +      'find build/chrome-app/spark -name "packages" -print0 | xargs -0 rm -rf');
  +  copyDirectory(
  +      joinDir(Directory.current, ['build', 'polymer-build', 'web', 'packages']),
  +      joinDir(Directory.current, ['build', 'chrome-app', 'spark', 'packages']));
  +  runCommandSync(context, 'rm -rf build/chrome-app/spark/test');
  +  runCommandSync(context, 'rm -rf build/chrome-app/spark/spark_test.dart');
  +
     // zip spark.zip . -r -q -x .*
  -  runProcess(context,
  -      'zip', arguments: ['../dist/spark.zip', '.', '-r', '-q', '-x', '.*'],
  -      workingDirectory: 'app');
  +  Directory.current = 'build/chrome-app/spark';
  +  runCommandSync(context, 'zip ../../../dist/spark.zip . -qr -x .*');
  +  Directory.current = '../../..';
     int sizeKb = new File('dist/spark.zip').lengthSync() ~/ 1024;
     context.log('spark.zip is ${sizeKb}kb');
   }
  +
  +String getBranchName() {
  +  return getCommandOutput('git branch | grep "*" | sed -e "s/\* //g"');
  +}
  +
  +String getRepositoryUrl() {
  +  return getCommandOutput('git config remote.origin.url');
  +}
  +
  +String getCurrentRevision() {
  +  return getCommandOutput('git rev-parse HEAD | cut -c1-10');
  +}
  +
  +bool canReleaseFromHere() {
  +  return (getRepositoryUrl() == 'https://github.com/dart-lang/spark.git') &&
  +         (getBranchName() == 'master');
  +}
  +
  +void archiveWithRevision(GrinderContext context) {
  +  context.log('Performing archive instead.');
  +  archive(context);
  +  File file = new File('dist/spark.zip');
  +  String version = getCurrentRevision();
  +  String filename = 'spark-rev-${version}.zip';
  +  file.rename('dist/${filename}');
  +  context.log("Created {filename}");
  +}
  +
  +Future<String> increaseBuildNumber(GrinderContext context) {
  +  // Tweaking build version in manifest.
  +  File file = new File('app/manifest.json');
  +  Future<String> finishedReading = file.readAsString();
  +  return finishedReading.then((String content) {
  +    Object manifestDict = JSON.decode(content);
  +    String version = manifestDict['version'];
  +    RegExp exp = new RegExp(r"(\d+\.\d+)\.(\d+)");
  +    Iterable<Match> matches = exp.allMatches(version);
  +    assert(matches.length > 0);
  +
  +    Match m = matches.first;
  +    String majorVersion = m.group(1);
  +    int buildVersion = int.parse(m.group(2));
  +    buildVersion ++;
  +
  +    version = '${majorVersion}.${buildVersion}';
  +    manifestDict['version'] = version;
  +    Future<File> finishedWriting =
  +        file.writeAsString(JSON.encode(manifestDict));
  +    finishedWriting.then((File writtenFile) {
  +      // Creating an archive of the Chrome App.
  +      context.log('Creating build ${version}');
  +
  +      // It needs to be copied to compile result directory.
  +      copyFile(
  +          joinFile(Directory.current, ['app', 'manifest.json']),
  +          joinDir(Directory.current, ['build', 'polymer-build', 'web']));
  +    });
  +    return version;
  +  });
  +}
  +
  +Future release(GrinderContext context) {
  +  // If repository is not original repository of Spark and the branch is not 
  +  if (!canReleaseFromHere()) {
  +    archiveWithRevision(context);
  +    return;
  +  }
  +
  +  increaseBuildNumber(context).then((String version) {
  +    // Creating an archive of the Chrome App.
  +    context.log('Creating build ${version}');
  +
  +    // It needs to be copied to compile result directory.
  +    copyFile(
  +        joinFile(Directory.current, ['app', 'manifest.json']),
  +        joinDir(Directory.current, ['build', 'polymer-build', 'web']));
  +
  +    archive(context);
  +
  +    runCommandSync(
  +        context,
  +        'git commit -m "Build version ${version}" app/manifest.json');
  +    File file = new File('dist/spark.zip');
  +    String filename = 'spark-${version}.zip';
  +    file.rename('dist/${filename}').then((File file) {
  +      context.log('Created ${filename}');
  +      context.log('** A commit has been created, you need to push it. ***');
  +    });
  +    
  +    return filename;
  +  });
  +}
  
positive.code: 
  void dart2JSBuild(GrinderContext context) {
    // We remove the symlink and replace it with a copy.
    Process.runSync('rm', ['-rf', 'web/packages']);
    copyDirectory(
        joinDir(Directory.current, ['packages']),
        joinDir(Directory.current, ['web', 'packages']));
  
negative.code: }
  
  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);
  