 	func wasSelected()
 }
 
+public class RecvCase<C: SelectableRecvChannel, V where C.ValueType == V>: SelectCase {
+	let ch: C
+	let received: (V) -> ()
+
+	private let receivedValue = dispatch_group_create()
+	private var v: V?
+
+	public init(channel: C, onSelected: (V) -> ()) {
+		ch = channel
+		received = onSelected
+	}
+
+	public func start(onReady: CommReadyCallback) -> Comm {
+		v = nil
+		dispatch_group_enter(receivedValue)
+
+		let (sender, receiver) = ch.recv(onReady)
+		if let sender = sender {
+			go {
+				let (v, _) = sender.recv()
+				self.v = v
+				dispatch_group_leave(self.receivedValue)
+				onReady()
+			}
+
+			return sender.comm
+
+		} else {
+			go {
+				let (v, _) = receiver!.waitForSender()
+				self.v = v
+				dispatch_group_leave(self.receivedValue)
+				onReady()
+			}
+
+			return receiver!.comm
+		}
+	}
+
+	public func wasSelected() {
+		dispatch_group_wait(receivedValue, DISPATCH_TIME_FOREVER)
+		received(v!)
+	}
+}
+
+public func recv<C: SelectableRecvChannel, V where C.ValueType == V>(from channel: C, block: (V) -> ()) -> SelectCase {
+	return RecvCase<C, V>(channel: channel, onSelected: block)
+}
+
 public func Select (cases: () -> [SelectCase]) {
 	return selectCases(cases())
 }

			}
		}
	}
}

public struct SendOnlyChan<C: SendChannel>: SendChannel {

public protocol RecvChannel {
	typealias ValueType
	func recv() -> ValueType
}

public protocol SelectableRecvChannel {
	typealias ValueType
	func recv(CommReadyCallback) -> (WaitForRecv<ValueType>?, WaitForSend<ValueType>?)
}

public struct ASyncRecv<V> {
