Merge branch 'master' into develop
diff --git a/docs/flow.md b/docs/flow.md
index 43467da..2a3ffb5 100644
--- a/docs/flow.md
+++ b/docs/flow.md
@@ -63,14 +63,14 @@
 
 ## Asynchronous Flow
 
-Suspending functions asynchronously return a single value, but how can you return
-multiple asynchronously computed values? That is what Kotlin Flows are for.
+Suspending functions asynchronously returns a single value, but how can we return
+multiple asynchronously computed values? This is where Kotlin Flows come in.
 
 ### Representing multiple values
 
 Multiple values can be represented in Kotlin using [collections]. 
 For example, we can have a function `foo()` that returns a [List] 
-of three numbers and print them all using [forEach]:
+of three numbers and then print them all using [forEach]:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -84,7 +84,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-01.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-01.kt).
 
 This code outputs:
 
@@ -98,8 +98,8 @@
 
 #### Sequences
 
-If the numbers are computed with some CPU-consuming blocking code 
-(each computation taking 100ms) then we can represent the numbers using a [Sequence]:
+If we are computing the numbers with some CPU-consuming blocking code 
+(each computation taking 100ms), then we can represent the numbers using a [Sequence]:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -118,7 +118,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-02.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-02.kt).
 
 This code outputs the same numbers, but it waits 100ms before printing each one.
 
@@ -131,7 +131,7 @@
 #### Suspending functions
 
 However, this computation blocks the main thread that is running the code. 
-When those values are computed by an asynchronous code we can mark function `foo` with a `suspend` modifier,
+When these values are computed by asynchronous code we can mark the function `foo` with a `suspend` modifier,
 so that it can perform its work without blocking and return the result as a list:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -153,7 +153,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-03.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-03.kt).
 
 This code prints the numbers after waiting for a second.
 
@@ -165,9 +165,8 @@
 
 #### Flows
 
-Using `List<Int>` result type we can only return all the values at once. To represent
-the stream of values that are being asynchronously computed we can use [`Flow<Int>`][Flow] type similarly
-to the `Sequence<Int>` type for synchronously computed values:
+Using the `List<Int>` result type, means we can only return all the values at once. To represent
+the stream of values that are being asynchronously computed, we can use a [`Flow<Int>`][Flow] type just like we would the `Sequence<Int>` type for synchronously computed values:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -184,7 +183,7 @@
 }
 
 fun main() = runBlocking<Unit> {
-    // Launch a concurrent coroutine to see that the main thread is not blocked
+    // Launch a concurrent coroutine to check if the main thread is blocked
     launch {
         for (k in 1..3) {
             println("I'm not blocked $k")
@@ -199,7 +198,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt).
 
 This code waits 100ms before printing each number without blocking the main thread. This is verified
 by printing "I'm not blocked" every 100ms from a separate coroutine that is running in the main thread:
@@ -215,7 +214,7 @@
 
 <!--- TEST -->
 
-Notice the following differences of the code with the [Flow] from the earlier examples:
+Notice the following differences in the code with the [Flow] from the earlier examples:
 
 * A builder function for [Flow] type is called [flow].
 * Code inside the `flow { ... }` builder block can suspend.
@@ -223,12 +222,12 @@
 * Values are _emitted_ from the flow using [emit][FlowCollector.emit] function.
 * Values are _collected_ from the flow using [collect][collect] function.  
 
-> You can replace [delay] with `Thread.sleep` in the body of `foo`'s `flow { ... }` and see that the main
+> We can replace [delay] with `Thread.sleep` in the body of `foo`'s `flow { ... }` and see that the main
 thread is blocked in this case. 
 
 ### Flows are cold
 
-Flows are _cold_ streams similarly to sequences &mdash; the code inside a [flow] builder does not
+Flows are _cold_ streams similar to sequences &mdash; the code inside a [flow] builder does not
 run until the flow is collected. This becomes clear in the following example:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -259,7 +258,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-05.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-05.kt).
 
 Which prints:
 
@@ -279,17 +278,17 @@
 
 <!--- TEST -->
  
-That is a key reason why the `foo()` function (which returns a flow) is not marked with `suspend` modifier.
+This is a key reason the `foo()` function (which returns a flow) is not marked with `suspend` modifier.
 By itself, `foo()` returns quickly and does not wait for anything. The flow starts every time it is collected,
-that is why we see that when we call `collect` again, we get "Flow started" printed again.
+that is why we see "Flow started" when we call `collect` again.
 
 ### Flow cancellation
 
-Flow adheres to general cooperative cancellation of coroutines. However, flow infrastructure does not introduce
+Flow adheres to the general cooperative cancellation of coroutines. However, flow infrastructure does not introduce
 additional cancellation points. It is fully transparent for cancellation. As usual, flow collection can be 
-cancelled when the flow is suspended in a cancellable suspending function (like [delay]) and cannot be cancelled otherwise.
+cancelled when the flow is suspended in a cancellable suspending function (like [delay]), and cannot be cancelled otherwise.
 
-The following example shows how the flow gets cancelled on timeout when running in [withTimeoutOrNull] block 
+The following example shows how the flow gets cancelled on a timeout when running in a [withTimeoutOrNull] block 
 and stops executing its code:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -318,7 +317,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-06.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-06.kt).
 
 Notice how only two numbers get emitted by the flow in `foo()` function, producing the following output: 
 
