 }
 
 
-private final class ConcatState<Value, Error: ErrorType> {
-	/// The observer of a started `concat` producer.
-	let observer: Signal<Value, Error>.Observer
-
-	/// The top level disposable of a started `concat` producer.
-	let disposable: CompositeDisposable?
-
-	/// The active producer, if any, and the producers waiting to be started.
-	let queuedSignalProducers: Atomic<[SignalProducer<Value, Error>]> = Atomic([])
-
-	init(observer: Signal<Value, Error>.Observer, disposable: CompositeDisposable?) {
-		self.observer = observer
-		self.disposable = disposable
-	}
-
-	func enqueueSignalProducer(producer: SignalProducer<Value, Error>) {
-		if let d = disposable where d.disposed {
-			return
-		}
-
-		var shouldStart = true
-
-		queuedSignalProducers.modify { (var queue) in
-			// An empty queue means the concat is idle, ready & waiting to start
-			// the next producer.
-			shouldStart = queue.isEmpty
-			queue.append(producer)
-			return queue
-		}
-
-		if shouldStart {
-			startNextSignalProducer(producer)
-		}
-	}
-
-	func dequeueSignalProducer() -> SignalProducer<Value, Error>? {
-		if let d = disposable where d.disposed {
-			return nil
-		}
-
-		var nextSignalProducer: SignalProducer<Value, Error>?
-
-		queuedSignalProducers.modify { (var queue) in
-			// Active producers remain in the queue until completed. Since
-			// dequeueing happens at completion of the active producer, the
-			// first producer in the queue can be removed.
-			if !queue.isEmpty { queue.removeAtIndex(0) }
-			nextSignalProducer = queue.first
-			return queue
-		}
-
-		return nextSignalProducer
-	}
-
-	/// Subscribes to the given signal producer.
-	func startNextSignalProducer(signalProducer: SignalProducer<Value, Error>) {
-		signalProducer.startWithSignal { signal, disposable in
-			let handle = self.disposable?.addDisposable(disposable) ?? nil
-
-			signal.observe { event in
-				switch event {
-				case .Completed, .Interrupted:
-					handle?.remove()
-
-					if let nextSignalProducer = self.dequeueSignalProducer() {
-						self.startNextSignalProducer(nextSignalProducer)
-					}
-
-				default:
-					self.observer.action(event)
-				}
-			}
-		}
-	}
-}
-
 private struct LatestState<Value, Error: ErrorType> {
 	var outerSignalComplete: Bool = false
 	var innerSignalComplete: Bool = true
 	
 	var replacingInnerSignal: Bool = false
 }
