diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala
index c16fb0729a478de07a69744f0a445b06b817d8de..e6d0ba5bd538bbfe5934e7af0f6beb90ee7e3cba 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala
@@ -9,10 +9,11 @@ object BreakoutModel {
     externalId:    String,
     name:          String,
     sequence:      Integer,
+    freeJoin:      Boolean,
     voiceConf:     String,
     assignedUsers: Vector[String]
   ): BreakoutRoom2x = {
-    new BreakoutRoom2x(id, externalId, name, parentId, sequence, voiceConf, assignedUsers, Vector(), Vector(), None, false)
+    new BreakoutRoom2x(id, externalId, name, parentId, sequence, freeJoin, voiceConf, assignedUsers, Vector(), Vector(), None, false)
   }
 
 }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala
index 67af751dc9b659b06479a939cc0ca4464be6217d..cccb9fa0f69c261f4775f039f317113ab4dcb893 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomCreatedMsgHdlr.scala
@@ -61,7 +61,7 @@ trait BreakoutRoomCreatedMsgHdlr extends BreakoutHdlrHelpers {
 
   def sendBreakoutRoomsList(breakoutModel: BreakoutModel): BreakoutModel = {
     val breakoutRooms = breakoutModel.rooms.values.toVector map { r =>
-      new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence)
+      new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.freeJoin)
     }
 
     log.info("Sending breakout rooms list to {} with containing {} room(s)", liveMeeting.props.meetingProp.intId, breakoutRooms.length)
@@ -88,7 +88,7 @@ trait BreakoutRoomCreatedMsgHdlr extends BreakoutHdlrHelpers {
       BbbCommonEnvCoreMsg(envelope, event)
     }
 
-    val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence)
+    val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence, room.freeJoin)
     val event = build(liveMeeting.props.meetingProp.intId, breakoutInfo)
     outGW.send(event)
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomsListMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomsListMsgHdlr.scala
index 6a76462d8a4e859014862a56e22e68481da28d6d..860c3bcdc73975b6faba7ec1721e3df7c163ca51 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomsListMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomsListMsgHdlr.scala
@@ -28,7 +28,7 @@ trait BreakoutRoomsListMsgHdlr {
       breakoutModel <- state.breakout
     } yield {
       val rooms = breakoutModel.rooms.values.toVector map { r =>
-        new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence)
+        new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.freeJoin)
       }
       val ready = breakoutModel.hasAllStarted()
       broadcastEvent(rooms, ready)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala
index cf21ed82be664321a3d30d71ff8d2b9b33c727e2..f384c215f332c97af78faf57b4ede5bbecf552a6 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala
@@ -36,7 +36,7 @@ trait CreateBreakoutRoomsCmdMsgHdlr {
       val (internalId, externalId) = BreakoutRoomsUtil.createMeetingIds(liveMeeting.props.meetingProp.intId, i)
       val voiceConf = BreakoutRoomsUtil.createVoiceConfId(liveMeeting.props.voiceProp.voiceConf, i)
 
-      val breakout = BreakoutModel.create(parentId, internalId, externalId, room.name, room.sequence, voiceConf, room.users)
+      val breakout = BreakoutModel.create(parentId, internalId, externalId, room.name, room.sequence, room.freeJoin, voiceConf, room.users)
       rooms = rooms + (breakout.id -> breakout)
     }
 
