 // MARK: concatMap
 
 extension ObservableMergeTest {
-    func testConcatMap_Complete_Complete() {
-        let scheduler = TestScheduler(initialClock: 0)
-        
-        let xs = scheduler.createColdObservable([
-            next(100, 4),
-            next(200, 3),
-            next(300, 2),
-            next(400, 1),
-            completed(500)
-            ])
-        
-        let ys = scheduler.createColdObservable([
-            next(50, "foo"),
-            next(100, "bar"),
-            next(150, "baz"),
-            next(200, "qux"),
-            completed(250)
-            ])
-        
-        let results = scheduler.start(disposed: 2000) {
-            return xs.concatMap { _ in
-                return ys.asObservable()
+
+    func testConcatMap_InnerCompleteFasterThanOuterElementsAreProduced() {
+        let scheduler = TestScheduler(initialClock: 0)
+
+        let ys1 = scheduler.createColdObservable([
+            next(10, 102),
+            completed(20)
+            ])
+
+        let ys2 = scheduler.createColdObservable([
+            next(20, 202),
+            completed(25)
+            ])
+
+        let xs = scheduler.createHotObservable([
+            next(250, ys1),
+            next(300, ys2),
+            completed(900)
+            ])
+
+        let results = scheduler.start {
+            return xs.concatMap {
+                return $0
             }
         }
-        
-        XCTAssertEqual(xs.subscriptions, [
-            Subscription(200, 700)
-        ])
-        
-        XCTAssertEqual(ys.subscriptions, [
-            Subscription(300, 550),
-            Subscription(550, 800),
-            Subscription(800, 1050),
-            Subscription(1050, 1300)
-        ])
-        
+
+        XCTAssertEqual(xs.subscriptions, [
+            Subscription(200, 900)
+            ])
+
+        XCTAssertEqual(ys1.subscriptions, [
+            Subscription(250, 270)
+            ])
+
+        XCTAssertEqual(ys2.subscriptions, [
+            Subscription(300, 325)
+            ])
+
         XCTAssertEqual(results.events, [
-            next(350, "foo"),
-            next(400, "bar"),
-            next(450, "baz"),
-            next(500, "qux"),
-            next(600, "foo"),
-            next(650, "bar"),
-            next(700, "baz"),
-            next(750, "qux"),
-            next(850, "foo"),
-            next(900, "bar"),
-            next(950, "baz"),
-            next(1000, "qux"),
-            next(1100, "foo"),
-            next(1150, "bar"),
-            next(1200, "baz"),
-            next(1250, "qux"),
-            completed(1300)
-        ])
-    }
-    
-    func testConcatMap_Never_Complete() {
-        let scheduler = TestScheduler(initialClock: 0)
-        
-        let xs = scheduler.createColdObservable([
-            next(100, 4),
-            next(200, 3),
-            next(300, 2),
-            next(400, 1)
-            ])
-        
-        let ys = scheduler.createColdObservable([
-            next(50, "foo"),
-            next(100, "bar"),
-            next(150, "baz"),
-            next(200, "qux"),
-            completed(250)
-            ])
-        
-        let results = scheduler.start(disposed: 2000) {
-            return xs.concatMap { _ in
-                return ys.asObservable()
-            }
-        }
-        
-        XCTAssertEqual(xs.subscriptions, [
-            Subscription(200, 2000)
-        ])
-        
-        XCTAssertEqual(ys.subscriptions, [
-            Subscription(300, 550),
-            Subscription(550, 800),
-            Subscription(800, 1050),
-            Subscription(1050, 1300)
-        ])
-        
-        XCTAssertEqual(results.events, [
-            next(350, "foo"),
-            next(400, "bar"),
-            next(450, "baz"),
-            next(500, "qux"),
-            next(600, "foo"),
-            next(650, "bar"),
-            next(700, "baz"),
-            next(750, "qux"),
-            next(850, "foo"),
-            next(900, "bar"),
-            next(950, "baz"),
-            next(1000, "qux"),
-            next(1100, "foo"),
-            next(1150, "bar"),
-            next(1200, "baz"),
-            next(1250, "qux")
-            ])
-    }
-    
-    func testConcatMap_Complete_Never() {
-        let scheduler = TestScheduler(initialClock: 0)
-        
-        let xs = scheduler.createColdObservable([
-            next(100, 4),
-            next(200, 3),
-            next(300, 2),
-            next(400, 1),
-            completed(500)
-            ])
-        
-        let ys = scheduler.createColdObservable([
-            next(50, "foo"),
-            next(100, "bar"),
-            next(150, "baz"),
-            next(200, "qux")
-            ])
-        
-        let results = scheduler.start {
-            return xs.concatMap { _ in
-                return ys.asObservable()
-            }
-        }
-        
-        XCTAssertEqual(xs.subscriptions, [
-            Subscription(200, 700)
-        ])
-        
-        XCTAssertEqual(ys.subscriptions, [
-            Subscription(300, 1000)
-        ])
-        
-        XCTAssertEqual(results.events, [
-            next(350, "foo"),
-            next(400, "bar"),
-            next(450, "baz"),
-            next(500, "qux")
-        ])
-    }
-    
-    func testConcatMap_Complete_Error() {
-        let scheduler = TestScheduler(initialClock: 0)
-        
-        let xs = scheduler.createColdObservable([
-            next(100, 4),
-            next(200, 3),
-            next(300, 2),
-            next(400, 1),
-            completed(500)
-        ])
-        
-        let ys = scheduler.createColdObservable([
-            next(50, "foo"),
-            next(100, "bar"),
-            next(150, "baz"),
-            next(200, "qux"),
-            error(300, testError)
-        ])
-        
-        let results = scheduler.start {
-            return xs.concatMap { _ in
-                return ys.asObservable()
-            }
-        }
-        
-        XCTAssertEqual(xs.subscriptions, [
-            Subscription(200, 600)
-        ])
-        
-        XCTAssertEqual(ys.subscriptions, [
-            Subscription(300, 600)
-        ])
-        
-        XCTAssertEqual(results.events, [
-            next(350, "foo"),
-            next(400, "bar"),
-            next(450, "baz"),
-            next(500, "qux"),
-            error(600, testError)
-        ])
-    }
-    
-    func testConcatMap_Error_Complete() {
-        let scheduler = TestScheduler(initialClock: 0)
-        
-        let xs = scheduler.createColdObservable([
-            next(100, 4),
-            next(200, 3),
-            next(300, 2),
-            next(400, 1),
-            error(500, testError)
-            ])
-        
-        let ys = scheduler.createColdObservable([
-            next(50, "foo"),
-            next(100, "bar"),
-            next(150, "baz"),
-            next(200, "qux"),
-            completed(250)
-        ])
-        
-        let results = scheduler.start {
-            return xs.concatMap { _ in
-                return ys.asObservable()
-            }
-        }
-        
-        XCTAssertEqual(xs.subscriptions, [
-            Subscription(200, 700)
-        ])
-        
-        XCTAssertEqual(ys.subscriptions, [
-            Subscription(300, 550),
-            Subscription(550, 700)
-        ])
-        
-        XCTAssertEqual(results.events, [
-            next(350, "foo"),
-            next(400, "bar"),
-            next(450, "baz"),
-            next(500, "qux"),
-            next(600, "foo"),
-            next(650, "bar"),
-            error(700, testError)
-        ])
-    }
-    
-    func testConcatMap_Error_Error() {
-        let scheduler = TestScheduler(initialClock: 0)
-        
-        let xs = scheduler.createColdObservable([
-            next(100, 4),
-            next(200, 3),
-            next(300, 2),
-            next(400, 1),
-            error(500, testError)
-            ])
-        
-        let ys = scheduler.createColdObservable([
-            next(50, "foo"),
-            next(100, "bar"),
-            next(150, "baz"),
-            next(200, "qux"),
-            error(250, testError)
-            ])
-        
-        let results = scheduler.start {
-            return xs.concatMap { _ in
-                return ys.asObservable()
-            }
-        }
-        
-        XCTAssertEqual(xs.subscriptions, [
-            Subscription(200, 550)
-        ])
-        
-        XCTAssertEqual(ys.subscriptions, [
-            Subscription(300, 550)
-        ])
-        
-        XCTAssertEqual(results.events, [
-            next(350, "foo"),
-            next(400, "bar"),
-            next(450, "baz"),
-            next(500, "qux"),
-            error(550, testError)
-        ])
-    }
-    
-    func testConcatMap_Complete() {
+            next(260, 102),
+            next(320, 202),
+            completed(900)
+            ])
+    }
+    
+    func testConcatMap_OuterComplete_InnerNotComplete() {
         let scheduler = TestScheduler(initialClock: 0)
         
         let ys1 = scheduler.createColdObservable([
-            error(1, testError, Int.self)
-        ])
-        
-        let ys2 = scheduler.createColdObservable([
-            error(1, testError1, Int.self)
-        ])
-        
-        let ys3 = scheduler.createColdObservable([
             next(10, 102),
             next(90, 103),
             next(110, 104),

            next(190, 105),
            next(440, 106),
            completed(460)
        ])
        
        let ys2 = scheduler.createColdObservable([
            next(180, 202),
            next(190, 203)
        ])
        
        let ys3 = scheduler.createColdObservable([
            next(10, 301),
            next(50, 302),
            completed(60)
        ])
        
        let ys4 = scheduler.createColdObservable([
            completed(40, Int.self)
        ])
        
        let ys5 = scheduler.createColdObservable([
            next(80, 401),
            next(90, 402),
            completed(100)
        ])
        
        let xs = scheduler.createHotObservable([
            next(300, ys1),
            next(400, ys2),
            next(550, ys3),
            next(750, ys4),
            next(850, ys5),
            completed(900)
        ])
        
        let results = scheduler.start {
            return xs.concatMap {
                return $0
            }
        }
        
        XCTAssertEqual(xs.subscriptions, [
            Subscription(200, 900)
        ])
        
        XCTAssertEqual(ys1.subscriptions, [
            Subscription(300, 760)
        ])
        
        XCTAssertEqual(ys2.subscriptions, [
            Subscription(760, 1000)
        ])
        
        XCTAssertEqual(ys3.subscriptions, [])
        
        XCTAssertEqual(ys4.subscriptions, [])
        
        XCTAssertEqual(ys5.subscriptions, [])
        
        XCTAssertEqual(results.events, [
            next(310, 102),
            next(390, 103),
            next(410, 104),
            next(490, 105),
            next(740, 106),
            next(940, 202),
            next(950, 203)
        ])
    }
    
    func test_Complete_OuterNotComplete() {
        let scheduler = TestScheduler(initialClock: 0)
        
        let ys1 = scheduler.createColdObservable([
            next(10, 102),
            next(90, 103),
            next(110, 104),
            next(190, 105),
            next(440, 106),
            completed(460)
            ])
        
        let ys2 = scheduler.createColdObservable([
            next(180, 202),
            next(190, 203),
            completed(205)
            ])
        
        let ys3 = scheduler.createColdObservable([
            next(10, 301),
            next(50, 302),
            completed(60)
            ])
        
        let ys4 = scheduler.createColdObservable([
            completed(40, Int.self)
            ])
        
        let ys5 = scheduler.createColdObservable([
            next(80, 401),
            next(90, 402),
            completed(100)
            ])
        
        let xs = scheduler.createHotObservable([
            next(300, ys1),
            next(400, ys2),
            next(550, ys3),
            next(750, ys4),
            next(850, ys5)
            ])
        
        let results = scheduler.start {
            return xs.concatMap {
                return $0
            }
        }
        
        XCTAssertEqual(xs.subscriptions, [
            Subscription(200, 1000)
        ])
        
        XCTAssertEqual(ys1.subscriptions, [
            Subscription(300, 760)
        ])
        
        XCTAssertEqual(ys2.subscriptions, [
            Subscription(760, 965)
        ])
        
        XCTAssertEqual(ys3.subscriptions, [
            Subscription(965, 1000)
        ])
        
        XCTAssertEqual(ys4.subscriptions, [])
        
        XCTAssertEqual(ys5.subscriptions, [])
        
        XCTAssertEqual(results.events, [
            next(310, 102),
            next(390, 103),

            next(740, 106),
            next(940, 202),
            next(950, 203),
        ])
    }

    func test_InnerComplete_OuterCompleteBeforeInner() {
        let scheduler = TestScheduler(initialClock: 0)

        let ys1 = scheduler.createColdObservable([
            next(10, 102),
            next(90, 103),
