diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala
index db34f225139f549ce7ae75a1c6d28dfe078e9c39..aea42a2fb4efa4f02b00126e8932d219eb7a5cc1 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala
@@ -7,7 +7,7 @@ import org.bigbluebutton.core2.{ MeetingStatus2x }
 
 object LockSettingsUtil {
 
-  def muteUserInVoiceConf(liveMeeting: LiveMeeting, outGW: OutMsgRouter, vu: VoiceUserState, mute: Boolean): Unit = {
+  private def muteUserInVoiceConf(liveMeeting: LiveMeeting, outGW: OutMsgRouter, vu: VoiceUserState, mute: Boolean): Unit = {
     val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, vu.intId)
     val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing)
     val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, liveMeeting.props.meetingProp.intId)
@@ -19,20 +19,17 @@ object LockSettingsUtil {
     outGW.send(msgEvent)
   }
 
-  def applyMutingOfUsers(mute: Boolean, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
+  private def applyMutingOfUsers(disableMic: Boolean, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
     VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu =>
       Users2x.findWithIntId(liveMeeting.users2x, vu.intId).foreach { user =>
-        if (user.role == Roles.VIEWER_ROLE) {
-          if (mute) {
-            // Mute everyone. We also mute listenOnly users as sledgehammer to make sure
-            // audio can't be transmitted. (ralam dec 6, 2019)
-            muteUserInVoiceConf(liveMeeting, outGW, vu, mute)
-          } else {
-            // Only unmute viewers and non-listenOnly users.
-            if (!vu.listenOnly) {
-              muteUserInVoiceConf(liveMeeting, outGW, vu, mute)
-            }
-          }
+        if (user.role == Roles.VIEWER_ROLE && !vu.listenOnly) {
+          // Apply lock setting to users who are not listen only. (ralam dec 6, 2019)
+          muteUserInVoiceConf(liveMeeting, outGW, vu, disableMic)
+        }
+
+        // Make sure listen only users are muted. (ralam dec 6, 2019)
+        if (vu.listenOnly && !vu.muted) {
+          muteUserInVoiceConf(liveMeeting, outGW, vu, true)
         }
       }
     }
@@ -41,25 +38,21 @@ object LockSettingsUtil {
   def enforceLockSettingsForAllVoiceUsers(liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
     val permissions = MeetingStatus2x.getPermissions(liveMeeting.status)
     applyMutingOfUsers(permissions.disableMic, liveMeeting, outGW)
-
   }
 
-  def enforceLockSettingsForVoiceUser(intUserId: String, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
+  def enforceLockSettingsForVoiceUser(voiceUser: VoiceUserState, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = {
     val permissions = MeetingStatus2x.getPermissions(liveMeeting.status)
     if (permissions.disableMic) {
-      Users2x.findWithIntId(liveMeeting.users2x, intUserId).foreach { user =>
+      Users2x.findWithIntId(liveMeeting.users2x, voiceUser.intId).foreach { user =>
         if (user.role == Roles.VIEWER_ROLE) {
-          val voiceUser = VoiceUsers.findWithIntId(liveMeeting.voiceUsers, intUserId)
-          voiceUser.foreach { vu =>
-            // Make sure that user is muted when lock settings has mic disabled. (ralam dec 6, 2019
-            if (!vu.muted) {
-              muteUserInVoiceConf(liveMeeting, outGW, vu, true)
-            }
+          // Make sure that user is muted when lock settings has mic disabled. (ralam dec 6, 2019
+          if (!voiceUser.muted) {
+            muteUserInVoiceConf(liveMeeting, outGW, voiceUser, true)
           }
         }
       }
     } else {
-      enforceListenOnlyUserIsMuted(intUserId, liveMeeting, outGW)
+      enforceListenOnlyUserIsMuted(voiceUser.intId, liveMeeting, outGW)
     }
   }
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserTalkingInVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserTalkingInVoiceConfEvtMsgHdlr.scala
index 5b7314d2798dd2b01fe28988ebb785161caaf3da..709697bf1f9f343241f146c3ab783810a27665d6 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserTalkingInVoiceConfEvtMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserTalkingInVoiceConfEvtMsgHdlr.scala
@@ -37,7 +37,7 @@ trait UserTalkingInVoiceConfEvtMsgHdlr {
     } yield {
       // Make sure lock settings are in effect (ralam dec 6, 2019)
       LockSettingsUtil.enforceLockSettingsForVoiceUser(
-        talkingUser.intId,
+        talkingUser,
         liveMeeting,
         outGW
       )
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala
index 9306f35d39d39574d01b8bfe7c4acc7262fd5937..d2d374d8aab589e6542c1a67bcd634be8ac7c53a 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala
@@ -97,18 +97,19 @@ object VoiceApp {
       if (!muted) {
         // Make sure lock settings are in effect (ralam dec 6, 2019)
         LockSettingsUtil.enforceLockSettingsForVoiceUser(
-          mutedUser.intId,
-          liveMeeting,
-          outGW
-        )
-      } else {
-        broadcastUserMutedVoiceEvtMsg(
-          liveMeeting.props.meetingProp.intId,
           mutedUser,
-          liveMeeting.props.voiceProp.voiceConf,
+          liveMeeting,
           outGW
         )
       }
+
+      broadcastUserMutedVoiceEvtMsg(
+        liveMeeting.props.meetingProp.intId,
+        mutedUser,
+        liveMeeting.props.voiceProp.voiceConf,
+        outGW
+      )
+
     }
   }
 
@@ -170,6 +171,20 @@ object VoiceApp {
     }
   }
 
+  private def checkAndEjectOldDuplicateVoiceConfUser(
+      userid:      String,
+      liveMeeting: LiveMeeting,
+      outGW:       OutMsgRouter
+  ): Unit = {
+    for {
+      u <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, userid)
+      oldU <- VoiceUsers.removeWithIntId(liveMeeting.voiceUsers, userid)
+    } yield {
+      val event = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(liveMeeting.props.meetingProp.intId, liveMeeting.props.voiceProp.voiceConf, oldU.voiceUserId)
+      outGW.send(event)
+    }
+  }
+
   def handleUserJoinedVoiceConfEvtMsg(
       liveMeeting:  LiveMeeting,
       outGW:        OutMsgRouter,
@@ -224,6 +239,8 @@ object VoiceApp {
       outGW.send(msgEvent)
     }
 
+    checkAndEjectOldDuplicateVoiceConfUser(intId, liveMeeting, outGW)
+
     val isListenOnly = if (callerIdName.startsWith("LISTENONLY")) true else false
 
     val voiceUserState = VoiceUserState(
@@ -263,12 +280,11 @@ object VoiceApp {
 
     // Make sure lock settings are in effect. (ralam dec 6, 2019)
     LockSettingsUtil.enforceLockSettingsForVoiceUser(
-      intId,
+      voiceUserState,
       liveMeeting,
       outGW
     )
 
-    LockSettingsUtil.enforceLockSettingsForVoiceUser(intId, liveMeeting, outGW)
   }
 
   def handleUserLeftVoiceConfEvtMsg(