@Override
  public BuildResult call() throws Exception {
   
    // set the name of this thread to the package
    // name for debugging
    Thread.currentThread().setName(pkg.getName());
    
    // write the POM to the base dir
    pkg.writePom();
    
    BuildResult result = new BuildResult();
    result.setPackageName(pkg.getName());

    List<String> command = Lists.newArrayList();
    command.add(getMavenPath());
    if(updateSnapshots) {
    //  command.add("-U");
    }
    // hot fix for tests that exceed memory
    if(pkg.getName().equals("MASS")) {
      command.add("-DskipTests");
    } else {
      command.add("-Dmaven.test.failure.ignore=true");
    }
    command.add("-DenvClassifier=linux-x86_64");
    command.add("-Dignore.gnur.compilation.failure=true");
    command.add("clean");
    command.add("deploy");

    ProcessBuilder builder = new ProcessBuilder(command);
    
    builder.directory(pkg.getBaseDir());
    builder.redirectErrorStream(true);
    try {
      long startTime = System.currentTimeMillis();
      Process process = builder.start();

      InputStream processOutput = process.getInputStream();
      OutputCollector collector = new OutputCollector(processOutput, logFile);
      collector.setName(pkg + " - output collector");
      collector.start();

      try {
        ProcessMonitor monitor = new ProcessMonitor(process);
        monitor.setName(pkg + " - monitor");
        monitor.start();

        while(!monitor.isFinished()) {

          if(System.currentTimeMillis() > (startTime + TIMEOUT_SECONDS * 1000)) {
            System.out.println(pkg + " build timed out after " + TIMEOUT_SECONDS + " seconds.");
            process.destroy();
            result.setOutcome(BuildOutcome.TIMEOUT);
            break;
          }
          Thread.sleep(1000);
        }

        collector.join();
        if(result.getOutcome() != BuildOutcome.TIMEOUT) {
          if(monitor.getExitCode() == 0) {
            result.setOutcome(BuildOutcome.SUCCESS);
          } else if(monitor.getExitCode() == 1) {
            result.setOutcome(BuildOutcome.FAILED);
          } else {
            System.out.println(pkg.getName() + " exited with code " + monitor.getExitCode());
            result.setOutcome(BuildOutcome.ERROR);
          }
        }
      } finally {
        Closeables.closeQuietly(processOutput);
      }
      
    } catch (Exception e) {
      result.setOutcome(BuildOutcome.ERROR);
      e.printStackTrace();
    }
    return result; 
  }