/**
  * Fired when a task finishes building, this adds the time taken and any error stacktrace to the
  * appropriate task element in the log.
  *
  * @param event An event with any relevant extra information. Will not be <code>null</code>.
  */
 public void taskFinished(BuildEvent event) {
   Task task = event.getTask();
   TimedElement taskElement = (TimedElement) tasks.get(task);
   if (taskElement != null) {
     long totalTime = System.currentTimeMillis() - taskElement.startTime;
     // taskElement.element.setAttribute(TIME_ATTR,
     // DefaultLogger.formatTime(totalTime));
     Target target = task.getOwningTarget();
     TimedElement targetElement = null;
     if (target != null) {
       targetElement = (TimedElement) targets.get(target);
     }
     if (targetElement == null) {
       buildElement.element.appendChild(taskElement.element);
     } else {
       targetElement.element.appendChild(taskElement.element);
     }
     Stack threadStack = getStack();
     if (!threadStack.empty()) {
       TimedElement poppedStack = (TimedElement) threadStack.pop();
       if (poppedStack != taskElement) {
         throw new RuntimeException(
             "Mismatch - popped element = "
                 + poppedStack
                 + " finished task element = "
                 + taskElement);
       }
     }
     tasks.remove(task);
   } else {
     throw new RuntimeException("Unknown task " + task + " not in " + tasks);
   }
 }