diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java
index d5562595647c8e667561507bed7284bc40f206ea..ce1c25bb2329733c64c0dad0034ac1260f29e624 100755
--- a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java
+++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java
@@ -79,6 +79,9 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 		for (IConnection conn : conns) {
 			String connUserId = (String) conn.getAttribute("USERID");
 			String connSessionId = conn.getSessionId();
+			String clientId = conn.getClient().getId();
+			String remoteHost = conn.getRemoteAddress();
+			int remotePort = conn.getRemotePort();
 			if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
 				conn.removeAttribute("USERID");
 				Map<String, Object> logData = new HashMap<String, Object>();
@@ -86,6 +89,8 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 				logData.put("userId", userId);
 				logData.put("oldConnId", connSessionId);
 				logData.put("newConnId", sessionId);
+				logData.put("clientId", clientId);
+				logData.put("remoteAddress", remoteHost + ":" + remotePort);
 				logData.put("event", "removing_defunct_connection");
 				logData.put("description", "Removing defunct connection BBB Video.");
 
@@ -96,11 +101,17 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 			  }
 		  }
 
+	  String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
+	  int remotePort = Red5.getConnectionLocal().getRemotePort();
+	  String clientId = Red5.getConnectionLocal().getClient().getId();
+
 		Map<String, Object> logData = new HashMap<String, Object>();
 		logData.put("meetingId", meetingId);
 		logData.put("userId", userId);
 		logData.put("connType", connType);
 		logData.put("connId", sessionId);