+
+
+extension SignalType {
+	/// Maps each event from `signal` to a new producer, then flattens the
+	/// resulting producers (into a signal of values), according to the
+	/// semantics of the given strategy.
+	///
+	/// If `signal` or any of the created producers fail, the returned signal
+	/// will forward that failure immediately.
+	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
+	public func flatMap<U>(strategy: FlattenStrategy, transform: Value -> SignalProducer<U, Error>) -> Signal<U, Error> {
+		return map(transform).flatten(strategy)
+	}
+
+	/// Maps each event from `signal` to a new signal, then flattens the
+	/// resulting signals (into a signal of values), according to the
+	/// semantics of the given strategy.
+	///
+	/// If `signal` or any of the created signals emit an error, the returned
+	/// signal will forward that error immediately.
+	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
+	public func flatMap<U>(strategy: FlattenStrategy, transform: Value -> Signal<U, Error>) -> Signal<U, Error> {
+		return map(transform).flatten(strategy)
+	}
+}
+
+extension SignalProducerType {
+	/// Maps each event from `self` to a new producer, then flattens the
+	/// resulting producers (into a producer of values), according to the
+	/// semantics of the given strategy.
+	///
+	/// If `self` or any of the created producers fail, the returned producer
+	/// will forward that failure immediately.
+	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
+	public func flatMap<U>(strategy: FlattenStrategy, transform: Value -> SignalProducer<U, Error>) -> SignalProducer<U, Error> {
+		return map(transform).flatten(strategy)
+	}
+
+	/// Maps each event from `self` to a new producer, then flattens the
+	/// resulting producers (into a producer of values), according to the
+	/// semantics of the given strategy.
+	///
+	/// If `self` or any of the created signals emit an error, the returned
+	/// producer will forward that error immediately.
+	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
+	public func flatMap<U>(strategy: FlattenStrategy, transform: Value -> Signal<U, Error>) -> SignalProducer<U, Error> {
+		return map(transform).flatten(strategy)
+	}
+}
+
+
+extension SignalType {
+	/// Catches any failure that may occur on the input signal, mapping to a new producer
+	/// that starts in its place.
+	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
+	public func flatMapError<F>(handler: Error -> SignalProducer<Value, F>) -> Signal<Value, F> {
+		return Signal { observer in
+			self.observe { event in
+				switch event {
+				case let .Next(value):
+					observer.sendNext(value)
+				case let .Failed(error):
+					handler(error).startWithSignal { signal, _ in
+						signal.observe(observer)
+					}
+				case .Completed:
+					observer.sendCompleted()
+				case .Interrupted:
+					observer.sendInterrupted()
+				}
+			}
+		}
+	}
+}
+
+extension SignalProducerType {
+	/// Catches any failure that may occur on the input producer, mapping to a new producer
+	/// that starts in its place.
+	@warn_unused_result(message="Did you forget to call `start` on the producer?")
+	public func flatMapError<F>(handler: Error -> SignalProducer<Value, F>) -> SignalProducer<Value, F> {
+		return SignalProducer { observer, disposable in
+			let serialDisposable = SerialDisposable()
+			disposable.addDisposable(serialDisposable)
+
+			self.startWithSignal { signal, signalDisposable in
+				serialDisposable.innerDisposable = signalDisposable
+
+				signal.observe { event in
+					switch event {
+					case let .Next(value):
+						observer.sendNext(value)
+					case let .Failed(error):
+						handler(error).startWithSignal { signal, signalDisposable in
+							serialDisposable.innerDisposable = signalDisposable
+							signal.observe(observer)
+						}
+					case .Completed:
+						observer.sendCompleted()
+					case .Interrupted:
+						observer.sendInterrupted()
+					}
+				}
+			}
+		}
+	}
+}

	}
}

extension SignalType {
	/// Maps each event from `signal` to a new producer, then flattens the
	/// resulting producers (into a signal of values), according to the
	/// semantics of the given strategy.
	///
	/// If `signal` or any of the created producers fail, the returned signal
	/// will forward that failure immediately.
	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
	public func flatMap<U>(strategy: FlattenStrategy, transform: Value -> SignalProducer<U, Error>) -> Signal<U, Error> {
		return map(transform).flatten(strategy)
	}

	/// Maps each event from `signal` to a new signal, then flattens the
	/// resulting signals (into a signal of values), according to the
	/// semantics of the given strategy.
	///
	/// If `signal` or any of the created signals emit an error, the returned
	/// signal will forward that error immediately.
	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
	public func flatMap<U>(strategy: FlattenStrategy, transform: Value -> Signal<U, Error>) -> Signal<U, Error> {
		return map(transform).flatten(strategy)
	}

	/// Merges the given signals into a single `Signal` that will emit all values
	/// from each of them, and complete when all of them have completed.
	public static func merge<S: SequenceType where S.Generator.Element == Signal<Value, Error>>(signals: S) -> Signal<Value, Error> {
		let producer = SignalProducer<Signal<Value, Error>, Error>(values: signals)
		var result: Signal<Value, Error>!

		producer.startWithSignal { (signal, _) in
			result = signal.flatten(.Merge)
		}

		return result
	}

	/// Catches any failure that may occur on the input signal, mapping to a new producer
	/// that starts in its place.
	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
	public func flatMapError<F>(handler: Error -> SignalProducer<Value, F>) -> Signal<Value, F> {
		return Signal { observer in
			self.observe { event in
				switch event {
				case let .Next(value):
					observer.sendNext(value)
				case let .Failed(error):
					handler(error).startWithSignal { signal, _ in
						signal.observe(observer)
					}
				case .Completed:
					observer.sendCompleted()
				case .Interrupted:
					observer.sendInterrupted()
				}
			}
		}
	}
}

