/**
   * Record the test results into the current build.
   *
   * @param junitFilePattern
   * @param build
   * @param listener
   * @return
   * @throws InterruptedException
   * @throws IOException
   */
  private boolean recordTestResult(
      String junitFilePattern, AbstractBuild<?, ?> build, BuildListener listener)
      throws InterruptedException, IOException {
    TestResultAction existingAction = build.getAction(TestResultAction.class);
    TestResultAction action;

    try {
      final long buildTime = build.getTimestamp().getTimeInMillis();

      TestResult existingTestResults = null;
      if (existingAction != null) {
        existingTestResults = existingAction.getResult();
      }
      TestResult result = getTestResult(junitFilePattern, build, existingTestResults, buildTime);

      if (existingAction == null) {
        action = new TestResultAction(build, result, listener);
      } else {
        action = existingAction;
        action.setResult(result, listener);
      }
      if (result.getPassCount() == 0 && result.getFailCount() == 0)
        new AbortException("None of the test reports contained any result");
    } catch (AbortException e) {
      if (build.getResult() == Result.FAILURE)
        // most likely a build failed before it gets to the test phase.
        // don't report confusing error message.
        return true;

      listener.getLogger().println(e.getMessage());
      build.setResult(Result.FAILURE);
      return true;
    }

    if (existingAction == null) {
      build.getActions().add(action);
    }

    if (action.getResult().getFailCount() > 0) build.setResult(Result.UNSTABLE);

    return true;
  }