 	}
 
 	public func start(onReady: CommReadyCallback) -> Comm {
+		dispatch_group_enter(receivedValue)
 		v = nil
-		dispatch_group_enter(receivedValue)
-
-		let (sender, receiver) = ch.recv(onReady)
-		if let sender = sender {
+
+		func haveValue(v: V?) {
+			self.v = v
+			dispatch_group_leave(self.receivedValue)
+			onReady()
+		}
+
+		switch ch.recv(onReady) {
+		case let .Block(thread):
 			go {
-				let (v, _) = sender.recv()
-				self.v = v
-				dispatch_group_leave(self.receivedValue)
-				onReady()
-			}
-
-			return sender.comm
-
-		} else {
+				let (v, _) = thread.waitForSender()
+				haveValue(v)
+			}
+
+			return thread.comm
+
+		case let .FromSender(thread):
 			go {
-				let (v, _) = receiver!.waitForSender()
-				self.v = v
-				dispatch_group_leave(self.receivedValue)
-				onReady()
-			}
-
-			return receiver!.comm
+				let (v, _) = thread.recv()
+				haveValue(v)
+			}
+
+			return thread.comm
 		}
 	}
 

}

// What is about to happen as a thread enters into a receive action on a channel.
private enum Receive<V> {
	case FromSender(WaitForRecv<V>)
	case Block(WaitForSend<V>)
}

// What is about to happen as a thread enters into a send action on a channel.
private enum Send<V> {
	case ToReceiver(WaitForSend<V>)
	case Block(WaitForRecv<V>)
}


public protocol SelectableRecvChannel {
	associatedtype ValueType
	func recv(_: CommReadyCallback) -> Receive<ValueType>
}

public protocol SelectableSendChannel {
	associatedtype ValueType
	func send(_: CommReadyCallback) -> Send<ValueType>
}

public struct ASyncRecv<V> {
