 public typealias URLRequesterState = Set<URLRequest>
 
 
-// Implementation
+/// Implementation
 public final class URLRequester<State> {
 
-	public init(store: Store<State>, lens: @escaping (State) -> URLRequesterState) {
+	public init(session: URLSession = URLSession.shared, store: Store<State>, lens: @escaping (State) -> URLRequesterState) {
+		self.session = session
 		self.store = store
-		unsubscribe = store.subscribe { [weak self] state in
-			let requests = lens(state)
-			self?.configure(using: requests)
+		unsubscriber = store.subscribe { [weak self] (state) in
+			let requesterState = lens(state)
+			self?.configure(using: requesterState)
 		}
 	}
 
+	private let session: URLSession
 	private let store: Store<State>
-	private var unsubscribe: Unsubscriber?
+	private var unsubscriber: Unsubscriber?
 	private var current: [URLRequest: URLSessionTask] = [:]
 
 	private func configure(using target: URLRequesterState) {

import Foundation


// Logic
public
enum URLRequesterEvent: Event {
	case success(data: Data, response: URLResponse)
	case failure(error: Error, response: URLResponse)

	public
	var response: URLResponse {
		switch self {
		case .success(let (_, response)), .failure(let (_, response)):
			return response
		}
	}
}

	}

	private func launch(request: URLRequest) {
		let dataTask = session.dataTask(with: request) { (data, response, error) in
			DispatchQueue.main.async {
				if let data = data, let response = response {
					self.store.dispatch(event: URLRequesterEvent.success(request: request, data: data, response: response))
				}
				if let error = error {
					self.store.dispatch(event: URLRequesterEvent.failure(request: request, error: error))
				}
			}
		}
		current[request] = dataTask
		dataTask.resume()
	}
}

public func cancelLaunch<T>(current: Set<T>, target: Set<T>, cancel: (T) -> Void, launch: (T) -> Void) {
