diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index 2777f220a1ad238a1f4ac3dadcffc7d1acce5c25..198d149675e0e101e1a20b3442246aab06239e74 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -40,9 +40,7 @@
 		0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0438663A1D2313B700E06CE2 /* AccountDetailsViewController.swift */; };
 		043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043999F61D1C2D9D00E99CD9 /* AppDelegate.swift */; };
 		043999FA1D1C2D9D00E99CD9 /* Ring.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 043999F81D1C2D9D00E99CD9 /* Ring.xcdatamodeld */; };
-		04399A011D1C2D9D00E99CD9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 043999FF1D1C2D9D00E99CD9 /* Main.storyboard */; };
 		04399A031D1C2D9D00E99CD9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04399A021D1C2D9D00E99CD9 /* Assets.xcassets */; };
-		04399A061D1C2D9D00E99CD9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 04399A041D1C2D9D00E99CD9 /* LaunchScreen.storyboard */; };
 		04399A111D1C2D9D00E99CD9 /* RingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04399A101D1C2D9D00E99CD9 /* RingTests.swift */; };
 		04399A1C1D1C2D9D00E99CD9 /* RingUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04399A1B1D1C2D9D00E99CD9 /* RingUITests.swift */; };
 		04399A2A1D1C2DE300E99CD9 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399A291D1C2DE300E99CD9 /* CoreMedia.framework */; };
@@ -108,6 +106,7 @@
 		5557FD4E1E81B1F20043E394 /* AccountModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5516C29E1E71CEFF009D3D2D /* AccountModelHelper.swift */; };
 		5557FD4F1E81B2990043E394 /* AccountCredentialsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DD80C91E1EAF1A009A3510 /* AccountCredentialsModel.swift */; };
 		557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */; };
+		562FB6CD1EFAD18A00C61A78 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562FB6CC1EFAD18A00C61A78 /* ConversationViewController.swift */; };
 		56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56308BA61EA00E5700660275 /* NameRegistrationResponse.m */; };
 		563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 563AEC761EA664C0003A5641 /* RegistrationResponse.m */; };
 		564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */; };
@@ -122,7 +121,6 @@
 		5669A8031EAA58E6003C7B93 /* LinkDeviceToAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5669A8021EAA58E6003C7B93 /* LinkDeviceToAccountViewController.swift */; };
 		568F56751EA7E5DE00132D7D /* PKHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 568F56721EA7E38F00132D7D /* PKHUD.framework */; };
 		56AC64D51E7C7F4000EA1AA9 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64D41E7C7F4000EA1AA9 /* WelcomeViewController.swift */; };
-		56AC64D91E8012CA00EA1AA9 /* Walkthrough.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56AC64DB1E8012CA00EA1AA9 /* Walkthrough.strings */; };
 		56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64DE1E804ECC00EA1AA9 /* SwitchCell.swift */; };
 		56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */; };
 		56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E21E805F0200EA1AA9 /* TextCell.swift */; };
@@ -141,9 +139,16 @@
 		56BBC9BA1ED715FE00CDAF8B /* ContactHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */; };
 		56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */; };
 		56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */; };
-		56BBC9C51ED8BF3300CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9C41ED8BF3300CDAF8B /* libargon2.a */; };
-		56BBC9DB1EDDC7F700CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */; };
-		56BBC9DC1EDDC82600CDAF8B /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */; };
+		56BBC9CD1EDC5E7000CDAF8B /* MessageAccessoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9C71EDC5E7000CDAF8B /* MessageAccessoryView.swift */; };
+		56BBC9CE1EDC5E7000CDAF8B /* MessageAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9C81EDC5E7000CDAF8B /* MessageAccessoryView.xib */; };
+		56BBC9CF1EDC5E7000CDAF8B /* MessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9C91EDC5E7000CDAF8B /* MessageCell.swift */; };
+		56BBC9D01EDC5E7000CDAF8B /* MessageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9CA1EDC5E7000CDAF8B /* MessageCell.xib */; };
+		56BBC9D21EDC5E7000CDAF8B /* MessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9CC1EDC5E7000CDAF8B /* MessageViewModel.swift */; };
+		56BBC9D41EDC7A6D00CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9D31EDC7A6D00CDAF8B /* libargon2.a */; };
+		56BBC9D51EDCA85900CDAF8B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 043999FF1D1C2D9D00E99CD9 /* Main.storyboard */; };
+		56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */; };
+		56BBC9E01EDDC9E600CDAF8B /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */; };
+		56BBC9E11EDDCA5900CDAF8B /* Walkthrough.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56AC64DB1E8012CA00EA1AA9 /* Walkthrough.strings */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -275,6 +280,7 @@
 		5557FD491E81AE850043E394 /* AccountModelHelperTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountModelHelperTests.swift; sourceTree = "<group>"; };
 		557086501E8ADB9D001A7CE4 /* SystemAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SystemAdapter.h; path = Bridging/SystemAdapter.h; sourceTree = "<group>"; };
 		557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SystemAdapter.mm; path = Bridging/SystemAdapter.mm; sourceTree = "<group>"; };
+		562FB6CC1EFAD18A00C61A78 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewController.swift; sourceTree = "<group>"; };
 		56308BA51EA00E5700660275 /* NameRegistrationResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameRegistrationResponse.h; sourceTree = "<group>"; };
 		56308BA61EA00E5700660275 /* NameRegistrationResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NameRegistrationResponse.m; sourceTree = "<group>"; };
 		563AEC751EA664C0003A5641 /* RegistrationResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationResponse.h; sourceTree = "<group>"; };
@@ -313,9 +319,14 @@
 		56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactHelper.swift; sourceTree = "<group>"; };
 		56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Helpers.swift"; path = "Extensions/Date+Helpers.swift"; sourceTree = "<group>"; };
 		56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewModel.swift; sourceTree = "<group>"; };
-		56BBC9C41ED8BF3300CDAF8B /* libargon2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libargon2.a; path = ../fat/lib/libargon2.a; sourceTree = "<group>"; };
-		56BBC9D81EDDC0B400CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
-		56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LookupNameResponse.m; sourceTree = "<group>"; };
+		56BBC9C71EDC5E7000CDAF8B /* MessageAccessoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageAccessoryView.swift; sourceTree = "<group>"; };
+		56BBC9C81EDC5E7000CDAF8B /* MessageAccessoryView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageAccessoryView.xib; sourceTree = "<group>"; };
+		56BBC9C91EDC5E7000CDAF8B /* MessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCell.swift; sourceTree = "<group>"; };
+		56BBC9CA1EDC5E7000CDAF8B /* MessageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCell.xib; sourceTree = "<group>"; };
+		56BBC9CC1EDC5E7000CDAF8B /* MessageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageViewModel.swift; sourceTree = "<group>"; };
+		56BBC9D31EDC7A6D00CDAF8B /* libargon2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libargon2.a; path = ../fat/lib/libargon2.a; sourceTree = "<group>"; };
+		56BBC9DD1EDDC9D300CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
+		56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LookupNameResponse.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -323,7 +334,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				56BBC9C51ED8BF3300CDAF8B /* libargon2.a in Frameworks */,
+				56BBC9D41EDC7A6D00CDAF8B /* libargon2.a in Frameworks */,
 				568F56751EA7E5DE00132D7D /* PKHUD.framework in Frameworks */,
 				02674C851E0C757B0065EDF9 /* RxCocoa.framework in Frameworks */,
 				02674C861E0C757B0065EDF9 /* RxSwift.framework in Frameworks */,