@@ -45,6 +45,7 @@ trait CreateBreakoutRoomsCmdMsgHdlr {
         breakout.id, breakout.name,
         liveMeeting.props.meetingProp.intId,
         breakout.sequence,
+        breakout.freeJoin,
         breakout.voiceConf,
         msg.body.durationInMinutes,
         liveMeeting.props.password.moderatorPass,
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala
index 2b89955293596741e650061c4d0df956f4771735..00c1eea66d63f94992b076d6a2b75d829f45ea22 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala
@@ -6,6 +6,7 @@ case class BreakoutRoom2x(
     name:          String,
     parentId:      String,
     sequence:      Int,
+    freeJoin:      Boolean,
     voiceConf:     String,
     assignedUsers: Vector[String],
     users:         Vector[BreakoutUser],
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/BreakoutRooms.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/BreakoutRooms.scala
index 07462b5f133310b934657911b73a2627f8ab5294..1d82379414d14233f289f1d7a865f063a1892917 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/BreakoutRooms.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/BreakoutRooms.scala
@@ -9,9 +9,9 @@ object BreakoutRooms {
   def breakoutRoomsdurationInMinutes(status: BreakoutRooms) = status.breakoutRoomsdurationInMinutes
   def breakoutRoomsdurationInMinutes(status: BreakoutRooms, duration: Int) = status.breakoutRoomsdurationInMinutes = duration
 
-  def newBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String,
-                      assignedUsers: Vector[String], breakoutRooms: BreakoutRooms): Option[BreakoutRoomVO] = {
-    val brvo = new BreakoutRoomVO(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector())
+  def newBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, freeJoin: Boolean,
+                      voiceConfId: String, assignedUsers: Vector[String], breakoutRooms: BreakoutRooms): Option[BreakoutRoomVO] = {
+    val brvo = new BreakoutRoomVO(id, externalMeetingId, name, parentRoomId, sequence, freeJoin, voiceConfId, assignedUsers, Vector())
     breakoutRooms.add(brvo)
     Some(brvo)
   }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala
index c0e6555d37d4a12f67f0b838cd1e95a8cf470e9d..327f07665550e3a3d0bbcf5db445df89e4a54889 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala
@@ -2,7 +2,6 @@ package org.bigbluebutton.core.pubsub.senders
 
 import org.bigbluebutton.core.api._
 import org.bigbluebutton.core.messaging.Util
-import org.bigbluebutton.messages._
 
 object MeetingMessageToJsonConverter {
   def meetingDestroyedToJson(msg: MeetingDestroyed): String = {
diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequestPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequestPayload.java
index 55a6944c39b402b4a77074a56cbdf0531fb82110..ed50b1d8e94a7d29461cd1fc6aee0ea3319ecb4a 100755
--- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequestPayload.java
+++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequestPayload.java
@@ -19,6 +19,7 @@ public class CreateMeetingRequestPayload {
     public final String createDate;
     public final Boolean isBreakout;
     public final Integer sequence;
+    public final Boolean freeJoin;
     public final Map<String, String> metadata;
     public final String guestPolicy;
 
@@ -28,7 +29,8 @@ public class CreateMeetingRequestPayload {
                                        Boolean autoStartRecording, Boolean allowStartStopRecording,
                                        Boolean webcamsOnlyForModerator, String moderatorPass,
                                        String viewerPass, Long createTime, String createDate,
-                                       Boolean isBreakout, Integer sequence, Map<String, String> metadata, String guestPolicy) {
+                                       Boolean isBreakout, Integer sequence, Boolean freeJoin,
+                                       Map<String, String> metadata, String guestPolicy) {
         this.id = id;
         this.externalId = externalId;
         this.parentId = parentId;
@@ -45,6 +47,7 @@ public class CreateMeetingRequestPayload {
         this.createDate = createDate;
         this.isBreakout = isBreakout;
         this.sequence = sequence;
+        this.freeJoin = freeJoin;
         this.metadata = metadata;
         this.guestPolicy = guestPolicy;
     }
diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala
index b4e0e92aa2ba50dcf4f371142d687e2a0624180d..3981dfd5e78f499cfc08fb5e203e37a8cd4f9e51 100755
--- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala
+++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala
@@ -8,7 +8,7 @@ warnMinutesBeforeMax:     Int, meetingExpireIfNoUserJoinedInMinutes: Int,
 
 case class MeetingProp(name: String, extId: String, intId: String, isBreakout: Boolean)
 
-case class BreakoutProps(parentId: String, sequence: Int, breakoutRooms: Vector[String])
+case class BreakoutProps(parentId: String, sequence: Int, freeJoin: Boolean, breakoutRooms: Vector[String])
 
 case class PasswordProp(moderatorPass: String, viewerPass: String)
 
diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala
index 191163a56ea8020aa2630d7da04babeda3fcf9df..d92c5fb31024c232f9cac98d17aefb02a436fb64 100755
--- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala
+++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala
@@ -14,7 +14,7 @@ package org.bigbluebutton.common2.msgs
   object BreakoutRoomsListEvtMsg { val NAME = "BreakoutRoomsListEvtMsg" }
   case class BreakoutRoomsListEvtMsg(header: BbbClientMsgHeader, body: BreakoutRoomsListEvtMsgBody) extends BbbCoreMsg
   case class BreakoutRoomsListEvtMsgBody(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean)
-  case class BreakoutRoomInfo(name: String, externalId: String, breakoutId: String, sequence: Int)
+  case class BreakoutRoomInfo(name: String, externalId: String, breakoutId: String, sequence: Int, freeJoin:Boolean)
 
   object BreakoutRoomsListMsg { val NAME = "BreakoutRoomsListMsg" }
   case class BreakoutRoomsListMsg(header: BbbClientMsgHeader, body: BreakoutRoomsListMsgBody) extends StandardMsg
@@ -39,7 +39,7 @@ package org.bigbluebutton.common2.msgs
   case class CreateBreakoutRoomSysCmdMsg(header: BbbCoreBaseHeader,
                                       body: CreateBreakoutRoomSysCmdMsgBody) extends BbbCoreMsg
   case class CreateBreakoutRoomSysCmdMsgBody(meetingId: String, room: BreakoutRoomDetail)
-  case class BreakoutRoomDetail(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
+  case class BreakoutRoomDetail(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer, freeJoin:Boolean,
                                 voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
                                 sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
 
@@ -49,7 +49,7 @@ package org.bigbluebutton.common2.msgs
   object CreateBreakoutRoomsCmdMsg { val NAME = "CreateBreakoutRoomsCmdMsg" }
   case class CreateBreakoutRoomsCmdMsg(header: BbbClientMsgHeader, body: CreateBreakoutRoomsCmdMsgBody) extends StandardMsg
   case class CreateBreakoutRoomsCmdMsgBody(meetingId: String, durationInMinutes: Int, record: Boolean, rooms: Vector[BreakoutRoomMsgBody])
-  case class BreakoutRoomMsgBody(name: String, sequence: Int, users: Vector[String])
+  case class BreakoutRoomMsgBody(name: String, sequence: Int, freeJoin:Boolean, users: Vector[String])
 
   // Sent by user to request ending all the breakout rooms
   object EndAllBreakoutRoomsMsg { val NAME = "EndAllBreakoutRoomsMsg" }
@@ -89,7 +89,7 @@ case class RequestBreakoutJoinURLRespMsgBody(parentId: String, breakoutId: Strin
   case class BreakoutUserVO(id: String, name: String)
 
   case class BreakoutRoomVO(id: String, externalId: String, name: String, parentId: String,
-                            sequence: Int, voiceConf: String,
+                            sequence: Int, freeJoin: Boolean, voiceConf: String,
                             assignedUsers: Vector[String], users: Vector[BreakoutUserVO])
 
 
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java
index 1640afdb08ade50ea6e530977b1f7ef6f9da689f..589e5c7bf8c822aa66ce3e54d7686a80394fc655 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java
@@ -246,6 +246,7 @@ public class MeetingService implements MessageListener {
         Map<String, String> breakoutMetadata = new TreeMap<String, String>();
         breakoutMetadata.put("meetingId", m.getExternalId());
         breakoutMetadata.put("sequence", m.getSequence().toString());
+        breakoutMetadata.put("freeJoin", m.isFreeJoin().toString());
         breakoutMetadata.put("parentMeetingId", m.getParentMeetingId());
         storeService.recordBreakoutInfo(m.getInternalId(), breakoutMetadata);
       }
@@ -256,6 +257,7 @@ public class MeetingService implements MessageListener {
     logData.put("externalMeetingId", m.getExternalId());
     if (m.isBreakout()) {
       logData.put("sequence", m.getSequence());
+      logData.put("freeJoin", m.isFreeJoin());
       logData.put("parentMeetingId", m.getParentMeetingId());
     }
     logData.put("name", m.getName());
@@ -277,7 +279,7 @@ public class MeetingService implements MessageListener {
       m.getAllowStartStopRecording(), m.getWebcamsOnlyForModerator(),
       m.getModeratorPassword(), m.getViewerPassword(),
       m.getCreateTime(), formatPrettyDate(m.getCreateTime()),
-      m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy(), m.getWelcomeMessageTemplate(),
+      m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(), m.getGuestPolicy(), m.getWelcomeMessageTemplate(),
       m.getWelcomeMessage(), m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers(),
       m.getMaxInactivityTimeoutMinutes(), m.getWarnMinutesBeforeMax(),
       m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getmeetingExpireWhenLastUserLeftInMinutes(),
@@ -412,6 +414,7 @@ public class MeetingService implements MessageListener {
       params.put("parentMeetingID", message.parentMeetingId);
       params.put("isBreakout", "true");
       params.put("sequence", message.sequence.toString());
+      params.put("freeJoin", message.freeJoin.toString());
       params.put("attendeePW", message.viewerPassword);
       params.put("moderatorPW", message.moderatorPassword);
       params.put("voiceBridge", message.voiceConfId);
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java
index 878dd0d0fd8ec69acf37cb7841f54bcd44c51817..ec09d552a8ae78dacae6a1e70513182615e4ea64 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java
@@ -482,6 +482,7 @@ public class ParamsProcessorUtil {
         // Add extra parameters for breakout room
         if (isBreakout) {
             meeting.setSequence(Integer.parseInt(params.get("sequence")));
+            meeting.setFreeJoin(Boolean.parseBoolean(params.get("freeJoin")));
             meeting.setParentMeetingId(parentMeetingId);
         }
 
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java
index 627d3346670c09571a00b64afa5b7045b2721650..99ec4c9ed56522ed1fe982a65f304ac495c1e4d5 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java
@@ -32,7 +32,8 @@ public class Meeting {
 	private String intMeetingId;
 	private String parentMeetingId = "bbb-none"; // Initialize so we don't send null in the json message.
 	private Integer sequence = 0;
-	private Integer duration = 0;	 
+	private Boolean freeJoin = false;
+    private Integer duration = 0;	 
 	private long createdTime = 0;
 	private long startTime = 0;
 	private long endTime = 0;
@@ -176,6 +177,14 @@ public class Meeting {
         return sequence;
     }
 
+    public Boolean isFreeJoin() {
+        return freeJoin;
+    }
+
+    public void setFreeJoin(Boolean freeJoin) {
+        this.freeJoin = freeJoin;
+    }
+	
 	public Integer getDuration() {
 		return duration;
 	}
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java
index 79aedee164ff5c5b7b117f8a738c731396028d3e..33915458bf8ab0d93795db61ba1c131423babd2b 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java
@@ -6,6 +6,7 @@ public class CreateBreakoutRoom implements IMessage {
     public final String parentMeetingId; // The main meeting internal id
     public final String name; // The name of the breakout room
     public final Integer sequence; // The sequence number of the breakout room
+    public final Boolean freeJoin; // Allow users to freely join the conference in the client
     public final String voiceConfId; // The voice conference id
     public final String viewerPassword;
     public final String moderatorPassword;
@@ -15,7 +16,7 @@ public class CreateBreakoutRoom implements IMessage {
     public final Boolean record;
 
     public CreateBreakoutRoom(String meetingId, String parentMeetingId,
-            String name, Integer sequence, String voiceConfId,
+            String name, Integer sequence, Boolean freeJoin, String voiceConfId,
             String viewerPassword, String moderatorPassword, Integer duration,
             String sourcePresentationId, Integer sourcePresentationSlide,
             Boolean record) {
@@ -23,6 +24,7 @@ public class CreateBreakoutRoom implements IMessage {
         this.parentMeetingId = parentMeetingId;
         this.name = name;
         this.sequence = sequence;
+        this.freeJoin = freeJoin;
         this.voiceConfId = voiceConfId;
         this.viewerPassword = viewerPassword;
         this.moderatorPassword = moderatorPassword;
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java
index 569b08336881ffa5df74324735f91300c31e7432..7b5ff0c5b5a62891790f3b95d4dc2e35ffff022c 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java
@@ -14,7 +14,7 @@ public interface IPublisherService {
                        Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator,
                        String moderatorPass, String viewerPass, Long createTime,
                        String createDate, Boolean isBreakout, Integer sequence,
-                       Map<String, String> metadata, String guestPolicy);
+                       Boolean freeJoin, Map<String, String> metadata, String guestPolicy);
     void endMeeting(String meetingId);
     void send(String channel, String message);
     void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID,
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java
index aa1bb8f4998c72a1ff9605cbd73b5cdeed9d5e06..2cfbd859a65d4746849fe1af28673706782eb99d 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java
@@ -14,7 +14,7 @@ public interface IBbbWebApiGWApp {
                      String voiceBridge, Integer duration, Boolean autoStartRecording,
                      Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator,
                      String moderatorPass, String viewerPass, Long createTime,
-                     String createDate, Boolean isBreakout, Integer sequence, Map<String, String> metadata,
+                     String createDate, Boolean isBreakout, Integer sequence, Boolean freejoin, Map<String, String> metadata,
                      String guestPolicy, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage,
                      String dialNumber, Integer maxUsers,
                      Integer maxInactivityTimeoutMinutes, Integer warnMinutesBeforeMax,
diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala
index 3b6b2b2d93333da04b733d0513672cbe7797ffb9..6dbef4eaa7fa54de3aefeb195e546a0f99793a2c 100755
--- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala
+++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala
@@ -82,6 +82,7 @@ class BbbWebApiGWApp(
                     allowStartStopRecording: java.lang.Boolean, webcamsOnlyForModerator: java.lang.Boolean, moderatorPass: String,
                     viewerPass: String, createTime: java.lang.Long, createDate: String, isBreakout: java.lang.Boolean,
                     sequence: java.lang.Integer,
+                    freeJoin: java.lang.Boolean,
                     metadata: java.util.Map[String, String], guestPolicy: String,
                     welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String,
                     dialNumber: String, maxUsers: java.lang.Integer, maxInactivityTimeoutMinutes: java.lang.Integer,
@@ -103,7 +104,7 @@ class BbbWebApiGWApp(
     val password = PasswordProp(moderatorPass = moderatorPass, viewerPass = viewerPass)
     val recordProp = RecordProp(record = recorded.booleanValue(), autoStartRecording = autoStartRecording.booleanValue(),
       allowStartStopRecording = allowStartStopRecording.booleanValue())
-    val breakoutProps = BreakoutProps(parentId = parentMeetingId, sequence = sequence.intValue(), breakoutRooms = Vector())
+    val breakoutProps = BreakoutProps(parentId = parentMeetingId, sequence = sequence.intValue(), freeJoin = freeJoin.booleanValue(), breakoutRooms = Vector())
     val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg,
       modOnlyMessage = modOnlyMessage)
     val voiceProp = VoiceProp(telVoice = voiceBridge, voiceConf = voiceBridge, dialNumber = dialNumber, muteOnStart = muteOnStart.booleanValue())
diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/Recording.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/Recording.scala
index d173b102c11dff5b170e321feac090583106e096..a68e7b28c0dbf4977eb4ef7116cebfd40cedc4b3 100755
--- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/Recording.scala
+++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/Recording.scala
@@ -54,8 +54,9 @@ object RecMeta {
       val breakoutElem = breakoutNode(0) // convert from Node to Elem
       val parentId = breakoutElem.attribute("parentMeetingId").getOrElse("unknown").toString
       val sequence = breakoutElem.attribute("sequence").getOrElse("0").toString
+      val freeJoin = breakoutElem.attribute("freeJoin").getOrElse("false").toString
       val meetingId = breakoutElem.attribute("meetingId").getOrElse("unknown").toString
-      Some(RecMetaBreakout(parentId, sequence.toInt, meetingId))
+      Some(RecMetaBreakout(parentId, sequence.toInt, freeJoin.toBoolean, meetingId))
     }
   }
 
@@ -395,15 +396,17 @@ case class RecMetaPlayback(format: String, link: String, processingTime: Int,
 
 case class RecMetaImage(width: String, height: String, alt: String, link: String)
 
-case class RecMetaBreakout(parentId: String, sequence: Int, meetingId: String) {
+case class RecMetaBreakout(parentId: String, sequence: Int, freeJoin: Boolean, meetingId: String) {
   def toXml(): Elem = {
     val buffer = new scala.xml.NodeBuffer
 
     val parentIdElem = <parentId>{parentId}</parentId>
     val sequenceElem =  <sequence>{sequence}</sequence>
+    val freeJoinElem =  <freeJoin>{freeJoin}</freeJoin>
 
     buffer += parentIdElem
     buffer += sequenceElem
+    buffer += freeJoinElem
 
     <breakout>{buffer}</breakout>
   }
diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala
index b8f8b351133e3636892fb562e748e5f2ecbf481d..1761fb17c5e5e0a0ad7afaee78bae15a0ba0e668 100755
--- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala
+++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala
@@ -9,7 +9,7 @@ import org.bigbluebutton.common2.msgs.{BbbCommonEnvCoreMsg, MeetingCreatedEvtMsg
 
 sealed trait ApiMsg
 case class CreateBreakoutRoomMsg(meetingId: String, parentMeetingId: String,
-                                 name: String, sequence: Integer, voiceConfId: String,
+                                 name: String, sequence: Integer, freeJoin: Boolean, voiceConfId: String,
                                  viewerPassword: String, moderatorPassword: String, duration: Int,
                                  sourcePresentationId: String, sourcePresentationSlide: Int,
                                  record: Boolean) extends ApiMsg
diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala
index 5ed2d4bfe2c958e72ade5ea6c55a9b133418181f..44c3ca8253a6e43c43d5d3c3abf96eabdada236c 100755
--- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala
+++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala
@@ -58,6 +58,7 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW)
        msg.body.room.parentId,
        msg.body.room.name,
        msg.body.room.sequence,
+       msg.body.room.freeJoin,
        msg.body.room.voiceConfId,
        msg.body.room.viewerPassword,
        msg.body.room.moderatorPassword,
diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties
index 0410b53fa127bb49ce0e5c51a871b94a626213f1..f5d4463ba5486c91d61953e55706b074a4362691 100755
--- a/bigbluebutton-client/locale/en_US/bbbResources.properties
+++ b/bigbluebutton-client/locale/en_US/bbbResources.properties
@@ -846,6 +846,8 @@ bbb.users.breakout.roomsCombo.accessibilityName = Number of rooms to create
 bbb.users.breakout.room = Room
 bbb.users.breakout.timeLimit = Time Limit
 bbb.users.breakout.durationStepper.accessibilityName = Time limit in minutes
+bbb.users.breakout.freeJoin = Allow users to choose breakout room to join
+bbb.users.breakout.freeJoin.accessibilityName = Allow users to choose breakout room to join
 bbb.users.breakout.minutes = Minutes
 bbb.users.breakout.record = Record
 bbb.users.breakout.recordCheckbox.accessibilityName = Record breakout rooms
@@ -858,6 +860,7 @@ bbb.users.breakout.closeAllRooms = Close All Breakout Rooms
 bbb.users.breakout.insufficientUsers = Insufficient users. You should place at least one user in one breakout room.
 bbb.users.breakout.confirm = Join A Breakout Room
 bbb.users.breakout.invited = You have been invited to join <b>Breakout Room</b>
+bbb.users.breakout.selectRoom = Chose a<b>Breakout Room</b> to join
 bbb.users.breakout.accept = By accepting, you will automatically leave the audio and the video conferences.
 bbb.users.breakout.joinSession = Join Session
 bbb.users.breakout.joinSession.accessibilityName = Join Breakout Room Session
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/model/BreakoutRooms.as b/bigbluebutton-client/src/org/bigbluebutton/core/model/BreakoutRooms.as
index ff89f45a28bb3809844516265e002d2600d9a7ea..43f847c461598bb8417f5ff4ea1e75eb7df93380 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/core/model/BreakoutRooms.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/model/BreakoutRooms.as
@@ -173,5 +173,15 @@ package org.bigbluebutton.core.model
       
       dispatcher.dispatchEvent(new BreakoutRoomsListUpdatedEvent());
     }
+	
+	public function haveFreeJoinRooms():Boolean {
+		for (var i:int = 0; i < _breakoutRooms.length; i++) {
+			var br:BreakoutRoom = BreakoutRoom(_breakoutRooms.getItemAt(i));
+			if (br.freeJoin) {
+				return true;
+			}
+		}
+		return false;
+	}
   }
 }
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as
index 04aa659826b8e0d83388ec4de8691510eea6111d..99627b0bd98c249059ec7e16590e57f3939f905f 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as
@@ -40,6 +40,8 @@ package org.bigbluebutton.main.model.users {
     
     public var users:ArrayCollection;
     
+	public var freeJoin : Boolean;
+	
     public var invitedRecently : Boolean;
     
     // Can be one of three following values self, none, other
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
index 67c35926bdbf1c9111f8a45eb4837ddc289fd27f..79f26203e764ce7a7105f3dd867101466c5132cb 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as
@@ -774,6 +774,7 @@ package org.bigbluebutton.modules.users.services
         breakoutRoom.externalMeetingId = room.externalId as String;
         breakoutRoom.name = room.name as String;
         breakoutRoom.sequence = room.sequence as Number;
+		breakoutRoom.freeJoin = room.freeJoin as Boolean;
         LiveMeeting.inst().breakoutRooms.addBreakoutRoom(breakoutRoom);
       }
       LiveMeeting.inst().breakoutRooms.breakoutRoomsReady = msg.body.roomsReady as Boolean;
@@ -824,12 +825,14 @@ package org.bigbluebutton.modules.users.services
       var externalId: String = breakout.externalId as String;
       var name: String = breakout.name as String;
       var sequence: int = breakout.sequence as Number;
+      var freeJoin: Boolean = breakout.freeJoin as Boolean;
       
       var breakoutRoom : BreakoutRoom = new BreakoutRoom();
       breakoutRoom.meetingId = breakoutId;
       breakoutRoom.externalMeetingId = externalId;
       breakoutRoom.name = name;
       breakoutRoom.sequence = sequence;
+      breakoutRoom.freeJoin = freeJoin;
       LiveMeeting.inst().breakoutRooms.addBreakoutRoom(breakoutRoom);
     }
     
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml
index 921b470123a7e33cf0820d1330878f9c9997be57..f9fb904a72c7181fe9e146c42ad7c605ba4fd774 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml
@@ -56,6 +56,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
             
             [Bindable]
             private var recordingEnabled:Boolean;
+			
+			[Bindable]
+			private var freeJoin:Boolean;
             
             private static var assignment : Dictionary;
             
@@ -74,6 +77,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 event.rooms = new Array();
                 var parentMeetingName:String = UsersUtil.getMeetingName();
                 var roomResource:String = ResourceUtil.getInstance().getString('bbb.users.breakout.room');
+				var freeJoin : Boolean = freeJoinCheckbox.selected;
                 for (var i:int = 0; i < (roomsCombo.selectedIndex + 2); i++) {
                     var users:Array = BreakoutList(roomsContainer.getChildAt(i)).users.source;
                     totalUsers += users.length;
@@ -81,12 +85,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                     room.users = new Array();
                     room.sequence = i + 1;
                     room.name = parentMeetingName + " (" + roomResource + " - " + room.sequence.toString() + ")";
-                    for (var j:int = 0; j < users.length; j++) {
-                        room.users.push((User2x)(users[j]).intId);
-                    }
+					room.freeJoin = freeJoin;
+					if (!freeJoin) {
+	                    for (var j:int = 0; j < users.length; j++) {
+	                        room.users.push((User2x)(users[j]).intId);
+	                    }
+					}
                     event.rooms.push(room);
                 }
-                if (totalUsers > 0) {
+                if (totalUsers > 0 || freeJoin) {
                     event.durationInMinutes = durationStepper.value;
                     event.record = recordCheckbox.selected;
                     dispatcher.dispatchEvent(event);
@@ -170,6 +177,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 roomsCombo.selectedIndex = assignment['rooms'] - 2;
                 recordCheckbox.selected = assignment['record'];
                 durationStepper.value = assignment['duration'];
+				freeJoinCheckbox.selected = assignment['freeJoin'];
                 var user:User2x;
                 var currentUsers:ArrayCollection = UsersUtil.getUsers();
                 // Create breakout rooms boxes
@@ -179,18 +187,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                     list.roomName = ResourceUtil.getInstance().getString('bbb.users.breakout.room') + " " + (r).toString();
                     list.usersList.accessibilityName = ResourceUtil.getInstance().getString('bbb.users.breakout.room') + " " + (r).toString();
                 }
-                // Load user assignment from the previous action
-                var unassignedUsers:ArrayCollection = new ArrayCollection();
-                for (var u:int = 0; u < currentUsers.length; u++) {
-                    user = currentUsers.getItemAt(u) as User2x;
-                    if (assignment.hasOwnProperty(user.intId)) {
-                        BreakoutList(roomsContainer.getChildAt(assignment[user.intId])).users.addItem(User2x.copy(user));
-                    } else {
-                        unassignedUsers.addItem(User2x.copy(user));
-                    }
-                }
-                // Create not assigned users list
-                createUnassignedList(unassignedUsers);
+				// Load user assignment from the previous action
+				var unassignedUsers:ArrayCollection = new ArrayCollection();
+				for (var u:int = 0; u < currentUsers.length; u++) {
+					user = currentUsers.getItemAt(u) as User2x;
+					if (assignment.hasOwnProperty(user.intId)) {
+						BreakoutList(roomsContainer.getChildAt(assignment[user.intId])).users.addItem(User2x.copy(user));
+					} else {
+						unassignedUsers.addItem(User2x.copy(user));
+					}
+				}
+				// Create not assigned users list
+				createUnassignedList(unassignedUsers);
             }
             
             protected function assignUsersForInvitation():void {
@@ -239,13 +247,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 assignment['rooms'] = roomsCombo.selectedIndex + 2;
                 assignment['record'] = recordCheckbox.selected;
                 assignment['duration'] = durationStepper.value;
-                for (var r:int = 0; r < assignment['rooms']; r++) {
-                    var users:ArrayCollection = BreakoutList(roomsContainer.getChildAt(r)).users;
-                    for (var u:int = 0; u < users.length; u++) {
-                        // We store pairs { userID : roomNumber } to be easier to check later
-                        assignment[User2x(users[u]).intId] = r;
-                    }
-                }
+				assignment['freeJoin'] = freeJoinCheckbox.selected;
+				if (!freeJoin) {
+					for (var r:int = 0; r < assignment['rooms']; r++) {
+						var users:ArrayCollection = BreakoutList(roomsContainer.getChildAt(r)).users;
+						for (var u:int = 0; u < users.length; u++) {
+							// We store pairs { userID : roomNumber } to be easier to check later
+							assignment[User2x(users[u]).intId] = r;
+						}
+					}	
+				}
             }
             
             public function initCreateBreakoutRooms(mode:String, record:Boolean):void {
@@ -276,7 +287,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 }
 				PopUpManager.centerPopUp(this);
             }
-        ]]>
+			
+			protected function freeJoinCheckbox_changeHandler(event:Event):void
+			{
+				roomsContainer.enabled = !freeJoinCheckbox.selected;
+			}
+			
+		]]>
     </fx:Script>
     
     <mx:VBox width="100%" height="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5" horizontalAlign="center">
@@ -302,12 +319,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                                              toolTip="{ResourceUtil.getInstance().getString('bbb.users.breakout.durationStepper.accessibilityName')}"/>
             <mx:Label text="{ResourceUtil.getInstance().getString('bbb.users.breakout.minutes')}"/>
         </mx:HBox>
-        
+		
         <mx:HBox id="recordBox" width="100%" paddingTop="12" visible="{recordingEnabled}">
             <mx:Label text="{ResourceUtil.getInstance().getString('bbb.users.breakout.record')}"/>
             <mx:CheckBox id="recordCheckbox"
                          accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.recordCheckbox.accessibilityName')}"/>
         </mx:HBox>
+		
+		<mx:HBox id="freeJoinBox" width="100%" paddingTop="12">
+			<mx:Label text="{ResourceUtil.getInstance().getString('bbb.users.breakout.freeJoin')}" />
+			<mx:CheckBox id="freeJoinCheckbox" change="freeJoinCheckbox_changeHandler(event)"
+						 accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.freeJoinCheckbox.accessibilityName')}"/>
+		</mx:HBox>
 
         <mx:Tile id="roomsContainer" styleName="roomsContainer" width="100%" height="100%"/>
         
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
index 3e1aed204ea0d146adfc52c2335ef8e61cccadd2..370a64ca09193f2c04281c084f10238c3efbbe38 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
@@ -34,19 +34,29 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			import flash.net.navigateToURL;
 			
+			import mx.collections.ArrayCollection;
+			
 			import org.bigbluebutton.core.PopUpUtil;
+			import org.bigbluebutton.core.UsersUtil;
 			import org.bigbluebutton.core.model.LiveMeeting;
+			import org.bigbluebutton.main.events.BreakoutRoomEvent;
 			import org.bigbluebutton.modules.phone.events.LeaveVoiceConferenceCommand;
 			import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 
 			private var dispatcher:Dispatcher = new Dispatcher();
 
-			private var joinUrl:String;
+			private var joinURL:String;
 
-			public function setBreakoutRoomSettings(sequence:int, joinUrl:String):void {
+			public function setBreakoutRoomSettings(sequence:int, joinURL:String):void {
+				currentState = "normal";
 				sequenceLabel.text = sequence.toString();
-				this.joinUrl = joinUrl;
+				this.joinURL = joinURL;
+			}
+			
+			public function setBeakoutRoomsData(breakoutRooms : ArrayCollection):void {
+				currentState = "freeJoin";
+				breakoutRoomsCombo.dataProvider = breakoutRooms;
 			}
 
 			protected function joinButtonClickHandler(event:MouseEvent):void {
@@ -54,11 +64,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 					LiveMeeting.inst().me.breakoutEjectFromAudio = true;
 				} else {
 					LiveMeeting.inst().me.breakoutEjectFromAudio = false;
-
 				}
 				dispatcher.dispatchEvent(new LeaveVoiceConferenceCommand());
 				dispatcher.dispatchEvent(new StopBroadcastEvent());
-				navigateToURL(new URLRequest(this.joinUrl), "_blank");
+				if (currentState == "normal") {
+					navigateToURL(new URLRequest(this.joinURL), "_blank");
+				} else {
+					var e:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.REQUEST_BREAKOUT_JOIN_URL);
+					e.breakoutMeetingId = breakoutRoomsCombo.selectedItem.meetingId as String;
+					e.userId = UsersUtil.getMyUserID();
+					dispatcher.dispatchEvent(e);
+				}
 				PopUpUtil.removePopUp(this);
 			}
 			
@@ -67,13 +83,20 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			}
 		]]>
 	</fx:Script>
+	
+	<mx:states>
+		<mx:State name="normal"/>
+		<mx:State name="freeJoin"/>
+	</mx:states>
 
 	<mx:VBox height="100%" width="100%" paddingTop="15" paddingBottom="15" verticalGap="15" horizontalAlign="center">
 		<common:AdvancedLabel styleName="titleWindowStyle"
 							  maxWidth="580"
 							  text="{ResourceUtil.getInstance().getString('bbb.users.breakout.confirm')}" />
-		<mx:Label htmlText="{ResourceUtil.getInstance().getString('bbb.users.breakout.invited')}" paddingTop="4" />
-		<mx:Canvas>
+		<mx:Label htmlText.normal="{ResourceUtil.getInstance().getString('bbb.users.breakout.invited')}"
+				  htmlText.freeJoin="{ResourceUtil.getInstance().getString('bbb.users.breakout.selectRoom')}"
+				  paddingTop="4" />
+		<mx:Canvas includeIn="normal">
 			<mx:Image source="{getStyle('iconRooms')}" />
 			<mx:Canvas x="16" y="47" height="38" width="70"
 					   verticalScrollPolicy="off" horizontalScrollPolicy="off">
@@ -83,6 +106,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 						 horizontalCenter="0" />
 			</mx:Canvas>
 		</mx:Canvas>
+		<mx:ComboBox includeIn="freeJoin" id="breakoutRoomsCombo" labelField="name" width="40%"/>
 		<mx:Label width="100%" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.users.breakout.accept')}" />
 		<mx:Button id="joinButton"
 				   label="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession')}"
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml
index 2ff5f35c4fcea62d7bee438583aa4b4316a7c746..c953ce08521e7adbfcb683d695f8dd1ed302d2ac 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml
@@ -71,7 +71,7 @@
              width="20"
              height="20"
              icon="{getStyle('iconJoin')}"
-             visible="{(breakoutRoomsReady &amp;&amp; moderator) || (!moderator &amp;&amp; data.invitedRecently)}"
+             visible="{(breakoutRoomsReady &amp;&amp; moderator) || (!moderator &amp;&amp; data.invitedRecently) || (data.joinFree)}"
              toolTip="{ResourceUtil.getInstance().getString('bbb.users.roomsGrid.join')}"
              click="requestBreakoutJoinUrl(event)" />
   <mx:Button id="listenBtn"
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
index c314f7fa6637a96a551a1b7b2af27a2a80042cec..26ef500f252b36e1eb840eaa4098991742d5202e 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
@@ -42,6 +42,7 @@ $Id: $
 	<mate:Listener type="{BBBEvent.CHANGE_WEBCAMS_ONLY_FOR_MODERATOR}" method="setRoomLocked"/>
     <mate:Listener type="{BreakoutRoomEvent.UPDATE_REMAINING_TIME_PARENT}" method="handleRemainingTimeUpdate" />
     <mate:Listener type="{BreakoutRoomEvent.BREAKOUT_JOIN_URL}" method="handleBreakoutJoinUrl" />
+	<mate:Listener type="{BreakoutRoomsReadyEvent.BREAKOUT_ROOMS_READY_EVENT}" method="handleBreakoutRoomsReady" />
     <mate:Listener type="{ChangeMyRole.CHANGE_MY_ROLE_EVENT}" method="onChangeMyRole" />
     <mate:Listener type="{UserJoinedEvent.JOINED}" method="handleUserJoinedEvent" />    
     <mate:Listener type="{BreakoutRoomsListUpdatedEvent.BREAKOUT_ROOMS_LIST_UPDATED_EVENT}" method="handleBreakoutRoomsListUpdatedEvent" />
@@ -66,6 +67,8 @@ $Id: $
     <![CDATA[
 		import com.asfusion.mate.events.Dispatcher;
 		
+		import flash.net.navigateToURL;
+		
 		import mx.binding.utils.BindingUtils;
 		import mx.collections.ArrayCollection;
 		import mx.controls.Menu;
@@ -89,6 +92,7 @@ $Id: $
 		import org.bigbluebutton.core.TimerUtil;
 		import org.bigbluebutton.core.UsersUtil;
 		import org.bigbluebutton.core.events.BreakoutRoomsListUpdatedEvent;
+		import org.bigbluebutton.core.events.BreakoutRoomsReadyEvent;
 		import org.bigbluebutton.core.events.BreakoutRoomsUsersListUpdatedEvent;
 		import org.bigbluebutton.core.events.CoreEvent;
 		import org.bigbluebutton.core.events.LockControlEvent;
@@ -467,11 +471,23 @@ $Id: $
 	  }
       
       private function handleBreakoutJoinUrl(event:BreakoutRoomEvent):void {
-        // We display only one alert
-        removeJoinWindow();
-		joinWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, JoinBreakoutRoomWindow, true) as JoinBreakoutRoomWindow;
-		joinWindow.setBreakoutRoomSettings(event.breakoutMeetingSequence, event.joinURL);
+		if (!LiveMeeting.inst().breakoutRooms.haveFreeJoinRooms()) {
+			// We display only one alert
+			removeJoinWindow();
+			joinWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, JoinBreakoutRoomWindow, true) as JoinBreakoutRoomWindow;
+			joinWindow.setBreakoutRoomSettings(event.breakoutMeetingSequence, event.joinURL);
+		}
+		else {
+			navigateToURL(new URLRequest(event.joinURL), "_blank");
+		}
       }
+		
+	  private function handleBreakoutRoomsReady(event:BreakoutRoomsReadyEvent):void {
+		  if (LiveMeeting.inst().breakoutRooms.haveFreeJoinRooms()) {
+			  joinWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, JoinBreakoutRoomWindow, true) as JoinBreakoutRoomWindow;
+			  joinWindow.setBeakoutRoomsData(LiveMeeting.inst().breakoutRooms.breakoutRooms);
+		  }
+	  }
       
       private function removeJoinWindow():void {
         if (joinWindow != null) {
diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
index 363d0d6e5dda948dd6f253834af823b328d9bd72..3224fae57a5242594ef8ff85facab227bddd7939 100755
--- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
+++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy
@@ -1932,7 +1932,8 @@ class ApiController {
             internalMeetingID(meeting.getInternalId())
             if (meeting.isBreakout()) {
                 parentMeetingID() { mkp.yield(meeting.getParentMeetingId()) }
-                sequence(meeting.getSequence())
+                sequence() { mkp.yield(meeting.getSequence()) }
+                freeJoin() { mkp.yield(meeting.isFreeJoin()) }
             }
             createTime(meeting.getCreateTime())
             createDate(formatPrettyDate(meeting.getCreateTime()))
diff --git a/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meeting-info.ftlx b/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meeting-info.ftlx
index d7aebe3e2f70209c566c58a280ed6a1fc580eb5a..416d243b1762d772e1b4e8770a2fcf356a2e6906 100755
--- a/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meeting-info.ftlx
+++ b/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meeting-info.ftlx
@@ -65,6 +65,7 @@
   <#if meeting.isBreakout()>
      <parentMeetingID>${meeting.getParentMeetingId()}</parentMeetingID>
      <sequence>${meeting.getSequence()}</sequence>
+     <freeJoin>${meeting.isFreeJoin()?c}</freeJoin>
   </#if>
 
   <#list meeting.getBreakoutRooms()>
diff --git a/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meetings.ftlx b/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meetings.ftlx
index a43bfaea9c23ac5679bfb2e773432cb0db2e8ace..98358a24ede596c4a1faf1a688bcfe1cd898e9b1 100755
--- a/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meetings.ftlx
+++ b/bigbluebutton-web/web-app/WEB-INF/freemarker/get-meetings.ftlx
@@ -62,6 +62,7 @@
         <#if meetingDetail.meeting.isBreakout()>
            <parentMeetingID>${meetingDetail.meeting.getParentMeetingId()}</parentMeetingID>
            <sequence>${meetingDetail.meeting.getSequence()}</sequence>
+           <freeJoin>${meetingDetail.meeting.isFreeJoin()?c}</freeJoin>
         </#if>
 
         <#list meetingDetail.meeting.getBreakoutRooms()>
diff --git a/bigbluebutton-web/web-app/WEB-INF/freemarker/include-recording.ftlx b/bigbluebutton-web/web-app/WEB-INF/freemarker/include-recording.ftlx
index 30cf1bc0a62bca6fac306fcb4baa218c0be27ce2..db85ffdac20f2db6cb1d05bbcf2146ae04a46f06 100755
--- a/bigbluebutton-web/web-app/WEB-INF/freemarker/include-recording.ftlx
+++ b/bigbluebutton-web/web-app/WEB-INF/freemarker/include-recording.ftlx
@@ -22,6 +22,7 @@
     <breakout>
         <parentId>${breakout.getParentMeetingId()}</parentId>
         <sequence>${breakout.getSequence()?c}</sequence>
+        <freeJoin>${breakout.isFreeJoin()?c}</freeJoin>
     </breakout>
 </#if>