anchor.diff:    context.log('spark.zip is ${sizeKb}kb');
   }
   
  +// Returns the name of the current branch.
   String getBranchName() {
     return getCommandOutput('git branch | grep "*" | sed -e "s/\* //g"');
   }
   
  +// Returns the URL of the git repository.
   String getRepositoryUrl() {
     return getCommandOutput('git config remote.origin.url');
   }
   
  +// Returns the current revision identifier of the local copy.
   String getCurrentRevision() {
     return getCommandOutput('git rev-parse HEAD | cut -c1-10');
   }
   
  +// We can build a real release only if the repository is the original
  +// repository of spark and master is the working branch since we need to
  +// increase the version and commit it to the repository.
   bool canReleaseFromHere() {
     return (getRepositoryUrl() == 'https://github.com/dart-lang/spark.git') &&
            (getBranchName() == 'master');
   }
   
  +// In case, release is performed on a non-releasable branch/repository, we just
  +// archive and name the archive with the revision identifier.
   void archiveWithRevision(GrinderContext context) {
     context.log('Performing archive instead.');
     archive(context);
  
positive.code:   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;
    });
  }
  
negative.code:       joinDir(Directory.current, ['app', 'packages']));
  }
  
  // Prepare the build folder.
  // It will copy all the required source files to build/.
  // It will prepare the directory layout to be compatible with polymer builder.
  void prepareBuild(GrinderContext context) {
    context.log('prepare build');
    // Copy files to build directory.
  