@@ -437,7 +448,7 @@
 		02AED8171DD4C4B000F740BA /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
-				56BBC9C41ED8BF3300CDAF8B /* libargon2.a */,
+				56BBC9D31EDC7A6D00CDAF8B /* libargon2.a */,
 				568F56721EA7E38F00132D7D /* PKHUD.framework */,
 				02674C801E0C757B0065EDF9 /* RxBlocking.framework */,
 				02674C811E0C757B0065EDF9 /* RxCocoa.framework */,
@@ -687,8 +698,8 @@
 		563AEC731EA6627F003A5641 /* NameRegistration */ = {
 			isa = PBXGroup;
 			children = (
-				56BBC9D81EDDC0B400CDAF8B /* LookupNameResponse.h */,
-				56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */,
+				56BBC9DD1EDDC9D300CDAF8B /* LookupNameResponse.h */,
+				56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */,
 				564C445E1E943C37000F92B1 /* NameRegistrationAdapter.h */,
 				564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */,
 				56308BA51EA00E5700660275 /* NameRegistrationResponse.h */,
@@ -744,6 +755,11 @@
 		56BBC9A41ED7150200CDAF8B /* Messages */ = {
 			isa = PBXGroup;
 			children = (
+				56BBC9C71EDC5E7000CDAF8B /* MessageAccessoryView.swift */,
+				56BBC9C81EDC5E7000CDAF8B /* MessageAccessoryView.xib */,
+				56BBC9C91EDC5E7000CDAF8B /* MessageCell.swift */,
+				56BBC9CA1EDC5E7000CDAF8B /* MessageCell.xib */,
+				56BBC9CC1EDC5E7000CDAF8B /* MessageViewModel.swift */,
 				56BBC9A51ED7151500CDAF8B /* MessageModel.swift */,
 			);
 			name = Messages;
@@ -752,6 +768,7 @@
 		56BBC9AD1ED7154800CDAF8B /* Conversations */ = {
 			isa = PBXGroup;
 			children = (
+				562FB6CC1EFAD18A00C61A78 /* ConversationViewController.swift */,
 				56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */,
 				56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */,
 				56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */,
@@ -849,6 +866,11 @@
 						CreatedOnToolsVersion = 7.3.1;
 						DevelopmentTeam = KM95526DS8;
 						LastSwiftMigration = 0810;
+						SystemCapabilities = {
+							com.apple.BackgroundModes = {
+								enabled = 0;
+							};
+						};
 					};
 					04399A0B1D1C2D9D00E99CD9 = {
 						CreatedOnToolsVersion = 7.3.1;
@@ -887,17 +909,18 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				56AC64D91E8012CA00EA1AA9 /* Walkthrough.strings in Resources */,
 				02B22E031DF755F7000358C9 /* WalkthroughStoryboard.storyboard in Resources */,
 				5669A7FE1EA904E4003C7B93 /* TextCell.xib in Resources */,
-				04399A061D1C2D9D00E99CD9 /* LaunchScreen.storyboard in Resources */,
 				56BBC9AC1ED7154300CDAF8B /* Smartlist.strings in Resources */,
 				56BBC9AA1ED7153800CDAF8B /* Global.strings in Resources */,
+				56BBC9CE1EDC5E7000CDAF8B /* MessageAccessoryView.xib in Resources */,
+				56BBC9D51EDCA85900CDAF8B /* Main.storyboard in Resources */,
 				04399A031D1C2D9D00E99CD9 /* Assets.xcassets in Resources */,
-				04399A011D1C2D9D00E99CD9 /* Main.storyboard in Resources */,
+				56BBC9D01EDC5E7000CDAF8B /* MessageCell.xib in Resources */,
 				5669A7FA1EA904AF003C7B93 /* SwitchCell.xib in Resources */,
 				56BBC9B51ED7156500CDAF8B /* ConversationCell.xib in Resources */,
 				5669A7FC1EA904D2003C7B93 /* TextFieldCell.xib in Resources */,
+				56BBC9E11EDDCA5900CDAF8B /* Walkthrough.strings in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -941,7 +964,6 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				56BBC9DC1EDDC82600CDAF8B /* ConversationViewModel.swift in Sources */,
 				557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */,
 				5669A8031EAA58E6003C7B93 /* LinkDeviceToAccountViewController.swift in Sources */,
 				0273C3051E0C68B100CF00BA /* CreateProfileViewController.swift in Sources */,
@@ -951,7 +973,9 @@
 				02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
 				0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */,
 				56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */,
+				56BBC9CF1EDC5E7000CDAF8B /* MessageCell.swift in Sources */,
 				02C9B63F1E1D4E8C00F82F0C /* ServiceEvent.swift in Sources */,
+				56BBC9D21EDC5E7000CDAF8B /* MessageViewModel.swift in Sources */,
 				02DD80CD1E1EB2E4009A3510 /* ConfigKeyModel.swift in Sources */,
 				56BBC9A81ED7152300CDAF8B /* SmartlistViewController.swift in Sources */,
 				5516C29F1E71CEFF009D3D2D /* AccountModelHelper.swift in Sources */,
@@ -961,7 +985,6 @@
 				56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */,
 				56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */,
 				02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
-				56BBC9DB1EDDC7F700CDAF8B /* LookupNameResponse.m in Sources */,
 				564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
 				043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
 				02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
@@ -977,11 +1000,15 @@
 				043999FA1D1C2D9D00E99CD9 /* Ring.xcdatamodeld in Sources */,
 				564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */,
 				0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */,
+				56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */,
+				56BBC9CD1EDC5E7000CDAF8B /* MessageAccessoryView.swift in Sources */,
 				02DD80CA1E1EAF1A009A3510 /* AccountCredentialsModel.swift in Sources */,
 				56559B171EEED50D00BF20E1 /* Colors.swift in Sources */,
 				0273C3081E0C68BF00CF00BA /* RoundedButton.swift in Sources */,
 				56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */,
+				562FB6CD1EFAD18A00C61A78 /* ConversationViewController.swift in Sources */,
 				564C44621E943DE6000F92B1 /* NameService.swift in Sources */,
+				56BBC9E01EDDC9E600CDAF8B /* ConversationViewModel.swift in Sources */,
 				043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
 				04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
 				0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */,
diff --git a/Ring/Ring/Account/AccountModelHelper.swift b/Ring/Ring/Account/AccountModelHelper.swift
index f64dcb689fde8cd867f0295704eb34a474c83a89..202bdeba510804209343e65c7862089f9c197dca 100644
--- a/Ring/Ring/Account/AccountModelHelper.swift
+++ b/Ring/Ring/Account/AccountModelHelper.swift
@@ -120,4 +120,18 @@ struct AccountModelHelper {
         }
         return self.account
     }
+
+    var ringId :String? {
+
+        let accountUsernameKey = ConfigKeyModel(withKey: ConfigKey.AccountUsername)
+        let accountUsername = self.account.details.get(withConfigKeyModel: accountUsernameKey)
+
+        let ringIdPrefix = "ring:"
+        if accountUsername.contains(ringIdPrefix) {
+            let index = accountUsername.range(of: ringIdPrefix)?.upperBound
+            return accountUsername.substring(from: index!)
+        } else {
+            return nil
+        }
+    }
 }
diff --git a/Ring/Ring/Base.lproj/Main.storyboard b/Ring/Ring/Base.lproj/Main.storyboard
index e764877f82a6a7e7410a3fe8fa64474347a0cada..a7363869122022e228df8d102d491020602a79f3 100644
--- a/Ring/Ring/Base.lproj/Main.storyboard
+++ b/Ring/Ring/Base.lproj/Main.storyboard
@@ -248,12 +248,76 @@
                     <navigationItem key="navigationItem" id="b8m-eG-Q9D"/>
                     <connections>
                         <outlet property="tableView" destination="B6Y-MZ-L7L" id="dXp-J4-x68"/>
+                        <segue destination="Qlv-cA-wRT" kind="show" identifier="ShowMessages" id="X75-kM-dPZ"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="rzQ-ll-5bo" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
             <point key="canvasLocation" x="-97.5" y="-1177.8169014084508"/>
         </scene>
+        <!--Conversation View Controller-->
+        <scene sceneID="N9T-Vl-P5n">
+            <objects>
+                <viewController hidesBottomBarWhenPushed="YES" id="Qlv-cA-wRT" customClass="ConversationViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="wEb-Zj-bvJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="S9d-I1-nWj"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" misplaced="YES" id="jPi-CC-dFO">
+                        <rect key="frame" x="0.0" y="64" width="320" height="455"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="M1r-X5-oFv">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="455"/>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <prototypes>
+                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="MessageCellId" id="8rX-Qa-Ypu">
+                                        <rect key="frame" x="0.0" y="28" width="320" height="44"/>
+                                        <autoresizingMask key="autoresizingMask"/>
+                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="8rX-Qa-Ypu" id="7vA-nx-B3h">
+                                            <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                        </tableViewCellContentView>
+                                    </tableViewCell>
+                                </prototypes>
+                            </tableView>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PYu-2x-JXM">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="455"/>
+                                <subviews>
+                                    <activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="oH9-4M-JpG">
+                                        <rect key="frame" x="142" y="209" width="37" height="37"/>
+                                        <color key="color" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
+                                    </activityIndicatorView>
+                                </subviews>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="oH9-4M-JpG" firstAttribute="centerY" secondItem="PYu-2x-JXM" secondAttribute="centerY" id="105-id-Oqu"/>
+                                    <constraint firstItem="oH9-4M-JpG" firstAttribute="centerX" secondItem="PYu-2x-JXM" secondAttribute="centerX" id="Fk6-H6-Vdq"/>
+                                </constraints>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstAttribute="trailing" secondItem="M1r-X5-oFv" secondAttribute="trailing" id="4Dh-nK-p84"/>
+                            <constraint firstItem="M1r-X5-oFv" firstAttribute="top" secondItem="jPi-CC-dFO" secondAttribute="top" id="BFo-2E-BaG"/>
+                            <constraint firstAttribute="bottom" secondItem="M1r-X5-oFv" secondAttribute="bottom" id="PoM-IX-CFt"/>
+                            <constraint firstAttribute="trailing" secondItem="PYu-2x-JXM" secondAttribute="trailing" id="X7H-Er-Udk"/>
+                            <constraint firstItem="PYu-2x-JXM" firstAttribute="leading" secondItem="jPi-CC-dFO" secondAttribute="leading" id="dQk-7P-cld"/>
+                            <constraint firstItem="PYu-2x-JXM" firstAttribute="top" secondItem="jPi-CC-dFO" secondAttribute="top" id="g9s-sd-GJC"/>
+                            <constraint firstItem="M1r-X5-oFv" firstAttribute="leading" secondItem="jPi-CC-dFO" secondAttribute="leading" id="i0E-9E-6co"/>
+                            <constraint firstAttribute="bottom" secondItem="PYu-2x-JXM" secondAttribute="bottom" id="j3b-gd-iBK"/>
+                        </constraints>
+                    </view>
+                    <extendedEdge key="edgesForExtendedLayout"/>
+                    <connections>
+                        <outlet property="spinnerView" destination="PYu-2x-JXM" id="hxZ-lU-3XC"/>
+                        <outlet property="tableView" destination="M1r-X5-oFv" id="5Lh-Iu-nQb"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="bv6-qf-2Pa" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="844" y="-1179"/>
+        </scene>
         <!--Ring-->
         <scene sceneID="oqo-zJ-m0o">
             <objects>
diff --git a/Ring/Ring/ConversationCell.xib b/Ring/Ring/ConversationCell.xib
index c48708bf66698f6ca971f9c9e28c5943c5e1dc38..2125486ba74100ef966f7813d9c137f55471095d 100644
--- a/Ring/Ring/ConversationCell.xib
+++ b/Ring/Ring/ConversationCell.xib
@@ -80,7 +80,7 @@
                 <constraints>
                     <constraint firstItem="2fJ-Wf-1e0" firstAttribute="leading" secondItem="pFB-Jn-TNP" secondAttribute="trailing" constant="4" id="2NV-6m-dri"/>
                     <constraint firstItem="eug-ak-r49" firstAttribute="leading" secondItem="pFB-Jn-TNP" secondAttribute="trailing" constant="4" id="9ah-Ed-RlY"/>
-                    <constraint firstItem="pFB-Jn-TNP" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="9mO-5E-3lA"/>
+                   <constraint firstItem="pFB-Jn-TNP" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="9mO-5E-3lA"/>
                     <constraint firstItem="7Yv-cC-LKx" firstAttribute="leading" secondItem="2fJ-Wf-1e0" secondAttribute="trailing" constant="4" id="BzU-Ya-2ME"/>
                     <constraint firstAttribute="trailing" secondItem="eug-ak-r49" secondAttribute="trailing" constant="16" id="ITl-14-BeZ"/>
                     <constraint firstItem="JTE-eF-Y5s" firstAttribute="trailing" secondItem="pFB-Jn-TNP" secondAttribute="trailing" id="MgK-cd-QXM"/>
diff --git a/Ring/Ring/ConversationViewController.swift b/Ring/Ring/ConversationViewController.swift
new file mode 100644
index 0000000000000000000000000000000000000000..22638ed7478bfee6ded5f72bd31ffc82fe37f4ca
--- /dev/null
+++ b/Ring/Ring/ConversationViewController.swift
@@ -0,0 +1,168 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+import RxSwift
+
+class ConversationViewController: UIViewController, UITextFieldDelegate {
+
+    let disposeBag = DisposeBag()
+
+    var viewModel: ConversationViewModel?
+    var textFieldShouldEndEditing = false
+    var bottomOffset :CGFloat = 0
+
+    @IBOutlet weak var tableView: UITableView!
+    @IBOutlet weak var spinnerView: UIView!
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+
+        self.setupUI()
+        self.setupTableView()
+        self.setupBindings()
+
+        self.messageAccessoryView.messageTextField.delegate = self
+
+        /*
+         Register to keyboard notifications to adjust tableView insets when the keybaord appears
+         or disappears
+         */
+        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(withNotification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(withNotification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
+    }
+
+    func keyboardWillShow(withNotification notification: Notification) {
+
+        let userInfo: Dictionary = notification.userInfo!
+        let keyboardFrame: NSValue = userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue
+        let keyboardRectangle = keyboardFrame.cgRectValue
+        let keyboardHeight = keyboardRectangle.height
+
+        self.tableView.contentInset.bottom = keyboardHeight
+        self.tableView.scrollIndicatorInsets.bottom = keyboardHeight
+
+        self.scrollToBottom(animated: true)
+        self.updateBottomOffset()
+    }
+
+    func keyboardWillHide(withNotification notification: Notification) {
+        self.tableView.contentInset.bottom = 0
+        self.tableView.scrollIndicatorInsets.bottom = 0
+        self.updateBottomOffset()
+    }
+
+    func setupUI() {
+        self.viewModel?.userName.bind(to: self.navigationItem.rx.title).addDisposableTo(disposeBag)
+
+        self.tableView.contentInset.bottom = messageAccessoryView.frame.size.height
+        self.tableView.scrollIndicatorInsets.bottom = messageAccessoryView.frame.size.height
+    }
+
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+
+        self.scrollToBottom(animated: false)
+        self.messagesLoadingFinished()
+    }
+
+    override func viewWillDisappear(_ animated: Bool) {
+        super.viewWillDisappear(animated)
+
+        self.textFieldShouldEndEditing = true
+        self.viewModel?.setMessagesAsRead()
+    }
+
+    func setupTableView() {
+        self.tableView.estimatedRowHeight = 50
+        self.tableView.rowHeight = UITableViewAutomaticDimension
+        self.tableView.separatorStyle = .none
+
+        //Register cell
+        self.tableView.register(UINib.init(nibName: "MessageCell", bundle: nil),
+                                forCellReuseIdentifier: "MessageCellId")
+
+        //Bind the TableView to the ViewModel
+        self.viewModel?.messages.bind(to: tableView.rx.items(cellIdentifier: "MessageCellId", cellType: MessageCell.self))
+            { index, messageViewModel, cell in
+                cell.messageLabel.text = messageViewModel.content
+                cell.bubblePosition = messageViewModel.bubblePosition()
+            }.addDisposableTo(disposeBag)
+
+        //Scroll to bottom when reloaded
+        self.tableView.rx.methodInvoked(#selector(UITableView.reloadData)).subscribe(onNext: { element in
+            self.scrollToBottomIfNeed()
+            self.updateBottomOffset()
+        }).addDisposableTo(disposeBag)
+    }
+
+    fileprivate func updateBottomOffset() {
+        self.bottomOffset = self.tableView.contentSize.height
+            - ( self.tableView.frame.size.height
+                - self.tableView.contentInset.top
+                - self.tableView.contentInset.bottom )
+    }
+
+    fileprivate func messagesLoadingFinished() {
+        self.spinnerView.isHidden = true
+    }
+
+    fileprivate func scrollToBottomIfNeed() {
+        if self.isBottomContentOffset {
+            self.scrollToBottom(animated: true)
+        }
+    }
+
+    fileprivate func scrollToBottom(animated: Bool) {
+        let last = IndexPath(row: self.tableView.numberOfRows(inSection: 0) - 1, section: 0)
+        self.tableView.scrollToRow(at: last, at: .bottom, animated: animated)
+    }
+
+    fileprivate var isBottomContentOffset: Bool {
+        return self.tableView.contentOffset.y + self.tableView.contentInset.top >= bottomOffset
+    }
+
+    override var inputAccessoryView: UIView {
+        return self.messageAccessoryView
+    }
+
+    override var canBecomeFirstResponder: Bool {
+        return true
+    }
+
+    lazy var messageAccessoryView: MessageAccessoryView = {
+        return MessageAccessoryView.instanceFromNib()
+    }()
+
+    func setupBindings() {
+
+        //Binds the keyboard Send button action to the ViewModel
+        self.messageAccessoryView.messageTextField.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: { event in
+            self.viewModel?.sendMessage(withContent: self.messageAccessoryView.messageTextField.text!)
+            self.messageAccessoryView.messageTextField.text = ""
+        }).addDisposableTo(disposeBag)
+    }
+
+    // Avoid the keyboard to be hidden when the Send button is touched
+    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
+        return textFieldShouldEndEditing
+    }
+
+}
diff --git a/Ring/Ring/ConversationViewModel.swift b/Ring/Ring/ConversationViewModel.swift
index 19537035c2ece2f2a61117460ba0f5707da4f8ea..833f8d369979a07e4e292d95920673d78e3d49da 100644
--- a/Ring/Ring/ConversationViewModel.swift
+++ b/Ring/Ring/ConversationViewModel.swift
@@ -34,28 +34,40 @@ class ConversationViewModel {
 
     private let disposeBag = DisposeBag()
 
+    let messages :Observable<[MessageViewModel]>
+
+    private let conversationsService = AppDelegate.conversationsService
+    private let accountService = AppDelegate.accountService
+
     init(withConversation conversation: ConversationModel) {
         self.conversation = conversation
+
         dateFormatter.dateStyle = .medium
         hourFormatter.dateFormat = "HH:mm"
 
         self.userName = ContactHelper.lookupUserName(forRingId: self.conversation.recipient.ringId,
                                                 nameService: AppDelegate.nameService,
                                                 disposeBag: self.disposeBag).asObservable()
+
+        //Create observable from sorted conversations and flatMap them to view models
+        self.messages = self.conversationsService.conversations.asObservable().map({ conversations in
+            return conversations.filter({ currentConversation in
+                return currentConversation.recipient == conversation.recipient
+            }).flatMap({ conversation in
+                conversation.messages.map({ message in
+                    return MessageViewModel(withMessage: message)
+                })
+            })
+        }).observeOn(MainScheduler.instance)
+
     }
 
     var unreadMessages: String {
        return self.unreadMessagesCount.description
     }
 
-    fileprivate var unreadMessagesCount: Int {
-        return self.conversation.messages.filter({ message in
-            return message.status != .read
-        }).count
-    }
-
     var hasUnreadMessages: Bool {
-        return conversation.messages.count > 0
+        return unreadMessagesCount > 0
     }
 
     var lastMessage: String {
@@ -96,4 +108,43 @@ class ConversationViewModel {
             return dateFormatter.string(from: lastMessageDate)
         }
     }
+
+    var hideNewMessagesLabel: Bool {
+        return self.unreadMessagesCount == 0
+    }
+
+    func sendMessage(withContent content: String) {
+        self.conversationsService
+            .sendMessage(withContent: content,
+                         from: accountService.currentAccount!,
+                         to: self.conversation.recipient)
+            .subscribe(onCompleted: {
+                let accountHelper = AccountModelHelper(withAccount: self.accountService.currentAccount!)
+                self.saveMessage(withContent: content, byAuthor: accountHelper.ringId!, toConversationWith: self.conversation.recipient.ringId)
+            }).addDisposableTo(disposeBag)
+    }
+
+    fileprivate func saveMessage(withContent content: String, byAuthor author: String, toConversationWith account: String) {
+        self.conversationsService
+            .saveMessage(withContent: content, byAuthor: author, toConversationWith: account)
+            .subscribe(onCompleted: {
+                print("Message saved")
+            })
+            .addDisposableTo(disposeBag)
+    }
+
+    func setMessagesAsRead() {
+        self.conversationsService
+            .setMessagesAsRead(forConversation: self.conversation)
+            .subscribe(onCompleted: {
+                print("Message set as read")
+            }).addDisposableTo(disposeBag)
+    }
+
+    fileprivate var unreadMessagesCount: Int {
+        let accountHelper = AccountModelHelper(withAccount: self.accountService.currentAccount!)
+        return self.conversation.messages.filter({ message in
+            return message.status != .read && message.author != accountHelper.ringId!
+        }).count
+    }
 }
