Structured concurrency for guava, jdk8 and promise modules, proper reference to newCoroutineContext
diff --git a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt
index 0080665..0a7848f 100644
--- a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt
+++ b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt
@@ -144,6 +144,7 @@
 	public static final fun getIO ()Lkotlinx/coroutines/experimental/CoroutineDispatcher;
 	public static final fun newCoroutineContext (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
 	public static final fun newCoroutineContext (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/Job;)Lkotlin/coroutines/experimental/CoroutineContext;
+	public static final fun newCoroutineContext (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
 	public static synthetic fun newCoroutineContext$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/Job;ILjava/lang/Object;)Lkotlin/coroutines/experimental/CoroutineContext;
 }
 
diff --git a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt
index 02056de..efb5ce2 100644
--- a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt
+++ b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-guava.txt
@@ -1,11 +1,15 @@
 public final class kotlinx/coroutines/experimental/guava/ListenableFutureKt {
 	public static final fun asListenableFuture (Lkotlinx/coroutines/experimental/Deferred;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static final fun await (Lcom/google/common/util/concurrent/ListenableFuture;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
+	public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
+	public static final fun future (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lcom/google/common/util/concurrent/ListenableFuture;
+	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
+	public static synthetic fun future$default (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture;
 }
 
diff --git a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt
index c2c5c4b..94fb357 100644
--- a/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt
+++ b/binary-compatibility-validator/reference-public-api/kotlinx-coroutines-jdk8.txt
@@ -11,13 +11,17 @@
 	public static final synthetic fun await (Ljava/util/concurrent/CompletableFuture;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
 	public static final fun await (Ljava/util/concurrent/CompletionStage;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
 	public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/jvm/functions/Function1;)Ljava/util/concurrent/CompletableFuture;
+	public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
 	public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
 	public static final fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
 	public static final synthetic fun future (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
+	public static final fun future (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
+	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
 	public static synthetic fun future$default (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlinx/coroutines/experimental/Job;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
+	public static synthetic fun future$default (Lkotlinx/coroutines/experimental/CoroutineScope;Lkotlin/coroutines/experimental/CoroutineContext;Lkotlinx/coroutines/experimental/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
 	public static final fun toCompletableFuture (Lkotlinx/coroutines/experimental/Deferred;)Ljava/util/concurrent/CompletableFuture;
 }
 
diff --git a/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt b/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt
index f952c8d..4cac79c 100644
--- a/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt
+++ b/common/kotlinx-coroutines-core-common/src/CoroutineContext.common.kt
@@ -6,7 +6,7 @@
 
 import kotlin.coroutines.experimental.*
 
-public expect fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext
+public expect fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext
 
 @Suppress("PropertyName")
 public expect val DefaultDispatcher: CoroutineDispatcher
diff --git a/common/kotlinx-coroutines-core-common/src/Deferred.kt b/common/kotlinx-coroutines-core-common/src/Deferred.kt
index c7b8fe1..3266540 100644
--- a/common/kotlinx-coroutines-core-common/src/Deferred.kt
+++ b/common/kotlinx-coroutines-core-common/src/Deferred.kt
@@ -125,9 +125,7 @@
 
 /**
  * Creates new coroutine and returns its future result as an implementation of [Deferred].
- *
  * The running coroutine is cancelled when the resulting deferred is [cancelled][Job.cancel].
- * Parent of the created coroutine is inherited from the provided [CoroutineScope].
  *
  * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
  * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [DefaultDispatcher] is used.
diff --git a/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt b/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt
index 0f6b418..009cccc 100644
--- a/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt
+++ b/common/kotlinx-coroutines-core-common/src/channels/Broadcast.kt
@@ -7,7 +7,6 @@
 import kotlinx.coroutines.experimental.*
 import kotlinx.coroutines.experimental.channels.Channel.Factory.CONFLATED
 import kotlinx.coroutines.experimental.channels.Channel.Factory.UNLIMITED
-import kotlinx.coroutines.experimental.internal.*
 import kotlinx.coroutines.experimental.intrinsics.*
 import kotlin.coroutines.experimental.*
 
@@ -21,7 +20,7 @@
     capacity: Int = 1,
     start: CoroutineStart = CoroutineStart.LAZY
 ) : BroadcastChannel<E> =
-    broadcast(Unconfined, capacity = capacity, start = start, onCompletion = consumes()) {
+    GlobalScope.broadcast(Unconfined, capacity = capacity, start = start, onCompletion = consumes()) {
         for (e in this@broadcast) {
             send(e)
         }
@@ -29,9 +28,13 @@
 
 /**
  * Launches new coroutine to produce a stream of values by sending them to a broadcast channel.
- * Deprecated, use [CoroutineScope.broadcast] instead.
+ * @suppress **Deprecated**: use [CoroutineScope.broadcast] instead.
  */
-@Deprecated(message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead. This API will be hidden in the next release")
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.broadcast(context + parent, capacity, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.channels.broadcast"])
+)
 public fun <E> broadcast(
     context: CoroutineContext = DefaultDispatcher,
     capacity: Int = 1,
@@ -39,16 +42,8 @@
     parent: Job? = null,
     onCompletion: CompletionHandler? = null,
     block: suspend ProducerScope<E>.() -> Unit
-): BroadcastChannel<E> {
-    val channel = BroadcastChannel<E>(capacity)
-    val newContext = newCoroutineContext(context, parent)
-    val coroutine = if (start.isLazy)
-        LazyBroadcastCoroutine(newContext, channel, block) else
-        BroadcastCoroutine(newContext, channel, active = true)
-    if (onCompletion != null) coroutine.invokeOnCompletion(handler = onCompletion)
-    coroutine.start(start, coroutine, block)
-    return coroutine
-}
+): BroadcastChannel<E> =
+    GlobalScope.broadcast(context + (parent ?: DefaultDispatcher), capacity, start, onCompletion, block)
 
 /**
  * Launches new coroutine to produce a stream of values by sending them to a broadcast channel
diff --git a/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt b/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt
index ee51615..e2e7475 100644
--- a/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt
+++ b/common/kotlinx-coroutines-core-common/src/internal/Scopes.kt
@@ -25,6 +25,3 @@
 internal class ContextScope(context: CoroutineContext) : CoroutineScope {
     override val coroutineContext: CoroutineContext = context
 }
-
-internal fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext =
-    newCoroutineContext(coroutineContext + context, parent = null)
diff --git a/core/kotlinx-coroutines-core/src/Builders.kt b/core/kotlinx-coroutines-core/src/Builders.kt
index 8002100..43521c2 100644
--- a/core/kotlinx-coroutines-core/src/Builders.kt
+++ b/core/kotlinx-coroutines-core/src/Builders.kt
@@ -27,7 +27,7 @@
  * If this blocked thread is interrupted (see [Thread.interrupt]), then the coroutine job is cancelled and
  * this `runBlocking` invocation throws [InterruptedException].
  *
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
  *
  * @param context context of the coroutine. The default value is an implementation of [EventLoop].
  * @param block the coroutine code.
@@ -38,7 +38,7 @@
     val contextInterceptor = context[ContinuationInterceptor]
     val privateEventLoop = contextInterceptor == null // create private event loop if no dispatcher is specified
     val eventLoop = if (privateEventLoop) BlockingEventLoop(currentThread) else contextInterceptor as? EventLoop
-    val newContext = newCoroutineContext(
+    val newContext = GlobalScope.newCoroutineContext(
         if (privateEventLoop) context + (eventLoop as ContinuationInterceptor) else context
     )
     val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop, privateEventLoop)
diff --git a/core/kotlinx-coroutines-core/src/CoroutineContext.kt b/core/kotlinx-coroutines-core/src/CoroutineContext.kt
index b46e856..853ccfd 100644
--- a/core/kotlinx-coroutines-core/src/CoroutineContext.kt
+++ b/core/kotlinx-coroutines-core/src/CoroutineContext.kt
@@ -10,22 +10,22 @@
 import kotlin.coroutines.experimental.*
 
 /**
- * Name of the property that controls coroutine debugging. See [newCoroutineContext].
+ * Name of the property that controls coroutine debugging. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
  */
 public const val DEBUG_PROPERTY_NAME = "kotlinx.coroutines.debug"
 
 /**
- * Automatic debug configuration value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
+ * Automatic debug configuration value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
  */
 public const val DEBUG_PROPERTY_VALUE_AUTO = "auto"
 
 /**
- * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
+ * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
  */
 public const val DEBUG_PROPERTY_VALUE_ON = "on"
 
 /**
- * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext].
+ * Debug turned on value for [DEBUG_PROPERTY_NAME]. See [newCoroutineContext][CoroutineScope.newCoroutineContext].
  */
 public const val DEBUG_PROPERTY_VALUE_OFF = "off"
 
@@ -106,14 +106,24 @@
  * Coroutine name can be explicitly assigned using [CoroutineName] context element.
  * The string "coroutine" is used as a default name.
  */
+public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
+    val combined = coroutineContext + context
+    val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined
+    return if (combined !== DefaultDispatcher && combined[ContinuationInterceptor] == null)
+        debug + DefaultDispatcher else debug
+}
+
+/**
+ * @suppress **Deprecated**: Use extension on CoroutineScope.
+ */
 @JvmOverloads // for binary compatibility with newCoroutineContext(context: CoroutineContext) version
 @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
-public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
-    val debug = if (DEBUG) context + CoroutineId(COROUTINE_ID.incrementAndGet()) else context
-    val wp = if (parent == null) debug else debug + parent
-    return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
-        wp + DefaultDispatcher else wp
-}
+@Deprecated(
+    message = "Use extension on CoroutineScope",
+    replaceWith = ReplaceWith("GlobalScope.newCoroutineContext(context + parent)")
+)
+public fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext =
+    GlobalScope.newCoroutineContext(context + (parent ?: EmptyCoroutineContext))
 
 /**
  * Executes a block using a given coroutine context.
diff --git a/core/kotlinx-coroutines-core/src/CoroutineName.kt b/core/kotlinx-coroutines-core/src/CoroutineName.kt
index 0430d65..8f8131e 100644
--- a/core/kotlinx-coroutines-core/src/CoroutineName.kt
+++ b/core/kotlinx-coroutines-core/src/CoroutineName.kt
@@ -9,7 +9,7 @@
 
 /**
  * User-specified name of coroutine. This name is used in debugging mode.
- * See [newCoroutineContext] for the description of coroutine debugging facilities.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for the description of coroutine debugging facilities.
  */
 public data class CoroutineName(
     /**
diff --git a/core/kotlinx-coroutines-core/src/channels/Actor.kt b/core/kotlinx-coroutines-core/src/channels/Actor.kt
index cf01902..115ae03 100644
--- a/core/kotlinx-coroutines-core/src/channels/Actor.kt
+++ b/core/kotlinx-coroutines-core/src/channels/Actor.kt
@@ -65,7 +65,7 @@
  * * when `capacity` is positive, but less than [UNLIMITED] -- uses [ArrayChannel] with a buffer of the specified `capacity`;
  * * otherwise -- throws [IllegalArgumentException].
  *
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
  *
  * ### Using actors
  *
diff --git a/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt b/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt
index 984014a..29eb8ca 100644
--- a/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt
+++ b/integration/kotlinx-coroutines-guava/src/ListenableFuture.kt
@@ -11,17 +11,12 @@
 
 /**
  * Starts new coroutine and returns its results an an implementation of [ListenableFuture].
- * This coroutine builder uses [DefaultDispatcher] context by default.
- *
  * The running coroutine is cancelled when the resulting future is cancelled or otherwise completed.
  *
- * The [context] for the new coroutine can be explicitly specified.
- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
- * The [coroutineContext] of the parent coroutine may be used,
- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
- * The parent job may be also explicitly specified using [parent] parameter.
- *
+ * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
  * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [DefaultDispatcher] is used.
+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
+ * with corresponding [coroutineContext] element.
  *
  * By default, the coroutine is immediately scheduled for execution.
  * Other options can be specified via `start` parameter. See [CoroutineStart] for details.
@@ -29,7 +24,7 @@
  * (since `ListenableFuture` framework does not provide the corresponding capability) and
  * produces [IllegalArgumentException].
  *
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
  *
  * @param context context of the coroutine. The default value is [DefaultDispatcher].
  * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
@@ -37,15 +32,14 @@
  * @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
  * @param block the coroutine code.
  */
-public fun <T> future(
+public fun <T> CoroutineScope.future(
     context: CoroutineContext = DefaultDispatcher,
     start: CoroutineStart = CoroutineStart.DEFAULT,
-    parent: Job? = null,
     onCompletion: CompletionHandler? = null,
     block: suspend CoroutineScope.() -> T
 ): ListenableFuture<T> {
     require(!start.isLazy) { "$start start is not supported" }
-    val newContext = newCoroutineContext(context, parent)
+    val newContext = newCoroutineContext(context)
     val job = Job(newContext[Job])
     val future = ListenableFutureCoroutine<T>(newContext + job)
     job.cancelFutureOnCompletion(future)
@@ -54,6 +48,41 @@
     return future
 }
 
+/**
+ * Starts new coroutine and returns its results an an implementation of [ListenableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.future(context, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+    context: CoroutineContext = DefaultDispatcher,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    onCompletion: CompletionHandler? = null,
+    block: suspend CoroutineScope.() -> T
+): ListenableFuture<T> =
+    GlobalScope.future(context, start, onCompletion, block)
+
+/**
+ * Starts new coroutine and returns its results an an implementation of [ListenableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.future(context + parent, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+    context: CoroutineContext = DefaultDispatcher,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    parent: Job? = null,
+    onCompletion: CompletionHandler? = null,
+    block: suspend CoroutineScope.() -> T
+): ListenableFuture<T> =
+    GlobalScope.future(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block)
+
 /** @suppress **Deprecated**: Binary compatibility */
 @Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
 public fun <T> future(
@@ -61,7 +90,8 @@
     start: CoroutineStart = CoroutineStart.DEFAULT,
     parent: Job? = null,
     block: suspend CoroutineScope.() -> T
-): ListenableFuture<T> = future(context, start, parent, block = block)
+): ListenableFuture<T> =
+    GlobalScope.future(context + (parent ?: EmptyCoroutineContext), start, block = block)
 
 /** @suppress **Deprecated**: Binary compatibility */
 @Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
@@ -70,7 +100,7 @@
     start: CoroutineStart = CoroutineStart.DEFAULT,
     block: suspend CoroutineScope.() -> T
 ): ListenableFuture<T> =
-    future(context, start, block = block)
+    GlobalScope.future(context, start, block = block)
 
 private class ListenableFutureCoroutine<T>(
     override val context: CoroutineContext
@@ -108,7 +138,7 @@
  *
  * This suspending function is cancellable.
  * If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
- * stops waiting for the future and immediately resumes with [CancellationException].
+ * stops waiting for the future and immediately resumes with [CancellationException][kotlinx.coroutines.experimental.CancellationException].
  *
  * Note, that `ListenableFuture` does not support removal of installed listeners, so on cancellation of this wait
  * a few small objects will remain in the `ListenableFuture` list of listeners until the future completes. However, the
diff --git a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
index c1dc20c..25f19f3 100644
--- a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
+++ b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
@@ -22,7 +22,7 @@
     @Test
     fun testSimpleAwait() {
         val service = MoreExecutors.listeningDecorator(ForkJoinPool.commonPool())
-        val future = future {
+        val future = GlobalScope.future {
             service.submit(Callable<String> {
                 "O"
             }).await() + "K"
@@ -33,7 +33,7 @@
     @Test
     fun testAwaitWithContext() = runTest {
         val future = SettableFuture.create<Int>()
-        val deferred = async(coroutineContext) {
+        val deferred = async {
             withContext(DefaultDispatcher) {
                 future.await()
             }
@@ -46,7 +46,7 @@
     @Test
     fun testAwaitWithContextCancellation() = runTest(expected = {it is IOException}) {
         val future = SettableFuture.create<Int>()
-        val deferred = async(coroutineContext) {
+        val deferred = async {
             withContext(DefaultDispatcher) {
                 future.await()
             }
@@ -60,7 +60,7 @@
     fun testCompletedFuture() {
         val toAwait = SettableFuture.create<String>()
         toAwait.set("O")
-        val future = future {
+        val future = GlobalScope.future {
             toAwait.await() + "K"
         }
         assertThat(future.get(), IsEqual("OK"))
@@ -69,7 +69,7 @@
     @Test
     fun testWaitForFuture() {
         val toAwait = SettableFuture.create<String>()
-        val future = future {
+        val future = GlobalScope.future {
             toAwait.await() + "K"
         }
         assertFalse(future.isDone)
@@ -81,7 +81,7 @@
     fun testCompletedFutureExceptionally() {
         val toAwait = SettableFuture.create<String>()
         toAwait.setException(IllegalArgumentException("O"))
-        val future = future<String> {
+        val future = GlobalScope.future {
             try {
                 toAwait.await()
             } catch (e: RuntimeException) {
@@ -95,7 +95,7 @@
     @Test
     fun testWaitForFutureWithException() {
         val toAwait = SettableFuture.create<String>()
-        val future = future<String> {
+        val future = GlobalScope.future {
             try {
                 toAwait.await()
             } catch (e: RuntimeException) {
@@ -111,7 +111,7 @@
     @Test
     fun testExceptionInsideCoroutine() {
         val service = MoreExecutors.listeningDecorator(ForkJoinPool.commonPool())
-        val future = future {
+        val future = GlobalScope.future {
             if (service.submit(Callable<Boolean> { true }).await()) {
                 throw IllegalStateException("OK")
             }
diff --git a/integration/kotlinx-coroutines-jdk8/src/future/Future.kt b/integration/kotlinx-coroutines-jdk8/src/future/Future.kt
index 54233e4..0250d4f 100644
--- a/integration/kotlinx-coroutines-jdk8/src/future/Future.kt
+++ b/integration/kotlinx-coroutines-jdk8/src/future/Future.kt
@@ -11,18 +11,13 @@
 
 /**
  * Starts new coroutine and returns its result as an implementation of [CompletableFuture].
- * This coroutine builder uses [DefaultDispatcher] context by default and is conceptually similar to [CompletableFuture.supplyAsync].
  *
  * The running coroutine is cancelled when the resulting future is cancelled or otherwise completed.
  *
- * The [context] for the new coroutine can be explicitly specified.
- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
- * The [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/coroutine-context.html)
- * of the parent coroutine may be used,
- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
- * The parent job may be also explicitly specified using [parent] parameter.
- *
+ * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
  * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [DefaultDispatcher] is used.
+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
+ * with corresponding [coroutineContext] element.
  *
  * By default, the coroutine is immediately scheduled for execution.
  * Other options can be specified via `start` parameter. See [CoroutineStart] for details.
@@ -30,23 +25,21 @@
  * (since `CompletableFuture` framework does not provide the corresponding capability) and
  * produces [IllegalArgumentException].
  *
- * See [newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
+ * See [newCoroutineContext][CoroutineScope.newCoroutineContext] for a description of debugging facilities that are available for newly created coroutine.
  *
  * @param context context of the coroutine. The default value is [DefaultDispatcher].
  * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
- * @param parent explicitly specifies the parent job, overrides job from the [context] (if any).
  * @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
  * @param block the coroutine code.
  */
-public fun <T> future(
+public fun <T> CoroutineScope.future(
     context: CoroutineContext = DefaultDispatcher,
     start: CoroutineStart = CoroutineStart.DEFAULT,
-    parent: Job? = null,
     onCompletion: CompletionHandler? = null,
     block: suspend CoroutineScope.() -> T
 ): CompletableFuture<T> {
     require(!start.isLazy) { "$start start is not supported" }
-    val newContext = newCoroutineContext(context, parent)
+    val newContext = this.newCoroutineContext(context)
     val job = Job(newContext[Job])
     val future = CompletableFutureCoroutine<T>(newContext + job)
     job.cancelFutureOnCompletion(future)
@@ -56,6 +49,41 @@
     return future
 }
 
+/**
+ * Starts new coroutine and returns its result as an implementation of [CompletableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.future(context, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+    context: CoroutineContext = DefaultDispatcher,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    onCompletion: CompletionHandler? = null,
+    block: suspend CoroutineScope.() -> T
+): CompletableFuture<T> =
+    GlobalScope.future(context, start, onCompletion, block)
+
+/**
+ * Starts new coroutine and returns its result as an implementation of [CompletableFuture].
+ * @suppress **Deprecated**. Use [CoroutineScope.future] instead.
+ */
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.future(context + parent, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.GlobalScope", "kotlinx.coroutines.experimental.future.future"])
+)
+public fun <T> future(
+    context: CoroutineContext = DefaultDispatcher,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    parent: Job? = null,
+    onCompletion: CompletionHandler? = null,
+    block: suspend CoroutineScope.() -> T
+): CompletableFuture<T> =
+    GlobalScope.future(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block)
+
 /** @suppress **Deprecated**: Binary compatibility */
 @Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
 public fun <T> future(
@@ -72,7 +100,7 @@
     start: CoroutineStart = CoroutineStart.DEFAULT,
     block: suspend CoroutineScope.() -> T
 ): CompletableFuture<T> =
-    future(context, start, block = block)
+    GlobalScope.future(context, start, block = block)
 
 private class CompletableFutureCoroutine<T>(
     override val context: CoroutineContext
@@ -205,4 +233,5 @@
 public fun <T> future(
     context: CoroutineContext = DefaultDispatcher,
     block: suspend () -> T
-): CompletableFuture<T> = future(context = context) { block() }
+): CompletableFuture<T> =
+    GlobalScope.future(context = context, block = { block() })
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt b/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt
index b5c01e6..c8617f3 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/CancelFuture-example.kt
@@ -4,12 +4,12 @@
 
 package kotlinx.coroutines.experimental.examples
 
-import kotlinx.coroutines.experimental.delay
-import kotlinx.coroutines.experimental.future.future
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
 
 
 fun main(args: Array<String>) {
-    val f = future {
+    val f = GlobalScope.future {
         try {
             log("Started f")
             delay(500)
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt b/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt
index 4112665..789b136 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/ExplicitJob-example.kt
@@ -4,20 +4,19 @@
 
 package kotlinx.coroutines.experimental.examples
 
-import kotlinx.coroutines.experimental.Job
-import kotlinx.coroutines.experimental.delay
-import kotlinx.coroutines.experimental.future.future
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
 import java.util.concurrent.CancellationException
 
 fun main(args: Array<String>) {
     val job = Job()
     log("Starting futures f && g")
-    val f = future(job) {
+    val f = GlobalScope.future(job) {
         log("Started f")
         delay(500)
         log("f should not execute this line")
     }
-    val g = future(job) {
+    val g = GlobalScope.future(job) {
         log("Started g")
         try {
             delay(500)
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt
index e2608bb..9de9798 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-2.kt
@@ -4,13 +4,12 @@
 
 package kotlinx.coroutines.experimental.examples
 
-import kotlinx.coroutines.experimental.delay
-import kotlinx.coroutines.experimental.future.future
-import java.util.concurrent.CompletableFuture
-import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
+import java.util.concurrent.*
 
 // this function returns a CompletableFuture using Kotlin coroutines
-fun supplyTheAnswerAsync(): CompletableFuture<Int> = future {
+fun supplyTheAnswerAsync(): CompletableFuture<Int> = GlobalScope.future {
     println("We might be doing some asynchronous IO here or something else...")
     delay(1, TimeUnit.SECONDS) // just do a non-blocking delay
     42 // The answer!
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt
index ee09a87..cd683aa 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/simple-example-3.kt
@@ -4,13 +4,13 @@
 
 package kotlinx.coroutines.experimental.examples
 
-import kotlinx.coroutines.experimental.future.await
-import kotlinx.coroutines.experimental.future.future
-import java.util.concurrent.CompletableFuture
+import kotlinx.coroutines.experimental.*
+import kotlinx.coroutines.experimental.future.*
+import java.util.concurrent.*
 
 fun main(args: Array<String>) {
     // this example shows how easy it is to perform multiple async operations with coroutines
-    val future = future {
+    val future = GlobalScope.future {
         (1..5).map { // loops are no problem at all
             startLongAsyncOperation(it).await() // suspend while the long method is running
         }.joinToString("\n")
diff --git a/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt b/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt
index 0d79637..332e34c 100644
--- a/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/examples/withTimeout-example.kt
@@ -8,11 +8,11 @@
 import kotlinx.coroutines.experimental.future.*
 
 fun main(args: Array<String>) {
-    fun slow(s: String) = future {
+    fun slow(s: String) = GlobalScope.future {
         delay(500L)
         s
     }
-    val f = future<String> {
+    val f = GlobalScope.future {
         log("Started f")
         val a = slow("A").await()
         log("a = $a")
diff --git a/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt b/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt
index dac314c..1c403d1 100644
--- a/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt
+++ b/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt
@@ -24,7 +24,7 @@
 
     @Test
     fun testSimpleAwait() {
-        val future = future {
+        val future = GlobalScope.future {
             CompletableFuture.supplyAsync {
                 "O"
             }.await() + "K"
@@ -36,7 +36,7 @@
     fun testCompletedFuture() {
         val toAwait = CompletableFuture<String>()
         toAwait.complete("O")
-        val future = future {
+        val future = GlobalScope.future {
             toAwait.await() + "K"
         }
         assertThat(future.get(), IsEqual("OK"))
@@ -47,7 +47,7 @@
         val completable = CompletableFuture<String>()
         completable.complete("O")
         val toAwait: CompletionStage<String> = completable
-        val future = future {
+        val future = GlobalScope.future {
             toAwait.await() + "K"
         }
         assertThat(future.get(), IsEqual("OK"))
@@ -56,7 +56,7 @@
     @Test
     fun testWaitForFuture() {
         val toAwait = CompletableFuture<String>()
-        val future = future {
+        val future = GlobalScope.future {
             toAwait.await() + "K"
         }
         assertFalse(future.isDone)
@@ -68,7 +68,7 @@
     fun testWaitForCompletionStage() {
         val completable = CompletableFuture<String>()
         val toAwait: CompletionStage<String> = completable
-        val future = future {
+        val future = GlobalScope.future {
             toAwait.await() + "K"
         }
         assertFalse(future.isDone)
@@ -80,7 +80,7 @@
     fun testCompletedFutureExceptionally() {
         val toAwait = CompletableFuture<String>()
         toAwait.completeExceptionally(TestException("O"))
-        val future = future {
+        val future = GlobalScope.future {
             try {
                 toAwait.await()
             } catch (e: TestException) {
@@ -96,7 +96,7 @@
         val completable = CompletableFuture<String>()
         val toAwait: CompletionStage<String> = completable
         completable.completeExceptionally(TestException("O"))
-        val future = future {
+        val future = GlobalScope.future {
             try {
                 toAwait.await()
             } catch (e: TestException) {
@@ -132,7 +132,7 @@
     fun testWaitForCompletionStageWithException() {
         val completable = CompletableFuture<String>()
         val toAwait: CompletionStage<String> = completable
-        val future = future {
+        val future = GlobalScope.future {
             try {
                 toAwait.await()
             } catch (e: TestException) {
@@ -146,7 +146,7 @@
 
     @Test
     fun testExceptionInsideCoroutine() {
-        val future = future {
+        val future = GlobalScope.future {
             if (CompletableFuture.supplyAsync { true }.await()) {
                 throw IllegalStateException("OK")
             }
@@ -226,7 +226,7 @@
     @Test
     fun testContinuationWrapped() {
         val depth = AtomicInteger()
-        val future = future(wrapContinuation {
+        val future = GlobalScope.future(wrapContinuation {
             depth.andIncrement
             it()
             depth.andDecrement
diff --git a/integration/kotlinx-coroutines-quasar/src/Quasar.kt b/integration/kotlinx-coroutines-quasar/src/Quasar.kt
index 7dd693e..182d799 100644
--- a/integration/kotlinx-coroutines-quasar/src/Quasar.kt
+++ b/integration/kotlinx-coroutines-quasar/src/Quasar.kt
@@ -44,7 +44,7 @@
     private val block: suspend () -> T
 ) : FiberAsync<T, Throwable>(), Continuation<T> {
     override val context: CoroutineContext =
-        newCoroutineContext(Fiber.currentFiber().scheduler.executor.asCoroutineDispatcher())
+        GlobalScope.newCoroutineContext(Fiber.currentFiber().scheduler.executor.asCoroutineDispatcher())
     override fun resume(value: T) { asyncCompleted(value) }
     override fun resumeWithException(exception: Throwable) { asyncFailed(exception) }
 
diff --git a/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt b/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
index 2b6bf4b..bc065c0 100644
--- a/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
+++ b/js/kotlinx-coroutines-core-js/src/CoroutineContext.kt
@@ -27,15 +27,10 @@
 
 internal actual val DefaultDelay: Delay = DefaultDispatcher as Delay
 
-/**
- * Creates context for the new coroutine. It installs [DefaultDispatcher] when no other dispatcher nor
- * [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on).
- */
-@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
-public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
-    val wp = if (parent == null) context else context + parent
-    return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
-        wp + DefaultDispatcher else wp
+public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
+    val combined = coroutineContext + context
+    return if (combined !== DefaultDispatcher && combined[ContinuationInterceptor] == null)
+        combined + DefaultDispatcher else combined
 }
 
 // No debugging facilities on JS
diff --git a/js/kotlinx-coroutines-core-js/src/Promise.kt b/js/kotlinx-coroutines-core-js/src/Promise.kt
index 11e84f4..4452a2a 100644
--- a/js/kotlinx-coroutines-core-js/src/Promise.kt
+++ b/js/kotlinx-coroutines-core-js/src/Promise.kt
@@ -10,24 +10,53 @@
 /**
  * Starts new coroutine and returns its result as an implementation of [Promise].
  *
- * The [context] for the new coroutine can be explicitly specified.
- * See [CoroutineDispatcher] for the standard context implementations that are provided by `kotlinx.coroutines`.
- * The [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/coroutine-context.html)
- * of the parent coroutine may be used,
- * in which case the [Job] of the resulting coroutine is a child of the job of the parent coroutine.
- * The parent job may be also explicitly specified using [parent] parameter.
- *
+ * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
  * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [DefaultDispatcher] is used.
+ * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
+ * with corresponding [coroutineContext] element.
  *
  * By default, the coroutine is immediately scheduled for execution.
  * Other options can be specified via `start` parameter. See [CoroutineStart] for details.
  *
  * @param context context of the coroutine. The default value is [DefaultDispatcher].
  * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
- * @param parent explicitly specifies the parent job, overrides job from the [context] (if any).
  * @param onCompletion optional completion handler for the coroutine (see [Job.invokeOnCompletion]).
  * @param block the coroutine code.
  */
+public fun <T> CoroutineScope.promise(
+    context: CoroutineContext = DefaultDispatcher,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    onCompletion: CompletionHandler? = null,
+    block: suspend CoroutineScope.() -> T
+): Promise<T> =
+    async(context, start, onCompletion, block = block).asPromise()
+
+/**
+ * Starts new coroutine and returns its result as an implementation of [Promise].
+ * @suppress **Deprecated**. Use [CoroutineScope.promise] instead.
+ */
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.promise(context + parent, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.*"])
+)
+public fun <T> promise(
+    context: CoroutineContext = DefaultDispatcher,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    onCompletion: CompletionHandler? = null,
+    block: suspend CoroutineScope.() -> T
+): Promise<T> =
+    GlobalScope.promise(context, start, onCompletion, block = block)
+
+/**
+ * Starts new coroutine and returns its result as an implementation of [Promise].
+ * @suppress **Deprecated**. Use [CoroutineScope.promise] instead.
+ */
+@Deprecated(
+    message = "Standalone coroutine builders are deprecated, use extensions on CoroutineScope instead",
+    replaceWith = ReplaceWith("GlobalScope.promise(context + parent, start, onCompletion, block)",
+        imports = ["kotlinx.coroutines.experimental.*"])
+)
 public fun <T> promise(
     context: CoroutineContext = DefaultDispatcher,
     start: CoroutineStart = CoroutineStart.DEFAULT,
@@ -35,7 +64,7 @@
     onCompletion: CompletionHandler? = null,
     block: suspend CoroutineScope.() -> T
 ): Promise<T> =
-    GlobalScope.async(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block = block).asPromise()
+    GlobalScope.promise(context + (parent ?: EmptyCoroutineContext), start, onCompletion, block = block)
 
 /**
  * Converts this deferred value to the instance of [Promise].
diff --git a/js/kotlinx-coroutines-core-js/test/PromiseTest.kt b/js/kotlinx-coroutines-core-js/test/PromiseTest.kt
index 0398b1d..2e165c1 100644
--- a/js/kotlinx-coroutines-core-js/test/PromiseTest.kt
+++ b/js/kotlinx-coroutines-core-js/test/PromiseTest.kt
@@ -10,7 +10,7 @@
 
 class PromiseTest : TestBase() {
     @Test
-    fun testPromiseResolvedAsDeferred() = promise {
+    fun testPromiseResolvedAsDeferred() = GlobalScope.promise {
         val promise = Promise<String> { resolve, _ ->
             resolve("OK")
         }
@@ -19,7 +19,7 @@
     }
     
     @Test
-    fun testPromiseRejectedAsDeferred() = promise {
+    fun testPromiseRejectedAsDeferred() = GlobalScope.promise {
         lateinit var promiseReject: (Throwable) -> Unit
         val promise = Promise<String> { _, reject ->
             promiseReject = reject
@@ -37,7 +37,7 @@
     }
 
     @Test
-    fun testCompletedDeferredAsPromise() = promise {
+    fun testCompletedDeferredAsPromise() = GlobalScope.promise {
         val deferred = async(coroutineContext, CoroutineStart.UNDISPATCHED) {
             // completed right away
             "OK"
@@ -47,7 +47,7 @@
     }
 
     @Test
-    fun testWaitForDeferredAsPromise() = promise {
+    fun testWaitForDeferredAsPromise() = GlobalScope.promise {
         val deferred = async(coroutineContext) {
             // will complete later
             "OK"
@@ -57,7 +57,7 @@
     }
 
     @Test
-    fun testCancellableAwaitPromise() = promise {
+    fun testCancellableAwaitPromise() = GlobalScope.promise {
         lateinit var r: (String) -> Unit
         val toAwait = Promise<String> { resolve, _ -> r = resolve }
         val job = launch(coroutineContext, CoroutineStart.UNDISPATCHED) {
@@ -68,7 +68,7 @@
     }
 
     @Test
-    fun testAsPromiseAsDeferred() = promise {
+    fun testAsPromiseAsDeferred() = GlobalScope.promise {
         val deferred = async { "OK" }
         val promise = deferred.asPromise()
         val d2 = promise.asDeferred()
diff --git a/js/kotlinx-coroutines-core-js/test/TestBase.kt b/js/kotlinx-coroutines-core-js/test/TestBase.kt
index 8db40db..473f279 100644
--- a/js/kotlinx-coroutines-core-js/test/TestBase.kt
+++ b/js/kotlinx-coroutines-core-js/test/TestBase.kt
@@ -72,7 +72,7 @@
     ): dynamic {
         var exCount = 0
         var ex: Throwable? = null
-        return promise(block = block, context = CoroutineExceptionHandler { context, e ->
+        return GlobalScope.promise(block = block, context = CoroutineExceptionHandler { context, e ->
             if (e is CancellationException) return@CoroutineExceptionHandler // are ignored
             exCount++
             when {
diff --git a/native/kotlinx-coroutines-core-native/src/Builders.kt b/native/kotlinx-coroutines-core-native/src/Builders.kt
index 50d8185..4abdbd0 100644
--- a/native/kotlinx-coroutines-core-native/src/Builders.kt
+++ b/native/kotlinx-coroutines-core-native/src/Builders.kt
@@ -38,7 +38,7 @@
         newEventLoop
     } else
         contextInterceptor as? EventLoop
-    val newContext = newCoroutineContext(
+    val newContext = GlobalScope.newCoroutineContext(
         if (privateEventLoop) context + (eventLoop as ContinuationInterceptor) else context
     )
     val coroutine = BlockingCoroutine<T>(newContext, eventLoop, privateEventLoop)
diff --git a/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt b/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt
index ae6fb02..c90e23a 100644
--- a/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt
+++ b/native/kotlinx-coroutines-core-native/src/CoroutineContext.kt
@@ -41,15 +41,10 @@
 
 internal actual val DefaultDelay: Delay = DefaultExecutor
 
-/**
- * Creates context for the new coroutine. It installs [DefaultDispatcher] when no other dispatcher nor
- * [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on).
- */
-@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
-public actual fun newCoroutineContext(context: CoroutineContext, parent: Job? = null): CoroutineContext {
-    val wp = if (parent == null) context else context + parent
-    return if (context !== DefaultDispatcher && context[ContinuationInterceptor] == null)
-        wp + DefaultDispatcher else wp
+public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
+    val combined = coroutineContext + context
+    return if (combined !== kotlinx.coroutines.experimental.DefaultDispatcher && combined[ContinuationInterceptor] == null)
+        combined + kotlinx.coroutines.experimental.DefaultDispatcher else combined
 }
 
 // No debugging facilities on native
diff --git a/ui/coroutines-guide-ui.md b/ui/coroutines-guide-ui.md
index 05325b3..781cb02 100644
--- a/ui/coroutines-guide-ui.md
+++ b/ui/coroutines-guide-ui.md
@@ -468,7 +468,7 @@
 The natural solution to this problem is to associate a [Job] object with each UI object that has a lifecycle and create
 all the coroutines in the context of this job. But passing associated job object to every coroutine builder is error-prone, 
 it is easy to forget it. For this purpose, [CoroutineScope] interface should be implemented by UI owner, and then every
-coroutine builder defined as an extension on [CoroutineScope] will inherit UI job without explicit mentioning.
+coroutine builder defined as an extension on [CoroutineScope] inherits UI job without explicitly mentioning it.
 
 For example, in Android application an `Activity` is initially _created_ and is _destroyed_ when it is no longer 
 needed and when its memory must be released. A natural solution is to attach an 
@@ -477,8 +477,9 @@
 
 ```kotlin
 abstract class ScopedAppActivity: AppCompatActivity(), CoroutineScope {
-    override val coroutineContext: CoroutineContext by lazy { job + UI }
     protected lateinit var job: Job
+    override val coroutineContext: CoroutineContext 
+        get() = job + UI
     
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -513,7 +514,7 @@
 }
 ```
 
-Every coroutine launched from within a `MainActivity` will have its job as a parent and will be cancelled if
+Every coroutine launched from within a `MainActivity` has its job as a parent and is immediately cancelled when
 activity is destroyed.
 
 To propagate activity scope to its views and presenters, one can use [currentScope] builder which captures current