 						dispatch_group_leave(group)
 					}
 
-					task.launch()
+					rawTask.launch()
 					close(stdoutPipe.writeFD)
 					close(stderrPipe.writeFD)
 
-					observer.sendNext(.Launch(taskDescription))
+					observer.sendNext(.Launch(task))
 
 					stdinProducer.startWithSignal { signal, signalDisposable in
 						disposable += signalDisposable
 					}
 
 					disposable.addDisposable {
-						task.terminate()
+						rawTask.terminate()
 					}
 				}
 			}

/// Launches a new shell task.
///
/// - Parameters:
///   - taskDescription: The task to launch.
///   - standardInput:   Data to stream to standard input of the launched process. If nil, stdin will
///                      be inherited from the parent process.
///
/// - Returns: A producer that will launch the task when started, then send
/// `TaskEvent`s as execution proceeds.
public func launchTask(taskDescription: Task, standardInput: SignalProducer<NSData, NoError>? = nil) -> SignalProducer<TaskEvent<NSData>, TaskError> {
	return SignalProducer { observer, disposable in
		let queue = dispatch_queue_create(taskDescription.description, DISPATCH_QUEUE_SERIAL)
		let group = Task.group

		let task = NSTask()
		task.launchPath = taskDescription.launchPath
		task.arguments = taskDescription.arguments

		if let cwd = taskDescription.workingDirectoryPath {
			task.currentDirectoryPath = cwd
		}

		if let env = taskDescription.environment {
			task.environment = env
		}

		var stdinProducer: SignalProducer<(), TaskError> = .empty

		if let input = standardInput {
			switch Pipe.create(queue, group) {
			case let .Success(pipe):
				rawTask.standardInput = pipe.readHandle

				stdinProducer = pipe.writeDataFromProducer(input).on(started: {
					close(pipe.readFD)