+	  logData.put("clientId", clientId);
+	  logData.put("remoteAddress", remoteHost + ":" + remotePort);
 		logData.put("event", "user_joining_bbb_video");
 		logData.put("description", "User joining BBB Video.");
 
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java
index ee600aab123798fba46d0dfd44e3963eba47a1ec..d508fa1f8f88316f7d5977935295fffc5e1d1673 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java
@@ -138,6 +138,9 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
 		for (IConnection conn : conns) {
 			String connUserId = (String) conn.getAttribute("INTERNAL_USER_ID");
 			String connSessionId = conn.getSessionId();
+			String clientId = conn.getClient().getId();
+			String remoteHost = connection.getRemoteAddress();
+			int remotePort = connection.getRemotePort();
 			if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
 				conn.removeAttribute("INTERNAL_USER_ID");
 				Map<String, Object> logData = new HashMap<String, Object>();
@@ -145,6 +148,8 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
 				logData.put("userId", userId);
 				logData.put("oldConnId", connSessionId);
 				logData.put("newConnId", sessionId);
+				logData.put("clientId", clientId);
+				logData.put("remoteAddress", remoteHost + ":" + remotePort);
 				logData.put("event", "removing_defunct_connection");
 				logData.put("description", "Removing defunct connection BBB Apps.");
 
@@ -173,14 +178,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
 	    String connId = Red5.getConnectionLocal().getSessionId();	        
 		
 		String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
-		int remotePort = Red5.getConnectionLocal().getRemotePort();   
-
+		int remotePort = Red5.getConnectionLocal().getRemotePort();
+		String clientId = Red5.getConnectionLocal().getClient().getId();
 
 		Map<String, Object> logData = new HashMap<String, Object>();
 		logData.put("meetingId", meetingId);
 		logData.put("connType", connType);
 		logData.put("connId", connId);
-		logData.put("conn", remoteHost + ":" + remotePort);
+		logData.put("clientId", clientId);
+		logData.put("remoteAddress", remoteHost + ":" + remotePort);
 		logData.put("userId", userId);
 		logData.put("externalUserId", externalUserID);
 		logData.put("sessionId", sessionId);
@@ -222,14 +228,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
 	    String connType = getConnectionType(Red5.getConnectionLocal().getType());
 	    String userFullname = bbbSession.getUsername();
 	    String connId = Red5.getConnectionLocal().getSessionId();
-	    
+		String clientId = Red5.getConnectionLocal().getClient().getId();
         String sessionId =  CONN + userId;
 	    	    
 	    Map<String, Object> logData = new HashMap<String, Object>();
 	    logData.put("meetingId", meetingId);
 	    logData.put("connType", connType);
 	    logData.put("connId", connId);
-	    logData.put("conn", remoteHost + ":" + remotePort);
+		logData.put("clientId", clientId);
+		logData.put("remoteAddress", remoteHost + ":" + remotePort);
 	    logData.put("sessionId", sessionId);
 	    logData.put("userId", userId);
 	    logData.put("username", userFullname);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as
index 1c4f27e3a64fd24ad8cc41d782fa9c997af2453d..0ab10e7dd69c7bb9a315d0c64506df1de94039fd 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as
@@ -144,7 +144,7 @@ package org.bigbluebutton.main.model
 			try {
                 var logData:Object = UsersUtil.initLogData();
                 logData.connection = this.baseURI;
-                logData.tags = ["connection"];
+                logData.tags = ["initialization", "port-test", "connection"];
                 logData.message = "Port testing connection.";
                 LOGGER.info(JSON.stringify(logData));
         
@@ -168,7 +168,7 @@ package org.bigbluebutton.main.model
 		public function connectionTimeout (e:TimerEvent) : void {
             var logData:Object = UsersUtil.initLogData();
             logData.connection = this.baseURI;
-            logData.tags = ["connection"];
+            logData.tags = ["initialization", "port-test", "connection"];
             logData.message = "Port testing connection timedout.";
             LOGGER.info(JSON.stringify(logData));
 
@@ -200,7 +200,7 @@ package org.bigbluebutton.main.model
     private function closeConnectionTimerHandler (e:TimerEvent) : void {
         var logData:Object = UsersUtil.initLogData();
         logData.connection = this.baseURI;
-        logData.tags = ["connection"];
+        logData.tags = ["initialization", "port-test", "connection"];
         logData.message = "Closing port testing connection.";
         LOGGER.info(JSON.stringify(logData));
 
@@ -222,7 +222,7 @@ package org.bigbluebutton.main.model
             
         var logData:Object = UsersUtil.initLogData();
         logData.connection = this.baseURI;
-        logData.tags = ["connection"];
+        logData.tags = ["initialization", "port-test", "connection"];
 
         
         if ( statusCode == "NetConnection.Connect.Success" ) {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as
index a5cac6a9fd97a0b856f979517fbf51c55f2f45c7..ce92a8f875ecc6cbc3694b8dc4088c27cf00356c 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as
@@ -70,15 +70,18 @@ package org.bigbluebutton.main.model.modules
         var dispatcher:Dispatcher = new Dispatcher();
         dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL));			
       } else if (returncode == 'SUCCESS') {
-        logData.tags = ["initialization"];
-        logData.message = "Enter API call succeeded.";
-        LOGGER.info(JSON.stringify(logData));
+
           
         var response:Object = new Object();
         response.username = result.response.fullname;
         response.userId = result.response.internalUserID;
         response.meetingName = result.response.confname;
         response.meetingId = result.response.meetingID;
+        
+        logData.response = response;
+        logData.tags = ["initialization"];
+        logData.message = "Enter API call succeeded.";
+        LOGGER.info(JSON.stringify(logData));
          
         if (_resultListener != null) _resultListener(true, response);
       }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as
index 7b5cad45d88fa94b13458a3bf211cfa1104c1c06..35356beada6d35a34519df52d06e0702e15b564e 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as
@@ -26,7 +26,7 @@ package org.bigbluebutton.main.model.users
 	import flash.events.TimerEvent;
 	import flash.net.NetConnection;
 	import flash.net.Responder;
-	import flash.utils.Timer;	
+	import flash.utils.Timer;
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
 	import org.bigbluebutton.core.BBB;
@@ -40,358 +40,396 @@ package org.bigbluebutton.main.model.users
 	import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
 	import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
   
-	public class NetConnectionDelegate
-	{
-		private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate);
-		
-		private var _netConnection:NetConnection;	
-		private var connectionId:Number;
-		private var connected:Boolean = false;
-		
-		private var _userid:Number = -1;
-		private var _role:String = "unknown";
-		
-		private var logoutOnUserCommand:Boolean = false;
-		private var dispatcher:Dispatcher;    
-    private var _messageListeners:Array = new Array();
-    
-    private var authenticated: Boolean = false;
-    private var reconnecting:Boolean = false;
-	private var numNetworkChangeCount:int = 0;
-	
-		private var _validateTokenTimer:Timer = null;	
-	
-		public function NetConnectionDelegate():void {
-			dispatcher = new Dispatcher();
-		}
-		  
-		public function get connection():NetConnection {
-			return _netConnection;
-		}
+    public class NetConnectionDelegate {
+        private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate);
+
+        private var _netConnection:NetConnection;	
+        private var connectionId:Number;
+        private var connected:Boolean = false;
+        private var _userid:Number = -1;
+        private var _role:String = "unknown";
+        private var logoutOnUserCommand:Boolean = false;
+        private var dispatcher:Dispatcher;    
+        private var _messageListeners:Array = new Array();
+        private var authenticated: Boolean = false;
+        private var reconnecting:Boolean = false;
         
-    public function addMessageListener(listener:IMessageListener):void {
-      _messageListeners.push(listener);
-    }
+        private var maxConnectAttempt:int = 2;
+        private var connectAttemptCount:int = 0;
+        private var connectAttemptTimeout:Number = 5000;
+        private var connectionTimer:Timer;
+    
+        private var numNetworkChangeCount:int = 0;
+        private var _validateTokenTimer:Timer = null;
+
+        private var bbbAppsUrl: String = null;
         
-    public function removeMessageListener(listener:IMessageListener):void {
-      for (var ob:int=0; ob<_messageListeners.length; ob++) {
-        if (_messageListeners[ob] == listener) {
-          _messageListeners.splice (ob,1);
-          break;
+        public function NetConnectionDelegate():void {
+            dispatcher = new Dispatcher();
         }
-      }
-    }
+
         
-    private function notifyListeners(messageName:String, message:Object):void {
-      if (messageName != null && messageName != "") {
-        for (var notify:String in _messageListeners) {
-          _messageListeners[notify].onMessage(messageName, message);
-        }                
-      } else {
-		  LOGGER.debug("Message name is undefined");
-      }
-    }   
+        public function get connection():NetConnection {
+            return _netConnection;
+        }
+            
+        public function addMessageListener(listener:IMessageListener):void {
+          _messageListeners.push(listener);
+        }
+            
+        public function removeMessageListener(listener:IMessageListener):void {
+          for (var ob:int=0; ob<_messageListeners.length; ob++) {
+            if (_messageListeners[ob] == listener) {
+              _messageListeners.splice (ob,1);
+              break;
+            }
+          }
+        }
+            
+        private function notifyListeners(messageName:String, message:Object):void {
+          if (messageName != null && messageName != "") {
+            for (var notify:String in _messageListeners) {
+              _messageListeners[notify].onMessage(messageName, message);
+            }                
+          } else {
+            LOGGER.debug("Message name is undefined");
+          }
+        }   
+            
+        public function onMessageFromServer(messageName:String, msg:Object):void {
+          if (!authenticated && (messageName == "validateAuthTokenReply")) {
+            handleValidateAuthTokenReply(msg)
+          } else if (messageName == "validateAuthTokenTimedOut") {
+            handleValidateAuthTokenTimedOut(msg)
+          } else if (authenticated) {
+            notifyListeners(messageName, msg);
+          } else {
+            LOGGER.debug("Ignoring message=[{0}] as our token hasn't been validated yet.", [messageName]);
+          }     
+        }
+
+        private function validataTokenTimerHandler(event:TimerEvent):void {
+            var logData:Object = UsersUtil.initLogData();
+            logData.tags = ["apps"];
+            logData.key = "validate_token_request_timedout";
+            logData.message = "No response for validate token request.";
+            LOGGER.info(JSON.stringify(logData));
+        }
+
+        private function validateToken():void {
+            var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams();
+          
+            var message:Object = new Object();
+            message["userId"] = confParams.internalUserID;
+            message["authToken"] = confParams.authToken;
+          
+            _validateTokenTimer = new Timer(7000, 1);
+            _validateTokenTimer.addEventListener(TimerEvent.TIMER, validataTokenTimerHandler);
+            _validateTokenTimer.start();
+          
+            sendMessage(
+                "validateToken",// Remote function name
+                // result - On successful result
+                function(result:Object):void { 
+              
+                },
+                // status - On error occurred
+                function(status:Object):void {
+                    LOGGER.error("Error occurred:");
+                    for (var x:Object in status) {
+                        LOGGER.error(x + " : " + status[x]);
+                    } 
+                },
+                message
+            ); //_netConnection.call      
+        }
         
-    public function onMessageFromServer(messageName:String, msg:Object):void {
-      if (!authenticated && (messageName == "validateAuthTokenReply")) {
-        handleValidateAuthTokenReply(msg)
-      } else if (messageName == "validateAuthTokenTimedOut") {
-        handleValidateAuthTokenTimedOut(msg)
-      } else if (authenticated) {
-        notifyListeners(messageName, msg);
-      } else {
-        LOGGER.debug("Ignoring message=[{0}] as our token hasn't been validated yet.", [messageName]);
-      }     
-    }
-	
-	private function validataTokenTimerHandler(event:TimerEvent):void {
-		var logData:Object = UsersUtil.initLogData();
-        logData.tags = ["apps"];
-		logData.message = "No response for validate token request.";
-		LOGGER.info(JSON.stringify(logData));
-	}
-	
-    private function validateToken():void {
-      var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams();
-      
-      var message:Object = new Object();
-      message["userId"] = confParams.internalUserID;
-      message["authToken"] = confParams.authToken;
+        private function stopValidateTokenTimer():void {
+            if (_validateTokenTimer != null && _validateTokenTimer.running) {
+                _validateTokenTimer.stop();
+                _validateTokenTimer = null;
+            }
+        }
+
+        private function handleValidateAuthTokenTimedOut(msg: Object):void {  
+            stopValidateTokenTimer();
       
-	  _validateTokenTimer = new Timer(7000, 1);
-	  _validateTokenTimer.addEventListener(TimerEvent.TIMER, validataTokenTimerHandler);
-	  _validateTokenTimer.start();
-	  
-      sendMessage(
-        "validateToken",// Remote function name
-        // result - On successful result
-        function(result:Object):void { 
-          
-        },	
-        // status - On error occurred
-        function(status:Object):void {
-	      LOGGER.error("Error occurred:");
-          for (var x:Object in status) {
-			LOGGER.error(x + " : " + status[x]);
-          } 
-        },
-        message
-      ); //_netConnection.call      
-    }
-    
-	private function stopValidateTokenTimer():void {
-		if (_validateTokenTimer != null && _validateTokenTimer.running) {
-			_validateTokenTimer.stop();
-			_validateTokenTimer = null;
-		}		
-	}
-	
-    private function handleValidateAuthTokenTimedOut(msg: Object):void {  
-      stopValidateTokenTimer();
-	  
-      var map:Object = JSON.parse(msg.msg);  
-      var tokenValid: Boolean = map.valid as Boolean;
-      var userId: String = map.userId as String;
-
-      var logData:Object = UsersUtil.initLogData();
-      logData.tags = ["apps"];
-	  logData.message = "Validate auth token timed out.";
-	  LOGGER.info(JSON.stringify(logData));
-	  
-      if (tokenValid) {
-        authenticated = true;
-      } else {
-        dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
-      }
-	  if (reconnecting) {
-		  onReconnect();
-		  reconnecting = false;
-	  }
-    }
-    
-    private function handleValidateAuthTokenReply(msg: Object):void {  
-      stopValidateTokenTimer();
-		
-      var map:Object = JSON.parse(msg.msg);  
-      var tokenValid: Boolean = map.valid as Boolean;
-      var userId: String = map.userId as String;
+            var map:Object = JSON.parse(msg.msg);  
+            var tokenValid: Boolean = map.valid as Boolean;
+            var userId: String = map.userId as String;
+
+            var logData:Object = UsersUtil.initLogData();
+            logData.tags = ["apps", "connected"];
+            logData.tokenValid = tokenValid;
+            logData.key = "validate_token_response_received";
+            logData.message = "Validate auth token timed out.";
+            LOGGER.info(JSON.stringify(logData));
       
-      if (tokenValid) {
-        authenticated = true;
-      } else {
-        dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
-      }
-	  if (reconnecting) {
-		  onReconnect();
-		  reconnecting = false;
-	  }
-    }
+            if (tokenValid) {
+                authenticated = true;
+            } else {
+                dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
+            }
 
-	private function onReconnect():void {
-		if (authenticated) {
-			onReconnectSuccess();
-		} else {
-			onReconnectFailed();
-		}
-	}
-	
-    private function onReconnectSuccess():void {
-      var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
-      attemptSucceeded.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
-      dispatcher.dispatchEvent(attemptSucceeded);
-    }
+            if (reconnecting) {
+              onReconnect();
+              reconnecting = false;
+            }
+        }
+        
+        private function handleValidateAuthTokenReply(msg: Object):void {  
+            stopValidateTokenTimer();
 
-    private function onReconnectFailed():void {
-      sendUserLoggedOutEvent();
-    }
-    
-    private function sendConnectionSuccessEvent(userid:String):void{      
-      var e:UsersConnectionEvent = new UsersConnectionEvent(UsersConnectionEvent.CONNECTION_SUCCESS);
-      e.userid = userid;
-      dispatcher.dispatchEvent(e);
+            var map:Object = JSON.parse(msg.msg);  
+            var tokenValid: Boolean = map.valid as Boolean;
+            var userId: String = map.userId as String;
+ 
+            var logData:Object = UsersUtil.initLogData();
+            logData.tags = ["apps", "connected"];
+            logData.tokenValid = tokenValid;
+            logData.key = "validate_token_response_received";
+            logData.message = "Received validate token response from server.";
+            LOGGER.info(JSON.stringify(logData));
+            
+            if (tokenValid) {
+                authenticated = true;
+            } else {
+                dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
+            }
       
-    }
-    
-		public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object=null):void {
-			var responder:Responder =	new Responder(                    
-					function(result:Object):void { // On successful result
-						onSuccess("Successfully sent [" + service + "]."); 
-					},	                   
-					function(status:Object):void { // status - On error occurred
-						var errorReason:String = "Failed to send [" + service + "]:\n"; 
-						for (var x:Object in status) { 
-							errorReason += "\t" + x + " : " + status[x]; 
-						} 
-					}
-				);
-			
-			if (message == null) {
-				_netConnection.call(service, responder);			
-			} else {
-				_netConnection.call(service, responder, message);
-			}
-		}
-		
-		/**
-		 * Connect to the server.
-		 * uri: The uri to the conference application.
-		 * username: Fullname of the participant.
-		 * role: MODERATOR/VIEWER
-		 * conference: The conference room
-		 * mode: LIVE/PLAYBACK - Live:when used to collaborate, Playback:when being used to playback a recorded conference.
-		 * room: Need the room number when playing back a recorded conference. When LIVE, the room is taken from the URI.
-		 */
-		public function connect():void {	
-      var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams();
-			
-      _netConnection = new NetConnection();				
-      _netConnection.proxyType = "best";
-      _netConnection.client = this;
-      _netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
-      _netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, netASyncError );
-      _netConnection.addEventListener( SecurityErrorEvent.SECURITY_ERROR, netSecurityError );
-      _netConnection.addEventListener( IOErrorEvent.IO_ERROR, netIOError );
+            if (reconnecting) {
+              onReconnect();
+              reconnecting = false;
+            }
+        }
+
+        private function onReconnect():void {
+            if (authenticated) {
+                onReconnectSuccess();
+            } else {
+                onReconnectFailed();
+            }
+        }
+
+        private function onReconnectSuccess():void {
+            var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
+            attemptSucceeded.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
+            dispatcher.dispatchEvent(attemptSucceeded);
+        }
+
+        private function onReconnectFailed():void {
+            sendUserLoggedOutEvent();
+        }
+        
+        private function sendConnectionSuccessEvent(userid:String):void{      
+            var e:UsersConnectionEvent = new UsersConnectionEvent(UsersConnectionEvent.CONNECTION_SUCCESS);
+            e.userid = userid;
+            dispatcher.dispatchEvent(e);
+        }
+        
+        public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object=null):void {
+            var responder:Responder =	new Responder(
+                function(result:Object):void { // On successful result
+                    onSuccess("Successfully sent [" + service + "]."); 
+                },
+                function(status:Object):void { // status - On error occurred
+                    var errorReason:String = "Failed to send [" + service + "]:\n"; 
+                    for (var x:Object in status) { 
+                        errorReason += "\t" + x + " : " + status[x]; 
+                    } 
+                }
+            );
+
+            if (message == null) {
+                _netConnection.call(service, responder);
+            } else {
+                _netConnection.call(service, responder, message);
+            }
+        }
+
+        public function connect():void {
+            var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams();
+
+            _netConnection = new NetConnection();
+            _netConnection.proxyType = "best";
+            _netConnection.client = this;
+            _netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
+            _netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, netASyncError );
+            _netConnection.addEventListener( SecurityErrorEvent.SECURITY_ERROR, netSecurityError );
+            _netConnection.addEventListener( IOErrorEvent.IO_ERROR, netIOError );
+                
+            try {
+                var appURL:String = BBB.getConfigManager().config.application.uri;
+                var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
+                var result:Array = pattern.exec(appURL);
+            
+                var protocol:String = "rtmp";
+                var uri:String = appURL + "/" + confParams.room;
+            
+                if (BBB.initConnectionManager().isTunnelling) {
+                    bbbAppsUrl = "rtmpt://" + result.server + "/" + result.app + "/" + confParams.room;
+                } else {
+                    bbbAppsUrl = "rtmp://" + result.server + ":1935/" + result.app + "/" + confParams.room;
+                }
+
+                var logData:Object = UsersUtil.initLogData();
+                logData.connection = bbbAppsUrl;
+                logData.tags = ["apps", "connection"];
+                logData.message = "Connecting to bbb-apps.";
+                LOGGER.info(JSON.stringify(logData));
             
-			try {	
-        var appURL:String = BBB.getConfigManager().config.application.uri;
-        var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
-        var result:Array = pattern.exec(appURL);
+                connectAttemptCount++;
+                
+                connectionTimer = new Timer(connectAttemptTimeout, 1);
+                connectionTimer.addEventListener(TimerEvent.TIMER, connectionTimeout);
+                connectionTimer.start();
+
+                _netConnection.connect(uri, confParams.username, confParams.role,
+                                        confParams.room, confParams.voicebridge, 
+                                        confParams.record, confParams.externUserID,
+                                        confParams.internalUserID, confParams.muteOnStart, confParams.lockSettings);
+                   
+            } catch(e:ArgumentError) {
+                // Invalid parameters.
+                switch (e.errorID) {
+                    case 2004 :
+                        LOGGER.debug("Error! Invalid server location: {0}", [uri]);
+                        break;
+                    default :
+                        LOGGER.debug("UNKNOWN Error! Invalid server location: {0}", [uri]);
+                       break;
+                }
+            }
+        }
+            
+        public function connectionTimeout (e:TimerEvent) : void {
+            var logData:Object = UsersUtil.initLogData();
+            logData.connection = bbbAppsUrl;
+            logData.tags = ["apps", "connection"];
+            logData.connectAttemptCount = connectAttemptCount;
+            logData.message = "Connecting attempt to bbb-apps timedout. Retrying.";
+            LOGGER.info(JSON.stringify(logData));
+            
+            if (connectAttemptCount <= maxConnectAttempt) {
+                connect();
+            } else {
+                sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_ATTEMPT_TIMEDOUT);
+            }
+            
+        }
+            
+
+        public function disconnect(logoutOnUserCommand:Boolean):void {
+            this.logoutOnUserCommand = logoutOnUserCommand;
+            _netConnection.close();
+        }
         
