diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index aa7323ab83504d3ce29af76d6e64215f726151dd..f0d96eac5215592c00e3f802ea8f27bf5ecbdb98 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -186,6 +186,8 @@
 		56BBC9D41EDC7A6D00CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9D31EDC7A6D00CDAF8B /* libargon2.a */; };
 		56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */; };
 		56C715FF1F0D36C600770048 /* ContactsAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 56C715FE1F0D36C600770048 /* ContactsAdapter.mm */; };
+		621231F91F880EDF009B86F0 /* UILabel+Ring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621231F81F880EDF009B86F0 /* UILabel+Ring.swift */; };
+		621231FB1F8D6FEE009B86F0 /* MessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621231FA1F8D6FEE009B86F0 /* MessageCell.swift */; };
 		62A88D371F6C2ED400F8AB18 /* PresenceAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A88D361F6C2ED400F8AB18 /* PresenceAdapterDelegate.swift */; };
 		62A88D391F6C323500F8AB18 /* PresenceAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 62A88D381F6C323500F8AB18 /* PresenceAdapter.mm */; };
 		62A88D3B1F6C3ACC00F8AB18 /* PresenceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A88D3A1F6C3ACC00F8AB18 /* PresenceService.swift */; };
@@ -417,6 +419,8 @@
 		56C715FE1F0D36C600770048 /* ContactsAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContactsAdapter.mm; sourceTree = "<group>"; };
 		56C716001F0D36D900770048 /* ContactsAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactsAdapterDelegate.swift; sourceTree = "<group>"; };
 		56C716021F0D466100770048 /* ContactsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactsService.swift; sourceTree = "<group>"; };
+		621231F81F880EDF009B86F0 /* UILabel+Ring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+Ring.swift"; sourceTree = "<group>"; };
+		621231FA1F8D6FEE009B86F0 /* MessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCell.swift; sourceTree = "<group>"; };
 		62A88D351F6C2E5F00F8AB18 /* PresenceAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PresenceAdapter.h; sourceTree = "<group>"; };
 		62A88D361F6C2ED400F8AB18 /* PresenceAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresenceAdapterDelegate.swift; sourceTree = "<group>"; };
 		62A88D381F6C323500F8AB18 /* PresenceAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PresenceAdapter.mm; sourceTree = "<group>"; };
@@ -633,6 +637,7 @@
 				1A2D18A51F27F7A400B2C785 /* UIViewController+Rx.swift */,
 				0586C94A1F684DF600613517 /* UIImage+Helpers.swift */,
 				0EE1B54D1F75ACDE00BA98EE /* CNContactVCardSerialization+Helpers.swift */,
+				621231F81F880EDF009B86F0 /* UILabel+Ring.swift */,
 			);
 			path = Extensions;
 			sourceTree = "<group>";
@@ -957,6 +962,7 @@
 				1A2D18F11F292D7200B2C785 /* MessageCellReceived.swift */,
 				1A2D18F21F292D7200B2C785 /* MessageCellReceived.xib */,
 				1A2D18F31F292D7200B2C785 /* MessageCellSent.swift */,
+				621231FA1F8D6FEE009B86F0 /* MessageCell.swift */,
 				1A2D18F41F292D7200B2C785 /* MessageCellSent.xib */,
 				0E403F801F7D797300C80BC2 /* MessageCellGenerated.swift */,
 				0E403F821F7D79B000C80BC2 /* MessageCellGenerated.xib */,
