diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SendRecordingTimerInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SendRecordingTimerInternalMsgHdlr.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b4c71c0d72532542aa29e4383d7b8371b9031b3f
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SendRecordingTimerInternalMsgHdlr.scala
@@ -0,0 +1,41 @@
+package org.bigbluebutton.core.apps.users
+
+import org.bigbluebutton.common2.msgs._
+import org.bigbluebutton.core.api.SendRecordingTimerInternalMsg
+import org.bigbluebutton.core.domain.MeetingState2x
+import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
+import org.bigbluebutton.core.util.TimeUtil
+import org.bigbluebutton.core2.MeetingStatus2x
+
+trait SendRecordingTimerInternalMsgHdlr {
+  this: UsersApp =>
+
+  val liveMeeting: LiveMeeting
+  val outGW: OutMsgRouter
+
+ def handleSendRecordingTimerInternalMsg(msg: SendRecordingTimerInternalMsg, state: MeetingState2x): MeetingState2x = {
+    def buildUpdateReocrdingTimerEvtMsg(meetingId: String, recordingTime: Long): BbbCommonEnvCoreMsg = {
+      val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
+      val envelope = BbbCoreEnvelope(UpdateRecordingTimerEvtMsg.NAME, routing)
+      val body = UpdateRecordingTimerEvtMsgBody(recordingTime)
+      val header = BbbClientMsgHeader(UpdateRecordingTimerEvtMsg.NAME, meetingId, "not-used")
+      val event = UpdateRecordingTimerEvtMsg(header, body)
+
+      BbbCommonEnvCoreMsg(envelope, event)
+    }
+
+    var newDuration = 0L
+    if (MeetingStatus2x.isRecording(liveMeeting.status)) {
+      newDuration = TimeUtil.timeNowInMs()
+    }
+
+    val tracker = state.recordingTracker.udpateCurrentDuration(newDuration)
+
+    val recordingTime = TimeUtil.millisToSeconds(tracker.recordingDuration())
+
+    val event = buildUpdateReocrdingTimerEvtMsg(liveMeeting.props.meetingProp.intId, recordingTime)
+    outGW.send(event)
+
+    state.update(tracker)
+  }
+}
\ No newline at end of file
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala
index a71c10dbf11cabe1cc9bb39de5c11f4413a2a2fd..cbccb68a71dd92342fba4374072b709c0322331e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala
@@ -1,59 +1,56 @@
-package org.bigbluebutton.core.apps.users
-
-import org.bigbluebutton.common2.msgs._
-import org.bigbluebutton.core.domain.{ MeetingRecordingTracker, MeetingState2x }
-import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
-import org.bigbluebutton.core2.MeetingStatus2x
-import org.bigbluebutton.core.util.TimeUtil
-
-trait SetRecordingStatusCmdMsgHdlr {
-  this: UsersApp =>
-
-  val liveMeeting: LiveMeeting
-  val outGW: OutMsgRouter
-
-  def handleSetRecordingStatusCmdMsg(msg: SetRecordingStatusCmdMsg, state: MeetingState2x): MeetingState2x = {
-    log.info("Change recording status. meetingId=" + liveMeeting.props.meetingProp.intId + " recording=" + msg.body.recording)
-
-    def buildRecordingStatusChangedEvtMsg(meetingId: String, userId: String, recording: Boolean): BbbCommonEnvCoreMsg = {
-      val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
-      val envelope = BbbCoreEnvelope(RecordingStatusChangedEvtMsg.NAME, routing)
-      val body = RecordingStatusChangedEvtMsgBody(recording, userId)
-      val header = BbbClientMsgHeader(RecordingStatusChangedEvtMsg.NAME, meetingId, userId)
-      val event = RecordingStatusChangedEvtMsg(header, body)
-
-      BbbCommonEnvCoreMsg(envelope, event)
-    }
-
-    if (liveMeeting.props.recordProp.allowStartStopRecording &&
-      MeetingStatus2x.isRecording(liveMeeting.status) != msg.body.recording) {
-      if (msg.body.recording) {
-        log.debug("+++++++ Start timer {}", TimeUtil.timeNowInMs())
-
-        MeetingStatus2x.recordingStarted(liveMeeting.status)
-
-      } else {
-        MeetingStatus2x.recordingStopped(liveMeeting.status)
-      }
-
-      val event = buildRecordingStatusChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.setBy, msg.body.recording)
-      outGW.send(event)
-
-      if (MeetingStatus2x.isRecording(liveMeeting.status)) {
-        val tracker = state.recordingTracker.startTimer(TimeUtil.timeNowInMs())
-        state.update(tracker)
-      } else {
-        println("pause - before:  start=" + state.recordingTracker.startedOnInMs
-          + " previous=" + state.recordingTracker.previousDurationInMs
-          + " current=" + state.recordingTracker.currentDurationInMs)
-        val tracker = state.recordingTracker.pauseTimer(TimeUtil.timeNowInMs())
-        println("pause - after: start=" + tracker.startedOnInMs + " previous=" + tracker.previousDurationInMs + " current=" + tracker.currentDurationInMs)
-        state.update(tracker)
-      }
-
-    } else {
-      state
-    }
-
-  }
-}
+package org.bigbluebutton.core.apps.users
+
+import org.bigbluebutton.common2.msgs._
+import org.bigbluebutton.core.domain.MeetingState2x
+import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
+import org.bigbluebutton.core2.MeetingStatus2x
+import org.bigbluebutton.core.util.TimeUtil
+import org.bigbluebutton.core.bus.BigBlueButtonEvent
+import org.bigbluebutton.core.api.SendRecordingTimerInternalMsg
+
+trait SetRecordingStatusCmdMsgHdlr {
+  this: UsersApp =>
+
+  val liveMeeting: LiveMeeting
+  val outGW: OutMsgRouter
+
+  def handleSetRecordingStatusCmdMsg(msg: SetRecordingStatusCmdMsg, state: MeetingState2x): MeetingState2x = {
+    log.info("Change recording status. meetingId=" + liveMeeting.props.meetingProp.intId + " recording=" + msg.body.recording)
+
+    def buildRecordingStatusChangedEvtMsg(meetingId: String, userId: String, recording: Boolean): BbbCommonEnvCoreMsg = {
+      val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
+      val envelope = BbbCoreEnvelope(RecordingStatusChangedEvtMsg.NAME, routing)
+      val body = RecordingStatusChangedEvtMsgBody(recording, userId)
+      val header = BbbClientMsgHeader(RecordingStatusChangedEvtMsg.NAME, meetingId, userId)
+      val event = RecordingStatusChangedEvtMsg(header, body)
+
+      BbbCommonEnvCoreMsg(envelope, event)
+    }
+
+    if (liveMeeting.props.recordProp.allowStartStopRecording &&
+      MeetingStatus2x.isRecording(liveMeeting.status) != msg.body.recording) {
+      if (msg.body.recording) {
+        MeetingStatus2x.recordingStarted(liveMeeting.status)
+      } else {
+        MeetingStatus2x.recordingStopped(liveMeeting.status)
+      }
+
+      val event = buildRecordingStatusChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.setBy, msg.body.recording)
+      outGW.send(event)
+
+      var newState = state
+      if (MeetingStatus2x.isRecording(liveMeeting.status)) {
+        val tracker = state.recordingTracker.startTimer(TimeUtil.timeNowInMs())
+        newState = state.update(tracker)
+      } else {
+        val tracker = state.recordingTracker.pauseTimer(TimeUtil.timeNowInMs())
+        newState = state.update(tracker)
+      }
+      eventBus.publish(BigBlueButtonEvent(liveMeeting.props.meetingProp.intId, SendRecordingTimerInternalMsg(liveMeeting.props.meetingProp.intId)))
+      newState
+    } else {
+      state
+    }
+
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
index f2c0442bb856ec5c2b895e0a6be249440e497a13..bf532ed983ef598f0c21fd6d787668d08077891d 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
@@ -19,6 +19,7 @@ class UsersApp(
     with LogoutAndEndMeetingCmdMsgHdlr
     with MeetingActivityResponseCmdMsgHdlr
     with SetRecordingStatusCmdMsgHdlr
+    with SendRecordingTimerInternalMsgHdlr
     with UpdateWebcamsOnlyForModeratorCmdMsgHdlr
     with GetRecordingStatusReqMsgHdlr
     with GetWebcamsOnlyForModeratorReqMsgHdlr
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingInactivityTracker.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingInactivityTracker.scala
index dba0cd05ec1a2d76abbb7ca95873ad038343adb4..820c72672d07f81d9c17a1cea1a9caee6ce6be2a 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingInactivityTracker.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingInactivityTracker.scala
@@ -102,11 +102,11 @@ case class MeetingRecordingTracker(
   }
 
   def pauseTimer(nowInMs: Long): MeetingRecordingTracker = {
-    copy(currentDurationInMs = 0, previousDurationInMs = previousDurationInMs + nowInMs - startedOnInMs)
+    copy(currentDurationInMs = 0L, previousDurationInMs = previousDurationInMs + nowInMs - startedOnInMs, startedOnInMs = 0L)
   }
 
   def stopTimer(nowInMs: Long): MeetingRecordingTracker = {
-    copy(startedOnInMs = 0, previousDurationInMs = 0, currentDurationInMs = 0)
+    copy(startedOnInMs = 0L, previousDurationInMs = 0L, currentDurationInMs = 0L)
   }
 
   def udpateCurrentDuration(nowInMs: Long): MeetingRecordingTracker = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala
index 746518f757287a1e6a359a5c3d3816b3edc06287..a0af719db9cf9d58890df843b9cdd72433069da0 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala
@@ -41,8 +41,7 @@ trait HandlerHelpers extends SystemConfiguration {
         emoji = "none",
         presenter = false,
         locked = MeetingStatus2x.getPermissions(liveMeeting.status).lockOnJoin,
-        avatar = regUser.avatarURL
-      )
+        avatar = regUser.avatarURL)
     }
 
     nu match {
@@ -51,24 +50,24 @@ trait HandlerHelpers extends SystemConfiguration {
 
         val event = UserJoinedMeetingEvtMsgBuilder.build(liveMeeting.props.meetingProp.intId, newUser)
         outGW.send(event)
-        startRecordingIfAutoStart2x(outGW, liveMeeting, state)
+        val newState = startRecordingIfAutoStart2x(outGW, liveMeeting, state)
         if (!Users2x.hasPresenter(liveMeeting.users2x)) {
           automaticallyAssignPresenter(outGW, liveMeeting)
         }
-        state.update(state.expiryTracker.setUserHasJoined())
+        newState.update(newState.expiryTracker.setUserHasJoined())
       case None =>
         state
     }
   }
 
