@Test
  public void stopsAtFirstActionWhichThrowsException() {
    final Throwable failure = new RuntimeException("failure");
    final Collector<Throwable> wrappedFailure = collector();
    context.checking(
        new Expectations() {
          {
            allowing(task).getTaskActions();
            will(returnValue(toList(action1, action2)));

            one(listener).beforeActions(task);
            inSequence(sequence);

            one(state).setExecuting(true);
            inSequence(sequence);

            one(state).setDidWork(true);
            inSequence(sequence);

            one(standardOutputCapture).start();
            inSequence(sequence);

            one(action1).contextualise(executionContext);
            inSequence(sequence);

            one(action1).execute(task);
            will(throwException(failure));
            inSequence(sequence);

            one(action1).contextualise(null);
            inSequence(sequence);

            one(standardOutputCapture).stop();
            inSequence(sequence);

            one(state).executed(with(notNullValue(Throwable.class)));
            will(collectTo(wrappedFailure));
            inSequence(sequence);

            one(state).setExecuting(false);
            inSequence(sequence);

            one(listener).afterActions(task);
            inSequence(sequence);
          }
        });

    executer.execute(task, state, executionContext);

    assertThat(wrappedFailure.get(), instanceOf(TaskExecutionException.class));
    TaskExecutionException exception = (TaskExecutionException) wrappedFailure.get();
    assertThat(exception.getTask(), equalTo((Task) task));
    assertThat(exception.getMessage(), equalTo("Execution failed for <task>."));
    assertThat(exception.getCause(), sameInstance(failure));
  }
  public Throwable transform(Throwable exception) {
    Throwable actualException = findDeepest(exception);
    if (actualException == null) {
      return exception;
    }
    if (actualException instanceof LocationAwareException) {
      return actualException;
    }

    ScriptSource source = null;
    Integer lineNumber = null;

    // todo - remove this special case
    if (actualException instanceof ScriptCompilationException) {
      ScriptCompilationException scriptCompilationException =
          (ScriptCompilationException) actualException;
      source = scriptCompilationException.getScriptSource();
      lineNumber = scriptCompilationException.getLineNumber();
    }

    if (source == null) {
      for (Throwable currentException = actualException;
          currentException != null;
          currentException = currentException.getCause()) {
        for (StackTraceElement element : currentException.getStackTrace()) {
          if (scripts.containsKey(element.getFileName())) {
            source = scripts.get(element.getFileName());
            lineNumber = element.getLineNumber() >= 0 ? element.getLineNumber() : null;
            break;
          }
        }
      }
    }

    if (source == null) {
      if (actualException instanceof TaskExecutionException) {
        TaskExecutionException taskExecutionException = (TaskExecutionException) actualException;
        source =
            ((ProjectInternal) taskExecutionException.getTask().getProject())
                .getBuildScriptSource();
      }
    }

    return generator.newInstance(actualException.getClass(), actualException, source, lineNumber);
  }