diff --git a/clients/flash/air-client/src/Default.css b/clients/flash/air-client/src/Default.css
index bdbd0eb52e52c61aedf91be54de762afbe0fb6a6..0ff768a7c5d28b2fe317cb092cd95127b2ecc4af 100755
--- a/clients/flash/air-client/src/Default.css
+++ b/clients/flash/air-client/src/Default.css
@@ -375,3 +375,8 @@ settings|SettingsItemRenderer {
 	borderColorOver     : PropertyReference("grey700");
 	borderColorDown     : PropertyReference("grey700");
 }
+
+.startingScreensharingLabel {
+	color     : PropertyReference("bbbBlack");
+	textAlign : center;
+}
\ No newline at end of file
diff --git a/clients/flash/air-client/src/Main-app.xml b/clients/flash/air-client/src/Main-app.xml
index 754c74d44431928c74444a8f4d6506033d378b70..80fb0991dc347faf5e1e92bcb74a6b2f03fb8867 100755
--- a/clients/flash/air-client/src/Main-app.xml
+++ b/clients/flash/air-client/src/Main-app.xml
@@ -385,5 +385,6 @@
 	<extensions>
         <extensionID>com.freshplanet.AirCapabilities</extensionID>
         <extensionID>com.juankpro.ane.LocalNotification</extensionID>
+        <extensionID>org.bigbluebutton.BBBRtmpPlayer</extensionID>
     </extensions>
 </application>
diff --git a/clients/flash/air-client/src/css/hdpi.css b/clients/flash/air-client/src/css/hdpi.css
index 1797d518cf9ad024cdb232fc0d6cf99f2f777929..a6e870b095549b9bcea2ba0619344a143d07645f 100755
--- a/clients/flash/air-client/src/css/hdpi.css
+++ b/clients/flash/air-client/src/css/hdpi.css
@@ -58,8 +58,8 @@
         padding: 10.50;
         gap: 6.00;
         leftIndent: 33.00;
-        fontSize: 23.00;
-        nameFontSize: 23.00;
+        fontSize: 24.00;
+        nameFontSize: 24.00;
         timeFontSize: 21.00;
     }
 
@@ -131,8 +131,8 @@
     }
 
     .sendButton {
-        diameter: 48.00;
-        fontSize: 22.00;
+        diameter: 42.00;
+        fontSize: 22.50;
     }
 
     .titleGroup {
@@ -221,4 +221,8 @@
     .audioButtonStyle {
         iconSize: 66.00;
     }
+
+    .startingScreensharingLabel {
+        fontSize: 42.00;
+    }
 }
diff --git a/clients/flash/air-client/src/css/ldpi.css b/clients/flash/air-client/src/css/ldpi.css
index 3cd66acbcaab29e76c9438f5cbd5fd7a0cc80c58..99aeba7e3725cf7c44905673d6abf0051b82bd31 100755
--- a/clients/flash/air-client/src/css/ldpi.css
+++ b/clients/flash/air-client/src/css/ldpi.css
@@ -221,4 +221,8 @@
     .audioButtonStyle {
         iconSize: 33.000;
     }
+
+    .startingScreensharingLabel {
+        fontSize: 21.000;
+    }
 }
diff --git a/clients/flash/air-client/src/css/mdpi.css b/clients/flash/air-client/src/css/mdpi.css
index 191b02de0cf02c9734faa99f97d2801cd6e85b85..5d8bc2ed42a6bed142953bb12ac548854cf4ed04 100755
--- a/clients/flash/air-client/src/css/mdpi.css
+++ b/clients/flash/air-client/src/css/mdpi.css
@@ -132,7 +132,7 @@
 
     .sendButton {
         diameter: 28.0;
-        fontSize: 15;
+        fontSize: 15.0;
     }
 
     .titleGroup {
@@ -221,4 +221,8 @@
     .audioButtonStyle {
         iconSize: 44.0;
     }
+
+    .startingScreensharingLabel {
+        fontSize: 28.0;
+    }
 }
diff --git a/clients/flash/air-client/src/css/xhdpi.css b/clients/flash/air-client/src/css/xhdpi.css
index b238f81348d487c3dfd1db060b76ec57a5ec74a0..8effe499fab7b975630a244addb0085a66dded0a 100755
--- a/clients/flash/air-client/src/css/xhdpi.css
+++ b/clients/flash/air-client/src/css/xhdpi.css
@@ -209,4 +209,8 @@
 	.audioButtonStyle {
 		iconSize : 88;
 	}
+	
+	.startingScreensharingLabel {
+		fontSize : 56;
+	}
 }
diff --git a/clients/flash/air-client/src/css/xxhdpi.css b/clients/flash/air-client/src/css/xxhdpi.css
index 8e6e62c31b2c22f11bb2462bd155f6a45871600d..c75820f5c8babd9ecdfc9a1125a2d6ab91d4d6ce 100755
--- a/clients/flash/air-client/src/css/xxhdpi.css
+++ b/clients/flash/air-client/src/css/xxhdpi.css
@@ -132,7 +132,7 @@
 
     .sendButton {
         diameter: 84.0;
-        fontSize: 45;
+        fontSize: 45.0;
     }
 
     .titleGroup {
@@ -221,4 +221,8 @@
     .audioButtonStyle {
         iconSize: 132.0;
     }
+
+    .startingScreensharingLabel {
+        fontSize: 84.0;
+    }
 }
diff --git a/clients/flash/air-client/src/css/xxxhdpi.css b/clients/flash/air-client/src/css/xxxhdpi.css
index 146b8b5e1c5b937cb5bd2dea240207c37b839393..b95b4f244f51205e0255de7ceae4b095bd67e2e6 100755
--- a/clients/flash/air-client/src/css/xxxhdpi.css
+++ b/clients/flash/air-client/src/css/xxxhdpi.css
@@ -221,4 +221,8 @@
     .audioButtonStyle {
         iconSize: 176;
     }