-  def startRecordingIfAutoStart2x(outGW: OutMsgRouter, liveMeeting: LiveMeeting, state: MeetingState2x): Unit = {
+  def startRecordingIfAutoStart2x(outGW: OutMsgRouter, liveMeeting: LiveMeeting, state: MeetingState2x): MeetingState2x = {
+    var newState = state
     if (liveMeeting.props.recordProp.record && !MeetingStatus2x.isRecording(liveMeeting.status) &&
       liveMeeting.props.recordProp.autoStartRecording && Users2x.numUsers(liveMeeting.users2x) == 1) {
 
       MeetingStatus2x.recordingStarted(liveMeeting.status)
 
       val tracker = state.recordingTracker.startTimer(TimeUtil.timeNowInMs())
-      state.update(tracker);
 
       def buildRecordingStatusChangedEvtMsg(meetingId: String, userId: String, recording: Boolean): BbbCommonEnvCoreMsg = {
         val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
@@ -82,19 +81,22 @@ trait HandlerHelpers extends SystemConfiguration {
 
       val event = buildRecordingStatusChangedEvtMsg(
         liveMeeting.props.meetingProp.intId,
-        "system", MeetingStatus2x.isRecording(liveMeeting.status)
-      )
+        "system", MeetingStatus2x.isRecording(liveMeeting.status))
       outGW.send(event)
-
+      newState = state.update(tracker)
     }
+    newState
   }
 
-  def stopRecordingIfAutoStart2x(outGW: OutMsgRouter, liveMeeting: LiveMeeting, state: MeetingState2x): Unit = {
+  def stopRecordingIfAutoStart2x(outGW: OutMsgRouter, liveMeeting: LiveMeeting, state: MeetingState2x): MeetingState2x = {
+    var newState = state
     if (liveMeeting.props.recordProp.record && MeetingStatus2x.isRecording(liveMeeting.status) &&
       liveMeeting.props.recordProp.autoStartRecording && Users2x.numUsers(liveMeeting.users2x) == 0) {
 
       MeetingStatus2x.recordingStopped(liveMeeting.status)
 
+      val tracker = state.recordingTracker.pauseTimer(TimeUtil.timeNowInMs())
+
       def buildRecordingStatusChangedEvtMsg(meetingId: String, userId: String, recording: Boolean): BbbCommonEnvCoreMsg = {
         val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
         val envelope = BbbCoreEnvelope(RecordingStatusChangedEvtMsg.NAME, routing)
@@ -107,10 +109,11 @@ trait HandlerHelpers extends SystemConfiguration {
 
       val event = buildRecordingStatusChangedEvtMsg(
         liveMeeting.props.meetingProp.intId,
-        "system", MeetingStatus2x.isRecording(liveMeeting.status)
-      )
+        "system", MeetingStatus2x.isRecording(liveMeeting.status))
       outGW.send(event)
+      newState = state.update(tracker)
     }
+    newState
   }
 
   def automaticallyAssignPresenter(outGW: OutMsgRouter, liveMeeting: LiveMeeting): Unit = {
@@ -168,8 +171,7 @@ trait HandlerHelpers extends SystemConfiguration {
     if (liveMeeting.props.meetingProp.isBreakout) {
       eventBus.publish(BigBlueButtonEvent(
         liveMeeting.props.breakoutProps.parentId,
-        new BreakoutRoomEndedInternalMsg(liveMeeting.props.meetingProp.intId)
-      ))
+        new BreakoutRoomEndedInternalMsg(liveMeeting.props.meetingProp.intId)))
     }
   }
 
@@ -209,8 +211,7 @@ trait HandlerHelpers extends SystemConfiguration {
     if (liveMeeting.props.meetingProp.isBreakout) {
       eventBus.publish(BigBlueButtonEvent(
         liveMeeting.props.breakoutProps.parentId,
-        new BreakoutRoomEndedInternalMsg(meetingId)
-      ))
+        new BreakoutRoomEndedInternalMsg(meetingId)))
     }
 
     val event = MsgBuilder.buildEjectAllFromVoiceConfMsg(meetingId, liveMeeting.props.voiceProp.voiceConf)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
index 3c751c36e5d12a852f0f4b1e167204b79711e40b..9ff320978f5400815d45b30237c02a2fd47cde67 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
@@ -6,7 +6,6 @@ import org.bigbluebutton.core.apps.users._
 import org.bigbluebutton.core.apps.whiteboard.ClientToServerLatencyTracerMsgHdlr
 import org.bigbluebutton.core.domain.{ MeetingExpiryTracker, MeetingInactivityTracker, MeetingRecordingTracker, MeetingState2x }
 import org.bigbluebutton.core.util.TimeUtil
-//import java.util.concurrent.TimeUnit
 
 import akka.actor._
 import akka.actor.SupervisorStrategy.Resume
@@ -41,8 +40,7 @@ object MeetingActor {
     props:       DefaultProps,
     eventBus:    InternalEventBus,
     outGW:       OutMsgRouter,
-    liveMeeting: LiveMeeting
-  ): Props =
+    liveMeeting: LiveMeeting): Props =
     Props(classOf[MeetingActor], props, eventBus, outGW, liveMeeting)
 }
 