@@ -335,12 +334,12 @@
 ### Flow builders
 
 The `flow { ... }` builder from the previous examples is the most basic one. There are other builders for
-convenient declaration of flows:
+easier declaration of flows:
 
 * [flowOf] builder that defines a flow emitting a fixed set of values.
 * Various collections and sequences can be converted to flows using `.asFlow()` extension functions.
 
-Thus, the example that prints numbers from 1 to 3 from a flow can be written as:
+So, the example that prints the numbers from 1 to 3 from a flow can be written as:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -358,7 +357,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-07.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-07.kt).
  
 <!--- TEST
 1
@@ -368,17 +367,17 @@
 
 ### Intermediate flow operators
 
-Flows can be transformed with operators similarly to collections and sequences. 
+Flows can be transformed with operators, just as you would with collections and sequences. 
 Intermediate operators are applied to an upstream flow and return a downstream flow. 
 These operators are cold, just like flows are. A call to such an operator is not
 a suspending function itself. It works quickly, returning the definition of a new transformed flow. 
 
 The basic operators have familiar names like [map] and [filter]. 
-The important difference from sequences is that blocks of 
-code inside those operators can call suspending functions. 
+The important difference to sequences is that blocks of 
+code inside these operators can call suspending functions. 
 
 For example, a flow of incoming requests can be
-mapped to results with the [map] operator even when performing a request is a long-running
+mapped to the results with the [map] operator, even when performing a request is a long-running
 operation that is implemented by a suspending function:   
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -403,9 +402,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-08.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-08.kt).
 
-It produces the following three lines, each line appearing after a second:
+It produces the following three lines, each line appearing after each second:
 
 ```text                                                                    
 response 1
@@ -418,8 +417,8 @@
 #### Transform operator
 
 Among the flow transformation operators, the most general one is called [transform]. It can be used to imitate
-simple transformations like [map] and [filter] as well as implement more complex transformations. 
-Using `transform` operator, you can [emit][FlowCollector.emit] arbitrary values an arbitrary number of times.
+simple transformations like [map] and [filter], as well as implement more complex transformations. 
+Using the `transform` operator, we can [emit][FlowCollector.emit] arbitrary values an arbitrary number of times.
 
 For example, using `transform` we can emit a string before performing a long-running asynchronous request 
 and follow it with a response:
@@ -449,7 +448,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-09.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-09.kt).
 
 The output of this code is:
 
@@ -467,7 +466,7 @@
 #### Size-limiting operators
 
 Size-limiting intermediate operators like [take] cancel the execution of the flow when the corresponding limit
-is reached. Cancellation in coroutines is always performed by throwing an exception so that all the resource-management
+is reached. Cancellation in coroutines is always performed by throwing an exception, so that all the resource-management
 functions (like `try { ... } finally { ... }` blocks) operate normally in case of cancellation:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -498,10 +497,10 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-10.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-10.kt).
 
-The output of this code clearly shows that execution of the `flow { ... }` body in `numbers()` function
-had stopped after emitting the second number:
+The output of this code clearly shows that the execution of the `flow { ... }` body in the `numbers()` function
+stopped after emitting the second number:
 
 ```text       
 1