-        var protocol:String = "rtmp";
-        var uri:String = appURL + "/" + confParams.room;
+        public function forceClose():void {
+          _netConnection.close();
+        }
         
-        if (BBB.initConnectionManager().isTunnelling) {
-          uri = "rtmpt://" + result.server + "/" + result.app + "/" + confParams.room;
-        } else {
-          uri = "rtmp://" + result.server + ":1935/" + result.app + "/" + confParams.room;
+        protected function netStatus(event:NetStatusEvent):void {
+            handleResult( event );
         }
-				
-				
-				LOGGER.debug("BBB Apps URI=" + uri);
-				
-				_netConnection.connect(uri, confParams.username, confParams.role,
-          confParams.room, confParams.voicebridge, 
-          confParams.record, confParams.externUserID,
-          confParams.internalUserID, confParams.muteOnStart, confParams.lockSettings);
-               
-			} catch(e:ArgumentError) {
-				// Invalid parameters.
-				switch (e.errorID) {
-					case 2004 :
-						LOGGER.debug("Error! Invalid server location: {0}", [uri]);
-						break;						
-					default :
-						LOGGER.debug("UNKNOWN Error! Invalid server location: {0}", [uri]);
-					   break;
-				}
-			}	
-		}
-			
-		public function disconnect(logoutOnUserCommand:Boolean):void {
-			this.logoutOnUserCommand = logoutOnUserCommand;
-			_netConnection.close();
-		}
-		
-    
-    public function forceClose():void {
-      _netConnection.close();
-    }
-    
-		protected function netStatus(event:NetStatusEvent):void {
-			handleResult( event );
-		}
-		
-		public function handleResult(event:Object):void {
-			var info : Object = event.info;
-			var statusCode : String = info.code;
+
+        public function handleResult(event:Object):void {
+            var info : Object = event.info;
+            var statusCode : String = info.code;
+            
+            //Stop timeout timer when connected/rejected
+            if (connectionTimer != null && connectionTimer.running) {
+                connectionTimer.stop();
+                connectionTimer = null;
+            }
+            
 
             var logData:Object = UsersUtil.initLogData();
-            logData.tags = ["apps"];
-      
-			switch (statusCode) {
-				case "NetConnection.Connect.Success":
-					numNetworkChangeCount = 0;
-                    logData.message = "Successfully connected to BBB App.";
+            logData.tags = ["apps", "connection"];
+          
+            switch (statusCode) {
+                case "NetConnection.Connect.Success":
+                    numNetworkChangeCount = 0;
+                    logData.message = "Successfully connected to bbb-apps.";
                     LOGGER.info(JSON.stringify(logData));
                     validateToken();
-					break;
-			
-				case "NetConnection.Connect.Failed":					
-                    logData.message = "Connection to bbb-apps failed, even when tunneling.";
+                    break;
+
+                case "NetConnection.Connect.Failed":
+                    logData.message = "Connection to bbb-apps failed.";
+                    LOGGER.info(JSON.stringify(logData));
+                    sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_FAILED);	
+                    break;
+
+                case "NetConnection.Connect.Closed":
+                    logData.message = "NetConnection.Connect.Closed on bbb-apps";
                     LOGGER.info(JSON.stringify(logData));
-					sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_FAILED);								
-					break;
-					
-				case "NetConnection.Connect.Closed":	
-					logData.message = "NetConnection.Connect.Closed on bbb-apps";
-					LOGGER.info(JSON.stringify(logData));
-                    sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_CLOSED);		
-					break;
-					
-				case "NetConnection.Connect.InvalidApp":
+                    sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_CLOSED);
+                    break;
+
+                case "NetConnection.Connect.InvalidApp":
                     logData.message = "bbb-app not found.";
                     LOGGER.info(JSON.stringify(logData));
