diff --git a/akka-bbb-apps/scala/Collections.sc b/akka-bbb-apps/scala/Collections.sc
new file mode 100755
index 0000000000000000000000000000000000000000..9640c593bf0e190c01f6572dc9dc4edfb7b04084
--- /dev/null
+++ b/akka-bbb-apps/scala/Collections.sc
@@ -0,0 +1,9 @@
+import scala.collection.mutable
+
+object Collections {
+  val messages = new mutable.Queue[String]()
+  messages += "foo"
+  messages += "bar"
+  messages += "baz"
+  messages.foreach(f => println(f))
+}
\ No newline at end of file
diff --git a/akka-bbb-apps/scala/Test2.sc b/akka-bbb-apps/scala/Test2.sc
index 784ccd76cfadf6fa45957f106f5e5bdbcf2bd07b..214b311d850eefe4ec2417dc64d854c91d5e7366 100755
--- a/akka-bbb-apps/scala/Test2.sc
+++ b/akka-bbb-apps/scala/Test2.sc
@@ -1,23 +1,23 @@
 import scala.collection.immutable.StringOps
 import java.net.URLEncoder
 import scala.collection._
-
+
 object Test2 {
-  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
+  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
    
-  val userId = new StringOps("abc_12")            //> userId  : scala.collection.immutable.StringOps = abc_12
-  val s2 = userId.split('_')                      //> s2  : Array[String] = Array(abc, 12)
-  val s1 = if (s2.length == 2) s2(0) else userId  //> s1  : Comparable[String] = abc
+  val userId = new StringOps("abc_12")            //> userId  : scala.collection.immutable.StringOps = abc_12
+  val s2 = userId.split('_')                      //> s2  : Array[String] = Array(abc, 12)
+  val s1 = if (s2.length == 2) s2(0) else userId  //> s1  : Comparable[String] = abc
 
   def sortParam(params: mutable.Map[String, String]):SortedSet[String] = {
     collection.immutable.SortedSet[String]() ++ params.keySet
   }                                               //> sortParam: (params: scala.collection.mutable.Map[String,String])scala.collec
-                                                  //| tion.SortedSet[String]
+                                                  //| tion.SortedSet[String]
   
   def createBaseString(params: mutable.Map[String, String]): String = {
     val csbuf = new StringBuffer()
     var keys = sortParam(params)
-
+
     var first = true;
     for (key <- keys) {
       for (value <- params.get(key)) {
@@ -26,42 +26,52 @@ object Test2 {
         } else {
           csbuf.append("&");
         }
-
+
         csbuf.append(key);
         csbuf.append("=");
         csbuf.append(value);
       }
     }
-
+
     return csbuf.toString();
   }                                               //> createBaseString: (params: scala.collection.mutable.Map[String,String])Strin
-                                                  //| g
+                                                  //| g
     
   def urlEncode(s: String): String = {
     URLEncoder.encode(s, "UTF-8");
-  }                                               //> urlEncode: (s: String)String
+  }                                               //> urlEncode: (s: String)String
   
   val baseString = "fullName=User+4621018&isBreakout=true&meetingID=random-1853792&password=mp&redirect=true"
                                                   //> baseString  : String = fullName=User+4621018&isBreakout=true&meetingID=rand
-                                                  //| om-1853792&password=mp&redirect=true
+                                                  //| om-1853792&password=mp&redirect=true
   
   val params = new collection.mutable.HashMap[String, String]
-                                                  //> params  : scala.collection.mutable.HashMap[String,String] = Map()
+                                                  //> params  : scala.collection.mutable.HashMap[String,String] = Map()
   params += "fullName" -> urlEncode("User 4621018")
-                                                  //> res0: Test2.params.type = Map(fullName -> User+4621018)
+                                                  //> res0: Test2.params.type = Map(fullName -> User+4621018)
   params += "isBreakout" -> urlEncode("true")     //> res1: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true)
-                                                  //| 
+                                                  //| 
   params += "meetingID" -> urlEncode("random-1853792")
                                                   //> res2: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true,
-                                                  //|  meetingID -> random-1853792)
+                                                  //|  meetingID -> random-1853792)
   params += "password" -> urlEncode("mp")         //> res3: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true,
-                                                  //|  meetingID -> random-1853792, password -> mp)
+                                                  //|  meetingID -> random-1853792, password -> mp)
   params += "redirect" -> urlEncode("true")       //> res4: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true,
-                                                  //|  meetingID -> random-1853792, redirect -> true, password -> mp)
+                                                  //|  meetingID -> random-1853792, redirect -> true, password -> mp)
   val keys = sortParam(params)                    //> keys  : scala.collection.SortedSet[String] = TreeSet(fullName, isBreakout, 
-                                                  //| meetingID, password, redirect)
+                                                  //| meetingID, password, redirect)
 
   val result = createBaseString(params)           //> result  : String = fullName=User+4621018&isBreakout=true&meetingID=random-1