+
+    .startingScreensharingLabel {
+        fontSize: 112;
+    }
 }
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as
new file mode 100755
index 0000000000000000000000000000000000000000..ba9f0e96c9d704ac8069b752e9554e70e7e6e33a
--- /dev/null
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/IOSVideoView.as
@@ -0,0 +1,121 @@
+package org.bigbluebutton.air.common.views {
+	import mx.formatters.DateFormatter;
+	
+	import spark.components.Image;
+	
+	import org.bigbluebutton.BBBRtmpPlayer;
+	import org.bigbluebutton.BBBRtmpPlayerEvent;
+	import org.bigbluebutton.air.util.ConnUtil;
+	
+	public class IOSVideoView extends VideoBaseView {
+		
+		protected var player:BBBRtmpPlayer;
+		protected var dateFormat:DateFormatter = new DateFormatter("Y-MM-DD J:NN:SS:QQ");
+		
+		private var _connectionId : String;
+		
+		private function get image():Image {
+			return videoComp as Image;
+		}
+		
+		public function startStream(uri:String, streamName:String, imgWidth:Number, imgHeight:Number, meetingId:String, authToken:String, externalUserId:String):void {
+			
+			if (player) {
+				close();
+			}
+			
+			videoComp = new Image();
+			if (numChildren == 0) {
+				addChild(videoComp);
+			}
+			
+			this.originalVideoWidth = imgWidth;
+			this.originalVideoHeight = imgHeight;
+			
+			_connectionId = ConnUtil.generateConnId();
+			
+			var url:String = uri + "/" + streamName + " live=1 conn=S:" + meetingId + " conn=S:" + externalUserId + " conn=S:" + authToken + " conn=S:" + _connectionId;
+			
+			player = new BBBRtmpPlayer(url);
+
+			player.addEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected);
+			player.addEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting);
+			player.addEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed);
+			player.addEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected);
+			
+			player.play();
+		}
+		
+		private function onConnected(e:BBBRtmpPlayerEvent):void {
+			trace(dateFormat.format(new Date()) +  " EVENT: " + e.type + " MESSAGE: " + e.getMessage());
+			image.source = player.getBmpData();
+		}
+
+		private function onConnecting(e:BBBRtmpPlayerEvent):void {
+			trace(dateFormat.format(new Date()) +  " EVENT: " + e.type + " MESSAGE: " + e.getMessage());
+		}
+
+		private function onConnectionFailed(e:BBBRtmpPlayerEvent):void {
+			close();
+		}
+		
+		private function onDisconnected(e:BBBRtmpPlayerEvent):void {
+			close();
+		}
+		
+		public function close():void {
+			if (player) {
+				player.removeEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected);
+				player.removeEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting);
+				player.removeEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed);
+				player.removeEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected);
+			}
+			if (numChildren > 0 && getChildAt(0) == image) {
+				removeChild(image);
+			}
+			videoComp = null;
+			player = null;
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void {
+			super.updateDisplayList(w, h);
+			
+			if (player) {
+				resizeForPortrait();
+			}
+		}
+		
+		public function rotateVideo(rotation:Number):void {
+			if (image && stage.contains(image)) {
+				removeChild(image);
+			}
+			videoComp = new Image();
+			switch (rotation) {
+				case 0:
+					resizeForPortrait();
+					image.x = width / 2 - image.width / 2;
+					image.y = height / 2 - image.height / 2; // + topMenuBarHeight;
+					break;
+				case -90:
+					resizeForLandscape();
+					image.x = (width / 2) - (image.height / 2);
+					image.y = (height / 2) + (image.width / 2); // + topMenuBarHeight;
+					break;
+				case 90:
+					resizeForLandscape();
+					image.x = (width / 2) + (image.height / 2);
+					image.y = (height / 2) - (image.width / 2); // + topMenuBarHeight;
+					break;
+				case 180:
+					resizeForPortrait();
+					image.x = width / 2 + image.width / 2;
+					image.y = (height / 2) + (image.height / 2); // + topMenuBarHeight
+					break;
+				default:
+					break;
+			}
+			image.rotation = rotation;
+			addChild(image);
+		}
+	}
+}
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoBaseView.as b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoBaseView.as
new file mode 100644
index 0000000000000000000000000000000000000000..7ecd55b8d9c3f3af47207e51e265c82d8e182f25
--- /dev/null
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoBaseView.as
@@ -0,0 +1,65 @@
+package org.bigbluebutton.air.common.views {
+	import flash.display.DisplayObject;
+	
+	import mx.core.UIComponent;
+	
+	public class VideoBaseView extends UIComponent {
+		protected var videoComp:DisplayObject;
+		
+		protected var originalVideoWidth:Number;
+		
+		protected var originalVideoHeight:Number;
+		
+		public function resizeForLandscape():void {
+			if (height < width) {
+				videoComp.height = width;
+				videoComp.width = ((originalVideoWidth * videoComp.height) / originalVideoHeight);
+				if (width < videoComp.width) {
+					videoComp.width = height;
+					videoComp.height = (videoComp.width / originalVideoWidth) * originalVideoHeight;
+				}
+			} else {
+				videoComp.width = height;
+				videoComp.height = (videoComp.width / originalVideoWidth) * originalVideoHeight;
+				if (height < videoComp.height) {
+					videoComp.height = width;
+					videoComp.width = ((originalVideoWidth * videoComp.height) / originalVideoHeight);
+				}
+			}
+		}
+		
+		public function resizeForPortrait():void {
+			// if we have device where screen width less than screen height e.g. phone
+			if (width < height) {
+				// make the video width full width of the screen 
+				videoComp.width = width;
+				// calculate height based on a video width, it order to keep the same aspect ratio
+				videoComp.height = (videoComp.width / originalVideoWidth) * originalVideoHeight;
+				// if calculated height appeared to be bigger than screen height, recalculuate the video size based on width
+				if (height < videoComp.height) {
+					// make the video height full height of the screen
+					videoComp.height = height;
+					// calculate width based on a video height, it order to keep the same aspect ratio
+					videoComp.width = ((originalVideoWidth * videoComp.height) / originalVideoHeight);
+				}
+			} // if we have device where screen height less than screen width e.g. tablet
+			else {
+				// make the video height full height of the screen
+				videoComp.height = height;
+				// calculate width based on a video height, it order to keep the same aspect ratio
+				videoComp.width = ((originalVideoWidth * videoComp.height) / originalVideoHeight);
+				// if calculated width appeared to be bigger than screen width, recalculuate the video size based on height
+				if (width < videoComp.width) {
+					// make the video width full width of the screen 
+					videoComp.width = width;
+					// calculate height based on a video width, it order to keep the same aspect ratio
+					videoComp.height = (videoComp.width / originalVideoWidth) * originalVideoHeight;
+				}
+			}
+			
+			videoComp.x = width - videoComp.width;
+			videoComp.y = height - videoComp.height;
+		}
+	
+	}
+}
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoView.as b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoView.as
index 50d3b096c35d7d8ae81856feed15b73e70713a8a..aefdc6b30f237b62827138f825030a5cae9f8882 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoView.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/common/views/VideoView.as
@@ -6,13 +6,10 @@ package org.bigbluebutton.air.common.views {
 	import flash.net.NetConnection;
 	import flash.net.NetStream;
 	import flash.system.Capabilities;
-	import mx.core.UIComponent;
 	
-	public class VideoView extends UIComponent {
+	public class VideoView extends VideoBaseView {
 		protected var ns:NetStream;
 		
-		protected var _video:Video;
-		
 		protected var connection:NetConnection;
 		
 		public var userId:String;
@@ -21,13 +18,13 @@ package org.bigbluebutton.air.common.views {
 		
 		public var streamName:String;
 		
-		protected var originalVideoWidth:Number;
-		
-		protected var originalVideoHeight:Number;
+		private function get video():Video {
+			return videoComp as Video;
+		}
 		
 		public function VideoView():void {
-			_video = new Video();
-			addChild(_video);
+			videoComp = new Video();
+			addChild(videoComp);
 		}
 		
 		public function startStream(connection:NetConnection, name:String, streamName:String, userId:String, oWidth:Number, oHeight:Number):void {
@@ -51,8 +48,8 @@ package org.bigbluebutton.air.common.views {
 			ns.bufferTime = 0;
 			ns.receiveVideo(true);
 			ns.receiveAudio(false);
-			_video.smoothing = true;
-			_video.attachNetStream(ns);
+			video.smoothing = true;
+			video.attachNetStream(ns);
 			ns.play(streamName);
 		}
 		
@@ -87,7 +84,7 @@ package org.bigbluebutton.air.common.views {
 		
 		public function close():void {
 			if (ns) {
-				_video.attachCamera(null);
+				video.attachCamera(null);
 				ns.removeEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
 				ns.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
 				ns.close();
@@ -103,89 +100,38 @@ package org.bigbluebutton.air.common.views {
 			}
 		}
 		
-		public function resizeForPortrait():void {
-			// if we have device where screen width less than screen height e.g. phone
-			if (width < height) {
-				// make the video width full width of the screen 
-				_video.width = width;
-				// calculate height based on a video width, it order to keep the same aspect ratio
-				_video.height = (_video.width / originalVideoWidth) * originalVideoHeight;
-				// if calculated height appeared to be bigger than screen height, recalculuate the video size based on width
-				if (height < _video.height) {
-					// make the video height full height of the screen
-					_video.height = height;
-					// calculate width based on a video height, it order to keep the same aspect ratio
-					_video.width = ((originalVideoWidth * _video.height) / originalVideoHeight);
-				}
-			} // if we have device where screen height less than screen width e.g. tablet
-			else {
-				// make the video height full height of the screen
-				_video.height = height;
-				// calculate width based on a video height, it order to keep the same aspect ratio
-				_video.width = ((originalVideoWidth * _video.height) / originalVideoHeight);
-				// if calculated width appeared to be bigger than screen width, recalculuate the video size based on height
-				if (width < _video.width) {
-					// make the video width full width of the screen 
-					_video.width = width;
-					// calculate height based on a video width, it order to keep the same aspect ratio
-					_video.height = (_video.width / originalVideoWidth) * originalVideoHeight;
-				}
-			}
-			
-			_video.x = width - _video.width;
-			_video.y = height - _video.height;
-		}
-		
-		public function resizeForLandscape():void {
-			if (height < width) {
-				_video.height = width;
-				_video.width = ((originalVideoWidth * _video.height) / originalVideoHeight);
-				if (width < _video.width) {
-					_video.width = height;
-					_video.height = (_video.width / originalVideoWidth) * originalVideoHeight;
-				}
-			} else {
-				_video.width = height;
-				_video.height = (_video.width / originalVideoWidth) * originalVideoHeight;
-				if (height < _video.height) {
-					_video.height = width;
-					_video.width = ((originalVideoWidth * _video.height) / originalVideoHeight);
-				}
-			}
-		}
-		
 		public function rotateVideo(rotation:Number):void {
-			if (_video && stage.contains(_video)) {
-				stage.removeChild(_video);
+			if (video && stage.contains(video)) {
+				stage.removeChild(video);
 			}
-			_video = new Video();
-			_video.attachNetStream(ns);
+			videoComp = new Video();
+			video.attachNetStream(ns);
 			switch (rotation) {
 				case 0:
 					resizeForPortrait();
-					_video.x = width / 2 - _video.width / 2;
-					_video.y = height / 2 - _video.height / 2; // + topMenuBarHeight;
+					video.x = width / 2 - video.width / 2;
+					video.y = height / 2 - video.height / 2; // + topMenuBarHeight;
 					break;
 				case -90:
 					resizeForLandscape();
-					_video.x = (width / 2) - (_video.height / 2);
-					_video.y = (height / 2) + (_video.width / 2); // + topMenuBarHeight;
+					video.x = (width / 2) - (video.height / 2);
+					video.y = (height / 2) + (video.width / 2); // + topMenuBarHeight;
 					break;
 				case 90:
 					resizeForLandscape();
-					_video.x = (width / 2) + (_video.height / 2);
-					_video.y = (height / 2) - (_video.width / 2); // + topMenuBarHeight;
+					video.x = (width / 2) + (video.height / 2);
+					video.y = (height / 2) - (video.width / 2); // + topMenuBarHeight;
 					break;
 				case 180:
 					resizeForPortrait();
-					_video.x = width / 2 + _video.width / 2;
-					_video.y = (height / 2) + (_video.height / 2); // + topMenuBarHeight
+					video.x = width / 2 + video.width / 2;
+					video.y = (height / 2) + (video.height / 2); // + topMenuBarHeight
 					break;
 				default:
 					break;
 			}
-			_video.rotation = rotation;
-			this.stage.addChild(_video);
+			video.rotation = rotation;
+			this.stage.addChild(video);
 		}
 	}
 }
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/main/models/IUISession.as b/clients/flash/air-client/src/org/bigbluebutton/air/main/models/IUISession.as
index 7e28f65aca8d641713d3cd729ab238903075b64e..e811a152b21ed812bfb740403df85d4ec766b4a0 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/main/models/IUISession.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/main/models/IUISession.as
@@ -12,8 +12,8 @@ package org.bigbluebutton.air.main.models {
 		function get pageTransitionStartSignal():ISignal;
 		function get currentPage():String;
 		function get lastPage():String;
-		function popPage(animation:int = TransitionAnimationEnum.APPEAR):void;
-		function pushPage(value:String, details:Object = null, animation:int = TransitionAnimationEnum.APPEAR):void;
+		function popPage(animation:int = 0):void;
+		function pushPage(value:String, details:Object = null, animation:int = 0):void;
 		function get currentPageDetails():Object;
 	}
 }
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as b/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as
index 795ebabb88287523daddae3fac94852790d46ba9..e2f0009888e357d7d07a6c4f0ac52bf15017cb16 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/main/services/BigBlueButtonConnection.as
@@ -1,107 +1,110 @@
-package org.bigbluebutton.air.main.services {
-	
-	import flash.net.NetConnection;
-	import flash.net.Responder;
-	import mx.utils.ObjectUtil;
-	import org.bigbluebutton.air.common.services.DefaultConnectionCallback;
-	import org.bigbluebutton.air.common.services.IBaseConnection;
-	import org.bigbluebutton.air.main.models.IConferenceParameters;
-	import org.osflash.signals.ISignal;
-	import org.osflash.signals.Signal;
-	
-	public class BigBlueButtonConnection extends DefaultConnectionCallback implements IBigBlueButtonConnection {
-		public static const NAME:String = "BigBlueButtonConnection";
-		
-		protected var _connectionSuccessSignal:ISignal = new Signal();
-		
-		protected var _connectionFailureSignal:ISignal = new Signal();
-		
-		[Inject]
-		public var baseConnection:IBaseConnection;
-		
-		private var _applicationURI:String;
-		
-		private var _conferenceParameters:IConferenceParameters;
-		
-		private var _tried_tunneling:Boolean = false;
-		
-		[PostConstruct]
-		public function init():void {
-			baseConnection.init(this);
-			baseConnection.connectionSuccessSignal.add(onConnectionSuccess);
-			baseConnection.connectionFailureSignal.add(onConnectionFailure);
-		}
-		
-		private function onConnectionFailure(reason:String):void {
-			connectionFailureSignal.dispatch(reason);
-		}
-		
-		private function onConnectionSuccess():void {
-			connectionSuccessSignal.dispatch();
-		}
-		
-		public function get connectionFailureSignal():ISignal {
-			return _connectionFailureSignal;
-		}
-		
-		public function get connectionSuccessSignal():ISignal {
-			return _connectionSuccessSignal;
-		}
-		
-		public function set uri(uri:String):void {
-			_applicationURI = uri;
-		}
-		
-		public function get uri():String {
-			return _applicationURI;
-		}
-		
-		public function get connection():NetConnection {
-			return baseConnection.connection;
-		}
-		
-		/**
-		 * 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(params:IConferenceParameters, tunnel:Boolean = false):void {
-			_conferenceParameters = params;
-			_tried_tunneling = tunnel;
-			var uri:String = _applicationURI + "/" + _conferenceParameters.room;
-			
-			var username:String = _conferenceParameters.username;
-			var role:String = _conferenceParameters.role;
-			var intMeetingId:String = _conferenceParameters.room;
-			var voiceConf:String = _conferenceParameters.voicebridge;
-			var recorded:Boolean = _conferenceParameters.record;
-			var extUserId:String = _conferenceParameters.externUserID;
-			var intUserId:String = _conferenceParameters.internalUserID;
-			var muteOnStart:Boolean = _conferenceParameters.muteOnStart;
-			var guest:Boolean = _conferenceParameters.guest;
-			var authToken:String = _conferenceParameters.authToken;
-			
-			var connectParams:Array = [username, role, intMeetingId, voiceConf, recorded, extUserId, intUserId, muteOnStart, guest, authToken];
-			
-			trace("BBB Apps connect: " + connectParams);
-			baseConnection.connect.apply(null, new Array(uri).concat(connectParams));
-		}
-		
-		public function disconnect(onUserCommand:Boolean):void {
-			baseConnection.disconnect(onUserCommand);
-		}
-		
-		/**** NEED TO REMOVE THIS BEFORE CONVERSION IS FINISHED ******/
-		public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object = null):void {
-			//baseConnection.sendMessage(service, onSuccess, onFailure, message);
-		}
-		
-		public function sendMessage2x(onSuccess:Function, onFailure:Function, message:Object):void {
-			baseConnection.sendMessage2x(onSuccess, onFailure, message);
-		}
-	}
-}
+package org.bigbluebutton.air.main.services {
+	
+	import flash.net.NetConnection;
+	
+	import org.bigbluebutton.air.common.services.DefaultConnectionCallback;
+	import org.bigbluebutton.air.common.services.IBaseConnection;
+	import org.bigbluebutton.air.main.models.IConferenceParameters;
+	import org.bigbluebutton.air.util.ConnUtil;
+	import org.osflash.signals.ISignal;
+	import org.osflash.signals.Signal;
+	
+	public class BigBlueButtonConnection extends DefaultConnectionCallback implements IBigBlueButtonConnection {
+		public static const NAME:String = "BigBlueButtonConnection";
+		
+		protected var _connectionSuccessSignal:ISignal = new Signal();
+		
+		protected var _connectionFailureSignal:ISignal = new Signal();
+		
+		[Inject]
+		public var baseConnection:IBaseConnection;
+		
+		private var _applicationURI:String;
+		
+		private var _conferenceParameters:IConferenceParameters;
+		
+		private var _connectionId : String;
+		
+		private var _tried_tunneling:Boolean = false;
+		
+		[PostConstruct]
+		public function init():void {
+			baseConnection.init(this);
+			baseConnection.connectionSuccessSignal.add(onConnectionSuccess);
+			baseConnection.connectionFailureSignal.add(onConnectionFailure);
+		}
+		
+		private function onConnectionFailure(reason:String):void {
+			connectionFailureSignal.dispatch(reason);
+		}
+		
+		private function onConnectionSuccess():void {
+			connectionSuccessSignal.dispatch();
+		}
+		
+		public function get connectionFailureSignal():ISignal {
+			return _connectionFailureSignal;
+		}
+		
+		public function get connectionSuccessSignal():ISignal {
+			return _connectionSuccessSignal;
+		}
+		
+		public function set uri(uri:String):void {
+			_applicationURI = uri;
+		}
+		
+		public function get uri():String {
+			return _applicationURI;
+		}
+		
+		public function get connection():NetConnection {
+			return baseConnection.connection;
+		}
+		
+		/**
+		 * 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(params:IConferenceParameters, tunnel:Boolean = false):void {
+			_conferenceParameters = params;
+			_tried_tunneling = tunnel;
+			_connectionId = ConnUtil.generateConnId();
+			var uri:String = _applicationURI + "/" + _conferenceParameters.room;
+			
+			var username:String = _conferenceParameters.username;
+			var role:String = _conferenceParameters.role;
+			var intMeetingId:String = _conferenceParameters.room;
+			var voiceConf:String = _conferenceParameters.voicebridge;
+			var recorded:Boolean = _conferenceParameters.record;
+			var extUserId:String = _conferenceParameters.externUserID;
+			var intUserId:String = _conferenceParameters.internalUserID;
+			var muteOnStart:Boolean = _conferenceParameters.muteOnStart;
+			var guest:Boolean = _conferenceParameters.guest;
+			var authToken:String = _conferenceParameters.authToken;
+			
+			var connectParams:Array = [username, role, intMeetingId, voiceConf, recorded, extUserId, intUserId, muteOnStart, guest, authToken, _connectionId];
+			
+			trace("BBB Apps connect: " + connectParams);
+			baseConnection.connect.apply(null, new Array(uri).concat(connectParams));
+		}
+		
+		public function disconnect(onUserCommand:Boolean):void {
+			baseConnection.disconnect(onUserCommand);
+		}
+		
+		/**** NEED TO REMOVE THIS BEFORE CONVERSION IS FINISHED ******/
+		public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object = null):void {
+			//baseConnection.sendMessage(service, onSuccess, onFailure, message);
+		}
+		
+		public function sendMessage2x(onSuccess:Function, onFailure:Function, message:Object):void {
+			baseConnection.sendMessage2x(onSuccess, onFailure, message);
+		}
+	}
+}
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/main/views/LoadingScreenMediator.as b/clients/flash/air-client/src/org/bigbluebutton/air/main/views/LoadingScreenMediator.as
index cf2de0bb5b068a3d957c2f111257d5f7d50ea611..23e01333e9c32dcd8a0b145bf7b011b662677a27 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/main/views/LoadingScreenMediator.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/main/views/LoadingScreenMediator.as
@@ -40,7 +40,9 @@ package org.bigbluebutton.air.main.views {
 			// If we are in the Flash Builder debugger the InvokeEvent will never be fired
 			if (Capabilities.isDebugger) {
 				//var url:String = "bigbluebutton://test-install.blindsidenetworks.com/bigbluebutton/api/join?fullName=AIR&meetingID=Demo+Meeting&password=mp&redirect=false&checksum=3fdf56e9915c1031c3ea012b4ec8823cedd7c272";
-				var url:String = "bigbluebutton://test-install.blindsidenetworks.com/bigbluebutton/api/join?fullName=User+2021828&meetingID=Demo+Meeting&password=ap&redirect=true&checksum=8751963df96437c7d435eac8124e4fb3ec147115";
+				//var url:String = "bigbluebutton://test-install.blindsidenetworks.com/bigbluebutton/api/join?fullName=User+2021828&meetingID=Demo+Meeting&password=ap&redirect=true&checksum=8751963df96437c7d435eac8124e4fb3ec147115";
+				//var url:String = "bigbluebuttons://dev21.bigbluebutton.org/bigbluebutton/api/join?meetingID=Demo+Meeting&fullName=AAA&password=mp&checksum=5516fb6f7d7330d0c02fd94c8e1fb683957e2da4a1c7013f66004b68148d4478";
+				var url:String = "bigbluebutton://206.47.241.19/bigbluebutton/api/join?meetingID=Demo+Meeting&fullName=AAA&password=mp&checksum=94cc8981bf215b13101fa4d3307d3aca8512578b23b91b7be8042f65abd4a007";
 				joinRoom(url);
 			}
 		}
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as
new file mode 100755
index 0000000000000000000000000000000000000000..608d6aa28ee96f3d5589c7dd65e0248f6eefa8b1
--- /dev/null
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/IOSScreenshareView.as
@@ -0,0 +1,223 @@
+package org.bigbluebutton.air.screenshare.views {
+	import flash.display.DisplayObject;
+	import flash.events.TimerEvent;
+	import flash.utils.Timer;
+	
+	import mx.core.UIComponent;
+	import mx.formatters.DateFormatter;
+	
+	import spark.components.Image;
+	import spark.components.Label;
+	import spark.components.ProgressBar;
+	
+	import org.bigbluebutton.BBBRtmpPlayer;
+	import org.bigbluebutton.BBBRtmpPlayerEvent;
+	import org.bigbluebutton.air.util.ConnUtil;
+	
+	// FIXME : Work in progress class, needs behave like Android screensahring display
+	public class IOSScreenshareView extends UIComponent {
+		protected var player:BBBRtmpPlayer;
+		
+		protected var videoComp:DisplayObject;
+		
+		protected var originalVideoWidth:Number;
+		
+		protected var originalVideoHeight:Number;
+		
+		private var _waitingBar:ProgressBar;
+		
+		private var _waitingTimer:Timer;
+		
+		private var _connectionId:String;
+		
+		private var _startingLabel:Label;
+		
+		private const WAITING_SECONDS:int = 15;
+		
+		protected var dateFormat:DateFormatter = new DateFormatter("Y-MM-DD J:NN:SS:QQ");
+		
+		private function waitingTimerProgressHandler(e:TimerEvent):void {
+			trace("PROGRESS " + _waitingTimer.currentCount);
+			_waitingBar.currentProgress = _waitingTimer.currentCount;
+		}
+		
+		public function resizeForProgressBar():void {
+			// if we have device where screen width less than screen height e.g. phone
+			if (width < height) {
+				// make the video width full width of the screen 
+				_waitingBar.width = width;
+				// calculate height based on a video width, it order to keep the same aspect ratio
+				_waitingBar.height = (_waitingBar.width / originalVideoWidth) * originalVideoHeight;
+				// if calculated height appeared to be bigger than screen height, recalculuate the video size based on width
+				if (height < _waitingBar.height) {
+					// make the video height full height of the screen
+					_waitingBar.height = height;
+					// calculate width based on a video height, it order to keep the same aspect ratio
+					_waitingBar.width = ((originalVideoWidth * _waitingBar.height) / originalVideoHeight);
+				}
+			} // if we have device where screen height less than screen width e.g. tablet
+			else {
+				// make the video height full height of the screen
+				_waitingBar.height = height;
+				// calculate width based on a video height, it order to keep the same aspect ratio
+				_waitingBar.width = ((originalVideoWidth * _waitingBar.height) / originalVideoHeight);
+				// if calculated width appeared to be bigger than screen width, recalculuate the video size based on height
+				if (width < _waitingBar.width) {
+					// make the video width full width of the screen 
+					_waitingBar.width = width;
+					// calculate height based on a video width, it order to keep the same aspect ratio
+					_waitingBar.height = (_waitingBar.width / originalVideoWidth) * originalVideoHeight;
+				}
+			}
+			
+			_startingLabel.x = _waitingBar.x = width - _waitingBar.width;
+			_waitingBar.y = height - _waitingBar.height;
+			
+			_startingLabel.y = _waitingBar.y + (_waitingBar.height * 0.5);
+			_startingLabel.width = _waitingBar.width;
+			_startingLabel.height = _waitingBar.height;
+		}
+		
+		public function resizeForPortrait():void {
+			// if we have device where screen width less than screen height e.g. phone
+			if (width < height) {
+				// make the video width full width of the screen 
+				videoComp.width = width;
+				// calculate height based on a video width, it order to keep the same aspect ratio
+				videoComp.height = (videoComp.width / originalVideoWidth) * originalVideoHeight;
+				// if calculated height appeared to be bigger than screen height, recalculuate the video size based on width
+				if (height < videoComp.height) {
+					// make the video height full height of the screen
+					videoComp.height = height;
+					// calculate width based on a video height, it order to keep the same aspect ratio
+					videoComp.width = ((originalVideoWidth * videoComp.height) / originalVideoHeight);
+				}
+			} // if we have device where screen height less than screen width e.g. tablet
+			else {
+				// make the video height full height of the screen
+				videoComp.height = height;
+				// calculate width based on a video height, it order to keep the same aspect ratio
+				videoComp.width = ((originalVideoWidth * videoComp.height) / originalVideoHeight);
+				// if calculated width appeared to be bigger than screen width, recalculuate the video size based on height
+				if (width < videoComp.width) {
+					// make the video width full width of the screen 
+					videoComp.width = width;
+					// calculate height based on a video width, it order to keep the same aspect ratio
+					videoComp.height = (videoComp.width / originalVideoWidth) * originalVideoHeight;
+				}
+			}
+			
+			videoComp.x = width - videoComp.width;
+			videoComp.y = height - videoComp.height;
+		}
+		
+		private function get image():Image {
+			return videoComp as Image;
+		}
+		
+		public function startStream(uri:String, streamName:String, imgWidth:Number, imgHeight:Number, meetingId:String, authToken:String, externalUserId:String):void {
+			_waitingBar = new ProgressBar();
+			
+			_waitingBar.width = imgWidth;
+			_waitingBar.height = imgWidth;
+			
+			_waitingBar.currentProgress = 0;
+			_waitingBar.totalProgress = WAITING_SECONDS;
+			_waitingBar.percentWidth = 80;
+			_waitingBar.percentHeight = 100;
+			_waitingBar.bottom = 20;
+			_waitingBar.styleName = "micLevelProgressBar";
+			
+			_startingLabel = new Label();
+			
+			_startingLabel.horizontalCenter = 0;
+			_startingLabel.text = "Starting screen sharing";
+			_startingLabel.styleName = "startingScreensharingLabel";
+			
+			addChild(_waitingBar);
+			addChild(_startingLabel);
+			
+			_waitingTimer = new Timer(1000, WAITING_SECONDS);
+			_waitingTimer.addEventListener(TimerEvent.TIMER, waitingTimerProgressHandler);
+			
+			if (player) {
+				close();
+			}
+			
+			videoComp = new Image();
+			addChild(videoComp);
+			
+			this.originalVideoWidth = imgWidth;
+			this.originalVideoHeight = imgHeight;
+			
+			_connectionId = ConnUtil.generateConnId();
+			
+			var url:String = uri + "/" + streamName + " live=1 conn=S:" + meetingId + " conn=S:" + externalUserId + " conn=S:" + authToken + " conn=S:" + _connectionId;
+			
+			player = new BBBRtmpPlayer(url);
+			
+			player.addEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected);
+			player.addEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting);
+			player.addEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed);
+			player.addEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected);
+			
+			player.play();
+		}
+		
+		private function onConnected(e:BBBRtmpPlayerEvent):void {
+			trace(dateFormat.format(new Date()) + " EVENT: " + e.type + " MESSAGE: " + e.getMessage());
+			if (_waitingBar && _waitingBar.parent == this) {
+				_waitingTimer.removeEventListener(TimerEvent.TIMER, waitingTimerProgressHandler);
+				_waitingBar.currentProgress = WAITING_SECONDS;
+				removeChild(_waitingBar);
+			}
+			if (_startingLabel && _startingLabel.parent == this) {
+				removeChild(_startingLabel);
+			}
+			if (image) {
+				image.source = player.getBmpData();
+			}
+		}
+		
+		private function onConnecting(e:BBBRtmpPlayerEvent):void {
+			trace(dateFormat.format(new Date()) + " EVENT: " + e.type + " MESSAGE: " + e.getMessage());
+			_waitingTimer.start();
+		}
+		
+		private function onConnectionFailed(e:BBBRtmpPlayerEvent):void {
+			trace("EVENT: " + e.type + " MESSAGE: " + e.getMessage());
+			close();
+		}
+		
+		private function onDisconnected(e:BBBRtmpPlayerEvent):void {
+			trace("EVENT: " + e.type + " MESSAGE: " + e.getMessage());
+			close();
+		}
+		
+		public function close():void {
+			if (player) {
+				player.addEventListener(BBBRtmpPlayerEvent.CONNECTED, onConnected);
+				player.addEventListener(BBBRtmpPlayerEvent.CONNECTING, onConnecting);
+				player.removeEventListener(BBBRtmpPlayerEvent.CONNECTION_FAILED, onConnectionFailed);
+				player.removeEventListener(BBBRtmpPlayerEvent.DISCONNECTED, onDisconnected);
+				if (image && image.parent == this) {
+					removeChild(image);
+				}
+				videoComp = null;
+				player = null;
+			}
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void {
+			super.updateDisplayList(w, h);
+			
+			if (_waitingBar) {
+				resizeForProgressBar();
+			}
+			
+			if (player) {
+				resizeForPortrait();
+			}
+		}
+	}
+}
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareDock.as b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareDock.as
index ff3947fd60968bec9aae14997c6764d57bd9054c..df2652556c52b47691cba3fd29f697ea88d0233e 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareDock.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareDock.as
@@ -10,6 +10,7 @@ package org.bigbluebutton.air.screenshare.views {
 	import flash.media.VideoStatus;
 	import flash.net.NetConnection;
 	import flash.net.NetStream;
+	import flash.system.Capabilities;
 	
 	import spark.components.Group;
 	
@@ -31,7 +32,16 @@ package org.bigbluebutton.air.screenshare.views {
 		private var _topRect:RectCoverView;
 		private var _bottomRect:RectCoverView;
 		
-		public function ScreenshareDock():void {	}
+		private var _iosScrenshareView:IOSScreenshareView;
+		
+		public function ScreenshareDock():void {	
+			if (Capabilities.version.indexOf("IOS") >= 0) {
+				_iosScrenshareView = new IOSScreenshareView();
+				_iosScrenshareView.percentWidth = 100;
+				_iosScrenshareView.percentHeight = 100;
+				addElement(_iosScrenshareView);
+			}
+		}
 		
 		private function onStageVideoState(event:StageVideoAvailabilityEvent):void {
 			var available:Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
@@ -167,21 +177,25 @@ package org.bigbluebutton.air.screenshare.views {
 			
 		}
 			
-		public function viewStream(conn:NetConnection, streamId:String, width:int, height:int):void {
+		public function startStream(conn:NetConnection, streamId:String, width:int, height:int, meetingId:String, authToken:String, externalUserId:String):void {
 			//trace("************ ScreenshareView: viewing of screenshare streamId=" + streamId + " w=" + width + " h=" + height);
 			_conn = conn;
 			_streamId = streamId;
 			_origVidWidth = width;
 			_origVidHeight = height;
-						
-			if (stage == null) {
-				//trace("************ ScreenshareView: STAGE IS NULL!!!!!!!!");
+			
+			if (Capabilities.version.indexOf("IOS") >= 0) {
+				_iosScrenshareView.startStream(conn.uri, streamId, width, height, meetingId, authToken, externalUserId);
 			} else {
-				stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoState);
+				if (stage == null) {
+					//trace("************ ScreenshareView: STAGE IS NULL!!!!!!!!");
+				} else {
+					stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoState);
+				}
 			}
 		}
 		
-		public function streamStopped(session:String, reason:String):void {
+		public function stopStream(session:String, reason:String):void {
 			if (_screenshareRunningListener != null) {
 				_screenshareRunningListener(_usingStageVideo, false);
 			}
@@ -287,6 +301,10 @@ package org.bigbluebutton.air.screenshare.views {
 				_sv.removeEventListener(StageVideoEvent.RENDER_STATE, stageVideoStateChange);
 				_sv = null;
 			}
+			
+			if (Capabilities.version.indexOf("IOS") >= 0) {
+				_iosScrenshareView.close();
+			}
 		
 			_ns = null;
 			
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareViewMediator.as b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareViewMediator.as
index 6b37470f67ebc92a98fc29567e6b75a93fb0ebfc..c4c7df5cefcbdb9a4fd51692247d5aab06776cab 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareViewMediator.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/screenshare/views/ScreenshareViewMediator.as
@@ -1,5 +1,6 @@
 package org.bigbluebutton.air.screenshare.views {
 	
+	import org.bigbluebutton.air.main.models.IConferenceParameters;
 	import org.bigbluebutton.air.screenshare.model.IScreenshareModel;
 	import org.bigbluebutton.air.screenshare.services.IScreenshareConnection;
 	
@@ -16,6 +17,9 @@ package org.bigbluebutton.air.screenshare.views {
 		[Inject]
 		public var model:IScreenshareModel;
 		
+		[Inject]
+		public var conferenceParameters:IConferenceParameters;
+		
 		override public function initialize():void {
 			//trace("************ ScreenshareViewMediator:: INIT **************");
 			model.screenshareStreamStartedSignal.add(viewStream);
@@ -26,11 +30,11 @@ package org.bigbluebutton.air.screenshare.views {
 		}
 		
 		public function viewStream(streamId:String, width:int, height:int):void {
-			view.viewStream(conn.connection, streamId, width, height);
+			view.startStream(conn.connection, streamId, width, height, conferenceParameters.meetingID, conferenceParameters.authToken, conferenceParameters.externUserID);
 		}
 		
 		public function streamStopped(session:String, reason:String):void {
-			view.streamStopped(session, reason);
+			view.stopStream(session, reason);
 		}
 		
 		override public function destroy():void {
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as b/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as
index 20f059643ffa6a26045f853d0e6dcc7b766e5b76..bb34b34c40d6b17e15d3cd749e9b0713cc4ce5a6 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/user/services/UsersMessageSender.as
@@ -19,7 +19,7 @@ package org.bigbluebutton.air.user.services {
 		public function joinMeeting():void {
 			var message:Object = {
 				header: {name: "UserJoinMeetingReqMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID},
-				body: {userId: conferenceParameters.internalUserID, authToken: conferenceParameters.authToken}
+				body: {userId: conferenceParameters.internalUserID, authToken: conferenceParameters.authToken, clientType: "FLASH"}
 			};
 			
 			userSession.mainConnection.sendMessage2x(defaultSuccessResponse, defaultFailureResponse, message);
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as b/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as
index 125930a9af246b027b1376628f5316c600847ecd..ceeddfb9edcb97efadd396f76b6eecd230a69c51 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/util/ConnUtil.as
@@ -14,5 +14,20 @@ package org.bigbluebutton.air.util
 				var result:Array = pattern.exec(appURL);
 				return result;
 			}
+			
+			private static function generateRandomString(strlen:Number):String{
+				var chars:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+				var num_chars:Number = chars.length - 1;
+				var randomChar:String = "";
+				
+				for (var i:Number = 0; i < strlen; i++){
+					randomChar += chars.charAt(Math.floor(Math.random() * num_chars));
+				}
+				return randomChar;
+			}
+			
+			public static function generateConnId():String {
+				return generateRandomString(15);
+			}
 	}
 }
\ No newline at end of file
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as b/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as
index b8b8dc714cbba765edfb09f614133618567cc37e..50cb850696f029fe597ed500491c3fb4de58edfe 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/video/services/VideoConnection.as
@@ -16,6 +16,7 @@ package org.bigbluebutton.air.video.services {
 	import org.bigbluebutton.air.main.models.IUserSession;
 	import org.bigbluebutton.air.main.models.LockSettings2x;
 	import org.bigbluebutton.air.user.models.UserRole;
+	import org.bigbluebutton.air.util.ConnUtil;
 	import org.bigbluebutton.air.video.commands.ShareCameraSignal;
 	import org.bigbluebutton.air.video.commands.StopShareCameraSignal;
 	import org.bigbluebutton.air.video.models.VideoProfile;
@@ -64,6 +65,8 @@ package org.bigbluebutton.air.video.services {
 		
 		protected var _selectedCameraRotation:int;
 		
+		private var _connectionId : String;
+		
 		[PostConstruct]
 		public function init():void {
 			baseConnection.init(this);
@@ -130,7 +133,8 @@ package org.bigbluebutton.air.video.services {
 		
 		public function connect():void {
 			trace("Video connect");
-			baseConnection.connect(uri, conferenceParameters.meetingID, userSession.userId, conferenceParameters.authToken);
+			_connectionId = ConnUtil.generateConnId();
+			baseConnection.connect(uri, conferenceParameters.meetingID, userSession.userId, conferenceParameters.authToken, _connectionId);
 		}
 		
 		public function disconnect(onUserCommand:Boolean):void {
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDock.as b/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDock.as
index ad7a0c3352f9a5f2a17201c587722da1267fd1ee..9d34d9f507769eb89e06e8f4df45c617371117e4 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDock.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDock.as
@@ -1,29 +1,48 @@
 package org.bigbluebutton.air.video.views {
 	import flash.net.NetConnection;
+	import flash.system.Capabilities;
 	
 	import spark.components.Group;
 	
-	import org.bigbluebutton.air.common.views.VideoView;
+	import org.bigbluebutton.air.common.views.IOSVideoView;
+	import org.bigbluebutton.air.common.views.VideoView;
 	
 	public class WebcamDock extends Group {
 		
 		private var _video:VideoView;
+		private var _iosVideoView:IOSVideoView;
 		
 		public function WebcamDock() {
 			super();
 			
-			_video = new VideoView();
-			_video.percentHeight = 100;
-			_video.percentWidth = 100;
-			addElement(_video);
+			if (Capabilities.version.indexOf("IOS") >= 0) {
+				_iosVideoView = new IOSVideoView();
+				_iosVideoView.percentWidth = 100;
+				_iosVideoView.percentHeight = 100;
+				addElement(_iosVideoView);
+			} else {
+				_video = new VideoView();
+				_video.percentHeight = 100;
+				_video.percentWidth = 100;
+				addElement(_video);	
+			}			
 		}
 		
-		public function startStream(connection:NetConnection, name:String, streamName:String, userId:String, oWidth:Number, oHeight:Number):void {
-			_video.startStream(connection, name, streamName, userId, oWidth, oHeight);
+		public function startStream(connection:NetConnection, name:String, streamName:String, userId:String, oWidth:Number, oHeight:Number, meetingId:String, authToken:String, externalUserId:String):void {
+			
+			if (Capabilities.version.indexOf("IOS") >= 0) {
+				_iosVideoView.startStream(connection.uri, streamName, oWidth, oHeight, meetingId, authToken, externalUserId);
+			} else {
+				_video.startStream(connection, name, streamName, userId, oWidth, oHeight);	
+			}
 		}
 		
 		public function closeStream():void {
-			_video.close();
+			if (Capabilities.version.indexOf("IOS") >= 0) {
+				_iosVideoView.close();
+			} else {
+				_video.close();
+			}	
 		}
 	}
 }
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDockMediator.as b/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDockMediator.as
index f1cc8bcee3c60d4d46273a6ea9225a961e8b74ba..b8a956b99efb3d17fb4ce93da2cc9cea24e71697 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDockMediator.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/video/views/WebcamDockMediator.as
@@ -1,11 +1,12 @@
 package org.bigbluebutton.air.video.views {
+	import org.bigbluebutton.air.main.models.IConferenceParameters;
 	import org.bigbluebutton.air.main.models.IMeetingData;
 	import org.bigbluebutton.air.main.models.IUserSession;
 	import org.bigbluebutton.air.video.models.VideoProfile;
 	import org.bigbluebutton.air.video.models.WebcamChangeEnum;
 	import org.bigbluebutton.air.video.models.WebcamStreamInfo;
 	
-	import robotlegs.bender.bundles.mvcs.Mediator;
+	import robotlegs.bender.bundles.mvcs.Mediator;
 	
 	public class WebcamDockMediator extends Mediator {
 		
@@ -18,6 +19,9 @@ package org.bigbluebutton.air.video.views {
 		[Inject]
 		public var userSession:IUserSession;
 		
+		[Inject]
+		public var conferenceParameters:IConferenceParameters;
+		
 		override public function initialize():void {
 			meetingData.webcams.webcamChangeSignal.add(onWebcamChangeSignal);
 			
@@ -65,7 +69,7 @@ package org.bigbluebutton.air.video.views {
 		private function startWebcam(webcam:WebcamStreamInfo):void {
 			var videoProfile:VideoProfile = userSession.videoProfileManager.getVideoProfileByStreamName(webcam.streamId);
 			if (videoProfile) {
-				view.startStream(userSession.videoConnection.connection, webcam.name, webcam.streamId, webcam.userId, videoProfile.width, videoProfile.height);
+				view.startStream(userSession.videoConnection.connection, webcam.name, webcam.streamId, webcam.userId, videoProfile.width, videoProfile.height, conferenceParameters.meetingID, conferenceParameters.authToken, conferenceParameters.externUserID);
 				meetingData.webcams.viewedWebcamStream = webcam.streamId;
 			}
 		}
diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as b/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as
index b6f4d5dae3576c3315bc98399a5776471ad6fdb3..711842d5cecbc0d486e738d1b8dc32a4bf71fa37 100755
--- a/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as
+++ b/clients/flash/air-client/src/org/bigbluebutton/air/voice/services/VoiceConnection.as
@@ -13,11 +13,11 @@ package org.bigbluebutton.air.voice.services {
 	import org.bigbluebutton.air.main.models.IUserSession;
 	import org.bigbluebutton.air.main.models.LockSettings2x;
 	import org.bigbluebutton.air.user.models.UserRole;
+	import org.bigbluebutton.air.util.ConnUtil;
 	import org.bigbluebutton.air.voice.commands.MicrophoneMuteSignal;
-	import org.bigbluebutton.air.voice.commands.ShareMicrophoneSignal;
 	import org.bigbluebutton.air.voice.models.VoiceUser;
 	import org.osflash.signals.ISignal;
-	import org.osflash.signals.Signal;
+	import org.osflash.signals.Signal;
 	
 	public class VoiceConnection extends DefaultConnectionCallback implements IVoiceConnection {
 		public const LOG:String = "VoiceConnection::";
@@ -50,6 +50,8 @@ package org.bigbluebutton.air.voice.services {
 		
 		protected var _conferenceParameters:IConferenceParameters;
 		
+		private var _connectionId : String;
+		
 		public function VoiceConnection() {
 		}
 		
@@ -116,8 +118,9 @@ package org.bigbluebutton.air.voice.services {
 			// we don't use scope in the voice communication (many hours lost on it)
 			_conferenceParameters = confParams;
 			_username = encodeURIComponent(confParams.internalUserID + "-bbbID-" + confParams.username);
+			_connectionId = ConnUtil.generateConnId();
 			trace("Voice app connect");
-			baseConnection.connect(_applicationURI, confParams.meetingID, confParams.externUserID, _username, confParams.authToken);
+			baseConnection.connect(_applicationURI, confParams.meetingID, confParams.externUserID, _username, confParams.authToken, _connectionId);
 		}
 		
 		public function disconnect(onUserCommand:Boolean):void {