@@ -1274,6 +1280,7 @@
 			files = (
 				557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */,
 				0586C94B1F684DF600613517 /* UIImage+Helpers.swift in Sources */,
+				621231F91F880EDF009B86F0 /* UILabel+Ring.swift in Sources */,
 				1A2D18AC1F29149D00B2C785 /* MeCoordinator.swift in Sources */,
 				1A2D18C51F29180700B2C785 /* ContactModel.swift in Sources */,
 				1A2D18F71F292D7200B2C785 /* MessageCellSent.swift in Sources */,
@@ -1310,6 +1317,7 @@
 				56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */,
 				1A3CA32D1F13DA7200283748 /* Chameleon+Ring.swift in Sources */,
 				1ABE07E21F0D924700D36361 /* Strings.swift in Sources */,
+				621231FB1F8D6FEE009B86F0 /* MessageCell.swift in Sources */,
 				56AC650E1E85694D00EA1AA9 /* DesignableTextField.swift in Sources */,
 				1A2D189A1F2642C000B2C785 /* NotificationCenter+Ring.swift in Sources */,
 				1A2D18FC1F292DAD00B2C785 /* ConversationCell.swift in Sources */,
diff --git a/Ring/Ring/AppDelegate.swift b/Ring/Ring/AppDelegate.swift
index 6deb2d7830e053db795efccb3f64a10e6e833e2e..57f30ffbf9b3e34349d3b755c2c57d654f44ed0b 100644
--- a/Ring/Ring/AppDelegate.swift
+++ b/Ring/Ring/AppDelegate.swift
@@ -58,6 +58,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 
         self.window = UIWindow(frame: UIScreen.main.bounds)
 
+        UserDefaults.standard.setValue(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")
+
         // initialize log format
         let console = ConsoleDestination()
         console.format = "$Dyyyy-MM-dd HH:mm:ss.SSS$d $C$L$c: $M"
diff --git a/Ring/Ring/Extensions/Chameleon+Ring.swift b/Ring/Ring/Extensions/Chameleon+Ring.swift
index 0146a074cd2ef35b9bc268b935d8a2fff51d41f9..f3961e46b7f8f63662b3d7e7b2d1674cf6df4c39 100644
--- a/Ring/Ring/Extensions/Chameleon+Ring.swift
+++ b/Ring/Ring/Extensions/Chameleon+Ring.swift
@@ -31,15 +31,12 @@ extension Chameleon {
         case .contrast:
             contentColor = ContrastColorOf(primaryColor, returnFlat: false)
             secondaryContentColor = ContrastColorOf(secondaryColor, returnFlat: false)
-            break
         case .light:
             contentColor = UIColor.white
             secondaryContentColor = UIColor.white
-            break
         case .dark:
             contentColor = UIColor.flatBlackColorDark()
             secondaryContentColor = UIColor.flatBlackColorDark()
-            break
         }
 
         UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = UIColor.flatGray()
@@ -48,12 +45,12 @@ extension Chameleon {
         MessageBubble.appearance().backgroundColor = secondaryColor
 
         MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellSent.self]).tintColor = contentColor
-        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellSent.self]).backgroundColor = primaryColor
-        UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellSent.self]).textColor = contentColor
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellSent.self]).backgroundColor = UIColor.ringMsgCellSent
+        UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellSent.self]).textColor = UIColor.ringMsgCellSentText
 
         MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).tintColor = secondaryContentColor
-        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).backgroundColor = secondaryColor
-        UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellReceived.self]).textColor = secondaryContentColor
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).backgroundColor = UIColor.ringMsgCellReceived
+        UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellReceived.self]).textColor = UIColor.ringMsgCellReceivedText
 
         MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellGenerated.self]).tintColor = UIColor.clear
         MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellGenerated.self]).backgroundColor = UIColor.clear
diff --git a/Ring/Ring/Extensions/UIColor+Ring.swift b/Ring/Ring/Extensions/UIColor+Ring.swift
index 27d831c548a37dda982a03177d0f04ea147b45c5..ae88929776ac3e689bb11ffc5933efad3e10fe61 100644
--- a/Ring/Ring/Extensions/UIColor+Ring.swift
+++ b/Ring/Ring/Extensions/UIColor+Ring.swift
@@ -33,4 +33,24 @@ extension UIColor {
                                   blue: 96.0/255.0,
                                   alpha: 1.0)
 