-                                                  //| 853792&password=mp&redirect=true
-  
+                                                  //| 853792&password=mp&redirect=true
+
+  val between = Set("xab", "bc")
+  val u2 = Set("bc", "xab")
+  val u3 = u2 + "zxc"
+  val foo = between subsetOf(u2)
+
+  val id = between.toSeq.sorted.mkString("-")
+
+
+
+
 }
\ No newline at end of file
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatAppHandlers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatAppHandlers.scala
new file mode 100755
index 0000000000000000000000000000000000000000..0424174c091086ee2e82304819ec3138b07a9ea2
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatAppHandlers.scala
@@ -0,0 +1,29 @@
+package org.bigbluebutton.core.apps
+
+import org.bigbluebutton.core.OutMessageGateway
+import org.bigbluebutton.core.api.SendDirectChatMsgCmd
+import org.bigbluebutton.core.models.DirectChats
+import org.bigbluebutton.core.running.LiveMeeting
+
+trait ChatAppHandlers {
+  val liveMeeting: LiveMeeting
+  val outGW: OutMessageGateway
+
+  def handleSendDirectChatMsgCmd(msg: SendDirectChatMsgCmd): Unit = {
+    def send(): Unit = {
+
+    }
+
+    val between = Set("foo", "bar")
+    for {
+      chat <- DirectChats.find(between, liveMeeting.chatModel.directChats)
+
+    } yield {
+      send()
+    }
+  }
+
+  def handleCreatePublicChatCmd(): Unit = {
+
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatModel.scala
index 515dd2adabfd34c9409c3d90c324353f0d6b9266..593c795a1fcb804f174a27293b9d2863d454a27e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatModel.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/ChatModel.scala
@@ -1,9 +1,14 @@
 package org.bigbluebutton.core.apps
 
+import org.bigbluebutton.core.models.{ DirectChats, PublicChats, UserIdAndName }
+
 import scala.collection.mutable.ArrayBuffer
-import scala.collection.immutable.HashMap
 
 class ChatModel {
+
+  val directChats = new DirectChats
+  val publicChats = new PublicChats
+
   private val messages = new ArrayBuffer[Map[String, String]]()
 
   def getChatHistory(): Array[Map[String, String]] = {
@@ -20,4 +25,5 @@ class ChatModel {
   def clearPublicChatHistory() {
     messages.clear();
   }
-}
\ No newline at end of file
+}
+
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermisssionCheck.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermisssionCheck.scala
new file mode 100755
index 0000000000000000000000000000000000000000..e5bceaa6b392d80090b8bd518e295bf9bcc43ec4
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermisssionCheck.scala
@@ -0,0 +1,10 @@
+package org.bigbluebutton.core.apps
+
+import org.bigbluebutton.core.models.UserVO
+
+trait PermisssionCheck {
+
+  def isAllowed(permission: String, role: String, user: UserVO): Boolean = {
+    true
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/DirectChat.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/DirectChat.scala
new file mode 100755
index 0000000000000000000000000000000000000000..00732e3de249b757f787a3efad358e7df32ae384
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/DirectChat.scala
@@ -0,0 +1,61 @@
+package org.bigbluebutton.core.models
+
+import scala.collection.mutable
+
+object DirectChats {
+
+  def create(between: Set[String], chats: DirectChats): DirectChat = {
+    val chat = DirectChat(between)
+    chats.save(chat)
+    chat
+  }
+
+  def find(between: Set[String], chats: DirectChats): Option[DirectChat] = {
+    chats.toVector.find { c => between subsetOf (c.between) }
+  }
+
+}
+
+class DirectChats {
+  private var chats: collection.immutable.HashMap[String, DirectChat] = new collection.immutable.HashMap[String, DirectChat]
+
+  def toVector: Vector[DirectChat] = chats.values.toVector
+
+  private def save(chat: DirectChat): DirectChat = {
+    chats += chat.id -> chat
+    chat
+  }
+
+  private def remove(id: String): Option[DirectChat] = {
+    for {
+      chat <- chats.get(id)
+    } yield {
+      chats -= chat.id
+      chat
+    }
+  }
+}
+
+object DirectChat {
+  private def createId(between: Set[String]): String = {
+    between.toSeq.sorted.mkString("-")
+  }
+
+  def apply(between: Set[String]) = new DirectChat(createId(between), between)
+}
+
+class DirectChat(val id: String, val between: Set[String]) {
+  private var msgs: collection.mutable.Queue[DirectChatMessage] = new mutable.Queue[DirectChatMessage]()
+
+  def messages: Vector[DirectChatMessage] = msgs.toVector
+
+  def append(msg: DirectChatMessage): DirectChatMessage = {
+    msgs += msg
+    msg
+  }
+
+}
+
+case class DirectChatMessage(msgId: String, timestamp: Long, from: UserIdAndName, to: UserIdAndName, message: ChatMessage)
+
+case class ChatMessage(font: String, size: Int, color: String, message: String)
\ No newline at end of file
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PublicChat.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PublicChat.scala
new file mode 100755
index 0000000000000000000000000000000000000000..8593aaab729ccb689fe6d8ff5053c13209cf0133
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PublicChat.scala
@@ -0,0 +1,57 @@
+package org.bigbluebutton.core.models
+
+import org.bigbluebutton.core.util.RandomStringGenerator
+
+import scala.collection.mutable
+
+object PublicChats {
+  def create(chats: PublicChats): PublicChat = {
+    val id = RandomStringGenerator.randomAlphanumericString(20)
+    val chat = new PublicChat(id)
+    chats.save(chat)
+    chat
+  }
+
+  def find(id: String, chats: PublicChats): Option[PublicChat] = {
+    chats.toVector.find { chat => chat.id == id }
+  }
+}
+
+class PublicChats {
+  private var chats: collection.immutable.HashMap[String, PublicChat] = new collection.immutable.HashMap[String, PublicChat]
+
+  private def toVector: Vector[PublicChat] = chats.values.toVector
+
+  private def save(chat: PublicChat): PublicChat = {
+    chats += chat.id -> chat
+    chat
+  }
+
+  private def remove(id: String): Option[PublicChat] = {
+    for {
+      chat <- chats.get(id)
+    } yield {
+      chat
+    }
+  }
+}
+
+object PublicChat {
+
+  def append(chat: PublicChat, msg: PublicChatMessage): PublicChatMessage = {
+    chat.append(msg)
+  }
+}
+
+class PublicChat(val id: String) {
+  private var messages: collection.mutable.Queue[PublicChatMessage] = new mutable.Queue[PublicChatMessage]()
+
+  private def toVector: Vector[PublicChatMessage] = messages.toVector
+
+  private def append(msg: PublicChatMessage): PublicChatMessage = {
+    messages += msg
+    msg
+  }
+}
+
+case class PublicChatMessage(msgId: String, timestamp: Long, from: UserIdAndName, message: ChatMessage)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Streams.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Streams.scala
new file mode 100755
index 0000000000000000000000000000000000000000..f0ecc2eeb7095c5377af04ae194e25fda75cc578
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Streams.scala
@@ -0,0 +1,23 @@
+package org.bigbluebutton.core.models
+
+import com.softwaremill.quicklens._
+
+object Streams {
+
+  def add(stream: Stream, user: String): Stream = {
+    val newViewers = stream.viewers + user
+    modify(stream)(_.viewers).setTo(newViewers)
+  }
+
+  def remove(stream: Stream, user: String): Stream = {
+    val newViewers = stream.viewers - user
+    modify(stream)(_.viewers).setTo(newViewers)
+  }
+}
+
+/**
+ * Borrow some ideas from SDP.
+ * https://en.wikipedia.org/wiki/Session_Description_Protocol
+ */
+case class MediaAttribute(key: String, value: String)
+case class Stream(id: String, sessionId: String, attributes: Set[MediaAttribute], viewers: Set[String])
diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/ChatModelTest.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/ChatModelTest.scala
new file mode 100755
index 0000000000000000000000000000000000000000..bacacdfec0eb015616b18308948c3b32fed72859
--- /dev/null
+++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/ChatModelTest.scala
@@ -0,0 +1,17 @@
+package org.bigbluebutton.core.models
+
+import org.scalatest._
+import org.bigbluebutton.core.UnitSpec
+import scala.collection.mutable.Stack
+
+class ChatModelTest extends UnitSpec {
+
+  "A Stack" should "pop values in last-in-first-out order" in {
+    val stack = new Stack[Int]
+    stack.push(1)
+    stack.push(2)
+    assert(stack.pop() === 2)
+    assert(stack.pop() === 1)
+  }
+
+}
diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/DirectChatModelTest.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/DirectChatModelTest.scala
new file mode 100755
index 0000000000000000000000000000000000000000..6be1a84ff8e50de110f2e0637e111fe64df93c17
--- /dev/null
+++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/DirectChatModelTest.scala
@@ -0,0 +1,39 @@
+package org.bigbluebutton.core.models
+
+import org.bigbluebutton.core.UnitSpec
+
+class DirectChatModelTest extends UnitSpec {
+
+  "A DirectChat" should "be able to add a message" in {
+    val msg = ChatMessage("arial", 10, "red", "Hello")
+    val from = UserIdAndName("user1", "User 1")
+    val to = UserIdAndName("user2", "User 2")
+    val dm = new DirectChatMessage("msgId", System.currentTimeMillis(), from, to, msg)
+
+    val between = Set("user1", "user2")
+    val directChats = new DirectChats()
+    val dc = DirectChats.create(between, directChats)
+    val dm2 = dc.append(dm)
+    assert(dc.messages.length == 1)
+
+    val dm3 = dc.append(dm)
+    assert(dc.messages.length == 2)
+
+    val dc2 = DirectChats.find(between, directChats)
+    dc2 match {
+      case Some(directChat) => assert(directChat.messages.length == 2)
+      case None => fail("No direct chat found!")
+    }
+
+    val dm4 = dc.append(dm)
+    assert(dc.messages.length == 3)
+
+    val dc3 = DirectChats.find(between, directChats)
+    dc3 match {
+      case Some(directChat) => assert(directChat.messages.length == 3)
+      case None => fail("No direct chat found!")
+    }
+
+  }
+
+}