@@ -514,8 +513,7 @@
 ### Terminal flow operators
 
 Terminal operators on flows are _suspending functions_ that start a collection of the flow.
-The [collect] operator is the most basic one, but there are other terminal operators for 
-convenience:
+The [collect] operator is the most basic one, but there are other terminal operators, which can make it easier:
 
 * Conversion to various collections like [toList] and [toSet].
 * Operators to get the [first] value and to ensure that a flow emits a [single] value.
@@ -541,7 +539,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-11.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-11.kt).
 
 Prints a single number:
 
@@ -556,10 +554,10 @@
 Each individual collection of a flow is performed sequentially unless special operators that operate
 on multiple flows are used. The collection works directly in the coroutine that calls a terminal operator. 
 No new coroutines are launched by default. 
-Each emitted value is processed by all intermediate operators from 
-upstream to downstream and is delivered to the terminal operator after that. 
+Each emitted value is processed by all the intermediate operators from 
+upstream to downstream and is then delivered to the terminal operator after. 
 
-See the following example that filters even integers and maps them to strings:
+See the following example that filters the even integers and maps them to strings:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -586,7 +584,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-12.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-12.kt).
 
 Producing:
 
@@ -608,7 +606,7 @@
 
 Collection of a flow always happens in the context of the calling coroutine. For example, if there is 
 a `foo` flow, then the following code runs in the context specified
-by the author of this code, regardless of implementation details of the `foo` flow:
+by the author of this code, regardless of the implementation details of the `foo` flow:
 
 <div class="sample" markdown="1" theme="idea" data-highlight-only>
 
@@ -654,7 +652,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-13.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-13.kt).
 
 Running this code produces:
 
@@ -668,14 +666,14 @@
 <!--- TEST FLEXIBLE_THREAD -->
 
 Since `foo().collect` is called from the main thread, the body of `foo`'s flow is also called in the main thread.
-This is a perfect default for fast-running or asynchronous code that does not care about the execution context and
+This is the perfect default for fast-running or asynchronous code that does not care about the execution context and
 does not block the caller. 
 
 #### Wrong emission withContext
 
 However, the long-running CPU-consuming code might need to be executed in the context of [Dispatchers.Default] and UI-updating
 code might need to be executed in the context of [Dispatchers.Main]. Usually, [withContext] is used
-to change the context in code using Kotlin coroutines, but code in the `flow { ... }` builder has to honor context
+to change the context in the code using Kotlin coroutines, but code in the `flow { ... }` builder has to honor the context
 preservation property and is not allowed to [emit][FlowCollector.emit] from a different context. 
 
 Try running the following code:
