 	}
 }
 
-private struct ZipState<Value> {
-	var values: [Value] = []
-	var completed = false
+private struct ZipState<Left, Right> {
+	var values: (left: [Left], right: [Right]) = ([], [])
+	var completed: (left: Bool, right: Bool) = (false, false)
 
 	var isFinished: Bool {
-		return completed && values.isEmpty
+		return (completed.left && values.left.isEmpty) || (completed.right && values.right.isEmpty)
 	}
 }
 

			disposable += otherSignal.observe { event in
				switch event {
				case let .Next(value):
					states.modify { states in
						var states = states
						states.1.values.append(value)
						return states
					}
					
					flush()
				case let .Failed(error):
					onFailed(error)
				case .Completed:
					states.modify { states in
						var states = states
						states.1.completed = true
						return states
					}
					
					flush()

	@warn_unused_result(message="Did you forget to call `observe` on the signal?")
	public func zipWith<U>(otherSignal: Signal<U, Error>) -> Signal<(Value, U), Error> {
		return Signal { observer in
			let state = Atomic(ZipState<Value, U>())
			let disposable = CompositeDisposable()
			
			let flush = {
				var tuple: (Value, U)?
				var isFinished = false
				state.modify { state in
					var state = state
					guard !state.values.left.isEmpty && !state.values.right.isEmpty else {
						return state
					}

					tuple = (state.values.left.removeFirst(), state.values.right.removeFirst())
					isFinished = state.isFinished

					return state
				}

				if let tuple = tuple {
