 }
 
 extension NSURLSession {
-	/// Returns a signal that will download a file using the given request. The
-	/// file will be deleted after the URL has been sent upon the signal.
-	internal func carthage_downloadWithRequest(request: NSURLRequest) -> ColdSignal<(NSURL, NSURLResponse)> {
-		return ColdSignal { (sink, disposable) in
+	/// Returns a producer that will download a file using the given request. The
+	/// file will be deleted after the producer terminates.
+	internal func carthage_downloadWithRequest(request: NSURLRequest) -> SignalProducer<(NSURL, NSURLResponse), NSError> {
+		return SignalProducer { observer, disposable in
 			let serialDisposable = SerialDisposable()
 			let handle = disposable.addDisposable(serialDisposable)
 

	return result
}

extension ColdSignal {
	/// Sends each value that occurs on the receiver combined with each value
	/// that occurs on the given signal (repeats included).
	internal func permuteWith<U>(signal: ColdSignal<U>) -> ColdSignal<(T, U)> {
		return ColdSignal<(T, U)> { (sink, disposable) in
			var selfValues: [T] = []
			var selfCompleted = false
			var otherValues: [U] = []
			var otherCompleted = false

			self.startWithSink { selfDisposable in
				disposable.addDisposable(selfDisposable)

				return Event.sink(next: { value in
					selfValues.append(value)

					for otherValue in otherValues {
						sink.put(.Next(Box((value, otherValue))))
					}
				}, error: { error in
					sink.put(.Error(error))
				}, completed: {
					selfCompleted = true
					if otherCompleted {
						sink.put(.Completed)
					}
				})
			}

			signal.startWithSink { signalDisposable in
				disposable.addDisposable(signalDisposable)

				return Event.sink(next: { value in
					otherValues.append(value)

					for selfValue in selfValues {
						sink.put(.Next(Box((selfValue, value))))
					}
				}, error: { error in
					sink.put(.Error(error))
				}, completed: {
					otherCompleted = true
					if selfCompleted {
						sink.put(.Completed)
					}
				})
			}
		}
	}

	/// Dematerializes the signal, like dematerialize(), but only yields Error
	/// events if no values were sent.
	internal func dematerializeErrorsIfEmpty<U>(evidence: ColdSignal -> ColdSignal<Event<U>>) -> ColdSignal<U> {
		return ColdSignal<U> { (sink, disposable) in
			var receivedValue = false
			var receivedError: NSError? = nil

			evidence(self).startWithSink { selfDisposable in
				disposable.addDisposable(selfDisposable)

				return Event.sink(next: { event in
					switch event {
					case let .Next(value):
						receivedValue = true
						fallthrough

					case .Completed:
						sink.put(event)

					case let .Error(error):
						receivedError = error
					}
				}, error: { error in
					sink.put(.Error(error))
				}, completed: {
					if !receivedValue {
						if let receivedError = receivedError {
							sink.put(.Error(receivedError))
						}
					}

					sink.put(.Completed)
				})
			}
		}
	}
}

/// Sends all permutations of the values from the input signals, as they arrive.
///
/// If no input signals are given, sends a single empty array then completes.
internal func permutations<T>(signals: [ColdSignal<T>]) -> ColdSignal<[T]> {
	var combined: ColdSignal<[T]> = .single([])

	for signal in signals {
		combined = combined.permuteWith(signal).map { (var array, value) in
			array.append(value)
			return array
		}
	}

	return combined

				handle.remove()

				if URL == nil || response == nil {
					sendError(observer, error)
				} else {
					let value = (URL!, response!)
					sendNext(observer, value)
					sendCompleted(observer)
				}
			}

