code: public void taskStatusUpdatedToFinalState() {
          // If any of the build tasks have failed or all are complete, then the build set is done
          if(buildTasks.stream().anyMatch(bt -> bt.getStatus().equals(BuildCoordinationStatus.CANCELLED))) {
              log.debug("Marking build set as CANCELLED as one or more tasks were cancelled. BuildSetTask: {}", this);
              if (log.isDebugEnabled()) {
                  logTasksStatus(buildTasks);
              }
              buildConfigSetRecord.ifPresent(r -> r.setStatus(BuildStatus.CANCELLED));
              finishBuildSetTask();
          } else if(buildTasks.stream().anyMatch(bt -> bt.getStatus().hasFailed())) {
              log.debug("Marking build set as FAILED as one or more tasks failed. BuildSetTask: {}", this);
              if (log.isDebugEnabled()) {
                  logTasksStatus(buildTasks);
              }
              buildConfigSetRecord.ifPresent(r -> r.setStatus(BuildStatus.FAILED));
              finishBuildSetTask();
          } else if (buildTasks.stream().allMatch(bt -> bt.getStatus().isCompleted())) {
              log.debug("Marking build set as SUCCESS. BuildSetTask: {}", this);
              buildConfigSetRecord.ifPresent(r -> r.setStatus(BuildStatus.SUCCESS));
              finishBuildSetTask();
          } else {
              if (log.isTraceEnabled()) {
                  List<Integer> running = buildTasks.stream()
                          .filter(bt -> !bt.getStatus().isCompleted())
                          .filter(bt -> !bt.getStatus().hasFailed())
                          .map(BuildTask::getId)
                          .collect(Collectors.toList());
                  log.trace("There are still running or waiting builds [{}].", running);
              }
          }
      }
docs: Notify the set that the state of one of it's tasks has changed.