Decouple AbstractContinuation and CancellableContinuation from Job interface
diff --git a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/Future.kt b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/Future.kt
index b10f0cd..6909b99 100644
--- a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/Future.kt
+++ b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/Future.kt
@@ -22,15 +22,46 @@
 import java.util.concurrent.*
 
 /**
- * Cancels a specified [future] when this job is complete.
- *
+ * Cancels a specified [future] when this job is cancelled.
  * This is a shortcut for the following code with slightly more efficient implementation (one fewer object created).
  * ```
  * invokeOnCompletion { future.cancel(false) }
  * ```
  */
 public fun Job.cancelFutureOnCompletion(future: Future<*>): DisposableHandle =
-    invokeOnCompletion(handler = CancelFutureOnCompletion(this, future))
+    invokeOnCompletion(handler = CancelFutureOnCompletion(this, future)) // TODO make it work only on cancellation as well?
+
+/**
+ * Cancels a specified [future] when this job is cancelled.
+ * This is a shortcut for the following code with slightly more efficient implementation (one fewer object created).
+ * ```
+ * invokeOnCompletion { future.cancel(false) }
+ * ```
+ */
+@Deprecated(
+    message = "Disposable handlers on regular completion are no longer supported",
+    replaceWith = ReplaceWith("cancelFutureOnCancellation(future)"),
+    level = DeprecationLevel.WARNING)
+public fun CancellableContinuation<*>.cancelFutureOnCompletion(future: Future<*>): DisposableHandle {
+    cancelFutureOnCancellation(future)
+    return NonDisposableHandle
+}
+
+/**
+ * Cancels a specified [future] when this job is cancelled.
+ * This is a shortcut for the following code with slightly more efficient implementation (one fewer object created).
+ * ```
+ * invokeOnCancellation { future.cancel(false) }
+ * ```
+ */
+public fun CancellableContinuation<*>.cancelFutureOnCancellation(future: Future<*>) {
+    if (this is AbstractContinuation<*>) {
+        invokeOnCancellation(handler = CancelFutureOnCancellation(this, future))
+    } else {
+        // Fallback if someone else implement CancellableContinuation
+        invokeOnCancellation { future.cancel(false)  }
+    }
+}
 
 private class CancelFutureOnCompletion(
     job: Job,
@@ -44,3 +75,15 @@
     override fun toString() = "CancelFutureOnCompletion[$future]"
 }
 
+private class CancelFutureOnCancellation(
+    continuation: CancellableContinuation<*>,
+    private val future: Future<*>
+) : CancellationHandlerImpl<AbstractContinuation<*>>(continuation as AbstractContinuation<*>)  {
+
+    override fun invoke(reason: Throwable?) {
+        // Don't interrupt when cancelling future on completion, because no one is going to reset this
+        // interruption flag and it will cause spurious failures elsewhere
+        future.cancel(false)
+    }
+    override fun toString() = "CancelFutureOnCancellation[$future]"
+}