-					sendConnectionFailedEvent(ConnectionFailedEvent.INVALID_APP);				
-					break;
-					
-				case "NetConnection.Connect.AppShutDown":
+                    sendConnectionFailedEvent(ConnectionFailedEvent.INVALID_APP);
+                    break;
+
+                case "NetConnection.Connect.AppShutDown":
                     LOGGER.debug(":viewers application has been shutdown");
-					sendConnectionFailedEvent(ConnectionFailedEvent.APP_SHUTDOWN);	
-					break;
-					
-				case "NetConnection.Connect.Rejected":
-          var appURL:String = BBB.getConfigManager().config.application.uri
-          LOGGER.debug(":Connection to the server rejected. Uri: {0}. Check if the red5 specified in the uri exists and is running", [appURL]);
-					sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_REJECTED);		
-					break;
-				
-				case "NetConnection.Connect.NetworkChange":
-					numNetworkChangeCount++;
-					if (numNetworkChangeCount % 20 == 0) {
-						logData.message = "Detected network change on bbb-apps";
-						logData.numNetworkChangeCount = numNetworkChangeCount;
-						LOGGER.info(JSON.stringify(logData));
-					}
-					break;
-					
-				default :
-          LOGGER.debug(":Default status to the viewers application" );
-				   sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
-				   break;
-			}
-		}
-			
-		protected function netSecurityError(event: SecurityErrorEvent):void {
+                    sendConnectionFailedEvent(ConnectionFailedEvent.APP_SHUTDOWN);
+                    break;
+
+                case "NetConnection.Connect.Rejected":
+                    var appURL:String = BBB.getConfigManager().config.application.uri
+                    LOGGER.debug(":Connection to the server rejected. Uri: {0}. Check if the red5 specified in the uri exists and is running", [appURL]);
+                    sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_REJECTED);
+                    break;
+                
+                case "NetConnection.Connect.NetworkChange":
+                    numNetworkChangeCount++;
+                    if (numNetworkChangeCount % 20 == 0) {
+                        logData.message = "Detected network change on bbb-apps";
+                        logData.numNetworkChangeCount = numNetworkChangeCount;
+                        LOGGER.info(JSON.stringify(logData));
+                    }
+                    break;
+
+                default :
+                    LOGGER.debug(":Default status to the viewers application" );
+                    sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
+                    break;   
+             }
+        }
+
+        protected function netSecurityError(event: SecurityErrorEvent):void {
             var logData:Object = UsersUtil.initLogData();
-            logData.tags = ["apps"];
+            logData.tags = ["apps", "connection"];
             logData.message = "Security error - " + event.text;
             LOGGER.info(JSON.stringify(logData));
-			sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
-		}
-		
-		protected function netIOError(event: IOErrorEvent):void {
+            sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
+        }
+
+        protected function netIOError(event: IOErrorEvent):void {
             var logData:Object = UsersUtil.initLogData();
-            logData.tags = ["apps"];
+            logData.tags = ["apps", "connection"];
             logData.message = "Input/output error - " + event.text;
             LOGGER.info(JSON.stringify(logData));
 
-			sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
-		}
-			
-		protected function netASyncError(event: AsyncErrorEvent):void  {
-	  		LOGGER.debug("Asynchronous code error - {0}", [event.toString()]);
-			sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
-		}	
-			
+            sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
+        }
+
+        protected function netASyncError(event: AsyncErrorEvent):void  {
+            LOGGER.debug("Asynchronous code error - {0}", [event.toString()]);
+            sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
+        }
+
         private function sendConnectionFailedEvent(reason:String):void{
             var logData:Object = UsersUtil.initLogData();
-            logData.tags = ["apps"];
+            logData.tags = ["apps", "connection"];
 
             if (this.logoutOnUserCommand) {
                 logData.reason = "User requested.";
                 logData.message = "User logged out from BBB App.";
                 LOGGER.info(JSON.stringify(logData));
-                
+                   
                 sendUserLoggedOutEvent();
             } else if (reason == ConnectionFailedEvent.CONNECTION_CLOSED && !UsersUtil.isUserEjected()) {
                 // do not try to reconnect if the connection failed is different than CONNECTION_CLOSED  
@@ -400,20 +438,19 @@ package org.bigbluebutton.main.model.users
                 LOGGER.info(JSON.stringify(logData));
 
                 if (reconnecting) {
-                  var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
-                  attemptFailedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
-                  dispatcher.dispatchEvent(attemptFailedEvent);
+                    var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
+                    attemptFailedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
+                    dispatcher.dispatchEvent(attemptFailedEvent);
                 } else {
-                  reconnecting = true;
-                  authenticated = false;
-
-                  var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
-                  disconnectedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
-                  disconnectedEvent.payload.callback = connect;
-                  disconnectedEvent.payload.callbackParameters = new Array();
-                  dispatcher.dispatchEvent(disconnectedEvent);
-                }
+                    reconnecting = true;
+                    authenticated = false;
 
+                    var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
+                    disconnectedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
+                    disconnectedEvent.payload.callback = connect;
+                    disconnectedEvent.payload.callbackParameters = new Array();
+                    dispatcher.dispatchEvent(disconnectedEvent);
+                }
             } else {
                 if (UsersUtil.isUserEjected()) {
                     logData.message = "User has been ejected from meeting.";
@@ -428,22 +465,22 @@ package org.bigbluebutton.main.model.users
 
             }
         }