@@ -688,7 +686,7 @@
                       
 //sampleStart
 fun foo(): Flow<Int> = flow {
-    // WRONG way to change context for CPU-consuming code in flow builder
+    // The WRONG way to change context for CPU-consuming code in flow builder
     kotlinx.coroutines.withContext(Dispatchers.Default) {
         for (i in 1..3) {
             Thread.sleep(100) // pretend we are computing it in CPU-consuming way
@@ -705,7 +703,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt).
 
 This code produces the following exception:
 
@@ -717,14 +715,14 @@
 	at ...
 -->
    
-> Note that we had to use a fully qualified name of [kotlinx.coroutines.withContext][withContext] function in this example to 
+> Note that we had to use a fully qualified name of the [kotlinx.coroutines.withContext][withContext] function in this example to 
 demonstrate this exception. A short name of `withContext` would have resolved to a special stub function that
-produces compilation error to prevent us from running into this problem.   
+produces a compilation error to prevent us from running into this problem.   
 
 #### flowOn operator
    
-The exception refers to [flowOn] function that shall be used to change the context of flow emission.
-The correct way of changing the context of a flow is shown in the below example, which also prints 
+The exception refers to the [flowOn] function that shall be used to change the context of the flow emission.
+The correct way to change the context of a flow is shown in the example below, which also prints the 
 names of the corresponding threads to show how it all works:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -754,7 +752,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-15.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-15.kt).
   
 Notice how `flow { ... }` works in the background thread, while collection happens in the main thread:   
   
@@ -767,17 +765,17 @@
 [main @coroutine#1] Collected 3
 -->
 
-Another observation here is that [flowOn] operator had changed the default sequential nature of the flow.
+Another thing to observe here is that the [flowOn] operator has changed the default sequential nature of the flow.
 Now collection happens in one coroutine ("coroutine#1") and emission happens in another coroutine
-("coroutine#2") that is running in another thread concurrently with collecting coroutine. The [flowOn] operator
+("coroutine#2") that is running in another thread concurrently with the collecting coroutine. The [flowOn] operator
 creates another coroutine for an upstream flow when it has to change the [CoroutineDispatcher] in its context. 
 
 ### Buffering
 
-Running different parts of a flow in different coroutines can be helpful from the standpoint of overall time it takes 
+Running different parts of a flow in different coroutines can be helpful from the standpoint of the overall time it takes 
 to collect the flow, especially when long-running asynchronous operations are involved. For example, consider a case when
-emission by `foo()` flow is slow, taking 100 ms to produce an element; and collector is also slow, 
-taking 300 ms to process an element. Let us see how long does it take to collect such a flow with three numbers:
+the emission by `foo()` flow is slow, taking 100 ms to produce an element; and collector is also slow, 
+taking 300 ms to process an element. Let's see how long it takes to collect such a flow with three numbers:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -808,9 +806,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-16.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-16.kt).
 
-It produces something like this, the whole collection taking around 1200 ms (three numbers times 400 ms each):
+It produces something like this, with the whole collection taking around 1200 ms (three numbers, 400 ms for each):
 
 ```text
 1
@@ -821,7 +819,7 @@
 
 <!--- TEST ARBITRARY_TIME -->
 
-We can use [buffer] operator on a flow to run emitting code of `foo()` concurrently with collecting code,
+We can use a [buffer] operator on a flow to run emitting code of `foo()` concurrently with collecting code,
 as opposed to running them sequentially:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -855,10 +853,10 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-17.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-17.kt).
 
-It produces the same numbers faster, as we have effectively created a processing pipeline,
-only having to wait 100 ms for the first number and then spending only 300 ms to process
+It produces the same numbers just faster, as we have effectively created a processing pipeline,
+having to only wait 100 ms for the first number and then spending only 300 ms to process
 each number. This way it takes around 1000 ms to run:
 
 ```text
@@ -870,13 +868,13 @@
 
 <!--- TEST ARBITRARY_TIME -->
 
-> Note that [flowOn] operator uses the same buffering mechanism when it has to change [CoroutineDispatcher],
-but here we explicitly request buffering without changing execution context. 
+> Note that the [flowOn] operator uses the same buffering mechanism when it has to change a [CoroutineDispatcher],
+but here we explicitly request buffering without changing the execution context. 
 
 #### Conflation
 
-When flow represents partial results of some operation or operation status updates, it may not be necessary
-to process each value, but only to process the most recent ones. In this case, [conflate] operator can be used to skip
+When a flow represents partial results of the operation or operation status updates, it may not be necessary
+to process each value, but instead, only most recent ones. In this case, the [conflate] operator can be used to skip
 intermediate values when a collector is too slow to process them. Building on the previous example:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -910,9 +908,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-18.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-18.kt).
 
-We see that while the first number was being processed the second and the third ones were already produced, so
+We see that while the first number was still being processed the second, and third were already produced, so
 the second one was _conflated_ and only the most recent (the third one) was delivered to the collector:
 
 ```text
@@ -925,10 +923,10 @@
 
 #### Processing the latest value
 
-Conflation is one way to speed up processing when both emitter and collector are slow. It does that by dropping emitted values.
-The other way is to cancel slow collector and restart it every time a new value is emitted. There is
-a family of `xxxLatest` operators that perform the same essential logic of `xxx` operator, but cancel the
-code in their block on a new value. Let us change the previous example from [conflate] to [collectLatest]:
+Conflation is one way to speed up processing when both the emitter and collector are slow. It does it by dropping emitted values.
+The other way is to cancel a slow collector and restart it every time a new value is emitted. There is
+a family of `xxxLatest` operators that perform the same essential logic of a `xxx` operator, but cancel the
+code in their block on a new value. Let's try changing [conflate] to [collectLatest] in the previous example:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -961,7 +959,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-19.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-19.kt).
  
 Since the body of [collectLatest] takes 300 ms, but new values are emitted every 100 ms, we see that the block
 is run on every value, but completes only for the last value:
@@ -978,12 +976,12 @@
 
 ### Composing multiple flows
 
-There are several ways to compose multiple flows.
+There are lots of ways to compose multiple flows.
 
 #### Zip
 
-Similarly to [Sequence.zip] extension function in the Kotlin standard library, 
-flows have [zip] operator that combines the corresponding values of two flows:
+Just like the [Sequence.zip] extension function in the Kotlin standard library, 
+flows have a [zip] operator that combines the corresponding values of two flows:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1003,7 +1001,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-20.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-20.kt).
 
 This example prints:
 
@@ -1017,16 +1015,16 @@
 
 #### Combine
 
-When flow represents the most recent value of some variable or operation (see also a related 
-section on [conflation](#conflation)) it might be needed to perform a computation that depends on
-the most recent values of the corresponding flows and to recompute it whenever any of upstream
+When flow represents the most recent value of a variable or operation (see also the related 
+section on [conflation](#conflation)), it might be needed to perform a computation that depends on
+the most recent values of the corresponding flows and to recompute it whenever any of the upstream
 flows emit a value. The corresponding family of operators is called [combine].
 
 For example, if the numbers in the previous example update every 300ms, but strings update every 400 ms, 
-then zipping them using [zip] operator would still produce the same result, 
-albeit results are going to be printed every 400 ms:
+then zipping them using the [zip] operator will still produce the same result, 
+albeit results that are printed every 400 ms:
 
-> We use [onEach] intermediate operator in this example to delay each element and thus make the code 
+> We use a [onEach] intermediate operator in this example to delay each element and make the code 
 that emits sample flows more declarative and shorter.
  
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1050,7 +1048,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-21.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-21.kt).
 
 <!--- TEST ARBITRARY_TIME
 1 -> one at 437 ms from start
@@ -1058,7 +1056,7 @@
 3 -> three at 1243 ms from start
 -->
 
-However, using [combine] operator here instead of [zip]:
+However, when using a [combine] operator here instead of a [zip]:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1081,7 +1079,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-22.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-22.kt).
 
 We get quite a different output, where a line is printed at each emission from either `nums` or `strs` flows:
 
@@ -1129,13 +1127,13 @@
 
 Then we end up with a flow of flows (`Flow<Flow<String>>`) that needs to be _flattened_ into a single flow for 
 further processing. Collections and sequences have [flatten][Sequence.flatten] and [flatMap][Sequence.flatMap]
-operators for this purpose. However, the asynchronous nature of flows calls for different _modes_ of flattening 
-thus there is a family of flattening operators on flows.
+operators for this. However, due the asynchronous nature of flows they call for different _modes_ of flattening, 
+as such, there is a family of flattening operators on flows.
 
 #### flatMapConcat
 
 Concatenating mode is implemented by [flatMapConcat] and [flattenConcat] operators. They are the most direct
-analogues of the corresponding sequence operators. They wait for inner flow to complete before
+analogues of the corresponding sequence operators. They wait for the inner flow to complete before
 starting to collect the next one as the following example shows:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1164,7 +1162,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-23.kt).            
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-23.kt).            
 
 The sequential nature of [flatMapConcat] is clearly seen in the output:
 
@@ -1213,7 +1211,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-24.kt).            
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-24.kt).            
 
 The concurrent nature of [flatMapMerge] is obvious:
 
@@ -1228,16 +1226,16 @@
 
 <!--- TEST ARBITRARY_TIME -->
 
-> Note that [flatMapMerge] call its block of code (`{ requestFlow(it) }` in this example) sequentially, but 
-collects the resulting flows concurrently, so it is equivalent to performing a sequential 
+> Note that the [flatMapMerge] calls its block of code (`{ requestFlow(it) }` in this example) sequentially, but 
+collects the resulting flows concurrently, it is the equivalent of performing a sequential 
 `map { requestFlow(it) }` first and then calling [flattenMerge] on the result.   
 
 #### flatMapLatest   
 
-In a similar way to [collectLatest] operator that was shown in 
+In a similar way to the [collectLatest] operator, that was shown in 
 ["Processing the latest value"](#processing-the-latest-value) section, there is the corresponding "Latest" 
-flattening mode where collection of the previous flow is cancelled as soon as new flow is emitted. 
-It is implemented by [flatMapLatest] operator.
+flattening mode where a collection of the previous flow is cancelled as soon as new flow is emitted. 
+It is implemented by the [flatMapLatest] operator.
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1265,9 +1263,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-25.kt).            
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-25.kt).            
 
-The output of this example speaks for the way [flatMapLatest] works:
+The output here in this example is a good demonstration of how [flatMapLatest] works:
 
 ```text                      
 1: First at 142 ms from start
@@ -1284,7 +1282,7 @@
 
 ### Flow exceptions
 
-Flow collection can complete with an exception when emitter or any code inside any of the operators throw an exception. 
+Flow collection can complete with an exception when an emitter or code inside the operators throw an exception. 
 There are several ways to handle these exceptions.
 
 #### Collector try and catch
@@ -1320,10 +1318,10 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-26.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-26.kt).
 
 This code successfully catches an exception in [collect] terminal operator and, 
