diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java
index cfd35a8751753d8dc84d21974e8dd6c0b169c072..53520a6e0020ee1b71fc0b5dafff1831afc859ed 100755
--- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java
+++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java
@@ -76,7 +76,6 @@ public interface IBigBlueButtonInGW {
 	void clear(String meetingID);
 	void removePresentation(String meetingID, String presentationID);
 	void getPresentationInfo(String meetingID, String requesterID, String replyTo);
-	void sendCursorUpdate(String meetingID, double xPercent, double yPercent);
 	void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio);
 	void gotoSlide(String meetingID, String page);
 	void sharePresentation(String meetingID, String presentationID, boolean share);
@@ -110,7 +109,8 @@ public interface IBigBlueButtonInGW {
 	void clearPublicChatHistory(String meetingID, String requesterID);
 
 	// Whiteboard
-	void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation);	
+	void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation);
+	void sendCursorPosition(String meetingID, String requesterID, double xPercent, double yPercent);
 	void requestWhiteboardAnnotationHistory(String meetingID, String requesterID, String whiteboardId, String replyTo);
 	void clearWhiteboard(String meetingID, String requesterID, String whiteboardId);
 	void undoWhiteboard(String meetingID, String requesterID, String whiteboardId);
diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java
index 1709bf91b3d42516ea18009fd65432d0dbc43ff1..6338c66f8edda5b8f43c9492fb4cb7c3f9436b80 100755
--- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java
+++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java
@@ -10,7 +10,6 @@ import org.bigbluebutton.common.messages.RemovePresentationMessage;
 import org.bigbluebutton.common.messages.ResizeAndMoveSlideMessage;
 import org.bigbluebutton.common.messages.SendConversionCompletedMessage;
 import org.bigbluebutton.common.messages.SendConversionUpdateMessage;
-import org.bigbluebutton.common.messages.SendCursorUpdateMessage;
 import org.bigbluebutton.common.messages.SendPageCountErrorMessage;
 import org.bigbluebutton.common.messages.SendSlideGeneratedMessage;
 import org.bigbluebutton.common.messages.SharePresentationMessage;
@@ -118,9 +117,6 @@ public class PresentationMessageListener implements MessageHandler {
     					} else if (RemovePresentationMessage.REMOVE_PRESENTATION.equals(messageName)) {
     						RemovePresentationMessage msg = RemovePresentationMessage.fromJson(message);
     						bbbInGW.removePresentation(msg.meetingId, msg.presentationId);
-    					} else if (SendCursorUpdateMessage.SEND_CURSOR_UPDATE.equals(messageName)) {
-    						SendCursorUpdateMessage msg = SendCursorUpdateMessage.fromJson(message);
-    						bbbInGW.sendCursorUpdate(msg.meetingId, msg.xPercent, msg.yPercent);
     					} else if (SharePresentationMessage.SHARE_PRESENTATION.equals(messageName)) {
     						SharePresentationMessage msg = SharePresentationMessage.fromJson(message);
     						bbbInGW.sharePresentation(msg.meetingId, msg.presentationId, msg.share);
diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java
index a41344813b4e8d93ed9250755d182b0d9472d5db..62df29046ff01f74b288147d25f7515796101de3 100755
--- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java
+++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java
@@ -7,6 +7,7 @@ import org.bigbluebutton.common.messages.ModifyWhiteboardAccessRequestMessage;
 import org.bigbluebutton.common.messages.GetWhiteboardAccessRequestMessage;
 import org.bigbluebutton.common.messages.MessagingConstants;
 import org.bigbluebutton.common.messages.RequestWhiteboardAnnotationHistoryRequestMessage;
+import org.bigbluebutton.common.messages.SendCursorPositionMessage;
 import org.bigbluebutton.common.messages.SendWhiteboardAnnotationRequestMessage;
 import org.bigbluebutton.common.messages.UndoWhiteboardRequest;
 import org.bigbluebutton.core.api.IBigBlueButtonInGW;
@@ -52,6 +53,9 @@ public class WhiteboardMessageReceiver implements MessageHandler {
 					} else if (SendWhiteboardAnnotationRequestMessage.SEND_WHITEBOARD_ANNOTATION_REQUEST.equals(messageName)) {
 						SendWhiteboardAnnotationRequestMessage msg = SendWhiteboardAnnotationRequestMessage.fromJson(message);
 						bbbInGW.sendWhiteboardAnnotation(msg.meetingId, msg.requesterId, msg.annotation);
+					} else if (SendCursorPositionMessage.SEND_CURSOR_POSITION.equals(messageName)) {
+						SendCursorPositionMessage msg = SendCursorPositionMessage.fromJson(message);
+						bbbInGW.sendCursorPosition(msg.meetingId, msg.requesterId, msg.xPercent, msg.yPercent);
 					}
 				}
 			}
diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java
index 924c754d77834744e593f4792a535def2db3b322..22cedf83a77c1c14e3b6ab35240d9253fab15206 100755
--- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java
+++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java
@@ -18,13 +18,17 @@
 */
 package org.bigbluebutton.core.recorders.events;
 
-public class CursorUpdateRecordEvent extends AbstractPresentationRecordEvent{
+public class CursorUpdateRecordEvent extends AbstractWhiteboardRecordEvent{
 	
 	public CursorUpdateRecordEvent() {
 		super();
 		setEvent("CursorMoveEvent");
 	}
 	
+	public void setUserId(String userId) {
+		eventMap.put("userId", userId);
+	}
+	
 	public void setXPercent(double percent) {
 		eventMap.put("xOffset", Double.toString(percent));
 	}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
index b4cebad5677ce49b6af70f60d39102d3ffa5c572..4bf0c7447c45849ae2d793e5e83e23fa6d9ac077 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
@@ -367,10 +367,6 @@ class BigBlueButtonInGW(
     eventBus.publish(BigBlueButtonEvent(meetingID, new GetPresentationInfo(meetingID, requesterID, replyTo)))
   }
 
-  def sendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) {
-    eventBus.publish(BigBlueButtonEvent(meetingID, new SendCursorUpdate(meetingID, xPercent, yPercent)))
-  }
-
   def resizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) {
     eventBus.publish(BigBlueButtonEvent(meetingID, new ResizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio)))
   }
@@ -466,6 +462,10 @@ class BigBlueButtonInGW(
     }
   }
 
+  def sendCursorPosition(meetingID: String, requesterID: String, xPercent: Double, yPercent: Double) {
+    eventBus.publish(BigBlueButtonEvent(meetingID, new SendCursorPositionRequest(meetingID, requesterID, xPercent, yPercent)))
+  }
+
   def requestWhiteboardAnnotationHistory(meetingID: String, requesterID: String, whiteboardId: String, replyTo: String) {
     eventBus.publish(BigBlueButtonEvent(meetingID, new GetWhiteboardShapesRequest(meetingID, requesterID, whiteboardId, replyTo)))
   }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala
index 1a9ccde6b38cd7bcb8c7d21883aa9014b5f95916..adcc465807919dc8c59106252053900d24599d4c 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala
@@ -86,7 +86,6 @@ class MessageSenderActor(val service: MessageSender)
     case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
     case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
     case msg: GetPresentationInfoOutMsg => handleGetPresentationInfoOutMsg(msg)
-    case msg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(msg)
     case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
     case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
     case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
@@ -137,6 +136,7 @@ class MessageSenderActor(val service: MessageSender)
     case msg: LockLayoutEvent => handleLockLayoutEvent(msg)
     case msg: GetWhiteboardShapesReply => handleGetWhiteboardShapesReply(msg)
     case msg: SendWhiteboardAnnotationEvent => handleSendWhiteboardAnnotationEvent(msg)
+    case msg: CursorPositionUpdatedEvent => handleCursorPositionUpdatedEvent(msg)
     case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg)
     case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
     case msg: ModifiedWhiteboardAccessEvent => handleModifiedWhiteboardAccessEvent(msg)
@@ -381,11 +381,6 @@ class MessageSenderActor(val service: MessageSender)
     service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
   }
 
-  private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) {
-    val json = PesentationMessageToJsonConverter.sendCursorUpdateOutMsgToJson(msg)
-    service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
-  }
-
   private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) {
     val json = PesentationMessageToJsonConverter.resizeAndMoveSlideOutMsgToJson(msg)
     service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
@@ -748,6 +743,11 @@ class MessageSenderActor(val service: MessageSender)
     service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
   }
 
+  private def handleCursorPositionUpdatedEvent(msg: CursorPositionUpdatedEvent) {
+    val json = WhiteboardMessageToJsonConverter.cursorPositionUpdatedEventToJson(msg)
+    service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
+  }
+
   private def handleClearWhiteboardEvent(msg: ClearWhiteboardEvent) {
     val json = WhiteboardMessageToJsonConverter.clearWhiteboardEventToJson(msg)
     service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala
index f4b45140767f0b20f8ddbb890f42ac170fcf8a6b..533532c2b2a88dd04d4c4626ad1cad8db378d229 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala
@@ -66,7 +66,6 @@ class RecorderActor(val recorder: RecorderApplication)
     case msg: ClearPublicChatHistoryReply => handleClearPublicChatHistoryReply(msg)
     case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
     case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
-    case msg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(msg)
     case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
     case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
     case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
@@ -86,6 +85,7 @@ class RecorderActor(val recorder: RecorderApplication)
     case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
     case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
     case msg: SendWhiteboardAnnotationEvent => handleSendWhiteboardAnnotationEvent(msg)
+    case msg: CursorPositionUpdatedEvent => handleCursorPositionUpdatedEvent(msg)
     case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg)
     case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
     case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg)
@@ -196,18 +196,6 @@ class RecorderActor(val recorder: RecorderApplication)
     }
   }
 