extension SignalType where Value: SignalProducerType, Error == Value.Error {
	/// Returns a signal which sends all the values from producer signal emitted from

			}
		}
	}
}

extension SignalProducerType where Value: SignalProducerType, Error == Value.Error {
	/// Returns a producer which sends all the values from each producer emitted from
	/// `producer`, waiting until each inner producer completes before beginning to
	/// send the values from the next inner producer.
	///
	/// If any of the inner producers emit an error, the returned producer will emit
	/// that error.
	///
	/// The returned producer completes only when `producer` and all producers
	/// emitted from `producer` complete.
	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
	private func concat() -> SignalProducer<Value.Value, Error> {
		return SignalProducer<Value.Value, Error> { observer, disposable in
			let state = ConcatState(observer: observer, disposable: disposable)

			self.startWithSignal { signal, signalDisposable in
				disposable += signalDisposable

				signal.observe { event in
					switch event {
					case let .Next(value):
						state.enqueueSignalProducer(value.producer)

					case let .Failed(error):
						observer.sendFailed(error)

					case .Completed:
						// Add one last producer to the queue, whose sole job is to
						// "turn out the lights" by completing `observer`.
						state.enqueueSignalProducer(SignalProducer.empty.on(completed: {
							observer.sendCompleted()
						}))

					case .Interrupted:
						observer.sendInterrupted()
					}
				}
			}
		}
	}
}

extension SignalProducerType {
	/// `concat`s `next` onto `self`.
	@warn_unused_result(message="Did you forget to call `start` on the producer?")
	public func concat(next: SignalProducer<Value, Error>) -> SignalProducer<Value, Error> {
		return SignalProducer<SignalProducer<Value, Error>, Error>(values: [self.producer, next]).flatten(.Concat)
	}
}

private final class ConcatState<Value, Error: ErrorType> {
	/// The observer of a started `concat` producer.
	let observer: Signal<Value, Error>.Observer

	/// The top level disposable of a started `concat` producer.
	let disposable: CompositeDisposable?

	/// The active producer, if any, and the producers waiting to be started.
	let queuedSignalProducers: Atomic<[SignalProducer<Value, Error>]> = Atomic([])

	init(observer: Signal<Value, Error>.Observer, disposable: CompositeDisposable?) {
		self.observer = observer
		self.disposable = disposable
	}

	func enqueueSignalProducer(producer: SignalProducer<Value, Error>) {
		if let d = disposable where d.disposed {
			return
		}

		var shouldStart = true

		queuedSignalProducers.modify { (var queue) in
			// An empty queue means the concat is idle, ready & waiting to start
			// the next producer.
			shouldStart = queue.isEmpty
			queue.append(producer)
			return queue
		}

		if shouldStart {
			startNextSignalProducer(producer)
		}
	}

	func dequeueSignalProducer() -> SignalProducer<Value, Error>? {
		if let d = disposable where d.disposed {
			return nil
		}

		var nextSignalProducer: SignalProducer<Value, Error>?

		queuedSignalProducers.modify { (var queue) in
			// Active producers remain in the queue until completed. Since
			// dequeueing happens at completion of the active producer, the
			// first producer in the queue can be removed.
			if !queue.isEmpty { queue.removeAtIndex(0) }
			nextSignalProducer = queue.first
			return queue
		}

		return nextSignalProducer
	}

	/// Subscribes to the given signal producer.
	func startNextSignalProducer(signalProducer: SignalProducer<Value, Error>) {
		signalProducer.startWithSignal { signal, disposable in
			let handle = self.disposable?.addDisposable(disposable) ?? nil

			signal.observe { event in
				switch event {
				case .Completed, .Interrupted:
					handle?.remove()

					if let nextSignalProducer = self.dequeueSignalProducer() {
						self.startNextSignalProducer(nextSignalProducer)
					}

				default:
					self.observer.action(event)
				}
			}
		}
	}
}

extension SignalType where Value: SignalProducerType, Error == Value.Error {
	/// Merges a `signal` of SignalProducers down into a single signal, biased toward the producer
	/// added earlier. Returns a Signal that will forward events from the inner producers as they arrive.
	@warn_unused_result(message="Did you forget to call `start` on the producer?")