-as you can see, no more values are emitted after that:
+as we see, no more values are emitted after that:
 
 ```text 
 Emitting 1
@@ -1337,8 +1335,8 @@
 
 #### Everything is caught
 
-The previous example actually catches any exception happening in emitter or in any intermediate or terminal operators.
-For example, let us change the code so that emitted values are [mapped][map] to strings,
+The previous example actually catches any exception happening in the emitter or in any intermediate or terminal operators.
+For example, let's change the code so that emitted values are [mapped][map] to strings,
 but the corresponding code produces an exception:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1372,7 +1370,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-27.kt).
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-27.kt).
 
 This exception is still caught and collection is stopped:
 
@@ -1387,13 +1385,13 @@
 
 ### Exception transparency
 
-But how can code of emitter encapsulate its exception handling behavior?  
+But how can code of the emitter encapsulate its exception handling behavior?  
 
-Flows must be _transparent to exceptions_ and it is a violation of exception transparency to [emit][FlowCollector.emit] values in the 
-`flow { ... }` builder from inside of `try/catch` block. This guarantees that a collector throwing an exception
+Flows must be _transparent to exceptions_ and it is a violation of the exception transparency to [emit][FlowCollector.emit] values in the 
+`flow { ... }` builder from inside of a `try/catch` block. This guarantees that a collector throwing an exception
 can always catch it using `try/catch` as in the previous example.
 
-The emitter can use [catch] operator that preserves this exception transparency and allows encapsulation
+The emitter can use a [catch] operator that preserves this exception transparency and allows encapsulation
 of its exception handling. The body of the `catch` operator can analyze an exception
 and react to it in different ways depending on which exception was caught:
 
@@ -1401,7 +1399,7 @@
 * Exceptions can be turned into emission of values using [emit][FlowCollector.emit] from the body of [catch].
 * Exceptions can be ignored, logged, or processed by some other code.
 
-For example, let us emit a text on catching an exception:
+For example, let us emit the text on catching an exception:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1432,7 +1430,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-28.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-28.kt). 
  
 The output of the example is the same, even though we do not have `try/catch` around the code anymore. 
 
@@ -1476,9 +1474,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-29.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-29.kt). 
  
-The "Caught ..." message is not printed despite the `catch` operator: 
+A "Caught ..." message is not printed despite there being a `catch` operator: 
 
 <!--- TEST EXCEPTION  
 Emitting 1
@@ -1490,8 +1488,8 @@
 
 #### Catching declaratively
 
-We can combine a declarative nature of [catch] operator with a desire to handle all exceptions by moving the body
-of [collect] operator into [onEach] and putting it before the `catch` operator. Collection of this flow must
+We can combine the declarative nature of the [catch] operator with a desire to handle all the exceptions, by moving the body
+of the [collect] operator into [onEach] and putting it before the `catch` operator. Collection of this flow must
 be triggered by a call to `collect()` without parameters:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1522,9 +1520,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-30.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-30.kt). 
  
-Now we can see that "Caught ..." message is printed and thus we can catch all exceptions without explicitly
+Now we can see that a "Caught ..." message is printed and so we can catch all the exceptions without explicitly
 using a `try/catch` block: 
 
 <!--- TEST EXCEPTION  
@@ -1536,12 +1534,12 @@
 
 ### Flow completion
 
-When flow collection completes (normally or exceptionally) it may be needed to execute some action. 
-As you might have already noticed, it also can be done in two ways: imperative and declarative.
+When flow collection completes (normally or exceptionally) it may need to execute an action. 
+As you may have already noticed, it can be done in two ways: imperative or declarative.
 
 #### Imperative finally block
 
-In addition to `try`/`catch`, a collector can also use `finally` block to execute an action 
+In addition to `try`/`catch`, a collector can also use a `finally` block to execute an action 
 upon `collect` completion.
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1565,9 +1563,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-31.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-31.kt). 
 
-This code prints three numbers produced by the `foo()` flow followed by "Done" string:
+This code prints three numbers produced by the `foo()` flow followed by a "Done" string:
 
 ```text
 1
