diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala
index 0e9108e9b2c12d5da24f7cbda4dff107e1530371..ffe13b6b9dc56bc0f1bc33563b081fd6cac9959e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectedToGlobalAudioMsgHdlr.scala
@@ -29,6 +29,7 @@ trait UserConnectedToGlobalAudioMsgHdlr {
     for {
       user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId)
     } yield {
+
       val vu = VoiceUserState(intId = user.intId, voiceUserId = user.intId, callingWith = "flash", callerName = user.name,
         callerNum = user.name, muted = true, talking = false, listenOnly = true)
       VoiceUsers.add(liveMeeting.voiceUsers, vu)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala
index 5fde42e71140ef84db27cb57a0d9cdb2d04a7580..15e35a59bf57d996fe77dee9856fa304bccf7379 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala
@@ -41,8 +41,9 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends BreakoutHdlrHelpers {
       outGW.send(msgEvent)
     }
 
-    val voiceUserState = VoiceUserState(intId, voiceUserId, callingWith, callerIdName, callerIdNum, muted, talking, listenOnly = false)
+    val isListenOnly = if (callerIdName.startsWith("LISTENONLY")) true else false
 
+    val voiceUserState = VoiceUserState(intId, voiceUserId, callingWith, callerIdName, callerIdNum, muted, talking, listenOnly = isListenOnly)
     VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState)
 
     broadcastEvent(voiceUserState)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala
index 45be25433044093c9aed82ff328b73da8543e6f5..f9f11212f159a0ee1be9b1ef1795b2d1bb49eb8f 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala
@@ -37,7 +37,6 @@ object VoiceUsers {
     } yield {
       val vu = u.modify(_.muted).setTo(muted)
         .modify(_.talking).setTo(false)
-        .modify(_.listenOnly).setTo(false)
       users.save(vu)
       vu
     }
@@ -49,7 +48,6 @@ object VoiceUsers {
     } yield {
       val vu = u.modify(_.muted).setTo(false)
         .modify(_.talking).setTo(talkng)
-        .modify(_.listenOnly).setTo(false)
       users.save(vu)
       vu
     }
@@ -61,7 +59,6 @@ object VoiceUsers {
     } yield {
       val vu = u.modify(_.muted).setTo(true)
         .modify(_.talking).setTo(false)
-        .modify(_.listenOnly).setTo(true)
       users.save(vu)
       vu
     }
@@ -73,7 +70,6 @@ object VoiceUsers {
     } yield {
       val vu = u.modify(_.muted).setTo(false)
         .modify(_.talking).setTo(false)
-        .modify(_.listenOnly).setTo(false)
       users.save(vu)
       vu
     }
diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css
index d2f6026d7280ed3f6fdc29427647b94880615b8e..db918a408187e39ea626873412bdaaa4058876f4 100755
--- a/bigbluebutton-client/branding/default/style/css/V2Theme.css
+++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css
@@ -144,8 +144,7 @@ phonecomponents|MuteMeButton {
 .toolbarMainBox {
 	backgroundColor : #FFFFFF;
 	paddingTop      : 0;
-	paddingBottom   : 0;
-	verticalGap     : 0;
+	paddingBottom   : 6;
 }
 
 .breakoutRoomRibbon {
@@ -164,7 +163,7 @@ phonecomponents|MuteMeButton {
 }
 
 .topBoxStyle {
-	paddingTop    : 0;
+	paddingTop    : 6;
 	paddingBottom : 0;
 	paddingLeft   : 8;
 	paddingRight  : 8;
@@ -437,7 +436,7 @@ mx|Button {
 	borderAlphaUp               : 1;
 	borderAlphaOver             : 1;
 	borderAlphaDown             : 1;
-	borderAlphaDisabled         : 1;
+	borderAlphaDisabled         : 0.25;
 
 	borderThickness             : 1;
 
@@ -554,6 +553,10 @@ views|BrowserPermissionHelper {
 //------------------------------
 */
 
+views|ClientStatusWindow {
+	horizontalAlign : right;
+}
+
 views|ClientStatusItemRenderer {
 	iconSuccess : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Success");
 	iconWarning : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Warning");
@@ -644,7 +647,7 @@ chat|AddChatTabBox {
 }
 
 .chatOptionsLabel {
-	fontSize : 14;
+	fontSize   : 14;
 }
 
 .chatMessageListStyle {
@@ -771,10 +774,6 @@ mx|DataGrid {
 //------------------------------
 */
 
-.deskshareControlButtonStyle {
-	cornerRadius : 18;
-}
-
 .deskshareWarningLabelStyle {
 	fontWeight : bold;
 	fontSize   : 18;
@@ -937,6 +936,7 @@ views|LockSettings {
 */
 
 views|MainApplicationShell {
+	borderStyle   : none;
 	paddingBottom : 0;
 	verticalGap   : 0;
 }
@@ -1089,6 +1089,35 @@ views|NetworkStatsWindow {
 	iconRefresh : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Refresh");
 }
 
+/*
+//------------------------------
+//  NumericStepper
+//------------------------------
+*/
+
+mx|NumericStepper {
+	/* Normal state */
+	fillColorUp         : #FFFFFF;
+	fillColorOver       : #CDD4DB;
+	fillColorDown       : #ACB2B7;
+	fillColorDisabled   : #F0F2F6;
+	borderColorUp       : #CDD4DB;
+	borderColorOver     : #1070D7;
+	borderColorDown     : #0A5EAC;
+	borderColorDisabled : #CDD4DB;
+
+	/* Icon states */
+	iconColor           : #4E5A66;
+	iconColorOver       : #1070D7;
+	iconColorDown       : #4E5A66;
+
+	borderThickness     : 1;
+
+	/* Skins */
+	downArrowSkin       : ClassReference("org.bigbluebutton.skins.NumericStepperDownSkin");
+	upArrowSkin         : ClassReference("org.bigbluebutton.skins.NumericStepperUpSkin");
+}
+
 /*
 //------------------------------
 //  PopUpButton
diff --git a/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/ButtonSkin.as b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/ButtonSkin.as
index 17869687a4fd46b750df112b26f0d5871aa91337..2449dea7b3006977b5b045564e4639a1ba51e657 100644
--- a/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/ButtonSkin.as
+++ b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/ButtonSkin.as
@@ -22,24 +22,6 @@ package org.bigbluebutton.skins {
 
 	public class ButtonSkin extends Border {
 
-		//--------------------------------------------------------------------------
-		//
-		//  Constructor
-		//
-		//--------------------------------------------------------------------------
-
-		/**
-		 *  Constructor.
-		 *
-		 *  @langversion 3.0
-		 *  @playerversion Flash 9
-		 *  @playerversion AIR 1.1
-		 *  @productversion Flex 3
-		 */
-		public function ButtonSkin() {
-			super();
-		}
-
 		//--------------------------------------------------------------------------
 		//
 		//  Overridden properties
diff --git a/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/NumericStepperDownSkin.as b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/NumericStepperDownSkin.as
new file mode 100644
index 0000000000000000000000000000000000000000..6b0456bb1a53f86c1e8c5d9441cfeb33efef07a5
--- /dev/null
+++ b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/NumericStepperDownSkin.as
@@ -0,0 +1,166 @@
+/**
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ *
+ * Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ *
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.bigbluebutton.skins {
+	import flash.display.Graphics;
+
+	import mx.skins.Border;
+
+	public class NumericStepperDownSkin extends Border {
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  measuredWidth
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get measuredWidth():Number {
+			return 19;
+		}
+
+		//----------------------------------
+		//  measuredHeight
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get measuredHeight():Number {
+			return 11;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 */
+		override protected function updateDisplayList(w:Number, h:Number):void {
+			super.updateDisplayList(w, h);
+
+			var borderColorUp:uint = getStyle("borderColorUp");
+			var borderColorOver:uint = getStyle("borderColorOver");
+			var borderColorDown:uint = getStyle("borderColorDown");
+			var borderColorDisabled:uint = getStyle("borderColorDisabled");
+
+			var borderThickness:uint = getStyle("borderThickness");
+
+			var fillColorUp:uint = getStyle("fillColorUp");
+			var fillColorOver:uint = getStyle("fillColorOver");
+			var fillColorDown:uint = getStyle("fillColorDown");
+			var fillColorDisabled:uint = getStyle("fillColorDisabled");
+
+			// User-defined styles.
+			var arrowColor:uint = getStyle("iconColor");
+			var arrowColorOver:uint = getStyle("iconColorOver");
+			var arrowColorDown:uint = getStyle("iconColorDown");
+
+			var cornerRadius:Number = getStyle("cornerRadius");
+
+			var cr:Object = {tl: 0, tr: 0, bl: 0, br: cornerRadius};
+			var cr1:Object = {tl: 0, tr: 0, bl: 0, br: Math.max(cornerRadius - 1, 0)};
+
+			// Draw the background and border.
+			var g:Graphics = graphics;
+
+			g.clear();
+
+			switch (name) {
+				case "downArrowUpSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorUp, 1, null, null, null, {x: 1, y: 0, w: w - 2, h: h - 1, r: cr1});
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorUp, 1);
+
+					break;
+				}
+
+				case "downArrowOverSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorOver, 1, null, null, null, {x: 1, y: 0, w: w - 2, h: h - 1, r: cr1});
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorOver, 1, null);
+
+					break;
+				}
+
+				case "downArrowDownSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorDown, 1);
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDown, 1);
+
+					break;
+				}
+
+				case "downArrowDisabledSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorDisabled, 0.5, null, null, null, {x: 1, y: 0, w: w - 2, h: h - 1, r: cr1});
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDisabled, 0.5, null);
+
+					arrowColor = getStyle("disabledIconColor");
+					break;
+				}
+			}
+
+			// Draw the arrow.
+			g.beginFill(arrowColor);
+			g.moveTo(w / 2, h / 2 + 1.5);
+			g.lineTo(w / 2 - 3.5, h / 2 - 2.5);
+			g.lineTo(w / 2 + 3.5, h / 2 - 2.5);
+			g.lineTo(w / 2, h / 2 + 1.5);
+			g.endFill();
+		}
+	}
+}
+
diff --git a/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/NumericStepperUpSkin.as b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/NumericStepperUpSkin.as
new file mode 100644
index 0000000000000000000000000000000000000000..26f2938c3ddd4f7ecd68032017dafff338647ccd
--- /dev/null
+++ b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/NumericStepperUpSkin.as
@@ -0,0 +1,165 @@
+/**
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ *
+ * Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ *
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.bigbluebutton.skins {
+	import flash.display.Graphics;
+
+	import mx.skins.Border;
+
+	public class NumericStepperUpSkin extends Border {
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  measuredWidth
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get measuredWidth():Number {
+			return 19;
+		}
+
+		//----------------------------------
+		//  measuredHeight
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get measuredHeight():Number {
+			return 11;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 */
+		override protected function updateDisplayList(w:Number, h:Number):void {
+			super.updateDisplayList(w, h);
+
+			var borderColorUp:uint = getStyle("borderColorUp");
+			var borderColorOver:uint = getStyle("borderColorOver");
+			var borderColorDown:uint = getStyle("borderColorDown");
+			var borderColorDisabled:uint = getStyle("borderColorDisabled");
+
+			var borderThickness:uint = getStyle("borderThickness");
+
+			var fillColorUp:uint = getStyle("fillColorUp");
+			var fillColorOver:uint = getStyle("fillColorOver");
+			var fillColorDown:uint = getStyle("fillColorDown");
+			var fillColorDisabled:uint = getStyle("fillColorDisabled");
+
+			// User-defined styles.
+			var arrowColor:uint = getStyle("iconColor");
+			var arrowColorOver:uint = getStyle("iconColorOver");
+			var arrowColorDown:uint = getStyle("iconColorDown");
+
+			var cornerRadius:Number = getStyle("cornerRadius");
+
+			var cr:Object = {tl: 0, tr: cornerRadius, bl: 0, br: 0};
+			var cr1:Object = {tl: 0, tr: Math.max(cornerRadius - 1, 0), bl: 0, br: 0};
+
+			// Draw the background and border.
+			var g:Graphics = graphics;
+
+			g.clear();
+
+			switch (name) {
+				case "upArrowUpSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorUp, 1, null, null, null, {x: 1, y: 1, w: w - 2, h: h - 2, r: cr1});
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorUp, 1);
+
+					break;
+				}
+
+				case "upArrowOverSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorOver, 1, null, null, null, {x: 1, y: 1, w: w - 2, h: h - 2, r: cr1});
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorOver, 1, null);
+
+					break;
+				}
+
+				case "upArrowDownSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorDown, 1);
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDown, 1);
+
+					break;
+				}
+
+				case "upArrowDisabledSkin":  {
+					// border
+					drawRoundRect(0, 0, w, h, cr, borderColorDisabled, 0.5, null, null, null, {x: 1, y: 1, w: w - 2, h: h - 2, r: cr1});
+
+					// button fill
+					drawRoundRect(borderThickness, borderThickness, w - (borderThickness * 2), h - (borderThickness * 2), cr1, fillColorDisabled, 0.5, null);
+
+					arrowColor = getStyle("disabledIconColor");
+					break;
+				}
+			}
+
+			// Draw the arrow.
+			g.beginFill(arrowColor);
+			g.moveTo(w / 2, h / 2 - 2.5);
+			g.lineTo(w / 2 - 3.5, h / 2 + 1.5);
+			g.lineTo(w / 2 + 3.5, h / 2 + 1.5);
+			g.lineTo(w / 2, h / 2 - 2.5);
+			g.endFill();
+		}
+	}
+}
diff --git a/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/TabSkin.as b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/TabSkin.as
index d98beece30ff2ee0009cc90d7515e9c27ec1c870..4393939c032e2245e73f4ad1b068fabe20752483 100644
--- a/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/TabSkin.as
+++ b/bigbluebutton-client/branding/default/style/css/org/bigbluebutton/skins/TabSkin.as
@@ -40,7 +40,7 @@ package org.bigbluebutton.skins {
 	import flash.display.DisplayObjectContainer;
 	import flash.utils.describeType;
 	import flash.utils.getQualifiedClassName;
-	
+
 	import mx.core.EdgeMetrics;
 	import mx.core.UIComponent;
 	import mx.skins.Border;
@@ -48,17 +48,6 @@ package org.bigbluebutton.skins {
 
 	public class TabSkin extends Border {
 
-		//--------------------------------------------------------------------------
-		//
-		//  Class variables
-		//
-		//--------------------------------------------------------------------------
-
-		/**
-		 *  @private
-		 */
-		private static var cache:Object = {};
-
 		//--------------------------------------------------------------------------
 		//
 		//  Overridden properties
diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties
index f644248ef99760d99a0b516aa377c7652176a203..dff7c063e7f6671bfd33912d19594ec63724e2e2 100755
--- a/bigbluebutton-client/locale/en_US/bbbResources.properties
+++ b/bigbluebutton-client/locale/en_US/bbbResources.properties
@@ -383,6 +383,7 @@ bbb.video.publish.closeBtn.accessName = Close the webcam settings dialog box
 bbb.video.publish.closeBtn.label = Cancel
 bbb.video.publish.titleBar = Publish Webcam Window
 bbb.video.streamClose.toolTip = Close stream for: {0}
+bbb.video.message.browserhttp = This server is not configured with SSL. As a result, {0} disables sharing of your webcam.
 bbb.screensharePublish.title = Screen Sharing: Presenter's Preview
 bbb.screensharePublish.pause.tooltip = Pause screen share
 bbb.screensharePublish.pause.label = Pause
@@ -462,6 +463,7 @@ bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Screen
 bbb.toolbar.sharednotes.toolTip = Open Shared Notes
 bbb.toolbar.video.toolTip.start = Share Your Webcam
 bbb.toolbar.video.toolTip.stop = Stop Sharing Your Webcam
+bbb.layout.addButton.label = Add
 bbb.layout.addButton.toolTip = Add the custom layout to the list
 bbb.layout.overwriteLayoutName.title = Overwrite layout
 bbb.layout.overwriteLayoutName.text = Name already in use. Do you want to overwrite?
@@ -475,6 +477,8 @@ bbb.layout.combo.custom = * Custom layout
 bbb.layout.combo.customName = Custom layout
 bbb.layout.combo.remote = Remote
 bbb.layout.window.name = Layout name
+bbb.layout.window.close.tooltip = Close
+bbb.layout.window.close.accessibilityName = Close add new layout window
 bbb.layout.save.complete = Layouts were successfully saved
 bbb.layout.save.ioerror = Layouts were not saved. Try saving again.
 bbb.layout.load.complete = Layouts were successfully loaded
diff --git a/bigbluebutton-client/resources/prod/lib/bbb_blinker.js b/bigbluebutton-client/resources/prod/lib/bbb_blinker.js
index beb32772ddab5652b26ce23a19a4c434c397edbf..eded9d29f0b4b55fb50dec1407e81a78c5a85795 100755
--- a/bigbluebutton-client/resources/prod/lib/bbb_blinker.js
+++ b/bigbluebutton-client/resources/prod/lib/bbb_blinker.js
@@ -97,11 +97,9 @@ function determineBrowser()
 	var nameOffset,verOffset,ix;
 
 	// In Opera, the true version is after "Opera" or after "Version"
-	if ((verOffset=nAgt.indexOf("Opera"))!=-1) {
+	if ((verOffset=nAgt.indexOf("OPR/"))!=-1) {
 		browserName = "Opera";
-		fullVersion = nAgt.substring(verOffset+6);
-		if ((verOffset=nAgt.indexOf("Version"))!=-1) 
-			fullVersion = nAgt.substring(verOffset+8);
+		fullVersion = nAgt.substring(verOffset+4);
 	}
 	// In MSIE, the true version is after "MSIE" in userAgent
 	else if ((verOffset=nAgt.indexOf("MSIE"))!=-1) {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/common/IKeyboardClose.as b/bigbluebutton-client/src/org/bigbluebutton/common/IKeyboardClose.as
new file mode 100644
index 0000000000000000000000000000000000000000..56fc919a237772830753b559600bdd6ae7607ef0
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/common/IKeyboardClose.as
@@ -0,0 +1,26 @@
+/**
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ *
+ * Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ *
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.bigbluebutton.common {
+
+	/**
+	 * Add it to popup classes to add the Keyboard.ESCAPE close behaviour
+	 */
+	public interface IKeyboardClose {
+	}
+}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/PopUpUtil.as b/bigbluebutton-client/src/org/bigbluebutton/core/PopUpUtil.as
index d500bd937b60d2e196c7ac84e265230a9745d580..af268ec346ac0700cafc828d1b0ae9c56fa964de 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/core/PopUpUtil.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/PopUpUtil.as
@@ -17,76 +17,90 @@
  *
  */
 package org.bigbluebutton.core {
-    import flash.display.DisplayObject;
-    import flash.utils.Dictionary;
-    import flash.utils.getQualifiedClassName;
+	import flash.display.DisplayObject;
+	import flash.events.KeyboardEvent;
+	import flash.ui.Keyboard;
+	import flash.utils.Dictionary;
+	import flash.utils.getQualifiedClassName;
 
-    import mx.core.FlexGlobals;
-    import mx.core.IChildList;
-    import mx.core.IFlexDisplayObject;
-    import mx.core.IUIComponent;
-    import mx.managers.PopUpManager;
-    import mx.managers.SystemManager;
+	import mx.core.FlexGlobals;
+	import mx.core.IChildList;
+	import mx.core.IFlexDisplayObject;
+	import mx.core.IUIComponent;
+	import mx.managers.PopUpManager;
+	import mx.managers.SystemManager;
 
-    import org.as3commons.logging.api.ILogger;
-    import org.as3commons.logging.api.getClassLogger;
+	import org.as3commons.logging.api.ILogger;
+	import org.as3commons.logging.api.getClassLogger;
+	import org.bigbluebutton.common.IKeyboardClose;
 
-    public final class PopUpUtil {
+	public final class PopUpUtil {
 
-        private static const LOGGER:ILogger = getClassLogger(PopUpUtil);
+		private static const LOGGER:ILogger = getClassLogger(PopUpUtil);
 
-        private static var popUpDict:Dictionary = new Dictionary(true);
+		private static var popUpDict:Dictionary = new Dictionary(true);
 
-        public static function createNonModelPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
-            if (!checkPopUpExists(className)) {
-                return addPopUpToStage(parent, className, false, center);
-            }
-            return null;
-        }
+		public static function createNonModalPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
+			if (!checkPopUpExists(className)) {
+				return addPopUpToStage(parent, className, false, center);
+			}
+			return null;
+		}
 
-        public static function createModalPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
-            if (!checkPopUpExists(className)) {
-                return addPopUpToStage(parent, className, true, center);
-            }
-            return null;
-        }
+		public static function createModalPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
+			if (!checkPopUpExists(className)) {
+				return addPopUpToStage(parent, className, true, center);
+			}
+			return null;
+		}
 
-        public static function removePopUp(classOrInstance:*):void {
-            var fqcn:String = getQualifiedClassName(classOrInstance);
-            if (popUpDict[fqcn] != undefined) {
-                PopUpManager.removePopUp(popUpDict[fqcn])
-                delete popUpDict[fqcn];
-                LOGGER.debug("Removed PopUp with type [{0}]", [fqcn]);
-            }
-        }
+		public static function removePopUp(classOrInstance:*):void {
+			var fqcn:String = getQualifiedClassName(classOrInstance);
+			if (popUpDict[fqcn] != undefined) {
+				PopUpManager.removePopUp(popUpDict[fqcn])
+				delete popUpDict[fqcn];
+				LOGGER.debug("Removed PopUp with type [{0}]", [fqcn]);
+			}
+		}
 
-        private static function checkPopUpExists(className:Class):Boolean {
-            LOGGER.debug("Checking if [{0}] exists as a PopUp", [className]);
-            var systemManager:SystemManager = FlexGlobals.topLevelApplication.systemManager;
+		private static function checkPopUpExists(className:Class):Boolean {
+			LOGGER.debug("Checking if [{0}] exists as a PopUp", [className]);
+			var systemManager:SystemManager = FlexGlobals.topLevelApplication.systemManager;
 
-            var childList:IChildList = systemManager.rawChildren;
-            for (var i:int = childList.numChildren - 1; i >= 0; i--) {
-                var childObject:IUIComponent = childList.getChildAt(i) as IUIComponent;
-                // PopUp already exists
-                if (childObject is className && childObject.isPopUp) {
-                    LOGGER.debug("PopUp with type [{0}] found", [className]);
-                    return true;
-                }
-            }
-            LOGGER.debug("No PopUp with type [{0}] not found", [className]);
-            return false;
-        }
+			var childList:IChildList = systemManager.rawChildren;
+			for (var i:int = childList.numChildren - 1; i >= 0; i--) {
+				var childObject:IUIComponent = childList.getChildAt(i) as IUIComponent;
+				// PopUp already exists
+				if (childObject is className && childObject.isPopUp) {
+					LOGGER.debug("PopUp with type [{0}] found", [className]);
+					return true;
+				}
+			}
+			LOGGER.debug("No PopUp with type [{0}] not found", [className]);
+			return false;
+		}
 
-        private static function addPopUpToStage(parent:DisplayObject, className:Class, modal:Boolean = false, center:Boolean = true):IFlexDisplayObject {
-            var popUp:IFlexDisplayObject = PopUpManager.createPopUp(parent, className, modal);
-            if (center) {
-                PopUpManager.centerPopUp(popUp)
-            }
-            popUpDict[getQualifiedClassName(className)] = popUp;
+		private static function addPopUpToStage(parent:DisplayObject, className:Class, modal:Boolean = false, center:Boolean = true):IFlexDisplayObject {
+			var popUp:IFlexDisplayObject = PopUpManager.createPopUp(parent, className, modal);
+			if (center) {
+				PopUpManager.centerPopUp(popUp)
+			}
+			popUpDict[getQualifiedClassName(className)] = popUp;
 
-            LOGGER.debug("Created PopUp with type [{0}]", [className]);
+			if (popUp is IKeyboardClose) {
+				popUp.addEventListener(KeyboardEvent.KEY_DOWN, escapeKeyDownHandler);
+			}
 
-            return popUp;
-        }
-    }
+			LOGGER.debug("Created PopUp with type [{0}]", [className]);
+
+			return popUp;
+		}
+
+		private static function escapeKeyDownHandler(event:KeyboardEvent):void {
+			if (event.charCode == Keyboard.ESCAPE) {
+				event.currentTarget.removeEventListener(KeyboardEvent.KEY_DOWN, escapeKeyDownHandler);
+				removePopUp(event.currentTarget);
+			}
+		}
+	}
 }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/api/JSAPI.as b/bigbluebutton-client/src/org/bigbluebutton/main/api/JSAPI.as
