Change stacktrace recovery contract

    * Stacktraces are no longer recovered in DispatchedTask.run
    * Callers of uCont.resumeWithException are responsible for recovering the stacktrace
    * CancellableContinuation.resumeWithException recovers stacktrace if necessary
    * Properly recover stacktrace in Channel.receive fast-path
    * Properly recover stactraces on Channel.send fast-path
    * Restructure stacktrace recovery tests
diff --git a/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt b/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt
index 559afb8..31cf415 100644
--- a/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt
+++ b/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt
@@ -244,7 +244,7 @@
     }
 
     override fun resumeWith(result: Result<T>) {
-        resumeImpl(result.toState(), resumeMode)
+        resumeImpl(result.toState(this), resumeMode)
     }
 
     override fun resume(value: T, onCancellation: (cause: Throwable) -> Unit) {
diff --git a/kotlinx-coroutines-core/common/src/CompletedExceptionally.kt b/kotlinx-coroutines-core/common/src/CompletedExceptionally.kt
index 785041d..b75d430 100644
--- a/kotlinx-coroutines-core/common/src/CompletedExceptionally.kt
+++ b/kotlinx-coroutines-core/common/src/CompletedExceptionally.kt
@@ -9,8 +9,10 @@
 import kotlin.coroutines.*
 import kotlin.jvm.*
 
-internal fun <T> Result<T>.toState(): Any? =
-    if (isSuccess) getOrThrow() else CompletedExceptionally(exceptionOrNull()!!) // todo: need to do it better
+internal fun <T> Result<T>.toState(): Any? = fold({ it }, { CompletedExceptionally(it) })
+
+internal fun <T> Result<T>.toState(caller: CancellableContinuation<*>): Any? = fold({ it },
+    { CompletedExceptionally(recoverStackTrace(it, caller)) })
 
 @Suppress("RESULT_CLASS_IN_RETURN_TYPE", "UNCHECKED_CAST")
 internal fun <T> recoverResult(state: Any?, uCont: Continuation<T>): Result<T> =
diff --git a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
index 8aadd26..4639bb8 100644
--- a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
+++ b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
@@ -144,13 +144,13 @@
 
     public final override suspend fun send(element: E) {
         // fast path -- try offer non-blocking
-        if (offer(element)) return
-        // slow-path does suspend
+        if (offerInternal(element) === OFFER_SUCCESS) return
+        // slow-path does suspend or throws exception
         return sendSuspend(element)
     }
 
     internal suspend fun sendFair(element: E) {
-        if (offer(element)) {
+        if (offerInternal(element) === OFFER_SUCCESS) {
             yield() // Works only on fast path to properly work in sequential use-cases
             return
         }
@@ -547,7 +547,11 @@
     public final override suspend fun receive(): E {
         // fast path -- try poll non-blocking
         val result = pollInternal()
-        if (result !== POLL_FAILED) return receiveResult(result)
+        /*
+         * If result is Closed -- go to tail-call slow-path that will allow us to
+         * properly recover stacktrace without paying a performance cost on fast path.
+         */
+        if (result !== POLL_FAILED && result !is Closed<*>) return receiveResult(result)
         // slow-path does suspend
         return receiveSuspend(RECEIVE_THROWS_ON_CLOSE)
     }
diff --git a/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt b/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt
index 6c33aba..98b45d5 100644
--- a/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt
+++ b/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt
@@ -52,7 +52,7 @@
                     cancelResult(state, cause)
                     continuation.resumeWithStackTrace(cause)
                 } else {
-                    if (exception != null) continuation.resumeWithStackTrace(exception)
+                    if (exception != null) continuation.resumeWithException(exception)
                     else continuation.resume(getSuccessfulResult(state))
                 }
             }
@@ -116,19 +116,8 @@
 internal fun <T> DispatchedTask<T>.resume(delegate: Continuation<T>, useMode: Int) {
     // slow-path - use delegate
     val state = takeState()
-    val exception = getExceptionalResult(state)?.let {
-        /*
-         * Recover stacktrace for non-dispatched tasks.
-         * We usually do not recover stacktrace in a `resume` as all resumes go through `DispatchedTask.run`
-         * and we recover stacktraces there, but this is not the case for a `suspend fun main()` that knows nothing about
-         * kotlinx.coroutines and DispatchedTask
-         */
-        if (delegate is DispatchedTask<*>) it else recoverStackTrace(it, delegate)
-    }
-    val result = if (exception != null)
-        Result.failure(exception)
-    else
-        Result.success(state as T)
+    val exception = getExceptionalResult(state)?.let { recoverStackTrace(it, delegate) }
+    val result = if (exception != null) Result.failure(exception) else Result.success(state as T)
     when (useMode) {
         MODE_ATOMIC_DEFAULT -> delegate.resumeWith(result)
         MODE_CANCELLABLE -> delegate.resumeCancellableWith(result)
diff --git a/kotlinx-coroutines-core/common/src/internal/Scopes.kt b/kotlinx-coroutines-core/common/src/internal/Scopes.kt
index 49770c2..c6cb187 100644
--- a/kotlinx-coroutines-core/common/src/internal/Scopes.kt
+++ b/kotlinx-coroutines-core/common/src/internal/Scopes.kt
@@ -33,11 +33,6 @@
     }
 }
 
-internal fun AbstractCoroutine<*>.tryRecover(exception: Throwable): Throwable {
-    val cont = (this as? ScopeCoroutine<*>)?.uCont ?: return exception
-    return recoverStackTrace(exception, cont)
-}
-
 internal class ContextScope(context: CoroutineContext) : CoroutineScope {
     override val coroutineContext: CoroutineContext = context
 }
diff --git a/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt b/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt
index cfef935..0aa9cd7 100644
--- a/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt
+++ b/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt
@@ -85,7 +85,7 @@
  * First, this function initializes the parent job from the `parentContext` of this coroutine that was passed to it
  * during construction. Second, it starts the coroutine using [startCoroutineUninterceptedOrReturn].
  */
-internal fun <T, R> AbstractCoroutine<T>.startUndispatchedOrReturn(receiver: R, block: suspend R.() -> T): Any? {
+internal fun <T, R> ScopeCoroutine<T>.startUndispatchedOrReturn(receiver: R, block: suspend R.() -> T): Any? {
     initParentJob()
     return undispatchedResult({ true }) {
         block.startCoroutineUninterceptedOrReturn(receiver, this)
@@ -95,7 +95,7 @@
 /**
  * Same as [startUndispatchedOrReturn], but ignores [TimeoutCancellationException] on fast-path.
  */
-internal fun <T, R> AbstractCoroutine<T>.startUndispatchedOrReturnIgnoreTimeout(
+internal fun <T, R> ScopeCoroutine<T>.startUndispatchedOrReturnIgnoreTimeout(
     receiver: R, block: suspend R.() -> T): Any? {
     initParentJob()
     return undispatchedResult({ e -> !(e is TimeoutCancellationException && e.coroutine === this) }) {
@@ -103,7 +103,7 @@
     }
 }
 
-private inline fun <T> AbstractCoroutine<T>.undispatchedResult(
+private inline fun <T> ScopeCoroutine<T>.undispatchedResult(
     shouldThrow: (Throwable) -> Boolean,
     startBlock: () -> Any?
 ): Any? {
@@ -129,8 +129,8 @@
     if (state === COMPLETING_WAITING_CHILDREN) return COROUTINE_SUSPENDED // (2)
     return if (state is CompletedExceptionally) { // (3)
         when {
-            shouldThrow(state.cause) -> throw tryRecover(state.cause)
-            result is CompletedExceptionally -> throw tryRecover(result.cause)
+            shouldThrow(state.cause) -> throw recoverStackTrace(state.cause, uCont)
+            result is CompletedExceptionally -> throw recoverStackTrace(result.cause, uCont)
             else -> result
         }
     } else {
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testCancelledOffer.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testCancelledOffer.txt
new file mode 100644
index 0000000..095be1e
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testCancelledOffer.txt
@@ -0,0 +1,15 @@
+kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelling}@2a06d350
+	(Coroutine boundary)
+	at kotlinx.coroutines.channels.AbstractSendChannel.offer(AbstractChannel.kt:170)
+	at kotlinx.coroutines.channels.ChannelCoroutine.offer(ChannelCoroutine.kt)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testCancelledOffer$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:153)
+Caused by: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelling}@2a06d350
+	at kotlinx.coroutines.JobSupport.createJobCancellationException(JobSupport.kt:680)
+	at kotlinx.coroutines.JobSupport.createCauseException(JobSupport.kt:696)
+	at kotlinx.coroutines.JobSupport.cancelMakeCompleting(JobSupport.kt:673)
+	at kotlinx.coroutines.JobSupport.cancelImpl$kotlinx_coroutines_core(JobSupport.kt:645)
+	at kotlinx.coroutines.JobSupport.cancelInternal(JobSupport.kt:611)
+	at kotlinx.coroutines.JobSupport.cancel(JobSupport.kt:599)
+	at kotlinx.coroutines.Job$DefaultImpls.cancel$default(Job.kt:164)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testCancelledOffer$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:151)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferFromScope.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferFromScope.txt
new file mode 100644
index 0000000..bf3fd3a
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferFromScope.txt
@@ -0,0 +1,10 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferFromScope$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:109)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.sendInChannel(StackTraceRecoveryChannelsTest.kt:167)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$sendWithContext$2.invokeSuspend(StackTraceRecoveryChannelsTest.kt:162)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$sendFromScope$2.invokeSuspend(StackTraceRecoveryChannelsTest.kt:172)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferFromScope$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:112)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferFromScope$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:109)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferWithContextWrapped.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferWithContextWrapped.txt
new file mode 100644
index 0000000..612d00d
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferWithContextWrapped.txt
@@ -0,0 +1,9 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferWithContextWrapped$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:98)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.sendInChannel(StackTraceRecoveryChannelsTest.kt:199)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$sendWithContext$2.invokeSuspend(StackTraceRecoveryChannelsTest.kt:194)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferWithContextWrapped$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:100)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferWithContextWrapped$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:98)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferWithCurrentContext.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferWithCurrentContext.txt
new file mode 100644
index 0000000..833afbf
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testOfferWithCurrentContext.txt
@@ -0,0 +1,9 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferWithCurrentContext$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:86)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.sendInChannel(StackTraceRecoveryChannelsTest.kt:210)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$sendWithContext$2.invokeSuspend(StackTraceRecoveryChannelsTest.kt:205)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferWithCurrentContext$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:89)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testOfferWithCurrentContext$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:86)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testReceiveFromChannel.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testReceiveFromChannel.txt
new file mode 100644
index 0000000..66bb5e5
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testReceiveFromChannel.txt
@@ -0,0 +1,8 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testReceiveFromChannel$1$job$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:97)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.channelReceive(StackTraceRecoveryChannelsTest.kt:116)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testReceiveFromChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:101)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testReceiveFromChannel$1$job$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:97)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testReceiveFromClosedChannel.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testReceiveFromClosedChannel.txt
new file mode 100644
index 0000000..76c0b1a
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testReceiveFromClosedChannel.txt
@@ -0,0 +1,8 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testReceiveFromClosedChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:110)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.channelReceive(StackTraceRecoveryChannelsTest.kt:116)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testReceiveFromClosedChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:111)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testReceiveFromClosedChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:110)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendFromScope.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendFromScope.txt
new file mode 100644
index 0000000..9f93203
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendFromScope.txt
@@ -0,0 +1,10 @@
+kotlinx.coroutines.RecoverableTestCancellationException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendFromScope$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:136)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.sendInChannel(StackTraceRecoveryChannelsTest.kt:167)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$sendWithContext$2.invokeSuspend(StackTraceRecoveryChannelsTest.kt:162)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$sendFromScope$2.invokeSuspend(StackTraceRecoveryChannelsTest.kt:172)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendFromScope$1$deferred$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:126)
+Caused by: kotlinx.coroutines.RecoverableTestCancellationException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendFromScope$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:136)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendToChannel.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendToChannel.txt
new file mode 100644
index 0000000..dab728f
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendToChannel.txt
@@ -0,0 +1,12 @@
+java.util.concurrent.CancellationException: RendezvousChannel was cancelled
+	at kotlinx.coroutines.channels.AbstractChannel.cancel(AbstractChannel.kt:630)
+	at kotlinx.coroutines.channels.ReceiveChannel$DefaultImpls.cancel$default(Channel.kt:311)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendToChannel$1$job$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:52)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.channelSend(StackTraceRecoveryChannelsTest.kt:73)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendToChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:56)
+Caused by: java.util.concurrent.CancellationException: RendezvousChannel was cancelled
+	at kotlinx.coroutines.channels.AbstractChannel.cancel(AbstractChannel.kt:630)
+	at kotlinx.coroutines.channels.ReceiveChannel$DefaultImpls.cancel$default(Channel.kt:311)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendToChannel$1$job$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:52)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendToClosedChannel.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendToClosedChannel.txt
new file mode 100644
index 0000000..54fdbb3
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/channels/testSendToClosedChannel.txt
@@ -0,0 +1,8 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendToClosedChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:43)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest.channelSend(StackTraceRecoveryChannelsTest.kt:74)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendToClosedChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:44)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryChannelsTest$testSendToClosedChannel$1.invokeSuspend(StackTraceRecoveryChannelsTest.kt:43)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testEventLoopDispatcher.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testEventLoopDispatcher.txt
new file mode 100644
index 0000000..6b40ec8
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testEventLoopDispatcher.txt
@@ -0,0 +1,12 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testEventLoopDispatcher$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:40)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:76)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doFastPath(StackTraceRecoveryResumeModeTest.kt:71)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:62)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testEventLoopDispatcher$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:40)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testEventLoopDispatcher$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:40)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testEventLoopDispatcherSuspending.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testEventLoopDispatcherSuspending.txt
new file mode 100644
index 0000000..5afc559
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testEventLoopDispatcherSuspending.txt
@@ -0,0 +1,10 @@
+otlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:99)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$4.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:116)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doSuspendingPath(StackTraceRecoveryResumeModeTest.kt:110)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeSuspending(StackTraceRecoveryResumeModeTest.kt:101)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testEventLoopDispatcherSuspending$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:89)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:99)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopChangedContext.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopChangedContext.txt
new file mode 100644
index 0000000..406b2d1
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopChangedContext.txt
@@ -0,0 +1,13 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopChangedContext$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:54)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:76)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doFastPath(StackTraceRecoveryResumeModeTest.kt:71)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:62)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopChangedContext$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:54)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopChangedContext$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:53)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopChangedContext$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:54)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopChangedContextSuspending.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopChangedContextSuspending.txt
new file mode 100644
index 0000000..86ec5e4
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopChangedContextSuspending.txt
@@ -0,0 +1,11 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:113)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$4.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:130)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doSuspendingPath(StackTraceRecoveryResumeModeTest.kt:124)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeSuspending(StackTraceRecoveryResumeModeTest.kt:115)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopChangedContextSuspending$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:103)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopChangedContextSuspending$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:102)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:113)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopDispatcher.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopDispatcher.txt
new file mode 100644
index 0000000..d9098bb
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopDispatcher.txt
@@ -0,0 +1,13 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopDispatcher$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:47)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:76)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doFastPath(StackTraceRecoveryResumeModeTest.kt:71)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:62)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopDispatcher$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:47)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopDispatcher$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:46)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopDispatcher$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:47)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopDispatcherSuspending.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopDispatcherSuspending.txt
new file mode 100644
index 0000000..8caed7a
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedEventLoopDispatcherSuspending.txt
@@ -0,0 +1,11 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:113)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$4.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:130)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doSuspendingPath(StackTraceRecoveryResumeModeTest.kt:124)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeSuspending(StackTraceRecoveryResumeModeTest.kt:115)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopDispatcherSuspending$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:96)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedEventLoopDispatcherSuspending$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:95)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:113)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfined.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfined.txt
new file mode 100644
index 0000000..a2cd009
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfined.txt
@@ -0,0 +1,13 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfined$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:27)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:76)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doFastPath(StackTraceRecoveryResumeModeTest.kt:71)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:62)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfined$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:27)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfined$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:26)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfined$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:27)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedChangedContext.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedChangedContext.txt
new file mode 100644
index 0000000..a786682
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedChangedContext.txt
@@ -0,0 +1,13 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedChangedContext$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:34)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:76)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doFastPath(StackTraceRecoveryResumeModeTest.kt:71)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:62)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedChangedContext$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:34)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedChangedContext$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:33)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedChangedContext$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:34)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedChangedContextSuspending.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedChangedContextSuspending.txt
new file mode 100644
index 0000000..8c937a7
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedChangedContextSuspending.txt
@@ -0,0 +1,11 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:128)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$4.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:148)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doSuspendingPath(StackTraceRecoveryResumeModeTest.kt:140)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeSuspending(StackTraceRecoveryResumeModeTest.kt:130)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedChangedContextSuspending$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:95)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedChangedContextSuspending$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:94)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:128)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedSuspending.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedSuspending.txt
new file mode 100644
index 0000000..b6eef47
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testNestedUnconfinedSuspending.txt
@@ -0,0 +1,11 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:128)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$4.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:148)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doSuspendingPath(StackTraceRecoveryResumeModeTest.kt:140)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeSuspending(StackTraceRecoveryResumeModeTest.kt:130)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedSuspending$1$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:88)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testNestedUnconfinedSuspending$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:87)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:128)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testUnconfined.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testUnconfined.txt
new file mode 100644
index 0000000..9b9cba3
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testUnconfined.txt
@@ -0,0 +1,12 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testUnconfined$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:40)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$withContext$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:76)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doFastPath(StackTraceRecoveryResumeModeTest.kt:71)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:62)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testUnconfined$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:40)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeFastPath(StackTraceRecoveryResumeModeTest.kt:61)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testUnconfined$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:40)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testUnconfinedSuspending.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testUnconfinedSuspending.txt
new file mode 100644
index 0000000..ca0bbe7
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/resume-mode/testUnconfinedSuspending.txt
@@ -0,0 +1,9 @@
+kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:128)
+	(Coroutine boundary)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.doSuspendingPath(StackTraceRecoveryResumeModeTest.kt:140)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest.testResumeModeSuspending(StackTraceRecoveryResumeModeTest.kt:130)
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testUnconfinedSuspending$1.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:82)
+Caused by: kotlinx.coroutines.RecoverableTestException
+	at kotlinx.coroutines.exceptions.StackTraceRecoveryResumeModeTest$testResumeModeSuspending$2.invokeSuspend(StackTraceRecoveryResumeModeTest.kt:128)
+	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryChannelsTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryChannelsTest.kt
new file mode 100644
index 0000000..478b9ad
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryChannelsTest.kt
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.coroutines.exceptions
+
+import kotlinx.coroutines.*
+import kotlinx.coroutines.channels.*
+import org.junit.*
+import org.junit.rules.*
+import kotlin.coroutines.*
+
+class StackTraceRecoveryChannelsTest : TestBase() {
+
+    @get:Rule
+    val name = TestName()
+
+    @Test
+    fun testReceiveFromChannel() = runTest {
+        val channel = Channel<Int>()
+        val job = launch {
+            expect(2)
+            channel.close(RecoverableTestException())
+        }
+
+        expect(1)
+        channelReceive(channel)
+        expect(3)
+        job.join()
+        finish(4)
+    }
+
+    @Test
+    fun testReceiveFromClosedChannel() = runTest {
+        val channel = Channel<Int>()
+        channel.close(RecoverableTestException())
+        channelReceive(channel)
+    }
+
+
+    @Test
+    fun testSendToClosedChannel() = runTest {
+        val channel = Channel<Int>()
+        channel.close(RecoverableTestException())
+        channelSend(channel)
+    }
+
+    @Test
+    fun testSendToChannel() = runTest {
+        val channel = Channel<Int>()
+        val job = launch {
+            expect(2)
+            channel.cancel()
+        }
+
+        expect(1)
+        channelSend(channel)
+        expect(3)
+        job.join()
+        finish(4)
+    }
+
+    private suspend fun channelReceive(channel: Channel<Int>) {
+        try {
+            yield()
+            channel.receive()
+            expectUnreached()
+        } catch (e: RecoverableTestException) {
+            verifyStackTrace("channels/${name.methodName}", e)
+        }
+    }
+
+    private suspend fun channelSend(channel: Channel<Int>) {
+        try {
+            yield()
+            channel.send(1)
+            expectUnreached()
+        } catch (e: Exception) {
+            verifyStackTrace("channels/${name.methodName}", e)
+        }
+    }
+
+    @Test
+    fun testOfferWithCurrentContext() = runTest {
+        val channel = Channel<Int>()
+        channel.close(RecoverableTestException())
+
+        try {
+            channel.sendWithContext(coroutineContext)
+        } catch (e: RecoverableTestException) {
+            verifyStackTrace("channels/${name.methodName}", e)
+        }
+    }
+
+    @Test
+    fun testOfferWithContextWrapped() = runTest {
+        val channel = Channel<Int>()
+        channel.close(RecoverableTestException())
+        try {
+            channel.sendWithContext(wrapperDispatcher(coroutineContext))
+        } catch (e: Exception) {
+            verifyStackTrace("channels/${name.methodName}", e)
+        }
+    }
+
+    @Test
+    fun testOfferFromScope() = runTest {
+        val channel = Channel<Int>()
+        channel.close(RecoverableTestException())
+
+        try {
+            channel.sendFromScope()
+        } catch (e: Exception) {
+            verifyStackTrace("channels/${name.methodName}", e)
+        }
+    }
+
+    // Slow path via suspending send
+    @Test
+    fun testSendFromScope() = runTest {
+        val channel = Channel<Int>()
+        val deferred = async {
+            try {
+                expect(1)
+                channel.sendFromScope()
+            } catch (e: Exception) {
+                verifyStackTrace("channels/${name.methodName}", e)
+            }
+        }
+
+        yield()
+        expect(2)
+        // Cancel is an analogue of `produce` failure, just a shorthand
+        channel.cancel(RecoverableTestCancellationException())
+        finish(3)
+        deferred.await()
+    }
+
+    // See https://github.com/Kotlin/kotlinx.coroutines/issues/950
+    @Test
+    fun testCancelledOffer() = runTest {
+        expect(1)
+        val job = Job()
+        val actor = actor<Int>(job, Channel.UNLIMITED) {
+            consumeEach {
+                expectUnreached() // is cancelled before offer
+            }
+        }
+        job.cancel()
+        try {
+            actor.offer(1)
+        } catch (e: Exception) {
+            verifyStackTrace("channels/${name.methodName}", e)
+            finish(2)
+        }
+    }
+
+    private suspend fun Channel<Int>.sendWithContext(ctx: CoroutineContext) = withContext(ctx) {
+        sendInChannel()
+        yield() // TCE
+    }
+
+    private suspend fun Channel<Int>.sendInChannel() {
+        send(42)
+        yield() // TCE
+    }
+
+    private suspend fun Channel<Int>.sendFromScope() = coroutineScope {
+        sendWithContext(wrapperDispatcher(coroutineContext))
+    }
+}
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedChannelsTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedChannelsTest.kt
deleted file mode 100644
index 748f0c1..0000000
--- a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedChannelsTest.kt
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-@file:Suppress("DeferredResultUnused", "DEPRECATION")
-
-package kotlinx.coroutines.exceptions
-
-import kotlinx.coroutines.*
-import kotlinx.coroutines.channels.*
-import org.junit.*
-import kotlin.coroutines.*
-
-class StackTraceRecoveryNestedChannelsTest : TestBase() {
-
-    private val channel = Channel<Int>(0)
-
-    private suspend fun sendWithContext(ctx: CoroutineContext) = withContext(ctx) {
-        sendInChannel()
-        yield() // TCE
-    }
-
-    private suspend fun sendInChannel() {
-        channel.send(42)
-        yield() // TCE
-    }
-
-    private suspend fun sendFromScope() = coroutineScope {
-        sendWithContext(wrapperDispatcher(coroutineContext))
-    }
-
-    @Test
-    fun testOfferWithCurrentContext() = runTest {
-        channel.close(RecoverableTestException())
-
-        try {
-            yield() // Will be fixed in 1.3.20 after KT-27190
-            sendWithContext(coroutineContext)
-        } catch (e: Exception) {
-            verifyStackTrace(e,
-                "kotlinx.coroutines.RecoverableTestException\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferWithCurrentContext\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:34)\n" +
-                    "\t(Coroutine boundary)\n" +
-                    "\tat kotlinx.coroutines.channels.AbstractSendChannel.offer(AbstractChannel.kt:180)\n" +
-                    "\tat kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:168)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest.sendInChannel(StackTraceRecoveryNestedChannelsTest.kt:24)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendWithContext\$2.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:19)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendWithContext\$2.invoke(StackTraceRecoveryNestedChannelsTest.kt)\n" +
-                    "\tat kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:85)\n" +
-                    "\tat kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:146)\n" +
-                    "\tat kotlinx.coroutines.BuildersKt.withContext(Unknown Source)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest.sendWithContext(StackTraceRecoveryNestedChannelsTest.kt:18)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferWithCurrentContext\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:37)\n" +
-                "Caused by: kotlinx.coroutines.RecoverableTestException\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferWithCurrentContext\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:34)\n" +
-                    "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n")
-        }
-    }
-
-    @Test
-    fun testOfferWithContextWrapped() = runTest {
-        channel.close(RecoverableTestException())
-
-        try {
-            sendWithContext(wrapperDispatcher(coroutineContext))
-        } catch (e: Exception) {
-            verifyStackTrace(e,
-                "kotlinx.coroutines.RecoverableTestException\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferWithContextWrapped\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:59)\n" +
-                    "\t(Coroutine boundary)\n" +
-                    "\tat kotlinx.coroutines.channels.AbstractSendChannel.offer(AbstractChannel.kt:180)\n" +
-                    "\tat kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:168)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest.sendInChannel(StackTraceRecoveryNestedChannelsTest.kt:24)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendWithContext\$2.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:19)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferWithContextWrapped\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:62)\n" +
-            "Caused by: kotlinx.coroutines.RecoverableTestException\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferWithContextWrapped\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:59)\n" +
-                    "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)")
-        }
-    }
-
-    @Test
-    fun testOfferFromScope() = runTest {
-        channel.close(RecoverableTestException())
-
-        try {
-            sendFromScope()
-        } catch (e: Exception) {
-            verifyStackTrace(e,
-                "kotlinx.coroutines.RecoverableTestException\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferFromScope\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:81)\n" +
-                    "\t(Coroutine boundary)\n" +
-                    "\tat kotlinx.coroutines.channels.AbstractSendChannel.offer(AbstractChannel.kt:180)\n" +
-                    "\tat kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:168)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest.sendInChannel(StackTraceRecoveryNestedChannelsTest.kt:24)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendWithContext\$2.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:19)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendFromScope\$2.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:28)\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferFromScope\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:84)\n" +
-                 "Caused by: kotlinx.coroutines.RecoverableTestException\n" +
-                    "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testOfferFromScope\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:81)\n" +
-                    "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)")
-        }
-    }
-
-    // Slow path via suspending send
-    @Test
-    fun testSendFromScope() = runTest {
-        val deferred = async {
-            try {
-                expect(1)
-                sendFromScope()
-            } catch (e: Exception) {
-                verifyStackTrace(e,
-                    "kotlinx.coroutines.RecoverableTestCancellationException\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testSendFromScope\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:118)\n" +
-                        "\t(Coroutine boundary)\n" +
-                        "\tat kotlinx.coroutines.channels.AbstractSendChannel.offer(AbstractChannel.kt:180)\n" +
-                        "\tat kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:168)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest.sendInChannel(StackTraceRecoveryNestedChannelsTest.kt:24)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendWithContext\$2.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:19)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$sendFromScope\$2.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:29)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testSendFromScope\$1\$deferred\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:109)\n" +
-                    "Caused by: kotlinx.coroutines.RecoverableTestCancellationException\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testSendFromScope\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:118)\n" +
-                        "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)")
-            }
-        }
-
-        yield()
-        expect(2)
-        // Cancel is an analogue of `produce` failure, just a shorthand
-        channel.cancel(RecoverableTestCancellationException())
-        finish(3)
-        deferred.await()
-    }
-
-    // See https://github.com/Kotlin/kotlinx.coroutines/issues/950
-    @Test
-    fun testCancelledOffer() = runTest {
-        expect(1)
-        val job = Job()
-        val actor = actor<Int>(job, Channel.UNLIMITED) {
-            consumeEach {
-                expectUnreached() // is cancelled before offer
-            }
-        }
-        job.cancel()
-        try {
-            actor.offer(1)
-        } catch (e: Exception) {
-            verifyStackTrace(e,
-                "kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelling}@3af42ad0\n" +
-                        "\t(Coroutine boundary)\n" +
-                        "\tat kotlinx.coroutines.channels.AbstractSendChannel.offer(AbstractChannel.kt:186)\n" +
-                        "\tat kotlinx.coroutines.channels.ChannelCoroutine.offer(ChannelCoroutine.kt)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testCancelledOffer\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:150)\n" +
-                    "Caused by: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=JobImpl{Cancelling}@3af42ad0\n",
-                    // ... java.lang.* stuff and JobSupport.* snipped here ...
-                        "\tat kotlinx.coroutines.Job\$DefaultImpls.cancel\$default(Job.kt:164)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedChannelsTest\$testCancelledOffer\$1.invokeSuspend(StackTraceRecoveryNestedChannelsTest.kt:148)"
-            )
-            finish(2)
-        }
-    }
-}
diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryResumeModeTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryResumeModeTest.kt
new file mode 100644
index 0000000..36f6052
--- /dev/null
+++ b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryResumeModeTest.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.coroutines.exceptions
+
+import kotlinx.coroutines.*
+import kotlinx.coroutines.channels.*
+import org.junit.*
+import kotlin.coroutines.*
+import org.junit.rules.TestName
+import org.junit.Rule
+
+class StackTraceRecoveryResumeModeTest : TestBase() {
+
+    @get:Rule
+    val testName = TestName()
+
+    @Test
+    fun testUnconfined() = runTest {
+        testResumeModeFastPath(Dispatchers.Unconfined)
+    }
+
+    @Test
+    fun testNestedUnconfined() = runTest {
+        withContext(Dispatchers.Unconfined) {
+            testResumeModeFastPath(Dispatchers.Unconfined)
+        }
+    }
+
+    @Test
+    fun testNestedUnconfinedChangedContext() = runTest {
+        withContext(Dispatchers.Unconfined) {
+            testResumeModeFastPath(CoroutineName("Test"))
+        }
+    }
+
+    @Test
+    fun testEventLoopDispatcher() = runTest {
+        testResumeModeFastPath(wrapperDispatcher())
+    }
+
+    @Test
+    fun testNestedEventLoopDispatcher() = runTest {
+        val dispatcher = wrapperDispatcher()
+        withContext(dispatcher) {
+            testResumeModeFastPath(dispatcher)
+        }
+    }
+
+    @Test
+    fun testNestedEventLoopChangedContext() = runTest {
+        withContext(wrapperDispatcher()) {
+            testResumeModeFastPath(CoroutineName("Test"))
+        }
+    }
+
+    private suspend fun testResumeModeFastPath(context: CoroutineContext) {
+        try {
+            val channel = Channel<Int>()
+            channel.close(RecoverableTestException())
+            doFastPath(context, channel)
+        } catch (e: Throwable) {
+            verifyStackTrace("resume-mode/${testName.methodName}", e)
+        }
+    }
+
+    private suspend fun doFastPath(context: CoroutineContext, channel: Channel<Int>) {
+        yield()
+        withContext(context, channel)
+    }
+
+    private suspend fun withContext(context: CoroutineContext, channel: Channel<Int>) {
+        withContext(context) {
+            channel.receive()
+            yield()
+        }
+    }
+
+    @Test
+    fun testUnconfinedSuspending() = runTest {
+        testResumeModeSuspending(Dispatchers.Unconfined)
+    }
+
+    @Test
+    fun testNestedUnconfinedSuspending() = runTest {
+        withContext(Dispatchers.Unconfined) {
+            testResumeModeSuspending(Dispatchers.Unconfined)
+        }
+    }
+
+    @Test
+    fun testNestedUnconfinedChangedContextSuspending() = runTest {
+        withContext(Dispatchers.Unconfined) {
+            testResumeModeSuspending(CoroutineName("Test"))
+        }
+    }
+
+    @Test
+    fun testEventLoopDispatcherSuspending() = runTest {
+        testResumeModeSuspending(wrapperDispatcher())
+    }
+
+    @Test
+    fun testNestedEventLoopDispatcherSuspending() = runTest {
+        val dispatcher = wrapperDispatcher()
+        withContext(dispatcher) {
+            testResumeModeSuspending(dispatcher)
+        }
+    }
+
+    @Test
+    fun testNestedEventLoopChangedContextSuspending() = runTest {
+        withContext(wrapperDispatcher()) {
+            testResumeModeSuspending(CoroutineName("Test"))
+        }
+    }
+
+    private suspend fun testResumeModeSuspending(context: CoroutineContext) {
+        try {
+            val channel = Channel<Int>()
+            val latch = Channel<Int>()
+            GlobalScope.launch(coroutineContext) {
+                latch.receive()
+                expect(3)
+                channel.close(RecoverableTestException())
+            }
+            doSuspendingPath(context, channel, latch)
+        } catch (e: Throwable) {
+            finish(4)
+            verifyStackTrace("resume-mode/${testName.methodName}", e)
+        }
+    }
+
+    private suspend fun doSuspendingPath(context: CoroutineContext, channel: Channel<Int>, latch: Channel<Int>) {
+        yield()
+        withContext(context, channel, latch)
+    }
+
+    private suspend fun withContext(context: CoroutineContext, channel: Channel<Int>, latch: Channel<Int>) {
+        withContext(context) {
+            expect(1)
+            latch.send(1)
+            expect(2)
+            channel.receive()
+            yield()
+        }
+    }
+}
\ No newline at end of file
diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryTest.kt
index 0f87960..3cddee5 100644
--- a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryTest.kt
+++ b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryTest.kt
@@ -8,7 +8,9 @@
 import kotlinx.coroutines.channels.*
 import kotlinx.coroutines.intrinsics.*
 import kotlinx.coroutines.selects.*