@@ -1580,10 +1578,10 @@
 
 #### Declarative handling
 
-For declarative approach, flow has [onCompletion] intermediate operator that is invoked
-when the flow is completely collected.
+For the declarative approach, flow has [onCompletion] intermediate operator that is invoked
+when the flow has completely collected.
 
-The previous example can be rewritten using [onCompletion] operator and produces the same output:
+The previous example can be rewritten using an [onCompletion] operator and produces the same output:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1603,7 +1601,7 @@
 ```
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-32.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-32.kt). 
 
 <!--- TEST 
 1
@@ -1613,8 +1611,8 @@
 -->
 
 The key advantage of [onCompletion] is a nullable `Throwable` parameter of the lambda that can be used
-to determine whether flow collection was completed normally or exceptionally. In the following
-example `foo()` flow throws exception after emitting number 1:
+to determine whether the flow collection was completed normally or exceptionally. In the following
+example the `foo()` flow throws an exception after emitting the number 1:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1638,7 +1636,7 @@
 ```
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-33.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-33.kt). 
 
 As you may expect, it prints:
 
@@ -1650,13 +1648,13 @@
 
 <!--- TEST -->
 
-[onCompletion] operator, unlike [catch], does not handle the exception. As we can see from the above
+The [onCompletion] operator, unlike [catch], does not handle the exception. As we can see from the above
 example code, the exception still flows downstream. It will be delivered to further `onCompletion` operators