index dd6afc395f0c795f620e85bebfdf8283b1058552..cb0afcc91436bc2401ff9936af45cedc8458e2f1 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/api/JSAPI.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/api/JSAPI.as
@@ -44,12 +44,6 @@ package org.bigbluebutton.main.api
       return false;
     }
     
-    public function getBrowserInfo():Array {
-      if (ExternalInterface.available) {
-        return ExternalInterface.call("determineBrowser");
-      }
-      return ["unknown", 0, 0];
-    }
   }
 }
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml
index eee6319ad3fdf1aef5e8ddf123ba20c5b773ce9e..96342523040b0e904a5674908f3b2cc516ce2b47 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/AudioSelectionWindow.mxml
@@ -23,9 +23,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				xmlns:fx="http://ns.adobe.com/mxml/2009"
 				xmlns:mate="http://mate.asfusion.com/"
 				xmlns:common="org.bigbluebutton.common.*"
+				implements="org.bigbluebutton.common.IKeyboardClose"
+				show="this.setFocus()"
 				initialize="init()"
 				layout="absolute"
-				close="onCancelClicked()"
 				verticalScrollPolicy="off"
 				horizontalScrollPolicy="off"
 				showCloseButton="false">
@@ -44,18 +45,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.modules.phone.events.JoinVoiceConferenceCommand;
 			import org.bigbluebutton.modules.phone.events.UseFlashModeCommand;
 			import org.bigbluebutton.modules.phone.models.PhoneOptions;
+			import org.bigbluebutton.util.browser.BrowserCheck;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 			
 			private static const LOGGER:ILogger = getClassLogger(AudioSelectionWindow);      
 
 			private var phoneOptions:PhoneOptions;
-			private var browserInfo:Array;
 
 			private function init():void {
 				phoneOptions = Options.getOptions(PhoneOptions) as PhoneOptions;
 
-				browserInfo = JSAPI.getInstance().getBrowserInfo();
-
 				if (!phoneOptions.listenOnlyMode)
 					btnListenOnly.enabled = false;
 
@@ -75,23 +74,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				}
 
 				// If Puffin browser is deteted and version is less than 4.6
-				if (browserInfo[0] == "Puffin" && String(browserInfo[2]).substr(0, 3) < "4.6") {
+				if (BrowserCheck.isPuffinBelow46()) {
 					vboxListen.percentWidth = 100;
 				}
 			}
-			
+
 			private function onMicClick():void {
 				LOGGER.debug("AudioSelectionWindow - Share Microphone Clicked");
 				var dispatcher:Dispatcher = new Dispatcher();
-				if (browserInfo[0] == "Puffin" && String(browserInfo[2]).substr(0, 3) >= "4.6") {
-					dispatcher.dispatchEvent(new UseFlashModeCommand());	
-				}
-				else {
+				if (BrowserCheck.isPuffin46AndAbove() || (!BrowserCheck.isHttps() && ((BrowserCheck.isChrome() && BrowserCheck.browserMajorVersion >= "60") || (BrowserCheck.isOpera() && BrowserCheck.browserMajorVersion >= "47")))) {
+					dispatcher.dispatchEvent(new UseFlashModeCommand());
+				} else {
 					var command:JoinVoiceConferenceCommand = new JoinVoiceConferenceCommand();
 					command.mic = true;
 					dispatcher.dispatchEvent(command);
 				}
-				
+
 				PopUpUtil.removePopUp(this);
 			}
 			
@@ -106,7 +104,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 			
 			private function onCancelClicked():void {
-				LOGGER.debug("AudioSelectionWindow - Cancel clicked");
+				LOGGER.debug("AudioSelectionWindow - Close clicked");
 				var dispatcher:Dispatcher = new Dispatcher();
 				dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.CLOSED_AUDIO_SELECTION));
 				
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml
index ef9fc85597cad67749505ce61f05ce6a43d2827e..84c386eac9eba1eb47d02d8ab10920f04eb4ba2b 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/BBBSettings.mxml
@@ -3,6 +3,8 @@
 		xmlns:fx="http://ns.adobe.com/mxml/2009"
 		xmlns:common="org.bigbluebutton.common.*" 
 		xmlns:mate="http://mate.asfusion.com/"
+		implements="org.bigbluebutton.common.IKeyboardClose"
+		show="this.setFocus()"
 		layout="vertical"
 		horizontalAlign="center"
 		showCloseButton="false"
@@ -14,6 +16,7 @@
 			import mx.core.UIComponent;
 			import mx.managers.PopUpManager;
 			
+			import org.bigbluebutton.common.IKeyboardClose;
 			import org.bigbluebutton.main.events.BBBEvent;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml
index 3aaea09d0cbe9c5c11aeee9bdf09c2b05d72ea24..5391b2262dcc46be17f37c4d96868eee1e9ed47c 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/CameraDisplaySettings.mxml
@@ -25,7 +25,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 layout="absolute"
                 verticalScrollPolicy="off" horizontalScrollPolicy="off"
                 width="630" height="450" creationComplete="onCreationComplete()" styleName="cameraDisplaySettingsWindowStyle" 
-                showCloseButton="false" close="onCancelClicked()" keyDown="handleKeyDown(event)">
+                showCloseButton="false" keyDown="handleKeyDown(event)">
   <fx:Script>
     <![CDATA[
 		import com.asfusion.mate.events.Dispatcher;
@@ -34,7 +34,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		
 		import mx.collections.ArrayCollection;
 		import mx.collections.ArrayList;
-		import mx.events.CloseEvent;
 		
 		import org.bigbluebutton.common.Media;
 		import org.bigbluebutton.core.BBB;
@@ -188,8 +187,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		
 		private function handleKeyDown(event:KeyboardEvent):void {
 			if (event.charCode == Keyboard.ESCAPE) {
-				disableCamera();
-				this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
+				onCancelClicked();
 			}
 		}
 		
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/ClientStatusWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/ClientStatusWindow.mxml
index f58613d45a7d53a9ed1de0f8a9bf43299a87f7c7..4904357c7ec4831dd8593436d9677eabcb2cf7e6 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/ClientStatusWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/ClientStatusWindow.mxml
@@ -23,12 +23,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				xmlns:fx="http://ns.adobe.com/mxml/2009"
 				xmlns:chat="org.bigbluebutton.modules.chat.views.*"
 				width="500" height="400"
+				implements="org.bigbluebutton.common.IKeyboardClose"
+				show="this.setFocus()"
 				horizontalScrollPolicy="off"
 				title="{ResourceUtil.getInstance().getString('bbb.clientstatus.title')}"
-				horizontalAlign="center"
 				creationComplete="onCreationComplete();">
 	<fx:Script>
 		<![CDATA[
+			import org.bigbluebutton.common.IKeyboardClose;
 			import org.bigbluebutton.core.PopUpUtil;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 			
@@ -45,6 +47,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 		]]>
 	</fx:Script>
-	<chat:AdvancedList id="messageList" width="100%" dragEnabled="false" variableRowHeight="true" wordWrap="true" alternatingItemColors="[#EFEFEF, #FEFEFE]" itemRenderer="org.bigbluebutton.main.views.ClientStatusItemRenderer"/>
+	<chat:AdvancedList id="messageList" width="100%" height="100%" dragEnabled="false" variableRowHeight="true" wordWrap="true" itemRenderer="org.bigbluebutton.main.views.ClientStatusItemRenderer"/>
 	<mx:Button id="closeBtn" label="{ResourceUtil.getInstance().getString('bbb.clientstatus.close')}" click="handleCloseButtonClick();" />
 </mx:TitleWindow>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
index f9b180daa6514a71a2a836310ac903babb6ab473..c5fab8fe03f26bd63ce141e2f284558bc648ecf8 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
@@ -25,8 +25,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				width="600" height="390"
 				verticalScrollPolicy="off"
 				creationComplete="onCreationComplete()" 
-				showCloseButton="false" 
-				close="onCancelClicked()" 
+				showCloseButton="false"
 				keyDown="handleKeyDown(event)">
 
 	<fx:Declarations>
@@ -44,7 +43,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import flash.ui.Keyboard;
 			
 			import mx.controls.sliderClasses.Slider;
-			import mx.events.CloseEvent;
 			import mx.events.SliderEvent;
 			
 			import org.as3commons.logging.api.ILogger;
@@ -184,7 +182,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			// Added by Chad to enable closing the window without clicking the X
 			private function handleKeyDown(event:KeyboardEvent):void {
 				if (event.charCode == Keyboard.ESCAPE) {
-					this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
+					onCancelClicked();
 				}
 			}
 								
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml
index c2f56a5270a2f666050203d241fd477e6baf399e..8cd0a52add52754f64f63e0f573503ee9d1aa50b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/GuestWindow.mxml
@@ -131,7 +131,6 @@ $Id: $
             public function closeWindow():void {
                 this.visible = false;
                 PopUpManager.removePopUp(this);
-                //dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
             }
             
         ]]>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/LockSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/LockSettings.mxml
