 						// discovering failed
 						req.failure?(errorInfo)
 					} else {
-						// discovering succeed
-						req.success?(nil)
-					}
-				})
+						// discovering succeed, call success closure of each req
+						req.success?(nil)
+					}
+				})
+				// 4. once the success/failure closure called, remove the req
 				dispatch_async(self.requestQ, { () -> Void in
 					self.characteristicDiscoveringRequests.remove(req)
 				})

	*/
	public func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) {
		dispatch_async(self.operationQ) { () -> Void in
			for req in self.serviceDiscoveringRequests {
				if let uuids = req.serviceUUIDs {
					if !self.areServicesAvailable(uuids: uuids) {
						return
					}
				}
			}
			for req in self.serviceDiscoveringRequests {
				req.timedOut = false
				dispatch_async(dispatch_get_main_queue(), { () -> Void in

	public func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
		// found out whether value is read or subscirbed

		dispatch_async(self.operationQ, { () -> Void in
			var tgtReq: ReadRequest?
			for req in self.readRequests {
				if req.characteristic == characteristic {
					tgtReq = req
					break
				}
			}
			dispatch_async(dispatch_get_main_queue(), { () -> Void in
				if let req = tgtReq {
					req.timedOut = false
					// read
					if let errorInfo = error {
						// failed
						req.failure?(errorInfo)
					} else {
						// succeed
						let resp = Response()
						resp.value = characteristic.value
						req.success?(resp)
					}
					dispatch_async(self.requestQ, { () -> Void in
						self.readRequests.remove(req)
					})
				} else {
					// subscribed
					// TODO: deal with value updates
					//						session.update?(characteristic.value)
				}
			})
		})
	}

	/*!