@@ -50,37 +48,36 @@ class MeetingActor(
   val props:       DefaultProps,
   val eventBus:    InternalEventBus,
   val outGW:       OutMsgRouter,
-  val liveMeeting: LiveMeeting
-)
-    extends BaseMeetingActor
-    with GuestsApp
-    with LayoutApp2x
-    with VoiceApp2x
-    with PollApp2x
-    with BreakoutApp2x
-    with UsersApp2x
-    with WhiteboardApp2x
-
-    with PermisssionCheck
-    with UserBroadcastCamStartMsgHdlr
-    with UserJoinMeetingReqMsgHdlr
-    with UserJoinMeetingAfterReconnectReqMsgHdlr
-    with UserBroadcastCamStopMsgHdlr
-    with UserConnectedToGlobalAudioMsgHdlr
-    with UserDisconnectedFromGlobalAudioMsgHdlr
-    with MuteAllExceptPresentersCmdMsgHdlr
-    with MuteMeetingCmdMsgHdlr
-    with IsMeetingMutedReqMsgHdlr
-    with MuteUserCmdMsgHdlr
-    with EjectUserFromVoiceCmdMsgHdlr
-    with EndMeetingSysCmdMsgHdlr
-    with DestroyMeetingSysCmdMsgHdlr
-    with SendTimeRemainingUpdateHdlr
-    with SendBreakoutTimeRemainingMsgHdlr
-    with ChangeLockSettingsInMeetingCmdMsgHdlr
-    with ValidateConnAuthTokenSysMsgHdlr
-    with SyncGetMeetingInfoRespMsgHdlr
-    with ClientToServerLatencyTracerMsgHdlr {
+  val liveMeeting: LiveMeeting)
+  extends BaseMeetingActor
+  with GuestsApp
+  with LayoutApp2x
+  with VoiceApp2x
+  with PollApp2x
+  with BreakoutApp2x
+  with UsersApp2x
+  with WhiteboardApp2x
+
+  with PermisssionCheck
+  with UserBroadcastCamStartMsgHdlr
+  with UserJoinMeetingReqMsgHdlr
+  with UserJoinMeetingAfterReconnectReqMsgHdlr
+  with UserBroadcastCamStopMsgHdlr
+  with UserConnectedToGlobalAudioMsgHdlr
+  with UserDisconnectedFromGlobalAudioMsgHdlr
+  with MuteAllExceptPresentersCmdMsgHdlr
+  with MuteMeetingCmdMsgHdlr
+  with IsMeetingMutedReqMsgHdlr
+  with MuteUserCmdMsgHdlr
+  with EjectUserFromVoiceCmdMsgHdlr
+  with EndMeetingSysCmdMsgHdlr
+  with DestroyMeetingSysCmdMsgHdlr
+  with SendTimeRemainingUpdateHdlr
+  with SendBreakoutTimeRemainingMsgHdlr
+  with ChangeLockSettingsInMeetingCmdMsgHdlr
+  with ValidateConnAuthTokenSysMsgHdlr
+  with SyncGetMeetingInfoRespMsgHdlr
+  with ClientToServerLatencyTracerMsgHdlr {
 
   override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
     case e: Exception => {
@@ -98,8 +95,7 @@ class MeetingActor(
    */
   var actorMonitor = context.actorOf(
     MeetingActorAudit.props(props, eventBus, outGW),
-    "actorMonitor-" + props.meetingProp.intId
-  )
+    "actorMonitor-" + props.meetingProp.intId)
 
   val presentationApp2x = new PresentationApp2x(liveMeeting, outGW)
   val screenshareApp2x = new ScreenshareApp2x(liveMeeting, outGW)
@@ -115,8 +111,7 @@ class MeetingActor(
     TimeUtil.minutesToMillis(props.durationProps.warnMinutesBeforeMax),
     lastActivityTimestampInMs = TimeUtil.timeNowInMs(),
     warningSent = false,
-    warningSentOnTimestampInMs = 0L
-  )
+    warningSentOnTimestampInMs = 0L)
 
   val expiryTracker = new MeetingExpiryTracker(
     startedOnInMs = TimeUtil.timeNowInMs(),
@@ -124,10 +119,9 @@ class MeetingActor(
     lastUserLeftOnInMs = None,
     durationInMs = TimeUtil.minutesToMillis(props.durationProps.duration),
     meetingExpireIfNoUserJoinedInMs = TimeUtil.minutesToMillis(props.durationProps.meetingExpireIfNoUserJoinedInMinutes),
-    meetingExpireWhenLastUserLeftInMs = TimeUtil.minutesToMillis(props.durationProps.meetingExpireWhenLastUserLeftInMinutes)
-  )
+    meetingExpireWhenLastUserLeftInMs = TimeUtil.minutesToMillis(props.durationProps.meetingExpireWhenLastUserLeftInMinutes))
 
-  val recordingTracker = new MeetingRecordingTracker(startedOnInMs = 0, previousDurationInMs = 0, currentDurationInMs = 0)
+  val recordingTracker = new MeetingRecordingTracker(startedOnInMs = 0L, previousDurationInMs = 0L, currentDurationInMs = 0L)
 
   var state = new MeetingState2x(None, inactivityTracker, expiryTracker, recordingTracker)
 
@@ -143,10 +137,10 @@ class MeetingActor(
   // Set webcamsOnlyForModerator property in case we didn't after meeting creation
   MeetingStatus2x.setWebcamsOnlyForModerator(liveMeeting.status, liveMeeting.props.usersProp.webcamsOnlyForModerator)
 
-  /*******************************************************************/
+/*******************************************************************/
   //object FakeTestData extends FakeTestData
   //FakeTestData.createFakeUsers(liveMeeting)
-  /*******************************************************************/
+/*******************************************************************/
 
   def receive = {
     //=============================
@@ -185,7 +179,7 @@ class MeetingActor(
     case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg)
 
     case msg: SendRecordingTimerInternalMsg =>
-      state = handleSendRecordingTimerInternalMsg(msg, state)
+      state = usersApp.handleSendRecordingTimerInternalMsg(msg, state)
 
     case _ => // do nothing
   }
@@ -351,8 +345,7 @@ class MeetingActor(
     // request screenshare to end
     screenshareApp2x.handleScreenshareStoppedVoiceConfEvtMsg(
       liveMeeting.props.voiceProp.voiceConf,
-      liveMeeting.props.screenshareProps.screenshareConf
-    )
+      liveMeeting.props.screenshareProps.screenshareConf)
 
   }
 
@@ -382,45 +375,6 @@ class MeetingActor(
     sendRttTraceTest()
   }
 
-  def handleSendRecordingTimerInternalMsg(msg: SendRecordingTimerInternalMsg, state: MeetingState2x): MeetingState2x = {
-    def buildUpdateReocrdingTimerEvtMsg(meetingId: String, recordingTime: Long): BbbCommonEnvCoreMsg = {
-      val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
-      val envelope = BbbCoreEnvelope(UpdateRecordingTimerEvtMsg.NAME, routing)
-      val body = UpdateRecordingTimerEvtMsgBody(recordingTime)
-      val header = BbbClientMsgHeader(UpdateRecordingTimerEvtMsg.NAME, meetingId, "not-used")
-      val event = UpdateRecordingTimerEvtMsg(header, body)
-
-      BbbCommonEnvCoreMsg(envelope, event)
-    }
-
-    log.debug("##### Sending UpdateReocrdingTimerEvtMsg")
-
-    log.debug("$$$$$$$ Meeting is recording {}", MeetingStatus2x.isRecording(liveMeeting.status))
-
-    var newDuration: Long = 0
-    if (MeetingStatus2x.isRecording(liveMeeting.status)) {
-      newDuration = TimeUtil.timeNowInMs()
-    }
-    log.debug("====== New duration {}", newDuration)
-
-    println("update - before:  start=" + state.recordingTracker.startedOnInMs
-      + " previous=" + state.recordingTracker.previousDurationInMs
-      + " current=" + state.recordingTracker.currentDurationInMs)
-    val tracker = state.recordingTracker.udpateCurrentDuration(newDuration)
-    println("update - before:  start=" + tracker.startedOnInMs + " previous=" + tracker.previousDurationInMs + " current=" + tracker.currentDurationInMs)
-
-    val newState = state.update(tracker)
-
-    val recordingTime = TimeUtil.millisToSeconds(tracker.recordingDuration())
-
-    log.debug("##### Recorded seconds {}", recordingTime)
-
-    val event = buildUpdateReocrdingTimerEvtMsg(liveMeeting.props.meetingProp.intId, recordingTime)
-    outGW.send(event)
-
-    newState
-  }
-
   def sendRttTraceTest(): Unit = {
     val now = System.currentTimeMillis()
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
index 876868bcb5beb0475e093bbec57ee31ed02f37ba..b1e984afdad01c5bf0f7f7a20c729faf7ad2eb87 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
@@ -202,7 +202,6 @@ object MsgBuilder {
     val header = BbbClientMsgHeader(UserLeftMeetingEvtMsg.NAME, meetingId, userId)
     val body = UserLeftMeetingEvtMsgBody(userId)
     val event = UserLeftMeetingEvtMsg(header, body)
-    val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
 
     BbbCommonEnvCoreMsg(envelope, event)
   }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/TimerUtil.as b/bigbluebutton-client/src/org/bigbluebutton/core/TimerUtil.as
index c65da609fb90be1575acd9e20b699fc8821c78c3..509e522405fa106a5018303aecb374bb46b228a9 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/core/TimerUtil.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/TimerUtil.as
@@ -29,7 +29,9 @@ package org.bigbluebutton.core {
 	import org.bigbluebutton.util.i18n.ResourceUtil;
 
 	public final class TimerUtil {
-		public static var timers:Dictionary = new Dictionary(true);
+		private static var timers:Dictionary = new Dictionary(true);
+
+		private static var times:Dictionary = new Dictionary(true);
 
 		public static function setCountDownTimer(label:Label, seconds:int, showMinuteWarning:Boolean = false):void {
 			var timer:Timer = getTimer(label.id, seconds);
@@ -58,19 +60,21 @@ package org.bigbluebutton.core {
 			timer.start();
 		}
 
-		public static function setTimer(label:Label, seconds:int):void {
+		public static function setTimer(label:Label, seconds:int, running:Boolean):void {
 			var timer:Timer = getTimer(label.id, seconds);
 			if (!timer.hasEventListener(TimerEvent.TIMER)) {
 				timer.addEventListener(TimerEvent.TIMER, function():void {
-					var elapsedSeconds:int = seconds + timer.currentCount;
+					var elapsedSeconds:int = times[timer] + timer.currentCount;
 					var formattedTime:String = (Math.floor(elapsedSeconds / 60)) + ":" + (elapsedSeconds % 60 >= 10 ? "" : "0") + (elapsedSeconds % 60);
 					label.text = formattedTime;
 				});
+			}
+			times[timer] = seconds - timer.currentCount;
+			if (running) {
+				timer.start();
 			} else {
 				timer.stop();
-				timer.reset();
 			}
-			timer.start();
 		}
 
 		public static function getTimer(name:String, defaultRepeatCount:Number):Timer {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
index 215cd8592accd38f344b83c4b39701f6086b9f18..cd6ea9c06aac7a0c83080110b97e8de8359569d2 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
@@ -212,7 +212,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 					recordingTimer.visible = false;
 				} else {
 					recordingTimer.visible = true;
-					TimerUtil.setTimer(recordingTimer, e.time);
+					TimerUtil.setTimer(recordingTimer, e.time, LiveMeeting.inst().meetingStatus.isRecording);
 				}
 			}
 
@@ -488,21 +488,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private function focusLogoutButton(e:ShortcutEvent):void{
 				btnLogout.setFocus();
 			}
-      
-      private function onRecordingStatusChanged(event:BBBEvent):void {
-        meetingNameLbl.text = "";
-        
-        if (event.payload.recording) {
-          meetingNameLbl.text =  ResourceUtil.getInstance().getString('bbb.mainToolbar.recordingLabel.recording')
-		}
-        
-        if (toolbarOptions.showMeetingName) {
-          var meetingTitle:String = LiveMeeting.inst().meeting.name;                   
-          if (meetingTitle != null) {
-            meetingNameLbl.text += " " + meetingTitle;
-          } 
-        }
-      }
+			
+			private function onRecordingStatusChanged(event:BBBEvent):void {
+
+				if (event.payload.recording) {
+					meetingNameLbl.text = ResourceUtil.getInstance().getString('bbb.mainToolbar.recordingLabel.recording')
+				} else {
+					meetingNameLbl.text = "";
+					TimerUtil.stopTimer(recordingTimer.id);
+				}
+
+				if (toolbarOptions.showMeetingName) {
+					var meetingTitle:String = LiveMeeting.inst().meeting.name;
+					if (meetingTitle != null) {
+						meetingNameLbl.text += " " + meetingTitle;
+					}
+				}
+			}
 
 			private function onNetStatsButtonClick(e:Event = null):void {
 				var d:Dispatcher = new Dispatcher();
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordWindow.mxml
index 3de2876b95f95829aeba95143fd8ff62f038cdc2..bc7c1eac20b230d16eeb8b42c0a19a64b042f375 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordWindow.mxml
@@ -86,7 +86,8 @@
 			<mx:Button id="noButton" styleName="mainActionButton" click="close()" label="{ResourceUtil.getInstance().getString('bbb.recordWindow.confirm.no')}" width="102"/>
 		</mx:HBox>
 
-		<mx:CheckBox id="clearRecordingsChecbox" label="{ResourceUtil.getInstance().getString('bbb.recordWindow.clearCheckbox.label')}" />
+		<mx:CheckBox id="clearRecordingsChecbox" label="{ResourceUtil.getInstance().getString('bbb.recordWindow.clearCheckbox.label')}"
+					 visible="{_recordingFlag}" includeInLayout="{_recordingFlag}"/>
 	</mx:VBox>
 
 	<mx:Button id="closeButton" click="close()" styleName="titleWindowCloseButton"