index cba5732e212519d275465df4cc0a217e15491978..82da5cbe347b1d786a9beebd310ba7221e93c9d4 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/LockSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/LockSettings.mxml
@@ -21,15 +21,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:TitleWindow xmlns:mx="library://ns.adobe.com/flex/mx" 
 				xmlns:fx="http://ns.adobe.com/mxml/2009"
 				xmlns:mate="http://mate.asfusion.com/" 
+				implements="org.bigbluebutton.common.IKeyboardClose"
+				show="this.setFocus()"
 				xmlns:common="org.bigbluebutton.common.*"
 				minWidth="340" showCloseButton="false" 
-				close="onCancelClicked()" 
 				keyDown="handleKeyDown(event)">
 	
 	<fx:Script>
 		<![CDATA[
-			import mx.events.CloseEvent;
-			
 			import org.bigbluebutton.core.PopUpUtil;
 			import org.bigbluebutton.core.events.LockControlEvent;
 			import org.bigbluebutton.core.vo.LockSettingsVO;
@@ -49,7 +48,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			private function handleKeyDown(event:KeyboardEvent):void {
 				if (event.charCode == Keyboard.ESCAPE) {
-					this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
+					onCancelClicked();
 				}
 			}
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml
index 1d7dfdbee6996145fda94d36b0a60e2830c676f0..7fbcafb862f8ca76e7c293db655370d10d20caa7 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/LogoutWindow.mxml
@@ -22,6 +22,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:TitleWindow xmlns:mx="library://ns.adobe.com/flex/mx"
 		  xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:mate="http://mate.asfusion.com/"
+		  implements="org.bigbluebutton.common.IKeyboardClose"
 		  verticalScrollPolicy="off"
           horizontalScrollPolicy="off"
           horizontalAlign="center"
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
index db065eafb55228f8316a285c58bf981a7920e3d6..8f03ee55e415ac339dc434c03f6cc0208c973347 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
@@ -150,6 +150,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
 			import org.bigbluebutton.modules.phone.events.WebRTCMediaEvent;
 			import org.bigbluebutton.modules.phone.models.PhoneOptions;
+			import org.bigbluebutton.util.browser.BrowserCheck;
 			import org.bigbluebutton.modules.users.model.UsersOptions;
 			import org.bigbluebutton.modules.users.views.BreakoutRoomSettings;
 			import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
@@ -492,21 +493,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private function versionCheck():void {
 				var browserOptions : BrowserVersionsOptions = Options.getOptions(BrowserVersionsOptions) as BrowserVersionsOptions;
 				if (!StringUtils.isEmpty(browserOptions.chrome) && !StringUtils.isEmpty(browserOptions.firefox) && !StringUtils.isEmpty(browserOptions.flash)) {
-					//find browser version
-					var browserVersion:Array = ExternalInterface.call("determineBrowser");
 					//check browser version
-					if ((browserVersion[0].toString().toLowerCase() == "chrome" && browserVersion[1] < browserOptions.chrome) || browserVersion[0].toString().toLowerCase() == "firefox" && browserVersion[1] < browserOptions.firefox) {
+					if ((BrowserCheck.isChrome() && BrowserCheck.browserMajorVersion < browserOptions.chrome) || BrowserCheck.isFirefox() && BrowserCheck.browserMajorVersion < browserOptions.firefox) {
 						globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT, 
 							ResourceUtil.getInstance().getString("bbb.clientstatus.browser.title"), 
-							ResourceUtil.getInstance().getString("bbb.clientstatus.browser.message", [browserVersion[0]+" "+browserVersion[1]]),
+							ResourceUtil.getInstance().getString("bbb.clientstatus.browser.message", [BrowserCheck.browserName+" "+BrowserCheck.browserMajorVersion]),
 							'bbb.clientstatus.browser.message'));
 					}
 					
 					//find flash version
 					var flashVersion:Object = getFlashVersion(); 
 					//check flash version
-					if ((flashVersion.os == 'LNX' && browserVersion[0].toString().toLowerCase() != "chrome" && flashVersion.major < 11) || 
-						((flashVersion.os != 'LNX' || browserVersion[0].toString().toLowerCase() == "chrome") && flashVersion.major < browserOptions.flash)) {
+					if ((flashVersion.os == 'LNX' && !BrowserCheck.isChrome() && flashVersion.major < 11) || 
+						((flashVersion.os != 'LNX' || BrowserCheck.isChrome()) && flashVersion.major < browserOptions.flash)) {
 						globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT, 
 							ResourceUtil.getInstance().getString("bbb.clientstatus.flash.title"), 
 							ResourceUtil.getInstance().getString("bbb.clientstatus.flash.message", [flashVersion.major+"."+flashVersion.minor+"."+flashVersion.build]),
@@ -607,7 +606,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
             }
 
             private function wrongLocaleVersion():void {
-                var localeWindow:OldLocaleWarnWindow = PopUpUtil.createNonModelPopUp(mdiCanvas, OldLocaleWarnWindow, false) as OldLocaleWarnWindow;
+                var localeWindow:OldLocaleWarnWindow = PopUpUtil.createNonModalPopUp(mdiCanvas, OldLocaleWarnWindow, false) as OldLocaleWarnWindow;
                 if (localeWindow) {
                     var point1:Point = new Point();
                     // Calculate position of TitleWindow in Application's coordinates. 
@@ -629,9 +628,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
             private function handleWebRTCMediaRequestEvent(event:WebRTCMediaEvent):void {
                 var options:PhoneOptions = new PhoneOptions();
                 if (!options.showMicrophoneHint) return;
-                var browser:String = ExternalInterface.call("determineBrowser")[0];
                 var browserPermissionHelper:BrowserPermissionHelper = PopUpUtil.createModalPopUp(mdiCanvas, BrowserPermissionHelper, false) as BrowserPermissionHelper;
-                if (browser == "Firefox") {
+                if (BrowserCheck.isFirefox()) {
                     if (browserPermissionHelper) {
 						if (Capabilities.os.indexOf("Mac") >= 0){
 							browserPermissionHelper.currentState = "firefoxMicMacOSX";
@@ -642,7 +640,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 						browserPermissionHelper.x = 50;
 						browserPermissionHelper.y = 200;
                     }
-                } else if (browser == "Chrome") {
+                } else if (BrowserCheck.isChrome()) {
                     if (browserPermissionHelper) {
 						browserPermissionHelper.currentState = "chromeMic";
 						browserPermissionHelper.x = 50;
@@ -666,14 +664,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
             }
 
             private function handleShareCameraRequestEvent(event:ShareCameraRequestEvent):void {
-                if (ExternalInterface.call("determineBrowser")[0] == "Chrome") {
+                if (BrowserCheck.isChrome()) {
 					// Show browserPermissionHelper component after showing the webcam window due event listeners registration order
                     setTimeout(showbrowserPermissionHelper, 100);
                 }
             }
 			
 			private function showbrowserPermissionHelper() : void {
-				var browserPermissionHelper : BrowserPermissionHelper = PopUpUtil.createNonModelPopUp(mdiCanvas, BrowserPermissionHelper, false) as BrowserPermissionHelper;
+				var browserPermissionHelper : BrowserPermissionHelper = PopUpUtil.createNonModalPopUp(mdiCanvas, BrowserPermissionHelper, false) as BrowserPermissionHelper;
 				if (browserPermissionHelper) {
 					browserPermissionHelper.currentState = "chromeCam";
 					browserPermissionHelper.x = 20;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
index 25d3d136cfac795d93bc6f880a9fa87bd8e63715..8497de825622a1f99eefbd23e3aa60fe0c25f6e3 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainToolbar.mxml
@@ -75,6 +75,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.common.events.ToolbarButtonEvent;
 			import org.bigbluebutton.core.BBB;
 			import org.bigbluebutton.core.Options;
+			import org.bigbluebutton.core.PopUpUtil;
 			import org.bigbluebutton.core.TimerUtil;
 			import org.bigbluebutton.core.UsersUtil;
 			import org.bigbluebutton.core.events.MeetingTimeRemainingEvent;
@@ -311,14 +312,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			private function confirmLogout():void {
 				if (toolbarOptions.confirmLogout) {
-					var logoutWindow:LogoutWindow;
-					logoutWindow = LogoutWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, LogoutWindow, true));
+					var logoutWindow:LogoutWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, LogoutWindow, true) as LogoutWindow;
 
 					var newX:Number = this.width - logoutWindow.width - 5;
 					var newY:Number = btnLogout.y + btnLogout.height + 5;
 
-					PopUpManager.centerPopUp(logoutWindow);
-
 					logoutWindow.x = newX;
 					logoutWindow.y = newY;
 				} else {
@@ -528,8 +526,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 
 			private function onSettingsButtonClick():void {
-				settingsPopup = BBBSettings(PopUpManager.createPopUp(this.parent, BBBSettings, true));
+				settingsPopup = PopUpUtil.createModalPopUp(this.parent, BBBSettings, true) as BBBSettings;
 				settingsPopup.pushComponents(settingsComponents);
+				PopUpManager.centerPopUp(settingsPopup);
 			}
 
 			private function refreshRole(e:ChangeMyRole):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml
index 87f69ff8a22bba353570f058119c8a8bbf408a83..2e31a4454a1a2f797926061f4603f674905f85b6 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml
@@ -24,8 +24,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				xmlns:common="org.bigbluebutton.common.*"
 				width="600" height="380"
 				creationComplete="onCreationComplete()"
-				showCloseButton="false"
-				close="onCancelClicked()">
+				showCloseButton="false">
 	
 	<fx:Declarations>
 		<mate:Listener type="{WebRTCEchoTestStartedEvent.WEBRTC_ECHO_TEST_STARTED}" method="handleWebRTCEchoTestStartedEvent" />
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/managers/LayoutManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/managers/LayoutManager.as
index 1cc0824e14012f022f9d6ea54964c9a51be4948b..8789bd413f8f2be157101797fdc91088fa810d0b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/managers/LayoutManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/managers/LayoutManager.as
@@ -33,7 +33,6 @@ package org.bigbluebutton.modules.layout.managers
   import mx.events.CloseEvent;
   import mx.events.EffectEvent;
   import mx.events.ResizeEvent;
-  import mx.managers.PopUpManager;
   
   import flexlib.mdi.containers.MDICanvas;
   import flexlib.mdi.containers.MDIWindow;
@@ -43,6 +42,7 @@ package org.bigbluebutton.modules.layout.managers
   import org.as3commons.logging.api.getClassLogger;
   import org.bigbluebutton.common.CustomMdiWindow;
   import org.bigbluebutton.core.Options;
+  import org.bigbluebutton.core.PopUpUtil;
   import org.bigbluebutton.core.UsersUtil;
   import org.bigbluebutton.core.events.SwitchedLayoutEvent;
   import org.bigbluebutton.core.model.LiveMeeting;
@@ -130,9 +130,8 @@ package org.bigbluebutton.modules.layout.managers
 		public function alertSaveCurrentLayoutFile(e:CloseEvent):void {
 				// Check to see if the YES button was pressed.
 				if (e.detail==Alert.YES) {
-					var layoutNameWindow:CustomLayoutNameWindow = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true) as CustomLayoutNameWindow;
+					var layoutNameWindow:CustomLayoutNameWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true) as CustomLayoutNameWindow;
 					layoutNameWindow.savingForFileDownload = true;
-					PopUpManager.centerPopUp(layoutNameWindow);
 				} else if (e.detail==Alert.NO){
 					saveLayoutsWindow();
 				}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/AddButton.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/AddButton.mxml
index 8379e718a56b126b79eec8b8248fa383700bd320..94a959779e4f7ca7d1b649817e04fec1db06c40b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/AddButton.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/AddButton.mxml
@@ -34,9 +34,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import flash.events.Event;
 			
 			import mx.core.FlexGlobals;
-			import mx.core.IFlexDisplayObject;
-			import mx.managers.PopUpManager;
 			
+			import org.bigbluebutton.core.PopUpUtil;
 			import org.bigbluebutton.core.UsersUtil;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 
@@ -46,8 +45,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 			
 			private function onClick(e:Event):void {
-				var layoutNameWindow:IFlexDisplayObject = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true);
-				PopUpManager.centerPopUp(layoutNameWindow);
+				PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, CustomLayoutNameWindow, true);
 			}
 			
 			public function refreshRole(amIModerator:Boolean):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/CustomLayoutNameWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/CustomLayoutNameWindow.mxml
index 0a76cea90ca0fd8806c1a47e165005325eee0815..fb9c77872605c83fadc7b9947fa86721ac9d0878 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/CustomLayoutNameWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/CustomLayoutNameWindow.mxml
@@ -22,14 +22,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:TitleWindow xmlns:mx="library://ns.adobe.com/flex/mx"
 		  xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:mate="http://mate.asfusion.com/"
+		  xmlns:common="org.bigbluebutton.common.*"
+		  implements="org.bigbluebutton.common.IKeyboardClose"
           verticalScrollPolicy="off"
           horizontalScrollPolicy="off"
           horizontalAlign="center"
-          showCloseButton="true"
-          close="onCancelClicked()"
+		  layout="absolute"
+		  showCloseButton="false"
           creationComplete="onCreationComplete()"
-          width="250"
-          title="{ResourceUtil.getInstance().getString('bbb.layout.window.name')}">
+          width="280">
 
 	<fx:Declarations>
 	  <mate:Listener type="{LayoutNameInUseEvent.LAYOUT_NAME_IN_USE_EVENT}" method="handleLayoutNameInUse"/>
@@ -37,13 +38,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
   <fx:Script>
     <![CDATA[
-      import com.asfusion.mate.events.Dispatcher;
-      
-      import mx.managers.PopUpManager;
-      
-      import org.bigbluebutton.modules.layout.events.LayoutEvent;
-      import org.bigbluebutton.modules.layout.events.LayoutNameInUseEvent;
-      import org.bigbluebutton.util.i18n.ResourceUtil;
+		import com.asfusion.mate.events.Dispatcher;
+		
+		import mx.managers.PopUpManager;
+		
+		import org.as3commons.logging.api.ILogger;
+		import org.as3commons.logging.api.getClassLogger;
+		import org.bigbluebutton.modules.layout.events.LayoutEvent;
+		import org.bigbluebutton.modules.layout.events.LayoutNameInUseEvent;
+		import org.bigbluebutton.util.i18n.ResourceUtil;
+		
+		private static const LOGGER:ILogger = getClassLogger(CustomLayoutNameWindow);      
 
       public var savingForFileDownload:Boolean = false;
 
@@ -65,7 +70,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
             savingForFileDownload = false;
           }
         } else {
-          trace("The name is already in use, waiting for overwrite command or rename");
+          LOGGER.debug("The name is already in use, waiting for overwrite command or rename");
         }
       }
 
@@ -79,8 +84,23 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
     ]]>
   </fx:Script>
 
-  <mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
-      <mx:TextInput id="textInput" maxChars="140" width="100%" text="{ResourceUtil.getInstance().getString('bbb.layout.combo.customName')}" enter="addButton_clickHandler()"/>
-      <mx:Button id="addButton" click="addButton_clickHandler()" enabled="{textInput.text.length > 0}" styleName="addLayoutButtonStyle" toolTip="{ResourceUtil.getInstance().getString('bbb.layout.addButton.toolTip')}"/>
-  </mx:HBox>
+  <mx:VBox width="100%"
+		   height="100%"
+		   paddingTop="5"
+		   horizontalAlign="center">
+	  <common:AdvancedLabel text="{ResourceUtil.getInstance().getString('bbb.layout.window.name')}"
+							styleName="titleWindowStyle"
+							width="180" />
+	  <mx:TextInput id="textInput" height="26" maxChars="140" width="100%"
+					text="{ResourceUtil.getInstance().getString('bbb.layout.combo.customName')}"
+					enter="addButton_clickHandler()" />
+	  <mx:Button id="addButton" height="30" width="100%" click="addButton_clickHandler()" enabled="{textInput.text.length > 0}" styleName="mainActionButton"
+				 label="{ResourceUtil.getInstance().getString('bbb.layout.addButton.label')}" toolTip="{ResourceUtil.getInstance().getString('bbb.layout.addButton.toolTip')}" />
+  </mx:VBox>
+
+  <mx:Button id="closeButton" click="onCancelClicked()" styleName="titleWindowCloseButton"
+		     toolTip="{ResourceUtil.getInstance().getString('bbb.layout.window.close.tooltip')}"
+			 top="15" right="10"
+			 accessibilityName="{ResourceUtil.getInstance().getString('bbb.layout.window.accessibilityName')}" />
+
 </mx:TitleWindow>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/WebRTCCallManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/WebRTCCallManager.as
index e21ee048af77da323b6082b210596457e4b2306b..732d6406026782f56c7844cbd82cac80944d53fb 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/WebRTCCallManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/WebRTCCallManager.as
@@ -14,7 +14,6 @@ package org.bigbluebutton.modules.phone.managers
   import org.as3commons.logging.util.jsonXify;
   import org.bigbluebutton.core.Options;
   import org.bigbluebutton.core.UsersUtil;
-  import org.bigbluebutton.main.api.JSAPI;
   import org.bigbluebutton.main.events.ClientStatusEvent;
   import org.bigbluebutton.main.model.users.AutoReconnect;
   import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
@@ -36,8 +35,6 @@ package org.bigbluebutton.modules.phone.managers
     private static const LOGGER:ILogger = getClassLogger(WebRTCCallManager);
     private const MAX_RETRIES:Number = 3;
     
-    private var browserType:String = "unknown";
-    private var browserVersion:int = 0;
     private var dispatcher:Dispatcher = new Dispatcher();
     private var echoTestDone:Boolean = false;
     
@@ -50,11 +47,6 @@ package org.bigbluebutton.modules.phone.managers
     private var reconnecting:Boolean = false;
     
     public function WebRTCCallManager() {
-      var browserInfo:Array = JSAPI.getInstance().getBrowserInfo();
-      if (browserInfo != null) {
-        browserType = browserInfo[0];
-        browserVersion = browserInfo[1];
-      }
       options = Options.getOptions(PhoneOptions) as PhoneOptions;
       
       // only show the warning if the admin has enabled WebRTC
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollChoicesModal.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollChoicesModal.mxml
index 816fc93020d6a6336ae25863ee02e9d24d29510e..7ebd65c0be60d25b577b86f4546f85644171a7b6 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollChoicesModal.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollChoicesModal.mxml
@@ -21,15 +21,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
 				xmlns:s="library://ns.adobe.com/flex/spark" 
 				xmlns:mx="library://ns.adobe.com/flex/mx"
+				xmlns:common="org.bigbluebutton.common.*"
 				width="350" layout="vertical"
-				close="onCloseClicked()"
-				show="{focusManager.setFocus(choiceFirst)}" xmlns:common="org.bigbluebutton.common.*">
+				implements="org.bigbluebutton.common.IKeyboardClose"
+				show="focusManager.setFocus(choiceFirst)">
 	<fx:Script>
 		<![CDATA[
 			import com.asfusion.mate.events.Dispatcher;
 			
 			import org.as3commons.lang.ArrayUtils;
 			import org.as3commons.lang.StringUtils;
+			import org.bigbluebutton.common.IKeyboardClose;
 			import org.bigbluebutton.core.PopUpUtil;
 			import org.bigbluebutton.modules.polling.events.StartCustomPollEvent;
 			import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml
index 4eb3924045ab92941f62c2dc3c36faf98efb532e..291fb756de190a1f2de03fc485431c3a48f08e4d 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileDownloadWindow.mxml
@@ -24,9 +24,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				xmlns:fx="http://ns.adobe.com/mxml/2009"
 				xmlns:mate="http://mate.asfusion.com/"
 				xmlns:common="org.bigbluebutton.common.*"
+				implements="org.bigbluebutton.common.IKeyboardClose"
 				layout="absolute"
 				width="580"
 				height="410"
+				creationComplete="creationCompleteHandler(event)"
 				close="onCancelClicked()"
 				initialize="initData();" >
 
@@ -37,6 +39,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	<fx:Script>
 		<![CDATA[
 			import mx.collections.ArrayCollection;
+			import mx.events.FlexEvent;
 			
 			import org.bigbluebutton.modules.present.events.DownloadEvent;
 			import org.bigbluebutton.modules.present.model.PresentationModel;
@@ -44,6 +47,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 			[Bindable]
 			private var downloadablePresentations:ArrayCollection;
+			
+			protected function creationCompleteHandler(event:FlexEvent):void {
+				closeButton.setFocus()
+			}
 
 			override public function move(x:Number, y:Number):void {
 				return;
@@ -56,6 +63,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private function onCancelClicked():void {
 				globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW));
 			}
+			
 		]]>
 
 	</fx:Script>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as
index 3f6ce65b49f99b2657ca25a9e4c14c660a73e44e..031bbe8f8ff1fc4230aa0c887a3794ab7491ccc5 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as
@@ -36,7 +36,7 @@ package org.bigbluebutton.modules.screenshare.managers {
     import org.bigbluebutton.modules.screenshare.model.ScreenshareModel;
     import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
     import org.bigbluebutton.modules.screenshare.services.ScreenshareService;
-    import org.bigbluebutton.modules.screenshare.utils.BrowserCheck;
+    import org.bigbluebutton.util.browser.BrowserCheck;
 
     public class ScreenshareManager {
         private static const LOGGER:ILogger = getClassLogger(ScreenshareManager);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/BrowserCheck.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/BrowserCheck.as
deleted file mode 100755
index fb83f9057f4f06553cca241315b8aacee8ab609d..0000000000000000000000000000000000000000
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/BrowserCheck.as
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
-* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
-*
-* Copyright (c) 2016 BigBlueButton Inc. and by respective authors (see below).
-*
-* This program is free software; you can redistribute it and/or modify it under the
-* terms of the GNU Lesser General Public License as published by the Free Software
-* Foundation; either version 3.0 of the License, or (at your option) any later
-* version.
-*
-* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
-* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License along
-* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-package org.bigbluebutton.modules.screenshare.utils
-{
-	import flash.external.ExternalInterface;
-	
-	import org.as3commons.logging.api.ILogger;
-	import org.as3commons.logging.api.getClassLogger;
-
-	public class BrowserCheck {
-		private static const LOGGER:ILogger = getClassLogger(BrowserCheck);
-
-		public static function isWebRTCSupported():Boolean {
-			/*LOGGER.debug("isWebRTCSupported - ExternalInterface.available=[{0}], isWebRTCAvailable=[{1}]", [ExternalInterface.available, ExternalInterface.call("isWebRTCAvailable")]);*/
-			return (ExternalInterface.available && ExternalInterface.call("isWebRTCAvailable"));
-		}
-
-		public static function isChrome():Boolean {
-			var browser:Array = ExternalInterface.call("determineBrowser");
-			return browser[0] == "Chrome";
-		}
-
-		public static function isFirefox():Boolean {
-			var browser:Array = ExternalInterface.call("determineBrowser");
-			return browser[0] == "Firefox";
-		}
-
-		public static function isHttps():Boolean {
-                        var url:String = ExternalInterface.call("window.location.href.toString");
-                        var httpsPattern:RegExp = /^https/;
-                        return httpsPattern.test(url);
-                }
-	}
-}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/WebRTCScreenshareUtility.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/WebRTCScreenshareUtility.as
index 49c52d33ba3fb3148a43d36a69b728ee7db41b08..3cafe37827d60d3167de125dd157c192f4778774 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/WebRTCScreenshareUtility.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/utils/WebRTCScreenshareUtility.as
@@ -26,6 +26,7 @@ package org.bigbluebutton.modules.screenshare.utils
   import org.as3commons.logging.api.getClassLogger;
   import org.bigbluebutton.core.Options;
   import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
+  import org.bigbluebutton.util.browser.BrowserCheck;
 
   public class WebRTCScreenshareUtility {
     private static const LOGGER:ILogger = getClassLogger(WebRTCScreenshareUtility);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
index 52461fc6ae8fd5b5b4b945fe08193bf2f9e4ebe9..d4cdf78e29adfff2a21625c2dcb36b84e4e5904b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
@@ -128,8 +128,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
           os = "";
         }
 
-        browser = ExternalInterface.call("determineBrowser")[0];
-
         windowControls.maximizeRestoreBtn.enabled = false;
 
         titleBarOverlay.tabIndex = dsOptions.baseTabIndex;
@@ -343,23 +341,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         captureWidth = capWidth;
         captureHeight = capHeight;
 
-        var vidW:Number = captureWidth;
-        var vidH:Number = captureHeight;
-
-        // for some reason videoHolder's height is always '0' even when set to 100% so we have to do it manually
-        videoWrapper.height = this.height - controlBar.height - this.titleBar.height - pauseBtn.height - publishView.getStyle('paddingTop') - publishView.getStyle('paddingBottom') - 10;
-        videoWrapper.width = this.width - publishView.getStyle('paddingLeft') - publishView.getStyle('paddingRight') - 10;
-
-        vidW = videoWrapper.width;
-        vidH = videoWrapper.width * captureHeight / captureWidth;
-
-        if (vidH > videoWrapper.height) {
-          vidH = videoWrapper.height;
-          vidW = videoWrapper.height * captureWidth / captureHeight;
-        }
+		video = new Video(captureWidth, captureHeight);
+		
+		// for some reason videoHolder's height is always '0' even when set to 100% so we have to do it manually
+		video.width=this.width - publishView.getStyle('paddingLeft') - publishView.getStyle('paddingRight') - 10;
+		video.scaleY=video.scaleX;
+		if(video.height>this.height - controlBar.height - this.titleBar.height - publishView.getStyle('paddingTop') - publishView.getStyle('paddingBottom') - 10){
+			video.height=this.height - controlBar.height - this.titleBar.height - publishView.getStyle('paddingTop') - publishView.getStyle('paddingBottom') - 10;
+			video.scaleX=video.scaleY;
+		}
+		videoWrapper.width = video.width;
+		videoWrapper.height = video.height;
 
-        LOGGER.debug("deskshare preview[" + captureWidth + "," + captureHeight + "][" + vidW + "," + vidH + "]");
-        video = new Video(vidW, vidH);
+        LOGGER.debug("deskshare preview[" + captureWidth + "," + captureHeight + "][" + video.width + "," + video.height + "]");
 
         videoWrapper.addChild(video);
         video.x = videoWrapper.width/2 - video.width/2;
@@ -377,8 +371,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
         pauseBox.visible = pauseBox.includeInLayout = false;
         videoWrapper.visible = videoWrapper.includeInLayout = true;
-        pauseBox.width = vidW;
-        pauseBox.height = vidH;
+
+        pauseBox.width = videoWrapper.width;
+        pauseBox.height = videoWrapper.height;
       }
 
       public function onMetaData(info:Object):void{
@@ -586,20 +581,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
     </mx:VBox>
     <mx:VBox id="previewBox" width="100%" height="100%" visible="false" horizontalAlign="center" >
       <mx:Box id="videoHolder" width="100%" height="90%" horizontalAlign="center">
-        <mx:UIComponent id="videoWrapper" width="100%" height="100%" />
+        <mx:UIComponent id="videoWrapper" width="100%" height="100%" verticalCenter="0" horizontalCenter="0"/>
         <mx:VBox id="pauseBox" visible="false" includeInLayout="false" styleName="desksharePublishPauseBox" >
           <mx:Text width="100%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pauseMessage.label')}" />
         </mx:VBox>
 	  </mx:Box>
-      <mx:Button id="pauseBtn"
-                 click="pauseSharing()"
-                 toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.tooltip')}"
-                 label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.label')}" />
-      <mx:Button id="restartBtn"
-                 visible="false" includeInLayout="false"
-                 click="pauseSharing()"
-                 toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.tooltip')}"
-                 label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.label')}" />
     </mx:VBox>
     <mx:VBox id="errorBox" width="100%" height="100%" visible="false" includeInLayout="false" horizontalAlign="center" verticalAlign="middle">
       <mx:Text id="startFailedLbl" width="70%" visible="false" includeInLayout="false" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.startFailed.label')}"/>
@@ -619,6 +605,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         <mx:ComboBox id="shareTypeCombo" dataProvider="{shareTypeProvider}" />
       </mx:HBox>
     <mx:Spacer width="80%" />
+	<mx:Button id="pauseBtn" visible="false" includeInLayout="false" click="pauseSharing()" toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.tooltip')}" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pause.label')}" />
+	<mx:Button id="restartBtn" visible="false" includeInLayout="false" click="pauseSharing()" toolTip="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.tooltip')}" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.label')}" />
     <mx:Button id="startBtn" styleName="mainActionButton" click="onStartButtonClick()" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.startButton.label')}" />
     <mx:Button id="cancelBtn" click="closeWindow()" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.cancelButton.label')}" />
     <mx:Button id="stopBtn" styleName="mainActionButton" visible="false" includeInLayout="false" click="close()" label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.stopButton.label')}" />
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreenshareViewWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreenshareViewWindow.mxml
index d4165714c7df333f5c04de5009a2d7621b4f53f8..46db2ca82b47c2a613da7de21615368017f8a29a 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreenshareViewWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreenshareViewWindow.mxml
@@ -27,13 +27,14 @@
            width="100%"
            height="400"
            initialize="init()"
+		   layout="absolute"
            creationComplete="onCreationComplete()"
            implements="org.bigbluebutton.common.IBbbModuleWindow"
            xmlns:mate="http://mate.asfusion.com/"
            title="{    ResourceUtil.getInstance().getString('bbb.screenshareView.title')    }"
            showCloseButton="false"
            resize="fitToWindow()">
-
+ 
   <fx:Declarations>
     <mate:Listener type="{    ViewStreamEvent.STOP    }" method="onStopViewStreamEvent" />
     <mate:Listener type="{    LocaleChangeEvent.LOCALE_CHANGED    }" method="localeChanged" />
@@ -42,6 +43,7 @@
 
     <fx:Script>
         <![CDATA[
+			import mx.core.ScrollPolicy;
 			import mx.core.UIComponent;
 			
 			import flexlib.mdi.events.MDIWindowEvent;
@@ -66,9 +68,6 @@
             private static const LOG:String = "SC::ScreenshareViewWIndow - ";
             private static const LOGGER:ILogger = getClassLogger(ScreenshareViewWindow);
 
-			private var screenHeight:Number = Capabilities.screenResolutionY;
-			private var screenWidth:Number = Capabilities.screenResolutionX;
-
 			private var streamAvailable:Boolean = false;
 
 			private var video:Video;
@@ -79,7 +78,7 @@
 			private var videoWidth:Number = 1;
 
 			private static const VIDEO_WIDTH_PADDING:int = 7;
-			private static const VIDEO_HEIGHT_PADDING:int = 65;
+			private static const VIDEO_HEIGHT_PADDING:int = 40;
 
 			// The following code block is to deal with a bug in FLexLib
 			// with MDI windows not responding well to being maximized
@@ -90,19 +89,17 @@
 			private var isMaximized:Boolean = false;
 			private var connection:Connection;
 
-			[Bindable] private var baseIndex:int;
 			[Bindable] private var dsOptions:ScreenshareOptions;
 
 			private function init():void{
 				dsOptions = Options.getOptions(ScreenshareOptions) as ScreenshareOptions;
-				baseIndex = dsOptions.baseTabIndex;
 			}
 
 			private function onCreationComplete():void{
 				viewScreenshareStream();
 
 				videoHolder.addChild(video);
-				this.addChild(videoHolder);
+				videoCanvas.addChildAt(videoHolder, 0);
 				videoHolder.percentWidth = 100;
 				videoHolder.percentHeight = 100;
 				addEventListener(MDIWindowEvent.RESIZE_END, onResizeEndEvent);
@@ -111,11 +108,6 @@
 
 				resourcesChanged();
 
-				titleBarOverlay.tabIndex = baseIndex;
-				minimizeBtn.tabIndex = baseIndex+1;
-				maximizeRestoreBtn.tabIndex = baseIndex+2;
-				closeBtn.tabIndex = baseIndex+3;
-
 				var logData:Object = UsersUtil.initLogData();
 				logData.tags = ["screenshare"];
 				logData.width = videoWidth;
@@ -186,19 +178,6 @@
         LOGGER.info(JSON.stringify(logData));
       }
 
-      protected function updateButtonsPosition():void {
-        if (this.width < bottomBar.width) {
-          bottomBar.visible = false;
-        }
-
-        if (bottomBar.visible == false) {
-          bottomBar.y = bottomBar.x = 0;
-        } else {
-          bottomBar.y = (this.height - bottomBar.height) / 2;
-          bottomBar.x = (this.width - bottomBar.width) / 2;
-        }
-      }
-
 			public function stopViewing():void {
 				ns.close();
 				closeWindow();
@@ -239,7 +218,7 @@
 			}
 
             /**
-             * resizes the desktop sharing video to fit to this window
+             * Resizes the desktop sharing video to fit to this window
              */
             private function fitToWindow():void {
                 if (!streamAvailable)
@@ -253,15 +232,23 @@
                 if (!btnActualSize.selected) {
                     fitVideoToWindow();
                 }
-            }
 
+				videoHolder.verticalCenter = 0;
+				videoHolder.horizontalCenter = 0;
+            }
 
 			private function fitVideoToWindow():void {
-				if (this.width < this.height) {
-					fitToWidthAndAdjustHeightToMaintainAspectRatio();
-				} else {
-					fitToHeightAndAdjustWidthToMaintainAspectRatio();
+				video.width=this.width - VIDEO_WIDTH_PADDING;
+				video.scaleY=video.scaleX;
+				if(video.height>this.height - VIDEO_HEIGHT_PADDING){
+					video.height=this.height - VIDEO_HEIGHT_PADDING;
+					video.scaleX=video.scaleY;
 				}
+				videoHolder.width = video.width;
+				videoHolder.height = video.height;
+
+				videoCanvas.verticalScrollPolicy = ScrollPolicy.OFF;
+				videoCanvas.horizontalScrollPolicy = ScrollPolicy.OFF;
 			}
 
 			private function fitWindowToVideo():void {
@@ -269,33 +256,12 @@
 				videoHolder.width = videoWidth;
 				video.height = videoHeight;
 				videoHolder.height = videoHeight;
-				this.height = videoHeight + VIDEO_HEIGHT_PADDING;
-				this.width = videoWidth + VIDEO_WIDTH_PADDING;
 			}
 
 			private function videoIsSmallerThanWindow():Boolean {
 				return (videoHeight < this.height) && (videoWidth < this.width);
 			}
 
-
-			private function fitToWidthAndAdjustHeightToMaintainAspectRatio():void {
-					video.width = this.width - VIDEO_WIDTH_PADDING;
-					videoHolder.width = video.width;
-					// Maintain aspect-ratio
-					video.height = (videoHeight * video.width) / videoWidth;
-					videoHolder.height = video.height;
-					this.height = video.height + VIDEO_HEIGHT_PADDING;
-			}
-
-			private function fitToHeightAndAdjustWidthToMaintainAspectRatio():void {
-					video.height = this.height - VIDEO_HEIGHT_PADDING;
-					videoHolder.height = video.height;
-					// Maintain aspect-ratio
-					video.width = (videoWidth * video.height) / videoHeight;
-					videoHolder.width = video.width;
-					this.width = video.width + VIDEO_WIDTH_PADDING;
-			}
-
 			/**
 			 * resizes the desktop sharing video to actual video resolution
 			 */
@@ -308,6 +274,9 @@
 					video.height = videoHeight;
 					videoHolder.height = videoHeight;
 				}
+				
+				videoCanvas.verticalScrollPolicy = ScrollPolicy.AUTO;
+				videoCanvas.horizontalScrollPolicy = ScrollPolicy.AUTO;
 			}
 
 			private function determineHowToDisplayVideo():void {
@@ -354,17 +323,20 @@
 		]]>
   </fx:Script>
 
-    <mx:HBox id="bottomBar" visible="true" height="30" horizontalAlign="center" paddingTop="0" paddingBottom="0" width="100%">
-        <mx:Button id="btnActualSize"
-                   paddingTop="0"
-                   paddingBottom="0"
-                   styleName="deskshareControlButtonStyle"
-                   toggle="true"
-                   click="determineHowToDisplayVideo()"
-                   selected="false"
-                   height="90%"
-                   label="{    btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize')    }"
-                   toolTip="{    btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize')    }"
-                   tabIndex="{    baseIndex + 4    }" />
-    </mx:HBox>
+	<fx:Declarations>
+		<common:TabIndexer id="tabIndexer" startIndex="{dsOptions.baseTabIndex + 1}"
+						   tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, btnActualSize]}"/>
+	</fx:Declarations>
+
+	<mx:Canvas id="videoCanvas" width="100%" height="100%" />
+    <mx:Button id="btnActualSize"
+               toggle="true"
+			   horizontalCenter="0"
+			   top="{VIDEO_HEIGHT_PADDING}"
+               click="determineHowToDisplayVideo()"
+			   mouseOut="btnActualSize.alpha = 0"
+			   mouseOver="btnActualSize.alpha = 100"
+               selected="false"
+               label="{    btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize')    }"
+               toolTip="{    btnActualSize.selected ? ResourceUtil.getInstance().getString('bbb.screenshareView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.screenshareView.actualSize')    }"/>
 </common:CustomMdiWindow>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml
index a116d2546140e111a6b5271c8e517f4b8cbea842..432a3b1bb33a7b921464a4c4c12f7d412e8bb76a 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesNameWindow.mxml
@@ -23,21 +23,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:TitleWindow xmlns:mx="library://ns.adobe.com/flex/mx"
 				xmlns:fx="http://ns.adobe.com/mxml/2009"
 				xmlns:mate="http://mate.asfusion.com/"
+				implements="org.bigbluebutton.common.IKeyboardClose"
 				verticalScrollPolicy="off"
 				horizontalScrollPolicy="off"
 				horizontalAlign="center"
-				close="onCancelClicked()"
 				layout="absolute"
 				creationComplete="onCreationComplete()"
 				keyUp="keyUpHandler(event)"
-				width="240" xmlns:common="org.bigbluebutton.common.*">
+				width="280" xmlns:common="org.bigbluebutton.common.*">
 
 	<fx:Script>
 		<![CDATA[
 			import com.asfusion.mate.events.Dispatcher;
-
+			
 			import mx.managers.PopUpManager;
-
+			
+			import org.bigbluebutton.common.IKeyboardClose;
 			import org.bigbluebutton.core.model.LiveMeeting;
 			import org.bigbluebutton.modules.sharednotes.events.SharedNotesEvent;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesWindow.mxml
index 0e5c1ac1653df60c5bf692417b8c2654bb8ce167..6de89f5dfa3b487e31892350cefd8567866a33f4 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/SharedNotesWindow.mxml
@@ -50,11 +50,9 @@
 			import mx.controls.Alert;
 			import mx.controls.Menu;
 			import mx.core.FlexGlobals;
-			import mx.core.IFlexDisplayObject;
 			import mx.events.CloseEvent;
 			import mx.events.FlexEvent;
 			import mx.events.MenuEvent;
-			import mx.managers.PopUpManager;
 			
 			import flashx.textLayout.formats.Direction;
 			
@@ -66,6 +64,7 @@
 			import org.bigbluebutton.common.Role;
 			import org.bigbluebutton.common.events.LocaleChangeEvent;
 			import org.bigbluebutton.core.Options;
+			import org.bigbluebutton.core.PopUpUtil;
 			import org.bigbluebutton.core.UsersUtil;
 			import org.bigbluebutton.core.model.LiveMeeting;
 			import org.bigbluebutton.main.events.ShortcutEvent;
@@ -479,8 +478,7 @@
 			}
 
 			protected function newNoteHandler():void {
-				var noteNameWindow:IFlexDisplayObject = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, SharedNotesNameWindow, true);
-				PopUpManager.centerPopUp(noteNameWindow);
+				PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, SharedNotesNameWindow, true);
 			}
 
 			protected function btnUndo_clickHandler(event:MouseEvent = null):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml
index 0062d520004bf22948b8c1aee5c5377920bab3a4..e3c45162dfada46ff5a4941ea3bb88d1fec161e4 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml
@@ -25,8 +25,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 xmlns:mx="library://ns.adobe.com/flex/mx"
                 xmlns:mate="http://mate.asfusion.com/"
                 xmlns:common="org.bigbluebutton.common.*"
+				implements="org.bigbluebutton.common.IKeyboardClose"
+				show="this.setFocus()"
                 width="630"
-                close="onCloseClicked()"
                 visible="false"
                 showCloseButton="false">
     
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
index 8cbb7d6d08bf5332f1d525cf98f4221c71500e61..1e68d2f5e3bd5beec31b22a6ca4dc0f9168200ed 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
@@ -23,6 +23,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
 				xmlns:s="library://ns.adobe.com/flex/spark"
 				xmlns:mx="library://ns.adobe.com/flex/mx"
+				implements="org.bigbluebutton.common.IKeyboardClose"
+				show="this.setFocus()"
 				close="onCloseClick()"
 				layout="absolute"
 				width="600" xmlns:common="org.bigbluebutton.common.*">
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
index 5dc475203f55b2e4389def224672708225658f5c..1992f62e615156a607c9cc234f34714f0e71cea9 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
@@ -375,7 +375,7 @@ $Id: $
       }
       
       private function openEmojiStatusMenu():void {
-        var moodMenu:MoodMenu = PopUpUtil.createNonModelPopUp(DisplayObject(FlexGlobals.topLevelApplication), MoodMenu, false) as MoodMenu;
+        var moodMenu:MoodMenu = PopUpUtil.createNonModalPopUp(DisplayObject(FlexGlobals.topLevelApplication), MoodMenu, false) as MoodMenu;
         moodMenu.btn = emojiStatusBtn;
         moodMenu.show();
       }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/model/VideoConfOptions.as b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/model/VideoConfOptions.as
index 2df9f2f81727875b30351f2dbbf11be2ab2c4dc4..9fd13901574f9a1d9a840e92c0177f4d167db926 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/model/VideoConfOptions.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/model/VideoConfOptions.as
@@ -18,7 +18,7 @@
  */
 package org.bigbluebutton.modules.videoconf.model {
 	import org.bigbluebutton.core.Options;
-	import org.bigbluebutton.main.api.JSAPI;
+	import org.bigbluebutton.util.browser.BrowserCheck;
 
 	public class VideoConfOptions extends Options {
 		public var uri:String = "rtmp://localhost/video";
@@ -58,10 +58,8 @@ package org.bigbluebutton.modules.videoconf.model {
 		}
 
 		override protected function handleExtraData():void {
-			var browserInfo:Array = JSAPI.getInstance().getBrowserInfo();
-
 			// If we are using Puffin browser
-			if (browserInfo[0] == "Puffin" && String(browserInfo[2]).substr(0, 3) < "4.6") {
+			if (BrowserCheck.isPuffinBelow46()) {
 				showButton = false;
 			}
 		}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/ToolbarPopupButton.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/ToolbarPopupButton.mxml
index bcfa0b19b9986c2e5dfa05bd93e524dc0d89089b..84b20d8289b0336cea6e7946a6b7d3b0ac36dfc8 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/ToolbarPopupButton.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/ToolbarPopupButton.mxml
@@ -42,25 +42,31 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	
 	<fx:Script>
 		<![CDATA[
-      import com.asfusion.mate.events.Dispatcher;
+			import com.asfusion.mate.events.Dispatcher;
+			
+			import mx.controls.Alert;
+			import mx.controls.Menu;
+			import mx.events.MenuEvent;
+			import mx.styles.IStyleManager2;
+			import mx.styles.StyleManager;
+			
+			import org.as3commons.logging.api.ILogger;
+			import org.as3commons.logging.api.getClassLogger;
+			import org.bigbluebutton.common.Media;
+			import org.bigbluebutton.core.events.LockControlEvent;
+			import org.bigbluebutton.core.model.LiveMeeting;
+			import org.bigbluebutton.main.events.BBBEvent;
+			import org.bigbluebutton.main.events.ShortcutEvent;
+			import org.bigbluebutton.main.model.users.events.ChangeMyRole;
+			import org.bigbluebutton.main.views.MainToolbar;
+			import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
+			import org.bigbluebutton.modules.videoconf.events.StopShareCameraRequestEvent;
+			import org.bigbluebutton.util.browser.BrowserCheck;
+			import org.bigbluebutton.util.i18n.ResourceUtil;
+			
+			
       
-      import mx.controls.Menu;
-      import mx.events.MenuEvent;
-      import mx.styles.IStyleManager2;
-      import mx.styles.StyleManager;
       
-      import org.as3commons.logging.api.ILogger;
-      import org.as3commons.logging.api.getClassLogger;
-      import org.bigbluebutton.common.Media;
-      import org.bigbluebutton.core.events.LockControlEvent;
-      import org.bigbluebutton.core.model.LiveMeeting;
-      import org.bigbluebutton.main.events.BBBEvent;
-      import org.bigbluebutton.main.events.ShortcutEvent;
-      import org.bigbluebutton.main.model.users.events.ChangeMyRole;
-      import org.bigbluebutton.main.views.MainToolbar;
-      import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
-      import org.bigbluebutton.modules.videoconf.events.StopShareCameraRequestEvent;
-      import org.bigbluebutton.util.i18n.ResourceUtil;
 
 			private static const LOGGER:ILogger = getClassLogger(ToolbarPopupButton);      
 
@@ -177,6 +183,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 
 			private function openPublishWindow():void{
+				if (!BrowserCheck.isHttps() && ((BrowserCheck.isChrome() && BrowserCheck.browserMajorVersion >= "60") || (BrowserCheck.isOpera() && BrowserCheck.browserMajorVersion >= "47"))) {
+					Alert.show(ResourceUtil.getInstance().getString("bbb.video.message.browserhttp", [BrowserCheck.browserName]));
+					return;
+				}
 				this.enabled = false;
 				if(_currentState == ON_STATE) {
 					LOGGER.debug("[ToolbarPopupButton:openPublishWindow] Close window");
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserAvatar.as b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserAvatar.as
old mode 100644
new mode 100755
index 65a6aa23e324cbbbfc01f5aa636af0956b5796b1..e86c44b7f65974eb33952ec426732b1a89628cde
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserAvatar.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserAvatar.as
@@ -3,6 +3,8 @@ package org.bigbluebutton.modules.videoconf.views
     import flash.display.Loader;
     import flash.events.Event;
     import flash.net.URLRequest;
+    
+    import mx.core.UIComponent;
 
     public class UserAvatar extends UserGraphic {
 
@@ -18,14 +20,17 @@ package org.bigbluebutton.modules.videoconf.views
           _completed = false;
 
           _imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadingComplete);
-          addChild(_imageLoader);
+          
           var request:URLRequest = new URLRequest(avatarUrl);
           _imageLoader.load(request);
       }
 
       private function onLoadingComplete(event:Event):void {
           _completed = true;
+          addChild(_imageLoader);
           setOriginalDimensions(_imageLoader.width, _imageLoader.height);
+          if (parent && parent is UIComponent) 
+            UIComponent(parent).invalidateDisplayList();
       }
 
       override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserGraphic.as b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserGraphic.as
index 494db394b799329f8bd7a514ff8b8884fdd56404..f81e95db79a0ca3eeb6fd1ab26882983c2aefa88 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserGraphic.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/views/UserGraphic.as
@@ -62,12 +62,12 @@ package org.bigbluebutton.modules.videoconf.views
                 object_height = unscaledHeight;
                 object_width = Math.ceil(unscaledHeight * aspectRatio);
                 object_y = BORDER_THICKNESS;
-                object_x = Math.floor((unscaledWidth - object.width) / 2);
+                object_x = Math.floor((unscaledWidth - object_width) / 2);
             } else {
                 object_width = unscaledWidth;
                 object_height = Math.ceil(unscaledWidth / aspectRatio);
                 object_x = BORDER_THICKNESS;
-                object_y = Math.floor((unscaledHeight - object.height) / 2);
+                object_y = Math.floor((unscaledHeight - object_height) / 2);
             }
 
             object.x = object_x;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as
index bd3f9dc173d8e301e4b1362eaedceb8b1aa0af4d..153d0ee7386098b400caa965c9670a10fc7862fe 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as
@@ -76,6 +76,7 @@ package org.bigbluebutton.modules.whiteboard.views {
 			whiteboardToolbar.whiteboardAccessModified(wbModel.multiUser);
 			
 			this.clipContent = true;
+			this.mouseEnabled = false;
 			
 			//create the annotation display container
 			this.addChild(graphicObjectHolder);
@@ -119,12 +120,14 @@ package org.bigbluebutton.modules.whiteboard.views {
 			addEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
 			addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
 			addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
+			mouseEnabled = true;
 		}
 		
 		private function unregisterForMouseEvents():void {
 			removeEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
 			removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
 			removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
+			mouseEnabled = false;
 		}
 		
 		private function doMouseUp(event:MouseEvent):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/util/browser/BrowserCheck.as b/bigbluebutton-client/src/org/bigbluebutton/util/browser/BrowserCheck.as
new file mode 100755
index 0000000000000000000000000000000000000000..7325903ba6866114d6a67a49aa4ba7fdec21a3f7
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/util/browser/BrowserCheck.as
@@ -0,0 +1,95 @@
+/**
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ *
+ * Copyright (c) 2016 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ *
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package org.bigbluebutton.util.browser {
+	import flash.external.ExternalInterface;
+
+	import org.as3commons.lang.StringUtils;
+	import org.as3commons.logging.api.ILogger;
+	import org.as3commons.logging.api.getClassLogger;
+
+	public class BrowserCheck {
+		private static const LOGGER:ILogger = getClassLogger(BrowserCheck);
+
+		private static var _browserName:String;
+
+		private static var _majorVersion:String;
+
+		private static var _fullVersion:String;
+
+		// The function below is called in $cinit, while the class is used for the first time.
+		getBrowserInfo();
+
+		public static function isWebRTCSupported():Boolean {
+			/*LOGGER.debug("isWebRTCSupported - ExternalInterface.available=[{0}], isWebRTCAvailable=[{1}]", [ExternalInterface.available, ExternalInterface.call("isWebRTCAvailable")]);*/
+			return (ExternalInterface.available && ExternalInterface.call("isWebRTCAvailable"));
+		}
+
+		public static function get browserName():String {
+			return _browserName;
+		}
+
+		public static function get browserMajorVersion():String {
+			return _majorVersion;
+		}
+
+		public static function get browserFullVersion():String {
+			return _fullVersion;
+		}
+
+		public static function isChrome():Boolean {
+			return _browserName.toLowerCase() == "chrome";
+		}
+
+		public static function isOpera():Boolean {
+			return _browserName.toLowerCase() == "opera";
+		}
+
+		public static function isFirefox():Boolean {
+			return _browserName.toLowerCase() == "firefox";
+		}
+
+		public static function isPuffinBelow46():Boolean {
+			return _browserName.toLowerCase() == "puffin" && String(_fullVersion).substr(0, 3) < "4.6";
+		}
+
+		public static function isPuffin46AndAbove():Boolean {
+			return browserName.toLowerCase() == "puffin" && String(_fullVersion).substr(0, 3) >= "4.6";
+		}
+
+		private static function getBrowserInfo():void {
+			if (ExternalInterface.available && StringUtils.isEmpty(browserName)) {
+				var browserInfo:Array = ExternalInterface.call("determineBrowser");
+				_browserName = browserInfo[0];
+				_majorVersion = String(browserInfo[1]);
+				_fullVersion = String(browserInfo[2]);
+			} else {
+				_browserName = "unknown";
+				_majorVersion = "0";
+				_fullVersion = "0";
+			}
+		}
+
+		public static function isHttps():Boolean {
+			var url:String = ExternalInterface.call("window.location.href.toString");
+			var httpsPattern:RegExp = /^https/;
+			return httpsPattern.test(url);
+		}
+	}
+}
diff --git a/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js b/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js
index ac1c2fc6133d5577d4156fe392ad8d4df1716143..ba11154b81ad76f6dc10b4fb6d1bed4434a56592 100644
--- a/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js
+++ b/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js
@@ -357,15 +357,15 @@ export default function addAnnotation(meetingId, whiteboardId, userId, annotatio
 
   const cb = (err, numChanged) => {
     if (err) {
-      return Logger.error(`Adding annotation2x to collection: ${err}`);
+      return Logger.error(`Adding annotation to collection: ${err}`);
     }
 
     const { insertedId } = numChanged;
     if (insertedId) {
-      return Logger.info(`Added annotation2x id=${annotation.id} whiteboard=${whiteboardId}`);
+      return Logger.info(`Added annotation id=${annotation.id} whiteboard=${whiteboardId}`);
     }
 
-    return Logger.info(`Upserted annotation2x id=${annotation.id} whiteboard=${whiteboardId}`);
+    return Logger.info(`Upserted annotation id=${annotation.id} whiteboard=${whiteboardId}`);
   };
 
   return Annotations.upsert(query.selector, query.modifier, cb);
diff --git a/bigbluebutton-html5/imports/api/annotations/server/modifiers/clearAnnotations.js b/bigbluebutton-html5/imports/api/annotations/server/modifiers/clearAnnotations.js
index 8873ca47ca8f4f9f13b4cdce852cbcafb4a2f96d..c543326780c7a7a8a4fb78ec23a629e87c2b27d6 100644
--- a/bigbluebutton-html5/imports/api/annotations/server/modifiers/clearAnnotations.js
+++ b/bigbluebutton-html5/imports/api/annotations/server/modifiers/clearAnnotations.js
@@ -18,7 +18,7 @@ export default function clearAnnotations(meetingId, whiteboardId, userId) {
 
   const cb = (err) => {
     if (err) {
-      return Logger.error(`Removing Shapes2x from collection: ${err}`);
+      return Logger.error(`Removing Annotations from collection: ${err}`);
     }
 
     if (!meetingId) {
@@ -26,10 +26,10 @@ export default function clearAnnotations(meetingId, whiteboardId, userId) {
     }
 
     if (userId) {
-      return Logger.info(`Removed Shapes2x for userId=${userId} where whiteboard=${whiteboardId}`);
+      return Logger.info(`Removed Annotations for userId=${userId} where whiteboard=${whiteboardId}`);
     }
 
-    return Logger.info(`Removed Shapes2x where whiteboard=${whiteboardId}`);
+    return Logger.info(`Removed Annotations where whiteboard=${whiteboardId}`);
   };
 
   return Annotations.remove(selector, cb);
diff --git a/bigbluebutton-html5/imports/api/annotations/server/publishers.js b/bigbluebutton-html5/imports/api/annotations/server/publishers.js
index 06d085e5983bbe6c33592892c0da7bdd6542bae7..e682fcb49c91696e91e0b6c0bf5600b8af7e7c52 100644
--- a/bigbluebutton-html5/imports/api/annotations/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/annotations/server/publishers.js
@@ -11,7 +11,7 @@ function annotations(credentials) {
   check(requesterUserId, String);
   check(requesterToken, String);
 
-  Logger.info(`Publishing Annotations2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.info(`Publishing Annotations for ${meetingId} ${requesterUserId} ${requesterToken}`);
 
   return Annotations.find({ meetingId });
 }
diff --git a/bigbluebutton-html5/imports/api/breakouts/index.js b/bigbluebutton-html5/imports/api/breakouts/index.js
index 09388c9cc001a97d82ec127f88b851c4171ef9a6..41c6ed54e407cd6ee5d1090a9554feb6fd75af35 100644
--- a/bigbluebutton-html5/imports/api/breakouts/index.js
+++ b/bigbluebutton-html5/imports/api/breakouts/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Breakouts = new Mongo.Collection('breakouts2x');
+const Breakouts = new Mongo.Collection('breakouts');
 
 if (Meteor.isServer) {
   // types of queries for the breakouts:
diff --git a/bigbluebutton-html5/imports/api/breakouts/server/publishers.js b/bigbluebutton-html5/imports/api/breakouts/server/publishers.js
index 6efb01dd1f5d9525d67e8534bd70ea42958f47bb..f61d464c0ccc784de5cc3e1481251beed5b3bd8f 100644
--- a/bigbluebutton-html5/imports/api/breakouts/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/breakouts/server/publishers.js
@@ -9,7 +9,7 @@ function breakouts(credentials) {
     requesterUserId,
   } = credentials;
 
-  Logger.info(`Publishing Breakouts2x for ${meetingId} ${requesterUserId}`);
+  Logger.info(`Publishing Breakouts for ${meetingId} ${requesterUserId}`);
 
   return Breakouts.find({
     $or: [
@@ -29,4 +29,4 @@ function publish(...args) {
   return mapToAcl('subscriptions.breakouts', boundBreakouts)(args);
 }
 
-Meteor.publish('breakouts2x', publish);
+Meteor.publish('breakouts', publish);
diff --git a/bigbluebutton-html5/imports/api/captions/index.js b/bigbluebutton-html5/imports/api/captions/index.js
index 657d998ccf44b9776822ba8555e6ecd0e58397c2..b5d076f34bf1e8fd7b25201f9187004f743f379e 100644
--- a/bigbluebutton-html5/imports/api/captions/index.js
+++ b/bigbluebutton-html5/imports/api/captions/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Captions = new Mongo.Collection('captions2x');
+const Captions = new Mongo.Collection('captions');
 
 if (Meteor.isServer) {
   // types of queries for the captions:
diff --git a/bigbluebutton-html5/imports/api/captions/server/modifiers/addCaption.js b/bigbluebutton-html5/imports/api/captions/server/modifiers/addCaption.js
index 3b69f980230ec36f9035e8c69e43b052834deda7..c9642a93ee95cee3effbdc00ec9697ca20567881 100644
--- a/bigbluebutton-html5/imports/api/captions/server/modifiers/addCaption.js
+++ b/bigbluebutton-html5/imports/api/captions/server/modifiers/addCaption.js
@@ -37,15 +37,15 @@ export default function addCaption(meetingId, locale, captionHistory, id = false
 
   const cb = (err, numChanged) => {
     if (err) {
-      return Logger.error(`Adding caption2x to collection: ${err}`);
+      return Logger.error(`Adding caption to collection: ${err}`);
     }
 
     const { insertedId } = numChanged;
     if (insertedId) {
-      return Logger.verbose(`Added caption2x locale=${locale} meeting=${meetingId}`);
+      return Logger.verbose(`Added caption locale=${locale} meeting=${meetingId}`);
     }
 
-    return Logger.verbose(`Upserted caption2x locale=${locale} meeting=${meetingId}`);
+    return Logger.verbose(`Upserted caption locale=${locale} meeting=${meetingId}`);
   };
 
   return Captions.upsert(selector, modifier, cb);
diff --git a/bigbluebutton-html5/imports/api/captions/server/modifiers/clearCaptions.js b/bigbluebutton-html5/imports/api/captions/server/modifiers/clearCaptions.js
index 4e492c86b057542541ca6b3e4776335ad506620c..9d10d369cd3ff37cef465f99832ee8299eee3df6 100644
--- a/bigbluebutton-html5/imports/api/captions/server/modifiers/clearCaptions.js
+++ b/bigbluebutton-html5/imports/api/captions/server/modifiers/clearCaptions.js
@@ -3,8 +3,8 @@ import Logger from '/imports/startup/server/logger';
 
 export default function clearCaptions(meetingId) {
   if (meetingId) {
-    return Captions.remove({ meetingId }, Logger.info(`Cleared Captions2x (${meetingId})`));
+    return Captions.remove({ meetingId }, Logger.info(`Cleared Captions (${meetingId})`));
   }
 
-  return Captions.remove({}, Logger.info('Cleared Captions2x (all)'));
+  return Captions.remove({}, Logger.info('Cleared Captions (all)'));
 }
diff --git a/bigbluebutton-html5/imports/api/captions/server/publishers.js b/bigbluebutton-html5/imports/api/captions/server/publishers.js
index 987ce08597517a3efad02a7698fa0febfee20c34..869949618a90956baae7a0f4db38d59b43f2befc 100644
--- a/bigbluebutton-html5/imports/api/captions/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/captions/server/publishers.js
@@ -11,7 +11,7 @@ function captions(credentials) {
   check(requesterUserId, String);
   check(requesterToken, String);
 
-  Logger.verbose(`Publishing Captions2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.verbose(`Publishing Captions for ${meetingId} ${requesterUserId} ${requesterToken}`);
 
   return Captions.find({ meetingId });
 }
@@ -21,4 +21,4 @@ function publish(...args) {
   return mapToAcl('subscriptions.captions', boundCaptions)(args);
 }
 
-Meteor.publish('captions2x', publish);
+Meteor.publish('captions', publish);
diff --git a/bigbluebutton-html5/imports/api/chat/index.js b/bigbluebutton-html5/imports/api/chat/index.js
index 5338ef2f36650d2321e5416021d2171957ac54a8..a28361d05c70d390b43ae25f3e904ef8e09c241d 100644
--- a/bigbluebutton-html5/imports/api/chat/index.js
+++ b/bigbluebutton-html5/imports/api/chat/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Chat = new Mongo.Collection('chat2x');
+const Chat = new Mongo.Collection('chat');
 
 if (Meteor.isServer) {
   // types of queries for the chat:
diff --git a/bigbluebutton-html5/imports/api/chat/server/publishers.js b/bigbluebutton-html5/imports/api/chat/server/publishers.js
index a5d58a409c6326a2dcd7eae8af6dfd25d52f9fbf..752e9da7271ef8911ec23cbe9f97b1946be1207d 100644
--- a/bigbluebutton-html5/imports/api/chat/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/chat/server/publishers.js
@@ -37,4 +37,4 @@ function publish(...args) {
   return mapToAcl('subscriptions.chat', boundChat)(args);
 }
 
-Meteor.publish('chat2x', publish);
+Meteor.publish('chat', publish);
diff --git a/bigbluebutton-html5/imports/api/cursor/index.js b/bigbluebutton-html5/imports/api/cursor/index.js
index e023b336bd6e4c7cda74ca76587bf7be26be5dc2..b058fa39db50b38c392ca22cb614defc2533fdae 100644
--- a/bigbluebutton-html5/imports/api/cursor/index.js
+++ b/bigbluebutton-html5/imports/api/cursor/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Cursor = new Mongo.Collection('cursor2x');
+const Cursor = new Mongo.Collection('cursor');
 
 if (Meteor.isServer) {
   // types of queries for the cursor:
diff --git a/bigbluebutton-html5/imports/api/cursor/server/publishers.js b/bigbluebutton-html5/imports/api/cursor/server/publishers.js
index 7710e006040d456b9b8a7028991df51eae391d7b..dc693e60bac8c3cc84a90521d6fcd967c3aa6cec 100644
--- a/bigbluebutton-html5/imports/api/cursor/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/cursor/server/publishers.js
@@ -12,7 +12,7 @@ function cursor(credentials) {
   check(requesterUserId, String);
   check(requesterToken, String);
 
-  Logger.debug(`Publishing Cursor2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.debug(`Publishing Cursor for ${meetingId} ${requesterUserId} ${requesterToken}`);
 
   return Cursor.find({ meetingId });
 }
@@ -22,5 +22,5 @@ function publish(...args) {
   return mapToAcl('subscriptions.cursor', boundCursor)(args);
 }
 
-Meteor.publish('cursor2x', publish);
+Meteor.publish('cursor', publish);
 
diff --git a/bigbluebutton-html5/imports/api/meetings/index.js b/bigbluebutton-html5/imports/api/meetings/index.js
index ce719639feb8d41af22a508f26424b7049a23e49..1324a4a61fd7e41b1fe1e7ccc7b2498de455ec7c 100644
--- a/bigbluebutton-html5/imports/api/meetings/index.js
+++ b/bigbluebutton-html5/imports/api/meetings/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Meetings = new Mongo.Collection('meetings2x');
+const Meetings = new Mongo.Collection('meetings');
 
 if (Meteor.isServer) {
   // types of queries for the meetings:
diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js
index 8a6e28e6df155621d1abb00e7e59de0ea5568870..d18c31243958ec2e3c5d5f4b991f3e1a5ce578c1 100644
--- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js
+++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js
@@ -79,11 +79,11 @@ export default function addMeeting(meeting) {
 
     const { insertedId } = numChanged;
     if (insertedId) {
-      Logger.info(`Added meeting2x id=${meetingId}`);
+      Logger.info(`Added meeting id=${meetingId}`);
     }
 
     if (numChanged) {
-      Logger.info(`Upserted meeting2x id=${meetingId}`);
+      Logger.info(`Upserted meeting id=${meetingId}`);
     }
   };
 
diff --git a/bigbluebutton-html5/imports/api/meetings/server/publishers.js b/bigbluebutton-html5/imports/api/meetings/server/publishers.js
index c3cc4d404481cba26f1ba3eb8ccb2a88d02d85b7..df5b44f8dfc206f2c4ca1f0fc14287b5c7998ffc 100644
--- a/bigbluebutton-html5/imports/api/meetings/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/meetings/server/publishers.js
@@ -11,7 +11,7 @@ function meetings(credentials) {
   check(requesterUserId, String);
   check(requesterToken, String);
 
-  Logger.info(`Publishing meeting2x =${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.info(`Publishing meeting =${meetingId} ${requesterUserId} ${requesterToken}`);
 
   return Meetings.find({
     meetingId,
@@ -23,5 +23,5 @@ function publish(...args) {
   return mapToAcl('subscriptions.meetings', boundMeetings)(args);
 }
 
-Meteor.publish('meetings2x', publish);
+Meteor.publish('meetings', publish);
 
diff --git a/bigbluebutton-html5/imports/api/polls/index.js b/bigbluebutton-html5/imports/api/polls/index.js
index 1bb2c01a955c2035c9166a94e4e1b1f55023f755..da84a1e41714dc94c870673a96e34230854b7d90 100644
--- a/bigbluebutton-html5/imports/api/polls/index.js
+++ b/bigbluebutton-html5/imports/api/polls/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Polls = new Mongo.Collection('polls2x');
+const Polls = new Mongo.Collection('polls');
 
 if (Meteor.isServer) {
   // We can have just one active poll per meeting
diff --git a/bigbluebutton-html5/imports/api/polls/server/methods/publishVote.js b/bigbluebutton-html5/imports/api/polls/server/methods/publishVote.js
index 192c80af2ce883d6e54e39549b102e3286e69fb2..bc59d38e06d85cadeb75388256af9206beb725c2 100644
--- a/bigbluebutton-html5/imports/api/polls/server/methods/publishVote.js
+++ b/bigbluebutton-html5/imports/api/polls/server/methods/publishVote.js
@@ -43,10 +43,10 @@ export default function publishVote(credentials, id, pollAnswerId) { // TODO dis
 
   const cb = (err) => {
     if (err) {
-      return Logger.error(`Updating Polls2x collection: ${err}`);
+      return Logger.error(`Updating Polls collection: ${err}`);
     }
 
-    return Logger.info(`Updating Polls2x collection (meetingId: ${meetingId},
+    return Logger.info(`Updating Polls collection (meetingId: ${meetingId},
                                             pollId: ${currentPoll.id}!)`);
   };
 
diff --git a/bigbluebutton-html5/imports/api/polls/server/modifiers/addPoll.js b/bigbluebutton-html5/imports/api/polls/server/modifiers/addPoll.js
index 703a9a07fbe2a289dd63de9372275c8b3c3b4824..40fa737ef17f702511ccb4569333320c42ec0116 100644
--- a/bigbluebutton-html5/imports/api/polls/server/modifiers/addPoll.js
+++ b/bigbluebutton-html5/imports/api/polls/server/modifiers/addPoll.js
@@ -48,15 +48,15 @@ export default function addPoll(meetingId, requesterId, poll) {
 
   const cb = (err, numChanged) => {
     if (err != null) {
-      return Logger.error(`Adding Poll2x to collection: ${poll.id}`);
+      return Logger.error(`Adding Poll to collection: ${poll.id}`);
     }
 
     const { insertedId } = numChanged;
     if (insertedId) {
-      return Logger.info(`Added Poll2x id=${poll.id}`);
+      return Logger.info(`Added Poll id=${poll.id}`);
     }
 
-    return Logger.info(`Upserted Poll2x id=${poll.id}`);
+    return Logger.info(`Upserted Poll id=${poll.id}`);
   };
 
   return Polls.upsert(selector, modifier, cb);
diff --git a/bigbluebutton-html5/imports/api/polls/server/modifiers/clearPolls.js b/bigbluebutton-html5/imports/api/polls/server/modifiers/clearPolls.js
index 8461cf46b24318003c79912d67292721d12eee68..d614528ebf32449b050282a3aeca4348984c9d37 100644
--- a/bigbluebutton-html5/imports/api/polls/server/modifiers/clearPolls.js
+++ b/bigbluebutton-html5/imports/api/polls/server/modifiers/clearPolls.js
@@ -3,8 +3,8 @@ import Logger from '/imports/startup/server/logger';
 
 export default function clearPolls(meetingId) {
   if (meetingId) {
-    return Polls.remove({ meetingId }, Logger.info(`Cleared Polls2x (${meetingId})`));
+    return Polls.remove({ meetingId }, Logger.info(`Cleared Polls (${meetingId})`));
   }
 
-  return Polls.remove({}, Logger.info('Cleared Polls2x (all)'));
+  return Polls.remove({}, Logger.info('Cleared Polls (all)'));
 }
diff --git a/bigbluebutton-html5/imports/api/polls/server/modifiers/removePoll.js b/bigbluebutton-html5/imports/api/polls/server/modifiers/removePoll.js
index 92d4e5d06defd0f7164ec6d6d4b309f48e36cc46..6d59f73cbde6cde7b0a61442b86eb5b3584c9441 100644
--- a/bigbluebutton-html5/imports/api/polls/server/modifiers/removePoll.js
+++ b/bigbluebutton-html5/imports/api/polls/server/modifiers/removePoll.js
@@ -13,10 +13,10 @@ export default function removePoll(meetingId, id) {
 
   const cb = (err) => {
     if (err) {
-      return Logger.error(`Removing Poll2x from collection: ${err}`);
+      return Logger.error(`Removing Poll from collection: ${err}`);
     }
 
-    return Logger.info(`Removed Poll2x id=${id}`);
+    return Logger.info(`Removed Poll id=${id}`);
   };
 
   return Polls.remove(selector, cb);
diff --git a/bigbluebutton-html5/imports/api/polls/server/modifiers/updateVotes.js b/bigbluebutton-html5/imports/api/polls/server/modifiers/updateVotes.js
index c8b79259a0f19890778902a46d062c65a92672de..3cb37bd1dab58047d9bb316397a9b1f089adaac0 100644
--- a/bigbluebutton-html5/imports/api/polls/server/modifiers/updateVotes.js
+++ b/bigbluebutton-html5/imports/api/polls/server/modifiers/updateVotes.js
@@ -37,10 +37,10 @@ export default function updateVotes(poll, meetingId, requesterId) {
 
   const cb = (err) => {
     if (err) {
-      return Logger.error(`Updating Polls2x collection: ${err}`);
+      return Logger.error(`Updating Polls collection: ${err}`);
     }
 
-    return Logger.info(`Updating Polls2x collection (meetingId: ${meetingId}, pollId: ${id}!)`);
+    return Logger.info(`Updating Polls collection (meetingId: ${meetingId}, pollId: ${id}!)`);
   };
 
   return Polls.update(selector, modifier, cb);
diff --git a/bigbluebutton-html5/imports/api/polls/server/publishers.js b/bigbluebutton-html5/imports/api/polls/server/publishers.js
index d1f9bd215206a929cc47296e8142fad8ea48995c..15e9815a5c1678d14627036555f70fe584b4406c 100644
--- a/bigbluebutton-html5/imports/api/polls/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/polls/server/publishers.js
@@ -11,7 +11,7 @@ function polls(credentials) {
   check(requesterUserId, String);
   check(requesterToken, String);
 
-  Logger.info(`Publishing polls2x =${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.info(`Publishing polls =${meetingId} ${requesterUserId} ${requesterToken}`);
 
   const selector = {
     meetingId,
@@ -26,5 +26,5 @@ function publish(...args) {
   return mapToAcl('subscriptions.polls', boundPolls)(args);
 }
 
-Meteor.publish('polls2x', publish);
+Meteor.publish('polls', publish);
 
diff --git a/bigbluebutton-html5/imports/api/presentations/index.js b/bigbluebutton-html5/imports/api/presentations/index.js
index adcc4305c5b6f5ecbca61947ea085e6cd8178a63..e0df4849a02a1ac8b3216832f82c582c4219694e 100644
--- a/bigbluebutton-html5/imports/api/presentations/index.js
+++ b/bigbluebutton-html5/imports/api/presentations/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Presentations = new Mongo.Collection('presentations2x');
+const Presentations = new Mongo.Collection('presentations');
 
 if (Meteor.isServer) {
   // types of queries for the presentations:
diff --git a/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationConversionUpdate.js b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationConversionUpdate.js
index 809660d99b22cd8dd655e69208b64b7c43b82a64..a8c192261342d621083d34ba86fed75dd7b520c4 100644
--- a/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationConversionUpdate.js
+++ b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationConversionUpdate.js
@@ -71,15 +71,15 @@ export default function handlePresentationConversionUpdate({ body }, meetingId)
 
   const cb = (err, numChanged) => {
     if (err) {
-      return Logger.error(`Updating conversion status presentation2x to collection: ${err}`);
+      return Logger.error(`Updating conversion status presentation to collection: ${err}`);
     }
 
     const { insertedId } = numChanged;
     if (insertedId) {
-      return Logger.info(`Updated presentation2x conversion status=${status} id=${presentationId} meeting=${meetingId}`);
+      return Logger.info(`Updated presentation conversion status=${status} id=${presentationId} meeting=${meetingId}`);
     }
 
-    return Logger.info(`Upserted presentation2x conversion status=${status} id=${presentationId} meeting=${meetingId}`);
+    return Logger.info(`Upserted presentation conversion status=${status} id=${presentationId} meeting=${meetingId}`);
   };
 
   return Presentations.upsert(selector, modifier, cb);
diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js
index fe9282148717cf23c6457ec9508e220687a09e46..db07ede3a8196bbdc9b27819e6f42a5b029275a3 100644
--- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js
+++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js
@@ -54,7 +54,7 @@ export default function addPresentation(meetingId, presentation) {
 
   const cb = (err, numChanged) => {
     if (err) {
-      return Logger.error(`Adding presentation2x to collection: ${err}`);
+      return Logger.error(`Adding presentation to collection: ${err}`);
     }
 
     addSlides(meetingId, presentation.id, presentation.pages);
@@ -65,10 +65,10 @@ export default function addPresentation(meetingId, presentation) {
         setCurrentPresentation(meetingId, presentation.id);
       }
 
-      return Logger.info(`Added presentation2x id=${presentation.id} meeting=${meetingId}`);
+      return Logger.info(`Added presentation id=${presentation.id} meeting=${meetingId}`);
     }
 
-    return Logger.info(`Upserted presentation2x id=${presentation.id} meeting=${meetingId}`);
+    return Logger.info(`Upserted presentation id=${presentation.id} meeting=${meetingId}`);
   };
 
   return Presentations.upsert(selector, modifier, cb);
diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js
index b92072dc395b04f03907b04b8aca425439ca8a7f..2d084f2b7bad4eeb7109936f167aaeabeae9b2a1 100644
--- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js
+++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js
@@ -4,7 +4,7 @@ import Logger from '/imports/startup/server/logger';
 export default function clearPresentations(meetingId) {
   if (meetingId) {
     return Presentations.remove({ meetingId },
-      Logger.info(`Cleared Presentations2x (${meetingId})`));
+      Logger.info(`Cleared Presentations (${meetingId})`));
   }
   return Presentations.remove({}, Logger.info('Cleared Presentations (all)'));
 }
diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/setCurrentPresentation.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/setCurrentPresentation.js
index d67aaf6e22931b5cd672292bb2a26e417ea25349..3343376422d350e443f6fe4196777b607e1d64a6 100644
--- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/setCurrentPresentation.js
+++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/setCurrentPresentation.js
@@ -33,10 +33,10 @@ export default function setCurrentPresentation(meetingId, presentationId) {
     },
     callback: (err) => {
       if (err) {
-        return Logger.error(`Setting as current presentation2x id=${presentationId}: ${err}`);
+        return Logger.error(`Setting as current presentation id=${presentationId}: ${err}`);
       }
 
-      return Logger.info(`Setted as current presentation2x id=${presentationId}`);
+      return Logger.info(`Setted as current presentation id=${presentationId}`);
     },
   };
 
diff --git a/bigbluebutton-html5/imports/api/presentations/server/publishers.js b/bigbluebutton-html5/imports/api/presentations/server/publishers.js
index 23186c5ee34369d7b824b88dd60612c0f8ece35f..4d070b9c837ac02c6bb115c78a9ce101869cb89c 100644
--- a/bigbluebutton-html5/imports/api/presentations/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/presentations/server/publishers.js
@@ -11,7 +11,7 @@ function presentations(credentials) {
   check(requesterUserId, String);
   check(requesterToken, String);
 
-  Logger.info(`Publishing Presentations2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.info(`Publishing Presentations for ${meetingId} ${requesterUserId} ${requesterToken}`);
 
   return Presentations.find({ meetingId });
 }
@@ -21,4 +21,4 @@ function publish(...args) {
   return mapToAcl('subscriptions.presentations', boundPresentations)(args);
 }
 
-Meteor.publish('presentations2x', publish);
+Meteor.publish('presentations', publish);
diff --git a/bigbluebutton-html5/imports/api/slides/index.js b/bigbluebutton-html5/imports/api/slides/index.js
index 7831569b538ad980ee2843959160dfb24189efeb..8ee878085f9b22f14efe4b6f099e5c5a82f26bae 100644
--- a/bigbluebutton-html5/imports/api/slides/index.js
+++ b/bigbluebutton-html5/imports/api/slides/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Slides = new Mongo.Collection('slides2x');
+const Slides = new Mongo.Collection('slides');
 
 if (Meteor.isServer) {
   // types of queries for the slides:
diff --git a/bigbluebutton-html5/imports/api/slides/server/publishers.js b/bigbluebutton-html5/imports/api/slides/server/publishers.js
index 6c6054e1448b951f27fba5580d1ee5802623c94e..f517b7538225e08ea8a58d5933e29a1372726ae2 100644
--- a/bigbluebutton-html5/imports/api/slides/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/slides/server/publishers.js
@@ -21,4 +21,4 @@ function publish(...args) {
   return mapToAcl('subscriptions.slides', boundSlides)(args);
 }
 
-Meteor.publish('slides2x', publish);
+Meteor.publish('slides', publish);
diff --git a/bigbluebutton-html5/imports/api/users/index.js b/bigbluebutton-html5/imports/api/users/index.js
index 62f1d206fc5b90e297ba3e615b187453551f849a..6f7e08d42626fcf2722d9846bf8e3b9ca900c6ca 100644
--- a/bigbluebutton-html5/imports/api/users/index.js
+++ b/bigbluebutton-html5/imports/api/users/index.js
@@ -1,6 +1,6 @@
 import { Meteor } from 'meteor/meteor';
 
-const Users = new Mongo.Collection('users2x');
+const Users = new Mongo.Collection('users');
 
 if (Meteor.isServer) {
   // types of queries for the users:
diff --git a/bigbluebutton-html5/imports/api/users/server/methods.js b/bigbluebutton-html5/imports/api/users/server/methods.js
index 0e41df246ffcdcc01015766fd143544d716b064b..4aa61b73a820007222945324e240caf0e0303291 100644
--- a/bigbluebutton-html5/imports/api/users/server/methods.js
+++ b/bigbluebutton-html5/imports/api/users/server/methods.js
@@ -16,4 +16,4 @@ Meteor.methods(mapToAcl(['methods.userLogout', 'methods.setEmojiStatus', 'method
     kickUser,
   }));
 
-Meteor.methods({ validateAuthToken2x: validateAuthToken });
+Meteor.methods({ validateAuthToken, });
diff --git a/bigbluebutton-html5/imports/api/users/server/methods/validateAuthToken.js b/bigbluebutton-html5/imports/api/users/server/methods/validateAuthToken.js
index 257cc16c336c18f1bb73effe350dc5242e275778..b1b3ed4adff593a57029a8845ddc603b6cc70fa3 100644
--- a/bigbluebutton-html5/imports/api/users/server/methods/validateAuthToken.js
+++ b/bigbluebutton-html5/imports/api/users/server/methods/validateAuthToken.js
@@ -3,7 +3,7 @@ import { check } from 'meteor/check';
 import RedisPubSub from '/imports/startup/server/redis';
 import Logger from '/imports/startup/server/logger';
 import Users from '/imports/api/users';
-import createDummyUser2x from '../modifiers/createDummyUser';
+import createDummyUser from '../modifiers/createDummyUser';
 import setConnectionStatus from '../modifiers/setConnectionStatus';
 
 const ONLINE_CONNECTION_STATUS = 'online';
@@ -25,7 +25,7 @@ export default function validateAuthToken(credentials) {
   });
 
   if (!User) {
-    createDummyUser2x(meetingId, requesterUserId, requesterToken);
+    createDummyUser(meetingId, requesterUserId, requesterToken);
   } else if (User.validated) {
     setConnectionStatus(meetingId, requesterUserId, ONLINE_CONNECTION_STATUS);
   }
diff --git a/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js b/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js
index c3fe5b94976ddc90a47046a3518db942a6fcf2b1..a292b1bf077b8924906ee02d5a2a9cd0fbde7ca7 100644
--- a/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js
+++ b/bigbluebutton-html5/imports/api/users/server/modifiers/createDummyUser.js
@@ -3,7 +3,7 @@ import { check } from 'meteor/check';
 import Logger from '/imports/startup/server/logger';
 import Users from '/imports/api/users';
 
-export default function createDummyUser2x(meetingId, userId, authToken) {
+export default function createDummyUser(meetingId, userId, authToken) {
   check(meetingId, String);
   check(userId, String);
   check(authToken, String);
@@ -26,7 +26,7 @@ export default function createDummyUser2x(meetingId, userId, authToken) {
       return Logger.error(`Creating dummy user to collection: ${err}`);
     }
 
-    Logger.info(`Created dummy user 2x id=${userId} token=${authToken} meeting=${meetingId}`);
+    Logger.info(`Created dummy user id=${userId} token=${authToken} meeting=${meetingId}`);
   };
 
   return Users.insert(doc, cb);
diff --git a/bigbluebutton-html5/imports/api/users/server/publishers.js b/bigbluebutton-html5/imports/api/users/server/publishers.js
index 20257202542c8f135d258aa3847eafb728bc42b6..a75d672863e4fa38d029bc68e71d18cdce420d47 100644
--- a/bigbluebutton-html5/imports/api/users/server/publishers.js
+++ b/bigbluebutton-html5/imports/api/users/server/publishers.js
@@ -6,7 +6,7 @@ import mapToAcl from '/imports/startup/mapToAcl';
 
 import userLeaving from './methods/userLeaving';
 
-Meteor.publish('current-user2x', (credentials) => {
+Meteor.publish('current-user', (credentials) => {
   const { meetingId, requesterUserId, requesterToken } = credentials;
 
   check(meetingId, String);
@@ -57,7 +57,7 @@ function users(credentials) {
     },
   };
 
-  Logger.info(`Publishing Users2x for ${meetingId} ${requesterUserId} ${requesterToken}`);
+  Logger.info(`Publishing Users for ${meetingId} ${requesterUserId} ${requesterToken}`);
 
   return Users.find(selector, options);
 }
@@ -67,4 +67,4 @@ function publish(...args) {
   return mapToAcl('subscriptions.users', boundUsers)(args);
 }
 
-Meteor.publish('users2x', publish);
+Meteor.publish('users', publish);
diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx
index 726012248fe9cff02219eb09131cd57b489fb896..3583457ace752cf3bdf53f9dfcce3ad8ea6b27ca 100644
--- a/bigbluebutton-html5/imports/startup/client/base.jsx
+++ b/bigbluebutton-html5/imports/startup/client/base.jsx
@@ -87,8 +87,8 @@ Base.propTypes = propTypes;
 Base.defaultProps = defaultProps;
 
 const SUBSCRIPTIONS_NAME = [
-  'users2x', 'chat2x', 'cursor2x', 'meetings2x', 'polls2x', 'presentations2x', 'annotations',
-  'slides2x', 'captions2x', 'breakouts2x', 'voiceUsers', 'whiteboard-multi-user',
+  'users', 'chat', 'cursor', 'meetings', 'polls', 'presentations', 'annotations',
+  'slides', 'captions', 'breakouts', 'voiceUsers', 'whiteboard-multi-user',
 ];
 
 const BaseContainer = createContainer(({ params }) => {
diff --git a/bigbluebutton-html5/imports/startup/server/redis.js b/bigbluebutton-html5/imports/startup/server/redis.js
index 43151cb5254b7f7be565d19932ac9ce0a32b4eeb..4e15cf962aea24a8f79b2d77b3655f2a3a7acd9f 100644
--- a/bigbluebutton-html5/imports/startup/server/redis.js
+++ b/bigbluebutton-html5/imports/startup/server/redis.js
@@ -90,7 +90,7 @@ class MettingMessageQueue {
   }
 }
 
-class RedisPubSub2x {
+class RedisPubSub {
 
   static handlePublishError(err) {
     if (err) {
@@ -189,7 +189,7 @@ class RedisPubSub2x {
 
     const envelope = makeEnvelope(channel, eventName, header, payload);
 
-    return this.pub.publish(channel, envelope, RedisPubSub2x.handlePublishError);
+    return this.pub.publish(channel, envelope, RedisPubSub.handlePublishError);
   }
 
   publishSystemMessage(channel, eventName, payload) {
@@ -199,7 +199,7 @@ class RedisPubSub2x {
 
     const envelope = makeEnvelope(channel, eventName, header, payload);
 
-    return this.pub.publish(channel, envelope, RedisPubSub2x.handlePublishError);
+    return this.pub.publish(channel, envelope, RedisPubSub.handlePublishError);
   }
 
   publishMeetingMessage(channel, eventName, meetingId, payload) {
@@ -210,7 +210,7 @@ class RedisPubSub2x {
 
     const envelope = makeEnvelope(channel, eventName, header, payload);
 
-    return this.pub.publish(channel, envelope, RedisPubSub2x.handlePublishError);
+    return this.pub.publish(channel, envelope, RedisPubSub.handlePublishError);
   }
 
   publishUserMessage(channel, eventName, meetingId, userId, payload) {
@@ -222,11 +222,11 @@ class RedisPubSub2x {
 
     const envelope = makeEnvelope(channel, eventName, header, payload);
 
-    return this.pub.publish(channel, envelope, RedisPubSub2x.handlePublishError);
+    return this.pub.publish(channel, envelope, RedisPubSub.handlePublishError);
   }
 }
 
-const RedisPubSubSingleton = new RedisPubSub2x();
+const RedisPubSubSingleton = new RedisPubSub();
 
 Meteor.startup(() => {
   const REDIS_CONFIG = Meteor.settings.redis;
diff --git a/bigbluebutton-html5/imports/ui/components/app/container.jsx b/bigbluebutton-html5/imports/ui/components/app/container.jsx
index c86f0506eabc4ca7dbc9b737c55fc7e1c12cfdc6..0d0d3430c7b224b84f0afc5e49ac09c1a9de894d 100644
--- a/bigbluebutton-html5/imports/ui/components/app/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/app/container.jsx
@@ -28,7 +28,6 @@ const propTypes = {
   actionsbar: PropTypes.node,
   media: PropTypes.node,
   location: PropTypes.object.isRequired,
-  children: PropTypes.node.isRequired,
 };
 
 const defaultProps = {
@@ -69,9 +68,7 @@ const AppContainer = (props) => {
       actionsbar={actionsbar}
       media={media}
       {...otherProps}
-    >
-      {props.children}
-    </App>
+    />
   );
 };
 
diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx
index 894ec742b1b63a6e38625575567840ad315f9048..905c88571bace25567e2f7db3cfcada491280a34 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/chat-dropdown/component.jsx
@@ -120,7 +120,7 @@ class ChatDropdown extends Component {
       >
         <DropdownTrigger
           tabIndex={0}
-          ariaLabel={intl.formatMessage(intlMessages.options)}
+          aria-label={intl.formatMessage(intlMessages.options)}
           className={styles.btn}
         >
           <Icon iconName="more" />
diff --git a/bigbluebutton-html5/imports/ui/components/dropdown/trigger/component.jsx b/bigbluebutton-html5/imports/ui/components/dropdown/trigger/component.jsx
index a55cb8a379976891038a02d2af3d539ba4038ce9..9c15694103da63879ea48a996e83243c1b4edd98 100644
--- a/bigbluebutton-html5/imports/ui/components/dropdown/trigger/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/dropdown/trigger/component.jsx
@@ -41,7 +41,17 @@ export default class DropdownTrigger extends Component {
   }
 
   render() {
-    const { children, className, ...restProps } = this.props;
+    const remainingProps = { ...this.props };
+    delete remainingProps.dropdownToggle;
+    delete remainingProps.dropdownShow;
+    delete remainingProps.dropdownHide;
+
+    const {
+      children,
+      className,
+      ...restProps
+    } = remainingProps;
+
     const TriggerComponent = React.Children.only(children);
 
     const TriggerComponentBounded = React.cloneElement(TriggerComponent, {
diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx
index a312d765e0a7c694b4527849f9c64f2486a91846..fe237918b046f8183b9c4ce32789df0bbb64405c 100644
--- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx
@@ -45,6 +45,9 @@ const openBreakoutJoinConfirmation = (breakoutURL, breakoutName, mountModal) =>
     breakoutName={breakoutName}
   />);
 
+const closeBreakoutJoinConfirmation = (mountModal) =>
+   mountModal(null);
+
 class NavBar extends Component {
   constructor(props) {
     super(props);
@@ -143,13 +146,20 @@ class NavBar extends Component {
     );
   }
 
-  componentDidUpdate() {
+  componentDidUpdate(oldProps) {
     const {
       breakouts,
       getBreakoutJoinURL,
       isBreakoutRoom,
     } = this.props;
 
+    const hadBreakouts = oldProps.breakouts.length;
+    const hasBreakouts = breakouts.length;
+
+    if(!hasBreakouts && hadBreakouts) {
+      closeBreakoutJoinConfirmation(this.props.mountModal);
+    }
+
     breakouts.forEach((breakout) => {
       if (!breakout.users) {
         return;
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx
index 8c5d28c042fbf2a7f3b526e0aba6558d6ad4ed57..ad40945cdc135fc731b62236171f124fe7edc2cb 100755
--- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx
@@ -191,7 +191,6 @@ class UserParticipants extends Component {
           className={styles.scrollableList}
           role="tabpanel"
           tabIndex={0}
-          refScrollContainer
           ref={(ref) => { this.refScrollContainer = ref; }}
         >
           <CSSTransitionGroup
diff --git a/bigbluebutton-html5/imports/ui/services/auth/index.js b/bigbluebutton-html5/imports/ui/services/auth/index.js
index 04bfec590168c9ba36a2d36529f17b1c011793d4..1274790f133a5abea3931a4461bd4edc080ad264 100644
--- a/bigbluebutton-html5/imports/ui/services/auth/index.js
+++ b/bigbluebutton-html5/imports/ui/services/auth/index.js
@@ -3,7 +3,7 @@ import { Tracker } from 'meteor/tracker';
 
 import Storage from '/imports/ui/services/storage/session';
 
-import Users2x from '/imports/api/users';
+import Users from '/imports/api/users';
 import { makeCall, logClient } from '/imports/ui/services/api';
 
 const CONNECTION_TIMEOUT = Meteor.settings.public.app.connectionTimeout;
@@ -158,7 +158,7 @@ class Auth {
           });
         }, 5000);
 
-        const subscription = Meteor.subscribe('current-user2x', credentials);
+        const subscription = Meteor.subscribe('current-user', credentials);
         if (!subscription.ready()) return;
 
         resolve(c);
@@ -187,7 +187,7 @@ class Auth {
 
       Tracker.autorun((c) => {
         const selector = { meetingId: this.meetingID, userId: this.userID };
-        const query = Users2x.find(selector);
+        const query = Users.find(selector);
 
         query.observeChanges({
           changed: (id, fields) => {
@@ -208,7 +208,7 @@ class Auth {
         });
       });
 
-      makeCall('validateAuthToken2x');
+      makeCall('validateAuthToken');
     });
   }
 
diff --git a/record-and-playback/core/scripts/utils/gen_webvtt b/record-and-playback/core/scripts/utils/gen_webvtt
index aedbf721eb5706ebcdb02f099ff3c7fdc24c72a7..0221a4ccb5b306b73f0abf35a02591d383d02c7e 100755
--- a/record-and-playback/core/scripts/utils/gen_webvtt
+++ b/record-and-playback/core/scripts/utils/gen_webvtt
@@ -72,8 +72,11 @@ class Caption:
 
             if i < len(self.timestamps) and timestamp > self.timestamps[i]:
                 timestamp = self._del_timestamps[i]
-                if timestamp is None and i > 0:
-                    timestamp = self.timestamps[i-1]
+                if timestamp is None:
+                    if i > 0:
+                        timestamp = self.timestamps[i-1]
+                    else:
+                        timestamp = self.timestamps[i]
                 logger.debug("Out of order timestamps, using ts: %d", timestamp)
 
         self._del_timestamps[i:j] = [del_timestamp] * len(text)