-		
-		private function sendUserLoggedOutEvent():void{
-			var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT);
-			dispatcher.dispatchEvent(e);
-		}
-		
-		public function onBWCheck(... rest):Number { 
-			return 0; 
-		} 
-    
-		public function onBWDone(... rest):void { 
-			var p_bw:Number; 
-			if (rest.length > 0) p_bw = rest[0]; 
-			// your application should do something here 
-			// when the bandwidth check is complete 
-			LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]); 
-		}
-	}
+
+        private function sendUserLoggedOutEvent():void{
+            var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT);
+            dispatcher.dispatchEvent(e);
+        }
+
+        public function onBWCheck(... rest):Number { 
+            return 0; 
+        } 
+        
+        public function onBWDone(... rest):void { 
+            var p_bw:Number; 
+            if (rest.length > 0) p_bw = rest[0]; 
+            // your application should do something here 
+            // when the bandwidth check is complete 
+            LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]); 
+        }
+    }
 }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as
index 6ceb8b8efd29258a32fa63ddcc7f523a8df3af4e..f6b8530e5a99d5138daeff5fc225127aadf836be 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as
@@ -18,23 +18,22 @@
 */
 package org.bigbluebutton.main.model.users.events
 {
-	import flash.events.Event;
+    import flash.events.Event;
 
-	public class ConnectionFailedEvent extends Event
-	{
-		public static const UNKNOWN_REASON:String = "unknownReason";
-		public static const CONNECTION_FAILED:String = "connectionFailed";
-		public static const CONNECTION_CLOSED:String = "connectionClosed";
-		public static const INVALID_APP:String = "invalidApp";
-		public static const APP_SHUTDOWN:String = "appShutdown";
-		public static const CONNECTION_REJECTED:String = "connectionRejected";
-		public static const ASYNC_ERROR:String = "asyncError";
-		public static const USER_LOGGED_OUT:String = "userHasLoggedOut";
-		public static const USER_EJECTED_FROM_MEETING:String = "userHasBeenEjectFromMeeting";
-		
-		public function ConnectionFailedEvent(type:String)
-		{
-			super(type, true, false);
-		}
-	}
+    public class ConnectionFailedEvent extends Event {
+        public static const UNKNOWN_REASON:String = "unknownReason";
+        public static const CONNECTION_FAILED:String = "connectionFailed";
+        public static const CONNECTION_CLOSED:String = "connectionClosed";
+        public static const CONNECTION_ATTEMPT_TIMEDOUT:String = "connectionAttemptTimedout";
+        public static const INVALID_APP:String = "invalidApp";
+        public static const APP_SHUTDOWN:String = "appShutdown";
+        public static const CONNECTION_REJECTED:String = "connectionRejected";
+        public static const ASYNC_ERROR:String = "asyncError";
+        public static const USER_LOGGED_OUT:String = "userHasLoggedOut";
+        public static const USER_EJECTED_FROM_MEETING:String = "userHasBeenEjectFromMeeting";
+
+        public function ConnectionFailedEvent(type:String) {
+            super(type, true, false);
+        }
+    }
 }
