diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f49ee1ea..4f4ccf6f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Version 1.x
 
+## `1.2.2`  2020/8/22
+- 修复依赖冲突问题 (#523)
+
 ## `1.2.1`  2020/8/19
 - 修复在 Java 调用 `group.uploadImage` 时编译出错的问题 (#511)
 - 为 `group.uploadVoice` 添加 Java 方法 (需要 [kotlin-jvm-blocking-bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge)) (#512)
@@ -8,7 +11,7 @@
 ## `1.2.0`  2020/8/19
 
 ### 新特性
-- 初步语音支持: `Group.uploadVoice`, 支持 silk 或 arm 格式.  
+- 初步语音支持: `Group.uploadVoice`, 支持 silk 或 amr 格式.  
    **注意**: 现阶段语音实现仅为临时方案, 在将来 (`2.0.0`) 一定会变动. 使用时请评估可能带来的不兼容性.
 
 - 新增将日志转换为 log4j, JDK Logger, SLF4J 等框架的方法: `LoggerAdapters` (#498 by [@Karlatemp](https://github.com/Karlatemp))
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index abe4ae21f..b92b21c30 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,6 +8,12 @@ mirai 欢迎一切形式的代码贡献。你可以通过以下几种途径向 m
 
 **阅读文档**: [docs/mirai.md](docs/mirai.md)
 
+### 构建
+- 要构建项目, 请运行 `gradlew assemble`
+- 要运行测试, 请运行 `gradlew test`
+- 要构建项目并运行测试, 请运行 `gradlew build`
+- 若要添加一个 suspend 函数, 请务必考虑 Java 兼容性, 使用 [kotlin-jvm-blocking-bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge/blob/master/README-chs.md)
+
 ### 能做什么?
 
 **请基于 `master` 分支进行文档修改; 基于 `dev` 分支进行其他修改 (否则你的修改可能被关闭或不会立即合并)**
diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt
index f0a7dbb5d..90b01fd16 100644
--- a/buildSrc/src/main/kotlin/Versions.kt
+++ b/buildSrc/src/main/kotlin/Versions.kt
@@ -9,7 +9,7 @@
 
 object Versions {
     object Mirai {
-        const val version = "1.2.1"
+        const val version = "1.2.2"
     }
 
     object Kotlin {
diff --git a/mirai-core-qqandroid/build.gradle.kts b/mirai-core-qqandroid/build.gradle.kts
index 46a8f1d57..637b3e190 100644
--- a/mirai-core-qqandroid/build.gradle.kts
+++ b/mirai-core-qqandroid/build.gradle.kts
@@ -60,14 +60,12 @@ kotlin {
 
         val commonMain by getting {
             dependencies {
-                api(kotlinx("serialization-core", Versions.Kotlin.serialization))
+                api1(kotlinx("serialization-core", Versions.Kotlin.serialization))
                 api(kotlinx("coroutines-core", Versions.Kotlin.coroutines))
-                implementation(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
-                api("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
-                api(kotlinx("io", Versions.Kotlin.io)) {
-                    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                }
-                implementation(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
+                implementation1(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
+                api1("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
+                api1(kotlinx("io", Versions.Kotlin.io))
+                implementation1(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
             }
         }
 
@@ -97,11 +95,8 @@ kotlin {
 
         val jvmMain by getting {
             dependencies {
-                runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE
                 implementation("org.bouncycastle:bcprov-jdk15on:1.64")
-                api(kotlinx("io-jvm", Versions.Kotlin.io)) {
-                    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                }
+                api1(kotlinx("io-jvm", Versions.Kotlin.io))
                 //    api(kotlinx("coroutines-debug", Versions.Kotlin.coroutines))
             }
         }
@@ -112,14 +107,29 @@ kotlin {
                 implementation(kotlin("test", Versions.Kotlin.compiler))
                 implementation(kotlin("test-junit", Versions.Kotlin.compiler))
                 implementation("org.pcap4j:pcap4j-distribution:1.8.2")
-
-                runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE
-                runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE
             }
         }
     }
 }
 
+fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
+    implementation(dependencyNotation) {
+        exclude("org.jetbrains.kotlin", "kotlin-stdlib")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
+    }
+
+fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNotation: String) =
+    api(dependencyNotation) {
+        exclude("org.jetbrains.kotlin", "kotlin-stdlib")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
+    }
+
 apply(from = rootProject.file("gradle/publish.gradle"))
 
 
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
index 53e7c17b7..ea8726168 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
@@ -180,7 +180,7 @@ internal class MemberImpl constructor(
         check(this.id != bot.id) {
             "A bot can't mute itself."
         }
-        checkBotPermissionHigherThanThis()
+        checkBotPermissionHigherThanThis("mute")
         bot.network.run {
             TroopManagement.Mute(
                 client = bot.client,
@@ -194,10 +194,10 @@ internal class MemberImpl constructor(
         net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast()
     }
 
-    private fun checkBotPermissionHigherThanThis() {
+    private fun checkBotPermissionHigherThanThis(operationName: String) {
         check(group.botPermission > this.permission) {
             throw PermissionDeniedException(
-                "`kick` operation requires bot to have a higher permission than the target member, " +
+                "`$operationName` operation requires bot to have a higher permission than the target member, " +
                         "but bot's is ${group.botPermission}, target's is ${this.permission}"
             )
         }
@@ -205,7 +205,7 @@ internal class MemberImpl constructor(
 
     @JvmSynthetic
     override suspend fun unmute() {
-        checkBotPermissionHigherThanThis()
+        checkBotPermissionHigherThanThis("unmute")
         bot.network.run {
             TroopManagement.Mute(
                 client = bot.client,
@@ -222,7 +222,7 @@ internal class MemberImpl constructor(
 
     @JvmSynthetic
     override suspend fun kick(message: String) {
-        checkBotPermissionHigherThanThis()
+        checkBotPermissionHigherThanThis("kick")
         check(group.members.getOrNull(this.id) != null) {
             "Member ${this.id} had already been kicked from group ${group.id}"
         }
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt
index 0f07c98a5..f357e0af6 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/MsgSvc.kt
@@ -19,7 +19,7 @@ internal class MsgSvc : ProtoBuf {
         @ProtoNumber(1) @JvmField val result: Int = 0,
         @ProtoNumber(2) @JvmField val errmsg: String = "",
         @ProtoNumber(3) @JvmField val syncCookie: ByteArray? = EMPTY_BYTE_ARRAY,
-        @ProtoNumber(4) @JvmField val syncFlag: SyncFlag,
+        @ProtoNumber(4) @JvmField val syncFlag: SyncFlag = SyncFlag.CONTINUE,
         @ProtoNumber(5) @JvmField val uinPairMsgs: List<MsgComm.UinPairMsg>? = null,
         @ProtoNumber(6) @JvmField val bindUin: Long = 0L,
         @ProtoNumber(7) @JvmField val msgRspType: Int = 0,
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt
index 41ace422f..6eed3e4c6 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt
@@ -14,6 +14,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
 import kotlinx.atomicfu.loop
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.*
+import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import kotlinx.io.core.ByteReadPacket
 import kotlinx.io.core.discardExact
@@ -43,6 +44,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
 import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl
 import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact
 import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
+import net.mamoe.mirai.qqandroid.utils._miraiContentToString
 import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
 import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
 import net.mamoe.mirai.qqandroid.utils.read
@@ -56,6 +58,12 @@ import net.mamoe.mirai.utils.warning
  * 获取好友消息和消息记录
  */
 internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Response>("MessageSvc.PbGetMsg") {
+
+
+    private val msgUidQueue = ArrayDeque<Long>()
+    private val msgUidSet = hashSetOf<Long>()
+    private val msgQueueMutex = Mutex()
+
     @Suppress("SpellCheckingInspection")
     operator fun invoke(
         client: QQAndroidClient,
@@ -114,8 +122,9 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
 
     private fun MsgComm.Msg.getNewMemberInfo(): MemberInfo {
         return object : MemberInfo {
-            override val nameCard: String get() = msgHead.authNick.takeIf { it.isNotEmpty() }
-                ?: msgHead.fromNick
+            override val nameCard: String
+                get() = msgHead.authNick.takeIf { it.isNotEmpty() }
+                    ?: msgHead.fromNick
             override val permission: MemberPermission get() = MemberPermission.MEMBER
             override val specialTitle: String get() = ""
             override val muteTimestamp: Int get() = 0
@@ -135,9 +144,23 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                 .warning { "MessageSvcPushNotify: result != 0, result = ${resp.result}, errorMsg=${resp.errmsg}" }
             return EmptyResponse
         }
+        when (resp.msgRspType) {
+            0 -> {
+                bot.client.c2cMessageSync.syncCookie = resp.syncCookie
+                bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie
+            }
+            1 -> {
+                bot.client.c2cMessageSync.syncCookie = resp.syncCookie
+            }
+            2 -> {
+                bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie
+
+            }
+        }
+
+//        bot.logger.debug(resp.msgRspType._miraiContentToString())
+//        bot.logger.debug(resp.syncCookie._miraiContentToString())
 
-        bot.client.c2cMessageSync.syncCookie = resp.syncCookie
-        bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie
         bot.client.c2cMessageSync.msgCtrlBuf = resp.msgCtrlBuf
 
         if (resp.uinPairMsgs == null) {
@@ -151,10 +174,21 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                     .filter { msg: MsgComm.Msg -> msg.msgHead.msgTime > it.lastReadTime.toLong() and 4294967295L }
             }.also {
                 MessageSvcPbDeleteMsg.delete(bot, it) // 删除消息
-                // todo 实现一个锁来防止重复收到消息
             }
             .mapNotNull<MsgComm.Msg, Packet> { msg ->
 
+                msgQueueMutex.lock()
+                val msgUid = msg.msgHead.msgUid
+                if (msgUidSet.size > 50) {
+                    msgUidSet.remove(msgUidQueue.removeFirst())
+                }
+                if (!msgUidSet.add(msgUid)) {
+                    msgQueueMutex.unlock()
+                    return@mapNotNull null
+                }
+                msgQueueMutex.unlock()
+                msgUidQueue.addLast(msgUid)
+
                 suspend fun createGroupForBot(groupUin: Long): Group? {
                     val group = bot.getGroupByUinOrNull(groupUin)
                     if (group != null) {
@@ -294,18 +328,15 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                             return@mapNotNull null
                         }
 
-                        if (friend.lastMessageSequence.compareAndSet(
-                                friend.lastMessageSequence.value,
-                                msg.msgHead.msgSeq
-                            )
-                        ) {
-                            return@mapNotNull FriendMessageEvent(
-                                friend,
-                                msg.toMessageChain(bot, groupIdOrZero = 0, onlineSource = true),
-                                msg.msgHead.msgTime
-                            )
+                        friend.lastMessageSequence.loop {
+                            if (friend.lastMessageSequence.compareAndSet(it, msg.msgHead.msgSeq)) {
+                                return@mapNotNull FriendMessageEvent(
+                                    friend,
+                                    msg.toMessageChain(bot, groupIdOrZero = 0, onlineSource = true),
+                                    msg.msgHead.msgTime
+                                )
+                            } else return@mapNotNull null
                         }
-                        return@mapNotNull null
                     }
                     208 -> {
                         // friend ptt
@@ -387,7 +418,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                     MessageSvcPbGetMsg(
                         client,
                         MsgSvc.SyncFlag.CONTINUE,
-                        packet.syncCookie
+                        bot.client.c2cMessageSync.syncCookie
                     ).sendAndExpect<Packet>()
                 }
                 return
@@ -398,7 +429,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
                     MessageSvcPbGetMsg(
                         client,
                         MsgSvc.SyncFlag.CONTINUE,
-                        packet.syncCookie
+                        bot.client.c2cMessageSync.syncCookie
                     ).sendAndExpect<Packet>()
                 }
                 return
diff --git a/mirai-core/build.gradle.kts b/mirai-core/build.gradle.kts
index b0971340e..7efa4d7e7 100644
--- a/mirai-core/build.gradle.kts
+++ b/mirai-core/build.gradle.kts
@@ -63,21 +63,17 @@ kotlin {
                 api(kotlin("serialization"))
                 api(kotlin("reflect"))
 
-                api(kotlinx("serialization-core", Versions.Kotlin.serialization))
-                implementation(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
-                api(kotlinx("io", Versions.Kotlin.io)) {
-                    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                }
-                api(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo)) {
-                    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                }
+                api1(kotlinx("serialization-core", Versions.Kotlin.serialization))
+                implementation1(kotlinx("serialization-protobuf", Versions.Kotlin.serialization))
+                api1(kotlinx("io", Versions.Kotlin.io))
+                api1(kotlinx("coroutines-io", Versions.Kotlin.coroutinesIo))
                 api(kotlinx("coroutines-core", Versions.Kotlin.coroutines))
 
-                implementation("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
+                implementation1("org.jetbrains.kotlinx:atomicfu:${Versions.Kotlin.atomicFU}")
 
-                api(ktor("client-cio"))
-                api(ktor("client-core"))
-                api(ktor("network"))
+                api1(ktor("client-cio"))
+                api1(ktor("client-core"))
+                api1(ktor("network"))
             }
         }
 
@@ -93,14 +89,10 @@ kotlin {
                 dependencies {
                     api(kotlin("reflect"))
 
-                    api(kotlinx("io-jvm", Versions.Kotlin.io)) {
-                        exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                    }
-                    api(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo)) {
-                        exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                    }
+                    api1(kotlinx("io-jvm", Versions.Kotlin.io))
+                    api1(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo))
 
-                    api(ktor("client-android", Versions.Kotlin.ktor))
+                    api1(ktor("client-android", Versions.Kotlin.ktor))
                 }
             }
 
@@ -116,21 +108,13 @@ kotlin {
 
         val jvmMain by getting {
             dependencies {
-                //api(kotlin("stdlib-jdk8"))
-                //api(kotlin("stdlib-jdk7"))
                 api(kotlin("reflect"))
                 compileOnly("org.apache.logging.log4j:log4j-api:" + Versions.Logging.log4j)
                 compileOnly("org.slf4j:slf4j-api:" + Versions.Logging.slf4j)
 
-                api(ktor("client-core-jvm", Versions.Kotlin.ktor))
-                api(kotlinx("io-jvm", Versions.Kotlin.io)) {
-                    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                }
-                api(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo)) {
-                    exclude("org.jetbrains.kotlin", "kotlin-stdlib")
-                }
-
-                runtimeOnly(files("build/classes/kotlin/jvm/main")) // classpath is not properly set by IDE
+                api1(ktor("client-core-jvm", Versions.Kotlin.ktor))
+                api1(kotlinx("io-jvm", Versions.Kotlin.io))
+                api1(kotlinx("coroutines-io-jvm", Versions.Kotlin.coroutinesIo))
             }
         }
 
@@ -146,6 +130,24 @@ kotlin {
     }
 }
 
+fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.implementation1(dependencyNotation: String) =
+    implementation(dependencyNotation) {
+        exclude("org.jetbrains.kotlin", "kotlin-stdlib")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
+    }
+
+fun org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler.api1(dependencyNotation: String) =
+    api(dependencyNotation) {
+        exclude("org.jetbrains.kotlin", "kotlin-stdlib")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-common")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm")
+        exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core-metadata")
+    }
+
 apply(from = rootProject.file("gradle/publish.gradle"))
 
 tasks.withType<com.jfrog.bintray.gradle.tasks.BintrayUploadTask> {
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
index 664110225..54d869940 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
@@ -26,7 +26,7 @@ import kotlin.reflect.KClass
 internal fun <L : Listener<E>, E : Event> KClass<out E>.subscribeInternal(listener: L): L {
     with(GlobalEventListeners[listener.priority]) {
         @Suppress("UNCHECKED_CAST")
-        val node = ListenerNode(listener as Listener<Event>, this@subscribeInternal)
+        val node = ListenerRegistry(listener as Listener<Event>, this@subscribeInternal)
         addLast(node)
         listener.invokeOnCompletion {
             this.remove(node)
@@ -107,13 +107,13 @@ internal class Handler<in E : Event> internal constructor(
     }
 }
 
-internal class ListenerNode(
+internal class ListenerRegistry(
     val listener: Listener<Event>,
-    val owner: KClass<out Event>
+    val type: KClass<out Event>
 )
 
 internal expect object GlobalEventListeners {
-    operator fun get(priority: Listener.EventPriority): LockFreeLinkedList<ListenerNode>
+    operator fun get(priority: Listener.EventPriority): LockFreeLinkedList<ListenerRegistry>
 }
 
 internal expect class MiraiAtomicBoolean(initial: Boolean) {
@@ -135,50 +135,50 @@ internal suspend inline fun AbstractEvent.broadcastInternal() {
 internal suspend inline fun <E : AbstractEvent> callAndRemoveIfRequired(
     event: E
 ) {
-    for (p in Listener.EventPriority.valuesExceptMonitor) {
-        GlobalEventListeners[p].forEachNode { eventNode ->
+    for (p in Listener.EventPriority.prioritiesExcludedMonitor) {
+        GlobalEventListeners[p].forEachNode { registeredRegistryNode ->
             if (event.isIntercepted) {
                 return
             }
-            val node = eventNode.nodeValue
-            if (!node.owner.isInstance(event)) return@forEachNode
-            val listener = node.listener
+            val listenerRegistry = registeredRegistryNode.nodeValue
+            if (!listenerRegistry.type.isInstance(event)) return@forEachNode
+            val listener = listenerRegistry.listener
             when (listener.concurrencyKind) {
                 Listener.ConcurrencyKind.LOCKED -> {
                     (listener as Handler).lock!!.withLock {
                         if (listener.onEvent(event) == ListeningStatus.STOPPED) {
-                            removeNode(eventNode)
+                            removeNode(registeredRegistryNode)
                         }
                     }
                 }
                 Listener.ConcurrencyKind.CONCURRENT -> {
                     if (listener.onEvent(event) == ListeningStatus.STOPPED) {
-                        removeNode(eventNode)
+                        removeNode(registeredRegistryNode)
                     }
                 }
             }
         }
     }
     coroutineScope {
-        GlobalEventListeners[EventPriority.MONITOR].forEachNode { eventNode ->
+        GlobalEventListeners[EventPriority.MONITOR].forEachNode { registeredRegistryNode ->
             if (event.isIntercepted) {
                 return@coroutineScope
             }
-            val node = eventNode.nodeValue
-            if (!node.owner.isInstance(event)) return@forEachNode
-            val listener = node.listener
+            val listenerRegistry = registeredRegistryNode.nodeValue
+            if (!listenerRegistry.type.isInstance(event)) return@forEachNode
+            val listener = listenerRegistry.listener
             launch {
                 when (listener.concurrencyKind) {
                     Listener.ConcurrencyKind.LOCKED -> {
                         (listener as Handler).lock!!.withLock {
                             if (listener.onEvent(event) == ListeningStatus.STOPPED) {
-                                removeNode(eventNode)
+                                removeNode(registeredRegistryNode)
                             }
                         }
                     }
                     Listener.ConcurrencyKind.CONCURRENT -> {
                         if (listener.onEvent(event) == ListeningStatus.STOPPED) {
-                            removeNode(eventNode)
+                            removeNode(registeredRegistryNode)
                         }
                     }
                 }
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
index fd46a3582..8064800bd 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/subscriber.kt
@@ -110,7 +110,9 @@ public interface Listener<in E : Event> : CompletableJob {
 
         internal companion object {
             @JvmStatic
-            internal val valuesExceptMonitor: Array<EventPriority> = arrayOf(HIGHEST, HIGH, NORMAL, LOW, LOWEST)
+            internal val prioritiesExcludedMonitor: Array<EventPriority> = run {
+                values().filter { it != MONITOR }.toTypedArray()
+            }
         }
     }
 
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
index de6182ae5..05d4d479c 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
@@ -844,7 +844,7 @@ internal open class LockFreeLinkedListNode<E>(
      * [Tail], is not being tested.
      */
     inline fun allMatching(condition: (LockFreeLinkedListNode<E>) -> Boolean): Boolean =
-        this.childIterateReturnsLastSatisfying({ it.nextNode }, condition) !is Tail
+        this.childIterateReturnsLastSatisfying({ it.nextNode }, condition) is Tail
 
     /**
      * Stop on and returns the former element of the element that is [equals] to the [element]
diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt
new file mode 100644
index 000000000..4b58df483
--- /dev/null
+++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/GlobalEventListeners.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019-2020 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+package net.mamoe.mirai.event.internal
+
+import net.mamoe.mirai.event.Listener
+import net.mamoe.mirai.utils.LockFreeLinkedList
+import java.util.*
+
+
+internal actual object GlobalEventListeners {
+    private val ALL_LEVEL_REGISTRIES: Map<Listener.EventPriority, LockFreeLinkedList<ListenerRegistry>>
+
+    init {
+        val map = EnumMap<Listener.EventPriority, LockFreeLinkedList<ListenerRegistry>>(Listener.EventPriority::class.java)
+        Listener.EventPriority.values().forEach {
+            map[it] = LockFreeLinkedList()
+        }
+        this.ALL_LEVEL_REGISTRIES = map
+    }
+
+    actual operator fun get(priority: Listener.EventPriority): LockFreeLinkedList<ListenerRegistry> = ALL_LEVEL_REGISTRIES[priority]!!
+
+}
diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt
index a5bb1f3fe..0ed43c023 100644
--- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt
+++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/MiraiAtomicBoolean.kt
@@ -9,16 +9,10 @@
 
 package net.mamoe.mirai.event.internal
 
-import net.mamoe.mirai.event.Event
 import net.mamoe.mirai.event.Listener
 import net.mamoe.mirai.utils.LockFreeLinkedList
-import net.mamoe.mirai.utils.LockFreeLinkedListNode
-import net.mamoe.mirai.utils.isRemoved
-import net.mamoe.mirai.utils.MiraiInternalAPI
 import java.util.*
 import java.util.concurrent.atomic.AtomicBoolean
-import kotlin.reflect.KClass
-
 
 internal actual class MiraiAtomicBoolean actual constructor(initial: Boolean) {
     private val delegate: AtomicBoolean = AtomicBoolean(initial)
@@ -33,42 +27,3 @@ internal actual class MiraiAtomicBoolean actual constructor(initial: Boolean) {
             delegate.set(value)
         }
 }
-
-internal actual object GlobalEventListeners {
-    private val map: Map<Listener.EventPriority, LockFreeLinkedList<ListenerNode>>
-
-    init {
-        val map = EnumMap<Listener.EventPriority, LockFreeLinkedList<ListenerNode>>(Listener.EventPriority::class.java)
-        Listener.EventPriority.values().forEach {
-            map[it] = LockFreeLinkedList()
-        }
-        this.map = map
-    }
-
-    actual operator fun get(priority: Listener.EventPriority): LockFreeLinkedList<ListenerNode> = map[priority]!!
-
-}
-
-/*
-internal actual class EventListeners<E : Event> actual constructor(clazz: KClass<E>) :
-    LockFreeLinkedList<Listener<E>>() {
-    @Suppress("UNCHECKED_CAST", "UNSUPPORTED", "NO_REFLECTION_IN_CLASS_PATH")
-    actual val supertypes: Set<KClass<out Event>> by lazy {
-        val supertypes = mutableSetOf<KClass<out Event>>()
-
-        fun addSupertypes(klass: KClass<out Event>) {
-            klass.supertypes.forEach {
-                val classifier = it.classifier as? KClass<out Event>
-                if (classifier != null) {
-                    supertypes.add(classifier)
-                    addSupertypes(classifier)
-                }
-            }
-        }
-        addSupertypes(clazz)
-
-        supertypes
-    }
-
-}
- */
\ No newline at end of file
diff --git a/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt b/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
index bc5c52ac6..a439df16f 100644
--- a/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
+++ b/mirai-core/src/jvmTest/kotlin/net/mamoe/mirai/utils/LockFreeLinkedListTest.kt
@@ -33,6 +33,14 @@ internal class LockFreeLinkedListTest {
         list.size shouldBeEqualTo 4
     }
 
+    @Test
+    fun isEmpty() {
+        val list = LockFreeLinkedList<Int>()
+        assertTrue { list.isEmpty() }
+        list.addLast(1)
+        assertFalse { list.isEmpty() }
+    }
+
     @Test
     fun addAndGetConcurrent() = runBlocking {
         //withContext(Dispatchers.Default){