+import org.junit.*
 import org.junit.Test
+import org.junit.rules.*
 import java.util.concurrent.*
 import kotlin.concurrent.*
 import kotlin.coroutines.*
@@ -85,55 +87,6 @@
     }
 
     @Test
-    fun testReceiveFromChannel() = runTest {
-        val channel = Channel<Int>()
-        val job = launch {
-            expect(2)
-            channel.close(IllegalArgumentException())
-        }
-
-        expect(1)
-        channelNestedMethod(
-            channel,
-                "java.lang.IllegalArgumentException\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromChannel\$1\$job\$1.invokeSuspend(StackTraceRecoveryTest.kt:93)\n" +
-                        "\t(Coroutine boundary)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.channelNestedMethod(StackTraceRecoveryTest.kt:110)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromChannel\$1.invokeSuspend(StackTraceRecoveryTest.kt:89)",
-                "Caused by: java.lang.IllegalArgumentException\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromChannel\$1\$job\$1.invokeSuspend(StackTraceRecoveryTest.kt:93)\n" +
-                        "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n")
-        expect(3)
-        job.join()
-        finish(4)
-    }
-
-    @Test
-    fun testReceiveFromClosedChannel() = runTest {
-        val channel = Channel<Int>()
-        channel.close(IllegalArgumentException())
-        channelNestedMethod(
-            channel,
-                "java.lang.IllegalArgumentException\n" +
-                        "\t(Coroutine boundary)\n" +
-                        "\tat kotlinx.coroutines.channels.AbstractChannel.receiveResult(AbstractChannel.kt:574)\n" +
-                        "\tat kotlinx.coroutines.channels.AbstractChannel.receive(AbstractChannel.kt:567)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.channelNestedMethod(StackTraceRecoveryTest.kt:117)\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromClosedChannel\$1.invokeSuspend(StackTraceRecoveryTest.kt:111)\n",
-                "Caused by: java.lang.IllegalArgumentException\n" +
-                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromClosedChannel\$1.invokeSuspend(StackTraceRecoveryTest.kt:110)")
-    }
-
-    private suspend fun channelNestedMethod(channel: Channel<Int>, vararg traces: String) {
-        try {
-            channel.receive()
-            expectUnreached()
-        } catch (e: IllegalArgumentException) {
-            verifyStackTrace(e, *traces)
-        }
-    }
-
-    @Test
     fun testWithContext() = runTest {
         val deferred = async<Unit>(NonCancellable, start = CoroutineStart.LAZY) {
             throw RecoverableTestException()
@@ -312,4 +265,32 @@
                 "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testNonDispatchedRecovery\$await\$1.invokeSuspend(StackTraceRecoveryTest.kt:291)\n" +
                 "Caused by: kotlinx.coroutines.RecoverableTestException")
     }
+
+    private class Callback(val cont: CancellableContinuation<*>)
+
+    @Test
+    fun testCancellableContinuation() = runTest {
+        val channel = Channel<Callback>(1)
+        launch {
+            try {
+                awaitCallback(channel)
+            } catch (e: Throwable) {
+                verifyStackTrace(e, "kotlinx.coroutines.RecoverableTestException\n" +
+                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCancellableContinuation\$1.invokeSuspend(StackTraceRecoveryTest.kt:329)\n" +
+                        "\t(Coroutine boundary)\n" +
+                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.awaitCallback(StackTraceRecoveryTest.kt:348)\n" +
+                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCancellableContinuation\$1\$1.invokeSuspend(StackTraceRecoveryTest.kt:322)\n" +
+                        "Caused by: kotlinx.coroutines.RecoverableTestException\n" +
+                        "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCancellableContinuation\$1.invokeSuspend(StackTraceRecoveryTest.kt:329)")
+            }
+        }
+        val callback = channel.receive()
+        callback.cont.resumeWithException(RecoverableTestException())
+    }
+
+    private suspend fun awaitCallback(channel: Channel<Callback>) {
+        suspendCancellableCoroutine<Unit> { cont ->
+            channel.offer(Callback(cont))
+        }
+    }
 }
diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/Stacktraces.kt b/kotlinx-coroutines-core/jvm/test/exceptions/Stacktraces.kt
index 1588433..40c6930 100644
--- a/kotlinx-coroutines-core/jvm/test/exceptions/Stacktraces.kt
+++ b/kotlinx-coroutines-core/jvm/test/exceptions/Stacktraces.kt
@@ -1,5 +1,6 @@
 package kotlinx.coroutines.exceptions
 
+import kotlinx.coroutines.*
 import java.io.*
 import kotlin.test.*
 
@@ -19,6 +20,12 @@
     assertEquals(traces.map { it.count("Caused by") }.sum(), causes)
 }
 
+public fun verifyStackTrace(path: String, e: Throwable) {
+    val resource = Job.javaClass.classLoader.getResourceAsStream("stacktraces/$path.txt")
+    val lines = resource.reader().readLines()
+    verifyStackTrace(e, *lines.toTypedArray())
+}
+
 public fun toStackTrace(t: Throwable): String {
     val sw = StringWriter() as Writer
     t.printStackTrace(PrintWriter(sw))