+    static let ringMsgCellSent = UIColor(colorLiteralRed: 58.0/255.0,
+                                           green: 192.0/255.0,
+                                           blue: 210.0/255.0,
+                                           alpha: 1.0)
+
+    static let ringMsgCellSentText = UIColor(colorLiteralRed: 255.0/255.0,
+                                         green: 255.0/255.0,
+                                         blue: 255.0/255.0,
+                                         alpha: 1.0)
+
+    static let ringMsgCellReceived = UIColor(colorLiteralRed: 235.0/255.0,
+                                       green: 239.0/255.0,
+                                       blue: 239.0/255.0,
+                                       alpha: 1.0)
+
+    static let ringMsgCellReceivedText = UIColor(colorLiteralRed: 48.0/255.0,
+                                         green: 48.0/255.0,
+                                         blue: 48.0/255.0,
+                                         alpha: 1.0)
+
 }
diff --git a/Ring/Ring/Extensions/UILabel+Ring.swift b/Ring/Ring/Extensions/UILabel+Ring.swift
new file mode 100644
index 0000000000000000000000000000000000000000..106c380a29b24ac945643015e90c8a4bd0365efa
--- /dev/null
+++ b/Ring/Ring/Extensions/UILabel+Ring.swift
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Andreas Traczyk <andreas.traczyk@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 Foundation
+
+extension UILabel {
+    func setTextWithLineSpacing(withText: String, withLineSpacing: CGFloat) {
+        let attrString = NSMutableAttributedString(string: withText)
+        let style = NSMutableParagraphStyle()
+        style.lineSpacing = withLineSpacing
+        attrString.addAttribute(NSParagraphStyleAttributeName,
+                                value: style,
+                                range: NSRange(location: 0, length: withText.utf16.count))
+        self.attributedText = attrString
+    }
+}
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
new file mode 100644
index 0000000000000000000000000000000000000000..fa63c030205aee2ec2ea106338db4e94c9bf6595
--- /dev/null
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *  Author: Andreas Traczyk <andreas.traczyk@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 Reusable
+
+class MessageCell: UITableViewCell, NibReusable {
+
+    @IBOutlet weak var bubble: MessageBubble!
+    @IBOutlet weak var bubbleBottomConstraint: NSLayoutConstraint!
+    @IBOutlet weak var bubbleTopConstraint: NSLayoutConstraint!
+    @IBOutlet weak var messageLabel: UILabel!
+    @IBOutlet weak var bottomCorner: UIView!
+    @IBOutlet weak var topCorner: UIView!
+}
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.swift
index 0b42e9a7cff506df2e4ba5d36b6817b9bec42f46..c504acdef93d38101e79aa30bbea7258cf75f0c7 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.swift
@@ -21,9 +21,5 @@
 import UIKit
 import Reusable
 
