 		self.request = request
 		self.peers = peers
 	}
-}
 
-extension ResourceRequestReceipt: ResourceEventProducerProtocol {
-	public func addEventObserver(on queue: DispatchQueue, action: @escaping (ResourceEvent<Request>) -> Void) -> Disposable {
+	public func addEventObserver(on queue: DispatchQueue, action: @escaping (ResourceTransferEvent<Request>) -> Void) -> Disposable {
 		let observer = DispatchObserver(queue: queue, action: action)
-		let disposable = eventObserver.add(observer)
-		self.disposable += disposable
-		return disposable
+		return eventObserver.add(observer)
 	}
 }
 
-extension ResourceRequestReceipt: Disposable {
+extension ResourceTransferOperation: Disposable {
 	public var isDisposed: Bool {
 		return disposable.isDisposed
 	}

				switch event {
				case .didStartReceivingResource(let name, let from, let progress):
					guard name == request.resourceName, from == peer else { return }
					action(.transferStarted(request, peer, progress), sendAndDispose)
				case .didFinishReceivingResource(let name, let from, let localURL, let error):
					guard name == request.resourceName, from == peer else { return }
					if let error = error {
						action(.transferFailed(request, peer, error), sendAndDispose)
					} else {
						action(.transferFinished(request, peer, localURL), sendAndDispose)
					}
					sessionEventDisposable.dispose()
				default:

		return receipt
	}

	public func submit(resourceAt localURL: URL, to peers: [MCPeerID]) throws -> ResourceTransferOperation<ResourceRequest> {
		let request = ResourceRequest()
		return try submit(request, withResourceAt: localURL, to: peers)
	}
}

extension Session {
	public func addResponder<T: ResourceRequestProtocol>(for resourceRequestType: T.Type, on queue: DispatchQueue, action: @escaping (_ event: ResourceTransferEvent<T>, _ send: @escaping (_ response: T.Response) throws -> Void) -> Void) -> Disposable {
		let disposable = CompositeDisposable()

		let responseQueue = DispatchQueue(label: "com.junpluse.Tuka.Session.ResourceRequestResponderQueue")
		let responder = RequestResponder<T, MCPeerID>(queue: responseQueue) { request, peer, send in
			let sessionEventDisposable = CompositeDisposable()

			let sendAndDispose: (T.Response) throws -> Void = { response in