-and can be handled with `catch` operator. 
+and can be handled with a `catch` operator. 
 
 #### Upstream exceptions only
 
-Just like [catch] operator, [onCompletion] sees only exception coming from upstream and does not
+Just like the [catch] operator, [onCompletion] only sees exceptions coming from upstream and does not
 see downstream exceptions. For example, run the following code:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1681,9 +1679,9 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-34.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-34.kt). 
 
-And you can see the completion cause is null, yet collection failed with exception:
+We can see the completion cause is null, yet collection failed with exception:
 
 ```text 
 1
@@ -1695,20 +1693,20 @@
 
 ### Imperative versus declarative
 
-Now we know how to collect flow, handle its completion and exceptions in both imperative and declarative ways.
-The natural question here is which approach should be preferred and why.
+Now we know how to collect flow, and handle its completion and exceptions in both imperative and declarative ways.
+The natural question here is, which approach is preferred and why?
 As a library, we do not advocate for any particular approach and believe that both options
 are valid and should be selected according to your own preferences and code style. 
 
 ### Launching flow
 
-It is convenient to use flows to represent asynchronous events that are coming from some source.
-In this case, we need an analogue of `addEventListener` function that registers a piece of code with a reaction
-on incoming events and continues further work. The [onEach] operator can serve this role. 
+It is easy to use flows to represent asynchronous events that are coming from some source.
+In this case, we need an analogue of the `addEventListener` function that registers a piece of code with a reaction
+for incoming events and continues further work. The [onEach] operator can serve this role. 
 However, `onEach` is an intermediate operator. We also need a terminal operator to collect the flow. 
 Otherwise, just calling `onEach` has no effect.
  
-If we use [collect] terminal operator after `onEach`, then code after it waits until the flow is collected:
+If we use the [collect] terminal operator after `onEach`, then the code after it will wait until the flow is collected:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
 
@@ -1731,7 +1729,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-35.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-35.kt). 
   
 As you can see, it prints:
 
@@ -1744,8 +1742,8 @@
 
 <!--- TEST -->
  
-Here [launchIn] terminal operator comes in handy. Replacing `collect` with `launchIn` we can
-launch collection of the flow in a separate coroutine, so that execution of further code 
+The [launchIn] terminal operator comes in handy here. By replacing `collect` with `launchIn` we can
+launch a collection of the flow in a separate coroutine, so that execution of further code 
 immediately continues:
 
 <div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -1769,7 +1767,7 @@
 
 </div>
 
-> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-36.kt). 
+> You can get the full code from [here](../kotlinx-coroutines-core/jvm/test/guide/example-flow-36.kt). 
   
 It prints:
 
@@ -1783,17 +1781,17 @@
 <!--- TEST -->
 
 The required parameter to `launchIn` must specify a [CoroutineScope] in which the coroutine to collect the flow is 
-launched. In the above example this scope comes from [runBlocking]
-coroutine builder, so while the flow is running this [runBlocking] scope waits for completion of its child coroutine
+launched. In the above example this scope comes from the [runBlocking]
+coroutine builder, so while the flow is running, this [runBlocking] scope waits for completion of its child coroutine
 and keeps the main function from returning and terminating this example. 
 
-In real applications a scope is going to come from some entity with a limited 
+In actual applications a scope will come from an entity with a limited 
 lifetime. As soon as the lifetime of this entity is terminated the corresponding scope is cancelled, cancelling
-collection of the corresponding flow. This way the pair of `onEach { ... }.launchIn(scope)` works
-like `addEventListener`. However, there is no need for the corresponding `removeEventListener` function, 
+the collection of the corresponding flow. This way the pair of `onEach { ... }.launchIn(scope)` works
+like the `addEventListener`. However, there is no need for the corresponding `removeEventListener` function, 
 as cancellation and structured concurrency serve this purpose.
 
-Note, that [launchIn] also returns a [Job] which can be used to [cancel][Job.cancel] the corresponding flow collection
+Note that [launchIn] also returns a [Job], which can be used to [cancel][Job.cancel] the corresponding flow collection
 coroutine only without cancelling the whole scope or to [join][Job.join] it.
  
 <!-- stdlib references -->
diff --git a/kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt b/kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt
index 9a3c05c..7bde16c 100644
--- a/kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt
+++ b/kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt
@@ -16,7 +16,7 @@
 }
 
 fun main() = runBlocking<Unit> {
-    // Launch a concurrent coroutine to see that the main thread is not blocked
+    // Launch a concurrent coroutine to check if the main thread is blocked
     launch {
         for (k in 1..3) {
             println("I'm not blocked $k")
diff --git a/kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt b/kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt
index 6996abc..6628d12 100644
--- a/kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt
+++ b/kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt
@@ -9,7 +9,7 @@
 import kotlinx.coroutines.flow.*
                       
 fun foo(): Flow<Int> = flow {
-    // WRONG way to change context for CPU-consuming code in flow builder
+    // The WRONG way to change context for CPU-consuming code in flow builder
     kotlinx.coroutines.withContext(Dispatchers.Default) {
         for (i in 1..3) {
             Thread.sleep(100) // pretend we are computing it in CPU-consuming way