diff --git a/Ring/Ring/ConversationsService.swift b/Ring/Ring/ConversationsService.swift
index 0d77c07f2d8ad3e59e61e775e247b420647846e6..a6f7b9d5c17a98658dd3e885ece8329d64039cf0 100644
--- a/Ring/Ring/ConversationsService.swift
+++ b/Ring/Ring/ConversationsService.swift
@@ -27,28 +27,34 @@ class ConversationsService: MessagesAdapterDelegate {
     fileprivate let disposeBag = DisposeBag()
     fileprivate let textPlainMIMEType = "text/plain"
 
-    let conversations = Variable([ConversationModel]())
+    var conversations = Variable([ConversationModel]())
 
     init(withMessageAdapter messageAdapter: MessagesAdapter) {
         self.messageAdapter = messageAdapter
         MessagesAdapter.delegate = self
-    }
 
-    func status(forMessageId messageId: UInt64) -> MessageStatus {
-        return self.messageAdapter.status(forMessageId: messageId)
     }
 
-    //MARK: Message Adapter delegate
+    func sendMessage(withContent content: String, from senderAccount: AccountModel, to recipient: ContactModel) -> Completable {
 
-    func didReceiveMessage(_ message: Dictionary<String, String>, from senderAccount: String,
-                           to receiverAccountId: String) {
+        return Completable.create(subscribe: { [unowned self] completable in
+            let contentDict = [self.textPlainMIMEType : content]
+            self.messageAdapter.sendMessage(withContent: contentDict, withAccountId: senderAccount.id, to: recipient.ringId)
 
-        if let content = message[textPlainMIMEType] {
-            let message = MessageModel(withId: nil, receivedDate: Date(), content: content, author: senderAccount)
+            completable(.completed)
+
+            return Disposables.create {}
+        })
+    }
+
+    func saveMessage(withContent content: String, byAuthor author: String, toConversationWith account: String) -> Completable {
+
+        return Completable.create(subscribe: { [unowned self] completable in
+            let message = MessageModel(withId: nil, receivedDate: Date(), content: content, author: author)
 
             //Get conversations for this sender
-            var currentConversation = conversations.value.filter({ conversation in
-                return conversation.recipient.ringId == senderAccount
+            var currentConversation = self.conversations.value.filter({ conversation in
+                return conversation.recipient.ringId == account
             }).first
 
             //Get the current array of conversations
@@ -56,7 +62,7 @@ class ConversationsService: MessagesAdapterDelegate {
 
             //Create a new conversation for this sender if not exists
             if currentConversation == nil {
-                currentConversation = ConversationModel(withRecipient: ContactModel(withRingId: senderAccount), accountId: receiverAccountId)
+                currentConversation = ConversationModel(withRecipient: ContactModel(withRingId: account), accountId: author)
                 currentConversations.append(currentConversation!)
             }
 
@@ -65,6 +71,55 @@ class ConversationsService: MessagesAdapterDelegate {
 
             //Upate the value of the Variable
             self.conversations.value = currentConversations
+
+            completable(.completed)
+
+            return Disposables.create { }
+
+        })
+    }
+
+    func status(forMessageId messageId: UInt64) -> MessageStatus {
+        return self.messageAdapter.status(forMessageId: messageId)
+    }
+
+    func setMessagesAsRead(forConversation conversation: ConversationModel) -> Completable {
+
+        return Completable.create(subscribe: { completable in
+
+            //Get the current array of conversations
+            let currentConversations = self.conversations.value
+
+            //Filter unread messages
+            let unreadMessages = conversation.messages.filter({ messages in
+                return messages.status != .read
+            })
+
+            for message in unreadMessages {
+                message.status = .read
+            }
+
+            //Upate the value of the Variable
+            self.conversations.value = currentConversations
+
+            completable(.completed)
+
+            return Disposables.create { }
+
+        })
+    }
+
+    //MARK: Message Adapter delegate
+
+    func didReceiveMessage(_ message: Dictionary<String, String>, from senderAccount: String,
+                           to receiverAccountId: String) {
+
+        if let content = message[textPlainMIMEType] {
+            self.saveMessage(withContent: content, byAuthor: senderAccount, toConversationWith: senderAccount)
+                .subscribe(onCompleted: {
+                    print("Message saved")
+                })
+                .addDisposableTo(disposeBag)
         }
     }
 
diff --git a/Ring/Ring/Info.plist b/Ring/Ring/Info.plist
index 3af58c779856da670ecf406ac70a6fba07529474..b4b43918405a24faceb474711e49899f51a8cf87 100644
--- a/Ring/Ring/Info.plist
+++ b/Ring/Ring/Info.plist
@@ -30,6 +30,8 @@
 	<array>
 		<string>armv7</string>
 	</array>
+	<key>UIStatusBarStyle</key>
+	<string>UIStatusBarStyleLightContent</string>
 	<key>UIStatusBarTintParameters</key>
 	<dict>
 		<key>UINavigationBar</key>
diff --git a/Ring/Ring/MessageAccessoryView.swift b/Ring/Ring/MessageAccessoryView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..3e285bca7be51bf1315de062e195ab0d4d3785a9
--- /dev/null
+++ b/Ring/Ring/MessageAccessoryView.swift
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+
+class MessageAccessoryView: UIView {
+
+    @IBOutlet weak var messageTextField: UITextField!
+
+    class func instanceFromNib() -> MessageAccessoryView {
+        return UINib(nibName: "MessageAccessoryView", bundle: nil)
+            .instantiate(withOwner: nil, options: nil).first as! MessageAccessoryView
+    }
+
+}
diff --git a/Ring/Ring/MessageAccessoryView.xib b/Ring/Ring/MessageAccessoryView.xib
new file mode 100644
index 0000000000000000000000000000000000000000..65027b081e3ac504ae14a56552833c4049a90ee9
--- /dev/null
+++ b/Ring/Ring/MessageAccessoryView.xib
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="Fja-dy-lIy" customClass="MessageAccessoryView" customModule="Ring" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="315" height="38"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <subviews>
+                <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Write a message..." textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="AJA-0c-Rp7">
+                    <rect key="frame" x="4" y="4" width="307" height="30"/>
+                    <nil key="textColor"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                    <textInputTraits key="textInputTraits" returnKeyType="send" enablesReturnKeyAutomatically="YES"/>
+                </textField>
+            </subviews>
+            <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="AJA-0c-Rp7" secondAttribute="bottom" constant="4" id="Gph-b4-ZJH"/>
+                <constraint firstAttribute="trailing" secondItem="AJA-0c-Rp7" secondAttribute="trailing" constant="4" id="UyK-3a-JcH"/>
+                <constraint firstItem="AJA-0c-Rp7" firstAttribute="top" secondItem="Fja-dy-lIy" secondAttribute="top" constant="4" id="mDu-cF-UdO"/>
+                <constraint firstItem="AJA-0c-Rp7" firstAttribute="leading" secondItem="Fja-dy-lIy" secondAttribute="leading" constant="4" id="tvd-4f-jdO"/>
+            </constraints>
+            <nil key="simulatedStatusBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="messageTextField" destination="AJA-0c-Rp7" id="ga9-yi-G2h"/>
+            </connections>
+            <point key="canvasLocation" x="-15" y="-178"/>
+        </view>
+    </objects>
+</document>
diff --git a/Ring/Ring/MessageCell.swift b/Ring/Ring/MessageCell.swift
new file mode 100644
index 0000000000000000000000000000000000000000..7cc80f6543051f5373d7c50ce8d54f671fd3edaf
--- /dev/null
+++ b/Ring/Ring/MessageCell.swift
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+
+enum BubblePosition {
+    case received
+    case sent
+}
+
+class MessageCell: UITableViewCell {
+
+    @IBOutlet weak var bubble: UIView!
+    @IBOutlet weak var messageLabel: UILabel!
+
+    @IBOutlet weak var minimumLeadingConstraint: NSLayoutConstraint!
+    @IBOutlet weak var containerLeadingConstraint: NSLayoutConstraint!
+
+    @IBOutlet weak var minimumTrailingConstraint: NSLayoutConstraint!
+    @IBOutlet weak var containerTrailingConstraint: NSLayoutConstraint!
+
+    var bubblePosition = BubblePosition.received {
+        didSet {
+            if bubblePosition == .sent {
+                self.minimumTrailingConstraint.priority = 1
+                self.containerTrailingConstraint.priority = 999
+                self.containerLeadingConstraint.priority = 1
+                self.minimumLeadingConstraint.priority = 999
+
+                self.bubble.backgroundColor = Colors.ringMainColor
+                self.messageLabel.textColor = UIColor.white
+            } else {
+                self.minimumLeadingConstraint.priority = 1
+                self.containerLeadingConstraint.priority = 999
+                self.containerTrailingConstraint.priority = 1
+                self.minimumTrailingConstraint.priority = 999
+
+                self.bubble.backgroundColor = UIColor.lightGray
+                self.messageLabel.textColor = UIColor.black
+            }
+        }
+    }
+
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        self.bubblePosition = .received
+    }
+
+    override func setSelected(_ selected: Bool, animated: Bool) {
+        super.setSelected(selected, animated: animated)
+    }
+}
diff --git a/Ring/Ring/MessageCell.xib b/Ring/Ring/MessageCell.xib
new file mode 100644
index 0000000000000000000000000000000000000000..0bf54454032c3abd681c537bd54cb2fc3ec331d0
--- /dev/null
+++ b/Ring/Ring/MessageCell.xib
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="MessageCellId" rowHeight="60" id="KGk-i7-Jjw" customClass="MessageCell" customModule="Ring" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="510" height="47"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="510" height="46"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR">
+                        <rect key="frame" x="16" y="8" width="152.5" height="30.5"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label Label Label Label " lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lyR-7c-S2k">
+                                <rect key="frame" x="8" y="4" width="136.5" height="22.5"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <nil key="textColor"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="30" id="1Kj-UZ-gu7"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="leading" secondItem="kZJ-Ay-LTR" secondAttribute="leading" constant="8" id="8m5-sR-xnh"/>
+                            <constraint firstAttribute="bottom" secondItem="lyR-7c-S2k" secondAttribute="bottom" constant="4" id="gwN-uX-PWd"/>
+                            <constraint firstAttribute="trailing" secondItem="lyR-7c-S2k" secondAttribute="trailing" constant="8" id="uzV-kG-oGN"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" constant="4" id="ycc-WI-Jk6"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+                                <integer key="value" value="5"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" constant="8" id="1QQ-bu-6Bl"/>
+                    <constraint firstAttribute="trailing" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" priority="1" constant="16" id="99Y-bR-Ioq"/>
+                    <constraint firstItem="kZJ-Ay-LTR" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="H2p-sc-9uM" secondAttribute="leading" priority="1" constant="64" id="Eso-cy-OYs"/>
+                    <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" constant="64" id="TCY-7X-mFs"/>
+                    <constraint firstItem="kZJ-Ay-LTR" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="jhd-A8-c1o"/>
+                    <constraint firstItem="kZJ-Ay-LTR" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="nWe-5k-Qpn"/>
+                </constraints>
+            </tableViewCellContentView>
+            <connections>
+                <outlet property="bubble" destination="kZJ-Ay-LTR" id="hdG-fG-L69"/>
+                <outlet property="containerLeadingConstraint" destination="nWe-5k-Qpn" id="Ahu-gW-4IY"/>
+                <outlet property="containerTrailingConstraint" destination="99Y-bR-Ioq" id="JJr-pE-UfA"/>
+                <outlet property="messageLabel" destination="lyR-7c-S2k" id="hd3-pz-Pwh"/>
+                <outlet property="minimumLeadingConstraint" destination="Eso-cy-OYs" id="jhV-mE-FMA"/>
+                <outlet property="minimumTrailingConstraint" destination="TCY-7X-mFs" id="xj3-4A-I9G"/>
+            </connections>
+            <point key="canvasLocation" x="-411" y="-132"/>
+        </tableViewCell>
+    </objects>
+</document>
diff --git a/Ring/Ring/MessageViewModel.swift b/Ring/Ring/MessageViewModel.swift
new file mode 100644
index 0000000000000000000000000000000000000000..ea74b8715f7b91fa456fc21e9716462e045788de
--- /dev/null
+++ b/Ring/Ring/MessageViewModel.swift
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import RxSwift
+
+class MessageViewModel {
+
+    fileprivate let accountService = AppDelegate.accountService
+    fileprivate var message :MessageModel
+
+    init(withMessage message: MessageModel) {
+        self.message = message
+    }
+
+    var content: String {
+        return self.message.content
+    }
+
+    func bubblePosition() -> BubblePosition {
+
+        let accountHelper = AccountModelHelper(withAccount: accountService.currentAccount!)
+
+        if self.message.author == accountHelper.ringId! {
+            return .sent
+        } else {
+            return .received
+        }
+    }
+}
diff --git a/Ring/Ring/SmartlistViewController.swift b/Ring/Ring/SmartlistViewController.swift
index 0768bdf025826de9cd6042ab24399f63889b5c33..821409b9bd5ebeafd94e9687204005a62c187f58 100644
--- a/Ring/Ring/SmartlistViewController.swift
+++ b/Ring/Ring/SmartlistViewController.swift
@@ -30,6 +30,8 @@ class SmartlistViewController: UIViewController, UITableViewDelegate {
     fileprivate let disposeBag = DisposeBag()
     fileprivate let SmartlistRowHeight :CGFloat = 64.0
 
+    var selectedItem: ConversationViewModel?
+
     override func viewDidLoad() {
         super.viewDidLoad()
         self.setupUI()
@@ -61,16 +63,25 @@ class SmartlistViewController: UIViewController, UITableViewDelegate {
             cell.lastMessagePreviewLabel.text = viewModel.lastMessage
         }.addDisposableTo(disposeBag)
 
+        //Deselect the row
         self.tableView.rx.itemSelected.asObservable().subscribe(onNext: { indexPath in
             self.tableView.deselectRow(at: indexPath, animated: true)
         }).addDisposableTo(disposeBag)
+
+        //Show the Messages screens and pass the viewModel
+        self.tableView.rx.modelSelected(ConversationViewModel.self).subscribe(onNext: { item in
+            self.selectedItem = item
+            self.performSegue(withIdentifier: "ShowMessages", sender: nil)
+        }).addDisposableTo(disposeBag)
     }
 
     // MARK: - Navigation
 
     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
-
+        if let msgVC = segue.destination as? ConversationViewController {
+            msgVC.viewModel = self.selectedItem
+        }
     }
 
 }