-  private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) {
-    if (msg.recorded) {
-      val event = new CursorUpdateRecordEvent();
-      event.setMeetingId(msg.meetingID);
-      event.setTimestamp(TimestampGenerator.generateTimestamp);
-      event.setXPercent(msg.xPercent);
-      event.setYPercent(msg.yPercent);
-
-      recorder.record(msg.meetingID, event);
-    }
-  }
-
   private def handleEndAndKickAll(msg: EndAndKickAll): Unit = {
     if (msg.recorded) {
       val ev = new ParticipantEndAndKickAllRecordEvent();
@@ -444,6 +432,19 @@ class RecorderActor(val recorder: RecorderApplication)
 
   }
 
+  private def handleCursorPositionUpdatedEvent(msg: CursorPositionUpdatedEvent) {
+    if (msg.recorded) {
+      val event = new CursorUpdateRecordEvent();
+      event.setMeetingId(msg.meetingID);
+      event.setTimestamp(TimestampGenerator.generateTimestamp);
+      event.setUserId(msg.requesterID);
+      event.setXPercent(msg.xPercent);
+      event.setYPercent(msg.yPercent);
+
+      recorder.record(msg.meetingID, event);
+    }
+  }
+
   private def handleClearWhiteboardEvent(msg: ClearWhiteboardEvent) {
     if (msg.recorded) {
       val event = new ClearPageWhiteboardRecordEvent()
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
index e8c5dfdc3cb4e6f5fbb01120123a987361bd7126..1a7ef3a971fe245f5348276a1739194646ecec1d 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
@@ -137,7 +137,6 @@ case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout
 case class ClearPresentation(meetingID: String) extends InMessage
 case class RemovePresentation(meetingID: String, presentationID: String) extends InMessage
 case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
-case class SendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) extends InMessage
 case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double,
   widthRatio: Double, heightRatio: Double) extends InMessage
 case class GotoSlide(meetingID: String, page: String) extends InMessage
@@ -194,6 +193,7 @@ case class VoiceConfRecordingStartedMessage(voiceConfId: String, recordStream: S
 /////////////////////////////////////////////////////////////////////////////////////
 
 case class SendWhiteboardAnnotationRequest(meetingID: String, requesterID: String, annotation: AnnotationVO) extends InMessage
+case class SendCursorPositionRequest(meetingID: String, requesterID: String, xPercent: Double, yPercent: Double) extends InMessage
 case class GetWhiteboardShapesRequest(meetingID: String, requesterID: String, whiteboardId: String, replyTo: String) extends InMessage
 case class ClearWhiteboardRequest(meetingID: String, requesterID: String, whiteboardId: String) extends InMessage
 case class UndoWhiteboardRequest(meetingID: String, requesterID: String, whiteboardId: String) extends InMessage
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala
index 9cd8256186f198e14bbc12729f51ad5581f41e5d..acebc5ba80150bb13bb7e30e0cf51281904f9458 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala
@@ -62,7 +62,6 @@ object MessageNames {
   val PRESENTATION_PAGE_COUNT_ERROR = "presentation_page_count_error_message"
   val PRESENTATION_SLIDE_GENERATED = "presentation_slide_generated_message"
   val PRESENTATION_CONVERSION_COMPLETED = "presentation_conversion_completed_message"
-  val PRESENTATION_CURSOR_UPDATED = "presentation_cursor_updated_message"
   val SEND_VOICE_USERS_REQUEST = "send_voice_users_request"
   val MUTE_MEETING_REQUEST = "mute_meeting_request"
   val IS_MEETING_MUTED = "is_meeting_muted_request"
@@ -163,6 +162,7 @@ object MessageNames {
   val PRESENTATION_PAGE_GENERATED = "presentation_page_generated_message"
   val GET_WHITEBOARD_SHAPES_REPLY = "get_whiteboard_shapes_reply"
   val SEND_WHITEBOARD_SHAPE = "send_whiteboard_shape_message"
+  val CURSOR_POSITION_UPDATED = "cursor_position_updated_message"
   val UNDO_WHITEBOARD_MESSAGE = "undo_whiteboard_message"
   val MODIFIED_WHITEBOARD_ACCESS = "modified_whiteboard_access_message"
   val GET_WHITEBOARD_ACCESS_REPLY = "get_whiteboard_access_reply"
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala
index abb66df45a908d84544a934c33b5de5963a73358..e5260ecf91005ab9e70b2775041038f26000d40e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala
@@ -108,7 +108,6 @@ case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends
 case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage
 case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String,
   info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
-case class SendCursorUpdateOutMsg(meetingID: String, recorded: Boolean, xPercent: Double, yPercent: Double) extends IOutMessage
 case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
 case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
 case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage
@@ -145,6 +144,7 @@ case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requ
 // Whiteboard
 case class GetWhiteboardShapesReply(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shapes: Array[AnnotationVO], replyTo: String) extends IOutMessage
 case class SendWhiteboardAnnotationEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shape: AnnotationVO) extends IOutMessage
+case class CursorPositionUpdatedEvent(meetingID: String, recorded: Boolean, requesterID: String, xPercent: Double, yPercent: Double) extends IOutMessage
 case class ClearWhiteboardEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, fullClear: Boolean) extends IOutMessage
 case class UndoWhiteboardEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shapeId: String) extends IOutMessage
 case class ModifiedWhiteboardAccessEvent(meetingID: String, recorded: Boolean, requesterID: String, multiUser: Boolean) extends IOutMessage
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala
index 3710d46cd4a48b90d52c709d4f65004e8566b4f8..7ab527ca39ce807a1a8bc02d2d1baf1deaf51c57 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala
@@ -11,8 +11,6 @@ trait PresentationApp {
 
   val outGW: OutMessageGateway
 
-  private var cursorLocation = new CursorLocation
-
   def handlePreuploadedPresentations(msg: PreuploadedPresentations) {
     val pres = msg.presentations
 
@@ -83,11 +81,6 @@ trait PresentationApp {
     outGW.send(new GetPresentationInfoOutMsg(mProps.meetingID, mProps.recorded, msg.requesterID, presentationInfo, msg.replyTo))
   }
 
-  def handleSendCursorUpdate(msg: SendCursorUpdate) {
-    cursorLocation = new CursorLocation(msg.xPercent, msg.yPercent)
-    outGW.send(new SendCursorUpdateOutMsg(mProps.meetingID, mProps.recorded, msg.xPercent, msg.yPercent))
-  }
-
   def handleResizeAndMoveSlide(msg: ResizeAndMoveSlide) {
     // Force coordinate that are out-of-bounds inside valid values
     val xOffset = if (msg.xOffset <= 0) msg.xOffset else 0
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala
index ac92710ac1a93eb652a98bebcf1a2e12d98b4294..5dccb4f1f22ec1019d37a9ccb124c2e1376590a2 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala
@@ -2,7 +2,6 @@ package org.bigbluebutton.core.apps
 
 case class CurrentPresenter(userId: String, name: String, assignedBy: String)
 case class CurrentPresentationInfo(presenter: CurrentPresenter, presentations: Seq[Presentation])
-case class CursorLocation(xPercent: Double = 0D, yPercent: Double = 0D)
 case class Presentation(id: String, name: String, current: Boolean = false,
   pages: scala.collection.immutable.HashMap[String, Page], downloadable: Boolean)
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala
index 507299a5130a809fa893f16fbea0337001563c20..f6e1e317701d704d0c18ce16faeda96f631628b5 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala
@@ -47,6 +47,10 @@ trait WhiteboardApp {
 
   }
 
+  def handleSendCursorPositionRequest(msg: SendCursorPositionRequest) {
+    outGW.send(new CursorPositionUpdatedEvent(mProps.meetingID, mProps.recorded, msg.requesterID, msg.xPercent, msg.yPercent))
+  }
+
   def handleGetWhiteboardShapesRequest(msg: GetWhiteboardShapesRequest) {
     //println("WB: Received page history [" + msg.whiteboardId + "]")
     val history = liveMeeting.wbModel.getHistory(msg.whiteboardId);
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala
index 694553b1bb96a455741353a573d2639e857ed17f..0b97f4a829fee30093ed695af51e1462420951d8 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala
@@ -3,7 +3,6 @@ package org.bigbluebutton.core.apps
 import java.util.ArrayList;
 
 import org.bigbluebutton.core.util.jhotdraw.BezierWrapper
-import org.bigbluebutton.core.util.jhotdraw.PathData
 
 import scala.collection.immutable.List
 import scala.collection.immutable.HashMap
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala
index a26548a2342e7ecf2c210ce17ecc39faac493b1f..d381c21ea6f6eab182c7dfd8144f5927e45f0db2 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala
@@ -85,16 +85,6 @@ object PesentationMessageToJsonConverter {
     Util.buildJson(header, payload)
   }
 
-  def sendCursorUpdateOutMsgToJson(msg: SendCursorUpdateOutMsg): String = {
-    val payload = new java.util.HashMap[String, Any]()
-    payload.put(Constants.MEETING_ID, msg.meetingID)
-    payload.put(Constants.X_PERCENT, msg.xPercent)
-    payload.put(Constants.Y_PERCENT, msg.yPercent)
-
-    val header = Util.buildHeader(MessageNames.PRESENTATION_CURSOR_UPDATED, None)
-    Util.buildJson(header, payload)
-  }
-
   def resizeAndMoveSlideOutMsgToJson(msg: ResizeAndMoveSlideOutMsg): String = {
     val payload = new java.util.HashMap[String, Any]()
     payload.put(Constants.MEETING_ID, msg.meetingID)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala
index d2b8f337c21ec26fdf132bc160d408eb49fa4f10..66d7190f6a062fbb122c1866975f76a6d10589f9 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala
@@ -53,6 +53,17 @@ object WhiteboardMessageToJsonConverter {
     Util.buildJson(header, payload)
   }
 
+  def cursorPositionUpdatedEventToJson(msg: CursorPositionUpdatedEvent): String = {
+    val payload = new java.util.HashMap[String, Any]()
+    payload.put(Constants.MEETING_ID, msg.meetingID)
+    payload.put(Constants.REQUESTER_ID, msg.requesterID)
+    payload.put(Constants.X_PERCENT, msg.xPercent)
+    payload.put(Constants.Y_PERCENT, msg.yPercent)
+
+    val header = Util.buildHeader(MessageNames.CURSOR_POSITION_UPDATED, None)
+    Util.buildJson(header, payload)
+  }
+
   def clearWhiteboardEventToJson(msg: ClearWhiteboardEvent): String = {
     val payload = new java.util.HashMap[String, Any]()
     payload.put(Constants.MEETING_ID, msg.meetingID)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
index 1a6197fc55c4656f3e39b430ab576d908b65db29..b8104da0458ffded4a07aafb8b923afa9571a265 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
@@ -97,13 +97,13 @@ class MeetingActor(val mProps: MeetingProperties,
     case msg: PresentationConversionCompleted => handlePresentationConversionCompleted(msg)
     case msg: RemovePresentation => handleRemovePresentation(msg)
     case msg: GetPresentationInfo => handleGetPresentationInfo(msg)
-    case msg: SendCursorUpdate => handleSendCursorUpdate(msg)
     case msg: ResizeAndMoveSlide => handleResizeAndMoveSlide(msg)
     case msg: GotoSlide => handleGotoSlide(msg)
     case msg: SharePresentation => handleSharePresentation(msg)
     case msg: GetSlideInfo => handleGetSlideInfo(msg)
     case msg: PreuploadedPresentations => handlePreuploadedPresentations(msg)
     case msg: SendWhiteboardAnnotationRequest => handleSendWhiteboardAnnotationRequest(msg)
+    case msg: SendCursorPositionRequest => handleSendCursorPositionRequest(msg)
     case msg: GetWhiteboardShapesRequest => handleGetWhiteboardShapesRequest(msg)
     case msg: ClearWhiteboardRequest => handleClearWhiteboardRequest(msg)
     case msg: UndoWhiteboardRequest => handleUndoWhiteboardRequest(msg)
diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/PresentationCursorUpdateMessage.java b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/CursorPositionUpdatedMessage.java
similarity index 63%
rename from bbb-common-message/src/main/java/org/bigbluebutton/common/messages/PresentationCursorUpdateMessage.java
rename to bbb-common-message/src/main/java/org/bigbluebutton/common/messages/CursorPositionUpdatedMessage.java
index a39042ec377986cfa6e726e780bef17926f1f067..83481c4a43790ca769870e6892021987b9a0496a 100755
--- a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/PresentationCursorUpdateMessage.java
+++ b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/CursorPositionUpdatedMessage.java
@@ -4,16 +4,18 @@ import java.util.HashMap;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 
-public class PresentationCursorUpdateMessage implements ISubscribedMessage {
-	public static final String PRESENTATION_CURSOR_UPDATED = "presentation_cursor_updated_message";
+public class CursorPositionUpdatedMessage implements ISubscribedMessage {
+	public static final String CURSOR_POSITION_UPDATED = "cursor_position_updated_message";
 	public final String VERSION = "0.0.1";
 
 	public final String meetingId;
+	public final String requesterId;
 	public final double xPercent;
 	public final double yPercent;
 
-	public PresentationCursorUpdateMessage(String meetingId, double xPercent, double yPercent) {
+	public CursorPositionUpdatedMessage(String meetingId, String requesterId, double xPercent, double yPercent) {
 		this.meetingId = meetingId;
+		this.requesterId = requesterId;
 		this.xPercent = xPercent;
 		this.yPercent = yPercent;
 	}
@@ -21,15 +23,16 @@ public class PresentationCursorUpdateMessage implements ISubscribedMessage {
 	public String toJson() {
 		HashMap<String, Object> payload = new HashMap<String, Object>();
 		payload.put(Constants.MEETING_ID, meetingId);
+		payload.put(Constants.REQUESTER_ID, requesterId);
 		payload.put(Constants.X_PERCENT, xPercent);
 		payload.put(Constants.Y_PERCENT, yPercent);
 
-		java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(PRESENTATION_CURSOR_UPDATED, VERSION, null);
+		java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(CURSOR_POSITION_UPDATED, VERSION, null);
 
 		return MessageBuilder.buildJson(header, payload);
 	}
 
-	public static PresentationCursorUpdateMessage fromJson(String message) {
+	public static CursorPositionUpdatedMessage fromJson(String message) {
 		JsonParser parser = new JsonParser();
 		JsonObject obj = (JsonObject) parser.parse(message);
 
@@ -39,15 +42,17 @@ public class PresentationCursorUpdateMessage implements ISubscribedMessage {
 
 			if (header.has("name")) {
 				String messageName = header.get("name").getAsString();
-				if (PRESENTATION_CURSOR_UPDATED.equals(messageName)) {
+				if (CURSOR_POSITION_UPDATED.equals(messageName)) {
 					if (payload.has(Constants.MEETING_ID)
+							&& payload.has(Constants.REQUESTER_ID)
 							&& payload.has(Constants.X_PERCENT)
 						&& payload.has(Constants.Y_PERCENT)) {
 						String meetingId = payload.get(Constants.MEETING_ID).getAsString();
+						String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
 						double xPercent = payload.get(Constants.X_PERCENT).getAsDouble();
 						double yPercent = payload.get(Constants.Y_PERCENT).getAsDouble();
 
-						return new PresentationCursorUpdateMessage(meetingId, xPercent, yPercent);
+						return new CursorPositionUpdatedMessage(meetingId, requesterId, xPercent, yPercent);
 					}
 				}
 			}
diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorUpdateMessage.java b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorPositionMessage.java
similarity index 66%
rename from bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorUpdateMessage.java
rename to bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorPositionMessage.java
index bb11902959715aed83aecf3cd0655775b62c52fb..f768d4b84d6a69dfa923fcd8ab03afcdc004454e 100755
--- a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorUpdateMessage.java
+++ b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorPositionMessage.java
@@ -5,16 +5,18 @@ import java.util.HashMap;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 
-public class SendCursorUpdateMessage implements IBigBlueButtonMessage {
-	public static final String SEND_CURSOR_UPDATE = "send_cursor_update";
+public class SendCursorPositionMessage implements IBigBlueButtonMessage {
+	public static final String SEND_CURSOR_POSITION = "send_cursor_position";
 	public static final String VERSION = "0.0.1";
 
 	public final String meetingId;
+	public final String requesterId;
 	public final double xPercent;
 	public final double yPercent;
 
-	public SendCursorUpdateMessage(String meetingId, double xPercent, double yPercent){
+	public SendCursorPositionMessage(String meetingId, String requesterId, double xPercent, double yPercent){
 		this.meetingId = meetingId;
+		this.requesterId = requesterId;
 		this.xPercent = xPercent;
 		this.yPercent = yPercent;
 	}
@@ -22,15 +24,16 @@ public class SendCursorUpdateMessage implements IBigBlueButtonMessage {
 	public String toJson() {
 		HashMap<String, Object> payload = new HashMap<String, Object>();
 		payload.put(Constants.MEETING_ID, meetingId);
+		payload.put(Constants.REQUESTER_ID, requesterId);
 		payload.put(Constants.X_PERCENT, xPercent);
 		payload.put(Constants.Y_PERCENT, yPercent);
 
-		java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(SEND_CURSOR_UPDATE, VERSION, null);
+		java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(SEND_CURSOR_POSITION, VERSION, null);
 
 		return MessageBuilder.buildJson(header, payload);
 	}
 
-	public static SendCursorUpdateMessage fromJson(String message) {
+	public static SendCursorPositionMessage fromJson(String message) {
 		JsonParser parser = new JsonParser();
 		JsonObject obj = (JsonObject) parser.parse(message);
 
@@ -40,15 +43,17 @@ public class SendCursorUpdateMessage implements IBigBlueButtonMessage {
 
 			if (header.has("name")) {
 				String messageName = header.get("name").getAsString();
-				if (SEND_CURSOR_UPDATE.equals(messageName)) {
+				if (SEND_CURSOR_POSITION.equals(messageName)) {
 					if (payload.has(Constants.MEETING_ID)
+							&& payload.has(Constants.REQUESTER_ID)
 							&& payload.has(Constants.X_PERCENT)
 							&& payload.has(Constants.Y_PERCENT)) {
 						String meetingId = payload.get(Constants.MEETING_ID).getAsString();
+						String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
 						double xPercent = payload.get(Constants.X_PERCENT).getAsDouble();
 						double yPercent = payload.get(Constants.Y_PERCENT).getAsDouble();
 
-						return new SendCursorUpdateMessage(meetingId, xPercent, yPercent);
+						return new SendCursorPositionMessage(meetingId, requesterId, xPercent, yPercent);
 					}
 				}
 			}
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java
index b60d9f058c9735b902f1bb40803a054200778966..c8917eaf97fefef234eb7b4b11e9c3d31060b925 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java
@@ -10,7 +10,6 @@ import org.bigbluebutton.common.messages.GoToSlideReplyMessage;
 import org.bigbluebutton.common.messages.PresentationConversionDoneMessage;
 import org.bigbluebutton.common.messages.PresentationConversionErrorMessage;
 import org.bigbluebutton.common.messages.PresentationConversionProgressMessage;
-import org.bigbluebutton.common.messages.PresentationCursorUpdateMessage;
 import org.bigbluebutton.common.messages.PresentationPageGeneratedReplyMessage;
 import org.bigbluebutton.common.messages.PresentationPageResizedMessage;
 import org.bigbluebutton.common.messages.PresentationRemovedMessage;
@@ -55,9 +54,6 @@ public class PresentationClientMessageSender {
 				  case PresentationPageGeneratedReplyMessage.PRESENTATION_PAGE_GENERATED:
 					  processPresentationPageGeneratedReply(message);
 					  break;
-				  case PresentationCursorUpdateMessage.PRESENTATION_CURSOR_UPDATED:
-					  processPresentationCursorUpdate(message);
-					  break;
 				  case PresentationConversionErrorMessage.PRESENTATION_CONVERSION_ERROR:
 					  processPresentationConversionError(message);
 					  break;
@@ -227,23 +223,6 @@ public class PresentationClientMessageSender {
 		}
 	}
 
-	private void processPresentationCursorUpdate(String json) {
-		PresentationCursorUpdateMessage msg = PresentationCursorUpdateMessage.fromJson(json);
-		if (msg != null) {
-			Map<String, Object> args = new HashMap<String, Object>();
-			args.put("meetingID", msg.meetingId);
-			args.put("xPercent", msg.xPercent);
-			args.put("yPercent", msg.yPercent);
-
-			Map<String, Object> message = new HashMap<String, Object>();
-			Gson gson = new Gson();
-			message.put("msg", gson.toJson(args));
-
-			BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "PresentationCursorUpdateCommand", message);
-			service.sendMessage(m);
-		}
-	}
-
 	private void processPresentationPageGeneratedReply(String json) {
 		PresentationPageGeneratedReplyMessage msg = PresentationPageGeneratedReplyMessage.fromJson(json);
 		if (msg != null) {
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java
index 1ee5b78250c10df202206229842129745c94e1cf..7545712acb389965e074825a2349ebfdc04634c3 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java
@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.bigbluebutton.common.messages.ClearWhiteboardReplyMessage;
+import org.bigbluebutton.common.messages.CursorPositionUpdatedMessage;
 import org.bigbluebutton.common.messages.GetWhiteboardShapesReplyMessage;
 import org.bigbluebutton.common.messages.GetWhiteboardAccessReplyMessage;
 import org.bigbluebutton.common.messages.SendWhiteboardAnnotationReplyMessage;
@@ -59,6 +60,12 @@ public class WhiteboardClientMessageSender {
 							processSendWhiteboardAnnotationReplyMessage(swarm);
 						}
 						break;
+					case CursorPositionUpdatedMessage.CURSOR_POSITION_UPDATED:
+						CursorPositionUpdatedMessage cpum = CursorPositionUpdatedMessage.fromJson(message);
+						if (cpum != null) {
+							processCursorPositionUpdatedMessage(cpum);
+						}
+						break;
 					case ModifiedWhiteboardAccessMessage.MODIFIED_WHITEBOARD_ACCESS:
 						ModifiedWhiteboardAccessMessage mwam = ModifiedWhiteboardAccessMessage.fromJson(message);
 						if (mwam != null) {
@@ -100,6 +107,20 @@ public class WhiteboardClientMessageSender {
 		service.sendMessage(b);
 		
 	}
+	
+	private void processCursorPositionUpdatedMessage(CursorPositionUpdatedMessage msg) {
+		Map<String, Object> args = new HashMap<String, Object>();
+		args.put("requesterId", msg.requesterId);
+		args.put("xPercent", msg.xPercent);
+		args.put("yPercent", msg.yPercent);
+
+		Map<String, Object> message = new HashMap<String, Object>();
+		Gson gson = new Gson();
+		message.put("msg", gson.toJson(args));
+
+		BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "WhiteboardCursorPositionUpdatedCommand", message);
+		service.sendMessage(m);
+	}
 
 	private void processGetWhiteboardShapesReplyMessage(GetWhiteboardShapesReplyMessage msg) {
 
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java
index 16faf4c49e847f7d1ad399c4b4492c7d062b0128..212ee5987a1fb20ea31e3e5a343568c1a2734059 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java
@@ -180,11 +180,6 @@ public class MessagePublisher {
 
 	}
 
-	public void sendCursorUpdate(String meetingID, double xPercent, double yPercent) {
-		SendCursorUpdateMessage msg = new SendCursorUpdateMessage(meetingID, xPercent, yPercent);
-		sender.send(MessagingConstants.TO_PRESENTATION_CHANNEL, msg.toJson());
-	}
-
 	public void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio) {
 		ResizeAndMoveSlideMessage msg = new ResizeAndMoveSlideMessage(meetingID, xOffset, yOffset, widthRatio, heightRatio);
 		sender.send(MessagingConstants.TO_PRESENTATION_CHANNEL, msg.toJson());
@@ -262,11 +257,17 @@ public class MessagePublisher {
 		DeskShareGetInfoRequestMessage msg = new DeskShareGetInfoRequestMessage(meetingID, requesterID, replyTo);
 		sender.send(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson());
 	}
+
 	public void sendWhiteboardAnnotation(String meetingID, String requesterID, Map<String, Object> annotation) {
 		SendWhiteboardAnnotationRequestMessage msg = new SendWhiteboardAnnotationRequestMessage(meetingID, requesterID, annotation);
 		sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson());
 	}
 
+	public void sendCursorPosition(String meetingID, String requesterID, double xPercent, double yPercent) {
+		SendCursorPositionMessage msg = new SendCursorPositionMessage(meetingID, requesterID, xPercent, yPercent);
+		sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson());
+	}
+
 	public void requestWhiteboardAnnotationHistory(String meetingID, String requesterID, String whiteboardId, String replyTo) {
 		RequestWhiteboardAnnotationHistoryRequestMessage msg = new RequestWhiteboardAnnotationHistoryRequestMessage(meetingID, requesterID, whiteboardId, replyTo);
 		sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson());
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java
index 45375188da97143c351a1e0c0ce99475724d9503..da9f85321a0dc8c5f3f905cdbe8d228ed1860030 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java
@@ -77,11 +77,6 @@ public class PresentationApplication {
 		red5BBBInGW.getPresentationInfo(meetingID, requesterID, replyTo);
 	}
 
-	public void sendCursorUpdate(String meetingID, Double xPercent, Double yPercent) {	
-
-		red5BBBInGW.sendCursorUpdate(meetingID, xPercent, yPercent);
-	}
-
 	public void resizeAndMoveSlide(String meetingID, Double xOffset, Double yOffset, Double widthRatio, Double heightRatio) {
 
 		red5BBBInGW.resizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio);
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java
index 7a647bbdd11cee47b2265934c964a95cccb10067..d3ce4c6b04a4f2e79bd618f30c61080b3e258c4c 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java
@@ -73,29 +73,6 @@ public class PresentationService {
     presentationApplication.sharePresentation(scope.getName(), presentationID, share);
   }
 
-  public void sendCursorUpdate(Map<String, Object> msg) {
-    IScope scope = Red5.getConnectionLocal().getScope();
-
-    Double xPercent;
-    if (msg.get("xPercent") instanceof Integer) {
-      Integer tempXOffset = (Integer) msg.get("xPercent");
-      xPercent = tempXOffset.doubleValue();
-    } else {
-      xPercent = (Double) msg.get("xPercent");
-    }
-
-    Double yPercent;
-
-    if (msg.get("yPercent") instanceof Integer) {
-      Integer tempYOffset = (Integer) msg.get("yPercent");
-      yPercent = tempYOffset.doubleValue();
-    } else {
-      yPercent = (Double) msg.get("yPercent");
-    }
-
-    presentationApplication.sendCursorUpdate(scope.getName(), xPercent, yPercent);
-  }
-
   public void resizeAndMoveSlide(Map<String, Object> msg) {
     Double xOffset;
     if (msg.get("xOffset") instanceof Integer) {
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java
index 34be53789b673357a22883bf82066d788f7074bd..2a328d32541f8e48150ca9084cd574d3b48078a6 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java
@@ -99,6 +99,10 @@ public class WhiteboardApplication implements IApplication {
 	public void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> shape) {
 		red5BBBInGW.sendWhiteboardAnnotation(meetingID, requesterID, shape);
 	}
+	
+	public void sendCursorPosition(String meetingID, String requesterID, Double xPercent, Double yPercent) {
+		red5BBBInGW.sendCursorPosition(meetingID, requesterID, xPercent, yPercent);
+	}
 
 	public void clearWhiteboard(String meetingID, String requesterID, String whiteboardId) {
 		red5BBBInGW.clearWhiteboard(meetingID, requesterID, whiteboardId);
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java
index a373787be7b4e22fd01eff212685d7f4b57abd14..434991a4626a77d3f37bca1ff86e761e2a4299bc 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java
@@ -24,6 +24,7 @@ import org.bigbluebutton.red5.BigBlueButtonSession;
 import org.bigbluebutton.red5.Constants;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.api.Red5;
+import org.red5.server.api.scope.IScope;
 import org.slf4j.Logger;
 
 public class WhiteboardService {
@@ -47,19 +48,6 @@ public class WhiteboardService {
 		return false;
 	}
 	public void sendAnnotation(Map<String, Object> annotation) {
-//		for (Map.Entry<String, Object> entry : annotation.entrySet()) {
-//		    String key = entry.getKey();
-//		    Object value = entry.getValue();
-		    
-//		    if (key.equals("points")) {
-//		    	String points = "points=[";
-//		    	ArrayList<Double> v = (ArrayList<Double>) value;
-//		    	log.debug(points + pointsToString(v) + "]");
-//		    } else {
-//		    	log.debug(key + "=[" + value + "]");
-//		    }
-//		}
-			
 		String meetingID = getMeetingId();
 		String requesterID = getBbbSession().getInternalUserID();
 		
@@ -68,18 +56,29 @@ public class WhiteboardService {
 		}		
 	}
 	
-	/*private String pointsToString(ArrayList<Double> points){
-    	String datapoints = "";
-    	for (Double i : points) {
-    		datapoints += i + ",";
-    	}
-    	// Trim the trailing comma
-//    	log.debug("Data Point = " + datapoints);
-    	return datapoints.substring(0, datapoints.length() - 1);
+	public void sendCursorPosition(Map<String, Object> msg) {
+		String meetingID = getMeetingId();
+		String requesterID = getBbbSession().getInternalUserID();
+		
+		Double xPercent;
+		if (msg.get("xPercent") instanceof Integer) {
+			Integer tempXOffset = (Integer) msg.get("xPercent");
+			xPercent = tempXOffset.doubleValue();
+		} else {
+			xPercent = (Double) msg.get("xPercent");
+		}
 
-//		application.sendShape(shape, type, color, thickness, fill, fillColor, transparency, id, status);
+		Double yPercent;
 
-	}*/
+		if (msg.get("yPercent") instanceof Integer) {
+			Integer tempYOffset = (Integer) msg.get("yPercent");
+			yPercent = tempYOffset.doubleValue();
+		} else {
+			yPercent = (Double) msg.get("yPercent");
+		}
+
+		application.sendCursorPosition(meetingID, requesterID, xPercent, yPercent);
+	}
 	
 	public void requestAnnotationHistory(Map<String, Object> message) {
 		log.info("WhiteboardApplication - requestAnnotationHistory");
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as
old mode 100644
new mode 100755
index 5b040abab2b3a117859dfee3b2548a57694e8aa5..4e2e3b500fa236bd4ea6c993bd45050513460768
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as
@@ -229,15 +229,5 @@ package org.bigbluebutton.modules.present.business
 		public function zoomSlide(e:PresenterCommands):void{
       		sender.move(e.xOffset, e.yOffset, e.slideToCanvasWidthRatio, e.slideToCanvasHeightRatio);
 		}
-		
-		/**
-		 * Update the presenter cursor within the presentation window 
-		 * @param e
-		 * 
-		 */		
-		public function sendCursorUpdate(e:PresenterCommands):void{
-			sender.sendCursorUpdate(e.xPercent, e.yPercent);
-		}
-		
 	}
 }
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as
index 654b27f7931159d3950e63ee6e7df275c2d007d0..c8df6ffa38dc2d05fe82da8e63a777637a8be31b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as
@@ -34,7 +34,6 @@ package org.bigbluebutton.modules.present.events
 		public static const RESET_ZOOM:String = "RESTORE_ZOOM";
 		public static const MOVE:String = "MOVE_COMMAND";
 		public static const SHARE_PRESENTATION_COMMAND:String = "SHARE_PRESENTATION_COMMAND";
-		public static const SEND_CURSOR_UPDATE:String = "SEND_CURSOR_UPDATE";
 		
 		//Parameter for the slide navigation events
 		public var slideNumber:Number;
@@ -45,10 +44,6 @@ package org.bigbluebutton.modules.present.events
 		//Parameters for the resize event
 		public var newSizeInPercent:Number;
 		
-		//Parameters for the cursor event
-		public var xPercent:Number;
-		public var yPercent:Number;
-		
 		//Parameters for the move event
 		public var xOffset:Number;
 		public var yOffset:Number;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml
index ed9bd0a7369e38d8d080fa4d6dbfafeac4ea3395..24a547f7d255e593db96df2dda3d18febbec7046 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml
@@ -108,10 +108,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
   <EventHandlers type="{GetListOfPresentationsRequest.GET_LIST_OF_PRESENTATIONS}" >
     <MethodInvoker generator="{PresentProxy}" method="handleGetListOfPresentationsRequest" />
   </EventHandlers>
-  
-	<EventHandlers type="{PresenterCommands.SEND_CURSOR_UPDATE}" >
-		<MethodInvoker generator="{PresentProxy}" method="sendCursorUpdate" arguments="{event}" />
-	</EventHandlers>
 	
 	<EventHandlers type="{PresenterCommands.RESIZE}" >
 		<MethodInvoker generator="{PresentProxy}" method="resizeSlide" arguments="{event}" />
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as
index 0fad260c6f79819644ad10b43816a9478241d4f7..29e43eab75ae47065fec27818b5516870f339557 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as
@@ -5,7 +5,6 @@ package org.bigbluebutton.modules.present.services
   import mx.collections.ArrayCollection;
   
   import org.bigbluebutton.modules.present.commands.ChangePageCommand;
-  import org.bigbluebutton.modules.present.events.CursorEvent;
   import org.bigbluebutton.modules.present.events.PageChangedEvent;
   import org.bigbluebutton.modules.present.events.PresentationChangedEvent;
   import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
@@ -35,13 +34,6 @@ package org.bigbluebutton.modules.present.services
       dispatcher = new Dispatcher();
     }
     
-    public function cursorMoved(x: Number, y: Number):void {
-      var e:CursorEvent = new CursorEvent(CursorEvent.UPDATE_CURSOR);
-      e.xPercent = x;
-      e.yPercent = y;
-      dispatcher.dispatchEvent(e);
-    }
-    
     public function pageChanged(page: PageVO):void {
       var np: Page = model.getPage(page.id);
       if (np != null) {        
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as
index ead0449d8f11377883ef89abe12662cd7d925779..85dcfa103259fdf4731028a66aedb2f25a5955c9 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as
@@ -60,9 +60,6 @@ package org.bigbluebutton.modules.present.services.messaging
       //LOGGER.info("Presentation: received message " + messageName);
       
       switch (messageName) {
-        case "PresentationCursorUpdateCommand":
-          handlePresentationCursorUpdateCommand(message);
-          break;			
         case "goToSlideCallback":
           handleGotoSlideCallback(message);
           break;			
@@ -101,14 +98,6 @@ package org.bigbluebutton.modules.present.services.messaging
      
     }
     
-    private function handlePresentationCursorUpdateCommand(msg:Object):void {    
-//      trace(LOG + "*** handlePresentationCursorUpdateCommand " + msg.msg + " **** \n");      
-      var map:Object = JSON.parse(msg.msg);      
-      if (map.hasOwnProperty("xPercent") && map.hasOwnProperty("yPercent")) {
-        service.cursorMoved(map.xPercent, map.yPercent);
-      }
-    }
-    
     private function handleGotoSlideCallback(msg:Object) : void {
       var map:Object = JSON.parse(msg.msg);
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as
index 00cccb12b20fc4db9f6e7814f430ad7ba057ecdd..6c09c2f9a1e228f64eb85660130e949534ab6b85 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as
@@ -27,29 +27,6 @@ package org.bigbluebutton.modules.present.services.messaging
     
 	private static const LOGGER:ILogger = getClassLogger(MessageSender);
     
-    /**
-     * Send an event to the server to update the presenter's cursor view on the client 
-     * @param xPercent
-     * @param yPercent
-     * 
-     */		
-    public function sendCursorUpdate(xPercent:Number, yPercent:Number):void{
-      var message:Object = new Object();
-      message["xPercent"] = xPercent;
-      message["yPercent"] = yPercent;
-      
-      var _nc:ConnectionManager = BBB.initConnectionManager();
-      _nc.sendMessage("presentation.sendCursorUpdate", 
-        function(result:String):void { // On successful result
-		  //LOGGER.debug(result); 
-        },	                   
-        function(status:String):void { // status - On error occurred
-		  LOGGER.error(status); 
-        },
-        message
-      );		      
-    }
-    
     /**
      * Sends an event to the server to update the clients with the new slide position 
      * @param slideXPosition
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml
index 0a2ffd2a13d2d84ec587077ca16db1253aca4faa..36f2c17a1be59365d7edfae5a8d703ce2e5d7c7d 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml
@@ -28,15 +28,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	x="{slideModel.viewportX}" y="{slideModel.viewportY}"
   creationComplete="onCreationComplete()" 
 	verticalScrollPolicy="off" 
-	horizontalScrollPolicy="off"      
-  rollOut="hideCursor()" styleName="presentationSlideViewStyle"
+	horizontalScrollPolicy="off"
+	styleName="presentationSlideViewStyle"
   xmlns:views="org.bigbluebutton.modules.present.views.*">
      
   <mate:Listener type="{PageChangedEvent.PRESENTATION_PAGE_CHANGED_EVENT}" method="handlePageChangedEvent" />
   <mate:Listener type="{PageLoadedEvent.PAGE_LOADED_EVENT}" method="handlePageLoadedEvent" />
   <mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="handleSwitchToPresenterEvent" />
   <mate:Listener type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}" method="handleSwitchToViewerEvent" />
-  <mate:Listener type="{CursorEvent.UPDATE_CURSOR}" method="handleUpdateCursorEvent" />
   <mate:Listener type="{ShortcutEvent.FOCUS_SLIDE}" method="focusSlide" />
 	<mx:Script>
 		<![CDATA[
@@ -46,7 +45,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import mx.collections.Sort;
 			import mx.collections.SortField;
 			import mx.containers.Canvas;
-			import mx.managers.CursorManager;
 			
 			import org.as3commons.logging.api.ILogger;
 			import org.as3commons.logging.api.getClassLogger;
@@ -55,7 +53,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.main.events.MadePresenterEvent;
 			import org.bigbluebutton.main.events.ShortcutEvent;
 			import org.bigbluebutton.modules.present.commands.GoToPageCommand;
-			import org.bigbluebutton.modules.present.events.CursorEvent;
 			import org.bigbluebutton.modules.present.events.DisplaySlideEvent;
 			import org.bigbluebutton.modules.present.events.PageChangedEvent;
 			import org.bigbluebutton.modules.present.events.PageLoadedEvent;
@@ -73,8 +70,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			[Bindable] public var zoomPercentage:Number = 100;
 			public static const ZOOM_STEP:int = 5;
 			public static const THUMBNAILS_CLOSED:String = "ThumbnailsClosed";
-									
-			private var cursor:Shape;
+			
 			private var whiteboardCanvas:WhiteboardCanvas;
 										
 			private var dispatcher:Dispatcher = new Dispatcher();
@@ -84,21 +80,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
       private var pageCache:ArrayCollection = new ArrayCollection();
       
-      // Send update of mouse location to other users.
-      private var _sendCurrentMouseLocTimer:Timer = new Timer(100);
-      private var _lastMouseXPosition:Number = 0;
-      private var _lastMouseYPosition:Number = 0;
-      
 			private function onCreationComplete():void {
 				slideLoader.width = this.width;
 				slideLoader.height = this.height;
 				
-				cursor = new Shape();
-				cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
-				cursor.graphics.drawCircle(0,0,2.5);
-				this.rawChildren.addChild(cursor);
-				cursor.visible = false;
-				
 				this.setChildIndex(thumbnailView, this.numChildren - 1);
 				
 				/*
@@ -340,8 +325,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       private function becomeViewer():void {
         removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
         this.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
-        _sendCurrentMouseLocTimer.stop();
-        _sendCurrentMouseLocTimer.removeEventListener(TimerEvent.TIMER, mouseCursorUpdateTimerListener);        
       }
       
 			/**
@@ -361,9 +344,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
         addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
         this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
-        _sendCurrentMouseLocTimer.addEventListener(TimerEvent.TIMER, mouseCursorUpdateTimerListener);
-        _sendCurrentMouseLocTimer.start();
-        notifyOthersOfZoomEvent();        
+        notifyOthersOfZoomEvent();
       }
       
 			/**
@@ -373,53 +354,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         becomePresenter();
 			}
 			
-			
-      public function mouseCursorUpdateTimerListener(e:TimerEvent):void{
-        if (noSlideContentLoaded()) return;				
-        notifyOthersOfPresentersCursorPosition(this.mouseX, this.mouseY);
-      }
-			
-			/**
-			 * Broadcast to other participants the location fo the mouse cursor.
-			 */
-			private function notifyOthersOfPresentersCursorPosition(cursorXPosition:int, cursorYPosition:int):void {
-        // Only update the other users if the mouse moved a certain delta
-        if ( (Math.abs(cursorXPosition - _lastMouseXPosition) < 0.1) 
-          && (Math.abs(cursorYPosition - _lastMouseYPosition) < 0.1) ) {
-          return;
-        }
-        
-        if (cursorXPosition > this.width || cursorXPosition < 1 
-              || cursorYPosition > this.height || cursorYPosition < 1) {
-//          LogUtil.debug("Cursor outside the window...not sending [" + cursorXPosition + "," + cursorYPosition + "]");
-          return;
-        }
-          
-        _lastMouseXPosition = cursorXPosition;
-        _lastMouseYPosition = cursorYPosition;
-        
-				var command:PresenterCommands = new PresenterCommands(PresenterCommands.SEND_CURSOR_UPDATE);				
-				command.xPercent = cursorXPosition / this.width;
-				command.yPercent = cursorYPosition / this.height;				
-				dispatchEvent(command);
-			}
-			
-			/**
-			 * Handle notification from presenter about the location of the mouse cursor.
-			 */
-			private function handleUpdateCursorEvent(e:CursorEvent):void{
-				if (noSlideContentLoaded()) return;
-				
-				cursor.x = e.xPercent * this.width;
-				cursor.y = e.yPercent * this.height;
-								
-				if (isCursorOutsideWindow(e)) {
-					hideCursor()
-				} else {
-					showCursor();
-				}	
-			}
-			
 			private function noSlideContentLoaded():Boolean {
 				return slideLoader.content == null
 			}
@@ -443,20 +377,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				dispEvent.slideHeight = slideRealHeight;
 				dispatcher.dispatchEvent(dispEvent);
 			}
-						
-			private function isCursorOutsideWindow(e:CursorEvent):Boolean {
-				return (e.xPercent > 1 && e.yPercent > 1) 
-                || (cursor.x > this.width || cursor.x < 1
-                || cursor.y > this.height || cursor.y < 1);
-			}
-			
-			private function showCursor():void {
-				cursor.visible = true;
-			}
-			
-			private function hideCursor():void{
-				cursor.visible = false;
-			}
 			
 			public function acceptOverlayCanvas(overlay:WhiteboardCanvas):void{
 				whiteboardCanvas = overlay;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as
index 0f137f4bf6a70264f56d4159bf8ce2a96f766e10..f5133121714c5420b3caa062dca121fdc70cd6d7 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as
@@ -23,6 +23,7 @@ package org.bigbluebutton.modules.whiteboard
   import flash.events.FocusEvent;
   import flash.events.KeyboardEvent;
   import flash.ui.Keyboard;
+  import flash.utils.Dictionary;
   
   import org.as3commons.logging.api.ILogger;
   import org.as3commons.logging.api.getClassLogger;
@@ -42,6 +43,7 @@ package org.bigbluebutton.modules.whiteboard
   import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel;
   import org.bigbluebutton.modules.whiteboard.views.TextUpdateListener;
   import org.bigbluebutton.modules.whiteboard.views.WhiteboardCanvas;
+  import org.bigbluebutton.modules.whiteboard.views.WhiteboardCursor;
   
     /**
     * Class to handle displaying of received annotations from the server.
@@ -52,11 +54,13 @@ package org.bigbluebutton.modules.whiteboard
     private var whiteboardModel:WhiteboardModel;
     private var wbCanvas:WhiteboardCanvas;  
     private var _annotationsList:Array = new Array();
+	private var _cursors:Object = new Object();
     private var shapeFactory:ShapeFactory = new ShapeFactory();
     private var textUpdateListener:TextUpdateListener = new TextUpdateListener();
     
     private var width:Number;
     private var height:Number;
+	private var presenterId:String;
 	
 	public function setDependencies(whiteboardCanvas:WhiteboardCanvas, whiteboardModel:WhiteboardModel):void {
 		wbCanvas = whiteboardCanvas;
@@ -209,6 +213,32 @@ package org.bigbluebutton.modules.whiteboard
                 }
             }
         }
+		
+		public function drawCursor(userId:String, xPercent:Number, yPercent:Number):void {
+			if (!_cursors.hasOwnProperty(userId)) {
+				var newCursor:WhiteboardCursor = new WhiteboardCursor(userId, xPercent, yPercent, shapeFactory.parentWidth, shapeFactory.parentHeight, presenterId == userId);
+				wbCanvas.addCursor(newCursor);
+				
+				_cursors[userId] = newCursor;
+			} else {
+				(_cursors[userId] as WhiteboardCursor).updatePosition(xPercent, yPercent);
+			}
+		}
+		
+		public function presenterChange(amIPresenter:Boolean, presenterId:String):void {
+			this.presenterId = presenterId;
+			
+			for(var j:String in _cursors) {
+				(_cursors[j] as WhiteboardCursor).updatePresenter(j == presenterId);
+			}
+		}
+		
+		public function userLeft(userId:String):void {
+			if (_cursors.hasOwnProperty(userId)) {
+				wbCanvas.removeCursorChild(_cursors[userId]);
+				delete _cursors[userId];
+			}
+		}
     
     public function zoomCanvas(width:Number, height:Number):void{
       shapeFactory.setParentDim(width, height);  
@@ -218,6 +248,10 @@ package org.bigbluebutton.modules.whiteboard
       for (var i:int = 0; i < this._annotationsList.length; i++){
           redrawGraphic(this._annotationsList[i] as GraphicObject, i);
       }
+	  
+	  for(var j:String in _cursors) {
+		  (_cursors[j] as WhiteboardCursor).updateParentSize(width, height);
+	  }
     }
   
     private function redrawGraphic(gobj:GraphicObject, objIndex:int):void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as
index 93bb55d31a4bb2f2d04a792495fb38aeebca70a3..1976c39d88284a37113f896870c93948adfc6838 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as
@@ -26,6 +26,7 @@ package org.bigbluebutton.modules.whiteboard
   import org.bigbluebutton.modules.whiteboard.business.shapes.ShapeFactory;
   import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel;
   import org.bigbluebutton.modules.whiteboard.views.AnnotationIDGenerator;
+  import org.bigbluebutton.modules.whiteboard.views.CursorPositionListener;
   import org.bigbluebutton.modules.whiteboard.views.IDrawListener;
   import org.bigbluebutton.modules.whiteboard.views.PencilDrawListener;
   import org.bigbluebutton.modules.whiteboard.views.ShapeDrawListener;
@@ -39,32 +40,23 @@ package org.bigbluebutton.modules.whiteboard
   public class WhiteboardCanvasModel {
     private var _wbCanvas:WhiteboardCanvas;	      
     private var drawListeners:Array = new Array();
+	private var cursorPositionListener:CursorPositionListener;
     private var wbTool:WhiteboardTool = new WhiteboardTool();
     private var shapeFactory:ShapeFactory = new ShapeFactory();
     private var idGenerator:AnnotationIDGenerator = new AnnotationIDGenerator();
-
-    /* represents the max number of 'points' enumerated in 'segment' before 
-      sending an update to server. Used to prevent spamming red5 with unnecessary packets */
-    private var sendShapeFrequency:uint = 30;	
-
-    /* same as above, except a faster interval may be desirable when erasing, for aesthetics */
-    private var sendEraserFrequency:uint = 20;	
-
-    private var width:Number;
-    private var height:Number;
         
-    public function setDependencies(canvas:WhiteboardCanvas, displayModel:WhiteboardCanvasDisplayModel):void {
+    public function setDependencies(canvas:WhiteboardCanvas):void {
       _wbCanvas = canvas;
       
       drawListeners.push(new PencilDrawListener(idGenerator, _wbCanvas, shapeFactory));
       drawListeners.push(new ShapeDrawListener(idGenerator, _wbCanvas, shapeFactory));
       drawListeners.push(new TextDrawListener(idGenerator, _wbCanvas, shapeFactory));
+	  
+	  cursorPositionListener = new CursorPositionListener(_wbCanvas, shapeFactory);
     }
         
     public function zoomCanvas(width:Number, height:Number):void {
-      shapeFactory.setParentDim(width, height);	
-      this.width = width;
-      this.height = height;	
+      shapeFactory.setParentDim(width, height);
     }
         
     public function changeFontStyle(font:String):void {
@@ -112,6 +104,14 @@ package org.bigbluebutton.modules.whiteboard
     public function changeThickness(thickness:uint):void {
       wbTool.thickness = thickness;
     }
+	
+	public function presenterChange(amIPresenter:Boolean, presenterId:String):void {
+		cursorPositionListener.presenterChange(amIPresenter);
+	}
+	
+	public function multiUserChange(multiUser:Boolean):void {
+		cursorPositionListener.multiUserChange(multiUser);
+	}
 
     /** Helper method to test whether this user is the presenter */
     private function get isPresenter():Boolean {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/CursorEvent.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/events/WhiteboardCursorEvent.as
similarity index 71%
rename from bigbluebutton-client/src/org/bigbluebutton/modules/present/events/CursorEvent.as
rename to bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/events/WhiteboardCursorEvent.as
index b783adaf58525990086ae44809818581fca759f0..ac7d6e6154b639fa2b65b10d242b3d08ad9f297f 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/CursorEvent.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/events/WhiteboardCursorEvent.as
@@ -16,19 +16,18 @@
 * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 *
 */
-package org.bigbluebutton.modules.present.events
-{
+package org.bigbluebutton.modules.whiteboard.events {
 	import flash.events.Event;
 	
-	public class CursorEvent extends Event
-	{
-		public static const UPDATE_CURSOR:String = "UPDATE_CURSOR";
+	public class WhiteboardCursorEvent extends Event {
+		public static const SEND_CURSOR_POSITION:String = "SEND_CURSOR_POSITION";
+		public static const RECEIVED_CURSOR_POSITION:String = "RECEIVE_CURSOR_POSITION";
 		
 		public var xPercent:Number;
 		public var yPercent:Number;
+		public var userId:String;
 		
-		public function CursorEvent(type:String)
-		{
+		public function WhiteboardCursorEvent(type:String) {
 			super(type, true, false);
 		}
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml
index 75f5c2ff5492cb82ac4f9bf8bd99f3e172d57136..c771f555b0213455cdc551bdca7647d7cbf134b9 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml
@@ -32,6 +32,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.modules.whiteboard.events.StartWhiteboardModuleEvent;
 			import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent;
 			import org.bigbluebutton.modules.whiteboard.events.WhiteboardButtonEvent;
+			import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent;
 			import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
 			import org.bigbluebutton.modules.whiteboard.events.WhiteboardUpdateReceived;
 			import org.bigbluebutton.modules.whiteboard.managers.WhiteboardManager;
@@ -80,6 +81,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		<MethodInvoker generator="{WhiteboardService}" method="undoGraphic" arguments="{event}" />
 	</EventHandlers>
 	
+	<EventHandlers type="{WhiteboardCursorEvent.SEND_CURSOR_POSITION}" >
+		<MethodInvoker generator="{WhiteboardService}" method="sendCursorPosition" arguments="{event}" />
+	</EventHandlers>
+	
 	<EventHandlers type="{GetWhiteboardShapesCommand.GET_SHAPES}" >
 		<MethodInvoker generator="{WhiteboardService}" method="getAnnotationHistory" arguments="{event}" />
 	</EventHandlers>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as
index 140ef52ada2aabc3e08c601de11483f3ef04b386..e9410aa03c8583c672feb7b0e07cd2219eedc089 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as
@@ -31,6 +31,7 @@ package org.bigbluebutton.modules.whiteboard.models
 	import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject;
 	import org.bigbluebutton.modules.whiteboard.commands.GetWhiteboardShapesCommand;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent;
+	import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardUpdateReceived;
 
@@ -153,11 +154,19 @@ package org.bigbluebutton.modules.whiteboard.models
       var event:WhiteboardAccessEvent = new WhiteboardAccessEvent(WhiteboardAccessEvent.MODIFIED_WHITEBOARD_ACCESS);
       event.multiUser = multiUser;
       dispatchEvent(event);
-   }
+    }
+    
+    public function get multiUser():Boolean {
+      return _multiUser;
+    }
+	
+    public function updateCursorPosition(userId:String, xPercent:Number, yPercent:Number):void {
+      var event:WhiteboardCursorEvent = new WhiteboardCursorEvent(WhiteboardCursorEvent.RECEIVED_CURSOR_POSITION);
+      event.userId = userId;
+      event.xPercent = xPercent;
+      event.yPercent = yPercent;
+      dispatchEvent(event);
+    }
 	
-	public function get multiUser():Boolean {
-		return _multiUser;
-	}
-
 	}
 }
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as
index 8c4b0a1dd283ff5416eb0393a797346b711c713a..f52c216f4c95ecb976bbd2cf9e55f5766ab7c122 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as
@@ -49,16 +49,19 @@ package org.bigbluebutton.modules.whiteboard.services
           break;
         case "WhiteboardAccessModifiedCommand":
           handleWhiteboardAccessModifiedCommand(message);
-          break;    
+          break;
         case "WhiteboardNewAnnotationCommand":
           handleNewAnnotationCommand(message);
           break;  
         case "WhiteboardClearCommand":
           handleClearCommand(message);
-          break;  
+          break;
         case "WhiteboardUndoCommand":
           handleUndoCommand(message);
-          break;  			
+          break;
+        case "WhiteboardCursorPositionUpdatedCommand":
+          handleCursorPositionUpdatedCommand(message);
+          break;
         default:
 //          LogUtil.warn("Cannot handle message [" + messageName + "]");
       }
@@ -124,5 +127,11 @@ package org.bigbluebutton.modules.whiteboard.services
         }
       }
     }
+    
+    private function handleCursorPositionUpdatedCommand(message:Object):void {
+      var map:Object = JSON.parse(message.msg);
+      
+      whiteboardModel.updateCursorPosition(map.requesterId, map.xPercent, map.yPercent);
+    }
   }
 }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as
index b187e2f6e9a4f66fe5c7f181240e663e91bc0933..4a711ab430c6f5c0cf89311457a4dabf49662dc7 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as
@@ -143,5 +143,28 @@ package org.bigbluebutton.modules.whiteboard.services
 					e.annotation.annotation
 			);
 		}
+		
+		/**
+		 * Send an event to the server to update the user's cursor position
+		 * @param xPercent
+		 * @param yPercent
+		 * 
+		 */
+		public function sendCursorPosition(xPercent:Number, yPercent:Number):void {
+			var message:Object = new Object();
+			message["xPercent"] = xPercent;
+			message["yPercent"] = yPercent;
+			
+			var _nc:ConnectionManager = BBB.initConnectionManager();
+			_nc.sendMessage("whiteboard.sendCursorPosition", 
+				function(result:String):void { // On successful result
+					//LOGGER.debug(result); 
+				},
+				function(status:String):void { // status - On error occurred
+					LOGGER.error(status); 
+				},
+				message
+			);
+		}
 	}
 }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as
index 4e54ef4ae96ca771bb162a861e558b732541e66c..a825d39593261a06c242fa953c925ee7e3499f0c 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as
@@ -21,8 +21,9 @@ package org.bigbluebutton.modules.whiteboard.services
   import org.as3commons.logging.api.ILogger;
   import org.as3commons.logging.api.getClassLogger;
   import org.bigbluebutton.modules.whiteboard.commands.GetWhiteboardShapesCommand;
-  import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
   import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent;
+  import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent;
+  import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
   import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel;
 
   public class WhiteboardService
@@ -66,6 +67,8 @@ package org.bigbluebutton.modules.whiteboard.services
       sender.sendShape(e);
     }
 
-
+    public function sendCursorPosition(e:WhiteboardCursorEvent):void {
+      sender.sendCursorPosition(e.xPercent, e.yPercent);
+    }
   }
 }
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/CursorPositionListener.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/CursorPositionListener.as
new file mode 100755
index 0000000000000000000000000000000000000000..7b573f8bdd95cb19681d6bc50b03c3378a49d8eb
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/CursorPositionListener.as
@@ -0,0 +1,87 @@
+package org.bigbluebutton.modules.whiteboard.views {
+	import flash.events.TimerEvent;
+	import flash.geom.Point;
+	import flash.utils.Timer;
+	
+	import org.bigbluebutton.modules.whiteboard.business.shapes.ShapeFactory;
+
+	public class CursorPositionListener {
+		
+		private var _wbCanvas:WhiteboardCanvas;
+		private var _shapeFactory:ShapeFactory;
+		
+		private var _timer:Timer;
+		private var _lastXPosition:Number;
+		private var _lastYPosition:Number;
+		
+		private var _amIPresenter:Boolean;
+		private var _multiUser:Boolean;
+		
+		public function CursorPositionListener(wbCanvas:WhiteboardCanvas, shapeFactory:ShapeFactory) {
+			_wbCanvas = wbCanvas;
+			_shapeFactory = shapeFactory;
+			
+			_lastXPosition = -1;
+			_lastYPosition = 1;
+			
+			_timer = new Timer(100);
+			_timer.addEventListener(TimerEvent.TIMER, onTimerInterval);
+		}
+		
+		public function presenterChange(amIPresenter:Boolean):void {
+			_amIPresenter = amIPresenter;
+			verifyTimerState();
+		}
+		
+		public function multiUserChange(multiUser:Boolean):void {
+			_multiUser = multiUser;
+			verifyTimerState();
+		}
+		
+		private function verifyTimerState():void {
+			if (_amIPresenter || _multiUser) {
+				startTimer();
+			} else {
+				stopTimer();
+			}
+		}
+		
+		private function startTimer():void {
+			if (!_timer.running) {
+				_timer.start();
+			}
+		}
+		
+		private function stopTimer():void {
+			if (_timer.running) {
+				_timer.stop();
+				checkMousePosition(-1, -1)
+			}
+		}
+		
+		private function onTimerInterval(e:TimerEvent):void {
+			checkMousePosition(_wbCanvas.mouseX, _wbCanvas.mouseY);
+		}
+		
+		private function checkMousePosition(x:Number, y:Number):void {
+			// check if mouse position is within bounds
+			if (isXYOutsideCanvas(x, y)){
+				x = -1;
+				y = -1;
+			}
+			
+			if (x != _lastXPosition || y != _lastYPosition) {
+				_lastXPosition = x;
+				_lastYPosition = y;
+				
+				var np:Point = _shapeFactory.normalizePoint(x, y);
+				
+				_wbCanvas.sendCursorPositionToServer(np.x, np.y);
+			}
+		}
+		
+		private function isXYOutsideCanvas(x:Number, y:Number):Boolean {
+			return (x < 0 || y < 0 || x > _wbCanvas.width || y > _wbCanvas.height);
+		}
+	}
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as
index 50463b10725dcddeced9e1de1f2ec1b19ae8761f..aa6a6fd1f00dd19ab46d67151bea5ff7653ba56b 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as
@@ -84,10 +84,12 @@ package org.bigbluebutton.modules.whiteboard.views
           //normalize points as we get them to avoid shape drift
           var np:Point = _shapeFactory.normalizePoint(mouseX, mouseY);
           
+          var statusToSend:String = (_segment.length == 2 ? AnnotationStatus.DRAW_START : AnnotationStatus.DRAW_UPDATE);
+          
           _segment[2] = np.x;
           _segment[3] = np.y;
           
-          sendShapeToServer(AnnotationStatus.DRAW_UPDATE, tool);
+          sendShapeToServer(statusToSend, tool);
         }
       }
     }
@@ -102,14 +104,20 @@ package org.bigbluebutton.modules.whiteboard.views
             */
           _isDrawing = false;
           
+          //normalize points as we get them to avoid shape drift
+          var np:Point = _shapeFactory.normalizePoint(mouseX, mouseY);
+          
+          _segment[2] = np.x;
+          _segment[3] = np.y;
+          
           sendShapeToServer(AnnotationStatus.DRAW_END, tool);
         } /* (_isDrawing) */                
       }
     }
     
     private function sendShapeToServer(status:String, tool:WhiteboardTool):void {
-      if (_segment.length == 0) {
-//        LogUtil.debug("SEGMENT LENGTH = 0");
+      if (_segment.length > 2) {
+        // LogUtil.debug("SEGMENT too short");
         return;
       }
                        
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as
index 75de21a24634bea34adbcfd2322833b191973acd..8697eeb53191808e616e4808af8e7d2af6417b59 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as
@@ -25,12 +25,15 @@ package org.bigbluebutton.modules.whiteboard.views {
 	import flash.display.DisplayObject;
 	import flash.events.Event;
 	import flash.events.MouseEvent;
+	import flash.geom.Point;
 	
 	import mx.containers.Canvas;
 	import mx.managers.CursorManager;
 	
 	import org.bigbluebutton.common.Images;
+	import org.bigbluebutton.core.UsersUtil;
 	import org.bigbluebutton.main.events.MadePresenterEvent;
+	import org.bigbluebutton.main.events.UserLeftEvent;
 	import org.bigbluebutton.modules.whiteboard.WhiteboardCanvasDisplayModel;
 	import org.bigbluebutton.modules.whiteboard.WhiteboardCanvasModel;
 	import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject;
@@ -39,6 +42,7 @@ package org.bigbluebutton.modules.whiteboard.views {
 	import org.bigbluebutton.modules.whiteboard.commands.GetWhiteboardShapesCommand;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardButtonEvent;
+	import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
 	import org.bigbluebutton.modules.whiteboard.events.WhiteboardUpdateReceived;
 	import org.bigbluebutton.modules.whiteboard.models.Annotation;
@@ -52,8 +56,9 @@ package org.bigbluebutton.modules.whiteboard.views {
 		private var textToolbar:WhiteboardTextToolbar;
 		
 		private var graphicObjectHolder:Canvas = new Canvas();
-		private var images:Images = new Images();
+		private var cursorObjectHolder:Canvas = new Canvas();
 		
+		private var images:Images = new Images();
 		[Bindable] private var pencil_icon:Class = images.pencil_icon;
 		[Bindable] private var rectangle_icon:Class = images.square_icon;
 		[Bindable] private var triangle_icon:Class = images.triangle_icon;
@@ -64,12 +69,14 @@ package org.bigbluebutton.modules.whiteboard.views {
 		private var whiteboardEnabled:Boolean = false;
 		private var currentWhiteboardId:String;
 		
+		private var dispatcher:Dispatcher = new Dispatcher();
+		
 		public function WhiteboardCanvas(wbModel:WhiteboardModel):void {
 			canvasModel = new WhiteboardCanvasModel();
 			canvasDisplayModel = new WhiteboardCanvasDisplayModel();
 			
 			//set up model cross dependencies
-			canvasModel.setDependencies(this, canvasDisplayModel);
+			canvasModel.setDependencies(this);
 			canvasDisplayModel.setDependencies(this, wbModel);
 			
 			whiteboardToolbar = new WhiteboardToolbar();
@@ -87,17 +94,36 @@ package org.bigbluebutton.modules.whiteboard.views {
 			graphicObjectHolder.clipContent = true;
 			graphicObjectHolder.tabFocusEnabled = false;
 			
-			addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
-			addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
+			//create the cursor display container
+			this.addChild(cursorObjectHolder);
+			cursorObjectHolder.x = 0;
+			cursorObjectHolder.y = 0;
+			cursorObjectHolder.clipContent = true;
+			cursorObjectHolder.tabFocusEnabled = false;
 			
 			wbModel.addEventListener(WhiteboardUpdateReceived.NEW_ANNOTATION, onNewAnnotationEvent);
 			wbModel.addEventListener(WhiteboardUpdateReceived.RECEIVED_ANNOTATION_HISTORY, onReceivedAnnotationsHistory);
 			wbModel.addEventListener(WhiteboardUpdateReceived.CLEAR_ANNOTATIONS, onClearAnnotations);
 			wbModel.addEventListener(WhiteboardUpdateReceived.UNDO_ANNOTATION, onUndoAnnotation);
 			wbModel.addEventListener(WhiteboardAccessEvent.MODIFIED_WHITEBOARD_ACCESS, onModifiedAccess);
+			wbModel.addEventListener(WhiteboardCursorEvent.RECEIVED_CURSOR_POSITION, onReceivedCursorPosition);
 			
 			whiteboardToolbar.addEventListener(WhiteboardButtonEvent.ENABLE_WHITEBOARD, onEnableWhiteboardEvent);
 			whiteboardToolbar.addEventListener(WhiteboardButtonEvent.DISABLE_WHITEBOARD, onDisableWhiteboardEvent);
+			
+			var stpl:Listener = new Listener();
+			stpl.type = MadePresenterEvent.SWITCH_TO_PRESENTER_MODE;
+			stpl.method = onSwitchToPresenterEvent;
+			
+			var stvl:Listener = new Listener();
+			stvl.type = MadePresenterEvent.SWITCH_TO_VIEWER_MODE;
+			stvl.method = onSwitchToViewerEvent;
+			
+			presenterChange(UsersUtil.amIPresenter(), UsersUtil.getPresenterUserID());
+			
+			var ull:Listener = new Listener();
+			ull.type = UserLeftEvent.LEFT;
+			ull.method = onUserLeftEvent;
 		}
 		
 		public function attachToReceivingObject(ro:IWhiteboardReceiver):void {
@@ -107,14 +133,19 @@ package org.bigbluebutton.modules.whiteboard.views {
 		
 		private function registerForMouseEvents():void {
 			addEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
+			addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
+			addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
 		}
 		
 		private function unregisterForMouseEvents():void {
 			removeEventListener(MouseEvent.MOUSE_DOWN, doMouseDown);
+			removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
+			removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
 		}
 		
 		private function doMouseUp(event:MouseEvent):void {
-			canvasModel.doMouseUp(Math.min(Math.max(parent.mouseX, 0), parent.width) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height) - this.y);
+			var mousePoint:Point = getMouseXY();
+			canvasModel.doMouseUp(mousePoint.x, mousePoint.y);
 			
 			stage.removeEventListener(MouseEvent.MOUSE_UP, doMouseUp);
 			stage.removeEventListener(MouseEvent.MOUSE_MOVE, doMouseMove);
@@ -130,7 +161,8 @@ package org.bigbluebutton.modules.whiteboard.views {
 		}
 		
 		private function doMouseMove(event:MouseEvent):void {
-			canvasModel.doMouseMove(Math.min(Math.max(parent.mouseX, 0), parent.width-1) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height-1) - this.y);
+			var mousePoint:Point = getMouseXY();
+			canvasModel.doMouseMove(mousePoint.x, mousePoint.y);
 		}
 		
 		public function changeColor(e:Event):void {
@@ -145,24 +177,28 @@ package org.bigbluebutton.modules.whiteboard.views {
 			// LogUtil.debug("DISPATCHING SEND sendGraphicToServer [" + type + "]");
 			var event:WhiteboardDrawEvent = new WhiteboardDrawEvent(WhiteboardDrawEvent.SEND_SHAPE);
 			event.annotation = gobj;
-			var dispatcher:Dispatcher = new Dispatcher();
-			dispatcher.dispatchEvent(event);					
+			dispatcher.dispatchEvent(event);
 		}
 		
 		public function sendUndoToServer():void {
 			var event:WhiteboardDrawEvent = new WhiteboardDrawEvent(WhiteboardDrawEvent.UNDO);
 			event.wbId = currentWhiteboardId;
-			var dispatcher:Dispatcher = new Dispatcher();
 			dispatcher.dispatchEvent(event);
 		}
 		
 		public function sendClearToServer():void {
 			var event:WhiteboardDrawEvent = new WhiteboardDrawEvent(WhiteboardDrawEvent.CLEAR);
 			event.wbId = currentWhiteboardId;
-			var dispatcher:Dispatcher = new Dispatcher();
 			dispatcher.dispatchEvent(event);			
 		}
 		
+		public function sendCursorPositionToServer(x:Number, y:Number):void {
+			var event:WhiteboardCursorEvent = new WhiteboardCursorEvent(WhiteboardCursorEvent.SEND_CURSOR_POSITION);
+			event.xPercent = x;
+			event.yPercent = y;
+			dispatcher.dispatchEvent(event);
+		}
+		
 		public function setGraphicType(type:String):void {
 			if (canvasModel == null) return;
 			canvasModel.setGraphicType(type);
@@ -214,16 +250,21 @@ package org.bigbluebutton.modules.whiteboard.views {
 			CursorManager.removeCursor(CursorManager.currentCursorID);
 		}
 		
-		public function doesContain(child:DisplayObject):Boolean {
-			return this.graphicObjectHolder.rawChildren.contains(child);
+		private function getMouseXY():Point {
+			return new Point(Math.min(Math.max(parent.mouseX, 0), parent.width-1) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height-1) - this.y);
 		}
 		
-		public function getMouseXY():Array {
-			return [Math.min(Math.max(parent.mouseX, 0), parent.width-2) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height-2) - this.y];
+		private function presenterChange(amIPresenter:Boolean, presenterId:String):void {
+			canvasModel.presenterChange(amIPresenter, presenterId);
+			canvasDisplayModel.presenterChange(amIPresenter, presenterId);
+		}
+		
+		public function doesContainGraphic(child:DisplayObject):Boolean {
+			return this.graphicObjectHolder.rawChildren.contains(child);
 		}
 		
 		public function removeGraphic(child:DisplayObject):void {
-			if (doesContain(child)) this.graphicObjectHolder.rawChildren.removeChild(child);
+			if (doesContainGraphic(child)) this.graphicObjectHolder.rawChildren.removeChild(child);
 			else trace("Does not contain");
 		}
 		
@@ -231,6 +272,18 @@ package org.bigbluebutton.modules.whiteboard.views {
 			this.graphicObjectHolder.rawChildren.addChild(child);
 		}
 		
+		private function doesContainCursor(cursor:DisplayObject):Boolean {
+			return this.cursorObjectHolder.rawChildren.contains(cursor);
+		}
+		
+		public function addCursor(cursor:DisplayObject):void {
+			this.cursorObjectHolder.rawChildren.addChild(cursor);
+		}
+		
+		public function removeCursorChild(cursor:DisplayObject):void {
+			if (doesContainCursor(cursor)) this.cursorObjectHolder.rawChildren.removeChild(cursor);
+		}
+		
 		public function textToolbarSyncProxy(tobj:TextObject):void {
 			textToolbar.syncPropsWith(tobj);
 		}
@@ -243,6 +296,8 @@ package org.bigbluebutton.modules.whiteboard.views {
 		public function zoomCanvas(width:Number, height:Number):void {
 			graphicObjectHolder.width = width;
 			graphicObjectHolder.height = height;
+			cursorObjectHolder.width = width;
+			cursorObjectHolder.height = height;
 			this.width = width;
 			this.height = height;	
 			canvasDisplayModel.zoomCanvas(width, height);
@@ -282,9 +337,14 @@ package org.bigbluebutton.modules.whiteboard.views {
 		private function onModifiedAccess(e:WhiteboardAccessEvent):void {
 			//if (e.whiteboardId == currentWhiteboardId) {
 			whiteboardToolbar.whiteboardAccessModified(e.multiUser);
+			canvasModel.multiUserChange(e.multiUser);
 			//}
 		}
 		
+		private function onReceivedCursorPosition(e:WhiteboardCursorEvent):void {
+			canvasDisplayModel.drawCursor(e.userId, e.xPercent, e.yPercent);
+		}
+		
 		private function onEnableWhiteboardEvent(e:WhiteboardButtonEvent):void {
 			e.stopPropagation();
 			
@@ -298,5 +358,17 @@ package org.bigbluebutton.modules.whiteboard.views {
 			this.whiteboardEnabled = false;
 			setWhiteboardInteractable();
 		}
+		
+		private function onSwitchToPresenterEvent(e:MadePresenterEvent):void {
+			presenterChange(true, e.userID);
+		}
+		
+		private function onSwitchToViewerEvent(e:MadePresenterEvent):void {
+			presenterChange(false, e.userID);
+		}
+		
+		private function onUserLeftEvent(e:UserLeftEvent):void {
+			canvasDisplayModel.userLeft(e.userID);
+		}
 	}
 }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCursor.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCursor.as
new file mode 100755
index 0000000000000000000000000000000000000000..ae87c19039c2b9ec8551d71bf34d1beb154621ab
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCursor.as
@@ -0,0 +1,102 @@
+/**
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ * 
+ * Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ * 
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package org.bigbluebutton.modules.whiteboard.views {
+	import flash.display.Shape;
+	
+	public class WhiteboardCursor extends Shape {
+		private static const PRESENTER_COLOR:uint = 0xFF0000;
+		private static const OTHER_COLOR:uint = 0x00FF00;
+		
+		private var _userId:String;
+		private var _origX:Number;
+		private var _origY:Number;
+		private var _parentWidth:Number;
+		private var _parentHeight:Number;
+		private var _isPresenter:Boolean;
+		
+		public function WhiteboardCursor(userId:String, x:Number, y:Number, parentWidth:Number, parentHeight:Number, isPresenter:Boolean) {
+			_userId = userId;
+			_origX = x;
+			_origY = y;
+			_parentWidth = parentWidth;
+			_parentHeight = parentHeight;
+			_isPresenter = isPresenter;
+			
+			drawCursor();
+			setPosition();
+		}
+		
+		public function updatePosition(x:Number, y:Number):void {
+			_origX = x;
+			_origY = y;
+			
+			setPosition();
+		}
+		
+		public function updateParentSize(parentWidth:Number, parentHeight:Number):void {
+			_parentWidth = parentWidth;
+			_parentHeight = parentHeight;
+			
+			setPosition();
+		}
+		
+		public function updatePresenter(isPresenter:Boolean):void {
+			_isPresenter = isPresenter;
+			
+			drawCursor();
+		}
+		
+		private function setPosition():void {
+			x = denormalize(_origX, _parentWidth);
+			y = denormalize(_origY, _parentHeight);
+			
+			if (isCursorOutsideWindow()) {
+				hideCursor()
+			} else {
+				showCursor();
+			}	
+		}
+		
+		private function showCursor():void {
+			visible = true;
+		}
+		
+		private function hideCursor():void{
+			visible = false;
+		}
+		
+		private function isCursorOutsideWindow():Boolean {
+			return (_origX > 100 || _origX < 0 ||
+					_origY > 100 || _origY < 0);
+		}
+		
+		private function drawCursor():void {
+			var cursorColor:uint = (_isPresenter ? PRESENTER_COLOR : OTHER_COLOR);
+			
+			graphics.clear();
+			graphics.lineStyle(6, cursorColor, 0.6);
+			graphics.drawCircle(0,0,2.5);
+		}
+		
+		private function denormalize(val:Number, side:Number):Number {
+			return (val*side)/100.0;
+		}
+	}
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml
index 08ddea6168192a29880dfddb85eae73c6c496dd4..387b584ce2aaabc2af7260e90ed8ab2552285729 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml
@@ -93,11 +93,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			 * @param e The event
 			 * 
 			 */		
-			protected function setTextColor(e:Event):void{
-				enableTextToolbar();
-				this.textColor = e.target.selectedColor;
-				currentlySelectedTextObject.applyNewFormat(textColor, textSize);
-				canvas.stage.focus = currentlySelectedTextObject;
+			protected function onFontColorChange(e:Event):void{
+				setTextColor(e.target.selectedColor);
 			}
 			
 			/**
@@ -110,6 +107,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				this.textSize = size;
 				currentlySelectedTextObject.applyNewFormat(textColor, textSize);
 			}
+			
+			protected function setTextColor(color:uint):void {
+				enableTextToolbar();
+				this.textColor = color;
+				currentlySelectedTextObject.applyNewFormat(textColor, textSize);
+			}
 						
 			private function viewerMode(e:MadePresenterEvent):void{
 				disableTextToolbar();
@@ -134,9 +137,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				if(tobj != null) {
 					enableTextToolbar();
 					repositionToolbar();
-					this.textColor = ctextpik.selectedColor = tobj.textColor;
-					this.textSizeMenu.selectedItem = String(tobj.fontSize);
-					this.textSize = tobj.fontSize;
+					setTextColor(ctextpik.selectedColor);
+					setTextSize(Number(textSizeMenu.selectedItem));
 				} else {
 					disableTextToolbar();
 				}
@@ -170,26 +172,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			public function adjustForZoom(x:Number, y:Number):void {
 				repositionToolbar();
 			}
-			
-			/* used to check whether or not the TextToolbar and its children have focus when
-				checking whether or not it should be made visible=false. see handleObjDeselected().
-			*/
-			private function containsFocus(obj:DisplayObjectContainer):Boolean {
-				if(obj.stage.focus == obj) return true;
-				
-				for (var i:int = 0; i < obj.numChildren; i++) {
-					var currObj:DisplayObject = obj.getChildAt(i);
-					if(obj.stage.focus == currObj) return true;
-				}
-				
-				return false;
-			}		
 		]]>
 	</mx:Script>
 
-	<mx:ColorPicker width="20" height="20"  change="setTextColor(event)" id="ctextpik" selectedColor="0x000000"
+	<mx:ColorPicker width="20" height="20"  change="onFontColorChange(event)" id="ctextpik" selectedColor="0x000000"
 					toolTip="{ResourceUtil.getInstance().getString('ltbcustom.bbb.highlighter.texttoolbar.textColorPicker')}"/>
 
-	<views:CustomComboBox id="textSizeMenu" dataProvider="{fontSizes}" change="onFontSizeChange()" rowCount="8"
+	<views:CustomComboBox id="textSizeMenu" dataProvider="{fontSizes}" selectedItem="18" change="onFontSizeChange()" rowCount="8"
 				 toolTip="{ResourceUtil.getInstance().getString('ltbcustom.bbb.highlighter.texttoolbar.textSizeMenu')}" />
 </mx:HBox>