diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java
old mode 100755
new mode 100644
index 984e1884566d81446a336acb804eab6d9e141c84..43f6bb884c06f6202c648244d9c527b13c72c186
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/CallStream.java
@@ -97,7 +97,7 @@ public class CallStream implements StreamObserver {
 
     public void stop() {
     	log.debug("Stopping call stream");
-        userListenStream.stop();
+      userListenStream.stop();
     }
 
 	@Override
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java
old mode 100755
new mode 100644
index 86d395ad0d4b212cfd1086e60ab19654a2b7a21e..9fcf5ec90ef722694cb6f878e6e73f91525fad49
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/FlashToSipAudioStream.java
@@ -75,8 +75,8 @@ public class FlashToSipAudioStream {
 			}
 		};
 				
-	    broadcastStream.addStreamListener(mInputListener);    
-	    rtpSender = new RtpStreamSender(srcSocket, connInfo);
+	  broadcastStream.addStreamListener(mInputListener);    
+	  rtpSender = new RtpStreamSender(srcSocket, connInfo);
 		rtpSender.connect();
 		transcoder.start();
 	}
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java
old mode 100755
new mode 100644
index 9e2f8638aeb42652a0e5b34ea64bf9ed8d6dd159..218321f872aa02346347848db875fae70323ded5
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/RtpStreamReceiver.java
@@ -115,7 +115,6 @@ public class RtpStreamReceiver {
         	}
         }
         log.debug("Rtp Receiver stopped. Packet Received = " + packetReceivedCounter + "." );
-        if (listener != null) listener.onStoppedReceiving();
     }
     
     private boolean shouldDropDelayedPacket(RtpPacket rtpPacket) {
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java
old mode 100755
new mode 100644
index f68b7ab648757707476cf4055f2a25fb17a51168..b81cdd554ab63b8384a45994d09b36d6edc0356d
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java
@@ -87,9 +87,13 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt
 			if (log.isDebugEnabled()) log.debug("Stopped audioBroadcastStream for {}", listenStreamName);
 			audioBroadcastStream.close();
 		    if (log.isDebugEnabled()) log.debug("Closed audioBroadcastStream for {}", listenStreamName);
-		} else
+		} else {
 			if (log.isDebugEnabled()) log.debug("audioBroadcastStream is null, couldn't stop");
-	    if (log.isDebugEnabled()) log.debug("Stream(s) stopped");
+		}
+		
+	   if (log.isDebugEnabled()) log.debug("Stream(s) stopped");
+	    
+	    if (observer != null) observer.onStreamStopped();
 	}
 	
 	public void start() {
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java
old mode 100755
new mode 100644
index 2f3eca5316a74ecf99d69da24a1fddd2f4eed592..8f0047ccab499aa89b144a8fff21daa062de7df8
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/CallAgent.java
@@ -243,6 +243,8 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
     public void stopTalkStream(IBroadcastStream broadcastStream, IScope scope) {
     	if (callStream != null) {
     		callStream.stopTalkStream(broadcastStream, scope);   	
+    	} else {
+    		log.info("Can't stop talk stream as stream may have already stopped.");
     	}
     }
 
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/SipPeer.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/SipPeer.java
old mode 100755
new mode 100644
index 5a4dd9dfbde463c0cdfebadc9f9bcf5f8cf637d5..e842fe82e49fe8761e9a811d281d2e682414f6d0
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/SipPeer.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/sip/SipPeer.java
@@ -195,13 +195,15 @@ public class SipPeer implements SipRegisterAgentListener {
     	CallAgent ca = callManager.get(clientId);
         if (ca != null) {
            ca.startTalkStream(broadcastStream, scope);
-        }
+        } 
     }
     
     public void stopTalkStream(String clientId, IBroadcastStream broadcastStream, IScope scope) {
     	CallAgent ca = callManager.get(clientId);
         if (ca != null) {
            ca.stopTalkStream(broadcastStream, scope);
+        } else {
+        	log.info("Can't stop talk stream as stream may have already been stopped.");
         }
     }
 
diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
index 0580fe305bf69c3fb08a8dcd2fcc07b7f8a85f5f..99a5b060f192caa52cf06529d4f0c1acb8870e8e 100644
--- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
+++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
@@ -434,8 +434,7 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway, presUtil: PreuploadedPresen
 	  
 	  voiceGW.voiceUserJoined(meetingId, userId, webUserId, 
 	                            conference, callerIdNum, 
-	                            callerIdName,
-								muted, speaking)
+	                            callerIdName, muted, speaking)
 	}
 	
 	def voiceUserLeft(meetingId: String, userId: String) {
diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
index 48d8247c057d35f80aebb139f5513b880423f497..fddaea8e0550a3efa4649cc18c425fafa8debb76 100644
--- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
+++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
@@ -265,7 +265,7 @@ trait UsersApp {
         case Some(user) => {
           val nu = user.copy(voiceUser=msg.voiceUser)
           users.addUser(nu)
-//          println("Received user joined voice for user [" + nu.name + "] userid=[" + msg.voiceUser.webUserId + "]" )
+          logger.info("Received user joined voice for user [" + nu.name + "] userid=[" + msg.voiceUser.webUserId + "]" )
           outGW.send(new UserJoinedVoice(meetingID, recorded, voiceBridge, nu))
           
           if (meetingMuted)
@@ -285,7 +285,7 @@ trait UsersApp {
 		                  phoneUser=true, vu, listenOnly=false, permissions)
 		  	
 		      users.addUser(uvo)
-		      println("New user joined voice for user [" + uvo.name + "] userid=[" + msg.voiceUser.webUserId + "]")
+		      logger.info("New user joined voice for user [" + uvo.name + "] userid=[" + msg.voiceUser.webUserId + "]")
 		      outGW.send(new UserJoined(meetingID, recorded, uvo))
 		      
 		      outGW.send(new UserJoinedVoice(meetingID, recorded, voiceBridge, uvo))
diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConference.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConference.scala
index d5eb2e79616ee223f38d469131ea1bbeb7c4ffde..bb657183ffad57813428a383d8835bb985a6b09d 100644
--- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConference.scala
+++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConference.scala
@@ -1,10 +1,11 @@
 package org.bigbluebutton.freeswitch
 
 import org.bigbluebutton.core.api.UserVO
+import org.bigbluebutton.core.util._
 
 class FreeswitchConference(val conferenceNum: String, 
                            val meetingId: String,
-                           val recorded: Boolean) {
+                           val recorded: Boolean) extends LogHelper {
 
   private var users = new scala.collection.immutable.HashMap[String, UserVO]
   
@@ -19,7 +20,9 @@ class FreeswitchConference(val conferenceNum: String,
   }
 
   def getWebUserUsingExtId(webUserId: String):Option[UserVO] = {
-    users.values find (u => (u.externUserID == webUserId))  
+    users.values find {u => 
+      (u.externUserID == webUserId)    
+    }  
   }
     
   def getWebUser(webUserId: String):Option[UserVO] = {
diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceActor.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceActor.scala
index f53d1e27604484a9f4ef682bcc774b4a5649f260..f0168594f52ccf64ea22b0345eb1612a9d313c38 100644
--- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceActor.scala
+++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceActor.scala
@@ -26,6 +26,7 @@ class FreeswitchConferenceActor(fsproxy: FreeswitchManagerProxy, bbbInGW: IBigBl
 	  react {
 	    case msg: MeetingCreated                     => handleMeetingCreated(msg)
 	    case msg: MeetingEnded                       => handleMeetingEnded(msg)
+	    case msg: MeetingDestroyed                   => handleMeetingDestroyed(msg)
 	    case msg: UserJoined                         => handleUserJoined(msg)
 	    case msg: UserLeft                           => handleUserLeft(msg)
 	    case msg: MuteVoiceUser                      => handleMuteVoiceUser(msg)
@@ -56,7 +57,7 @@ class FreeswitchConferenceActor(fsproxy: FreeswitchManagerProxy, bbbInGW: IBigBl
     
   private def handleMeetingCreated(msg: MeetingCreated) {
     if (! confs.contains(msg.meetingID)) {
-      logger.info("FSConference rx meeting created for meeting id[" + msg.meetingID + "]")
+      logger.info("Meeting created [" + msg.meetingID + "] with voice conf [" + msg.voiceBridge + "]")
       val fsconf = new FreeswitchConference(msg.voiceBridge,
                                             msg.meetingID, 
                                             msg.recorded)
@@ -70,10 +71,23 @@ class FreeswitchConferenceActor(fsproxy: FreeswitchManagerProxy, bbbInGW: IBigBl
     val fsconf = confs.values find (c => c.meetingId == msg.meetingID)
     
     fsconf foreach (fc => {
+      logger.info("Meeting ended [" + msg.meetingID + "]")
       fsproxy.ejectUsers(fc.conferenceNum)
       confs -= fc.meetingId
     })
   }
+
+  private def handleMeetingDestroyed(msg: MeetingDestroyed) {
+    val fsconf = confs.values find (c => c.meetingId == msg.meetingID)
+    
+    fsconf foreach (fc => {
+      logger.info("Meeting destroyed [" + msg.meetingID + "]")
+      fsproxy.ejectUsers(fc.conferenceNum)
+      confs -= fc.meetingId
+    })
+  }
+    
+  
   
   private def handleUserJoinedVoice(msg: UserJoinedVoice) {
     val fsconf = confs.values find (c => c.meetingId == msg.meetingID)
@@ -107,7 +121,7 @@ class FreeswitchConferenceActor(fsproxy: FreeswitchManagerProxy, bbbInGW: IBigBl
     val fsconf = confs.values find (c => c.meetingId == msg.meetingID)
     
     fsconf foreach (fc => {
-      logger.info("Web user id joining meeting id[" + fc.meetingId + "] wid=[" + msg.user.userID + "]")
+      logger.info("Web user id joining meeting id[" + fc.meetingId + "] wid=[" + msg.user.userID + "], extId=[" + msg.user.externUserID + "]")
       fc.addUser(msg.user)
     })
   }
@@ -162,33 +176,31 @@ class FreeswitchConferenceActor(fsproxy: FreeswitchManagerProxy, bbbInGW: IBigBl
       } else if (fc.isRecording && ! msg.recording) {
         fc.recordingStopped
         bbbInGW.voiceRecording(fc.meetingId, msg.recordingFile, msg.timestamp, msg.recording)
-      }
-       
+      }     
     }
   }
   
   private def sendNonWebUserJoined(meetingId: String, webUserId: String, msg: FsVoiceUserJoined) {
-    logger.info("FreeswitchConferenceActor:: Sending FsVoiceUserJoined for conference [" + 
-                msg.conference + "] user=[" + msg.callerIdName + "] userid=[" + webUserId + "]")
     bbbInGW.voiceUserJoined(meetingId, msg.userId, 
 	              webUserId, msg.conference, msg.callerIdNum, msg.callerIdName,
 	              msg.muted, msg.speaking)    
   }
   
   private def handleFsVoiceUserJoined(msg: FsVoiceUserJoined) {
-     logger.info("FreeswitchConferenceActor:: Received FsVoiceUserJoined for conference [" + 
+     logger.info("A user has joined the voice conference [" + 
                 msg.conference + "] user=[" + msg.callerIdName + "] wid=[" + msg.webUserId + "]")
     val fsconf = confs.values find (c => c.conferenceNum == msg.conference)
     
     fsconf foreach (fc => {
+      logger.debug("Meeting [" + fc.meetingId + "] has [" + fc.numUsers + "]")
 	    fc.getWebUserUsingExtId(msg.webUserId) match {
 	      case Some(user) => {
-          logger.info("FreeswitchConferenceActor:: Found webuser for this user for conference [" + 
+          logger.info("The user is also in the web client. [" + 
                 msg.conference + "] user=[" + msg.callerIdName + "] wid=[" + msg.webUserId + "]")	     
 	        sendNonWebUserJoined(fc.meetingId, user.userID, msg)
 	      }
 	      case None => {
-          logger.info("FreeswitchConferenceActor:: Did not find webuser for this user for conference [" + 
+          logger.info("User is not a web user. Must be a phone caller. [" + 
                 msg.conference + "] user=[" + msg.callerIdName + "] wid=[" + msg.webUserId + "]")	
 	         sendNonWebUserJoined(fc.meetingId, msg.userId, msg)
 	      }
diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceService.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceService.scala
index 40336719387555be094048e2bd3fee62d18e9dbe..46d465aed1c7dd286e762b2a42321d3168f7a255 100644
--- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceService.scala
+++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/freeswitch/FreeswitchConferenceService.scala
@@ -23,6 +23,8 @@ class FreeswitchConferenceService(fsproxy: FreeswitchManagerProxy,
   def handleMessage(msg: IOutMessage) {
 	  msg match {
 	    case msg: MeetingCreated                => handleMeetingCreated(msg)
+	    case msg: MeetingEnded                  => handleMeetingEnded(msg)
+	    case msg: MeetingDestroyed              => handleMeetingDestroyed(msg)
 	    case msg: UserJoined                    => handleUserJoined(msg)
 	    case msg: UserLeft                      => handleUserLeft(msg)
 	    case msg: MuteVoiceUser                 => handleMuteVoiceUser(msg)
@@ -62,6 +64,15 @@ class FreeswitchConferenceService(fsproxy: FreeswitchManagerProxy,
     fsActor ! msg
   }
   
+  private def handleMeetingEnded(msg: MeetingEnded) {
+    fsActor ! msg
+  }
+    
+  private def handleMeetingDestroyed(msg: MeetingDestroyed) {
+    fsActor ! msg
+  }
+    
+  
   private def handleEjectAllVoiceUsers(msg: EjectAllVoiceUsers) {
     fsActor ! msg
   }
diff --git a/bigbluebutton-client/branding/default/style/css/BBBDefault.css b/bigbluebutton-client/branding/default/style/css/BBBDefault.css
index 6b3eac466b69b2423b350cdcf80923171af1da1a..090252267b70746c52e70ac9563e9d73432ddc25 100755
--- a/bigbluebutton-client/branding/default/style/css/BBBDefault.css
+++ b/bigbluebutton-client/branding/default/style/css/BBBDefault.css
@@ -437,14 +437,14 @@ DataGrid {
 
 }
 
-.presentationUploadFileFormatHintBoxStyle {
+.presentationUploadFileFormatHintBoxStyle, .desktopShareUsingChromeOnMacHintBoxStyle {
 	backgroundColor: #D4D4D4;
 	dropShadowEnabled: false;
 	paddingLeft: 10;
 	paddingRight: 10
 }
 
-.presentationUploadFileFormatHintTextStyle {
+.presentationUploadFileFormatHintTextStyle, .desktopShareUsingChromeOnMacHintTextStyle {
 	fontWeight: bold;
 }
 
diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties
index 2f3252d27cb3ccd25b0d5e6284be422d60605f52..e5a520ff5c2b956f06da7defe40a438d03076877 100755
--- a/bigbluebutton-client/locale/en_US/bbbResources.properties
+++ b/bigbluebutton-client/locale/en_US/bbbResources.properties
@@ -179,7 +179,7 @@ bbb.fileupload.okCancelBtn = Close
 bbb.fileupload.okCancelBtn.toolTip = Close the File Upload dialog box
 bbb.fileupload.genThumbText = Generating thumbnails..
 bbb.fileupload.progBarLbl = Progress:
-bbb.fileupload.fileFormatHint = Upload upload any office document or Portable Document Format (PDF) file.  For best results upload PDF.
+bbb.fileupload.fileFormatHint = Upload any office document or Portable Document Format (PDF) file.  For best results upload PDF.
 bbb.chat.title = Chat
 bbb.chat.quickLink.label = Chat Window
 bbb.chat.cmpColorPicker.toolTip = Text Color
@@ -234,6 +234,7 @@ bbb.desktopPublish.stop.tooltip = Close screen share
 bbb.desktopPublish.stop.label = Close
 bbb.desktopPublish.maximizeRestoreBtn.toolTip = You cannot maximize this window.
 bbb.desktopPublish.closeBtn.toolTip = Stop Sharing and Close
+bbb.desktopPublish.chromeOnMacUnsupportedHint = Desktop sharing is not currently supported on Chrome running under Mac OS X. Recommend you use FireFox to share desktop.
 bbb.desktopPublish.minimizeBtn.toolTip = Minimize
 bbb.desktopPublish.minimizeBtn.accessibilityName = Minimize the Desktop Sharing Publish Window
 bbb.desktopPublish.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing Publish Window
diff --git a/bigbluebutton-client/resources/prod/BigBlueButton.html b/bigbluebutton-client/resources/prod/BigBlueButton.html
old mode 100755
new mode 100644
index c831ae54b00a94ca4ee426b90eb2d9d9215edaa8..d262a9b499079e686a0f2d09c4da061f26fb3c87
--- a/bigbluebutton-client/resources/prod/BigBlueButton.html
+++ b/bigbluebutton-client/resources/prod/BigBlueButton.html
@@ -38,6 +38,7 @@
       swfobject.embedSWF("BigBlueButton.swf?v=VERSION", "altFlash", "100%", "100%", "11.0.0", "expressInstall.swf", flashvars, params, attributes);
     </script>
     <script src="lib/jquery-1.5.1.min.js" language="javascript"></script>
+    <script src="lib/bbblogger.js" language="javascript"></script>
     <script src="lib/bigbluebutton.js" language="javascript"></script>
     <script src="lib/bbb_localization.js" language="javascript"></script>
     <script src="lib/bbb_blinker.js" language="javascript"></script>
diff --git a/bigbluebutton-client/resources/prod/lib/bbblogger.js b/bigbluebutton-client/resources/prod/lib/bbblogger.js
new file mode 100644
index 0000000000000000000000000000000000000000..a8e5199fa2b7acd0714e3dc8087626c7f3facee6
--- /dev/null
+++ b/bigbluebutton-client/resources/prod/lib/bbblogger.js
@@ -0,0 +1,25 @@
+
+(function(window, undefined) {
+
+    var BBBLog = {};
+
+    /**
+     * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+     * NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE!
+     * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+     *
+     *   DO NOT CALL THIS METHOD FROM YOUR JS CODE.
+     *
+     * This is called by the BigBlueButton Flash client.
+     *
+     * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+     * NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE!
+     * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=     
+     */
+    BBBLog.log = function (text) {
+      console.log("LOG - " + text);
+    }
+
+    window.BBBLog = BBBLog;
+})(this);
+
diff --git a/bigbluebutton-client/src/BigBlueButton.mxml b/bigbluebutton-client/src/BigBlueButton.mxml
index 9bbcdb99c42109651c252fcf38694fda3597ecf2..bd8cbfd3747a2f7bb8dcbb77e91d5b54d2adfc82 100755
--- a/bigbluebutton-client/src/BigBlueButton.mxml
+++ b/bigbluebutton-client/src/BigBlueButton.mxml
@@ -25,6 +25,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 layout="absolute" 
                 preloader="org.bigbluebutton.main.model.BigBlueButtonPreloader">
    
-  <views:BigBlueButtonMainPanel id="bbbShell"/>
+  <views:BigBlueButtonMainContainer id="bbbShell"/>
  
 </mx:Application>
diff --git a/bigbluebutton-client/src/BigBlueButtonMainPanel.mxml b/bigbluebutton-client/src/BigBlueButtonMainContainer.mxml
similarity index 95%
rename from bigbluebutton-client/src/BigBlueButtonMainPanel.mxml
rename to bigbluebutton-client/src/BigBlueButtonMainContainer.mxml
index 5313b5e8589d36c894baa5bbd17d3f4eef028583..03a862b2475bbe3b96b9ae2d9e233f1fab5961d1 100644
--- a/bigbluebutton-client/src/BigBlueButtonMainPanel.mxml
+++ b/bigbluebutton-client/src/BigBlueButtonMainContainer.mxml
@@ -18,18 +18,16 @@ You should have received a copy of the GNU Lesser General Public License along
 with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 -->
-<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
+<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
   xmlns:views="org.bigbluebutton.main.views.*"
   xmlns:maps="org.bigbluebutton.main.maps.*"
   xmlns:userMap="org.bigbluebutton.modules.users.maps.*"
   xmlns:apimap="org.bigbluebutton.main.api.maps.*"
   xmlns:coreMap="org.bigbluebutton.core.controllers.maps.*"
   xmlns:mate="http://mate.asfusion.com/"
-  layout="absolute" 
   width="100%" height="100%"
-  borderStyle="none" horizontalAlign="center"
-  headerHeight="0" borderThicknessBottom="0" borderThicknessLeft="0"
-  borderThicknessRight="0" borderThicknessTop="0"
+  horizontalScrollPolicy="off"
+  verticalScrollPolicy="off"
   creationComplete="init()">
   
   <mx:Script>
@@ -218,4 +216,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
   
   <mate:Listener type="{ShortcutEvent.FOCUS_AWAY_EVENT}" method="loseFocusFromApp" />
   
-</mx:Panel>
+</mx:Canvas>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/api/JSLog.as b/bigbluebutton-client/src/org/bigbluebutton/main/api/JSLog.as
new file mode 100644
index 0000000000000000000000000000000000000000..251f8a108c402f30cd57a5583fee48d5dbc77649
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/api/JSLog.as
@@ -0,0 +1,31 @@
+package org.bigbluebutton.main.api
+{
+  public class JSLog
+  {
+    public static const LOGGER:String = "BBBLOGGER";
+    
+    public static function debug(message:String):void
+    {
+      logger.debug(message);
+    }
+    
+    public static function info(message:String):void
+    {
+      logger.info(message);
+    }
+    
+    public static function error(message:String):void
+    {
+      logger.error(message);
+    }
+    
+    public static function warn(message:String):void
+    {
+      logger.warn(message);
+    }
+        
+    private static function get logger():JSLogger {
+      return JSLogger.getInst();
+    }
+  }
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/api/JSLogger.as b/bigbluebutton-client/src/org/bigbluebutton/main/api/JSLogger.as
new file mode 100644
index 0000000000000000000000000000000000000000..2211bf1f80d6914813735d2ef96a59ef8ea4f4d5
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/api/JSLogger.as
@@ -0,0 +1,47 @@
+package org.bigbluebutton.main.api
+{
+  import flash.external.ExternalInterface;
+
+  class JSLogger {
+    private static var instance:JSLogger = null;
+    
+    public function JSLogger(enforcer:JSLoggerSingletonEnforcer) {
+      if (enforcer == null) {
+        throw new Error("There can only be 1 JSLogger instance");
+      }
+    }
+    
+    public static function getInst():JSLogger {
+      if (instance == null){
+        instance = new JSLogger(new JSLoggerSingletonEnforcer());
+      }
+      return instance;
+    }
+    
+    public function debug(message:String):void
+    {
+      log("[DEB] - " + message);
+    }
+    
+    public function info(message:String):void
+    {
+      log("[INF] - " +message);
+    }
+    
+    public function error(message:String):void
+    {
+      log("[ERR] -" + message);
+    }
+        
+    public function warn(message:String):void
+    {
+      log("[WAR] - " + message);
+    }
+    
+    public function log(text: String):void {
+      ExternalInterface.call("BBBLog.log", text);
+    }    
+  }
+}
+
+class JSLoggerSingletonEnforcer{}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
index 3bea16a7b011c91e7c7421efed891e2e8f935582..67609a29512d224f565c9b94e2c760ceb0569b77 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
@@ -280,6 +280,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 					mic = null;
 				}
 			}
+      
 			     
 			private function changeRecordVolume(event:SliderEvent):void {
 				var currentSlider:Slider=Slider(event.currentTarget);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
index fc30e1f73020d834c968b69e0dca038b9b6da995..2c01f31b17a8e5fbb0f3059a6fe383adc07f11d9 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/>.
 			[Bindable] private var toolbarPaddingTop:Number = 4;
 			[Bindable] private var showFooterOpt:Boolean = true;
 			[Bindable] private var footerHeight:Number = 24;
+			[Bindable] private var globalHeight:Number = 0;
 			
 			[Bindable] private var isTunneling:Boolean = false;
 			
@@ -192,6 +193,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				} else {
 					copyrightLabel2.width += Math.min(spacer.width, copyrightLabel2.measuredWidth - copyrightLabel2.width);
 				}
+				
+				globalHeight = screenRect.height;
 			}
 		
 			protected function initFullScreen():void {				
@@ -593,7 +596,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 					  verticalScrollPolicy="off" 
 					  effectsLib="{flexlib.mdi.effects.effectsLib.MDIVistaEffects}" 
 					  width="100%" 
-					  height="100%">
+					  height="{globalHeight - footerHeight - toolbarHeight - 12}">
 		<views:LoadingBar id="progressBar" horizontalCenter="0" verticalCenter="0" width="50%" />
 		<views:BrandingLogo x="{this.width - 300}" y="{this.height - 300}" />
 	</views:MainCanvas>	
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainCanvas.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainCanvas.mxml
old mode 100644
new mode 100755
index f167508ba025b2835560441a1e2ef103a4ae6345..f3ae3439e6c489dce67f0c5e1a56f952485186e9
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainCanvas.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainCanvas.mxml
@@ -185,8 +185,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 						if (y < 0) y = 1;
 						break;
 					case DESKTOP_SHARING_PUBLISH:
-						y = (this.height - win.height);
-						x = 1;
+						y = (this.height - win.height) - 23;
+						x = 8;
 						break;
 					case DESKTOP_SHARING_VIEW:
 						x = 1;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordButton.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordButton.mxml
old mode 100755
new mode 100644
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml
old mode 100755
new mode 100644
index 58791d4aae6c590fd604bf9f1c7b4bc17f389ee2..2f1d952361aa0d71d1a90bed16b9cbe4be7de9b7
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/WebRTCEchoTest.mxml
@@ -30,7 +30,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	<mate:Listener type="{WebRTCEchoTestStartedEvent.WEBRTC_ECHO_TEST_STARTED}" method="handleWebRTCEchoTestStartedEvent" />
 	<mate:Listener type="{WebRTCEchoTestEvent.WEBRTC_ECHO_TEST_ENDED}" method="handleWebRTCEchoTestEndedEvent" />
 	<mate:Listener type="{WebRTCCallEvent.WEBRTC_CALL_CONNECTING}" method="handleWebRTCCallConnectingEvent" />
-	<mate:Listener type="{WebRTCCallEvent.WEBRTC_CALL_STARTED}" method="handleWebRTCCallStartedEvent" />
+	<mate:Listener type="{WebRTCJoinedVoiceConferenceEvent.JOINED_VOICE_CONFERENCE}" method="handleWebRTCCallStartedEvent" />
 	
 	<mx:Script>
 		<![CDATA[
@@ -40,12 +40,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       
       import org.bigbluebutton.core.BBB;
       import org.bigbluebutton.main.api.JSAPI;
+      import org.bigbluebutton.main.api.JSLog;
       import org.bigbluebutton.main.events.BBBEvent;
       import org.bigbluebutton.modules.phone.PhoneModel;
       import org.bigbluebutton.modules.phone.PhoneOptions;
       import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
       import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
       import org.bigbluebutton.modules.phone.events.WebRTCEchoTestStartedEvent;
+      import org.bigbluebutton.modules.phone.events.WebRTCJoinedVoiceConferenceEvent;
       import org.bigbluebutton.modules.phone.models.Constants;
       import org.bigbluebutton.util.i18n.ResourceUtil;
 			
@@ -59,6 +61,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 			
 			private function onCancelClicked():void {
+        JSLog.debug(LOG + "onCancelClicked .");
 				dotTimer.stop();
 				PopUpManager.removePopUp(this);
 			}
@@ -90,6 +93,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			private function yesButtonClicked():void {
 				trace(LOG + "Echo test passed.");
+        JSLog.debug(LOG + "Echo test passed.");
 				var dispatcher:Dispatcher = new Dispatcher();
 				dispatcher.dispatchEvent(new WebRTCEchoTestEvent(WebRTCEchoTestEvent.WEBRTC_ECHO_TEST_HAS_AUDIO));
 				setCurrentState("connecting");
@@ -98,6 +102,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			private function noButtonClicked():void {
 				trace(LOG + "Echo test failed.");
+        JSLog.debug(LOG + "Echo test failed.");
 				var dispatcher:Dispatcher = new Dispatcher();
 				dispatcher.dispatchEvent(new WebRTCEchoTestEvent(WebRTCEchoTestEvent.WEBRTC_ECHO_TEST_NO_AUDIO));
 				onCancelClicked();
@@ -129,10 +134,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
       
       private function webRTCCallStarted():void {
+        JSLog.debug(LOG + "webRTCCallStarted.");
         onCancelClicked();
       }
 			
-			private function handleWebRTCCallStartedEvent(e:WebRTCCallEvent):void {
+			private function handleWebRTCCallStartedEvent(e:WebRTCJoinedVoiceConferenceEvent):void {
+        JSLog.debug(LOG + "handleWebRTCCallStartedEvent .");
         webRTCCallStarted();
 			}
 			
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/view/components/DesktopPublishWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/view/components/DesktopPublishWindow.mxml
index 4fbc607bd3b0b943a7b7679afec93e33559ccfbc..40ef279e3721d8a53a9f6d096780a4d45e6c7c49 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/view/components/DesktopPublishWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/view/components/DesktopPublishWindow.mxml
@@ -111,8 +111,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
 				cursor.graphics.drawCircle(0,0,3);		
 					
-				setCurrentState("dispFullRegionControlBar");
-				
+				if (isUsingChromeOnMac()) {
+				   setCurrentState("chromeOnMacWarningState");
+				}
+				else {
+				   setCurrentState("dispFullRegionControlBar");
+				}
 				resourcesChanged();
 				
 				titleBarOverlay.tabIndex = baseIndex;
@@ -362,6 +366,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         var CHECK_JAVA_URL:String = BBB.initConfigManager().config.javaTest.url;        
         navigateToURL(new URLRequest(CHECK_JAVA_URL));
       }
+			private function isUsingChromeOnMac():Boolean {
+				return ((ExternalInterface.call("determineBrowser")[0] == "Chrome") && (Capabilities.os.indexOf("Mac") >= 0));
+			}
 		]]>
 	</mx:Script>
 
@@ -406,13 +413,30 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                                    toolTip="{ResourceUtil.getInstance().getString('bbb.desktopPublish.javaTestLinkLabel.tooltip')}" 
                                    accessibilityDescription="{ResourceUtil.getInstance().getString('bbb.desktopPublish.javaTestLinkLabel.tooltip.accessibility')}"/>
                   </mx:VBox>
-                </mx:ControlBar>           
-
-              
+                </mx:ControlBar>
             </mx:AddChild>
         </mx:State>	
+		<mx:State name="chromeOnMacWarningState">
+			<mx:AddChild>
+				<mx:VBox id="chromeOnMacWarningBottomBar" horizontalAlign="center" width="100%" height="100%" verticalAlign="bottom">
+					<mx:HBox>
+						<mx:Button id="chromeOnMacWarningCloseButton"
+								   toolTip="{ResourceUtil.getInstance().getString('bbb.desktopPublish.stop.tooltip')}"
+								   label="{ResourceUtil.getInstance().getString('bbb.desktopPublish.stop.label')}"
+								   visible="true"
+								   enabled="true"
+								   click="stopSharing()"
+								   />
+						<mx:Spacer width="100%"/>
+					</mx:HBox>
+					<mx:HBox horizontalAlign="center" width="300" styleName="desktopShareUsingChromeOnMacHintBoxStyle">
+						<mx:Text id="chromeOnMacWarningLbl" width="100%" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.desktopPublish.chromeOnMacUnsupportedHint')}"
+								 styleName="desktopShareUsingChromeOnMacHintTextStyle" toolTip="{ResourceUtil.getInstance().getString('bbb.desktopPublish.chromeOnMacUnsupportedHint')}" />
+					</mx:HBox>
+				</mx:VBox>
+			</mx:AddChild>
+		</mx:State>
 	</dspub:states>
-
 	<mx:Image id="cursorImg" visible="false" source="@Embed('../../assets/images/cursor4.png')"/>
 
 </dspub:MDIWindow>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/events/WebRTCJoinedVoiceConferenceEvent.as b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/events/WebRTCJoinedVoiceConferenceEvent.as
new file mode 100644
index 0000000000000000000000000000000000000000..a8f1f44e5ad49ce5c0203bce3cd48841e2dfa2c2
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/events/WebRTCJoinedVoiceConferenceEvent.as
@@ -0,0 +1,14 @@
+package org.bigbluebutton.modules.phone.events
+{
+  import flash.events.Event;
+  
+  public class WebRTCJoinedVoiceConferenceEvent extends Event
+  {
+    public static const JOINED_VOICE_CONFERENCE:String = "webrtc joined voice conference event";
+    
+    public function WebRTCJoinedVoiceConferenceEvent()
+    {
+      super(JOINED_VOICE_CONFERENCE, true, false);
+    }
+  }
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as
index 15648d70a32b4358e165838d2f5f9a7c05ab2ab8..8ffce948b349985e4e1233fd4f95172337046b29 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as
@@ -31,6 +31,7 @@ package org.bigbluebutton.modules.phone.managers {
 	
 	import org.bigbluebutton.common.LogUtil;
 	import org.bigbluebutton.core.BBB;
+	import org.bigbluebutton.main.api.JSLog;
 	import org.bigbluebutton.modules.phone.events.ConnectionStatusEvent;
 	import org.bigbluebutton.modules.phone.events.FlashCallConnectedEvent;
 	import org.bigbluebutton.modules.phone.events.FlashCallDisconnectedEvent;
@@ -114,29 +115,33 @@ package org.bigbluebutton.modules.phone.managers {
       switch (statusCode) {
         case "NetConnection.Connect.Success":
           trace(LOG + "Connection success");
+          JSLog.debug(LOG + "Connection success");
           dispatcher.dispatchEvent(new FlashVoiceConnectionStatusEvent(FlashVoiceConnectionStatusEvent.CONNECTED));           
           break;
         case "NetConnection.Connect.Failed":
           trace(LOG + "Connection failed");
+          JSLog.debug(LOG + "Connection failed");
           dispatcher.dispatchEvent(new FlashVoiceConnectionStatusEvent(FlashVoiceConnectionStatusEvent.FAILED));
           break;
         case "NetConnection.Connect.NetworkChange":
           trace(LOG + "Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
+          JSLog.debug(LOG + "Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
           dispatcher.dispatchEvent(new FlashVoiceConnectionStatusEvent(FlashVoiceConnectionStatusEvent.NETWORK_CHANGE));
           break;
         case "NetConnection.Connect.Closed":
           trace(LOG + "Connection closed");
+          JSLog.debug(LOG + "Connection closed");
           handleConnectionClosed();
           break;
       }
 		} 
 		
 		private function asyncErrorHandler(event:AsyncErrorEvent):void {
-      LogUtil.debug("AsyncErrorEvent: " + event);
+      JSLog.debug("AsyncErrorEvent: " + event);
     }
 		
 		private function securityErrorHandler(event:SecurityErrorEvent):void {
-      LogUtil.debug("securityErrorHandler: " + event);
+      JSLog.debug("securityErrorHandler: " + event);
     }
         
     //********************************************************************************************
@@ -146,18 +151,21 @@ package org.bigbluebutton.modules.phone.managers {
 		//********************************************************************************************		
 		public function failedToJoinVoiceConferenceCallback(msg:String):* {
 			trace(LOG + "failedToJoinVoiceConferenceCallback " + msg);
+      JSLog.debug(LOG + "failedToJoinVoiceConferenceCallback " + msg);
 			var event:FlashCallDisconnectedEvent = new FlashCallDisconnectedEvent();
 			dispatcher.dispatchEvent(event);	
 		}
 		
 		public function disconnectedFromJoinVoiceConferenceCallback(msg:String):* {
 			trace(LOG + "disconnectedFromJoinVoiceConferenceCallback " + msg);
+      JSLog.debug(LOG + "disconnectedFromJoinVoiceConferenceCallback " + msg);
 			var event:FlashCallDisconnectedEvent = new FlashCallDisconnectedEvent();
 			dispatcher.dispatchEvent(event);	
 		}	
 				
      public function successfullyJoinedVoiceConferenceCallback(publishName:String, playName:String, codec:String):* {
       trace(LOG + "successfullyJoinedVoiceConferenceCallback [" + publishName + "] : [" + playName + "] : [" + codec + "]");
+      JSLog.debug(LOG + "successfullyJoinedVoiceConferenceCallback [" + publishName + "] : [" + playName + "] : [" + codec + "]");
 			var event:FlashCallConnectedEvent = new FlashCallConnectedEvent(publishName, playName, codec);
 			dispatcher.dispatchEvent(event);
 		}
@@ -169,12 +177,14 @@ package org.bigbluebutton.modules.phone.managers {
 		//********************************************************************************************		
 		public function doCall(dialStr:String, listenOnly:Boolean = false):void {
 			trace(LOG + "in doCall - Calling " + dialStr + (listenOnly? " *listen only*": ""));
+      JSLog.debug(LOG + "in doCall - Calling " + dialStr + (listenOnly? " *listen only*": ""));
 			netConnection.call("voiceconf.call", null, "default", username, dialStr, listenOnly.toString());
 		}
 				
 		public function doHangUp():void {			
 			if (isConnected()) {
         trace(LOG + "hanging up call");
+        JSLog.debug(LOG + "hanging up call");
 				netConnection.call("voiceconf.hangup", null, "default");
 			}
 		}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/FlashCallManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/FlashCallManager.as
index 5ae598595ab4102d51f5e5ea25ee437584c48304..0d71b0fb9c446d5113ff25c4b937839844184ba4 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/FlashCallManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/FlashCallManager.as
@@ -1,10 +1,13 @@
  package org.bigbluebutton.modules.phone.managers
 {
-  import com.asfusion.mate.events.Dispatcher; 
+  import com.asfusion.mate.events.Dispatcher;
+  
   import flash.external.ExternalInterface;
-  import flash.media.Microphone; 
+  import flash.media.Microphone;
+  
   import org.bigbluebutton.core.UsersUtil;
   import org.bigbluebutton.core.model.MeetingModel;
+  import org.bigbluebutton.main.api.JSLog;
   import org.bigbluebutton.modules.phone.PhoneOptions;
   import org.bigbluebutton.modules.phone.events.FlashCallConnectedEvent;
   import org.bigbluebutton.modules.phone.events.FlashCallDisconnectedEvent;
@@ -30,18 +33,18 @@
   {
     private static const LOG:String = "Phone::FlashCallManager - ";   
     
-    private static const INITED:String = "initialized state";
-    private static const DO_ECHO_TEST:String = "do echo test state";
-    private static const CALLING_INTO_ECHO_TEST:String = "calling into echo test state";
-    private static const IN_ECHO_TEST:String = "in echo test state";
-    private static const JOIN_VOICE_CONFERENCE:String = "join voice conference state";
-    private static const CALLING_INTO_CONFERENCE:String = "calling into conference state";
-    private static const IN_CONFERENCE:String = "in conference state";
-    private static const STOP_ECHO_THEN_JOIN_CONF:String = "stop echo then join conf state";
+    private static const INITED:String = "INITED";
+    private static const DO_ECHO_TEST:String = "DO_ECHO_TEST";
+    private static const CALLING_INTO_ECHO_TEST:String = "CALLING_INTO_ECHO_TEST";
+    private static const IN_ECHO_TEST:String = "IN_ECHO_TEST";
+    private static const JOIN_VOICE_CONFERENCE:String = "JOIN_VOICE_CONFERENCE";
+    private static const CALLING_INTO_CONFERENCE:String = "CALLING_INTO_CONFERENCE";
+    private static const IN_CONFERENCE:String = "IN_CONFERENCE";
+    private static const STOP_ECHO_THEN_JOIN_CONF:String = "STOP_ECHO_THEN_JOIN_CONF";
 
-    private static const CALL_TO_LISTEN_ONLY_STREAM:String = "call to listen only stream";
-    private static const CONNECTING_TO_LISTEN_ONLY_STREAM:String = "connecting to listen only stream";
-    private static const ON_LISTEN_ONLY_STREAM:String = "on listen only stream";
+    private static const CALL_TO_LISTEN_ONLY_STREAM:String = "CALL_TO_LISTEN_ONLY_STREAM";
+    private static const CONNECTING_TO_LISTEN_ONLY_STREAM:String = "CONNECTING_TO_LISTEN_ONLY_STREAM";
+    private static const ON_LISTEN_ONLY_STREAM:String = "ON_LISTEN_ONLY_STREAM";
 
     private var state:String = INITED;
     
@@ -95,13 +98,16 @@
       */
       if (mic) {
         if (options.skipCheck) {
+          JSLog.debug(LOG + "Calling into voice conference. skipCheck=[" + options.skipCheck + "] echoTestDone=[" + echoTestDone + "]");
           trace(LOG + "Calling into voice conference. skipCheck=[" + options.skipCheck + "] echoTestDone=[" + echoTestDone + "]");
           callIntoVoiceConference();
         } else {
+          JSLog.debug(LOG + "Performing echo test. echoTestDone=[" + echoTestDone + "]");
           trace(LOG + "Performing echo test. echoTestDone=[" + echoTestDone + "]");
           doEchoTest();
         }
       } else {
+        JSLog.debug(LOG + "Flash connecting to listen only voice conference");
         trace(LOG + "Flash connecting to listen only voice conference");
         joinListenOnlyCall();
       }
@@ -109,6 +115,7 @@
        
     private function joinListenOnlyCall():void {
       if (options.listenOnlyMode) {
+        JSLog.debug(LOG + "Joining listen only call");
         trace(LOG + "Joining listen only call");
         callToListenOnlyStream();
       }
@@ -116,6 +123,7 @@
 
     private function leaveListenOnlyCall():void {
       if (state == ON_LISTEN_ONLY_STREAM) {
+        JSLog.debug(LOG + "Leaving listen only call");
         trace(LOG + "Leaving listen only call");
         hangup();
       }
@@ -126,14 +134,17 @@
         var destination:String = UsersUtil.getVoiceBridge();
         
         if (destination != null && destination != "") {
+          JSLog.debug(LOG + "Connecting to listen only stream =[" + destination + "]");
           trace(LOG + "Connecting to listen only stream =[" + destination + "]");
           state = CONNECTING_TO_LISTEN_ONLY_STREAM;
           connectionManager.doCall(destination, true);
         } else {
+          JSLog.debug(LOG + "Invalid voice conference [" + destination + "]");
           trace(LOG + "Invalid voice conference [" + destination + "]");
           dispatcher.dispatchEvent(new FlashErrorEvent(FlashErrorEvent.INVALID_VOICE_DESTINATION));
         }
       } else {
+        JSLog.debug(LOG + "Need to connect before we can join the voice conference.");
         trace(LOG + "Need to connect before we can join the voice conference.");
         state = CALL_TO_LISTEN_ONLY_STREAM;
         connect();
@@ -145,14 +156,17 @@
         var destination:String = UsersUtil.getVoiceBridge();
         
         if (destination != null && destination != "") {
+          JSLog.debug(LOG + "Calling into voice conference =[" + destination + "]");
           trace(LOG + "Calling into voice conference =[" + destination + "]");
           state = CALLING_INTO_CONFERENCE;
           connectionManager.doCall(destination);             
         } else {
+          JSLog.debug(LOG + "Invalid voice conference [" + destination + "]");
           trace(LOG + "Invalid voice conference [" + destination + "]");
           dispatcher.dispatchEvent(new FlashErrorEvent(FlashErrorEvent.INVALID_VOICE_DESTINATION));
         }
       } else {
+        JSLog.debug(LOG + "Need to connect before we can join the voice conference.");
         trace(LOG + "Need to connect before we can join the voice conference.");
         state = JOIN_VOICE_CONFERENCE;
         connect();
@@ -163,14 +177,17 @@
       if (isConnected()) {
         var destination:String = options.echoTestApp;
         if (destination != null && destination != "") {
+          JSLog.debug(LOG + "Calling into echo test =[" + destination + "]");
           trace(LOG + "Calling into echo test =[" + destination + "]");
           state = CALLING_INTO_ECHO_TEST;
           connectionManager.doCall(destination);
         } else {
+          JSLog.debug(LOG + "Invalid echo test destination [" + destination + "]");
           trace(LOG + "Invalid echo test destination [" + destination + "]");
           dispatcher.dispatchEvent(new FlashErrorEvent(FlashErrorEvent.INVALID_ECHO_TEST_DESTINATION));
         }
       } else {
+        JSLog.debug(LOG + "Need to connect before we can call into echo test.");
         trace(LOG + "Need to connect before we can call into echo test.");
         state = DO_ECHO_TEST;
         connect();
@@ -179,11 +196,13 @@
     
     private function printMics():void {
       for (var i:int = 0; i < micNames.length; i++) {
+        JSLog.debug(LOG + "*** MIC [" + i + "] = [" + micNames[i] + "]");
         trace(LOG + "*** MIC [" + i + "] = [" + micNames[i] + "]");
       }
     }
     
     public function userRequestedHangup():void {
+      JSLog.debug(LOG + "userRequestedHangup, current state: " + state);
       trace(LOG + "userRequestedHangup, current state: " + state);
       if (usingFlash || state == ON_LISTEN_ONLY_STREAM) {
         streamManager.stopStreams();
@@ -202,27 +221,32 @@
     }
     
     private function hangup():void {
+      JSLog.debug(LOG + "hangup, current state: " + state);
       trace(LOG + "hangup, current state: " + state);
       streamManager.stopStreams();
       connectionManager.doHangUp();
     }
     
     private function hangupEchoThenJoinVoiceConference():void {
+      JSLog.debug(LOG + "hangup EchoThenJoinVoiceConference, current state: " + state);
       trace(LOG + "hangup EchoThenJoinVoiceConference, current state: " + state);
       state = STOP_ECHO_THEN_JOIN_CONF;
       hangup();
     }
     
     public function handleFlashStartEchoTestCommand(event:FlashStartEchoTestCommand):void {
+      JSLog.debug(LOG + "handling FlashStartEchoTestCommand. mic index=[" + event.micIndex + "] name=[" + event.micName + "]");
       trace(LOG + "handling FlashStartEchoTestCommand. mic index=[" + event.micIndex + "] name=[" + event.micName + "]");
       useMicIndex = event.micIndex;
       useMicName = event.micName;
+      JSLog.debug(LOG + "Setting up preferred micriphone.");
       trace(LOG + "Setting up preferred micriphone.");
       streamManager.usePreferredMic(event.micIndex, event.micName);
       callIntoEchoTest();
     }
     
     public function handleFlashStopEchoTestCommand(event:FlashStopEchoTestCommand):void {
+      JSLog.debug(LOG + "handling FlashStopEchoTestCommand, current state: " + state);
       trace(LOG + "handling FlashStopEchoTestCommand, current state: " + state);
       if (state == IN_ECHO_TEST) {
          hangup();
@@ -235,6 +259,7 @@
     }
     
     public function handleFlashEchoTestHasAudioEvent(event:FlashEchoTestHasAudioEvent):void {
+      JSLog.debug(LOG + "handling handleFlashEchoTestHasAudioEvent, current state: " + state);
       trace(LOG + "handling handleFlashEchoTestHasAudioEvent, current state: " + state);
       if (state == IN_ECHO_TEST) {
         hangupEchoThenJoinVoiceConference();
@@ -245,6 +270,7 @@
     }
     
     public function handleFlashEchoTestNoAudioEvent(event:FlashEchoTestNoAudioEvent):void {
+      JSLog.debug(LOG + "handling FlashEchoTestNoAudioEvent, current state: " + state);
       trace(LOG + "handling FlashEchoTestNoAudioEvent, current state: " + state);
       if (state == IN_ECHO_TEST) {
         hangup();
@@ -253,15 +279,18 @@
     }
     
     public function handleFlashCallConnectedEvent(event:FlashCallConnectedEvent):void {      
+      JSLog.debug(LOG + "handling FlashCallConnectedEvent, current state: " + state);
       trace(LOG + "handling FlashCallConnectedEvent, current state: " + state);
       switch (state) {
         case CALLING_INTO_CONFERENCE:
+          JSLog.debug(LOG + "Successfully joined the voice conference.");
           trace(LOG + "Successfully joined the voice conference.");
           state = IN_CONFERENCE;
           dispatcher.dispatchEvent(new FlashJoinedVoiceConferenceEvent());
           streamManager.callConnected(event.playStreamName, event.publishStreamName, event.codec, event.listenOnlyCall);
           break;
         case CONNECTING_TO_LISTEN_ONLY_STREAM:
+          JSLog.debug(LOG + "Successfully connected to the listen only stream.");
           trace(LOG + "Successfully connected to the listen only stream.");
           state = ON_LISTEN_ONLY_STREAM;
           dispatcher.dispatchEvent(new FlashJoinedListenOnlyVoiceConferenceEvent());
@@ -270,18 +299,22 @@
         case CALLING_INTO_ECHO_TEST:
           state = IN_ECHO_TEST;
           trace(LOG + "Successfully called into the echo test application.  [" + event.publishStreamName + "] : [" + event.playStreamName + "] : [" + event.codec + "]");
+          JSLog.debug(LOG + "Successfully called into the echo test application.  [" + event.publishStreamName + "] : [" + event.playStreamName + "] : [" + event.codec + "]");
           streamManager.callConnected(event.playStreamName, event.publishStreamName, event.codec, event.listenOnlyCall);
           
+          JSLog.debug(LOG + "Successfully called into the echo test application.");
           trace(LOG + "Successfully called into the echo test application.");
           dispatcher.dispatchEvent(new FlashEchoTestStartedEvent());
           break;
         default:
+          JSLog.debug(LOG + "unhandled state: " + state);
           trace(LOG + "unhandled state: " + state);
           break;
       }      
     }
 
     public function handleFlashCallDisconnectedEvent(event:FlashCallDisconnectedEvent):void {
+      JSLog.debug(LOG + "Flash call disconnected, current state: " + state);
       trace(LOG + "Flash call disconnected, current state: " + state);
       switch (state) {
         case IN_CONFERENCE:
@@ -290,46 +323,55 @@
           break;
         case ON_LISTEN_ONLY_STREAM:
           state = INITED;
+          JSLog.debug(LOG + "Flash user left the listen only stream.");
           trace(LOG + "Flash user left the listen only stream.");
 		      dispatcher.dispatchEvent(new FlashLeftVoiceConferenceEvent());
           break;
         case IN_ECHO_TEST:
           state = INITED;
+          JSLog.debug(LOG + "Flash echo test stopped.");
           trace(LOG + "Flash echo test stopped.");
           dispatcher.dispatchEvent(new FlashEchoTestStoppedEvent());
           break;
         case STOP_ECHO_THEN_JOIN_CONF:
+          JSLog.debug(LOG + "Flash echo test stopped, now joining the voice conference.");
           trace(LOG + "Flash echo test stopped, now joining the voice conference.");
           callIntoVoiceConference();
           break;
         case CALLING_INTO_ECHO_TEST:
           state = INITED;
+          JSLog.debug(LOG + "Unsuccessfully called into the echo test application.");
           trace(LOG + "Unsuccessfully called into the echo test application.");
           dispatcher.dispatchEvent(new FlashEchoTestFailedEvent());
           break;
         default:
+          JSLog.debug(LOG + "unhandled state: " + state);
           trace(LOG + "unhandled state: " + state);
           break;
       }
     }
     
     public function handleJoinVoiceConferenceCommand(event:JoinVoiceConferenceCommand):void {
+      JSLog.debug(LOG + "Handling JoinVoiceConferenceCommand.");
       trace(LOG + "Handling JoinVoiceConferenceCommand.");
       switch(state) {
         case INITED:
           if (usingFlash || !event.mic) {
             startCall(event.mic);
           } else {
+            JSLog.debug(LOG + "ignoring join voice conf as usingFlash=[" + usingFlash + "] or eventMic=[" + !event.mic + "]");
             trace(LOG + "ignoring join voice conf as usingFlash=[" + usingFlash + "] or eventMic=[" + !event.mic + "]");
           }
           break;
 		
         default:
+          JSLog.debug("Ignoring join voice as state=[" + state + "]");
           trace("Ignoring join voice as state=[" + state + "]");
       }
     }
     
     public function handleLeaveVoiceConferenceCommand(event:LeaveVoiceConferenceCommand):void {
+      JSLog.debug(LOG + "Handling LeaveVoiceConferenceCommand, current state: " + state + ", using flash: " + usingFlash);
       trace(LOG + "Handling LeaveVoiceConferenceCommand, current state: " + state + ", using flash: " + usingFlash);
       if (!usingFlash && state != ON_LISTEN_ONLY_STREAM) {
         // this is the case when the user was connected to webrtc and then leaves the conference
@@ -339,12 +381,13 @@
     }
     
 	public function handleBecomeViewer():void {
-		trace(LOG + "Handling BecomeViewer, current state: " + state + ", using flash: " + usingFlash);
-		
+    JSLog.debug(LOG + "Handling BecomeViewer, current state: " + state + ", using flash: " + usingFlash);
+    trace(LOG + "Handling BecomeViewer, current state: " + state + ", using flash: " + usingFlash);
 		if (options.presenterShareOnly) {
 			if (!usingFlash || state != IN_CONFERENCE || UsersUtil.amIModerator()) return;
 			
-			trace(LOG + "handleBecomeViewer leaving flash with mic and joining listen only stream");
+      JSLog.debug(LOG + "handleBecomeViewer leaving flash with mic and joining listen only stream");
+      trace(LOG + "handleBecomeViewer leaving flash with mic and joining listen only stream");
 			hangup();
 			
 			var command:JoinVoiceConferenceCommand = new JoinVoiceConferenceCommand();
@@ -354,6 +397,7 @@
 	}
 	
     public function handleFlashVoiceConnectionStatusEvent(event:FlashVoiceConnectionStatusEvent):void {
+      JSLog.debug(LOG + "Connection status event. status=[" + event.status + "]");
       trace(LOG + "Connection status event. status=[" + event.status + "]");
       if (event.status == FlashVoiceConnectionStatusEvent.CONNECTED) {
         switch (state) {
@@ -367,6 +411,7 @@
             callToListenOnlyStream();
             break;
           default:
+            JSLog.debug(LOG + "unhandled state: " + state);
             trace(LOG + "unhandled state: " + state);
             break;
         }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/StreamManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/StreamManager.as
index 62b8640a87854881f6604921a87f453471765f43..61c54e7b645cbacf6162a29938275cba347ac364 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/StreamManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/StreamManager.as
@@ -18,7 +18,8 @@
 */
 
 package org.bigbluebutton.modules.phone.managers {
-	import com.asfusion.mate.events.Dispatcher;	
+	import com.asfusion.mate.events.Dispatcher;
+	
 	import flash.events.ActivityEvent;
 	import flash.events.AsyncErrorEvent;
 	import flash.events.IEventDispatcher;
@@ -29,9 +30,11 @@ package org.bigbluebutton.modules.phone.managers {
 	import flash.media.MicrophoneEnhancedOptions;
 	import flash.media.SoundCodec;
 	import flash.net.NetConnection;
-	import flash.net.NetStream;	
+	import flash.net.NetStream;
+	
 	import org.bigbluebutton.common.LogUtil;
 	import org.bigbluebutton.core.BBB;
+	import org.bigbluebutton.main.api.JSLog;
 	import org.bigbluebutton.main.events.BBBEvent;
 	import org.bigbluebutton.modules.phone.PhoneOptions;
 	import org.bigbluebutton.modules.phone.events.FlashMicAccessAllowedEvent;
@@ -67,7 +70,8 @@ package org.bigbluebutton.modules.phone.managers {
       this.micName = micName;
       mic = Microphone.getMicrophone(micIndex);
       if(mic != null){
-        trace(LOG + "Setting up preferred microphone");
+        trace(LOG + "Setting up preferred microphone [" + micName + "]");
+        JSLog.debug(LOG + "Setting up preferred microphone [" + micName + "]");
         setupMicrophone();
         mic.addEventListener(StatusEvent.STATUS, micStatusHandler);
       }
@@ -78,7 +82,8 @@ package org.bigbluebutton.modules.phone.managers {
       
 			if(mic != null){
 				this.micIndex = mic.index;
-			  trace(LOG + "Setting up default microphone");
+			  trace(LOG + "Setting up default microphone [" + micName + "]");
+        JSLog.debug(LOG + "Setting up default microphone [" + micName + "]");
 				setupMicrophone();
 				mic.addEventListener(StatusEvent.STATUS, micStatusHandler);
 			}
@@ -134,6 +139,7 @@ package org.bigbluebutton.modules.phone.managers {
 		}
 										
 		public function callConnected(playStreamName:String, publishStreamName:String, codec:String, listenOnlyCall:Boolean):void {
+      JSLog.debug(LOG + "setting up streams. [" + playStreamName + "] : [" + publishStreamName + "] : [" + codec + "]");
       trace(LOG + "setting up streams. [" + playStreamName + "] : [" + publishStreamName + "] : [" + codec + "]");
 			isCallConnected = true;
 			audioCodec = codec;
@@ -142,7 +148,8 @@ package org.bigbluebutton.modules.phone.managers {
 			if (mic != null && !listenOnlyCall) {
 				setupOutgoingStream();
 			} else {
-				trace(LOG + "not setting up an outgoing stream because I'm in listen only mode");
+        JSLog.debug(LOG + "not setting up an outgoing stream because I'm in listen only mode");
+        trace(LOG + "not setting up an outgoing stream because I'm in listen only mode");
 			}
 
 			setupPlayStatusHandler();
@@ -151,6 +158,7 @@ package org.bigbluebutton.modules.phone.managers {
 				publish(publishStreamName);
 			} else {
 				trace(LOG + "not publishing any stream because I'm in listen only mode");
+        JSLog.debug(LOG + "not publishing any stream because I'm in listen only mode");
 			}
 		}
 		
@@ -162,12 +170,14 @@ package org.bigbluebutton.modules.phone.managers {
 			if (mic != null) {
         outgoingStream.publish(publishStreamName, "live");
       } else {
+        JSLog.debug(LOG + " publish: No Microphone to publish");
         trace(LOG + " publish: No Microphone to publish");
         dispatcher.dispatchEvent(new FlashMicUnavailableEvent());
       }     
 		}
 		
 		private function setupIncomingStream():void {
+      JSLog.debug(LOG + " setting up incoming stream");
       trace(LOG + " setting up incoming stream");
 			incomingStream = new NetStream(connManager.getConnection());
 			incomingStream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
@@ -186,6 +196,7 @@ package org.bigbluebutton.modules.phone.managers {
 		}
 		
 		private function setupOutgoingStream():void {
+      JSLog.debug(LOG + " setting up outgoing stream");
       trace(LOG + " setting up outgoing stream");
 			outgoingStream = new NetStream(connManager.getConnection());
 			outgoingStream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
@@ -208,26 +219,32 @@ package org.bigbluebutton.modules.phone.managers {
 			trace(LOG + "Stopping Stream(s)");
 			if(incomingStream != null) {
 				trace(LOG + "--Stopping Incoming Stream");
+        JSLog.debug(LOG + "--Stopping Incoming Stream");
         incomingStream.close(); 
 			} else {
 				trace(LOG + "--Incoming Stream Null");
+        JSLog.debug(LOG + "--Incoming Stream Null");
 			}
 			
 			if(outgoingStream != null) {
 				trace(LOG + "--Stopping Outgoing Stream");
+        JSLog.debug(LOG + "--Stopping Outgoing Stream");
 				outgoingStream.attachAudio(null);
 				outgoingStream.close();
 			} else {
 				trace(LOG + "--Outgoing Stream Null");
+        JSLog.debug(LOG + "--Outgoing Stream Null");
 			}
 				
 			isCallConnected = false;
 			trace(LOG + "Stopped Stream(s)");
+      JSLog.debug(LOG + "Stopped Stream(s)");
 		}
 
 		private function netStatus (evt:NetStatusEvent ):void {		 
 			var event:PlayStreamStatusEvent = new PlayStreamStatusEvent();
-			trace(LOG + "******* evt.info.code  " + evt.info.code);
+      JSLog.debug(LOG + "******* evt.info.code  " + evt.info.code);
+      trace(LOG + "******* evt.info.code  " + evt.info.code);
 			switch(evt.info.code) {			
 				case "NetStream.Play.StreamNotFound":
 					event.status = PlayStreamStatusEvent.PLAY_STREAM_STATUS_EVENT;
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 d8d13ce32849c3f00aed0c7a8b5e791b2a524d74..fabe870e367750a547de4541a33662a3153c3e5b 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/WebRTCCallManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/WebRTCCallManager.as
@@ -23,6 +23,7 @@ package org.bigbluebutton.modules.phone.managers
   import org.bigbluebutton.modules.phone.events.WebRTCAskUserToChangeMicEvent;
   import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
   import org.bigbluebutton.modules.phone.events.WebRTCEchoTestStartedEvent;
+  import org.bigbluebutton.modules.phone.events.WebRTCJoinedVoiceConferenceEvent;
   import org.bigbluebutton.modules.phone.events.WebRTCMediaEvent;
   import org.bigbluebutton.modules.phone.models.Constants;
   import org.bigbluebutton.modules.phone.models.WebRTCModel;
@@ -106,10 +107,14 @@ package org.bigbluebutton.modules.phone.managers
     public function handleWebRTCCallStartedEvent():void {
 	    trace(LOG + "setting state to IN_CONFERENCE");
       model.state = Constants.IN_CONFERENCE;
+      dispatcher.dispatchEvent(new WebRTCJoinedVoiceConferenceEvent());
+      
     }
     
     public function handleWebRTCCallEndedEvent():void {
       model.state = Constants.INITED;
+      
+      
     }
     
     private function joinVoiceConference():void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/views/components/ToolbarButton.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/views/components/ToolbarButton.mxml
index e026628984595fa917891c18569ab21dc78866e5..1f731da0fc05000223bc40233ae00361adba4541 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/views/components/ToolbarButton.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/views/components/ToolbarButton.mxml
@@ -24,7 +24,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
            styleName="voiceConfDefaultButtonStyle" click="startPhone()"
 	mouseOver = "mouseOverHandler(event)"
 	mouseOut = "mouseOutHandler(event)"
-	addedToStage="addedToStageHandler(event)"
+	creationComplete="onCreationComplete()"
 	height="24"
 	toolTip="{ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start')}"
 	implements="org.bigbluebutton.common.IBbbToolbarComponent">
@@ -38,27 +38,26 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
   
 	<mx:Script>
 		<![CDATA[
-			import com.asfusion.mate.events.Dispatcher;
-			
-			import flash.system.Security;
-			import flash.system.SecurityPanel;
-			
-			import org.bigbluebutton.common.LogUtil;
-			import org.bigbluebutton.core.BBB;
-			import org.bigbluebutton.main.events.BBBEvent;
-			import org.bigbluebutton.main.events.ShortcutEvent;
-			import org.bigbluebutton.main.views.MainToolbar;
-			import org.bigbluebutton.modules.phone.PhoneOptions;
-			import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
-			import org.bigbluebutton.modules.phone.events.FlashJoinedListenOnlyVoiceConferenceEvent;
-			import org.bigbluebutton.modules.phone.events.FlashJoinedVoiceConferenceEvent;
-			import org.bigbluebutton.modules.phone.events.FlashLeftVoiceConferenceEvent;
-			import org.bigbluebutton.modules.phone.events.FlashStopEchoTestCommand;
-			import org.bigbluebutton.modules.phone.events.JoinVoiceConferenceCommand;
-			import org.bigbluebutton.modules.phone.events.LeaveVoiceConferenceCommand;
-			import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
-			import org.bigbluebutton.modules.phone.views.assets.Images;
-			import org.bigbluebutton.util.i18n.ResourceUtil;
+      import com.asfusion.mate.events.Dispatcher;     
+      import flash.system.Security;
+      import flash.system.SecurityPanel;     
+      import org.bigbluebutton.common.LogUtil;
+      import org.bigbluebutton.core.BBB;
+      import org.bigbluebutton.main.api.JSLog;
+      import org.bigbluebutton.main.events.BBBEvent;
+      import org.bigbluebutton.main.events.ShortcutEvent;
+      import org.bigbluebutton.main.views.MainToolbar;
+      import org.bigbluebutton.modules.phone.PhoneOptions;
+      import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
+      import org.bigbluebutton.modules.phone.events.FlashJoinedListenOnlyVoiceConferenceEvent;
+      import org.bigbluebutton.modules.phone.events.FlashJoinedVoiceConferenceEvent;
+      import org.bigbluebutton.modules.phone.events.FlashLeftVoiceConferenceEvent;
+      import org.bigbluebutton.modules.phone.events.FlashStopEchoTestCommand;
+      import org.bigbluebutton.modules.phone.events.JoinVoiceConferenceCommand;
+      import org.bigbluebutton.modules.phone.events.LeaveVoiceConferenceCommand;
+      import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
+      import org.bigbluebutton.modules.phone.views.assets.Images;
+      import org.bigbluebutton.util.i18n.ResourceUtil;
 			
       private static const LOG:String = "Phone::ToolbarButton - ";
       
@@ -73,18 +72,21 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			private function startPhone():void {
 				trace(LOG + "startPhone 1 enabled=[" + enabled + "] selected=[" + selected + "]");
+        JSLog.debug(LOG + "startPhone 1 enabled=[" + enabled + "] selected=[" + selected + "]");
 				// Disable the button right away to prevent the user from clicking
 				// multiple times.
 				this.enabled = false;
 				trace(LOG + "startPhone 2 enabled=[" + enabled + "] selected=[" + selected + "]");
-        
+        JSLog.debug(LOG + "startPhone 2 enabled=[" + enabled + "] selected=[" + selected + "]");
 				if (this.selected) {
 					//trace(LOG + "Sending Join Conference command");
 					//dispatcher.dispatchEvent(new JoinVoiceConferenceCommand());
 					trace(LOG + "Sending Show Audio Selection command");
+          JSLog.debug(LOG + "Sending Show Audio Selection command");
 					dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.SHOW_AUDIO_SELECTION));
 				} else {
 					trace(LOG + "Sending Leave Conference command");
+          JSLog.debug(LOG + "Sending Leave Conference command");
 					dispatcher.dispatchEvent(new LeaveVoiceConferenceCommand());
 				}				
 			}
@@ -109,7 +111,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
           this.styleName = "voiceConfDefaultButtonStyle";			
 			}
 			
-			private function addedToStageHandler(event:Event):void {
+			private function onCreationComplete():void {
 				// when the button is added to the stage display the audio selection window if auto join is true
 				if (phoneOptions.autoJoin) {
           if (phoneOptions.skipCheck) {
@@ -122,6 +124,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
             dispatcher.dispatchEvent(command);            
           } else {
             trace(LOG + "Sending Show Audio Selection command");
+            JSLog.debug(LOG + "Sending Show Audio Selection command");
             dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.SHOW_AUDIO_SELECTION));            
           }
 				}
@@ -131,8 +134,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         this.selected = true;
         this.enabled = true;
 
+        JSLog.debug(LOG + "onUserJoinedConference enabled=[" + enabled + "] selected=[" + selected + "]");
         trace(LOG + "onUserJoinedConference enabled=[" + enabled + "] selected=[" + selected + "]");
-        
         _currentState = ACTIVE_STATE;
         this.styleName = "voiceConfActiveButtonStyle";
         this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.stop');	        
@@ -142,33 +145,39 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         this.selected = false;
         this.enabled = true;
         trace(LOG + "onUserLeftConference enabled=[" + enabled + "] selected=[" + selected + "]");
-        
+        JSLog.debug(LOG + "onUserLeftConference enabled=[" + enabled + "] selected=[" + selected + "]");
         _currentState = DEFAULT_STATE;
         this.styleName = "voiceConfDefaultButtonStyle";
-        this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start');        
+        this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start');    
+        JSLog.debug(LOG + "onUserLeftConference enabled=[" + enabled + "] selected=[" + selected + "]");
       }
       
       private function handleFlashJoinedVoiceConferenceEvent(event:FlashJoinedVoiceConferenceEvent):void {
         trace(LOG + "User has joined the conference using flash");
+        JSLog.debug(LOG + "User has joined the conference using flash");
         onUserJoinedConference();
       }
       	
       private function handleFlashJoinedListenOnlyConferenceEvent(event:FlashJoinedListenOnlyVoiceConferenceEvent):void {
         trace(LOG + "User has joined the listen only conference using flash");
+        JSLog.debug(LOG + "User has joined the listen only conference using flash");
         onUserJoinedConference();
       }
       
       private function handleFlashLeftVoiceConferenceEvent(event:FlashLeftVoiceConferenceEvent):void {
         trace(LOG + "User has left the conference using flash");
+        JSLog.debug(LOG + "User has left the conference using flash");
         onUserLeftConference();
       }
       
       private function handleWebRTCCallStartedEvent(event: WebRTCCallEvent):void {
+        JSLog.debug(LOG + "User has joined the conference using webrtc");
         trace(LOG + "User has joined the conference using webrtc");
         onUserJoinedConference();
       }
 						
 			private function handleWebRTCCallEndedEvent(event:WebRTCCallEvent):void {
+        JSLog.debug(LOG + "User has left the conference using webrtc");
         trace(LOG + "User has left the conference using webrtc");
         onUserLeftConference();
 			}
@@ -176,8 +185,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private function handleClosedAudioSelectionWindowEvent(event:AudioSelectionWindowEvent):void {
 				this.selected = false;
 				this.enabled = true;
-				trace(LOG + "onClosedAudioSelection enabled=[" + enabled + "] selected=[" + selected + "]");
-				
+        JSLog.debug(LOG + "onClosedAudioSelection enabled=[" + enabled + "] selected=[" + selected + "]");
+        trace(LOG + "onClosedAudioSelection enabled=[" + enabled + "] selected=[" + selected + "]");
 				_currentState = DEFAULT_STATE;
         this.styleName = "voiceConfDefaultButtonStyle";
 				this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start');
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as
index 278b205f911a1e5f8f0efe6ea95e0af37713851f..63a64f599b02d93a8b1a71777048b86daa6c6bdc 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/FileUploadService.as
@@ -35,6 +35,7 @@ package org.bigbluebutton.modules.present.business
 	
 	public class FileUploadService {
 		public static const ID:String = "FileUploadService";
+		private static const LOG:String = "Present::FileUploadService - ";
 
 		public static const UPLOAD_PROGRESS:String = "UPLOAD_PROGRESS";
 		public static const UPLOAD_COMPLETED:String = "UPLOAD_COMPLETED";
@@ -120,7 +121,8 @@ package org.bigbluebutton.modules.present.business
 		 * 
 		 */
 		private function onUploadIoError(event:IOErrorEvent):void {
-			if(event["text"] != "Error #2038"){ //upload works despite of this error.
+			if(event.errorID != 2038){ //upload works despite of this error.
+				trace(LOG + "onUploadIoError text: " + event.text + ", errorID: " + event.errorID);
 				dispatcher.dispatchEvent(new UploadIoErrorEvent());
 			}
 			
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml
index 3e6e4280a6b08b8cfdc19db95e6723724ef58d3d..4dc0e17c8c350ecdb16e48d09bb0d79471ee8008 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml
@@ -310,12 +310,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                       styleName="presentationUploadProgressBarStyle" labelPlacement="center" width="460" visible="false"/>
     </mx:HBox>
 	<mx:Box width="100%" height="100%" paddingLeft="5" paddingRight="5">
-		<mx:Box width="100%" height="100%" verticalAlign="middle" styleName="presentationUploadFileFormatHintBoxStyle">
-	        <mx:Text width="100%" id="fileFormatHintLbl" text="{ResourceUtil.getInstance().getString('bbb.fileupload.fileFormatHint')}" styleName="presentationUploadFileFormatHintTextStyle"/>
+		<mx:Box width="100%" height="100%" verticalAlign="middle" horizontalAlign="center" styleName="presentationUploadFileFormatHintBoxStyle">
+	        <mx:Text width="100%" id="fileFormatHintLbl" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.fileupload.fileFormatHint')}" styleName="presentationUploadFileFormatHintTextStyle"/>
 		</mx:Box>
     </mx:Box>
-    <mx:Canvas width="100%" height="142" verticalScrollPolicy="off">
-      <mx:List width="100%" height="142" left="5" top="5" right="5" id="uploadedFilesList" alternatingItemColors="[#EFEFEF, #FEFEFE]" allowMultipleSelection="false"
+    <mx:Canvas width="100%" height="145" verticalScrollPolicy="off">
+      <mx:List width="100%" height="142" left="5" top="5" right="5" bottom="5" id="uploadedFilesList" alternatingItemColors="[#EFEFEF, #FEFEFE]" allowMultipleSelection="false"
                itemRenderer="org.bigbluebutton.modules.present.ui.views.UploadedPresentationRenderer"
                dragEnabled="false" dataProvider="{presentationNamesAC}">
       </mx:List>
diff --git a/bigbluebutton-client/transifex.sh b/bigbluebutton-client/transifex.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a08588e4ae57bd1e2ba44b46aef49cf860d24f53
--- /dev/null
+++ b/bigbluebutton-client/transifex.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+for i in * ; do
+        if [ -d "$i" ]; then
+                # echo "processing $i"
+                if [ -f $i.properties ]; then
+                        if [ "$1" == "-test" ]; then
+                                echo "mv -f $i.properties $i/bbbResources.properties"
+                        else
+                                #echo "no"
+                                mv -f $i.properties $i/bbbResources.properties
+                        fi
+                fi
+        fi
+done
+