diff --git a/.github/workflows/main2.yml b/.github/workflows/main2.yml
new file mode 100644
index 000000000..95aba24e3
--- /dev/null
+++ b/.github/workflows/main2.yml
@@ -0,0 +1,40 @@
+# This is a basic workflow to help you get started with Actions
+
+name: Shadow
+
+# Controls when the action will run. Triggers the workflow on push or pull request 
+# events but only for the master branch
+on:
+  release:
+    types:
+      - created
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+  # This workflow contains a single job called "build"
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up JDK 1.8
+        uses: actions/setup-java@v1
+        with:
+          java-version: 1.8
+      - name: Grant execute permission for gradlew
+        run: chmod +x gradlew
+      - name: Build with Gradle and shadowJar
+        run: ./gradlew :mirai-core:shadowJar :mirai-core-qqandroid:shadowJar
+      - name: Upload artifact
+        uses: actions/upload-artifact@v1.0.0
+        with:
+          # Artifact name
+          name: mirai-core-all
+          # Directory containing files to upload
+          path: "mirai-core/build/libs/mirai-core-*-all.jar"
+      - name: Upload artifact
+        uses: actions/upload-artifact@v1.0.0
+        with:
+          # Artifact name
+          name: mirai-core-qqandroid-all
+          # Directory containing files to upload
+          path: "mirai-core-qqandroid/build/libs/mirai-core-qqandroid-*-all.jar"
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
index 7d2801ffa..76df1763d 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
@@ -160,7 +160,7 @@ internal open class QQAndroidClient(
 
     @UseExperimental(RawAccountIdUse::class)
     @Suppress("PropertyName")
-    internal var _uin: Long = bot.account.id
+    internal var _uin: Long = bot.uin
 
     var t530: ByteArray? = null
     var t528: ByteArray? = null
diff --git a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
index 48c629081..de70962a5 100644
--- a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
+++ b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/Bot.kt
@@ -54,12 +54,6 @@ actual abstract class Bot actual constructor() : CoroutineScope, LowLevelBotAPIA
      */
     actual abstract val context: Context
 
-    /**
-     * 账号信息
-     */
-    @MiraiInternalAPI
-    actual abstract val account: BotAccount
-
     /**
      * QQ 号码. 实际类型为 uint
      */
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
index e8a25b56e..54bb1308e 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
@@ -70,12 +70,6 @@ expect abstract class Bot() : CoroutineScope, LowLevelBotAPIAccessor {
      */
     abstract val context: Context
 
-    /**
-     * 账号信息
-     */
-    @MiraiInternalAPI
-    abstract val account: BotAccount
-
     /**
      * QQ 号码. 实际类型为 uint
      */
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt
index fe0ff4b4d..b4c84333a 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotAccount.kt
@@ -12,6 +12,7 @@
 package net.mamoe.mirai
 
 import io.ktor.utils.io.core.toByteArray
+import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiInternalAPI
 import net.mamoe.mirai.utils.md5
 import kotlin.annotation.AnnotationTarget.*
@@ -23,6 +24,8 @@ data class BotAccount(
      */
     @RawAccountIdUse
     val id: Long,
+    @MiraiExperimentalAPI
+    @MiraiInternalAPI
     val passwordMd5: ByteArray // md5
 ) {
     constructor(id: Long, passwordPlainText: String) : this(id, md5(passwordPlainText.toByteArray()))
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
index da87be75c..2596426c8 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
@@ -7,7 +7,7 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-@file:Suppress("EXPERIMENTAL_API_USAGE")
+@file:Suppress("EXPERIMENTAL_API_USAGE", "DEPRECATION_ERROR")
 
 package net.mamoe.mirai
 
@@ -40,12 +40,13 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
             ?: CoroutineExceptionHandler { _, e -> logger.error("An exception was thrown under a coroutine of Bot", e) })
     override val context: Context by context.unsafeWeakRef()
 
-    @Suppress("CanBePrimaryConstructorProperty") // for logger
+    @UseExperimental(LowLevelAPI::class)
+    @Suppress("CanBePrimaryConstructorProperty", "OverridingDeprecatedMember") // for logger
     final override val account: BotAccount = account
 
     @UseExperimental(RawAccountIdUse::class)
     override val uin: Long
-        get() = account.id
+        get() = this.account.id
     final override val logger: MiraiLogger by lazy { configuration.botLoggerSupplier(this) }
 
     init {
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
index 0940819a6..08387696a 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
@@ -17,6 +17,7 @@ import net.mamoe.mirai.data.GroupInfo
 import net.mamoe.mirai.data.MemberInfo
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
+import net.mamoe.mirai.utils.MiraiInternalAPI
 import net.mamoe.mirai.utils.WeakRef
 
 /**
@@ -37,6 +38,14 @@ annotation class LowLevelAPI
 @Suppress("FunctionName", "unused")
 @LowLevelAPI
 interface LowLevelBotAPIAccessor {
+    /**
+     * 账号信息
+     */
+    @Deprecated("将来会做修改", level = DeprecationLevel.ERROR)
+    @MiraiExperimentalAPI
+    @LowLevelAPI
+    @MiraiInternalAPI
+    abstract val account: BotAccount
 
     /**
      * 构造一个 [_lowLevelNewQQ] 对象. 它持有对 [Bot] 的弱引用([WeakRef]).
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
index f632f790b..73c4fa2c8 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/CombinedMessage.kt
@@ -58,4 +58,8 @@ class CombinedMessage(
     override fun toString(): String {
         return element.toString() + left.toString()
     }
+
+    fun isFlat(): Boolean {
+        return element is SingleMessage && left is SingleMessage
+    }
 }
\ No newline at end of file
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
index 48eecf939..c59e942ac 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
@@ -61,7 +61,7 @@ interface MessageChain : Message, Iterable<SingleMessage> {
     fun <M : Message> getOrNull(key: Message.Key<M>): M? = firstOrNull(key)
 
     /**
-     * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage].
+     * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage], [QuoteReply].
      * 仅供 `Java` 使用
      */
     @Suppress("FunctionName", "INAPPLICABLE_JVM_NAME")
@@ -71,13 +71,26 @@ interface MessageChain : Message, Iterable<SingleMessage> {
     fun `__forEachContent for Java__`(block: (Message) -> Unit) {
         this.foreachContent(block)
     }
+
+    /**
+     * 遍历每一个消息, 即 [MessageSource] [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage], [QuoteReply].
+     * 仅供 `Java` 使用
+     */
+    @Suppress("FunctionName", "INAPPLICABLE_JVM_NAME")
+    @JsName("forEach")
+    @JvmName("forEach")
+    @MiraiInternalAPI
+    fun `__forEach for Java__`(block: (Message) -> Unit) {
+        this.forEach(block)
+    }
 }
 
 // region accessors
 
 /**
- * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
+ * 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage], [QuoteReply]
  */
+@JvmSynthetic
 inline fun MessageChain.foreachContent(block: (Message) -> Unit) {
     this.forEach {
         if (it !is MessageMetadata) block(it)
@@ -87,23 +100,27 @@ inline fun MessageChain.foreachContent(block: (Message) -> Unit) {
 /**
  * 获取第一个 [M] 类型的 [Message] 实例
  */
+@JvmSynthetic
 inline fun <reified M : Message?> MessageChain.firstOrNull(): M? = this.firstOrNull { it is M } as M?
 
 /**
  * 获取第一个 [M] 类型的 [Message] 实例
  * @throws [NoSuchElementException] 如果找不到该类型的实例
  */
+@JvmSynthetic
 inline fun <reified M : Message> MessageChain.first(): M = this.first { it is M } as M
 
 /**
  * 获取第一个 [M] 类型的 [Message] 实例
  */
+@JvmSynthetic
 inline fun <reified M : Message> MessageChain.any(): Boolean = this.any { it is M }
 
 
 /**
  * 获取第一个 [M] 类型的 [Message] 实例
  */
+@JvmSynthetic
 @Suppress("UNCHECKED_CAST")
 fun <M : Message> MessageChain.firstOrNull(key: Message.Key<M>): M? = when (key) {
     At -> first<At>()
@@ -120,6 +137,7 @@ fun <M : Message> MessageChain.firstOrNull(key: Message.Key<M>): M? = when (key)
  * 获取第一个 [M] 类型的 [Message] 实例
  * @throws [NoSuchElementException] 如果找不到该类型的实例
  */
+@JvmSynthetic
 @Suppress("UNCHECKED_CAST")
 fun <M : Message> MessageChain.first(key: Message.Key<M>): M =
     firstOrNull(key) ?: throw NoSuchElementException("no such element: $key")
@@ -127,6 +145,7 @@ fun <M : Message> MessageChain.first(key: Message.Key<M>): M =
 /**
  * 获取第一个 [M] 类型的 [Message] 实例
  */
+@JvmSynthetic
 @Suppress("UNCHECKED_CAST")
 fun <M : Message> MessageChain.any(key: Message.Key<M>): Boolean = firstOrNull(key) != null
 
@@ -211,9 +230,6 @@ fun Message.asMessageChain(): MessageChain = when (this) {
     else -> SingleMessageChainImpl(this as SingleMessage)
 }
 
-@Deprecated("use asMessageChain instead", ReplaceWith("this.asMessageChain()"), DeprecationLevel.ERROR)
-fun Message.toChain(): MessageChain = this.asMessageChain()
-
 /**
  * 直接将 [this] 委托为一个 [MessageChain]
  */
@@ -233,8 +249,18 @@ fun Collection<Message>.asMessageChain(): MessageChain = MessageChainImplBySeque
 @JvmSynthetic
 fun Iterable<SingleMessage>.asMessageChain(): MessageChain = MessageChainImplByIterable(this)
 
+@JvmSynthetic
 inline fun MessageChain.asMessageChain(): MessageChain = this // 避免套娃
 
+@JvmSynthetic
+fun CombinedMessage.asMessageChain(): MessageChain {
+    if (left is SingleMessage && this.element is SingleMessage) {
+        @Suppress("UNCHECKED_CAST")
+        return (this as Iterable<SingleMessage>).asMessageChain()
+    }
+    return (this as Iterable<Message>).asMessageChain()
+} // 避免套娃
+
 /**
  * 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
  */
@@ -324,11 +350,20 @@ fun Sequence<SingleMessage>.flatten(): Sequence<SingleMessage> = this // fast pa
 fun Message.flatten(): Sequence<SingleMessage> {
     return when (this) {
         is MessageChain -> this.asSequence()
-        is CombinedMessage -> this.asSequence().flatten()
+        is CombinedMessage -> this.flatten()
         else -> sequenceOf(this as SingleMessage)
     }
 }
 
+fun CombinedMessage.flatten(): Sequence<SingleMessage> {
+    if (this.isFlat()){
+        @Suppress("UNCHECKED_CAST")
+        return (this as Iterable<SingleMessage>).asSequence()
+    } else return this.asSequence().flatten()
+}
+
+fun MessageChain.flatten(): Sequence<SingleMessage> = this.asSequence() // fast path
+
 // endregion converters
 
 // region implementations
diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
index 509ed8381..93c0ebd52 100644
--- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
+++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Bot.kt
@@ -64,12 +64,6 @@ actual abstract class Bot actual constructor() : CoroutineScope, LowLevelBotAPIA
      */
     actual abstract val context: Context
 
-    /**
-     * 账号信息
-     */
-    @MiraiInternalAPI
-    actual abstract val account: BotAccount
-
     /**
      * QQ 号码. 实际类型为 uint
      */