\ No newline at end of file
diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
index cb9a9ffbfb21087aa9285e888ad4fcad7c672d51..01e641cd98585163e011b320640b1f20eb256f61 100755
--- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
+++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
@@ -18,6 +18,8 @@
  */
 package org.bigbluebutton.web.controllers
 
+import com.google.gson.Gson
+
 import javax.servlet.ServletRequest;
 
 import java.net.URI;
@@ -1455,7 +1457,7 @@ class ApiController {
       reject = true
     } else {
       sessionToken = StringUtils.strip(params.sessionToken)
-      log.info("SessionToken = " + sessionToken)
+      log.info("Getting ConfigXml for SessionToken = " + sessionToken)
       if (!session[sessionToken]) {
           reject = true
       } else {
@@ -1478,6 +1480,20 @@ class ApiController {
         }
       }
     } else {
+      Map<String, Object> logData = new HashMap<String, Object>();
+      logData.put("meetingId", us.meetingID);
+      logData.put("externalMeetingId", us.externMeetingID);
+      logData.put("name", us.fullname);
+      logData.put("userId", us.internalUserId);
+      logData.put("sessionToken", sessionToken);
+      logData.put("message", "handle_configxml_api");
+      logData.put("description", "Handling ConfigXml API.");
+
+      Gson gson = new Gson();
+      String logStr = gson.toJson(logData);
+
+      log.info(logStr);
+
       response.addHeader("Cache-Control", "no-cache")
       render text: us.configXML, contentType: 'text/xml'
     }
@@ -1544,7 +1560,20 @@ class ApiController {
       // how many times a user reconnects or refresh the browser.
       String newInternalUserID = us.internalUserId + "_" + us.incrementConnectionNum()
 
-      log.info("Found conference for " + us.fullname)
+      Map<String, Object> logData = new HashMap<String, Object>();
+      logData.put("meetingId", us.meetingID);
+      logData.put("externalMeetingId", us.externMeetingID);
+      logData.put("name", us.fullname);
+      logData.put("userId", newInternalUserID);
+      logData.put("sessionToken", sessionToken);
+      logData.put("message", "handle_enter_api");
+      logData.put("description", "Handling ENTER API.");
+
+      Gson gson = new Gson();
+      String logStr = gson.toJson(logData);
+
+      log.info(logStr);
+
       response.addHeader("Cache-Control", "no-cache")
       withFormat {
         json {