 }
 
 extension KBAPIConnection: KBAPIConnectionProtocol {
+	open var isCancelled: Bool {
+		return self.taskWasCancelled || (self.taskWrapper.isTaskValid && (self.task.state == .canceling));
+	}
+	
 	open func cancel () {
+		guard !self.isCancelled else {
+			return;
+		}
+		self.taskWasCancelled = true;
 		self.task.cancel ();
 	}
 }

					connection.taskDidFinish (data: data, response: response, error: error, completion: completion);
				};
			});
			self.taskPointer = Int (bitPattern: Unmanaged.passUnretained (task).toOpaque ());
			return task;
		}
	}
}

		fileprivate let request: Request;
		
		fileprivate var task: URLSessionTask {
			guard let taskPointer = self.taskPointer else {
				log.fault ("URL session task is not created yet");
				return URLSessionTask ();
			}
			return taskPointer.pointee;
		}
		
		fileprivate var isTaskValid: Bool {
			return self.taskPointer != nil;
		}
		
		private unowned let session: URLSession;
		private var taskPointer: UnsafePointer <URLSessionTask>?;
		
		fileprivate init (session: URLSession, request: Request) {
			self.session = session;