-class MessageCellReceived: UITableViewCell, NibReusable {
-
-    @IBOutlet weak var bubble: MessageBubble!
-    @IBOutlet weak var messageLabel: UILabel!
-
+class MessageCellReceived: MessageCell {
 }
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
index 679b0e0e6f74c4e09375f91809fa431a1360c8e2..b381a8be6edd0eb6f85ef866c665e5b23b13e42e 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
@@ -15,48 +15,73 @@
             <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.5"/>
+                <rect key="frame" x="0.0" y="0.0" width="510" height="47"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WBd-CS-7Qv" userLabel="Top Corner">
+                        <rect key="frame" x="16" y="8" width="15" height="15"/>
+                        <color key="backgroundColor" red="1" green="0.0" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="15" id="fjJ-O1-VNm"/>
+                            <constraint firstAttribute="width" constant="15" id="gch-Wg-ytg"/>
+                        </constraints>
+                    </view>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XcL-CH-BiH" userLabel="Bottom Corner">
+                        <rect key="frame" x="16" y="24" width="15" height="15"/>
+                        <color key="backgroundColor" red="1" green="0.5" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="15" id="ocR-DU-zKZ"/>
+                            <constraint firstAttribute="height" constant="15" id="ooc-tv-fiO"/>
+                        </constraints>
+                    </view>
                     <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
-                        <rect key="frame" x="16" y="8" width="152.5" height="30.5"/>
+                        <rect key="frame" x="16" y="8" width="190.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"/>
+                            <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="10" y="8" width="170.5" height="14.5"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                                <color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <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"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="leading" secondItem="kZJ-Ay-LTR" secondAttribute="leading" constant="10" id="8m5-sR-xnh"/>
+                            <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="28" id="UWN-H4-Sh9"/>
+                            <constraint firstAttribute="bottom" secondItem="lyR-7c-S2k" secondAttribute="bottom" constant="8" id="gwN-uX-PWd"/>
+                            <constraint firstAttribute="trailing" secondItem="lyR-7c-S2k" secondAttribute="trailing" constant="10" id="uzV-kG-oGN"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" constant="8" id="ycc-WI-Jk6"/>
                         </constraints>
                         <userDefinedRuntimeAttributes>
                             <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                <real key="value" value="4"/>
+                                <integer key="value" value="15"/>
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </view>
                 </subviews>
                 <constraints>
                     <constraint firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" constant="8" id="1QQ-bu-6Bl"/>
+                    <constraint firstItem="XcL-CH-BiH" firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" id="2d4-0F-VWg"/>
+                    <constraint firstItem="WBd-CS-7Qv" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" id="4Zp-8q-rFJ"/>
                     <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 firstItem="XcL-CH-BiH" firstAttribute="leading" secondItem="kZJ-Ay-LTR" secondAttribute="leading" id="GaI-yj-QFt"/>
                     <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"/>
+                    <constraint firstItem="WBd-CS-7Qv" firstAttribute="leading" secondItem="kZJ-Ay-LTR" secondAttribute="leading" id="yBG-sT-w2a"/>
                 </constraints>
             </tableViewCellContentView>
             <connections>
+                <outlet property="bottomCorner" destination="XcL-CH-BiH" id="4gw-IC-EAM"/>
                 <outlet property="bubble" destination="kZJ-Ay-LTR" id="hdG-fG-L69"/>
+                <outlet property="bubbleBottomConstraint" destination="1QQ-bu-6Bl" id="a4F-pf-cXL"/>
+                <outlet property="bubbleTopConstraint" destination="jhd-A8-c1o" id="40k-2d-6rW"/>
                 <outlet property="messageLabel" destination="lyR-7c-S2k" id="hd3-pz-Pwh"/>
+                <outlet property="topCorner" destination="WBd-CS-7Qv" id="GCm-Hv-5Ei"/>
             </connections>
-            <point key="canvasLocation" x="-411" y="-132"/>
+            <point key="canvasLocation" x="-411" y="-132.5"/>
         </tableViewCell>
     </objects>
 </document>
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.swift
index 336836d6fd4271da69993d565c3ed5a8cd95648d..7d5d96a72726824801c4741ae06f11520a2ff169 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.swift
@@ -21,9 +21,5 @@
 import UIKit
 import Reusable
 
-class MessageCellSent: UITableViewCell, NibReusable {
-
-    @IBOutlet weak var bubble: MessageBubble!
-    @IBOutlet weak var messageLabel: UILabel!
-
+class MessageCellSent: MessageCell {
 }
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.xib
index 04dc0efe4a881bf121603ea92110f882db6576f1..41e65e646798012f611666493a47500e7318eed3 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.xib
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellSent.xib
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
@@ -18,45 +18,70 @@
                 <rect key="frame" x="0.0" y="0.0" width="510" height="46.5"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hdz-AQ-xHI" userLabel="Bottom Corner">
+                        <rect key="frame" x="479" y="24" width="15" height="15"/>
+                        <color key="backgroundColor" red="1" green="0.5" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="15" id="D0h-cW-9kB"/>
+                            <constraint firstAttribute="width" constant="15" id="wlh-ar-Nsv"/>
+                        </constraints>
+                    </view>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EMh-bG-ilg" userLabel="Top Corner">
+                        <rect key="frame" x="479" y="8" width="15" height="15"/>
+                        <color key="backgroundColor" red="1" green="0.0" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="15" id="zaa-Rn-ziw"/>
+                            <constraint firstAttribute="height" constant="15" id="zuP-4P-1GS"/>
+                        </constraints>
+                    </view>
                     <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
-                        <rect key="frame" x="341.5" y="8" width="152.5" height="30.5"/>
+                        <rect key="frame" x="303.5" y="8" width="190.5" height="31"/>
                         <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"/>
+                            <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="10" y="8" width="170.5" height="15"/>
+                                <fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="16"/>
+                                <color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <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"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="leading" secondItem="kZJ-Ay-LTR" secondAttribute="leading" constant="10" id="8m5-sR-xnh"/>
+                            <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="28" id="BZE-kP-hPK"/>
+                            <constraint firstAttribute="bottom" secondItem="lyR-7c-S2k" secondAttribute="bottom" constant="8" id="gwN-uX-PWd"/>
+                            <constraint firstAttribute="trailing" secondItem="lyR-7c-S2k" secondAttribute="trailing" constant="10" id="uzV-kG-oGN"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" constant="8" id="ycc-WI-Jk6"/>
                         </constraints>
                         <userDefinedRuntimeAttributes>
                             <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                <real key="value" value="4"/>
+                                <integer key="value" value="15"/>
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </view>
                 </subviews>
                 <constraints>
-                    <constraint firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" constant="8" id="1QQ-bu-6Bl"/>
+                    <constraint firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" constant="8" id="1QQ-bu-6Bl" userLabel="Bubble Bottom Constraint"/>
                     <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" priority="1" constant="64" id="99Y-bR-Ioq"/>
                     <constraint firstItem="kZJ-Ay-LTR" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" priority="1" constant="16" id="Eso-cy-OYs"/>
+                    <constraint firstItem="EMh-bG-ilg" firstAttribute="trailing" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" id="MY3-Aj-94K"/>
                     <constraint firstAttribute="trailing" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" constant="16" 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="hdz-AQ-xHI" firstAttribute="trailing" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" id="lSl-vu-Wkl"/>
                     <constraint firstItem="kZJ-Ay-LTR" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="64" id="nWe-5k-Qpn"/>
+                    <constraint firstItem="EMh-bG-ilg" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" id="zEh-jv-0Ha"/>
+                    <constraint firstItem="hdz-AQ-xHI" firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" id="zWA-Jg-F6Q"/>
                 </constraints>
             </tableViewCellContentView>
             <connections>
+                <outlet property="bottomCorner" destination="hdz-AQ-xHI" id="ChE-BT-0LS"/>
                 <outlet property="bubble" destination="kZJ-Ay-LTR" id="hdG-fG-L69"/>
+                <outlet property="bubbleBottomConstraint" destination="1QQ-bu-6Bl" id="woo-UQ-wXK"/>
+                <outlet property="bubbleTopConstraint" destination="jhd-A8-c1o" id="cll-eA-OC5"/>
                 <outlet property="messageLabel" destination="lyR-7c-S2k" id="hd3-pz-Pwh"/>
+                <outlet property="topCorner" destination="EMh-bG-ilg" id="nHl-hn-BZ1"/>
             </connections>
-            <point key="canvasLocation" x="-411" y="-132"/>
+            <point key="canvasLocation" x="-411" y="-132.5"/>
         </tableViewCell>
     </objects>
 </document>
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
index bf31333fc01b7c8e0736a8ff256da30caac5c43f..c938de3edb29778ccc04479a5e44dde4f8894cf3 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
@@ -21,9 +21,20 @@
 import UIKit
 import RxSwift
 import Reusable
+import SwiftyBeaver
+
+enum BubbleChaining {
+    case singleMessage
+    case firstOfSequence
+    case lastOfSequence
+    case middleOfSequence
+    case error
+}
 
 class ConversationViewController: UIViewController, UITextFieldDelegate, StoryboardBased, ViewModelBased {
 
+    let log = SwiftyBeaver.self
+
     @IBOutlet weak var tableView: UITableView!
     @IBOutlet weak var spinnerView: UIView!
 
@@ -33,6 +44,7 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
     var messageViewModels: [MessageViewModel]?
     var textFieldShouldEndEditing = false
     var bottomOffset: CGFloat = 0
+    let scrollOffsetThreshold: CGFloat = 600
 
     override func viewDidLoad() {
         super.viewDidLoad()
@@ -147,7 +159,7 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
 
     fileprivate func scrollToBottomIfNeed() {
         if self.isBottomContentOffset {
-            self.scrollToBottom(animated: true)
+            self.scrollToBottom(animated: false)
         }
     }
 
@@ -160,7 +172,9 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
     }
 
     fileprivate var isBottomContentOffset: Bool {
-        return self.tableView.contentOffset.y + self.tableView.contentInset.top >= bottomOffset
+        updateBottomOffset()
+        let offset = abs((self.tableView.contentOffset.y + self.tableView.contentInset.top) - bottomOffset)
+        return offset <= scrollOffsetThreshold
     }
 
     override var inputAccessoryView: UIView {
@@ -189,6 +203,86 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
         return textFieldShouldEndEditing
     }
 
+    func isFirstMessage(cellForRowAt indexPath: IndexPath) -> Bool {
+        return indexPath.row == 0
+    }
+
+    func isLastMessage(cellForRowAt indexPath: IndexPath) -> Bool {
+        return self.messageViewModels?.count == indexPath.row + 1
+    }
+
+    func getBubbleChaining(cellForRowAt indexPath: IndexPath) -> BubbleChaining {
+        if let msgViewModel = self.messageViewModels?[indexPath.row] {
+            let msgOwner = msgViewModel.bubblePosition()
+            if self.messageViewModels?.count == 1 || indexPath.row == 0 {
+                if self.messageViewModels?.count == indexPath.row + 1 {
+                    return BubbleChaining.singleMessage
+                }
+                let nextMsgViewModel = indexPath.row + 1 <= (self.messageViewModels?.count)!
+                    ? self.messageViewModels?[indexPath.row + 1] : nil
+                if nextMsgViewModel != nil {
+                    return msgOwner != nextMsgViewModel?.bubblePosition()
+                        ? BubbleChaining.singleMessage : BubbleChaining.firstOfSequence
+                }
+            } else if self.messageViewModels?.count == indexPath.row + 1 {
+                let lastMsgViewModel = indexPath.row - 1 >= 0 && indexPath.row - 1 < (self.messageViewModels?.count)!
+                    ? self.messageViewModels?[indexPath.row - 1] : nil
+                if lastMsgViewModel != nil {
+                    return msgOwner != lastMsgViewModel?.bubblePosition()
+                        ? BubbleChaining.singleMessage : BubbleChaining.lastOfSequence
+                }
+            }
+            let lastMsgViewModel = indexPath.row - 1 >= 0 && indexPath.row - 1 < (self.messageViewModels?.count)!
+                ? self.messageViewModels?[indexPath.row - 1] : nil
+            let nextMsgViewModel = indexPath.row + 1 <= (self.messageViewModels?.count)!
+                ? self.messageViewModels?[indexPath.row + 1] : nil
+            var chaining = BubbleChaining.singleMessage
+            if (lastMsgViewModel != nil) && (nextMsgViewModel != nil) {
+                if msgOwner != lastMsgViewModel?.bubblePosition() && msgOwner == nextMsgViewModel?.bubblePosition() {
+                    chaining = BubbleChaining.firstOfSequence
+                } else if msgOwner != nextMsgViewModel?.bubblePosition() && msgOwner == lastMsgViewModel?.bubblePosition() {
+                    chaining = BubbleChaining.lastOfSequence
+                } else if msgOwner == nextMsgViewModel?.bubblePosition() && msgOwner == lastMsgViewModel?.bubblePosition() {
+                    chaining = BubbleChaining.middleOfSequence
+                }
+            }
+            return chaining
+        }
+        return BubbleChaining.error
+    }
+
+    func applyBubbleStyleToCell(toCell cell: MessageCell,
+                                withChaining chaining: BubbleChaining,
+                                withContent content: String,
+                                withType type: BubblePosition) {
+
+        let bubbleColor = type == .received ? UIColor.ringMsgCellReceived : UIColor.ringMsgCellSent
+
+        cell.messageLabel.setTextWithLineSpacing(withText: content, withLineSpacing: 2)
+
+        cell.topCorner.isHidden = true
+        cell.topCorner.backgroundColor = bubbleColor
+        cell.bottomCorner.isHidden = true
+        cell.bottomCorner.backgroundColor = bubbleColor
+        cell.bubbleBottomConstraint.constant = 8
+        cell.bubbleTopConstraint.constant = 8
+
+        switch chaining {
+        case .middleOfSequence:
+            cell.topCorner.isHidden = false
+            cell.bottomCorner.isHidden = false
+            cell.bubbleBottomConstraint.constant = 1
+            cell.bubbleTopConstraint.constant = 1
+        case .firstOfSequence:
+            cell.bottomCorner.isHidden = false
+            cell.bubbleBottomConstraint.constant = 1
+        case .lastOfSequence:
+            cell.topCorner.isHidden = false
+            cell.bubbleTopConstraint.constant = 1
+        default: break
+        }
+    }
+
 }
 
 extension ConversationViewController: UITableViewDataSource {
@@ -199,21 +293,38 @@ extension ConversationViewController: UITableViewDataSource {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
 
         if let messageViewModel = self.messageViewModels?[indexPath.row] {
+            let chaining = self.getBubbleChaining(cellForRowAt: indexPath)
             if messageViewModel.bubblePosition() == .received {
+                // left side (incoming)
                 let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellReceived.self)
-                cell.messageLabel.text = messageViewModel.content
+
+                // Format cell
+                applyBubbleStyleToCell(toCell: cell, withChaining: chaining, withContent: messageViewModel.content, withType: .received)
+
+                // Special cases where top/bottom margins should be larger
+                if isFirstMessage(cellForRowAt: indexPath) {
+                    cell.bubbleTopConstraint.constant = 16
+                } else if isLastMessage(cellForRowAt: indexPath) {
+                    cell.bubbleBottomConstraint.constant = 16
+                }
+
                 return cell
-            }
+            } else {
+                // right side (outgoing)
+                let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
+
+                // Format cell
+                applyBubbleStyleToCell(toCell: cell, withChaining: chaining, withContent: messageViewModel.content, withType: .sent)
+
+                // Special cases where top/bottom margins should be larger
+                if isFirstMessage(cellForRowAt: indexPath) {
+                    cell.bubbleTopConstraint.constant = 16
+                } else if isLastMessage(cellForRowAt: indexPath) {
+                    cell.bubbleBottomConstraint.constant = 16
+                }
 
-            if messageViewModel.bubblePosition() == .generated {
-                let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellGenerated.self)
-                cell.messageLabel.text = messageViewModel.content
                 return cell
             }
-
-            let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
-            cell.messageLabel.text = messageViewModel.content
-            return cell
         }
 
         return tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)