Merge "Add another getMessages() api to Folder" into jb-ub-mail-ur10
diff --git a/Android.mk b/Android.mk
index 1cf0bb6..84f7b45 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,7 +19,8 @@
 
 #Include res dir from photoviewer
 photo_dir := ../../../frameworks/opt/photoviewer/res
-res_dirs := $(chips_dir) $(photo_dir) res
+res_dirs := res $(chips_dir) $(photo_dir)
+
 
 ##################################################
 # Build APK
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a615fac..febfebc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -42,7 +42,7 @@
             android:label="@string/app_name"
             android:name=".ui.MailActivity"
             android:launchMode="singleTop"
-            android:uiOptions="splitActionBarWhenNarrow">
+            android:theme="@style/PlainUnifiedEmailTheme" >
             <intent-filter >
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -123,6 +123,14 @@
         </activity>
 
         <provider
+                android:authorities="com.android.mail.accountcache"
+                android:label="@string/account_cache_provider"
+                android:multiprocess="false"
+                android:name=".providers.UnifiedAccountCacheProvider" >
+            <grant-uri-permission android:pathPattern=".*" />
+        </provider>
+
+        <provider
             android:authorities="com.android.mail.mockprovider"
             android:label="@string/mock_content_provider"
             android:multiprocess="false"
@@ -139,14 +147,6 @@
         </provider>
 
         <provider
-            android:authorities="com.android.mail.accountcache"
-            android:label="@string/account_cache_provider"
-            android:multiprocess="false"
-            android:name=".providers.UnifiedAccountCacheProvider" >
-            <grant-uri-permission android:pathPattern=".*" />
-        </provider>
-
-        <provider
                 android:authorities="@string/eml_attachment_provider"
                 android:multiprocess="false"
                 android:exported="false"
diff --git a/proguard.flags b/proguard.flags
index 5d90442..0699881 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -61,6 +61,10 @@
 -keepclasseswithmembers class com.android.mail.browse.ConversationItemView {
   *** setAnimatedHeightFraction(...);
   *** setAnimatedProgressFraction(...);
+  *** setAnimatedFadeFraction0(...);
+  *** setAnimatedFadeFraction1(...);
+  *** setPhotoFlipFraction(...);
+  *** setPeekIconFlipFraction(...);
 }
 
 -keepclasseswithmembers class com.android.mail.ui.MailActivity {
diff --git a/res/drawable-hdpi/ic_avatar_check.png b/res/drawable-hdpi/ic_avatar_check.png
new file mode 100644
index 0000000..e904f7d
--- /dev/null
+++ b/res/drawable-hdpi/ic_avatar_check.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_btn_star_off.png b/res/drawable-hdpi/ic_btn_star_off.png
new file mode 100644
index 0000000..85481fe
--- /dev/null
+++ b/res/drawable-hdpi/ic_btn_star_off.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_btn_star_on.png b/res/drawable-hdpi/ic_btn_star_on.png
new file mode 100644
index 0000000..4654ef5
--- /dev/null
+++ b/res/drawable-hdpi/ic_btn_star_on.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_peak_eye.png b/res/drawable-hdpi/ic_peak_eye.png
new file mode 100644
index 0000000..ee2238d
--- /dev/null
+++ b/res/drawable-hdpi/ic_peak_eye.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_off.png b/res/drawable-hdpi/ic_star_off.png
deleted file mode 100644
index cf1cd90..0000000
--- a/res/drawable-hdpi/ic_star_off.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png b/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png
index 8289a76..c119657 100644
--- a/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png
+++ b/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_on.png b/res/drawable-hdpi/ic_star_on.png
deleted file mode 100644
index b694bbb..0000000
--- a/res/drawable-hdpi/ic_star_on.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png b/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png
index 544b076..d180107 100644
--- a/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png
+++ b/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_avatar_check.png b/res/drawable-mdpi/ic_avatar_check.png
new file mode 100644
index 0000000..1224199
--- /dev/null
+++ b/res/drawable-mdpi/ic_avatar_check.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_btn_star_off.png b/res/drawable-mdpi/ic_btn_star_off.png
new file mode 100644
index 0000000..0add19a
--- /dev/null
+++ b/res/drawable-mdpi/ic_btn_star_off.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_btn_star_on.png b/res/drawable-mdpi/ic_btn_star_on.png
new file mode 100644
index 0000000..54a4230
--- /dev/null
+++ b/res/drawable-mdpi/ic_btn_star_on.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_peak_eye.png b/res/drawable-mdpi/ic_peak_eye.png
new file mode 100644
index 0000000..40e15fa
--- /dev/null
+++ b/res/drawable-mdpi/ic_peak_eye.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_off.png b/res/drawable-mdpi/ic_star_off.png
deleted file mode 100644
index 522b5ab..0000000
--- a/res/drawable-mdpi/ic_star_off.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png b/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png
index d01da9f..1b63df6 100644
--- a/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png
+++ b/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_on.png b/res/drawable-mdpi/ic_star_on.png
deleted file mode 100644
index 50dd679..0000000
--- a/res/drawable-mdpi/ic_star_on.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png b/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png
index 683258e..32d878e 100644
--- a/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png
+++ b/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_avatar_check.png b/res/drawable-xhdpi/ic_avatar_check.png
new file mode 100644
index 0000000..6bc3d92
--- /dev/null
+++ b/res/drawable-xhdpi/ic_avatar_check.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_btn_star_off.png b/res/drawable-xhdpi/ic_btn_star_off.png
new file mode 100644
index 0000000..eb5cbe2
--- /dev/null
+++ b/res/drawable-xhdpi/ic_btn_star_off.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_btn_star_on.png b/res/drawable-xhdpi/ic_btn_star_on.png
new file mode 100644
index 0000000..9751701
--- /dev/null
+++ b/res/drawable-xhdpi/ic_btn_star_on.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_peak_eye.png b/res/drawable-xhdpi/ic_peak_eye.png
new file mode 100644
index 0000000..3054b58
--- /dev/null
+++ b/res/drawable-xhdpi/ic_peak_eye.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_off.png b/res/drawable-xhdpi/ic_star_off.png
deleted file mode 100644
index a611a1f..0000000
--- a/res/drawable-xhdpi/ic_star_off.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png b/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png
index 23fe0ba..a401383 100644
--- a/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png
+++ b/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_on.png b/res/drawable-xhdpi/ic_star_on.png
deleted file mode 100644
index f77acd7..0000000
--- a/res/drawable-xhdpi/ic_star_on.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png b/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png
index e54a509..a3a39d2 100644
--- a/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png
+++ b/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png
Binary files differ
diff --git a/res/layout/ad_header_view.xml b/res/layout/ad_header_view.xml
new file mode 100644
index 0000000..1ed6c27
--- /dev/null
+++ b/res/layout/ad_header_view.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 Google Inc.
+     Licensed to The Android Open Source Project.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.mail.ads.AdHeaderView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/ad_header"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@color/ad_background_yellow"
+    android:orientation="vertical"
+    android:paddingTop="@dimen/conversation_header_vertical_padding"
+    android:paddingBottom="@dimen/conversation_header_vertical_padding"
+    android:layout_marginStart="@dimen/conversation_view_margin_side"
+    android:layout_marginEnd="@dimen/conversation_view_margin_side"
+    android:layout_marginLeft="@dimen/conversation_view_margin_side"
+    android:layout_marginRight="@dimen/conversation_view_margin_side" >
+
+    <TextView
+        android:id="@+id/ad_info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end|right"
+        android:background="?android:attr/selectableItemBackground"
+        android:gravity="center_vertical"
+        android:paddingStart="@dimen/conversation_header_side_padding"
+        android:paddingEnd="@dimen/conversation_header_side_padding"
+        android:paddingLeft="@dimen/conversation_header_side_padding"
+        android:paddingRight="@dimen/conversation_header_side_padding"
+        android:text="@string/ads"
+        android:textAllCaps="true"
+        android:textColor="@color/conv_header_text_dark"
+        android:drawableEnd="@drawable/ic_alert_grey"
+        android:drawableRight="@drawable/ic_alert_grey"
+        />
+
+    <TextView
+        android:id="@+id/ad_subject"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingBottom="@dimen/conversation_header_vertical_item_padding"
+        android:paddingStart="@dimen/conversation_header_side_padding"
+        android:paddingEnd="@dimen/conversation_header_side_padding"
+        android:paddingLeft="@dimen/conversation_header_side_padding"
+        android:paddingRight="@dimen/conversation_header_side_padding"
+        android:includeFontPadding="false"
+        style="@style/ConversationSubjectStyle" />
+
+</com.android.mail.ads.AdHeaderView>
diff --git a/res/layout/conversation_item_view_normal.xml b/res/layout/conversation_item_view_normal.xml
index 149dca0..b75de04 100644
--- a/res/layout/conversation_item_view_normal.xml
+++ b/res/layout/conversation_item_view_normal.xml
@@ -35,14 +35,6 @@
         android:layout_marginRight="16dp"
         android:orientation="horizontal">
 
-        <ImageView
-            android:id="@+id/checkmark"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginRight="12dp"
-            android:layout_gravity="center_vertical"
-            android:src="@drawable/btn_check_on_normal_holo_light" />
-
         <View
             android:id="@+id/contact_image"
             android:layout_width="48dp"
@@ -144,12 +136,14 @@
                     android:id="@+id/star"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_alignBottom="@+id/subject"
                     android:layout_alignParentRight="true"
+                    android:layout_marginBottom="6dp"
                     android:layout_marginTop="-1dp"
-                    android:src="@drawable/ic_star_off" />
+                    android:src="@drawable/ic_btn_star_off" />
 
                 <TextView
-                    android:id="@+id/subject"
+                    android:id="@id/subject"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_toLeftOf="@id/star"
@@ -177,12 +171,12 @@
         android:layout_marginBottom="12dp"
         android:visibility="gone" />
 
-    <!-- Folders should be 0dp below the subject, so we cancel out the 12dp bottom margin above -->
+    <!-- Folders should be 10dp below the subject, so we cancel out part of the 12dp bottom margin above -->
     <TextView
         android:id="@+id/folders"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="-12dp"
+        android:layout_marginTop="-2dp"
         android:fontFamily="sans-serif-light"
         android:includeFontPadding="false"
         android:text="@string/long_string"
diff --git a/res/layout/conversation_item_view_normal_spacious.xml b/res/layout/conversation_item_view_normal_spacious.xml
index 25218e6..10e34e0 100644
--- a/res/layout/conversation_item_view_normal_spacious.xml
+++ b/res/layout/conversation_item_view_normal_spacious.xml
@@ -35,14 +35,6 @@
         android:layout_marginRight="16dp"
         android:orientation="horizontal">
 
-        <ImageView
-            android:id="@+id/checkmark"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginRight="16dp"
-            android:layout_gravity="center_vertical"
-            android:src="@drawable/btn_check_on_normal_holo_light" />
-
         <View
             android:id="@+id/contact_image"
             android:layout_width="48dp"
@@ -144,9 +136,11 @@
                     android:id="@+id/star"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_alignBottom="@+id/subject"
                     android:layout_alignParentRight="true"
+                    android:layout_marginBottom="6dp"
                     android:layout_marginTop="-1dp"
-                    android:src="@drawable/ic_star_off" />
+                    android:src="@drawable/ic_btn_star_off" />
 
                 <TextView
                     android:id="@+id/subject"
@@ -180,12 +174,12 @@
         android:layout_marginBottom="16dp"
         android:visibility="gone" />
 
-    <!-- Labels should be 0dp below the subject, so we cancel out the 16dp bottom margin -->
+    <!-- Labels should be 10dp below the subject, so we cancel out part of the 16dp bottom margin -->
     <TextView
         android:id="@+id/folders"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="-16dp"
+        android:layout_marginTop="-6dp"
         android:fontFamily="sans-serif-light"
         android:includeFontPadding="false"
         android:text="@string/long_string"
diff --git a/res/layout/conversation_item_view_wide.xml b/res/layout/conversation_item_view_wide.xml
index 6061e21..04a0d48 100644
--- a/res/layout/conversation_item_view_wide.xml
+++ b/res/layout/conversation_item_view_wide.xml
@@ -44,13 +44,6 @@
             android:minHeight="66dp"
             android:gravity="center_vertical">
 
-            <ImageView
-                android:id="@+id/checkmark"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginRight="20dp"
-                android:src="@drawable/btn_check_on_normal_holo_light" />
-
             <View
                 android:id="@+id/contact_image"
                 android:layout_width="46dp"
@@ -135,14 +128,14 @@
                     android:includeFontPadding="false"
                     android:text="@string/date" />
 
-                <!-- align to date -->
+                <!-- align to bottom of subject text -->
                 <ImageView
                     android:id="@+id/star"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="-1dp"
+                    android:layout_marginTop="2dp"
                     android:layout_marginLeft="32dp"
-                    android:src="@drawable/ic_star_off" />
+                    android:src="@drawable/ic_btn_star_off" />
 
             </LinearLayout>
 
diff --git a/res/layout/conversation_message_details_header.xml b/res/layout/conversation_message_details_header.xml
index 505f24f..172bbd2 100644
--- a/res/layout/conversation_message_details_header.xml
+++ b/res/layout/conversation_message_details_header.xml
@@ -26,9 +26,10 @@
     android:paddingRight="@dimen/message_details_header_padding_end" >
     <TextView
         android:id="@+id/recipients_summary"
+        android:layout_width="0dp"
         android:layout_gravity="fill_horizontal"
-        android:layout_marginEnd="16dip"
-        android:layout_marginRight="16dip"
+        android:layout_marginEnd="16dp"
+        android:layout_marginRight="16dp"
         android:singleLine="true"
         android:bufferType="spannable"
         style="@style/MessageHeaderSmallStyle" />
diff --git a/res/layout/conversation_message_details_header_expanded.xml b/res/layout/conversation_message_details_header_expanded.xml
index 8381edf..a5aa753 100644
--- a/res/layout/conversation_message_details_header_expanded.xml
+++ b/res/layout/conversation_message_details_header_expanded.xml
@@ -47,7 +47,6 @@
         android:layout_marginBottom="4dp"
         android:layout_column="1"
         android:layout_row="0"
-        android:autoLink="email"
         android:visibility="gone"
         style="@style/MessageDetailsValueStyle" />
     <ImageView
@@ -80,7 +79,6 @@
         android:layout_marginBottom="4dp"
         android:layout_column="1"
         android:layout_row="1"
-        android:autoLink="email"
         android:visibility="gone"
         style="@style/MessageDetailsValueStyle" />
     <TextView
@@ -103,7 +101,6 @@
         android:layout_marginBottom="4dp"
         android:layout_column="1"
         android:layout_row="2"
-        android:autoLink="email"
         android:visibility="gone"
         style="@style/MessageDetailsValueStyle" />
     <TextView
@@ -126,7 +123,6 @@
         android:layout_marginBottom="4dp"
         android:layout_column="1"
         android:layout_row="3"
-        android:autoLink="email"
         android:visibility="gone"
         style="@style/MessageDetailsValueStyle" />
     <TextView
@@ -149,7 +145,6 @@
         android:layout_marginBottom="4dp"
         android:layout_column="1"
         android:layout_row="4"
-        android:autoLink="email"
         android:visibility="gone"
         style="@style/MessageDetailsValueStyle" />
 
diff --git a/res/layout/conversation_photo_teaser_view.xml b/res/layout/conversation_photo_teaser_view.xml
index dd6b9f6..46318f9 100644
--- a/res/layout/conversation_photo_teaser_view.xml
+++ b/res/layout/conversation_photo_teaser_view.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (c) 2013 Google Inc. -->
-<com.google.android.gm.ui.GmailConversationPhotoTeaserView
+<com.android.mail.ui.ConversationPhotoTeaserView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -59,4 +59,4 @@
             android:src="@drawable/ic_cancel_holo_light" />
     </LinearLayout>
 
-</com.google.android.gm.ui.GmailConversationPhotoTeaserView>
\ No newline at end of file
+</com.android.mail.ui.ConversationPhotoTeaserView>
\ No newline at end of file
diff --git a/res/menu-sw600dp/compose_menu.xml b/res/menu-sw600dp/compose_menu.xml
index aef2382..5377bce 100644
--- a/res/menu-sw600dp/compose_menu.xml
+++ b/res/menu-sw600dp/compose_menu.xml
@@ -27,6 +27,11 @@
         android:title="@string/save_draft"
         android:alphabeticShortcut="@string/trigger_save_char" />
 
+    <item android:id="@+id/add_photo_attachment"
+        android:icon="@drawable/ic_attachment_holo_light"
+        android:title="@string/add_photo_attachment"
+        android:showAsAction="never" />
+
     <item android:id="@+id/add_video_attachment"
         android:icon="@drawable/ic_attachment_holo_light"
         android:title="@string/add_video_attachment"
diff --git a/res/menu-sw600dp/general_prefs_fragment_menu.xml b/res/menu-sw600dp/general_prefs_fragment_menu.xml
index 37b73f2..bd4627f 100644
--- a/res/menu-sw600dp/general_prefs_fragment_menu.xml
+++ b/res/menu-sw600dp/general_prefs_fragment_menu.xml
@@ -19,11 +19,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
 
     <item
-            android:id="@+id/add_new_account"
-            android:title="@string/add_account"
-            android:showAsAction="ifRoom|withText" />
-
-    <item
             android:id="@+id/clear_picture_approvals_menu_item"
             android:showAsAction="never"
             android:title="@string/clear_display_images_whitelist_title"/>
diff --git a/res/menu-sw600dp/settings_fragment_menu.xml b/res/menu-sw600dp/settings_fragment_menu.xml
index afff6a9..a39e681 100644
--- a/res/menu-sw600dp/settings_fragment_menu.xml
+++ b/res/menu-sw600dp/settings_fragment_menu.xml
@@ -19,11 +19,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item
-            android:id="@+id/add_new_account"
-            android:title="@string/add_account"
-            android:showAsAction="ifRoom|withText" />
-
-    <item
             android:id="@+id/feedback_menu_item"
             android:icon="@android:drawable/ic_menu_send"
             android:title="@string/feedback" />
diff --git a/res/menu/settings_menu.xml b/res/menu/settings_menu.xml
index 4129ba2..a39e681 100644
--- a/res/menu/settings_menu.xml
+++ b/res/menu/settings_menu.xml
@@ -19,11 +19,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item
-            android:id="@+id/add_new_account"
-            android:title="@string/add_account"
-            android:showAsAction="always" />
-
-    <item
             android:id="@+id/feedback_menu_item"
             android:icon="@android:drawable/ic_menu_send"
             android:title="@string/feedback" />
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 37213d0..bfeb6ca 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"gesprek ongelees"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Konsep"</item>
     <item quantity="other" msgid="6961049507579977505">"Konsepte"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Vou ontvanger se details in"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Wys kontakinligting vir <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Wys kontakinligting"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> ouer boodskappe"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Van:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Antwoord aan:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Aan:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Vouer-ikoon"</string>
     <string name="add_account" msgid="2162808366829269770">"Voeg rekening by"</string>
     <string name="attached_message" msgid="4267189489654642035">"Heg boodskap aan"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Vandag <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Gister <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Advertensies"</string>
 </resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index dc03846..4e1de69 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"ያልተነበበ ውይይት"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"ረቂቅ"</item>
     <item quantity="other" msgid="6961049507579977505">"ረቂቆች"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"የተቀባይ ዝርዝሮች ሰብስብ"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"የ<xliff:g id="NAME">%1$s</xliff:g> የእውቂያ መረጃ አሳይ"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"የዕውቂያ መረጃ አሳይ"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"ቀን፦"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> የቆዩ መልዕክቶች"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"ከ፦"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"መልስ ለ፦"</string>
     <string name="to_heading" msgid="3219994961726691756">"ለ፦"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"የአቃፊ አዶ"</string>
     <string name="add_account" msgid="2162808366829269770">"መለያ ያክሉ"</string>
     <string name="attached_message" msgid="4267189489654642035">"የተያያዘ መልዕክት"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>፣ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"ዛሬ፣ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"ትላንት፣ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"ማስታወቂያዎች"</string>
 </resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index d630d9b..4058f61 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"لم تتم قراءة المحادثة"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"مسودة"</item>
     <item quantity="other" msgid="6961049507579977505">"مسودات"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"تصغير تفاصيل المستلم"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"عرض معلومات جهة الاتصال لـ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"عرض معلومات جهة الاتصال"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"التاريخ:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"الرسائل القديمة: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"من:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"جهة الرد:"</string>
     <string name="to_heading" msgid="3219994961726691756">"إلى:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"رمز المجلد"</string>
     <string name="add_account" msgid="2162808366829269770">"إضافة حساب"</string>
     <string name="attached_message" msgid="4267189489654642035">"الرسالة المرفقة"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>، <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"اليوم، <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"أمس، <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"الإعلانات"</string>
 </resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index f6a4682..4aca629 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -255,8 +255,7 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Згарнуць дадзеныя пра атрымальніка"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Паказаць кантактную інфармацыю карыстальнiка <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Паказаць кантактную інфармацыю"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Дата:"</string>
+    <!-- no translation found for show_messages_read:other (7439716291751085801) -->
     <string name="from_heading" msgid="8950294114718418954">"Ад:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Адказаць:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Каму:"</string>
@@ -429,4 +428,12 @@
     <!-- no translation found for add_account (2162808366829269770) -->
     <skip />
     <string name="attached_message" msgid="4267189489654642035">"Прымацаванае паведамленне"</string>
+    <!-- no translation found for date_message_received (6302308934790266050) -->
+    <skip />
+    <!-- no translation found for date_message_received_today (7923108495669251362) -->
+    <skip />
+    <!-- no translation found for date_message_received_yesterday (2240669381396206434) -->
+    <skip />
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 84e8f54..0f1ae32 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"кореспонденцията не е прочетена"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+ <xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Чернова"</item>
     <item quantity="other" msgid="6961049507579977505">"Чернови"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Свиване на подробностите за получателя"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Показване на информацията за връзка със: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Показване на информацията за връзка"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Дата:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> по-стари съобщения"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"От:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Отг. до:"</string>
     <string name="to_heading" msgid="3219994961726691756">"До:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Икона на папката"</string>
     <string name="add_account" msgid="2162808366829269770">"Добавяне на профил"</string>
     <string name="attached_message" msgid="4267189489654642035">"Прикачено съобщение"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Днес, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Вчера, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Реклами"</string>
 </resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index dfd88d6..dbc7cc8 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversa per llegir"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Esborrany"</item>
     <item quantity="other" msgid="6961049507579977505">"Esborranys"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Redueix les dades del destinatari"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Mostra la informació de contacte de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Mostra la informació de contacte"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Data:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> missatges anteriors"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Respon a:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Per a:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Icona de la carpeta"</string>
     <string name="add_account" msgid="2162808366829269770">"Afegeix un compte"</string>
     <string name="attached_message" msgid="4267189489654642035">"Missatge adjunt"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Avui a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ahir a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Anuncis"</string>
 </resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 07a02d9..7f17295 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"Konverzace nebyla přečtena."</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Koncept"</item>
     <item quantity="other" msgid="6961049507579977505">"Koncepty"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Sbalit podrobnosti o příjemci"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Zobrazit kontaktní údaje uživatele <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Zobrazit kontaktní údaje"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Starší zprávy: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Odesílatel:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Odpovědět:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Komu:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikona složky"</string>
     <string name="add_account" msgid="2162808366829269770">"Přidat účet"</string>
     <string name="attached_message" msgid="4267189489654642035">"Přiložená zpráva"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Dnes v <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Včera v <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Reklamy"</string>
 </resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index da5cac0..d92a607 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"samtalen er ulæst"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Kladde"</item>
     <item quantity="other" msgid="6961049507579977505">"Kladder"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Skjul modtageroplysninger"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Vis kontaktoplysninger for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Vis kontaktoplysninger"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Dato:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> ældre beskeder"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Fra:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Svar til:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Til:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Mappeikon"</string>
     <string name="add_account" msgid="2162808366829269770">"Tilføj konto"</string>
     <string name="attached_message" msgid="4267189489654642035">"Vedhæftet meddelelse"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"I dag kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"I går kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Annoncer"</string>
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 7548d3d..73b8edb 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"Konversation ungelesen"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+ <xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Entwurf"</item>
     <item quantity="other" msgid="6961049507579977505">"Entwürfe"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Empfängerdetails minimieren"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Kontaktinformationen für <xliff:g id="NAME">%1$s</xliff:g> anzeigen"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Kontaktinformationen anzeigen"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> ältere Nachrichten"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Von:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Antwort:"</string>
     <string name="to_heading" msgid="3219994961726691756">"An:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ordnersymbol"</string>
     <string name="add_account" msgid="2162808366829269770">"Konto hinzufügen"</string>
     <string name="attached_message" msgid="4267189489654642035">"Angehängte Nachricht"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> um <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Heute um <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Gestern um <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Anzeigen"</string>
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 923fd78..6d68c4a 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"μη αναγνωσμένη συνομιλία"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Πρόχειρο"</item>
     <item quantity="other" msgid="6961049507579977505">"Πρόχειρα"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Σύμπτυξη στοιχείων παραλήπτη"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Εμφάνιση στοιχείων επικοινωνίας για τον χρήστη <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Εμφάνιση στοιχείων επικοινωνίας"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Ημ/νία:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> παλαιότερα μηνύματα"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Από:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Απάντ. σε:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Προς:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Εικονίδιο φακέλου"</string>
     <string name="add_account" msgid="2162808366829269770">"Προσθήκη λογαριασμού"</string>
     <string name="attached_message" msgid="4267189489654642035">"Συνημμένο μήνυμα"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Σήμερα, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Χθες, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Διαφημίσεις"</string>
 </resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 31cac60..bc6ff1d 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversation unread"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Draft"</item>
     <item quantity="other" msgid="6961049507579977505">"Drafts"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Collapse recipient details"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Show contact information for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Show contact information"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Date:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> older messages"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"From:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Reply to:"</string>
     <string name="to_heading" msgid="3219994961726691756">"To:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Folder icon"</string>
     <string name="add_account" msgid="2162808366829269770">"Add account"</string>
     <string name="attached_message" msgid="4267189489654642035">"Attached message"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Today, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Yesterday, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Ads"</string>
 </resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 7804b7d..bc2a623 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversación no leída"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Borrador"</item>
     <item quantity="other" msgid="6961049507579977505">"Borradores"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Contraer detalles del destinatario"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Mostrar la información de contacto de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Mostrar la información de contacto"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Fecha:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> mensajes antiguos"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Responder a:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Para:"</string>
@@ -425,4 +425,9 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ícono de carpeta"</string>
     <string name="add_account" msgid="2162808366829269770">"Agregar cuenta"</string>
     <string name="attached_message" msgid="4267189489654642035">"Mensaje adjunto"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hoy, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ayer, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 46b0af5..62726ad 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversación no leída"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> - <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Borrador"</item>
     <item quantity="other" msgid="6961049507579977505">"Borradores"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Contraer información del destinatario"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Mostrar información de contacto de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Mostrar información de contacto"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Fecha:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> mensajes antiguos"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Responder a:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Para:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Icono de carpeta"</string>
     <string name="add_account" msgid="2162808366829269770">"Añadir cuenta"</string>
     <string name="attached_message" msgid="4267189489654642035">"Mensaje adjunto"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hoy a las <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ayer a las <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Anuncios"</string>
 </resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 63be8f0..001ee1c 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"lugemata vestlus"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>] <xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g>  –  <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Mustand"</item>
     <item quantity="other" msgid="6961049507579977505">"Mustandid"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Ahenda saaja üksikasjad"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Kuva saatja <xliff:g id="NAME">%1$s</xliff:g> kontaktandmed"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Kuva kontaktandmed"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Kuupäev:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> vanemat sõnumit"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Saatja:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Vasta:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Saaja:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Kausta ikoon"</string>
     <string name="add_account" msgid="2162808366829269770">"Lisa konto"</string>
     <string name="attached_message" msgid="4267189489654642035">"Lisatud sõnum"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Täna kell <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Eile kell <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Reklaamid"</string>
 </resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 8b5c7dc..5d4e506 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"مکالمه خوانده نشده است"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"پیش‌نویس‌"</item>
     <item quantity="other" msgid="6961049507579977505">"پیش‌نویس‌ها"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"کوچک کردن جزئیات گیرنده"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"نمایش اطلاعات تماس برای <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"نمایش اطلاعات مخاطب"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"تاریخ:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> پیام قدیمی‌تر"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"از:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"پاسخ به:"</string>
     <string name="to_heading" msgid="3219994961726691756">"گیرنده:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"نماد پوشه"</string>
     <string name="add_account" msgid="2162808366829269770">"افزودن حساب"</string>
     <string name="attached_message" msgid="4267189489654642035">"پیام پیوست شده"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>،‏ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"امروز، <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"دیروز، <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"آگهی‌ها"</string>
 </resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 5213d17..cec6c5f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"keskustelua ei ole luettu"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g>–<xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Luonnos"</item>
     <item quantity="other" msgid="6961049507579977505">"Luonnokset"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Tiivistä vastaanottajan tiedot"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Näytä henkilön <xliff:g id="NAME">%1$s</xliff:g> yhteystiedot"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Näytä yhteystiedot"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Pvm.:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> vanhempaa viestiä"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Lähettäjä:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Vastausos.:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Vast.ott:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Kansiokuvake"</string>
     <string name="add_account" msgid="2162808366829269770">"Lisää tili"</string>
     <string name="attached_message" msgid="4267189489654642035">"Liitetty viesti"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Tänään klo <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Eilen klo <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Mainokset"</string>
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 893926d..e6df3be 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversation non lue"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Brouillon"</item>
     <item quantity="other" msgid="6961049507579977505">"Brouillons"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Réduire les coordonnées du destinataire"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Afficher les coordonnées de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Afficher les coordonnées de l\'expéditeur"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Date :"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> messages plus anciens"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De :"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Adresse de réponse :"</string>
     <string name="to_heading" msgid="3219994961726691756">"À :"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Icône Dossier"</string>
     <string name="add_account" msgid="2162808366829269770">"Ajouter un compte"</string>
     <string name="attached_message" msgid="4267189489654642035">"Message joint"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> à <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Aujourd\'hui à <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Hier à <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Annonces"</string>
 </resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 32564c2..0ce09e0 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"वार्तालाप नहीं पढ़ा गया"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"ड्रॉफ़्ट"</item>
     <item quantity="other" msgid="6961049507579977505">"ड्राफ़्ट"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"प्राप्तकर्ता जानकारी संक्षिप्त करें"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"<xliff:g id="NAME">%1$s</xliff:g> की संपर्क जानकारी दिखाएं"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"संपर्क जानकारी दिखाएं"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"दिनांक:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> पुराने संदेश"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"प्रेषक:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"उत्तर पता:"</string>
     <string name="to_heading" msgid="3219994961726691756">"प्रति:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"फ़ोल्डर आइकन"</string>
     <string name="add_account" msgid="2162808366829269770">"खाता जोड़ें"</string>
     <string name="attached_message" msgid="4267189489654642035">"अनुलग्न किया गया संदेश"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"आज, <xliff:g id="TIME">%1$s</xliff:g> बजे"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"कल, <xliff:g id="TIME">%1$s</xliff:g> बजे"</string>
+    <string name="ads" msgid="8547072743610267481">"विज्ञापन"</string>
 </resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 1e8e118..60ec871 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"razgovor nije pročitan"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Skica"</item>
     <item quantity="other" msgid="6961049507579977505">"Skice"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Sažmi podatke o primatelju"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Prikaži podatke o kontaktu za <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Prikaži podatke o kontaktu"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Broj starijih poruka: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Šalje:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Prima:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Primatelj:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikona mape"</string>
     <string name="add_account" msgid="2162808366829269770">"Dodaj račun"</string>
     <string name="attached_message" msgid="4267189489654642035">"Poruka u privitku"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> u <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Danas u <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Jučer u <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Oglasi"</string>
 </resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 04c4b59..667fd90 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"a beszélgetés nincs elolvasva"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> -- <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Piszkozat"</item>
     <item quantity="other" msgid="6961049507579977505">"Piszkozatok"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Címzett adatainak elrejtése"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"<xliff:g id="NAME">%1$s</xliff:g> elérhetőségi adatainak megjelenítése"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Névjegyinformációk megjelenítése"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Dátum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> régebbi üzenet"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Feladó:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Válaszcím:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Címzett:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Mappa ikon"</string>
     <string name="add_account" msgid="2162808366829269770">"Fiók hozzáadása"</string>
     <string name="attached_message" msgid="4267189489654642035">"Csatolt üzenetek"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Ma, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Tegnap, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Hirdetések"</string>
 </resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 0fb132c..627c50e 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"percakapan belum dibaca"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Draf"</item>
     <item quantity="other" msgid="6961049507579977505">"Draf"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Ciutkan detail penerima"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Tampilkan informasi kontak untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Tampilkan informasi kontak"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Tanggal:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> pesan lebih lama"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Dari:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Balas-ke:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Kepada:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikon folder"</string>
     <string name="add_account" msgid="2162808366829269770">"Tambahkan akun"</string>
     <string name="attached_message" msgid="4267189489654642035">"Pesan terlampir"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hari ini, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Kemarin, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Iklan"</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 926a759..0faba73 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversazione da leggere"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> - <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Bozza"</item>
     <item quantity="other" msgid="6961049507579977505">"Bozze"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Comprimi i dettagli destinatario"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Mostra informazioni di contatto di <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Mostra informazioni di contatto"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Data:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> messaggi meno recenti"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Da:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Rispondi a:"</string>
     <string name="to_heading" msgid="3219994961726691756">"A:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Icona cartella"</string>
     <string name="add_account" msgid="2162808366829269770">"Aggiungi account"</string>
     <string name="attached_message" msgid="4267189489654642035">"Messaggio allegato"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Oggi alle <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ieri alle <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Annunci"</string>
 </resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 9df0fe1..f4108f6 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"השיחה לא נקראה"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"‎+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"טיוטה"</item>
     <item quantity="other" msgid="6961049507579977505">"טיוטות"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"כווץ את פרטי הנמען"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"הצג פרטי איש קשר של <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"הצג פרטי איש קשר"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"תאריך:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> הודעות ישנות יותר"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"מ:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"השב ל:"</string>
     <string name="to_heading" msgid="3219994961726691756">"אל:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"סמל תיקיה"</string>
     <string name="add_account" msgid="2162808366829269770">"הוסף חשבון"</string>
     <string name="attached_message" msgid="4267189489654642035">"הודעה מצורפת"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>‏, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"היום ב-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"אתמול ב-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"מודעות"</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index b11c6fd..fddeb5b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"未読のスレッド"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"下書き"</item>
     <item quantity="other" msgid="6961049507579977505">"下書き"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"受信者の詳細を隠す"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"<xliff:g id="NAME">%1$s</xliff:g>の連絡先情報を表示"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"連絡先情報を表示"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"日付:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"これ以前のメッセージ<xliff:g id="COUNT">%1$d</xliff:g>件"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"From:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"返信先:"</string>
     <string name="to_heading" msgid="3219994961726691756">"To:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"フォルダアイコン"</string>
     <string name="add_account" msgid="2162808366829269770">"アカウントを追加"</string>
     <string name="attached_message" msgid="4267189489654642035">"添付のメッセージ"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>、<xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"今日、<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"昨日、<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"広告"</string>
 </resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index e95fc11..5224cf8 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"대화 읽지 않음"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"임시보관"</item>
     <item quantity="other" msgid="6961049507579977505">"임시보관함"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"수신자 세부정보 접기"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"<xliff:g id="NAME">%1$s</xliff:g>님에 대한 연락처 정보 표시"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"연락처 정보 표시"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"날짜:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"이전 메일 <xliff:g id="COUNT">%1$d</xliff:g>개"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"보낸사람:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"답장:"</string>
     <string name="to_heading" msgid="3219994961726691756">"받는사람:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"폴더 아이콘"</string>
     <string name="add_account" msgid="2162808366829269770">"계정 추가"</string>
     <string name="attached_message" msgid="4267189489654642035">"첨부된 메시지"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"오늘 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"어제 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"광고"</string>
 </resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 0db9ad0..68911f7 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"pokalbis neskaitytas"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g>–<xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Juodraštis"</item>
     <item quantity="other" msgid="6961049507579977505">"Juodrašč."</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Sutraukti išsamią gavėjo informaciją"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Rodyti <xliff:g id="NAME">%1$s</xliff:g> kontaktinę informaciją"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Rodyti kontaktinę informaciją"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Data:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Senesnių pranešimų: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Nuo:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Atsakyti:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Kam:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Aplanko piktograma"</string>
     <string name="add_account" msgid="2162808366829269770">"Pridėti paskyrą"</string>
     <string name="attached_message" msgid="4267189489654642035">"Pridėtas pranešimas"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Šiandien <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Vakar <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Skelbimai"</string>
 </resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index d55fdf1..5180c9b 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"saruna nav izlasīta"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Melnraksts"</item>
     <item quantity="other" msgid="6961049507579977505">"Melnraksti"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Sakļaut informāciju par adresātu"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Rādīt sūtītāja <xliff:g id="NAME">%1$s</xliff:g> kontaktinformāciju"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Rādīt kontaktinformāciju"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datums:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> vecāki ziņojumi"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"No:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Atbildēt:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Kam:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Mapes ikona"</string>
     <string name="add_account" msgid="2162808366829269770">"Pievienot kontu"</string>
     <string name="attached_message" msgid="4267189489654642035">"Pievienots ziņojums"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, plkst. <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Šodien plkst. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Vakar plkst. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Reklāmas"</string>
 </resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index c1957a6..d5fcae6 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"perbualan belum dibaca"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Draf"</item>
     <item quantity="other" msgid="6961049507579977505">"Draf"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Runtuhkan butiran penerima"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Papar maklumat kenalan untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Tunjukkan maklumat kenalan"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Tarikh:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> mesej lebih lama"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Daripada:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Balas-kpd:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Kepada:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikon folder"</string>
     <string name="add_account" msgid="2162808366829269770">"Tambah akaun"</string>
     <string name="attached_message" msgid="4267189489654642035">"Mesej lampiran"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hari ini, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Semalam, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Iklan"</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 3a1ba72..09c2e76 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"samtalen er ulest"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Utkast"</item>
     <item quantity="other" msgid="6961049507579977505">"Utkast"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Skjul detaljer om mottaker"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Vis kontaktinformasjon for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Vis kontaktinformasjon"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Dato:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> eldre e-poster"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Fra:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Svar til:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Til:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Mappeikon"</string>
     <string name="add_account" msgid="2162808366829269770">"Legg til konto"</string>
     <string name="attached_message" msgid="4267189489654642035">"Vedlagt e-post"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"I dag kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"I går kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Annonser"</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 47f91d2..3758c5c 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -35,7 +35,7 @@
     <item msgid="4085029907540221568">"Allen beantwoorden"</item>
     <item msgid="857480048798815437">"Doorsturen"</item>
   </string-array>
-    <string name="reply_attribution" msgid="717207316577386788">"Op <xliff:g id="DATE">%s</xliff:g> schreef <xliff:g id="PERSON">%s</xliff:g> het volgende:"</string>
+    <string name="reply_attribution" msgid="717207316577386788">"Op <xliff:g id="DATE">%s</xliff:g> schreef <xliff:g id="PERSON">%s</xliff:g>:"</string>
     <string name="forward_attribution" msgid="1498936339458535158">"---------- Doorgestuurd bericht ----------&lt;br&gt;Van: <xliff:g id="FROM">%1$s</xliff:g>&lt;br&gt;Datum: <xliff:g id="DATE">%2$s</xliff:g>&lt;br&gt;Onderwerp: <xliff:g id="SUBJECT">%3$s</xliff:g>&lt;br&gt;Aan: <xliff:g id="TO">%4$s</xliff:g>&lt;br&gt;"</string>
     <string name="cc_attribution" msgid="374493748526504562">"Cc: <xliff:g id="CC">%1$s</xliff:g>&lt;br&gt;"</string>
     <string name="select_attachment_type" msgid="4711524151968942082">"Bijlagetype selecteren"</string>
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversatie ongelezen"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Concept"</item>
     <item quantity="other" msgid="6961049507579977505">"Concepten"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Ontvangersdetails samenvouwen"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Contactgegevens weergeven voor <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Contactgegevens weergeven"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> oudere berichten"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Van:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Antwoord:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Aan:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Mappictogram"</string>
     <string name="add_account" msgid="2162808366829269770">"Account toevoegen"</string>
     <string name="attached_message" msgid="4267189489654642035">"Bijgevoegd bericht"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Vandaag, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Gisteren, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Advertenties"</string>
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 76ac987..5754b91 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -162,8 +162,7 @@
     <string name="unread_string" msgid="588180203444398297">"wątek nie został przeczytany"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Wersja robocza"</item>
     <item quantity="other" msgid="6961049507579977505">"Wersje robocze"</item>
@@ -251,8 +250,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Zwiń szczegóły odbiorcy"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Pokaż informacje kontaktowe: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Pokaż informacje kontaktowe"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Data:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Starsze wiadomości: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Od:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Odp. do:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Do:"</string>
@@ -423,4 +423,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikona folderu"</string>
     <string name="add_account" msgid="2162808366829269770">"Dodaj konto"</string>
     <string name="attached_message" msgid="4267189489654642035">"Dołączona wiadomość"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Dzisiaj, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Wczoraj, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Reklamy"</string>
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index d0d933f..c4ae6bb 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversa não lida"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Rascunho"</item>
     <item quantity="other" msgid="6961049507579977505">"Rascunhos"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Fechar detalhes do destinatário"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Mostrar informações de contacto de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Mostrar informações de contacto"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Data:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> mensagens mais antigas"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Responder a:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Para:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ícone de pasta"</string>
     <string name="add_account" msgid="2162808366829269770">"Adicionar conta"</string>
     <string name="attached_message" msgid="4267189489654642035">"Mensagem anexada"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hoje às <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ontem às <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Anúncios"</string>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 7779c94..7d39969 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversa não lida"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Rascunho"</item>
     <item quantity="other" msgid="6961049507579977505">"Rascunhos"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Recolher detalhes do destinatário"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Mostrar informações de contato de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Mostrar informações de contato"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Data:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> mensagens mais antigas"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Res. para:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Para:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ícone de pasta"</string>
     <string name="add_account" msgid="2162808366829269770">"Adicionar conta"</string>
     <string name="attached_message" msgid="4267189489654642035">"Mensagem anexa"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hoje, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ontem, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Anúncios"</string>
 </resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 26b84e2..8cc17f7 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -381,9 +381,7 @@
     <skip />
     <!-- no translation found for contact_info_string_default (596531738469809159) -->
     <skip />
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <!-- no translation found for date_heading (2414358582984879303) -->
-    <skip />
+    <!-- no translation found for show_messages_read:other (7439716291751085801) -->
     <!-- no translation found for from_heading (8950294114718418954) -->
     <skip />
     <!-- no translation found for replyto_heading (2081358811894701297) -->
@@ -656,4 +654,12 @@
     <skip />
     <!-- no translation found for attached_message (4267189489654642035) -->
     <skip />
+    <!-- no translation found for date_message_received (6302308934790266050) -->
+    <skip />
+    <!-- no translation found for date_message_received_today (7923108495669251362) -->
+    <skip />
+    <!-- no translation found for date_message_received_yesterday (2240669381396206434) -->
+    <skip />
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index e86c9b6..6d86ba1 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"conversație necitită"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>] <xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Mesaj nefinalizat"</item>
     <item quantity="other" msgid="6961049507579977505">"Mesaje nefinalizate"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Restrângeţi detaliile destinatarului"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Afişaţi informaţiile de contact pentru <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Afişaţi informaţiile de contact"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Dată:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> (de) mesaje mai vechi"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"De la:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Răsp. la:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Către:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Pictogramă dosar"</string>
     <string name="add_account" msgid="2162808366829269770">"Adăugați un cont"</string>
     <string name="attached_message" msgid="4267189489654642035">"Mesaj atașat"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Astăzi, la <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Ieri, la <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Anunțuri"</string>
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 8c2c504..32c85d6 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"не прочитано"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Черновик"</item>
     <item quantity="other" msgid="6961049507579977505">"Черновики"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Скрыть сведения о получателе"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Показать контактные данные пользователя <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Показать контактные данные"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Дата:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Старых сообщений: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"От:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Ответить:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Кому:"</string>
@@ -425,4 +425,9 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Значок папки"</string>
     <string name="add_account" msgid="2162808366829269770">"Добавить аккаунт"</string>
     <string name="attached_message" msgid="4267189489654642035">"Прикрепленные сообщения"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Сегодня, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Вчера, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 36b6b51..f2c51d1 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"konverzácia nebola prečítaná"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Koncept"</item>
     <item quantity="other" msgid="6961049507579977505">"Koncepty"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Zbaliť podrobnosti o príjemcovi"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Zobraziť informácie kontaktu <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Zobraziť kontaktné informácie"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Dátum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Počet starších správ: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Od:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Odpovedať:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Komu:"</string>
@@ -425,4 +425,9 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikona priečinka"</string>
     <string name="add_account" msgid="2162808366829269770">"Pridať účet"</string>
     <string name="attached_message" msgid="4267189489654642035">"Priložená správa"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> o <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Dnes o <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Včera o <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 939f13c..161dc3b 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"pogovor ni bil prebran"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Osnutek"</item>
     <item quantity="other" msgid="6961049507579977505">"Osnutki"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Strni podrobnosti prejemnika"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Prikaz podatkov za stik za <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Prikaži podatke za stik"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Št. starejših sporočil: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Od:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Odgovori:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Za:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikona mape"</string>
     <string name="add_account" msgid="2162808366829269770">"Dodaj račun"</string>
     <string name="attached_message" msgid="4267189489654642035">"Pripeto sporočilo"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Danes ob <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Včeraj ob <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Oglasi"</string>
 </resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 0d6482b..5898936 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"преписка није прочитана"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>] <xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Недовршена порука"</item>
     <item quantity="other" msgid="6961049507579977505">"Недовршене поруке"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Скупи детаље о примаоцу"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Прикажи контакт информације корисника <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Прикажи контакт информације"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Датум:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Старијих порука: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Од:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Одговор на:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Коме:"</string>
@@ -425,4 +425,9 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Икона директоријума"</string>
     <string name="add_account" msgid="2162808366829269770">"Додај налог"</string>
     <string name="attached_message" msgid="4267189489654642035">"Приложена порука"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Данас, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Јуче, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 685a5fc..7a732f7 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"konversationen är oläst"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Utkast"</item>
     <item quantity="other" msgid="6961049507579977505">"Utkast"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Komprimera mottagardetaljer"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Visa kontaktuppgifter för <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Visa kontaktuppgifter"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Datum:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> äldre meddelanden"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Från:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Svara till:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Till:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Mappikon"</string>
     <string name="add_account" msgid="2162808366829269770">"Lägg till konto"</string>
     <string name="attached_message" msgid="4267189489654642035">"Bifogat meddelande"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Idag kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"I går kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Annonser"</string>
 </resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 43b7b95..bd9c804 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"mazungumzo hayajasomwa"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> - <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Rasimu"</item>
     <item quantity="other" msgid="6961049507579977505">"Rasimu"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Kunja maelezo ya wapokeaji"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Onyesha maelezo ya mawasiliano ya <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Onyesha maelezo ya mawasiliano"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Tarehe:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Ujumbe <xliff:g id="COUNT">%1$d</xliff:g> wa zamani"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Kutoka:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Jibu-kwa:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Kwa:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Ikoni ya folda"</string>
     <string name="add_account" msgid="2162808366829269770">"Ongeza akaunti"</string>
     <string name="attached_message" msgid="4267189489654642035">"Ujumbe ulioambatishwa"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Leo, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Jana, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Matangazo"</string>
 </resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index cf66250..d2c0255 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"ยังไม่ได้อ่านการสนทนา"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"ร่างจดหมาย"</item>
     <item quantity="other" msgid="6961049507579977505">"ร่างจดหมาย"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"ยุบรายละเอียดผู้รับ"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"แสดงข้อมูลติดต่อของ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"แสดงข้อมูลติดต่อ"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"วันที่:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> ข้อความเก่า"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"จาก:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"ตอบกลับ:"</string>
     <string name="to_heading" msgid="3219994961726691756">"ถึง:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"ไอคอนโฟลเดอร์"</string>
     <string name="add_account" msgid="2162808366829269770">"เพิ่มบัญชี"</string>
     <string name="attached_message" msgid="4267189489654642035">"ข้อความที่แนบมา"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g> เวลา <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"วันนี้เวลา <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"เมื่อวานนี้เวลา <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"โฆษณา"</string>
 </resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index e4e11ce..9cb6b4d 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"hindi pa nababasang pag-uusap"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Draft"</item>
     <item quantity="other" msgid="6961049507579977505">"Mga Draft"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Tiklupin ang mga detalye ng recipient"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Ipakita ang impormasyon ng contact para kay <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Ipakita ang impormasyon ng contact"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Petsa:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> (na) mas lumang mensahe"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Mula kay:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Tugon kay:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Para kay:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Icon ng folder"</string>
     <string name="add_account" msgid="2162808366829269770">"Magdagdag ng account"</string>
     <string name="attached_message" msgid="4267189489654642035">"Naka-attach na mensahe"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Ngayon, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Kahapon, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Mga Ad"</string>
 </resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 1aa6be8..2151a76 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"ileti dizisi okunmadı"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Taslak"</item>
     <item quantity="other" msgid="6961049507579977505">"Taslaklar"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Alıcı ayrıntılarını daralt"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"<xliff:g id="NAME">%1$s</xliff:g> iletişim bilgilerini göster"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"İletişim bilgilerini göster"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Tarih:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> eski ileti"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Gönderen:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Yanıt Adresi:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Alıcı:"</string>
@@ -425,4 +425,9 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Klasör simgesi"</string>
     <string name="add_account" msgid="2162808366829269770">"Hesap ekle"</string>
     <string name="attached_message" msgid="4267189489654642035">"Ekli ileti"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Bugün, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Dün, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index a0f849e..aec4c99 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"бесіду не прочитано"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> – <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Чернетка"</item>
     <item quantity="other" msgid="6961049507579977505">"Чернетки"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Згорнути дані отримувача"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Показати контактну інформацію відправника <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Показати контактну інформацію"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Дата:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"Попередні повідомлення: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Від:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Відпов.:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Кому:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Значок папки"</string>
     <string name="add_account" msgid="2162808366829269770">"Додати обліковий запис"</string>
     <string name="attached_message" msgid="4267189489654642035">"Вкладене повідомлення"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Сьогодні, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Учора, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Оголошення"</string>
 </resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index e61862d..a457943 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"cuộc trò chuyện chưa đọc"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Bản nháp"</item>
     <item quantity="other" msgid="6961049507579977505">"Bản nháp"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Thu gọn chi tiết người nhận"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Hiển thị thông tin liên hệ cho <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Hiển thị thông tin liên hệ"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Ngày:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> thư cũ hơn"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Từ:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Trả lời"</string>
     <string name="to_heading" msgid="3219994961726691756">"Đến:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Biểu tượng thư mục"</string>
     <string name="add_account" msgid="2162808366829269770">"Thêm tài khoản"</string>
     <string name="attached_message" msgid="4267189489654642035">"Tin nhắn đính kèm"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Hôm nay, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Hôm qua, <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Quảng cáo"</string>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 7d75de4..e0b3acd 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"未读会话"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>] <xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> - <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"草稿"</item>
     <item quantity="other" msgid="6961049507579977505">"草稿"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"折叠收件人详细信息"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"显示<xliff:g id="NAME">%1$s</xliff:g>的联系人信息"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"显示联系人信息"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"日期:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g>封较早的邮件"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"发件人:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"回复:"</string>
     <string name="to_heading" msgid="3219994961726691756">"收件人:"</string>
@@ -425,4 +425,9 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"文件夹图标"</string>
     <string name="add_account" msgid="2162808366829269770">"添加帐户"</string>
     <string name="attached_message" msgid="4267189489654642035">"附加的邮件"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"今天<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"昨天<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <!-- no translation found for ads (8547072743610267481) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index dc569fe..81e25d1 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"未閱讀的會話群組"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"還有 <xliff:g id="ID_1">%d</xliff:g> 個附件"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"草稿"</item>
     <item quantity="other" msgid="6961049507579977505">"草稿"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"收合收件者詳細資料"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"顯示 <xliff:g id="NAME">%1$s</xliff:g> 的聯絡人資訊"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"顯示聯絡人資訊"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"日期:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> 封較舊的郵件"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"寄件者:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"回覆:"</string>
     <string name="to_heading" msgid="3219994961726691756">"收件者:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"資料夾圖示"</string>
     <string name="add_account" msgid="2162808366829269770">"新增帳戶"</string>
     <string name="attached_message" msgid="4267189489654642035">"附加的郵件"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"今天<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"昨天<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"廣告"</string>
 </resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index b97b9c5..3141751 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -164,8 +164,7 @@
     <string name="unread_string" msgid="588180203444398297">"inkulumo engafundiwe"</string>
     <string name="filtered_tag" msgid="6470627954465675488">"[<xliff:g id="TAG">%1$s</xliff:g>]<xliff:g id="SUBJECT">%2$s</xliff:g>"</string>
     <string name="subject_and_snippet" msgid="7884124651812798896">"<xliff:g id="ID_1">%s</xliff:g> — <xliff:g id="ID_2">%s</xliff:g>"</string>
-    <!-- no translation found for ap_overflow_format (2285438422049030145) -->
-    <skip />
+    <string name="ap_overflow_format" msgid="2285438422049030145">"+<xliff:g id="ID_1">%d</xliff:g>"</string>
   <plurals name="draft">
     <item quantity="one" msgid="333591132893648383">"Okusalungiswa"</item>
     <item quantity="other" msgid="6961049507579977505">"Okusalungiswa"</item>
@@ -253,8 +252,9 @@
     <string name="collapse_recipient_details" msgid="3608892454869745927">"Goqa imininingwane yomtholi"</string>
     <string name="contact_info_string" msgid="6911322458329265644">"Khombisa imininingwane yokuxhumana ka-<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="contact_info_string_default" msgid="596531738469809159">"Bonisa ulwazi loxhumana naye"</string>
-    <!-- no translation found for show_messages_read:other (7344988174650303930) -->
-    <string name="date_heading" msgid="2414358582984879303">"Usuku:"</string>
+  <plurals name="show_messages_read">
+    <item quantity="other" msgid="7439716291751085801">"<xliff:g id="COUNT">%1$d</xliff:g> imilayezo emidala"</item>
+  </plurals>
     <string name="from_heading" msgid="8950294114718418954">"Kusuka:"</string>
     <string name="replyto_heading" msgid="2081358811894701297">"Phendula-ku:"</string>
     <string name="to_heading" msgid="3219994961726691756">"Kuya ku:"</string>
@@ -425,4 +425,8 @@
     <string name="folder_icon_desc" msgid="1500547397347480618">"Isithonjana sefolda"</string>
     <string name="add_account" msgid="2162808366829269770">"Engeza i-akhawunti"</string>
     <string name="attached_message" msgid="4267189489654642035">"Umlayezo oshumekiwe"</string>
+    <string name="date_message_received" msgid="6302308934790266050">"<xliff:g id="DAY_AND_DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="date_message_received_today" msgid="7923108495669251362">"Namhlanje, ngo-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="date_message_received_yesterday" msgid="2240669381396206434">"Izolo, ngo-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="ads" msgid="8547072743610267481">"Izikhangiso"</string>
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 21197aa..da9957f 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -32,6 +32,7 @@
     <color name="date_text_color">@color/dark_gray_text_color</color>
     <color name="message_info_text_color">@color/gray_text_color</color>
     <color name="subject_text_color">#333333</color>
+    <color name="ap_background_color">#fff1f1f2</color>
     <color name="ap_overflow_badge_color">#eeeeeeee</color>
     <color name="ap_overflow_text_color">#ff4f4c4c</color>
     <!-- a 'checked' item is in the conversation selection set. also the 'pressed' color. -->
@@ -128,4 +129,6 @@
     <color name="collapsed_message_header_background_color">#eeeded</color>
     <!-- The color of the expanded message header -->
     <color name="expanded_message_header_background_color">@android:color/white</color>
+
+    <color name="ad_background_yellow">#fff8e5</color>
 </resources>
diff --git a/res/values/constants.xml b/res/values/constants.xml
index 4cf9399..f0c15b5 100644
--- a/res/values/constants.xml
+++ b/res/values/constants.xml
@@ -117,10 +117,15 @@
 
     <!-- Duration of progress bar animation for attachment previews -->
     <integer name="ap_progress_animation_duration">4000</integer>
+    <!-- Duration of fade in/out animation for attachment previews -->
+    <integer name="ap_fade_animation_duration">500</integer>
     <!-- Duration of placeholder pulse animation for attachment previews -->
     <integer name="ap_placeholder_animation_duration">2000</integer>
     <!-- Delay before showing progress bar animations for attachment previews that are loading -->
     <integer name="ap_progress_animation_delay">2000</integer>
     <!-- Max overflow count to show for attachment previews -->
     <integer name="ap_overflow_max_count">99</integer>
+
+    <!-- Duration of the animations for entering/exiting CAB mode -->
+    <integer name="conv_item_view_cab_anim_duration">350</integer>
 </resources>
diff --git a/res/values/helpcontext.xml b/res/values/helpcontext.xml
index 2538dac..a16f4b5 100644
--- a/res/values/helpcontext.xml
+++ b/res/values/helpcontext.xml
@@ -18,10 +18,8 @@
 <resources>
     <!-- Help context for the compose screen  -->
     <string name="compose_help_context" translatable="false">compose</string>
-    <!-- Help context for the folder list, in one pane mode  -->
-    <string name="one_pane_folder_list_help_context" translatable="false">fl</string>
     <!-- Help context for the wait mode  -->
     <string name="wait_help_context" translatable="false">wait</string>
     <!-- Help context for the conversation list, and viewing the conversation (one or two pane)  -->
     <string name="main_help_context" translatable="false">ttl</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 14263b2..e76f72c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -962,4 +962,7 @@
     <!-- Shown to display the date of the message when the message was received yesterday. [CHAR LIMIT=50] -->
     <string name="date_message_received_yesterday">Yesterday, <xliff:g id="time">%1$s</xliff:g></string>
 
+    <!-- Shown in the message ad header and in the list item for a message ad. [CHAR LIMIT=15]-->
+    <string name="ads">Ads</string>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index c57900e..9263316 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -283,9 +283,11 @@
     </style>
 
     <style name="MessageDetailsValueStyle" parent="MessageHeaderSmallStyle">
-        <item name="android:textIsSelectable">true</item>
+        <item name="android:autoLink">email</item>
+        <item name="android:linksClickable">true</item>
         <item name="android:textColor">@color/conv_header_text_light</item>
         <item name="android:textColorLink">@color/conv_header_text_link_blue</item>
+        <item name="android:textIsSelectable">true</item>
     </style>
 
     <style name="MessageHeaderActionButtonStyle" parent="android:Widget.Holo.Button.Borderless">
diff --git a/src/com/android/mail/MailIntentService.java b/src/com/android/mail/MailIntentService.java
index 2fa0717..daca7a7 100644
--- a/src/com/android/mail/MailIntentService.java
+++ b/src/com/android/mail/MailIntentService.java
@@ -16,6 +16,7 @@
 package com.android.mail;
 
 import android.net.Uri;
+
 import com.android.mail.utils.StorageLowState;
 
 import android.app.IntentService;
@@ -24,6 +25,7 @@
 
 import com.android.mail.providers.Account;
 import com.android.mail.providers.Folder;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
 import com.android.mail.utils.NotificationUtils;
@@ -71,7 +73,8 @@
             final Uri accountUri = intent.getParcelableExtra(Utils.EXTRA_ACCOUNT_URI);
             final Uri folderUri = intent.getParcelableExtra(Utils.EXTRA_FOLDER_URI);
 
-            NotificationUtils.resendNotifications(this, false, accountUri, folderUri);
+            NotificationUtils.resendNotifications(this, false, accountUri,
+                    new FolderUri(folderUri));
         } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
             // The storage_low state is recorded centrally even though
             // no handler might be present to change application state
diff --git a/src/com/android/mail/adapter/DrawerItem.java b/src/com/android/mail/adapter/DrawerItem.java
index 00f76f3..f8a819b 100644
--- a/src/com/android/mail/adapter/DrawerItem.java
+++ b/src/com/android/mail/adapter/DrawerItem.java
@@ -313,7 +313,7 @@
             case VIEW_FOLDER:
                 // True if folder types and URIs are the same
                 if (currentFolder != null && mFolder != null) {
-                    return (mFolderType == currentType) && mFolder.uri.equals(currentFolder.uri);
+                    return (mFolderType == currentType) && mFolder.equals(currentFolder);
                 }
                 return false;
             case VIEW_ACCOUNT:
diff --git a/src/com/android/mail/ads/AdHeaderView.java b/src/com/android/mail/ads/AdHeaderView.java
new file mode 100644
index 0000000..f7da0ef
--- /dev/null
+++ b/src/com/android/mail/ads/AdHeaderView.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.ads;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.mail.R;
+import com.android.mail.browse.ConversationViewAdapter.AdHeaderItem;
+
+public class AdHeaderView extends LinearLayout implements View.OnClickListener {
+    private TextView mAdSubjectView;
+
+    private AdHeaderItem mHeaderItem;
+
+    public AdHeaderView(Context context) {
+        super(context);
+    }
+
+    public AdHeaderView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mAdSubjectView = (TextView) findViewById(R.id.ad_subject);
+        findViewById(R.id.ad_info).setOnClickListener(this);
+    }
+
+    public void setAdSubject(final String subject) {
+        mAdSubjectView.setText(subject);
+        if (TextUtils.isEmpty(subject)) {
+            mAdSubjectView.setVisibility(GONE);
+        }
+    }
+
+    public void bind(AdHeaderItem headerItem) {
+        mHeaderItem = headerItem;
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch(view.getId()) {
+            case R.id.ad_info:
+                // TODO wire up clicking the ad info button
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/src/com/android/mail/ads/AdViewFragment.java b/src/com/android/mail/ads/AdViewFragment.java
new file mode 100644
index 0000000..c5b747d
--- /dev/null
+++ b/src/com/android/mail/ads/AdViewFragment.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.ads;
+
+import android.os.Bundle;
+
+import com.android.mail.browse.ConversationMessage;
+import com.android.mail.browse.MessageCursor;
+import com.android.mail.providers.Conversation;
+import com.android.mail.ui.ConversationViewFragment;
+import com.android.mail.ui.ConversationViewState;
+import com.android.mail.utils.LogTag;
+import com.android.mail.utils.LogUtils;
+
+public final class AdViewFragment extends ConversationViewFragment {
+
+    private static final String LOG_TAG = LogTag.getLogTag();
+
+    /**
+     * Constructor needs to be public to handle orientation changes and activity lifecycle events.
+     */
+    public AdViewFragment() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of {@link AdViewFragment}, initialized
+     * to display a conversation with other parameters inherited/copied from an existing bundle,
+     * typically one created using {@link #makeBasicArgs}.
+     */
+    public static AdViewFragment newInstance(Bundle existingArgs,
+            Conversation conversation) {
+        final AdViewFragment f = new AdViewFragment();
+        final Bundle args = new Bundle(existingArgs);
+        args.putParcelable(ARG_CONVERSATION, conversation);
+        f.setArguments(args);
+        return f;
+    }
+
+    /**
+     * Populate the adapter with overlay views (message headers, super-collapsed blocks, a
+     * conversation header), and return an HTML document with spacer divs inserted for all overlays.
+     *
+     */
+    @Override
+    protected String renderMessageBodies(MessageCursor messageCursor,
+            boolean enableContentReadySignal) {
+        int pos = -1;
+
+        LogUtils.d(LOG_TAG, "IN renderMessageBodies, fragment=%s", this);
+        boolean allowNetworkImages = false;
+
+        // TODO: re-use any existing adapter item state (expanded, details expanded, show pics)
+
+        // Walk through the cursor and build up an overlay adapter as you go.
+        // Each overlay has an entry in the adapter for easy scroll handling in the container.
+        // Items are not necessarily 1:1 in cursor and adapter because of super-collapsed blocks.
+        // When adding adapter items, also add their heights to help the container later determine
+        // overlay dimensions.
+
+        // When re-rendering, prevent ConversationContainer from laying out overlays until after
+        // the new spacers are positioned by WebView.
+        mConversationContainer.invalidateSpacerGeometry();
+
+        mAdapter.clear();
+
+        // re-evaluate the message parts of the view state, since the messages may have changed
+        // since the previous render
+        final ConversationViewState prevState = mViewState;
+        mViewState = new ConversationViewState(prevState);
+
+        // N.B. the units of height for spacers are actually dp and not px because WebView assumes
+        // a pixel is an mdpi pixel, unless you set device-dpi.
+
+        // add a single conversation header item
+        final int adHeaderPos = mAdapter.addAdHeader(mConversation);
+        final int adHeaderPx = measureOverlayHeight(adHeaderPos);
+
+        mTemplates.startConversation(mWebView.screenPxToWebPx(mSideMarginPx),
+                mWebView.screenPxToWebPx(adHeaderPx));
+
+        if (messageCursor.moveToFirst()) {
+            final ConversationMessage msg = messageCursor.getMessage();
+            renderMessage(msg);
+        }
+
+        mWebView.getSettings().setBlockNetworkImage(false);
+
+        final boolean applyTransforms = shouldApplyTransforms();
+
+        // If the conversation has specified a base uri, use it here, otherwise use mBaseUri
+        return mTemplates.endConversation(mBaseUri, mConversation.getBaseUri(mBaseUri), 320,
+                mWebView.getViewportWidth(), enableContentReadySignal, isOverviewMode(mAccount),
+                applyTransforms, applyTransforms);
+    }
+
+    private void renderMessage(ConversationMessage msg) {
+        mAdapter.addAdFooter();
+
+        mTemplates.appendMessageHtml(msg, true /** expanded */, true /** showImages */,
+               0 /** headerHeight */, 0 /** footerHeight */);
+        timerMark("rendered message");
+    }
+}
diff --git a/src/com/android/mail/browse/AttachmentProgressDialogFragment.java b/src/com/android/mail/browse/AttachmentProgressDialogFragment.java
index aef90eb..36c158c 100644
--- a/src/com/android/mail/browse/AttachmentProgressDialogFragment.java
+++ b/src/com/android/mail/browse/AttachmentProgressDialogFragment.java
@@ -40,7 +40,7 @@
         final AttachmentProgressDialogFragment f = new AttachmentProgressDialogFragment();
 
         // Supply the attachment as an argument.
-        final Bundle args = new Bundle();
+        final Bundle args = new Bundle(1);
         args.putParcelable(ATTACHMENT_KEY, attachment);
         f.setArguments(args);
 
diff --git a/src/com/android/mail/browse/ConversationCursor.java b/src/com/android/mail/browse/ConversationCursor.java
index 2b1020b..4b05465 100644
--- a/src/com/android/mail/browse/ConversationCursor.java
+++ b/src/com/android/mail/browse/ConversationCursor.java
@@ -359,7 +359,7 @@
         private int mCachePos;
         private boolean mCachingEnabled = true;
         private final NewCursorUpdateObserver mCursorUpdateObserver;
-        private boolean mUpdateObserverRegistered;
+        private boolean mUpdateObserverRegistered = false;
 
         // Ideally these two objects could be combined into a Map from
         // conversationId -> position, but the cached values uses the conversation
@@ -377,8 +377,10 @@
             // any updates
             mCursorUpdateObserver =
                     new NewCursorUpdateObserver(new Handler(Looper.getMainLooper()));
-            result.registerContentObserver(mCursorUpdateObserver);
-            mUpdateObserverRegistered = true;
+            if (result != null) {
+                result.registerContentObserver(mCursorUpdateObserver);
+                mUpdateObserverRegistered = true;
+            }
 
             final long start = SystemClock.uptimeMillis();
             final Map<String, Integer> uriPositionMap;
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index cf15909..2e19842 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -28,14 +28,15 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.LinearGradient;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
-import android.net.Uri;
 import android.os.SystemClock;
 import android.text.Layout.Alignment;
 import android.text.Spannable;
@@ -72,7 +73,6 @@
 import com.android.mail.R.string;
 import com.android.mail.browse.ConversationItemViewModel.SenderFragment;
 import com.android.mail.perf.Timer;
-import com.android.mail.photo.MailPhotoViewActivity;
 import com.android.mail.photomanager.AttachmentPreviewsManager;
 import com.android.mail.photomanager.AttachmentPreviewsManager.AttachmentPreviewsDividedImageCanvas;
 import com.android.mail.photomanager.AttachmentPreviewsManager.AttachmentPreviewsManagerCallback;
@@ -91,15 +91,18 @@
 import com.android.mail.providers.UIProvider.ConversationListIcon;
 import com.android.mail.providers.UIProvider.FolderType;
 import com.android.mail.ui.AnimatedAdapter;
+import com.android.mail.ui.AnimatedAdapter.ConversationListListener;
 import com.android.mail.ui.ControllableActivity;
 import com.android.mail.ui.ConversationSelectionSet;
 import com.android.mail.ui.DividedImageCanvas;
 import com.android.mail.ui.DividedImageCanvas.InvalidateCallback;
+import com.android.mail.ui.ConversationSetObserver;
 import com.android.mail.ui.FolderDisplayer;
 import com.android.mail.ui.ImageCanvas;
 import com.android.mail.ui.SwipeableItemView;
 import com.android.mail.ui.SwipeableListView;
 import com.android.mail.ui.ViewMode;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.HardwareLayerEnabler;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
@@ -128,6 +131,8 @@
     // Static bitmaps.
     private static Bitmap STAR_OFF;
     private static Bitmap STAR_ON;
+    private static Bitmap PEEK;
+    private static Bitmap CHECK;
     private static Bitmap ATTACHMENT;
     private static Bitmap ONLY_TO_ME;
     private static Bitmap TO_ME_AND_OTHERS;
@@ -148,30 +153,30 @@
     private static String sOverflowCountFormat;
 
     // Static colors.
-    private static int sActivatedTextColor;
     private static int sSendersTextColorRead;
     private static int sSendersTextColorUnread;
     private static int sDateTextColor;
+    private static int sAttachmentPreviewsBackgroundColor;
     private static int sOverflowBadgeColor;
     private static int sOverflowTextColor;
     private static int sStarTouchSlop;
     private static int sSenderImageTouchSlop;
-    @Deprecated
-    private static int sStandardScaledDimen;
     private static int sShrinkAnimationDuration;
     private static int sSlideAnimationDuration;
-    private static int sAnimatingBackgroundColor;
     private static int sProgressAnimationDuration;
+    private static int sFadeAnimationDuration;
     private static float sPlaceholderAnimationDurationRatio;
     private static int sProgressAnimationDelay;
     private static Interpolator sPulseAnimationInterpolator;
     private static int sOverflowCountMax;
+    private static int sCabAnimationDuration;
 
     // Static paints.
-    private static TextPaint sPaint = new TextPaint();
-    private static TextPaint sFoldersPaint = new TextPaint();
+    private static final TextPaint sPaint = new TextPaint();
+    private static final TextPaint sFoldersPaint = new TextPaint();
+    private static final Paint sCheckBackgroundPaint = new Paint();
 
-    private static Rect sRect = new Rect();
+    private static final Rect sRect = new Rect();
 
     // Backgrounds for different states.
     private final SparseArray<Drawable> mBackgrounds = new SparseArray<Drawable>();
@@ -211,16 +216,17 @@
     private int mLastTouchX;
     private int mLastTouchY;
     private AnimatedAdapter mAdapter;
+    private int mAdapterPosition;
     private float mAnimatedHeightFraction = 1.0f;
     private final String mAccount;
     private ControllableActivity mActivity;
+    private ConversationListListener mConversationListListener;
     private final TextView mSubjectTextView;
     private final TextView mSendersTextView;
     private int mGadgetMode;
     private final DividedImageCanvas mContactImagesHolder;
     private static ContactPhotoManager sContactPhotoManager;
 
-
     private static int sFoldersLeftPadding;
     private static TextAppearanceSpan sSubjectTextUnreadSpan;
     private static TextAppearanceSpan sSubjectTextReadSpan;
@@ -236,17 +242,38 @@
      * this animator does not remove the progress bars.
      */
     private final ObjectAnimator mProgressAnimator;
+    private final ObjectAnimator mFadeAnimator0;
+    private final ObjectAnimator mFadeAnimator1;
     private long mProgressAnimatorCancelledTime;
     /** Range from 0.0f to 1.0f. */
     private float mAnimatedProgressFraction;
-    private int[] mImagesLoaded = new int[0];
+    private float mAnimatedFadeFraction0;
+    private float mAnimatedFadeFraction1;
+    private int[] mImageLoadStatuses = new int[0];
     private boolean mShowProgressBar;
-    private Runnable mSetShowProgressBarRunnable;
+    private final Runnable mCancelProgressAnimatorRunnable;
+    private final Runnable mSetShowProgressBarRunnable0;
+    private final Runnable mSetShowProgressBarRunnable1;
     private static final boolean CONVLIST_ATTACHMENT_PREVIEWS_ENABLED = true;
 
+    private final Matrix mPhotoFlipMatrix = new Matrix();
+    private final Matrix mCheckMatrix = new Matrix();
+    private final Matrix mPeekIconFlipMatrix = new Matrix();
+
+    private final CabAnimator mPhotoFlipAnimator;
+    private final CabAnimator mPeekIconFlipAnimator;
+
+    /**
+     * The conversation id, if this conversation was selected the last time we were in a selection
+     * mode. This is reset after any animations complete upon exiting the selection mode.
+     */
+    private long mLastSelectedId = -1;
+
     static {
         sPaint.setAntiAlias(true);
         sFoldersPaint.setAntiAlias(true);
+
+        sCheckBackgroundPaint.setColor(Color.GRAY);
     }
 
     public static void setScrollStateChanged(final int scrollState) {
@@ -281,7 +308,7 @@
         }
 
         @Override
-        public void loadConversationFolders(Conversation conv, final Uri ignoreFolderUri,
+        public void loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri,
                 final int ignoreFolderType) {
             super.loadConversationFolders(conv, ignoreFolderUri, ignoreFolderType);
             mFoldersCount = mFoldersSortedSet.size();
@@ -325,7 +352,6 @@
             final int xEnd = coordinates.foldersXEnd;
             final int y = coordinates.foldersY;
             final int height = coordinates.foldersHeight;
-            final int ascent = coordinates.foldersAscent;
             int textBottomPadding = coordinates.foldersTextBottomPadding;
 
             sFoldersPaint.setTextSize(coordinates.foldersFontSize);
@@ -403,13 +429,6 @@
         }
     }
 
-    /**
-     * Helpers function to align an element in the center of a space.
-     */
-    private static int getPadding(int space, int length) {
-        return (space - length) / 2;
-    }
-
     public ConversationItemView(Context context, String account) {
         super(context);
         Utils.traceBeginSection("CIVC constructor");
@@ -425,8 +444,10 @@
 
         if (STAR_OFF == null) {
             // Initialize static bitmaps.
-            STAR_OFF = BitmapFactory.decodeResource(res, R.drawable.ic_star_off);
-            STAR_ON = BitmapFactory.decodeResource(res, R.drawable.ic_star_on);
+            STAR_OFF = BitmapFactory.decodeResource(res, R.drawable.ic_btn_star_off);
+            STAR_ON = BitmapFactory.decodeResource(res, R.drawable.ic_btn_star_on);
+            PEEK = BitmapFactory.decodeResource(res, R.drawable.ic_peak_eye);
+            CHECK = BitmapFactory.decodeResource(res, R.drawable.ic_avatar_check);
             ATTACHMENT = BitmapFactory.decodeResource(res, R.drawable.ic_attachment_holo_light);
             ONLY_TO_ME = BitmapFactory.decodeResource(res, R.drawable.ic_email_caret_double);
             TO_ME_AND_OTHERS = BitmapFactory.decodeResource(res, R.drawable.ic_email_caret_single);
@@ -451,8 +472,8 @@
             PROGRESS_BAR = res.getDrawable(drawable.progress_holo);
 
             // Initialize colors.
-            sActivatedTextColor = res.getColor(R.color.senders_text_color_read);
-            sActivatedTextSpan = CharacterStyle.wrap(new ForegroundColorSpan(sActivatedTextColor));
+            sActivatedTextSpan = CharacterStyle.wrap(new ForegroundColorSpan(
+                    res.getColor(R.color.senders_text_color_read)));
             sSendersTextColorRead = res.getColor(R.color.senders_text_color_read);
             sSendersTextColorUnread = res.getColor(R.color.senders_text_color_unread);
             sSubjectTextUnreadSpan = new TextAppearanceSpan(mContext,
@@ -464,23 +485,23 @@
             sSnippetTextReadSpan =
                     new ForegroundColorSpan(res.getColor(R.color.snippet_text_color_read));
             sDateTextColor = res.getColor(R.color.date_text_color);
+            sAttachmentPreviewsBackgroundColor = res.getColor(color.ap_background_color);
             sOverflowBadgeColor = res.getColor(color.ap_overflow_badge_color);
             sOverflowTextColor = res.getColor(color.ap_overflow_text_color);
             sStarTouchSlop = res.getDimensionPixelSize(R.dimen.star_touch_slop);
             sSenderImageTouchSlop = res.getDimensionPixelSize(R.dimen.sender_image_touch_slop);
-            sStandardScaledDimen = res.getDimensionPixelSize(R.dimen.standard_scaled_dimen);
             sShrinkAnimationDuration = res.getInteger(R.integer.shrink_animation_duration);
             sSlideAnimationDuration = res.getInteger(R.integer.slide_animation_duration);
             // Initialize static color.
             sSendersSplitToken = res.getString(R.string.senders_split_token);
             sElidedPaddingToken = res.getString(R.string.elided_padding_token);
             sOverflowCountFormat = res.getString(string.ap_overflow_format);
-            sAnimatingBackgroundColor = res.getColor(R.color.animating_item_background_color);
             sScrollSlop = res.getInteger(R.integer.swipeScrollSlop);
             sFoldersLeftPadding = res.getDimensionPixelOffset(R.dimen.folders_left_padding);
             sContactPhotoManager = ContactPhotoManager.createContactPhotoManager(context);
             sAttachmentPreviewsManager = new AttachmentPreviewsManager(context);
             sProgressAnimationDuration = res.getInteger(integer.ap_progress_animation_duration);
+            sFadeAnimationDuration = res.getInteger(integer.ap_fade_animation_duration);
             final int placeholderAnimationDuration = res
                     .getInteger(integer.ap_placeholder_animation_duration);
             sPlaceholderAnimationDurationRatio = sProgressAnimationDuration
@@ -488,8 +509,34 @@
             sProgressAnimationDelay = res.getInteger(integer.ap_progress_animation_delay);
             sPulseAnimationInterpolator = new AccelerateDecelerateInterpolator();
             sOverflowCountMax = res.getInteger(integer.ap_overflow_max_count);
+            sCabAnimationDuration =
+                    res.getInteger(R.integer.conv_item_view_cab_anim_duration);
         }
 
+        mPhotoFlipAnimator = new CabAnimator("photoFlipFraction", 0, 2,
+                sCabAnimationDuration) {
+            @Override
+            public void invalidateArea() {
+                final int left = mCoordinates.contactImagesX;
+                final int right = left + mContactImagesHolder.getWidth();
+                final int top = mCoordinates.contactImagesY;
+                final int bottom = top + mContactImagesHolder.getHeight();
+                invalidate(left, top, right, bottom);
+            }
+        };
+
+        mPeekIconFlipAnimator = new CabAnimator("peekIconFlipFraction", 0, 2,
+                sCabAnimationDuration) {
+            @Override
+            public void invalidateArea() {
+                final int left = mCoordinates.starX;
+                final int right = left + mCoordinates.starWidth;
+                final int top = mCoordinates.starY;
+                final int bottom = top + mCoordinates.starHeight;
+                invalidate(left, top, right, bottom);
+            }
+        };
+
         mSendersTextView = new TextView(mContext);
         mSendersTextView.setIncludeFontPadding(false);
 
@@ -526,29 +573,67 @@
                 });
 
         mProgressAnimator = createProgressAnimator();
-        mSetShowProgressBarRunnable = new Runnable() {
+        mFadeAnimator0 = createFadeAnimator(0);
+        mFadeAnimator1 = createFadeAnimator(1);
+        mCancelProgressAnimatorRunnable = new Runnable() {
             @Override
             public void run() {
-                LogUtils.v(LOG_TAG, "progress bar: >>> set to true");
-                // It's OK to set this field to true when the status is no longer LOADING.
+                if (mProgressAnimator.isStarted() && areAllImagesLoaded()) {
+                    LogUtils.v(LOG_TAG, "progress animator: << stopped");
+                    mProgressAnimator.cancel();
+                }
+            }
+        };
+        mSetShowProgressBarRunnable0 = new Runnable() {
+            @Override
+            public void run() {
+                if (mImageLoadStatuses.length <= 0
+                        || mImageLoadStatuses[0] != PhotoManager.STATUS_LOADING) {
+                    return;
+                }
+                LogUtils.v(LOG_TAG, "progress bar 0: >>> set to true");
                 mShowProgressBar = true;
+                if (mFadeAnimator0.isStarted()) {
+                    mFadeAnimator0.cancel();
+                }
+                mFadeAnimator0.start();
+            }
+        };
+        mSetShowProgressBarRunnable1 = new Runnable() {
+            @Override
+            public void run() {
+                if (mImageLoadStatuses.length <= 1
+                        || mImageLoadStatuses[1] != PhotoManager.STATUS_LOADING) {
+                    return;
+                }
+                LogUtils.v(LOG_TAG, "progress bar 1: >>> set to true");
+                mShowProgressBar = true;
+                if (mFadeAnimator1.isStarted()) {
+                    mFadeAnimator1.cancel();
+                }
+                mFadeAnimator1.start();
             }
         };
         Utils.traceEndSection();
     }
 
     public void bind(Conversation conversation, ControllableActivity activity,
+            final ConversationListListener conversationListListener,
             ConversationSelectionSet set, Folder folder, int checkboxOrSenderImage,
-            boolean swipeEnabled, boolean priorityArrowEnabled, AnimatedAdapter adapter) {
+            boolean swipeEnabled, boolean priorityArrowEnabled, AnimatedAdapter adapter,
+            final int adapterPosition) {
         Utils.traceBeginSection("CIVC.bind");
-        bind(ConversationItemViewModel.forConversation(mAccount, conversation), activity, set,
-                folder, checkboxOrSenderImage, swipeEnabled, priorityArrowEnabled, adapter);
+        bind(ConversationItemViewModel.forConversation(mAccount, conversation), activity,
+                conversationListListener, set, folder, checkboxOrSenderImage, swipeEnabled,
+                priorityArrowEnabled, adapter, adapterPosition);
         Utils.traceEndSection();
     }
 
     private void bind(ConversationItemViewModel header, ControllableActivity activity,
+            final ConversationListListener conversationListListener,
             ConversationSelectionSet set, Folder folder, int checkboxOrSenderImage,
-            boolean swipeEnabled, boolean priorityArrowEnabled, AnimatedAdapter adapter) {
+            boolean swipeEnabled, boolean priorityArrowEnabled, AnimatedAdapter adapter,
+            final int adapterPosition) {
         boolean attachmentPreviewsChanged = false;
         if (mHeader != null) {
             // If this was previously bound to a different conversation, remove any contact photo
@@ -593,14 +678,22 @@
         mCoordinates = null;
         mHeader = header;
         mActivity = activity;
+        mConversationListListener = conversationListListener;
         mSelectedConversationSet = set;
         mDisplayedFolder = folder;
         mStarEnabled = folder != null && !folder.isTrash();
         mSwipeEnabled = swipeEnabled;
+
+        if (mAdapter != null) {
+            mAdapter.unregisterConversationSetObserver(mConversationSetObserver);
+        }
         mAdapter = adapter;
+        mAdapter.registerConversationSetObserver(mConversationSetObserver);
+
+        mAdapterPosition = adapterPosition;
         final int attachmentPreviewsSize = mHeader.conversation.getAttachmentPreviewUris().size();
-        if (attachmentPreviewsChanged || mImagesLoaded.length != attachmentPreviewsSize) {
-            mImagesLoaded = new int[attachmentPreviewsSize];
+        if (attachmentPreviewsChanged || mImageLoadStatuses.length != attachmentPreviewsSize) {
+            mImageLoadStatuses = new int[attachmentPreviewsSize];
         }
 
         if (checkboxOrSenderImage == ConversationListIcon.SENDER_IMAGE) {
@@ -623,8 +716,8 @@
             ignoreFolderType = -1;
         }
 
-        mHeader.folderDisplayer.loadConversationFolders(mHeader.conversation, mDisplayedFolder.uri,
-                ignoreFolderType);
+        mHeader.folderDisplayer.loadConversationFolders(mHeader.conversation,
+                mDisplayedFolder.folderUri, ignoreFolderType);
 
         mHeader.dateText = DateUtils.getRelativeTimeSpanString(mContext,
                 mHeader.conversation.dateMs);
@@ -722,8 +815,13 @@
 
         super.onLayout(changed, left, top, right, bottom);
 
+        Utils.traceBeginSection("text and bitmaps");
         calculateTextsAndBitmaps();
+        Utils.traceEndSection();
+
+        Utils.traceBeginSection("coordinates");
         calculateCoordinates();
+        Utils.traceEndSection();
 
         // Subject.
         createSubject(mHeader.unread);
@@ -937,7 +1035,7 @@
                     uri);
             int bestAvailableRendition = -1;
             // BEST first, else use less preferred renditions
-            for (int rendition : AttachmentRendition.PREFERRED_RENDITIONS) {
+            for (final int rendition : AttachmentRendition.PREFERRED_RENDITIONS) {
                 if (Attachment.getPreviewState(previewStates, i, rendition)) {
                     bestAvailableRendition = rendition;
                     break;
@@ -968,8 +1066,6 @@
             Utils.traceEndSection();
 
             Utils.traceBeginSection("start animator");
-            // We want to show default progress image
-            setImageLoaded(i, PhotoManager.STATUS_NOT_LOADED);
             if (!mProgressAnimator.isStarted()) {
                 LogUtils.v(LOG_TAG, "progress animator: >> started");
                 // Reduce progress bar stutter caused by reset()/bind() being called multiple
@@ -983,6 +1079,7 @@
                     LogUtils.v(LOG_TAG, "progress animator: correction for dt %d, fraction %f",
                             dt, passedFraction);
                 }
+                removeCallbacks(mCancelProgressAnimatorRunnable);
                 mProgressAnimator.start();
                 // Wow.. this must be called after start().
                 mProgressAnimator.setCurrentPlayTime((long) (sProgressAnimationDuration * (
@@ -1013,12 +1110,12 @@
                 "loadAttachmentPreviews: <= onImageDrawn callback [%b] on index %d for %s", success,
                 index, key);
         // We want to hide the spinning progress bar when we draw something.
-        setImageLoaded(index,
+        onImageLoadStatusChanged(index,
                 success ? PhotoManager.STATUS_LOADED : PhotoManager.STATUS_NOT_LOADED);
 
         if (mProgressAnimator.isStarted() && areAllImagesLoaded()) {
-            LogUtils.v(LOG_TAG, "progress animator: << stopped");
-            mProgressAnimator.cancel();
+            removeCallbacks(mCancelProgressAnimatorRunnable);
+            postDelayed(mCancelProgressAnimatorRunnable, sFadeAnimationDuration);
         }
         Utils.traceEndSection();
     }
@@ -1034,12 +1131,12 @@
         LogUtils.v(LOG_TAG,
                 "loadAttachmentPreviews: <= onImageLoadStarted callback on index %d for %s", index,
                 key);
-        setImageLoaded(index, PhotoManager.STATUS_LOADING);
+        onImageLoadStatusChanged(index, PhotoManager.STATUS_LOADING);
     }
 
     private boolean areAllImagesLoaded() {
-        for (int i = 0; i < mImagesLoaded.length; i++) {
-            if (mImagesLoaded[i] != PhotoManager.STATUS_LOADED) {
+        for (int i = 0; i < mImageLoadStatuses.length; i++) {
+            if (mImageLoadStatuses[i] != PhotoManager.STATUS_LOADED) {
                 return false;
             }
         }
@@ -1047,44 +1144,60 @@
     }
 
     /**
-     * Update the #mImagesLoaded state array with special logic.
+     * Update the #mImageLoadStatuses state array with special logic.
      * @param index Which attachment preview's state to update.
      * @param status What the new state is.
      */
-    private void setImageLoaded(final int index, final int status) {
-        if (index < 0 || index >= mImagesLoaded.length) {
+    private void onImageLoadStatusChanged(final int index, final int status) {
+        if (index < 0 || index >= mImageLoadStatuses.length) {
             return;
         }
-        final int prevStatus = mImagesLoaded[index];
+        final int prevStatus = mImageLoadStatuses[index];
+        if (prevStatus == status) {
+            return;
+        }
+
+        boolean changed = false;
         switch (status) {
             case PhotoManager.STATUS_NOT_LOADED:
+                LogUtils.v(LOG_TAG, "progress bar: <<< set to false");
+                mShowProgressBar = false;
                 // Cannot transition directly from LOADING to NOT_LOADED.
                 if (prevStatus != PhotoManager.STATUS_LOADING) {
-                    mImagesLoaded[index] = status;
+                    mImageLoadStatuses[index] = status;
+                    changed = true;
                 }
                 break;
             case PhotoManager.STATUS_LOADING:
                 // All other statuses must be set to not loading.
-                for (int i = 0; i < mImagesLoaded.length; i++) {
-                    if (i != index && mImagesLoaded[i] == PhotoManager.STATUS_LOADING) {
-                        mImagesLoaded[i] = PhotoManager.STATUS_NOT_LOADED;
+                for (int i = 0; i < mImageLoadStatuses.length; i++) {
+                    if (i != index && mImageLoadStatuses[i] == PhotoManager.STATUS_LOADING) {
+                        mImageLoadStatuses[i] = PhotoManager.STATUS_NOT_LOADED;
                     }
                 }
-                mImagesLoaded[index] = status;
+                mImageLoadStatuses[index] = status;
 
-                if (prevStatus != PhotoManager.STATUS_LOADING) {
-                    // Progress bar should only be shown after a delay
-                    LogUtils.v(LOG_TAG, "progress bar: <<< set to false");
-                    mShowProgressBar = false;
-                    LogUtils.v(LOG_TAG, "progress bar: === start delay");
-                    removeCallbacks(mSetShowProgressBarRunnable);
-                    postDelayed(mSetShowProgressBarRunnable, sProgressAnimationDelay);
-                }
+                // Progress bar should only be shown after a delay
+                LogUtils.v(LOG_TAG, "progress bar: <<< set to false");
+                mShowProgressBar = false;
+                LogUtils.v(LOG_TAG, "progress bar: === start delay");
+                final Runnable setShowProgressBarRunnable = index == 0
+                        ? mSetShowProgressBarRunnable0 : mSetShowProgressBarRunnable1;
+                removeCallbacks(setShowProgressBarRunnable);
+                postDelayed(setShowProgressBarRunnable, sProgressAnimationDelay);
+                changed = true;
                 break;
             case PhotoManager.STATUS_LOADED:
-                mImagesLoaded[index] = status;
+                mImageLoadStatuses[index] = status;
+                changed = true;
                 break;
         }
+        if (changed) {
+            final ObjectAnimator fadeAnimator = index == 0 ? mFadeAnimator0 : mFadeAnimator1;
+            if (!fadeAnimator.isStarted()) {
+                fadeAnimator.start();
+            }
+        }
     }
 
     private static int makeExactSpecForSize(int size) {
@@ -1194,8 +1307,6 @@
         }
 
         // Second pass to layout each fragment.
-        int sendersY = mCoordinates.sendersY - mCoordinates.sendersAscent;
-
         sPaint.setTextSize(mCoordinates.sendersFontSize);
         sPaint.setTypeface(Typeface.DEFAULT);
 
@@ -1219,9 +1330,6 @@
                 totalWidth += senderFragment.width;
             }
 
-            if (!ConversationItemViewCoordinates.displaySendersInline(mCoordinates.getMode())) {
-                sendersY += totalWidth <= mSendersWidth ? mCoordinates.sendersLineHeight / 2 : 0;
-            }
             if (mSendersWidth < 0) {
                 mSendersWidth = 0;
             }
@@ -1440,7 +1548,7 @@
         // Contact photo
         if (mGadgetMode == ConversationItemViewCoordinates.GADGET_CONTACT_PHOTO) {
             canvas.save();
-            drawContactImages(canvas);
+            drawContactImageArea(canvas);
             canvas.restore();
         }
 
@@ -1515,9 +1623,12 @@
             canvas.drawBitmap(mHeader.paperclip, mPaperclipX, mCoordinates.paperclipY, sPaint);
         }
 
-        if (mStarEnabled) {
-            // Star.
-            canvas.drawBitmap(getStarBitmap(), mCoordinates.starX, mCoordinates.starY, sPaint);
+        if (mConversationListListener.isInSelectionMode()) {
+            drawStarPeekIcon(canvas, mConversationListListener.isEnteringSelectionMode(),
+                    false /* reverse */, PEEK);
+        } else if (mStarEnabled) {
+            drawStarPeekIcon(canvas, mConversationListListener.isExitingSelectionMode(),
+                    true /* reverse */, getStarBitmap());
         }
 
         // Attachment previews
@@ -1539,39 +1650,30 @@
                 drawText(canvas, mHeader.overflowText, mOverflowX, mOverflowY, sPaint);
             }
 
-            // Progress bar
-            if (mProgressAnimator.isRunning()) {
-                // Fade from 55 -> 255 -> 55. Each cycle lasts for #sProgressAnimationDuration secs.
-                final int maxAlpha = 255, minAlpha = 55;
-                final int range = maxAlpha - minAlpha;
-                // We want the placeholder to pulse at a different rate from the progressbar to
-                // spin.
-                final float placeholderAnimFraction = mAnimatedProgressFraction
-                        * sPlaceholderAnimationDurationRatio;
-                // During the time that placeholderAnimFraction takes to go from 0 to 1, we
-                // want to go all the way to #maxAlpha and back down to #minAlpha. So from 0 to 0.5,
-                // we increase #modifiedProgress from 0 to 1, while from 0.5 to 1 we decrease
-                // accordingly from 1 to 0. Math.
-                final float modifiedProgress = -2 * Math.abs(placeholderAnimFraction - 0.5f) + 1;
-                // Make it feel like a heart beat.
-                final float interpolatedProgress = sPulseAnimationInterpolator
-                        .getInterpolation(modifiedProgress);
-                // More math.
-                final int alpha = (int) (interpolatedProgress * range + minAlpha);
-                sPaint.setAlpha(alpha);
+            // Placeholders and progress bars
 
-                final int count = mImagesLoaded.length;
-                for (int i = 0; i < count; i++) {
-                    if (mShowProgressBar && mImagesLoaded[i] == PhotoManager.STATUS_LOADING) {
-                        // status is LOADING and enough time has passed
-                        canvas.save();
-                        drawProgressBar(canvas, i, count);
-                        canvas.restore();
-                    } else if (mImagesLoaded[i] != PhotoManager.STATUS_LOADED) {
-                        // status is either NOT_LOADED or LOADING
-                        drawPlaceholder(canvas, i, count);
-                    }
-                }
+            // Fade from 55 -> 255 -> 55. Each cycle lasts for #sProgressAnimationDuration secs.
+            final int maxAlpha = 255, minAlpha = 55;
+            final int range = maxAlpha - minAlpha;
+            // We want the placeholder to pulse at a different rate from the progressbar to
+            // spin.
+            final float placeholderAnimFraction = mAnimatedProgressFraction
+                    * sPlaceholderAnimationDurationRatio;
+            // During the time that placeholderAnimFraction takes to go from 0 to 1, we
+            // want to go all the way to #maxAlpha and back down to #minAlpha. So from 0 to 0.5,
+            // we increase #modifiedProgress from 0 to 1, while from 0.5 to 1 we decrease
+            // accordingly from 1 to 0. Math.
+            final float modifiedProgress = -2 * Math.abs(placeholderAnimFraction - 0.5f) + 1;
+            // Make it feel like a heart beat.
+            final float interpolatedProgress = sPulseAnimationInterpolator
+                    .getInterpolation(modifiedProgress);
+            // More math.
+            final int pulseAlpha = (int) (interpolatedProgress * range + minAlpha);
+
+            final int count = mImageLoadStatuses.length;
+            for (int i = 0; i < count; i++) {
+                drawPlaceholder(canvas, i, count, pulseAlpha);
+                drawProgressBar(canvas, i, count);
             }
         }
 
@@ -1592,9 +1694,146 @@
         Utils.traceEndSection();
     }
 
-    private void drawContactImages(Canvas canvas) {
+    private void drawStarPeekIcon(final Canvas canvas, final boolean animate, final boolean reverse,
+            final Bitmap staticIcon) {
+        if (animate) {
+            // Animate the peek icon
+            if (!mPeekIconFlipAnimator.isStarted()) {
+                mPeekIconFlipAnimator.startAnimation(reverse);
+            }
+
+            canvas.save();
+
+            final float value = mPeekIconFlipAnimator.getValue();
+            final float scale;
+            final Bitmap bitmap;
+
+            if (value > 1) {
+                // Flip in the peek icon
+                scale = value - 1f;
+                bitmap = PEEK;
+            } else {
+                // Flip out the star icon
+                scale = 1f - value;
+                bitmap = getStarBitmap();
+            }
+
+            final float yOffset = mCoordinates.starHeight * (1f - scale) / 2f;
+
+            mPeekIconFlipMatrix.reset();
+            mPeekIconFlipMatrix.postScale(1, scale);
+
+            canvas.translate(mCoordinates.starX, mCoordinates.starY + yOffset);
+
+            canvas.drawBitmap(bitmap, mPeekIconFlipMatrix, sPaint);
+
+            canvas.restore();
+        } else {
+            mPeekIconFlipAnimator.stopAnimation();
+
+            // Star/Peek icon
+            canvas.drawBitmap(staticIcon, mCoordinates.starX, mCoordinates.starY, sPaint);
+        }
+    }
+
+    /**
+     * Draws the contact images or check, in the correct animated state.
+     */
+    private void drawContactImageArea(final Canvas canvas) {
+        if (isSelected()) {
+            mLastSelectedId = mHeader.conversation.id;
+
+            // Since this is selected, we draw the checkbox if the animation is not running, or if
+            // it's running, and is past the half-way point
+            if (mPhotoFlipAnimator.getValue() > 1 || !mPhotoFlipAnimator.isStarted()) {
+                // Flash in the check
+                drawCheckbox(canvas);
+            } else {
+                // Flip out the contact photo
+                drawContactImages(canvas);
+            }
+        } else {
+            if ((mConversationListListener.isExitingSelectionMode()
+                    && mLastSelectedId == mHeader.conversation.id)
+                    || mPhotoFlipAnimator.isStarted()) {
+                // Animate back to the photo
+                if (!mPhotoFlipAnimator.isStarted()) {
+                    mPhotoFlipAnimator.startAnimation(true /* reverse */);
+                }
+
+                if (mPhotoFlipAnimator.getValue() > 1) {
+                    // Flash out the check
+                    drawCheckbox(canvas);
+                } else {
+                    // Flip in the contact photo
+                    drawContactImages(canvas);
+                }
+            } else {
+                mLastSelectedId = -1; // We don't care anymore
+                mPhotoFlipAnimator.stopAnimation(); // It's not running, but we want to reset state
+
+                // Contact photos
+                drawContactImages(canvas);
+            }
+        }
+    }
+
+    private void drawContactImages(final Canvas canvas) {
+        // mPhotoFlipFraction goes from 0 to 1
+        final float value = mPhotoFlipAnimator.getValue();
+
+        final float scale = 1f - value;
+        final float xOffset = mContactImagesHolder.getWidth() * value / 2;
+
+        mPhotoFlipMatrix.reset();
+        mPhotoFlipMatrix.postScale(scale, 1);
+
+        canvas.translate(mCoordinates.contactImagesX + xOffset, mCoordinates.contactImagesY);
+
+        mContactImagesHolder.draw(canvas, mPhotoFlipMatrix);
+    }
+
+    private void drawCheckbox(final Canvas canvas) {
+        // mPhotoFlipFraction goes from 1 to 2
+
+        // Draw the background
+        canvas.save();
         canvas.translate(mCoordinates.contactImagesX, mCoordinates.contactImagesY);
-        mContactImagesHolder.draw(canvas);
+        canvas.drawRect(0, 0, mCoordinates.contactImagesWidth, mCoordinates.contactImagesHeight,
+                sCheckBackgroundPaint);
+        canvas.restore();
+
+        final int x = mCoordinates.contactImagesX
+                + (mCoordinates.contactImagesWidth - CHECK.getWidth()) / 2;
+        final int y = mCoordinates.contactImagesY
+                + (mCoordinates.contactImagesHeight - CHECK.getHeight()) / 2;
+
+        final float value = mPhotoFlipAnimator.getValue();
+        final float scale;
+
+        if (!mPhotoFlipAnimator.isStarted()) {
+            // We're not animating
+            scale = 1;
+        } else if (value < 1.9) {
+            // 1.0 to 1.9 will scale 0 to 1
+            scale = (value - 1f) / 0.9f;
+        } else if (value < 1.95) {
+            // 1.9 to 1.95 will scale 1 to 19/18
+            scale = (value - 1f) / 0.9f;
+        } else {
+            // 1.95 to 2.0 will scale 19/18 to 1
+            scale = (0.95f - (value - 1.95f)) / 0.9f;
+        }
+
+        final float xOffset = CHECK.getWidth() * (1f - scale) / 2f;
+        final float yOffset = CHECK.getHeight() * (1f - scale) / 2f;
+
+        mCheckMatrix.reset();
+        mCheckMatrix.postScale(scale, scale);
+
+        canvas.translate(x + xOffset, y + yOffset);
+
+        canvas.drawBitmap(CHECK, mCheckMatrix, sPaint);
     }
 
     private void drawAttachmentPreviews(Canvas canvas) {
@@ -1614,16 +1853,47 @@
 
     /**
      * Draws the specified placeholder on the canvas.
+     *
      * @param canvas The canvas to draw on.
-     * @param index If drawing multiple progress bars, this determines which one we are drawing.
-     * @param total Whether we are drawing multiple progress bars.
+     * @param index  If drawing multiple placeholders, this determines which one we are drawing.
+     * @param total  Whether we are drawing multiple placeholders.
+     * @param pulseAlpha The alpha to draw this at.
      */
-    private void drawPlaceholder(Canvas canvas, int index, int total) {
-        int placeholderX = getPlaceholderX(index, total);
+    private void drawPlaceholder(final Canvas canvas, final int index, final int total,
+            final int pulseAlpha) {
+        final int placeholderX = getAttachmentPreviewXCenter(index, total)
+                - mCoordinates.placeholderWidth / 2;
         if (placeholderX == -1) {
             return;
         }
 
+        // Set alpha for crossfading effect.
+        final ObjectAnimator fadeAnimator = index == 0 ? mFadeAnimator0 : mFadeAnimator1;
+        final float animatedFadeFraction = index == 0 ? mAnimatedFadeFraction0
+                : mAnimatedFadeFraction1;
+        final boolean notLoaded = mImageLoadStatuses[index] == PhotoManager.STATUS_NOT_LOADED;
+        final boolean loading = mImageLoadStatuses[index] == PhotoManager.STATUS_LOADING;
+        final boolean loaded = mImageLoadStatuses[index] == PhotoManager.STATUS_LOADED;
+        final float fadeAlphaFraction;
+        if (notLoaded) {
+            fadeAlphaFraction = 1.0f;
+        } else if (loading && !mShowProgressBar) {
+            fadeAlphaFraction = 1.0f;
+        } else if (fadeAnimator.isStarted() && (loading && mShowProgressBar
+                || loaded && !mShowProgressBar)) {
+            // Fade to progress bar or fade to image from placeholder
+            fadeAlphaFraction = 1.0f - animatedFadeFraction;
+        } else {
+            fadeAlphaFraction = 0.0f;
+        }
+
+        if (fadeAlphaFraction == 0.0f) {
+            return;
+        }
+        // Draw background
+        drawAttachmentPreviewBackground(canvas, index, total, (int) (255 * fadeAlphaFraction));
+
+        sPaint.setAlpha((int) (pulseAlpha * fadeAlphaFraction));
         canvas.drawBitmap(PLACEHOLDER, placeholderX, mCoordinates.placeholderY, sPaint);
     }
 
@@ -1633,62 +1903,114 @@
      * @param index If drawing multiple progress bars, this determines which one we are drawing.
      * @param total Whether we are drawing multiple progress bars.
      */
-    private void drawProgressBar(Canvas canvas, int index, int total) {
-        int progressBarX = getProgressBarX(index, total);
+    private void drawProgressBar(final Canvas canvas, final int index, final int total) {
+        final int progressBarX = getAttachmentPreviewXCenter(index, total)
+                - mCoordinates.progressBarWidth / 2;
         if (progressBarX == -1) {
             return;
         }
 
+        // Set alpha for crossfading effect.
+        final ObjectAnimator fadeAnimator = index == 0 ? mFadeAnimator0 : mFadeAnimator1;
+        final float animatedFadeFraction = index == 0 ? mAnimatedFadeFraction0
+                : mAnimatedFadeFraction1;
+        final boolean loading = mImageLoadStatuses[index] == PhotoManager.STATUS_LOADING;
+        final boolean loaded = mImageLoadStatuses[index] == PhotoManager.STATUS_LOADED;
+        final int fadeAlpha;
+        if (loading && mShowProgressBar) {
+            fadeAlpha = (int) (255 * animatedFadeFraction);
+        } else if (fadeAnimator.isStarted() && (loaded && mShowProgressBar)) {
+            // Fade to image from progress bar
+            fadeAlpha = (int) (255 * (1.0f - animatedFadeFraction));
+        } else {
+            fadeAlpha = 0;
+        }
+
+        if (fadeAlpha == 0) {
+            return;
+        }
+
+        // Draw background
+        drawAttachmentPreviewBackground(canvas, index, total, fadeAlpha);
+
         // Set the level from 0 to 10000 to animate the Drawable.
         PROGRESS_BAR.setLevel((int) (mAnimatedProgressFraction * 10000));
         // canvas.translate() for Bitmaps, setBounds() for Drawables.
         PROGRESS_BAR.setBounds(progressBarX, mCoordinates.progressBarY,
                 progressBarX + mCoordinates.progressBarWidth,
                 mCoordinates.progressBarY + mCoordinates.progressBarHeight);
+        PROGRESS_BAR.setAlpha(fadeAlpha);
         PROGRESS_BAR.draw(canvas);
     }
-
     /**
-     * @see com.android.mail.browse.ConversationItemView#drawProgressBar
+     * Draws the specified attachment previews background on the canvas.
+     * @param canvas The canvas to draw on.
+     * @param index If drawing for multiple attachment previews, this determines for which one's
+     *              background we are drawing.
+     * @param total Whether we are drawing for multiple attachment previews.
+     * @param fadeAlpha The alpha to draw this at.
      */
-    private void invalidatePlaceholderAndProgressBar(int index, int total) {
-        int progressBarX = getProgressBarX(index, total);
-        if (progressBarX == -1) {
+    private void drawAttachmentPreviewBackground(final Canvas canvas, final int index,
+            final int total, final int fadeAlpha) {
+        if (total == 0) {
             return;
         }
-
-        invalidate(progressBarX, mCoordinates.progressBarY,
-                progressBarX + mCoordinates.progressBarWidth,
-                mCoordinates.progressBarY + mCoordinates.progressBarHeight);
-
-        int placeholderX = getPlaceholderX(index, total);
-        if (placeholderX == -1) {
-            return;
-        }
-
-        invalidate(placeholderX, mCoordinates.placeholderY,
-                placeholderX + mCoordinates.placeholderWidth,
-                mCoordinates.placeholderY + mCoordinates.placeholderHeight);
+        final int sectionWidth = mCoordinates.attachmentPreviewsWidth / total;
+        final int sectionX = getAttachmentPreviewX(index, total);
+        sPaint.setColor(sAttachmentPreviewsBackgroundColor);
+        sPaint.setAlpha(fadeAlpha);
+        canvas.drawRect(sectionX, mCoordinates.attachmentPreviewsY, sectionX + sectionWidth,
+                mCoordinates.attachmentPreviewsY + mCoordinates.attachmentPreviewsHeight, sPaint);
     }
 
-    private int getPlaceholderX(int index, int total) {
-        if (mCoordinates == null) {
-            return -1;
+    private void invalidateAttachmentPreviews() {
+        final int total = mImageLoadStatuses.length;
+        for (int index = 0; index < total; index++) {
+            invalidateAttachmentPreview(index, total);
         }
-        int sectionWidth = mCoordinates.attachmentPreviewsWidth / total;
-        int sectionOffset = index * sectionWidth;
-        return mCoordinates.attachmentPreviewsX + sectionOffset + sectionWidth / 2
-                - mCoordinates.placeholderWidth / 2;
     }
 
-    private int getProgressBarX(int index, int total) {
-        if (mCoordinates == null) {
+    private void invalidatePlaceholdersAndProgressBars() {
+        final int total = mImageLoadStatuses.length;
+        for (int index = 0; index < total; index++) {
+            invalidatePlaceholderAndProgressBar(index, total);
+        }
+    }
+
+    private void invalidateAttachmentPreview(final int index, final int total) {
+        invalidate(getAttachmentPreviewX(index, total), mCoordinates.attachmentPreviewsY,
+                getAttachmentPreviewX(index + 1, total),
+                mCoordinates.attachmentPreviewsY + mCoordinates.attachmentPreviewsHeight);
+    }
+
+    private void invalidatePlaceholderAndProgressBar(final int index, final int total) {
+        final int width = Math.max(mCoordinates.placeholderWidth, mCoordinates.progressBarWidth);
+        final int height = Math.max(mCoordinates.placeholderHeight, mCoordinates.progressBarHeight);
+        final int x = getAttachmentPreviewXCenter(index, total) - width / 2;
+        final int xEnd = getAttachmentPreviewXCenter(index, total) + width / 2;
+        final int yCenter = mCoordinates.attachmentPreviewsY
+                + mCoordinates.attachmentPreviewsHeight / 2;
+        final int y = yCenter - height / 2;
+        final int yEnd = yCenter + height / 2;
+
+        invalidate(x, y, xEnd, yEnd);
+    }
+
+    private int getAttachmentPreviewX(final int index, final int total) {
+        if (mCoordinates == null || total == 0) {
             return -1;
         }
-        int sectionWidth = mCoordinates.attachmentPreviewsWidth / total;
-        int sectionOffset = index * sectionWidth;
-        return mCoordinates.attachmentPreviewsX + sectionOffset + sectionWidth / 2
-                - mCoordinates.progressBarWidth / 2;
+        final int sectionWidth = mCoordinates.attachmentPreviewsWidth / total;
+        final int sectionOffset = index * sectionWidth;
+        return mCoordinates.attachmentPreviewsX + sectionOffset;
+    }
+
+    private int getAttachmentPreviewXCenter(final int index, final int total) {
+        if (total == 0) {
+            return -1;
+        }
+        final int sectionWidth = mCoordinates.attachmentPreviewsWidth / total;
+        return getAttachmentPreviewX(index, total) + sectionWidth / 2;
     }
 
     private Bitmap getStarBitmap() {
@@ -1747,6 +2069,11 @@
             if (mSelectedConversationSet.isEmpty()) {
                 listView.commitDestructiveActions(true);
             }
+
+            final boolean reverse = !mSelected;
+            mPhotoFlipAnimator.startAnimation(reverse);
+            mPhotoFlipAnimator.invalidateArea();
+
             // We update the background after the checked state has changed
             // now that we have a selected background asset. Setting the background
             // usually waits for a layout pass, but we don't need a full layout,
@@ -1771,16 +2098,11 @@
         }
     }
 
-    public void viewAttachmentPreview(final int index) {
-        final String attachmentUri = mHeader.conversation.getAttachmentPreviewUris().get(index);
-        final Uri imageListUri = mHeader.conversation.attachmentPreviewsListUri;
-        LogUtils.d(LOG_TAG,
-                "ConversationItemView: tapped on attachment preview %d, "
-                        + "opening photoviewer for image list uri %s",
-                index, imageListUri);
-        MailPhotoViewActivity
-                .startMailPhotoViewActivity(mActivity.getActivityContext(), imageListUri,
-                        attachmentUri);
+    /**
+     * Peek into the conversation.
+     */
+    private void peek() {
+        mConversationListListener.viewConversation(mAdapterPosition);
     }
 
     private boolean isTouchInContactPhoto(float x, float y) {
@@ -1798,29 +2120,6 @@
                 && (!isAttachmentPreviewsEnabled() || y < mCoordinates.attachmentPreviewsY);
     }
 
-    /**
-     * If the touch is in the attachment previews, return the index of the attachment under that
-     * point (for multiple previews). Return -1 if the touch is outside of the previews.
-     *
-     * @return The index corresponding to where the attachment appears on the screen. This index
-     * may not be the same as the attachment's actual index in the message.
-     */
-    private int getAttachmentPreviewsIndexForTouch(float x, float y) {
-        if (!isAttachmentPreviewsEnabled()) {
-            return -1;
-        }
-        if (y > mCoordinates.attachmentPreviewsY
-                && y < mCoordinates.attachmentPreviewsY + mCoordinates.attachmentPreviewsHeight
-                && x > mCoordinates.attachmentPreviewsX
-                && x < mCoordinates.attachmentPreviewsX + mCoordinates.attachmentPreviewsWidth) {
-            int eachWidth = mCoordinates.attachmentPreviewsWidth / mHeader.conversation
-                    .getAttachmentPreviewUris().size();
-            int offset = (int) (x - mCoordinates.attachmentPreviewsX);
-            return offset / eachWidth;
-        }
-        return -1;
-    }
-
     @Override
     public boolean canChildBeDismissed() {
         return true;
@@ -1844,8 +2143,7 @@
         mLastTouchY = y;
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
-                if (isTouchInContactPhoto(x, y) || isTouchInStar(x, y)
-                        || getAttachmentPreviewsIndexForTouch(x, y) > -1) {
+                if (isTouchInContactPhoto(x, y) || isTouchInStar(x, y)) {
                     mDownEvent = true;
                     handled = true;
                 }
@@ -1857,16 +2155,17 @@
 
             case MotionEvent.ACTION_UP:
                 if (mDownEvent) {
-                    int index;
                     if (isTouchInContactPhoto(x, y)) {
                         // Touch on the check mark
                         toggleSelectedState();
                     } else if (isTouchInStar(x, y)) {
-                        // Touch on the star
-                        toggleStar();
-                    } else if ((index = getAttachmentPreviewsIndexForTouch(x, y)) > -1) {
-                        // Touch on an attachment preview
-                        viewAttachmentPreview(index);
+                        // Touch on the star/peek
+                        if (mConversationListListener.isInSelectionMode()) {
+                            // Peek
+                            peek();
+                        } else {
+                            toggleStar();
+                        }
                     }
                     handled = true;
                 }
@@ -1897,8 +2196,7 @@
         }
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
-                if (isTouchInContactPhoto(x, y) || isTouchInStar(x, y)
-                        || getAttachmentPreviewsIndexForTouch(x, y) > -1) {
+                if (isTouchInContactPhoto(x, y) || isTouchInStar(x, y)) {
                     mDownEvent = true;
                     Utils.traceEndSection();
                     return true;
@@ -1906,7 +2204,6 @@
                 break;
             case MotionEvent.ACTION_UP:
                 if (mDownEvent) {
-                    int index;
                     if (isTouchInContactPhoto(x, y)) {
                         // Touch on the check mark
                         Utils.traceEndSection();
@@ -1915,15 +2212,14 @@
                         Utils.traceEndSection();
                         return true;
                     } else if (isTouchInStar(x, y)) {
-                        // Touch on the star
+                        // Touch on the star/peek
                         mDownEvent = false;
-                        toggleStar();
-                        Utils.traceEndSection();
-                        return true;
-                    } else if ((index = getAttachmentPreviewsIndexForTouch(x, y)) > -1) {
-                        // Touch on an attachment preview
-                        mDownEvent = false;
-                        viewAttachmentPreview(index);
+                        if (mConversationListListener.isInSelectionMode()) {
+                            // Peek
+                            peek();
+                        } else {
+                            toggleStar();
+                        }
                         Utils.traceEndSection();
                         return true;
                     }
@@ -1970,8 +2266,8 @@
         setTranslationX(0f);
         mAnimatedHeightFraction = 1.0f;
         if (mProgressAnimator.isStarted()) {
-            LogUtils.v(LOG_TAG, "progress animator: << stopped");
-            mProgressAnimator.cancel();
+            removeCallbacks(mCancelProgressAnimatorRunnable);
+            postDelayed(mCancelProgressAnimatorRunnable, sFadeAnimationDuration);
         }
         Utils.traceEndSection();
     }
@@ -2068,7 +2364,7 @@
 
     private ObjectAnimator createProgressAnimator() {
         final ObjectAnimator animator = ObjectAnimator
-                .ofFloat(this, "animatedProgressFraction", 0f, 1.0f).setDuration(
+                .ofFloat(this, "animatedProgressFraction", 0.0f, 1.0f).setDuration(
                         sProgressAnimationDuration);
         animator.setInterpolator(new LinearInterpolator());
         animator.setRepeatCount(ObjectAnimator.INFINITE);
@@ -2086,10 +2382,27 @@
             }
 
             private void invalidateAll() {
-                final int count = mHeader.conversation.getAttachmentPreviewUris().size();
-                for (int i = 0; i < count; i++) {
-                    invalidatePlaceholderAndProgressBar(i, count);
-                }
+                invalidatePlaceholdersAndProgressBars();
+            }
+        });
+        return animator;
+    }
+
+    private ObjectAnimator createFadeAnimator(final int index) {
+        final ObjectAnimator animator = ObjectAnimator
+                .ofFloat(this, "animatedFadeFraction" + index, 0.0f, 1.0f).setDuration(
+                        sFadeAnimationDuration);
+        animator.setInterpolator(new DecelerateInterpolator());
+        animator.setRepeatCount(0);
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(final Animator animation) {
+                invalidateAttachmentPreview(index, mImageLoadStatuses.length);
+            }
+
+            @Override
+            public void onAnimationCancel(final Animator animation) {
+                invalidateAttachmentPreview(index, mImageLoadStatuses.length);
             }
         });
         return animator;
@@ -2102,12 +2415,19 @@
             return;
         }
         mAnimatedProgressFraction = fraction;
-        final int count = mImagesLoaded.length;
-        for (int i = 0; i < count; i++) {
-            if (mImagesLoaded[i] != PhotoManager.STATUS_LOADED) {
-                invalidatePlaceholderAndProgressBar(i, count);
-            }
-        }
+        invalidatePlaceholdersAndProgressBars();
+    }
+
+    // Used by animator
+    public void setAnimatedFadeFraction0(final float fraction) {
+        mAnimatedFadeFraction0 = fraction;
+        invalidateAttachmentPreview(0, mImageLoadStatuses.length);
+    }
+
+    // Used by animator
+    public void setAnimatedFadeFraction1(final float fraction) {
+        mAnimatedFadeFraction1 = fraction;
+        invalidateAttachmentPreview(1, mImageLoadStatuses.length);
     }
 
     @Override
@@ -2187,11 +2507,12 @@
 
         @Override
         public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
-            int width = mView.getWidth();
-            int height = mView.getHeight();
+            final int width = mView.getWidth();
+            final int height = mView.getHeight();
+
+            sPaint.setTextSize(mCoordinates.subjectFontSize);
             mDragDescX = mCoordinates.sendersX;
-            mDragDescY = getPadding(height, (int) mCoordinates.subjectFontSize)
-                    - mCoordinates.subjectAscent;
+            mDragDescY = (height - (int) mCoordinates.subjectFontSize) / 2 ;
             shadowSize.set(width, height);
             shadowTouchPoint.set(mTouchX, mTouchY);
         }
@@ -2201,7 +2522,7 @@
             mBackground.setBounds(0, 0, mView.getWidth(), mView.getHeight());
             mBackground.draw(canvas);
             sPaint.setTextSize(mCoordinates.subjectFontSize);
-            canvas.drawText(mDragDesc, mDragDescX, mDragDescY, sPaint);
+            canvas.drawText(mDragDesc, mDragDescX, mDragDescY - sPaint.ascent(), sPaint);
         }
     }
 
@@ -2209,4 +2530,111 @@
     public float getMinAllowScrollDistance() {
         return sScrollSlop;
     }
+
+    private abstract class CabAnimator {
+        private ObjectAnimator mAnimator = null;
+
+        private final String mPropertyName;
+
+        private float mValue;
+
+        private final float mStartValue;
+        private final float mEndValue;
+
+        private final long mDuration;
+
+        public CabAnimator(final String propertyName, final float startValue, final float endValue,
+                final long duration) {
+            mPropertyName = propertyName;
+
+            mStartValue = startValue;
+            mEndValue = endValue;
+
+            mDuration = duration;
+        }
+
+        private ObjectAnimator createAnimator() {
+            final ObjectAnimator animator = ObjectAnimator.ofFloat(ConversationItemView.this,
+                    mPropertyName, mStartValue, mEndValue);
+            animator.setDuration(mDuration);
+            animator.setInterpolator(new LinearInterpolator());
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(final Animator animation) {
+                    invalidateArea();
+                }
+            });
+            return animator;
+        }
+
+        public abstract void invalidateArea();
+
+        public void setValue(final float fraction) {
+            mValue = fraction;
+            invalidateArea();
+        }
+
+        public float getValue() {
+            return mValue;
+        }
+
+        /**
+         * @param reverse <code>true</code> to animate in reverse
+         */
+        public void startAnimation(final boolean reverse) {
+            if (mAnimator != null) {
+                mAnimator.cancel();
+            }
+
+            mAnimator = createAnimator();
+
+            if (reverse) {
+                mAnimator.reverse();
+            } else {
+                mAnimator.start();
+            }
+        }
+
+        public void stopAnimation() {
+            if (mAnimator != null) {
+                mAnimator.cancel();
+                mAnimator = null;
+            }
+
+            setValue(0);
+        }
+
+        public boolean isStarted() {
+            return mAnimator != null && mAnimator.isStarted();
+        }
+    }
+
+    public void setPhotoFlipFraction(final float fraction) {
+        mPhotoFlipAnimator.setValue(fraction);
+    }
+
+    public void setPeekIconFlipFraction(final float fraction) {
+        mPeekIconFlipAnimator.setValue(fraction);
+    }
+
+    private final ConversationSetObserver mConversationSetObserver = new ConversationSetObserver() {
+        @Override
+        public void onSetPopulated(final ConversationSelectionSet set) {
+            // Animate the peek icon in
+            // This will trigger a draw, which will start an animation
+            mPeekIconFlipAnimator.invalidateArea();
+        }
+
+        @Override
+        public void onSetEmpty() {
+            // Animate the peek icon out
+            // This will trigger a draw, which will start an animation
+            mPeekIconFlipAnimator.invalidateArea();
+        }
+
+        @Override
+        public void onSetChanged(final ConversationSelectionSet set) {
+            // Don't do anything
+        }
+    };
 }
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index 543f636..00322db 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -169,14 +169,11 @@
 
     final int height;
 
-    // Checkmark.
-    final int checkmarkX;
-    final int checkmarkY;
-
     // Star.
     final int starX;
     final int starY;
     final int starWidth;
+    final int starHeight;
 
     // Senders.
     final int sendersX;
@@ -186,7 +183,6 @@
     final int sendersLineCount;
     final int sendersLineHeight;
     final float sendersFontSize;
-    final int sendersAscent;
 
     // Subject.
     final int subjectX;
@@ -195,7 +191,6 @@
     final int subjectHeight;
     final int subjectLineCount;
     final float subjectFontSize;
-    final int subjectAscent;
 
     // Folders.
     final int foldersX;
@@ -204,7 +199,6 @@
     final int foldersHeight;
     final Typeface foldersTypeface;
     final float foldersFontSize;
-    final int foldersAscent;
     final int foldersTextBottomPadding;
 
     // Date.
@@ -212,7 +206,6 @@
     final int dateY;
     final int datePaddingLeft;
     final float dateFontSize;
-    final int dateAscent;
     final int dateYBaseline;
 
     // Paperclip.
@@ -317,24 +310,18 @@
                         : View.GONE);
 
         View contactImagesView = view.findViewById(R.id.contact_image);
-        View checkmark = view.findViewById(R.id.checkmark);
 
         switch (config.getGadgetMode()) {
             case GADGET_CONTACT_PHOTO:
                 contactImagesView.setVisibility(View.VISIBLE);
-                checkmark.setVisibility(View.GONE);
-                checkmark = null;
                 break;
             case GADGET_CHECKBOX:
                 contactImagesView.setVisibility(View.GONE);
-                checkmark.setVisibility(View.VISIBLE);
                 contactImagesView = null;
                 break;
             default:
                 contactImagesView.setVisibility(View.GONE);
-                checkmark.setVisibility(View.GONE);
                 contactImagesView = null;
-                checkmark = null;
                 break;
         }
 
@@ -355,12 +342,6 @@
 //        Utils.dumpViewTree((ViewGroup) view);
 
         // Records coordinates.
-        if (checkmark != null) {
-            checkmarkX = getX(checkmark);
-            checkmarkY = getY(checkmark);
-        } else {
-            checkmarkX = checkmarkY = 0;
-        }
 
         // Contact images view
         if (contactImagesView != null) {
@@ -376,6 +357,7 @@
         starX = getX(star);
         starY = getY(star);
         starWidth = star.getWidth();
+        starHeight = star.getHeight();
 
         final TextView senders = (TextView) view.findViewById(R.id.senders);
         final int sendersTopAdjust = getLatinTopAdjustment(senders);
@@ -386,7 +368,6 @@
         sendersLineCount = getLineCount(senders);
         sendersLineHeight = senders.getLineHeight();
         sendersFontSize = senders.getTextSize();
-        sendersAscent = (int) senders.getPaint().ascent();
 
         final TextView subject = (TextView) view.findViewById(R.id.subject);
         final int subjectTopAdjust = getLatinTopAdjustment(subject);
@@ -400,7 +381,6 @@
         subjectHeight = subject.getHeight();
         subjectLineCount = getLineCount(subject);
         subjectFontSize = subject.getTextSize();
-        subjectAscent = (int) subject.getPaint().ascent();
 
         if (config.areFoldersVisible()) {
             // vertically align folders min left edge with subject
@@ -416,7 +396,6 @@
             foldersTextBottomPadding = res
                     .getDimensionPixelSize(R.dimen.folders_text_bottom_padding);
             foldersFontSize = folders.getTextSize();
-            foldersAscent = (int) folders.getPaint().ascent();
         } else {
             foldersX = 0;
             foldersXEnd = 0;
@@ -425,7 +404,6 @@
             foldersTypeface = null;
             foldersTextBottomPadding = 0;
             foldersFontSize = 0;
-            foldersAscent = 0;
         }
 
         final View colorBlock = view.findViewById(R.id.color_block);
@@ -458,29 +436,21 @@
         datePaddingLeft = date.getPaddingLeft();
         dateFontSize = date.getTextSize();
         dateYBaseline = dateY + getLatinTopAdjustment(date) + date.getBaseline();
-        dateAscent = (int) date.getPaint().ascent();
 
         final View paperclip = view.findViewById(R.id.paperclip);
         paperclipY = getY(paperclip);
         paperclipPaddingLeft = paperclip.getPaddingLeft();
 
         if (attachmentPreviews != null) {
-            attachmentPreviewsX = getAttachmentPreviewsX(attachmentPreviews,
-                    config.mAttachmentPreviewMode);
+            attachmentPreviewsX = subjectX;
             attachmentPreviewsY = getY(attachmentPreviews) + sendersTopAdjust;
-            final int attachmentPreviewsXEnd;
-            if (isWide()) {
-                attachmentPreviewsXEnd = subjectX + subjectWidth;
-            } else {
-                attachmentPreviewsXEnd = starX + starWidth;
-            }
-
-            attachmentPreviewsWidth = attachmentPreviewsXEnd - attachmentPreviewsX;
+            attachmentPreviewsWidth = subjectWidth;
             attachmentPreviewsHeight = attachmentPreviews.getHeight();
 
             // We only care about the right and bottom of the overflow count
             final TextView overflow = (TextView) view.findViewById(id.ap_overflow);
-            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) overflow.getLayoutParams();
+            final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) overflow
+                    .getLayoutParams();
             overflowXEnd = attachmentPreviewsX + attachmentPreviewsWidth - params.rightMargin;
             overflowYEnd = attachmentPreviewsY + attachmentPreviewsHeight - params.bottomMargin;
             overflowDiameter = overflow.getWidth();
@@ -558,15 +528,9 @@
         }
     }
 
-    private int getAttachmentPreviewsX(View attachmentPreviews, int attachmentPreviewMode) {
-        if (isWide() || attachmentPreviewMode == ATTACHMENT_PREVIEW_READ) {
-            return subjectX;
-        }
-        return getX(attachmentPreviews);
-    }
-
-    private int getAttachmentPreviewsHeight(Context context, int attachmentPreviewMode) {
-        Resources res = context.getResources();
+    private int getAttachmentPreviewsHeight(final Context context,
+            final int attachmentPreviewMode) {
+        final Resources res = context.getResources();
         switch (attachmentPreviewMode) {
             case ATTACHMENT_PREVIEW_UNREAD:
                 return (int) (isWide() ? res.getDimension(dimen.attachment_preview_height_tall_wide)
@@ -585,8 +549,7 @@
         int x = 0;
         while (view != null) {
             x += (int) view.getX();
-            ViewParent parent = view.getParent();
-            view = parent != null ? (View) parent : null;
+            view = (View) view.getParent();
         }
         return x;
     }
@@ -598,8 +561,7 @@
         int y = 0;
         while (view != null) {
             y += (int) view.getY();
-            ViewParent parent = view.getParent();
-            view = parent != null ? (View) parent : null;
+            view = (View) view.getParent();
         }
         return y;
     }
diff --git a/src/com/android/mail/browse/ConversationItemViewModel.java b/src/com/android/mail/browse/ConversationItemViewModel.java
index ad6c0d8..10a0b6c 100644
--- a/src/com/android/mail/browse/ConversationItemViewModel.java
+++ b/src/com/android/mail/browse/ConversationItemViewModel.java
@@ -19,7 +19,6 @@
 
 import android.content.Context;
 import android.graphics.Bitmap;
-import android.net.Uri;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.StaticLayout;
@@ -34,6 +33,7 @@
 import com.android.mail.providers.Folder;
 import com.android.mail.providers.MessageInfo;
 import com.android.mail.providers.UIProvider;
+import com.android.mail.utils.FolderUri;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
@@ -360,8 +360,9 @@
      * Clear cached header model objects when the folder changes.
      */
     public static void onFolderUpdated(Folder folder) {
-        Uri old = sCachedModelsFolder != null ? sCachedModelsFolder.uri : Uri.EMPTY;
-        Uri newUri = folder != null ? folder.uri : Uri.EMPTY;
+        final FolderUri old = sCachedModelsFolder != null
+                ? sCachedModelsFolder.folderUri : FolderUri.EMPTY;
+        final FolderUri newUri = folder != null ? folder.folderUri : FolderUri.EMPTY;
         if (!old.equals(newUri)) {
             sCachedModelsFolder = folder;
             sConversationHeaderMap.evictAll();
diff --git a/src/com/android/mail/browse/ConversationViewAdapter.java b/src/com/android/mail/browse/ConversationViewAdapter.java
index 9f278ab..9f59f8c 100644
--- a/src/com/android/mail/browse/ConversationViewAdapter.java
+++ b/src/com/android/mail/browse/ConversationViewAdapter.java
@@ -29,6 +29,7 @@
 import com.android.mail.ContactInfoSource;
 import com.android.mail.FormattedDateBuilder;
 import com.android.mail.R;
+import com.android.mail.ads.AdHeaderView;
 import com.android.mail.browse.ConversationViewHeader.ConversationViewHeaderCallbacks;
 import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
 import com.android.mail.browse.SuperCollapsedBlock.OnClickListener;
@@ -74,10 +75,12 @@
     private final VeiledAddressMatcher mMatcher;
 
     public static final int VIEW_TYPE_CONVERSATION_HEADER = 0;
-    public static final int VIEW_TYPE_MESSAGE_HEADER = 1;
-    public static final int VIEW_TYPE_MESSAGE_FOOTER = 2;
-    public static final int VIEW_TYPE_SUPER_COLLAPSED_BLOCK = 3;
-    public static final int VIEW_TYPE_COUNT = 4;
+    public static final int VIEW_TYPE_AD_HEADER = 1;
+    public static final int VIEW_TYPE_AD_FOOTER = 2;
+    public static final int VIEW_TYPE_MESSAGE_HEADER = 3;
+    public static final int VIEW_TYPE_MESSAGE_FOOTER = 4;
+    public static final int VIEW_TYPE_SUPER_COLLAPSED_BLOCK = 5;
+    public static final int VIEW_TYPE_COUNT = 6;
 
     public class ConversationHeaderItem extends ConversationOverlayItem {
         public final Conversation mConversation;
@@ -119,6 +122,65 @@
 
     }
 
+    public class AdHeaderItem extends ConversationOverlayItem {
+        public final Conversation mConversation;
+
+        private AdHeaderItem(Conversation conv) {
+            mConversation = conv;
+        }
+
+        @Override
+        public int getType() {
+            return VIEW_TYPE_AD_HEADER;
+        }
+
+        @Override
+        public View createView(Context context, LayoutInflater inflater, ViewGroup parent) {
+            final AdHeaderView headerView = (AdHeaderView) inflater.inflate(
+                    R.layout.ad_header_view, parent, false);
+            headerView.bind(this);
+            headerView.setAdSubject(mConversation.subject);
+
+            return headerView;
+        }
+
+        @Override
+        public void bindView(View v, boolean measureOnly) {
+            final AdHeaderView header = (AdHeaderView) v;
+            header.bind(this);
+        }
+
+        @Override
+        public boolean isContiguous() {
+            return false;
+        }
+
+    }
+
+    public class AdFooterItem extends ConversationOverlayItem {
+
+        @Override
+        public int getType() {
+            return VIEW_TYPE_AD_FOOTER;
+        }
+
+        @Override
+        public View createView(Context context, LayoutInflater inflater, ViewGroup parent) {
+            return null;
+        }
+
+        @Override
+        public void bindView(View v, boolean measureOnly) {
+            // DO NOTHING
+        }
+
+        @Override
+        public boolean isContiguous() {
+            return true;
+        }
+
+    }
+
     public static class MessageHeaderItem extends ConversationOverlayItem {
 
         private final ConversationViewAdapter mAdapter;
@@ -407,6 +469,14 @@
         return addItem(new ConversationHeaderItem(conv));
     }
 
+    public int addAdHeader(Conversation conversation) {
+        return addItem(new AdHeaderItem(conversation));
+    }
+
+    public int addAdFooter() {
+        return addItem(new AdFooterItem());
+    }
+
     public int addMessageHeader(ConversationMessage msg, boolean expanded, boolean showImages) {
         return addItem(new MessageHeaderItem(this, msg, expanded, showImages));
     }
diff --git a/src/com/android/mail/browse/EmailAddressSpan.java b/src/com/android/mail/browse/EmailAddressSpan.java
new file mode 100644
index 0000000..cbf5ec4
--- /dev/null
+++ b/src/com/android/mail/browse/EmailAddressSpan.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.browse;
+
+import android.text.TextPaint;
+import android.text.style.URLSpan;
+import android.view.View;
+
+import com.android.mail.compose.ComposeActivity;
+import com.android.mail.providers.Account;
+
+public class EmailAddressSpan extends URLSpan {
+
+    private final Account mAccount;
+    private final String mEmailAddress;
+
+    public EmailAddressSpan(Account account, String emailAddress) {
+        super("mailto:" + emailAddress);
+        mAccount = account;
+        mEmailAddress = emailAddress;
+    }
+
+    @Override
+    public void onClick(View view) {
+        ComposeActivity.composeToAddress(view.getContext(), mAccount, mEmailAddress);
+    }
+
+    /**
+     * Makes the text in the link color and not underlined.
+     */
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setColor(ds.linkColor);
+        ds.setUnderlineText(false);
+    }
+}
diff --git a/src/com/android/mail/browse/EmlMessageViewFragment.java b/src/com/android/mail/browse/EmlMessageViewFragment.java
index 17b7a0c..d2824bc 100644
--- a/src/com/android/mail/browse/EmlMessageViewFragment.java
+++ b/src/com/android/mail/browse/EmlMessageViewFragment.java
@@ -191,7 +191,7 @@
 
     @Override
     public ConversationAccountController getConversationAccountController() {
-        return null;
+        return (EmlViewerActivity) getActivity();
     }
 
     @Override
diff --git a/src/com/android/mail/browse/EmlViewerActivity.java b/src/com/android/mail/browse/EmlViewerActivity.java
index a73c0f8..1e0652d 100644
--- a/src/com/android/mail/browse/EmlViewerActivity.java
+++ b/src/com/android/mail/browse/EmlViewerActivity.java
@@ -41,7 +41,8 @@
 import com.android.mail.utils.MimeType;
 import com.android.mail.utils.Utils;
 
-public class EmlViewerActivity extends Activity implements FeedbackEnabledActivity {
+public class EmlViewerActivity extends Activity implements FeedbackEnabledActivity,
+        ConversationAccountController {
     public static final String EXTRA_ACCOUNT_URI = "extra-account-uri";
 
     private static final String LOG_TAG = LogTag.getLogTag();
@@ -153,6 +154,11 @@
         return this;
     }
 
+    @Override
+    public Account getAccount() {
+        return mAccount;
+    }
+
     private class AccountLoadCallbacks
             implements LoaderManager.LoaderCallbacks<ObjectCursor<Account>> {
 
diff --git a/src/com/android/mail/browse/MessageHeaderDetailsDialogFragment.java b/src/com/android/mail/browse/MessageHeaderDetailsDialogFragment.java
new file mode 100644
index 0000000..1138e78
--- /dev/null
+++ b/src/com/android/mail/browse/MessageHeaderDetailsDialogFragment.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.browse;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.app.DialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.mail.R;
+import com.android.mail.providers.Account;
+import com.android.mail.providers.Address;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * {@link DialogFragment} used by secure conversation views to display
+ * the expanded message details as a dialog.
+ */
+public class MessageHeaderDetailsDialogFragment extends DialogFragment {
+
+    private static final String ARG_ACCOUNT = "account";
+    private static final String ARG_ADDRESS_CACHE = "addresses";
+    private static final String ARG_FROM = "from";
+    private static final String ARG_REPLY_TO = "replyto";
+    private static final String ARG_TO = "to";
+    private static final String ARG_CC = "cc";
+    private static final String ARG_BCC = "bcc";
+
+    /**
+     * Creates a new {@link MessageHeaderDetailsDialogFragment}.
+     * @param addressCache a mapping of RFC822 addresses as strings to {@link Address}.
+     * @param account {@link Account} used as the from address for any messages created
+     *                by tapping an email address.
+     * @param from from addresses for the message
+     * @param replyTo replyTo addresses for the message
+     * @param to to addresses for the message
+     * @param cc cc addresses for the message
+     * @param bcc bcc addresses for the message
+     * @return a newly created {@link MessageHeaderDetailsDialogFragment}
+     */
+    public static MessageHeaderDetailsDialogFragment newInstance(
+            Map<String, Address> addressCache, Account account, String[] from, String[] replyTo,
+            String[] to, String[] cc, String[] bcc) {
+        final MessageHeaderDetailsDialogFragment f = new MessageHeaderDetailsDialogFragment();
+
+        // Supply needed items as arguments
+        final Bundle args = new Bundle(7);
+        args.putParcelable(ARG_ACCOUNT, account);
+
+        final Bundle addresses = new Bundle();
+        addAddressesToBundle(addresses, addressCache, from);
+        addAddressesToBundle(addresses, addressCache, replyTo);
+        addAddressesToBundle(addresses, addressCache, to);
+        addAddressesToBundle(addresses, addressCache, cc);
+        addAddressesToBundle(addresses, addressCache, bcc);
+        args.putBundle(ARG_ADDRESS_CACHE, addresses);
+
+        args.putStringArray(ARG_FROM, from);
+        args.putStringArray(ARG_REPLY_TO, replyTo);
+        args.putStringArray(ARG_TO, to);
+        args.putStringArray(ARG_CC, cc);
+        args.putStringArray(ARG_BCC, bcc);
+        f.setArguments(args);
+
+        return f;
+    }
+
+    private static void addAddressesToBundle(
+            Bundle addresses, Map<String, Address> addressCache, String[] emails) {
+        for (final String email : emails) {
+            addresses.putParcelable(email, MessageHeaderView.getAddress(addressCache, email));
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(final Bundle onSavedInstanceState) {
+        final Context context = getActivity();
+        AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        final View expandedDetails = MessageHeaderView.inflateExpandedDetails(
+                LayoutInflater.from(context));
+
+        final Bundle args = getArguments();
+
+        // turn bundle back into Map<String, Address>
+        final Bundle addresses = args.getBundle(ARG_ADDRESS_CACHE);
+        final Map<String, Address> addressCache = new HashMap<String, Address>();
+        for (String email : addresses.keySet()) {
+            addressCache.put(email, (Address) addresses.getParcelable(email));
+        }
+
+        MessageHeaderView.renderExpandedDetails(getResources(), expandedDetails, null,
+                addressCache, (Account) args.getParcelable(ARG_ACCOUNT), null,
+                args.getStringArray(ARG_FROM), args.getStringArray(ARG_REPLY_TO),
+                args.getStringArray(ARG_TO), args.getStringArray(ARG_CC),
+                args.getStringArray(ARG_BCC));
+
+        expandedDetails.findViewById(R.id.details_expander)
+                .setVisibility(View.GONE);
+        builder.setView(expandedDetails)
+                .setCancelable(true)
+                .setTitle(context.getString(R.string.message_details_title));
+        return builder.create();
+    }
+}
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index 72987d3..24d83bc 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -16,7 +16,8 @@
 
 package com.android.mail.browse;
 
-import android.app.AlertDialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
 import android.content.AsyncQueryHandler;
 import android.content.Context;
 import android.content.res.Resources;
@@ -27,8 +28,10 @@
 import android.provider.ContactsContract;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
+import android.text.Spanned;
 import android.text.TextUtils;
 import android.text.style.StyleSpan;
+import android.text.style.URLSpan;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -103,6 +106,8 @@
     public static final boolean ENABLE_REPORT_RENDERING_PROBLEM =
             MailPrefs.SHOW_EXPERIMENTAL_PREFS;
 
+    private static final String DETAILS_DIALOG_TAG = "details-dialog";
+
     private MessageHeaderViewCallbacks mCallbacks;
 
     private ViewGroup mUpperHeaderView;
@@ -209,7 +214,7 @@
 
     private int mExpandMode = DEFAULT_MODE;
 
-    private AlertDialog mDetailsPopup;
+    private DialogFragment mDetailsPopup;
 
     private VeiledAddressMatcher mVeiledMatcher;
 
@@ -234,6 +239,8 @@
         boolean supportsMessageTransforms();
 
         String getMessageTransforms(Message msg);
+
+        FragmentManager getFragmentManager();
     }
 
     public MessageHeaderView(Context context) {
@@ -498,11 +505,11 @@
         return item == mMessageHeaderItem;
     }
 
-    private Address getAddress(String emailStr) {
+    public Address getAddress(String emailStr) {
         return getAddress(mAddressCache, emailStr);
     }
 
-    private static Address getAddress(Map<String, Address> cache, String emailStr) {
+    public static Address getAddress(Map<String, Address> cache, String emailStr) {
         Address addr = null;
         synchronized (cache) {
             if (cache != null) {
@@ -719,67 +726,6 @@
     }
 
     /**
-     * Render an email list for the expanded message details view.
-     * @param headerId
-     * @param detailsId
-     * @param emails
-     * @param showViaDomain
-     * @param rootView
-     */
-    private void renderEmailList(int headerId, int detailsId, String[] emails,
-            boolean showViaDomain, View rootView) {
-        if (emails == null || emails.length == 0) {
-            return;
-        }
-        final String[] formattedEmails = new String[emails.length];
-        final Resources res = getResources();
-        for (int i = 0; i < emails.length; i++) {
-            final Address email = getAddress(emails[i]);
-            String name = email.getName();
-            final String address = email.getAddress();
-            // Check if the address here is a veiled address.  If it is, we need to display an
-            // alternate layout
-            final boolean isVeiledAddress = mVeiledMatcher != null &&
-                    mVeiledMatcher.isVeiledAddress(address);
-            final String addressShown;
-            if (isVeiledAddress) {
-                // Add the warning at the end of the name, and remove the address.  The alternate
-                // text cannot be put in the address part, because the address is made into a link,
-                // and the alternate human-readable text is not a link.
-                addressShown = "";
-                if (TextUtils.isEmpty(name)) {
-                    // Empty name and we will block out the address. Let's write something more
-                    // readable.
-                    name = res.getString(VeiledAddressMatcher.VEILED_ALTERNATE_TEXT_UNKNOWN_PERSON);
-                } else {
-                    name = name + res.getString(VeiledAddressMatcher.VEILED_ALTERNATE_TEXT);
-                }
-            } else {
-                addressShown = address;
-            }
-            if (name == null || name.length() == 0) {
-                formattedEmails[i] = addressShown;
-            } else {
-                // The one downside to having the showViaDomain here is that
-                // if the sender does not have a name, it will not show the via info
-                if (showViaDomain) {
-                    formattedEmails[i] = res.getString(
-                            R.string.address_display_format_with_via_domain,
-                            name, addressShown, mMessage.viaDomain);
-                } else {
-                    formattedEmails[i] = res.getString(R.string.address_display_format,
-                            name, addressShown);
-                }
-            }
-        }
-
-        rootView.findViewById(headerId).setVisibility(VISIBLE);
-        final TextView detailsText = (TextView) rootView.findViewById(detailsId);
-        detailsText.setText(TextUtils.join("\n", formattedEmails));
-        detailsText.setVisibility(VISIBLE);
-    }
-
-    /**
      * Utility class to build a list of recipient lists.
      */
     private static class RecipientListsBuilder {
@@ -1320,45 +1266,127 @@
     private boolean ensureExpandedDetailsView() {
         boolean viewCreated = false;
         if (mExpandedDetailsView == null) {
-            View v = mInflater.inflate(R.layout.conversation_message_details_header_expanded, null,
-                    false);
+            View v = inflateExpandedDetails(mInflater);
             v.setOnClickListener(this);
 
             mExpandedDetailsView = (ViewGroup) v;
             viewCreated = true;
         }
         if (!mExpandedDetailsValid) {
-            renderEmailList(R.id.from_heading, R.id.from_details, mFrom, mMessage.viaDomain != null,
-                    mExpandedDetailsView);
-            renderEmailList(R.id.replyto_heading, R.id.replyto_details, mReplyTo, false,
-                    mExpandedDetailsView);
-            renderEmailList(R.id.to_heading, R.id.to_details, mTo, false, mExpandedDetailsView);
-            renderEmailList(R.id.cc_heading, R.id.cc_details, mCc, false, mExpandedDetailsView);
-            renderEmailList(R.id.bcc_heading, R.id.bcc_details, mBcc, false, mExpandedDetailsView);
+            renderExpandedDetails(getResources(), mExpandedDetailsView, mMessage.viaDomain,
+                    mAddressCache, getAccount(), mVeiledMatcher, mFrom, mReplyTo, mTo, mCc, mBcc);
 
             mExpandedDetailsValid = true;
         }
         return viewCreated;
     }
 
+    public static View inflateExpandedDetails(LayoutInflater inflater) {
+        return inflater.inflate(R.layout.conversation_message_details_header_expanded, null,
+                false);
+    }
+
+    public static void renderExpandedDetails(Resources res, View detailsView,
+            String viaDomain, Map<String, Address> addressCache, Account account,
+            VeiledAddressMatcher veiledMatcher, String[] from, String[] replyTo,
+            String[] to, String[] cc, String[] bcc) {
+        renderEmailList(res, R.id.from_heading, R.id.from_details, from, viaDomain,
+                detailsView, addressCache, account, veiledMatcher);
+        renderEmailList(res, R.id.replyto_heading, R.id.replyto_details, replyTo, viaDomain,
+                detailsView, addressCache, account, veiledMatcher);
+        renderEmailList(res, R.id.to_heading, R.id.to_details, to, viaDomain,
+                detailsView, addressCache, account, veiledMatcher);
+        renderEmailList(res, R.id.cc_heading, R.id.cc_details, cc, viaDomain,
+                detailsView, addressCache, account, veiledMatcher);
+        renderEmailList(res, R.id.bcc_heading, R.id.bcc_details, bcc, viaDomain,
+                detailsView, addressCache, account, veiledMatcher);
+    }
+
+    /**
+     * Render an email list for the expanded message details view.
+     */
+    private static void renderEmailList(Resources res, int headerId, int detailsId,
+            String[] emails, String viaDomain, View rootView,
+            Map<String, Address> addressCache, Account account,
+            VeiledAddressMatcher veiledMatcher) {
+        if (emails == null || emails.length == 0) {
+            return;
+        }
+        final String[] formattedEmails = new String[emails.length];
+        for (int i = 0; i < emails.length; i++) {
+            final Address email = getAddress(addressCache, emails[i]);
+            String name = email.getName();
+            final String address = email.getAddress();
+            // Check if the address here is a veiled address.  If it is, we need to display an
+            // alternate layout
+            final boolean isVeiledAddress = veiledMatcher != null &&
+                    veiledMatcher.isVeiledAddress(address);
+            final String addressShown;
+            if (isVeiledAddress) {
+                // Add the warning at the end of the name, and remove the address.  The alternate
+                // text cannot be put in the address part, because the address is made into a link,
+                // and the alternate human-readable text is not a link.
+                addressShown = "";
+                if (TextUtils.isEmpty(name)) {
+                    // Empty name and we will block out the address. Let's write something more
+                    // readable.
+                    name = res.getString(VeiledAddressMatcher.VEILED_ALTERNATE_TEXT_UNKNOWN_PERSON);
+                } else {
+                    name = name + res.getString(VeiledAddressMatcher.VEILED_ALTERNATE_TEXT);
+                }
+            } else {
+                addressShown = address;
+            }
+            if (name == null || name.length() == 0) {
+                formattedEmails[i] = addressShown;
+            } else {
+                // The one downside to having the showViaDomain here is that
+                // if the sender does not have a name, it will not show the via info
+                if (viaDomain != null) {
+                    formattedEmails[i] = res.getString(
+                            R.string.address_display_format_with_via_domain,
+                            name, addressShown, viaDomain);
+                } else {
+                    formattedEmails[i] = res.getString(R.string.address_display_format,
+                            name, addressShown);
+                }
+            }
+        }
+
+        rootView.findViewById(headerId).setVisibility(VISIBLE);
+        final TextView detailsText = (TextView) rootView.findViewById(detailsId);
+        detailsText.setText(TextUtils.join("\n", formattedEmails));
+        stripUnderlines(detailsText, account);
+        detailsText.setVisibility(VISIBLE);
+    }
+
+    private static void stripUnderlines(TextView textView, Account account) {
+        final Spannable spannable = (Spannable) textView.getText();
+        final URLSpan[] urls = textView.getUrls();
+
+        for (URLSpan span : urls) {
+            final int start = spannable.getSpanStart(span);
+            final int end = spannable.getSpanEnd(span);
+            spannable.removeSpan(span);
+            span = new EmailAddressSpan(account, span.getURL().substring(7));
+            spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
+    }
+
     private void showDetailsPopup() {
-        ensureExpandedDetailsView();
+        final FragmentManager manager = mCallbacks.getFragmentManager();
+        mDetailsPopup = (DialogFragment) manager.findFragmentByTag(DETAILS_DIALOG_TAG);
         if (mDetailsPopup == null) {
-            AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
-            mExpandedDetailsView.findViewById(R.id.details_expander)
-                .setVisibility(View.GONE);
-            builder.setView(mExpandedDetailsView)
-                .setCancelable(true)
-                .setTitle(getContext().getString(R.string.message_details_title));
-            mDetailsPopup = builder.show();
-        } else {
-            mDetailsPopup.show();
+            mDetailsPopup = MessageHeaderDetailsDialogFragment.newInstance(
+                    mAddressCache, getAccount(), mFrom, mReplyTo, mTo, mCc, mBcc);
+            mDetailsPopup.show(manager, DETAILS_DIALOG_TAG);
         }
     }
 
     private void hideDetailsPopup() {
         if (mDetailsPopup != null) {
-            mDetailsPopup.hide();
+            mDetailsPopup.dismiss();
+            mDetailsPopup = null;
         }
     }
 
diff --git a/src/com/android/mail/browse/SwipeableConversationItemView.java b/src/com/android/mail/browse/SwipeableConversationItemView.java
index a675b8d..cd98af0 100644
--- a/src/com/android/mail/browse/SwipeableConversationItemView.java
+++ b/src/com/android/mail/browse/SwipeableConversationItemView.java
@@ -26,6 +26,7 @@
 import com.android.mail.providers.Conversation;
 import com.android.mail.providers.Folder;
 import com.android.mail.ui.AnimatedAdapter;
+import com.android.mail.ui.AnimatedAdapter.ConversationListListener;
 import com.android.mail.ui.ControllableActivity;
 import com.android.mail.ui.ConversationSelectionSet;
 
@@ -52,10 +53,13 @@
     }
 
     public void bind(Conversation conversation, ControllableActivity activity,
+            final ConversationListListener conversationListListener,
             ConversationSelectionSet set, Folder folder, int checkboxOrSenderImage,
-            boolean swipeEnabled, boolean priorityArrowsEnabled, AnimatedAdapter animatedAdapter) {
-        mConversationItemView.bind(conversation, activity, set, folder, checkboxOrSenderImage,
-                swipeEnabled, priorityArrowsEnabled, animatedAdapter);
+            boolean swipeEnabled, boolean priorityArrowsEnabled, AnimatedAdapter animatedAdapter,
+            final int adapterPosition) {
+        mConversationItemView.bind(conversation, activity, conversationListListener, set, folder,
+                checkboxOrSenderImage, swipeEnabled, priorityArrowsEnabled, animatedAdapter,
+                adapterPosition);
     }
 
     public void startUndoAnimation(AnimatorListener listener, boolean swipe) {
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index fa31833..844696e 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -202,7 +202,7 @@
     private static final String EXTRA_SELECTED_REPLY_FROM_ACCOUNT = "replyFromAccount";
     private static final String EXTRA_REQUEST_ID = "requestId";
     private static final String EXTRA_FOCUS_SELECTION_START = "focusSelectionStart";
-    private static final String EXTRA_FOCUS_SELECTION_END = null;
+    private static final String EXTRA_FOCUS_SELECTION_END = "focusSelectionEnd";
     private static final String EXTRA_MESSAGE = "extraMessage";
     private static final int REFERENCE_MESSAGE_LOADER = 0;
     private static final int LOADER_ACCOUNT_CURSOR = 1;
@@ -296,6 +296,13 @@
     /**
      * Can be called from a non-UI thread.
      */
+    public static void composeToAddress(Context launcher, Account account, String toAddress) {
+        launch(launcher, account, null, COMPOSE, toAddress, null);
+    }
+
+    /**
+     * Can be called from a non-UI thread.
+     */
     public static Intent createReplyIntent(final Context launcher, final Account account,
             final Uri messageUri, final boolean isReplyAll) {
         return createActionIntent(launcher, account, messageUri, isReplyAll ? REPLY_ALL : REPLY);
@@ -313,6 +320,13 @@
             final Uri messageUri, final int action) {
         final Intent intent = new Intent(launcher, ComposeActivity.class);
 
+        updateActionIntent(account, messageUri, action, intent);
+
+        return intent;
+    }
+
+    @VisibleForTesting
+    static Intent updateActionIntent(Account account, Uri messageUri, int action, Intent intent) {
         intent.putExtra(EXTRA_FROM_EMAIL_TASK, true);
         intent.putExtra(EXTRA_ACTION, action);
         intent.putExtra(Utils.EXTRA_ACCOUNT, account);
@@ -834,9 +848,6 @@
         message.setFrom(selectedReplyFromAccount != null ? selectedReplyFromAccount.address
                 : mAccount != null ? mAccount.name : null);
         message.draftType = getDraftType(mode);
-        message.setTo(formatSenders(mTo.getText().toString()));
-        message.setCc(formatSenders(mCc.getText().toString()));
-        message.setBcc(formatSenders(mBcc.getText().toString()));
         return message;
     }
 
@@ -920,10 +931,10 @@
     }
 
     /**
-     * Given an account and which email address the message was sent to,
+     * Given an account and the message we're replying to,
      * return who the message should be sent from.
      * @param account Account in which the message arrived.
-     * @param sentTo Email address to which the message was sent.
+     * @param refMessage Message to analyze for account selection
      * @return the address from which to reply.
      */
     public ReplyFromAccount getReplyFromAccount(Account account, Message refMessage) {
@@ -936,8 +947,8 @@
             // all the message recipients and find one that matches
             // a custom from or account.
             List<String> allRecipients = new ArrayList<String>();
-            allRecipients.addAll(Arrays.asList(refMessage.getToAddresses()));
-            allRecipients.addAll(Arrays.asList(refMessage.getCcAddresses()));
+            allRecipients.addAll(Arrays.asList(refMessage.getToAddressesUnescaped()));
+            allRecipients.addAll(Arrays.asList(refMessage.getCcAddressesUnescaped()));
             return getMatchingRecipient(account, allRecipients);
         }
     }
@@ -1175,10 +1186,10 @@
         mDraftId = message.id;
         mSubject.setText(message.subject);
         mForward = message.draftType == UIProvider.DraftType.FORWARD;
-        final List<String> toAddresses = Arrays.asList(message.getToAddresses());
+        final List<String> toAddresses = Arrays.asList(message.getToAddressesUnescaped());
         addToAddresses(toAddresses);
-        addCcAddresses(Arrays.asList(message.getCcAddresses()), toAddresses);
-        addBccAddresses(Arrays.asList(message.getBccAddresses()));
+        addCcAddresses(Arrays.asList(message.getCcAddressesUnescaped()), toAddresses);
+        addBccAddresses(Arrays.asList(message.getBccAddressesUnescaped()));
         if (message.hasAttachments) {
             List<Attachment> attachments = message.getAttachments();
             for (Attachment a : attachments) {
@@ -1565,9 +1576,11 @@
         initReplyRecipients(refMessage, action);
     }
 
+    // TODO: This should be private.  This method shouldn't be used by ComposeActivityTests, as
+    // it doesn't setup the state of the activity correctly
     @VisibleForTesting
     void initReplyRecipients(final Message refMessage, final int action) {
-        String[] sentToAddresses = refMessage.getToAddresses();
+        String[] sentToAddresses = refMessage.getToAddressesUnescaped();
         final Collection<String> toAddresses;
         String replytoAddress = refMessage.getReplyTo();
         // If there is no reply to address, the reply to address is the sender.
@@ -1587,7 +1600,7 @@
             toAddresses = initToRecipients(refMessage.getFrom(), replytoAddress, sentToAddresses);
             addToAddresses(toAddresses);
             addRecipients(ccAddresses, sentToAddresses);
-            addRecipients(ccAddresses, refMessage.getCcAddresses());
+            addRecipients(ccAddresses, refMessage.getCcAddressesUnescaped());
             addCcAddresses(ccAddresses, toAddresses);
         }
     }
@@ -1718,7 +1731,6 @@
      * A recipient matches this account if it has the same address as the
      * currently selected account OR one of the custom from addresses associated
      * with the currently selected account.
-     * @param accountAddress currently selected account
      * @param recipientAddress address we are comparing with the currently selected account
      * @return
      */
diff --git a/src/com/android/mail/photomanager/PhotoManager.java b/src/com/android/mail/photomanager/PhotoManager.java
index b3037fc..0b937cb 100644
--- a/src/com/android/mail/photomanager/PhotoManager.java
+++ b/src/com/android/mail/photomanager/PhotoManager.java
@@ -468,19 +468,15 @@
             }
 
             case MESSAGE_PHOTOS_LOADED: {
-                if (!mPaused) {
-                    processLoadedImages();
-                }
+                processLoadedImages();
                 if (DEBUG) dumpStats();
                 return true;
             }
 
             case MESSAGE_PHOTO_LOADING: {
-                if (!mPaused) {
-                    final int hashcode = msg.arg1;
-                    final Request request = mPendingRequests.get(hashcode);
-                    onImageLoadStarted(request);
-                }
+                final int hashcode = msg.arg1;
+                final Request request = mPendingRequests.get(hashcode);
+                onImageLoadStarted(request);
                 return true;
             }
         }
@@ -494,9 +490,9 @@
     private void processLoadedImages() {
         Utils.traceBeginSection("process loaded images");
         final List<Integer> toRemove = Lists.newArrayList();
-        for (Integer hash : mPendingRequests.keySet()) {
-            Request request = mPendingRequests.get(hash);
-            boolean loaded = loadCachedPhoto(request, true);
+        for (final Integer hash : mPendingRequests.keySet()) {
+            final Request request = mPendingRequests.get(hash);
+            final boolean loaded = loadCachedPhoto(request, true);
             // Request can go through multiple attempts if the LoaderThread fails to load any
             // images for it, or if the images it loads are evicted from the cache before we
             // could access them in the main thread.
@@ -504,11 +500,11 @@
                 toRemove.add(hash);
             }
         }
-        for (Integer key : toRemove) {
+        for (final Integer key : toRemove) {
             mPendingRequests.remove(key);
         }
 
-        if (!mPendingRequests.isEmpty()) {
+        if (!mPaused && !mPendingRequests.isEmpty()) {
             LogUtils.d(TAG, "Finished loading batch. %d still have to be loaded.",
                     mPendingRequests.size());
             requestLoading();
diff --git a/src/com/android/mail/preferences/MailPrefs.java b/src/com/android/mail/preferences/MailPrefs.java
index 985dda4..269c7b4 100644
--- a/src/com/android/mail/preferences/MailPrefs.java
+++ b/src/com/android/mail/preferences/MailPrefs.java
@@ -79,6 +79,9 @@
         public static final String DISPLAY_IMAGES = "display_images";
         public static final String DISPLAY_IMAGES_PATTERNS = "display_sender_images_patterns_set";
 
+
+        public static final String SHOW_SENDER_IMAGES = "conversation-list-sender-image";
+
         public static final ImmutableSet<String> BACKUP_KEYS =
                 new ImmutableSet.Builder<String>()
                 .add(DEFAULT_REPLY_ALL)
@@ -86,6 +89,7 @@
                 .add(REMOVAL_ACTION)
                 .add(DISPLAY_IMAGES)
                 .add(DISPLAY_IMAGES_PATTERNS)
+                .add(SHOW_SENDER_IMAGES)
                 .build();
     }
 
@@ -351,4 +355,15 @@
         editor.putStringSet(PreferenceKeys.DISPLAY_IMAGES_PATTERNS, Collections.EMPTY_SET);
         editor.apply();
     }
+
+
+    public void setShowSenderImages(boolean enable) {
+        getEditor().putBoolean(PreferenceKeys.SHOW_SENDER_IMAGES, enable).apply();
+        notifyBackupPreferenceChanged();
+    }
+
+    public boolean getShowSenderImages() {
+        final SharedPreferences sharedPreferences = getSharedPreferences();
+        return sharedPreferences.getBoolean(PreferenceKeys.SHOW_SENDER_IMAGES, true);
+    }
 }
diff --git a/src/com/android/mail/preferences/VersionedPrefs.java b/src/com/android/mail/preferences/VersionedPrefs.java
index bc50d98..81eabde 100644
--- a/src/com/android/mail/preferences/VersionedPrefs.java
+++ b/src/com/android/mail/preferences/VersionedPrefs.java
@@ -51,7 +51,7 @@
      * The current version number for {@link SharedPreferences}. This is a constant for all
      * applications based on UnifiedEmail.
      */
-    protected static final int CURRENT_VERSION_NUMBER = 2;
+    protected static final int CURRENT_VERSION_NUMBER = 3;
 
     protected static final String LOG_TAG = LogTag.getLogTag();
 
diff --git a/src/com/android/mail/providers/Address.java b/src/com/android/mail/providers/Address.java
index 595568c..edd2db1 100644
--- a/src/com/android/mail/providers/Address.java
+++ b/src/com/android/mail/providers/Address.java
@@ -15,6 +15,12 @@
  */
 package com.android.mail.providers;
 
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.text.util.Rfc822Token;
+import android.text.util.Rfc822Tokenizer;
+
 import com.android.common.Rfc822Validator;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
@@ -24,10 +30,6 @@
 import org.apache.james.mime4j.codec.EncoderUtil;
 import org.apache.james.mime4j.decoder.DecoderUtil;
 
-import android.text.TextUtils;
-import android.text.util.Rfc822Token;
-import android.text.util.Rfc822Tokenizer;
-
 import java.util.ArrayList;
 import java.util.regex.Pattern;
 
@@ -42,7 +44,7 @@
  * Name and comment part should be MIME/base64 encoded in header if necessary.
  *
  */
-public class Address {
+public class Address implements Parcelable {
     public static final String ADDRESS_DELIMETER = ",";
     /**
      *  Address part, in the form local_part@domain_part. No surrounding angle brackets.
@@ -81,6 +83,8 @@
         setAddress(address);
     }
 
+
+
     /**
      * Returns a simplified string for this e-mail address.
      * When a name is known, it will return the first token of that name. Otherwise, it will
@@ -512,4 +516,32 @@
             return address + LIST_DELIMITER_PERSONAL + personal;
         }
     }
+
+    public static final Creator<Address> CREATOR = new Creator<Address>() {
+        @Override
+        public Address createFromParcel(Parcel parcel) {
+            return new Address(parcel);
+        }
+
+        @Override
+        public Address[] newArray(int size) {
+            return new Address[size];
+        }
+    };
+
+    public Address(Parcel in) {
+        setName(in.readString());
+        setAddress(in.readString());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mName);
+        out.writeString(mAddress);
+    }
 }
diff --git a/src/com/android/mail/providers/Conversation.java b/src/com/android/mail/providers/Conversation.java
index e936ed5..741c669 100644
--- a/src/com/android/mail/providers/Conversation.java
+++ b/src/com/android/mail/providers/Conversation.java
@@ -522,6 +522,7 @@
             fl = response.getParcelable(key);
         } else {
             // legacy fallback
+            // TODO: delete this once Email supports the respond call
             fl = FolderList.fromBlob(
                     cursor.getBlob(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN));
         }
diff --git a/src/com/android/mail/providers/Folder.java b/src/com/android/mail/providers/Folder.java
index 77c69ae..c1ddf00 100644
--- a/src/com/android/mail/providers/Folder.java
+++ b/src/com/android/mail/providers/Folder.java
@@ -31,6 +31,7 @@
 import com.android.mail.content.CursorCreator;
 import com.android.mail.content.ObjectCursorLoader;
 import com.android.mail.providers.UIProvider.FolderType;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
 import com.android.mail.utils.Utils;
@@ -79,7 +80,7 @@
     /**
      * The content provider URI that returns this folder for this account.
      */
-    public Uri uri;
+    public FolderUri folderUri;
 
     /**
      * The human visible name for this folder.
@@ -201,7 +202,7 @@
             final long lastMessageTimestamp) {
         this.id = id;
         this.persistentId = persistentId;
-        this.uri = uri;
+        this.folderUri = new FolderUri(uri);
         this.name = name;
         this.capabilities = capabilities;
         this.hasChildren = hasChildren;
@@ -234,7 +235,8 @@
     public Folder(Cursor cursor) {
         id = cursor.getInt(UIProvider.FOLDER_ID_COLUMN);
         persistentId = cursor.getString(UIProvider.FOLDER_PERSISTENT_ID_COLUMN);
-        uri = Uri.parse(cursor.getString(UIProvider.FOLDER_URI_COLUMN));
+        folderUri =
+                new FolderUri(Uri.parse(cursor.getString(UIProvider.FOLDER_URI_COLUMN)));
         name = cursor.getString(UIProvider.FOLDER_NAME_COLUMN);
         capabilities = cursor.getInt(UIProvider.FOLDER_CAPABILITIES_COLUMN);
         // 1 for true, 0 for false.
@@ -290,7 +292,7 @@
     public Folder(Parcel in, ClassLoader loader) {
         id = in.readInt();
         persistentId = in.readString();
-        uri = in.readParcelable(loader);
+        folderUri = new FolderUri((Uri) in.readParcelable(loader));
         name = in.readString();
         capabilities = in.readInt();
         // 1 for true, 0 for false.
@@ -326,7 +328,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(id);
         dest.writeString(persistentId);
-        dest.writeParcelable(uri, 0);
+        dest.writeParcelable(folderUri != null ? folderUri.fullUri : null, 0);
         dest.writeString(name);
         dest.writeInt(capabilities);
         // 1 for true, 0 for false.
@@ -371,7 +373,7 @@
     public static HashMap<Uri, Folder> hashMapForFolders(List<Folder> rawFolders) {
         final HashMap<Uri, Folder> folders = new HashMap<Uri, Folder>();
         for (Folder f : rawFolders) {
-            folders.put(f.uri, f);
+            folders.put(f.folderUri.getComparisonUri(), f);
         }
         return folders;
     }
@@ -421,12 +423,12 @@
         if (o == null || !(o instanceof Folder)) {
             return false;
         }
-        return Objects.equal(uri, ((Folder) o).uri);
+        return Objects.equal(folderUri, ((Folder) o).folderUri);
     }
 
     @Override
     public int hashCode() {
-        return uri == null ? 0 : uri.hashCode();
+        return folderUri == null ? 0 : folderUri.hashCode();
     }
 
     @Override
@@ -436,7 +438,7 @@
         sb.append(id);
         if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) {
             sb.append(", uri=");
-            sb.append(uri);
+            sb.append(folderUri);
             sb.append(", name=");
             sb.append(name);
         }
@@ -521,7 +523,7 @@
         final String[] folderUris = new String[folders.size()];
         int i = 0;
         for (Folder folder : folders) {
-            folderUris[i] = folder.uri.toString();
+            folderUris[i] = folder.folderUri.toString();
             i++;
         }
         return folderUris;
@@ -621,7 +623,7 @@
          }
          f.id = id;
          int index = 1;
-         f.uri = Folder.getValidUri(split[index++]);
+         f.folderUri = new FolderUri(Folder.getValidUri(split[index++]));
          f.name = split[index++];
          f.hasChildren = Integer.parseInt(split[index++]) != 0;
          f.capabilities = Integer.parseInt(split[index++]);
diff --git a/src/com/android/mail/providers/FolderWatcher.java b/src/com/android/mail/providers/FolderWatcher.java
index 8c0b1d3..4fb6474 100644
--- a/src/com/android/mail/providers/FolderWatcher.java
+++ b/src/com/android/mail/providers/FolderWatcher.java
@@ -220,7 +220,7 @@
                 return;
             }
             final Folder f = data.getModel();
-            final Uri uri = f.uri;
+            final Uri uri = f.folderUri.getComparisonUri();
             final int unreadCount = f.unreadCount;
             final Folder previousFolder = mInbox.get(uri);
             final boolean unreadCountChanged = previousFolder == null
diff --git a/src/com/android/mail/providers/MailAppProvider.java b/src/com/android/mail/providers/MailAppProvider.java
index 23c8965..97367a1 100644
--- a/src/com/android/mail/providers/MailAppProvider.java
+++ b/src/com/android/mail/providers/MailAppProvider.java
@@ -232,7 +232,6 @@
      * {@link ContentProvider#query()} for the specified uri.  The content provider handling the
      * query needs to handle the {@link UIProvider.ACCOUNTS_PROJECTION}
      * Any changes to the underlying provider will automatically be reflected.
-     * @param resolver
      * @param accountsQueryUri
      */
     private void addAccountsForUriAsync(Uri accountsQueryUri) {
@@ -266,17 +265,6 @@
         mCursorLoaderMap.put(accountsQueryUri, accountsCursorLoader);
     }
 
-    public static void addAccount(Account account, Uri accountsQueryUri) {
-        final MailAppProvider provider = getInstance();
-        if (provider == null) {
-            throw new IllegalStateException("MailAppProvider not intialized");
-        }
-        provider.addAccountImpl(account, accountsQueryUri, true /* notify */);
-
-        // Cache the updated account list
-        provider.cacheAccountList();
-    }
-
     private void addAccountImpl(Account account, Uri accountsQueryUri, boolean notify) {
         addAccountImpl(account.uri, new AccountCacheEntry(account, accountsQueryUri));
 
diff --git a/src/com/android/mail/providers/Message.java b/src/com/android/mail/providers/Message.java
index 0b71c69..4594ae1 100644
--- a/src/com/android/mail/providers/Message.java
+++ b/src/com/android/mail/providers/Message.java
@@ -482,6 +482,10 @@
         return mFromAddresses;
     }
 
+    public String[] getFromAddressesUnescaped() {
+        return unescapeAddresses(getFromAddresses());
+    }
+
     public synchronized String[] getToAddresses() {
         if (mToAddresses == null) {
             mToAddresses = tokenizeAddresses(mTo);
@@ -489,6 +493,10 @@
         return mToAddresses;
     }
 
+    public String[] getToAddressesUnescaped() {
+        return unescapeAddresses(getToAddresses());
+    }
+
     public synchronized String[] getCcAddresses() {
         if (mCcAddresses == null) {
             mCcAddresses = tokenizeAddresses(mCc);
@@ -496,6 +504,10 @@
         return mCcAddresses;
     }
 
+    public String[] getCcAddressesUnescaped() {
+        return unescapeAddresses(getCcAddresses());
+    }
+
     public synchronized String[] getBccAddresses() {
         if (mBccAddresses == null) {
             mBccAddresses = tokenizeAddresses(mBcc);
@@ -503,6 +515,10 @@
         return mBccAddresses;
     }
 
+    public String[] getBccAddressesUnescaped() {
+        return unescapeAddresses(getBccAddresses());
+    }
+
     public synchronized String[] getReplyToAddresses() {
         if (mReplyToAddresses == null) {
             mReplyToAddresses = tokenizeAddresses(mReplyTo);
@@ -510,10 +526,24 @@
         return mReplyToAddresses;
     }
 
+    public String[] getReplyToAddressesUnescaped() {
+        return unescapeAddresses(getReplyToAddresses());
+    }
+
+    private static String[] unescapeAddresses(String[] escaped) {
+        final String[] unescaped = new String[escaped.length];
+        for (int i = 0; i < escaped.length; i++) {
+            final String escapeMore = escaped[i].replace("<", "&lt;").replace(">", "&gt;");
+            unescaped[i] = Html.fromHtml(escapeMore).toString();
+        }
+        return unescaped;
+    }
+
     public static String[] tokenizeAddresses(String addresses) {
         if (TextUtils.isEmpty(addresses)) {
             return new String[0];
         }
+
         Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addresses);
         String[] strings = new String[tokens.length];
         for (int i = 0; i < tokens.length;i++) {
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index c6565bf..89b4034 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -125,6 +125,13 @@
     public static final String LABEL_QUERY_PARAMETER = "label";
     public static final String SEEN_QUERY_PARAMETER = "seen";
 
+    /**
+     * Query parameter that can be used to specify a parent for a the returned folder object from a
+     * query. When set, if a folder is returned that does not have a true parent, it will use this
+     * uri as its parent uri.
+     */
+    public static final String DEFAULT_PARENT_QUERY_PARAMETER = "defaultParent";
+
     public static final Map<String, Class<?>> ACCOUNTS_COLUMNS_NO_CAPABILITIES =
             new ImmutableMap.Builder<String, Class<?>>()
             .put(AccountColumns._ID, Integer.class)
diff --git a/src/com/android/mail/providers/protos/mock/MockRespondMatrixCursor.java b/src/com/android/mail/providers/protos/mock/MockRespondMatrixCursor.java
new file mode 100644
index 0000000..1409f88
--- /dev/null
+++ b/src/com/android/mail/providers/protos/mock/MockRespondMatrixCursor.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2013, Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.providers.protos.mock;
+
+import android.os.Bundle;
+import android.os.Parcelable;
+
+import com.android.mail.utils.LogUtils;
+import com.android.mail.utils.MatrixCursorWithCachedColumns;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class MockRespondMatrixCursor extends MatrixCursorWithCachedColumns{
+    private static final String LOG_TAG = "MockProvider";
+
+    static final String MOCK_RESPOND_PREFIX = "respond_";
+
+    final List<Map<String, Object>> mResultList;
+
+    public MockRespondMatrixCursor(final String[] columnNames, final int initialCapacity,
+            List<Map<String, Object>> queryResults) {
+        super(columnNames, initialCapacity);
+        mResultList = queryResults;
+    }
+
+    @Override
+    public Bundle respond(Bundle request) {
+        final Bundle response = new Bundle();
+
+        final int pos = getPosition();
+        if (pos >= mResultList.size()) {
+            LogUtils.wtf(LOG_TAG, "Unexpected position");
+            return response;
+        }
+
+        final Map<String, Object> rowData = mResultList.get(pos);
+
+        // For each of the keys in the request, we want to see if there is a mock response for the
+        // request
+        final Set<String> bundleKeys = request.keySet();
+        for (String key : bundleKeys) {
+            final Object responseData = rowData.get(MOCK_RESPOND_PREFIX + key);
+            if (responseData != null) {
+                response.putParcelable(key, (Parcelable)responseData);
+            }
+        }
+
+        return response;
+    }
+}
diff --git a/src/com/android/mail/providers/protos/mock/MockUiProvider.java b/src/com/android/mail/providers/protos/mock/MockUiProvider.java
index 1055b42..103f5d4 100644
--- a/src/com/android/mail/providers/protos/mock/MockUiProvider.java
+++ b/src/com/android/mail/providers/protos/mock/MockUiProvider.java
@@ -21,31 +21,26 @@
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
-import android.os.Parcel;
 import android.provider.BaseColumns;
 import android.text.Html;
 
-import com.android.mail.providers.Account;
 import com.android.mail.providers.ConversationInfo;
 import com.android.mail.providers.Folder;
 import com.android.mail.providers.FolderList;
-import com.android.mail.providers.MailAppProvider;
 import com.android.mail.providers.MessageInfo;
 import com.android.mail.providers.ReplyFromAccount;
-import com.android.mail.providers.Settings;
 import com.android.mail.providers.UIProvider.AccountCapabilities;
 import com.android.mail.providers.UIProvider.AccountColumns;
 import com.android.mail.providers.UIProvider.AccountColumns.SettingsColumns;
 import com.android.mail.providers.UIProvider.AttachmentColumns;
 import com.android.mail.providers.UIProvider.ConversationColumns;
+import com.android.mail.providers.UIProvider.ConversationCursorCommand;
 import com.android.mail.providers.UIProvider.FolderCapabilities;
 import com.android.mail.providers.UIProvider.FolderColumns;
 import com.android.mail.providers.UIProvider.MessageColumns;
-import com.android.mail.utils.MatrixCursorWithCachedColumns;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
@@ -61,144 +56,130 @@
 
     public static final String AUTHORITY = "com.android.mail.mockprovider";
 
+    private static final int NUM_ACCOUNTS = 5;
 
-    static final String BASE_URI_STRING = "content://" + AUTHORITY;
 
     private static final Uri MOCK_ACCOUNTS_URI = Uri.parse("content://" + AUTHORITY + "/accounts");
 
-
-    public static final int NUM_MOCK_ACCOUNTS = 2;
-
     // A map of query result for uris
-    // TODO(pwestbro) read this map from an external
+    // TODO(pwestbro) read this map from an external file
     private static Map<String, List<Map<String, Object>>> MOCK_QUERY_RESULTS = Maps.newHashMap();
 
+    private static void initializeAccount(int accountId,
+            Map<String, List<Map<String, Object>>> resultMap) {
+        final Map<String, Object> inboxfolderDetailsMap =
+                createFolderDetailsMap(0, accountId, "zero", true, 0, 2);
+        resultMap.put(inboxfolderDetailsMap.get(FolderColumns.URI).toString(),
+                ImmutableList.of(inboxfolderDetailsMap));
 
-    public static void initializeMockProvider() {
-        ImmutableMap.Builder<String, List<Map<String, Object>>> builder = ImmutableMap.builder();
+        final Map<String, Object> accountDetailsMap = createAccountDetailsMap(accountId,
+                (String)inboxfolderDetailsMap.get(FolderColumns.URI));
+        resultMap.put(((Uri) accountDetailsMap.get(AccountColumns.URI)).toString(),
+                ImmutableList.of(accountDetailsMap));
 
-        // Add results for account list
-        final List<Map<String, Object>> accountList = Lists.newArrayList();
-        Map<String, Object> accountDetailsMap0;
-        Map<String, Object> folderDetailsMap0 = createFolderDetailsMap(0, "zero", true, 0, 2);
-        builder.put(folderDetailsMap0.get(FolderColumns.URI).toString(),
-                ImmutableList.of(folderDetailsMap0));
-        Map<String, Object> folderDetailsMap2 = createFolderDetailsMap(2, "two", 2, 2);
-        // Account 0
-        accountDetailsMap0 = createAccountDetailsMap(0, true,
-                (String)folderDetailsMap0.get(FolderColumns.URI));
+        final Map<String, Object> secondFolderDetailsMap =
+                createFolderDetailsMap(2, accountId, "two", 2, 2);
+        resultMap.put(secondFolderDetailsMap.get(FolderColumns.URI).toString(),
+                ImmutableList.of(secondFolderDetailsMap));
 
-        accountList.add(accountDetailsMap0);
-        builder.put(((Uri) accountDetailsMap0.get(AccountColumns.URI)).toString(),
-                ImmutableList.of(accountDetailsMap0));
+        resultMap.put(
+                inboxfolderDetailsMap.get(FolderColumns.CHILD_FOLDERS_LIST_URI).toString(),
+                ImmutableList.of(createFolderDetailsMap(10, accountId, "zeroChild0", 0, 0),
+                        createFolderDetailsMap(11, accountId, "zeroChild1", 0, 0)));
 
-        // Account 1
-        Map<String, Object> accountDetailsMap1 = createAccountDetailsMap(1, true,
-                (String)folderDetailsMap2.get(FolderColumns.URI));
-        accountList.add(accountDetailsMap1);
-
-        builder.put(((Uri) accountDetailsMap1.get(AccountColumns.URI)).toString(),
-                ImmutableList.of(accountDetailsMap1));
-
-        // Account 2
-
-        Map<String, Object> accountDetailsMap2 = createAccountDetailsMap(2, true,
-                (String)folderDetailsMap0.get(FolderColumns.URI));
-        accountList.add(accountDetailsMap2);
-        builder.put(((Uri) accountDetailsMap2.get(AccountColumns.URI)).toString(),
-                ImmutableList.of(accountDetailsMap2));
-
-        // Account 3
-        Map<String, Object> accountDetailsMap3 = createAccountDetailsMap(3, true,
-                (String)folderDetailsMap2.get(FolderColumns.URI));
-        accountList.add(accountDetailsMap3);
-        builder.put(((Uri) accountDetailsMap3.get(AccountColumns.URI)).toString(),
-                ImmutableList.of(accountDetailsMap3));
-
-        // Add the account list to the builder
-        builder.put(getAccountsUri().toString(), accountList);
-
-        builder.put(
-                folderDetailsMap0.get(FolderColumns.CHILD_FOLDERS_LIST_URI).toString(),
-                ImmutableList.of(createFolderDetailsMap(10, "zeroChild0", 0, 0),
-                        createFolderDetailsMap(11, "zeroChild1", 0, 0)));
-
-
-        ArrayList<Map<String, Object>> conversations = new ArrayList<Map<String, Object>>();
+        final ArrayList<Map<String, Object>> conversations = new ArrayList<Map<String, Object>>();
         for (int i = 0; i < 100; i++) {
-            String name = "zeroConv"+i;
-            conversations.add(createConversationDetailsMap(name.hashCode(),
-                    name, 1, 5, 2));
+            final String name = "zeroConv"+i;
+            conversations.add(createConversationDetailsMap(accountId, name.hashCode(),
+                    name, 1, 5, i % 2));
         }
-        builder.put(folderDetailsMap0.get(FolderColumns.CONVERSATION_LIST_URI).toString(),
+        resultMap.put(inboxfolderDetailsMap.get(FolderColumns.CONVERSATION_LIST_URI).toString(),
                 conversations);
 
-        Map<String, Object> message0 = createMessageDetailsMap("zeroConv0".hashCode(), "zeroConv0",
-                1, false);
-        builder.put(message0.get(MessageColumns.URI).toString(), ImmutableList.of(message0));
-        builder.put(conversations.get(0).get(ConversationColumns.MESSAGE_LIST_URI).toString(),
+        final Map<String, Object> message0 =
+                createMessageDetailsMap(accountId, "zeroConv0".hashCode(), "zeroConv0", 1, false);
+        resultMap.put(message0.get(MessageColumns.URI).toString(), ImmutableList.of(message0));
+        resultMap.put(conversations.get(0).get(ConversationColumns.MESSAGE_LIST_URI).toString(),
                 ImmutableList.of(message0));
-        builder.put(message0.get(MessageColumns.ATTACHMENT_LIST_URI).toString(),
+        resultMap.put(message0.get(MessageColumns.ATTACHMENT_LIST_URI).toString(),
                 ImmutableList.of(createAttachmentDetailsMap(0, "zero")));
-        Map<String, Object> message1 = createMessageDetailsMap("zeroConv1".hashCode(), "zeroConv1",
-                1, false);
-        builder.put(message1.get(MessageColumns.URI).toString(), ImmutableList.of(message1));
-        Map<String, Object> message1a = createMessageDetailsMap("zeroConv1a".hashCode(), "zeroConv1a",
-                2, false);
-        builder.put(message1a.get(MessageColumns.URI).toString(), ImmutableList.of(message1a));
-        builder.put(conversations.get(1).get(ConversationColumns.MESSAGE_LIST_URI).toString(),
+        final Map<String, Object> message1 =
+                createMessageDetailsMap(accountId, "zeroConv1".hashCode(), "zeroConv1", 1, false);
+        resultMap.put(message1.get(MessageColumns.URI).toString(), ImmutableList.of(message1));
+        final Map<String, Object> message1a =
+                createMessageDetailsMap(accountId, "zeroConv1a".hashCode(), "zeroConv1a", 2, false);
+        resultMap.put(message1a.get(MessageColumns.URI).toString(), ImmutableList.of(message1a));
+        resultMap.put(conversations.get(1).get(ConversationColumns.MESSAGE_LIST_URI).toString(),
                 ImmutableList.of(message1, message1a));
-        builder.put(message1.get(MessageColumns.ATTACHMENT_LIST_URI).toString(),
+        resultMap.put(message1.get(MessageColumns.ATTACHMENT_LIST_URI).toString(),
                 ImmutableList.of(createAttachmentDetailsMap(1, "one")));
 
-        Map<String, Object> folderDetailsMap1 = createFolderDetailsMap(1, "one", 0, 0);
-        builder.put(folderDetailsMap1.get(FolderColumns.URI).toString(),
+        final Map<String, Object> folderDetailsMap1 =
+                createFolderDetailsMap(1, accountId,  "one", 0, 0);
+        resultMap.put(folderDetailsMap1.get(FolderColumns.URI).toString(),
                 ImmutableList.of(folderDetailsMap1));
-        builder.put(accountDetailsMap0.get(AccountColumns.FOLDER_LIST_URI).toString(),
-                ImmutableList.of(folderDetailsMap0, folderDetailsMap1));
 
-        builder.put(folderDetailsMap2.get(FolderColumns.URI).toString(),
-                ImmutableList.of(folderDetailsMap2));
-        Map<String, Object> folderDetailsMap3 = createFolderDetailsMap(3, "three", 0, 0);
-        builder.put(folderDetailsMap3.get(FolderColumns.URI).toString(),
-                ImmutableList.of(folderDetailsMap3));
-        builder.put(accountDetailsMap1.get(AccountColumns.FOLDER_LIST_URI).toString(),
-                ImmutableList.of(folderDetailsMap2, folderDetailsMap3));
+        // We currently have two configurations for accounts
+        if (accountId % 2 == 0) {
+            resultMap.put(accountDetailsMap.get(AccountColumns.FOLDER_LIST_URI).toString(),
+                    ImmutableList.of(inboxfolderDetailsMap, folderDetailsMap1));
+        } else {
+            resultMap.put(secondFolderDetailsMap.get(FolderColumns.URI).toString(),
+                    ImmutableList.of(secondFolderDetailsMap));
+            final Map<String, Object> folderDetailsMap3 =
+                    createFolderDetailsMap(3, accountId, "three", 0, 0);
+            resultMap.put(folderDetailsMap3.get(FolderColumns.URI).toString(),
+                    ImmutableList.of(folderDetailsMap3));
 
-        builder.put(accountDetailsMap2.get(AccountColumns.FOLDER_LIST_URI).toString(),
-                ImmutableList.of(folderDetailsMap0, folderDetailsMap1));
+            resultMap.put(accountDetailsMap.get(AccountColumns.FOLDER_LIST_URI).toString(),
+                    ImmutableList.of(secondFolderDetailsMap, folderDetailsMap3));
+        }
 
-        builder.put(accountDetailsMap3.get(AccountColumns.FOLDER_LIST_URI).toString(),
-                ImmutableList.of(folderDetailsMap0, folderDetailsMap1));
-
-        Map<String, Object> conv3 = createConversationDetailsMap("zeroConv3".hashCode(),
-                "zeroConv3", 0, 1, 0);
-        builder.put(conv3.get(ConversationColumns.URI).toString(),
+        final Map<String, Object> conv3 =
+                createConversationDetailsMap(accountId, "zeroConv3".hashCode(), "zeroConv3",
+                        0, 1, 0);
+        resultMap.put(conv3.get(ConversationColumns.URI).toString(),
                 ImmutableList.of(conv3));
-        Map<String, Object> conv4 = createConversationDetailsMap("zeroConv4".hashCode(),
-                "zeroConv4", 0, 1, 0);
-        builder.put(conv4.get(ConversationColumns.URI).toString(),
+        final Map<String, Object> conv4 =
+                createConversationDetailsMap(accountId, "zeroConv4".hashCode(), "zeroConv4",
+                        0, 1, 0);
+        resultMap.put(conv4.get(ConversationColumns.URI).toString(),
                 ImmutableList.of(conv4));
-        builder.put(folderDetailsMap2.get(FolderColumns.CONVERSATION_LIST_URI).toString(),
+        resultMap.put(secondFolderDetailsMap.get(FolderColumns.CONVERSATION_LIST_URI).toString(),
                 ImmutableList.of(conv3, conv4));
 
-        Map<String, Object> message2 = createMessageDetailsMap("zeroConv3".hashCode(), "zeroConv3",
-                0, true);
-        builder.put(message2.get(MessageColumns.URI).toString(), ImmutableList.of(message2));
-        builder.put(conv3.get(ConversationColumns.MESSAGE_LIST_URI).toString(),
+        final Map<String, Object> message2 =
+                createMessageDetailsMap(accountId, "zeroConv3".hashCode(), "zeroConv3", 0, true);
+        resultMap.put(message2.get(MessageColumns.URI).toString(), ImmutableList.of(message2));
+        resultMap.put(conv3.get(ConversationColumns.MESSAGE_LIST_URI).toString(),
                 ImmutableList.of(message2));
-        Map<String, Object> message3 = createMessageDetailsMap("zeroConv4".hashCode(), "zeroConv4",
-                0, true);
-        builder.put(message3.get(MessageColumns.URI).toString(), ImmutableList.of(message3));
-        builder.put(conv4.get(ConversationColumns.MESSAGE_LIST_URI).toString(),
+        final Map<String, Object> message3 =
+                createMessageDetailsMap(accountId, "zeroConv4".hashCode(), "zeroConv4", 0, true);
+        resultMap.put(message3.get(MessageColumns.URI).toString(), ImmutableList.of(message3));
+        resultMap.put(conv4.get(ConversationColumns.MESSAGE_LIST_URI).toString(),
                 ImmutableList.of(message3));
 
-        MOCK_QUERY_RESULTS = builder.build();
+        // Add the account to the list of accounts
+        List<Map<String, Object>> accountList = resultMap.get(getAccountsUri().toString());
+        if (accountList == null) {
+            accountList = Lists.newArrayList();
+            resultMap.put(getAccountsUri().toString(), accountList);
+        }
+        accountList.add(accountDetailsMap);
     }
 
-    private static Map<String, Object> createConversationDetailsMap(int conversationId,
-            String subject, int hasAttachments, int messageCount, int draftCount) {
-        final String conversationUri = "content://" + AUTHORITY + "/conversation/" + conversationId;
+    public static void initializeMockProvider() {
+        MOCK_QUERY_RESULTS = Maps.newHashMap();
+
+        for (int accountId = 0; accountId < NUM_ACCOUNTS; accountId++) {
+            initializeAccount(accountId, MOCK_QUERY_RESULTS);
+        }
+    }
+
+    private static Map<String, Object> createConversationDetailsMap(int accountId,
+            int conversationId, String subject, int hasAttachments, int messageCount,
+            int draftCount) {
+        final String conversationUri = getMockConversationUri(accountId, conversationId);
         Map<String, Object> conversationMap = Maps.newHashMap();
         conversationMap.put(BaseColumns._ID, Long.valueOf(conversationId));
         conversationMap.put(ConversationColumns.URI, conversationUri);
@@ -237,10 +218,11 @@
             }
 
             folders.add(folder);
-
         }
         final FolderList folderList = FolderList.copyOf(folders);
-        conversationMap.put(ConversationColumns.RAW_FOLDERS, folderList);
+        conversationMap.put(
+                MockRespondMatrixCursor.MOCK_RESPOND_PREFIX +
+                        ConversationCursorCommand.COMMAND_GET_RAW_FOLDERS, folderList);
         return conversationMap;
     }
 
@@ -262,9 +244,10 @@
         return info.toBlob();
     }
 
-    private static Map<String, Object> createMessageDetailsMap(int messageId, String subject,
-            int hasAttachments, boolean addReplyTo) {
-        final String messageUri = "content://" + AUTHORITY + "/message/" + messageId;
+    private static Map<String, Object> createMessageDetailsMap(int accountId, int messageId,
+            String subject, int hasAttachments, boolean addReplyTo) {
+        final String accountUri = getMockAccountUri(accountId);
+        final String messageUri = getMockMessageUri(accountId, messageId);
         Map<String, Object> messageMap = Maps.newHashMap();
         messageMap.put(BaseColumns._ID, Long.valueOf(messageId));
         messageMap.put(MessageColumns.URI, messageUri);
@@ -278,6 +261,7 @@
         messageMap.put(MessageColumns.ATTACHMENT_LIST_URI, messageUri + "/getAttachments");
         messageMap.put(MessageColumns.TO, "account1@mock.com, account2@mock.com");
         messageMap.put(MessageColumns.FROM, "fromaccount1@mock.com");
+        messageMap.put(MessageColumns.MESSAGE_ACCOUNT_URI, accountUri);
         return messageMap;
     }
 
@@ -290,14 +274,15 @@
         return attachmentMap;
     }
 
-    private static Map<String, Object> createFolderDetailsMap(int folderId, String name,
-            int unread, int total) {
-        return createFolderDetailsMap(folderId, name, false, unread, total);
+    private static Map<String, Object> createFolderDetailsMap(int folderId, int accountId,
+            String name, int unread, int total) {
+        return createFolderDetailsMap(folderId, accountId, name, false, unread, total);
     }
 
-    private static Map<String, Object> createFolderDetailsMap(int folderId, String name,
-            boolean hasChildren, int unread, int total) {
-        final String folderUri = "content://" + AUTHORITY + "/folder/" + folderId;
+    private static Map<String, Object> createFolderDetailsMap(int folderId, int accountId,
+            String name, boolean hasChildren, int unread, int total) {
+        final String folderUri = getMockAccountFolderUri(accountId, folderId);
+
         Map<String, Object> folderMap = Maps.newHashMap();
         folderMap.put(BaseColumns._ID, Long.valueOf(folderId));
         folderMap.put(FolderColumns.URI, folderUri);
@@ -319,12 +304,12 @@
     }
 
     // Temporarily made this public to allow the Gmail accounts to use the mock ui provider uris
-    public static Map<String, Object> createAccountDetailsMap(int accountId, boolean cacheMap,
-            String defaultInbox) {
+    public static Map<String, Object> createAccountDetailsMap(int accountId,String defaultInbox) {
         final String accountUri = getMockAccountUri(accountId);
         Map<String, Object> accountMap = Maps.newHashMap();
         accountMap.put(BaseColumns._ID, Long.valueOf(accountId));
         accountMap.put(AccountColumns.NAME, "account" + accountId + "@mockuiprovider.com");
+        accountMap.put(AccountColumns.TYPE, "com.android.mail.providers.protos.mock");
         accountMap.put(AccountColumns.PROVIDER_VERSION, Long.valueOf(1));
         accountMap.put(AccountColumns.URI, Uri.parse(accountUri));
         accountMap.put(AccountColumns.CAPABILITIES,
@@ -353,12 +338,15 @@
         }
         accountMap.put(AccountColumns.ACCOUNT_FROM_ADDRESSES, replyFroms.toString());
         accountMap.put(AccountColumns.FOLDER_LIST_URI, Uri.parse(accountUri + "/folders"));
+        accountMap.put(AccountColumns.FULL_FOLDER_LIST_URI, Uri.parse(accountUri + "/folders"));
         accountMap.put(AccountColumns.SEARCH_URI, Uri.parse(accountUri + "/search"));
         accountMap.put(AccountColumns.EXPUNGE_MESSAGE_URI,
                 Uri.parse(accountUri + "/expungeMessage"));
         accountMap.put(AccountColumns.UNDO_URI, Uri.parse(accountUri + "/undo"));
         accountMap.put(AccountColumns.SETTINGS_INTENT_URI, Uri.EMPTY);
         accountMap.put(AccountColumns.HELP_INTENT_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.SEND_FEEDBACK_INTENT_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.REAUTHENTICATION_INTENT_URI, Uri.EMPTY);
         accountMap.put(AccountColumns.SYNC_STATUS, 0);
         accountMap.put(AccountColumns.COMPOSE_URI, Uri.parse(accountUri + "/compose"));
         accountMap.put(AccountColumns.RECENT_FOLDER_LIST_URI,
@@ -366,18 +354,34 @@
         accountMap.put(AccountColumns.MIME_TYPE, "account/mock");
         accountMap.put(AccountColumns.COLOR, 0);
         accountMap.put(AccountColumns.RECENT_FOLDER_LIST_URI, Uri.EMPTY);
-        accountMap.put(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI,
-                Uri.EMPTY);
-        accountMap.put(AccountColumns.MANUAL_SYNC_URI,
-                Uri.EMPTY);
-        accountMap.put(AccountColumns.VIEW_INTENT_PROXY_URI,
-                Uri.EMPTY);
+        accountMap.put(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.MANUAL_SYNC_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.VIEW_INTENT_PROXY_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.ACCOUNT_COOKIE_QUERY_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.UPDATE_SETTINGS_URI, Uri.EMPTY);
+        accountMap.put(AccountColumns.ENABLE_MESSAGE_TRANSFORMS, 1);
 
-        // TODO: store the default inbox
+
+        // Add settings columns
+        accountMap.put(SettingsColumns.SIGNATURE, "");
+        accountMap.put(SettingsColumns.AUTO_ADVANCE, 1);
+        accountMap.put(SettingsColumns.MESSAGE_TEXT_SIZE, 1);
+        accountMap.put(SettingsColumns.SNAP_HEADERS, 1);
+        accountMap.put(SettingsColumns.REPLY_BEHAVIOR, 1);
+        accountMap.put(SettingsColumns.CONV_LIST_ICON, 1);
+        accountMap.put(SettingsColumns.CONFIRM_DELETE, 1);
+        accountMap.put(SettingsColumns.CONFIRM_ARCHIVE, 1);
+        accountMap.put(SettingsColumns.CONFIRM_SEND, 1);
         accountMap.put(SettingsColumns.DEFAULT_INBOX, defaultInbox);
-        if (cacheMap) {
-            addAccountInfoToAccountCache(accountMap);
-        }
+        accountMap.put(SettingsColumns.DEFAULT_INBOX_NAME, "Inbox");
+        accountMap.put(SettingsColumns.FORCE_REPLY_FROM_DEFAULT, 1);
+        accountMap.put(SettingsColumns.MAX_ATTACHMENT_SIZE, 25 * 1024 * 1024);
+        accountMap.put(SettingsColumns.SWIPE, 1);
+        accountMap.put(SettingsColumns.PRIORITY_ARROWS_ENABLED, 1);
+        accountMap.put(SettingsColumns.SETUP_INTENT_URI, Uri.EMPTY);
+        accountMap.put(SettingsColumns.CONVERSATION_VIEW_MODE, 1);
+        accountMap.put(SettingsColumns.VEILED_ADDRESS_PATTERN, null);
+        accountMap.put(SettingsColumns.MOVE_TO_INBOX, Uri.EMPTY);
         return accountMap;
     }
 
@@ -385,6 +389,18 @@
         return "content://" + AUTHORITY + "/account/" + accountId;
     }
 
+    private static String getMockAccountFolderUri(int accountId, int folderId) {
+        return getMockAccountUri(accountId) + "/folder/" + folderId;
+    }
+
+    private static String getMockConversationUri(int accountId, int conversationId) {
+        return getMockAccountUri(accountId) + "/conversation/" + conversationId;
+    }
+
+    private static String getMockMessageUri(int accountId, int messageId) {
+        return getMockAccountUri(accountId) + "/message/" + messageId;
+    }
+
     @Override
     public boolean onCreate() {
         MockUiProvider.initializeMockProvider();
@@ -395,10 +411,7 @@
     public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
             String sortOrder) {
 
-        // TODO (pwestbro): respect the projection that is specified by the caller
-
-        final List<Map<String, Object>> queryResults =
-                MOCK_QUERY_RESULTS.get(url.toString());
+        final List<Map<String, Object>> queryResults = MOCK_QUERY_RESULTS.get(url.toString());
 
         if (queryResults != null && queryResults.size() > 0) {
             // Get the projection.  If there are rows in the result set, pick the first item to
@@ -408,8 +421,8 @@
                 Set<String> keys = queryResults.get(0).keySet();
                 projection = keys.toArray(new String[keys.size()]);
             }
-            MatrixCursor matrixCursor =
-                    new MatrixCursorWithCachedColumns(projection, queryResults.size());
+            final MatrixCursor matrixCursor =
+                    new MockRespondMatrixCursor(projection, queryResults.size(), queryResults);
 
             for (Map<String, Object> queryResult : queryResults) {
                 MatrixCursor.RowBuilder rowBuilder = matrixCursor.newRow();
@@ -447,61 +460,7 @@
 
     @VisibleForTesting
     static Uri getAccountsUri() {
-        // TODO: this should probably return a different specific to the mock account list
-        return Uri.parse(BASE_URI_STRING + "/");
-    }
-
-    private static void addAccountInfoToAccountCache(Map<String, Object> accountInfo) {
-        final Parcel dest = Parcel.obtain();
-        dest.writeString((String) accountInfo.get(AccountColumns.NAME));
-        dest.writeString("mock");
-
-        final int providerVersion = 1;
-        dest.writeInt(providerVersion);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.URI), 0);
-        dest.writeInt((Integer) accountInfo.get(AccountColumns.CAPABILITIES));
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.FOLDER_LIST_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.FULL_FOLDER_LIST_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.SEARCH_URI), 0);
-        dest.writeString((String) accountInfo.get(AccountColumns.ACCOUNT_FROM_ADDRESSES));
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.EXPUNGE_MESSAGE_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.UNDO_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.SETTINGS_INTENT_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.HELP_INTENT_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.SEND_FEEDBACK_INTENT_URI), 0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.REAUTHENTICATION_INTENT_URI), 0);
-        dest.writeInt((Integer) accountInfo.get(AccountColumns.SYNC_STATUS));
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.COMPOSE_URI), 0);
-        dest.writeString((String) accountInfo.get(AccountColumns.MIME_TYPE));
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.RECENT_FOLDER_LIST_URI), 0);
-        dest.writeInt((Integer) accountInfo.get(AccountColumns.COLOR));
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI),
-                0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.MANUAL_SYNC_URI),
-                0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.VIEW_INTENT_PROXY_URI),
-                0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.ACCOUNT_COOKIE_QUERY_URI),
-                0);
-        dest.writeParcelable((Uri) accountInfo.get(AccountColumns.UPDATE_SETTINGS_URI),
-                0);
-        Parcel p = Parcel.obtain();
-        p.writeString("");
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeString((String)accountInfo.get(SettingsColumns.DEFAULT_INBOX));
-        p.writeInt(1);
-        p.setDataPosition(0);
-        dest.writeString(new Settings(p).serialize());
-        dest.setDataPosition(0);
-        final Account account = new Account(dest);
-        MailAppProvider.addAccount(account, MOCK_ACCOUNTS_URI);
+        return MOCK_ACCOUNTS_URI;
     }
 }
 
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index fe12594..6aec68c 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -99,7 +99,6 @@
 import com.android.mail.utils.Observable;
 import com.android.mail.utils.Utils;
 import com.android.mail.utils.VeiledAddressMatcher;
-
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
@@ -941,7 +940,7 @@
         }
         // If the previous folder was null, or if the two folders represent different data, then we
         // consider that the folder has changed.
-        if (mFolder == null || !newFolder.uri.equals(mFolder.uri)) {
+        if (mFolder == null || !newFolder.equals(mFolder)) {
             mFolderChanged = true;
         }
     }
@@ -1185,8 +1184,11 @@
         mRecentFolderList.initialize(mActivity);
         mVeiledMatcher.initialize(this);
 
+        // the "open drawer description" argument is for when the drawer is open
+        // so tell the user that interacting will cause the drawer to close
+        // and vice versa for the "close drawer description" argument
         mDrawerToggle = new ActionBarDrawerToggle((Activity) mActivity, mDrawerContainer,
-                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
+                R.drawable.ic_drawer, R.string.drawer_close, R.string.drawer_open);
         mDrawerListener = new MailDrawerListener();
         mDrawerContainer.setDrawerListener(mDrawerListener);
         mDrawerContainer.setDrawerShadow(
@@ -2120,8 +2122,7 @@
         // If search list/conv mode: disable indicator
         // Indicator is enabled either in conversation list or folder list mode.
         return isDrawerEnabled() && !ViewMode.isSearchMode(viewMode)
-            && (viewMode == ViewMode.FOLDER_LIST
-                || (viewMode == ViewMode.CONVERSATION_LIST  && isTopLevel));
+            && (viewMode == ViewMode.CONVERSATION_LIST  && isTopLevel);
     }
 
     /**
@@ -2282,7 +2283,7 @@
             } else if (intent.hasExtra(Utils.EXTRA_FOLDER)) {
                 final Folder folder =
                         Folder.fromString(intent.getStringExtra(Utils.EXTRA_FOLDER));
-                folderUri = folder.uri;
+                folderUri = folder.folderUri.fullUri;
             } else {
                 final Bundle extras = intent.getExtras();
                 LogUtils.d(LOG_TAG, "Couldn't find a folder URI in the extras: %s",
@@ -3125,7 +3126,7 @@
                     (UIProvider.FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES)
                 && folder.supportsCapability
                     (UIProvider.FolderCapabilities.CAN_HOLD_MAIL)
-                && !mFolder.uri.equals(folder.uri));
+                && !mFolder.equals(folder));
     }
 
     /**
@@ -3184,11 +3185,11 @@
             for (Conversation target : conversations) {
                 folderUris = new ArrayList<Uri>();
                 adds = new ArrayList<Boolean>();
-                folderUris.add(folder.uri);
+                folderUris.add(folder.folderUri.fullUri);
                 adds.add(Boolean.TRUE);
                 final HashMap<Uri, Folder> targetFolders =
                         Folder.hashMapForFolders(target.getRawFolders());
-                targetFolders.put(folder.uri, folder);
+                targetFolders.put(folder.folderUri.fullUri, folder);
                 ops.add(mConversationListCursor.getConversationFolderOperation(target,
                         folderUris, adds, targetFolders.values()));
             }
@@ -3240,14 +3241,14 @@
             for (Conversation target : mConversations) {
                 folderUris = new ArrayList<Uri>();
                 adds = new ArrayList<Boolean>();
-                folderUris.add(mStarred.uri);
+                folderUris.add(mStarred.folderUri.fullUri);
                 adds.add(Boolean.TRUE);
-                folderUris.add(mInitialFolder.uri);
+                folderUris.add(mInitialFolder.folderUri.fullUri);
                 adds.add(Boolean.FALSE);
                 final HashMap<Uri, Folder> targetFolders =
                         Folder.hashMapForFolders(target.getRawFolders());
-                targetFolders.put(mStarred.uri, mStarred);
-                targetFolders.remove(mInitialFolder.uri);
+                targetFolders.put(mStarred.folderUri.fullUri, mStarred);
+                targetFolders.remove(mInitialFolder.folderUri.fullUri);
                 values.put(ConversationColumns.STARRED, true);
                 operation = mConversationListCursor.getConversationFolderOperation(target,
                         folderUris, adds, targetFolders.values(), values);
@@ -3371,7 +3372,7 @@
                     LogUtils.d(LOG_TAG, "LOADER_FOLDER_CURSOR created");
                     final ObjectCursorLoader<Folder> loader = new
                             ObjectCursorLoader<Folder>(
-                            mContext, mFolder.uri, everything, Folder.FACTORY);
+                            mContext, mFolder.folderUri.fullUri, everything, Folder.FACTORY);
                     loader.setUpdateThrottle(mFolderItemUpdateDelayMs);
                     return loader;
                 case LOADER_RECENT_FOLDERS:
@@ -3750,12 +3751,12 @@
                     target.localDeleteOnUpdate = true;
                 }
                 for (FolderOperation op : mFolderOps) {
-                    folderUris.add(op.mFolder.uri);
+                    folderUris.add(op.mFolder.folderUri.fullUri);
                     adds.add(op.mAdd ? Boolean.TRUE : Boolean.FALSE);
                     if (op.mAdd) {
-                        targetFolders.put(op.mFolder.uri, op.mFolder);
+                        targetFolders.put(op.mFolder.folderUri.fullUri, op.mFolder);
                     } else {
-                        targetFolders.remove(op.mFolder.uri);
+                        targetFolders.remove(op.mFolder.folderUri.fullUri);
                     }
                 }
                 ops.add(mConversationListCursor.getConversationFolderOperation(target,
diff --git a/src/com/android/mail/ui/AbstractConversationWebViewClient.java b/src/com/android/mail/ui/AbstractConversationWebViewClient.java
index 0684b0c..dc59bce 100644
--- a/src/com/android/mail/ui/AbstractConversationWebViewClient.java
+++ b/src/com/android/mail/ui/AbstractConversationWebViewClient.java
@@ -67,11 +67,15 @@
 
         boolean result = false;
         final Intent intent;
-        Uri uri = Uri.parse(url);
+        final Uri uri = Uri.parse(url);
         if (mAccount != null && !Utils.isEmpty(mAccount.viewIntentProxyUri)) {
             intent = generateProxyIntent(uri);
         } else {
             intent = new Intent(Intent.ACTION_VIEW, uri);
+
+            // If this is a mailto: uri, we want to set the account name in the intent so
+            // the ComposeActivity can default to the current account
+            Utils.addAccountToMailtoIntent(intent, mAccount);
             intent.putExtra(Browser.EXTRA_APPLICATION_ID, mActivity.getPackageName());
         }
 
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index cdf9919..a8a995e 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -52,6 +52,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -86,6 +87,33 @@
     private final Handler mHandler;
     protected long mLastLeaveBehind = -1;
 
+    public interface ConversationListListener {
+        /**
+         * View the message at the given position.
+         *
+         * @param position The position of the conversation in the list (as opposed to its position
+         *        in the cursor)
+         */
+        void viewConversation(int position);
+
+        /**
+         * @return <code>true</code> if the list is in selection mode, <code>false</code> otherwise
+         */
+        boolean isInSelectionMode();
+
+        /**
+         * @return <code>true</code> if the list is just entering selection mode (so animations may
+         * be required), <code>false</code> otherwise
+         */
+        boolean isEnteringSelectionMode();
+
+        /**
+         * @return <code>true</code> if the list is just exiting selection mode (so animations may
+         * be required), <code>false</code> otherwise
+         */
+        boolean isExitingSelectionMode();
+    }
+
     private final AnimatorListener mAnimatorListener = new AnimatorListenerAdapter() {
 
         @Override
@@ -166,6 +194,7 @@
     /** True if priority inbox markers are enabled, false otherwise. */
     private boolean mPriorityMarkersEnabled;
     private final ControllableActivity mActivity;
+    private final ConversationListListener mConversationListListener;
     private final AccountObserver mAccountListener = new AccountObserver() {
         @Override
         public void onChanged(Account newAccount) {
@@ -193,6 +222,9 @@
     /** List of all child folders for this folder. */
     private List<NestedFolderView> mFolderViews;
 
+    private final SparseArray<WeakReference<ConversationSetObserver>> mItemViewSetObservers =
+            new SparseArray<WeakReference<ConversationSetObserver>>();
+
     private void setAccount(Account newAccount) {
         mAccount = newAccount;
         mPriorityMarkersEnabled = mAccount.settings.priorityArrowsEnabled;
@@ -204,13 +236,15 @@
 
     public AnimatedAdapter(Context context, ConversationCursor cursor,
             ConversationSelectionSet batch, ControllableActivity activity,
-            SwipeableListView listView, final List<ConversationSpecialItemView> specialViews,
+            final ConversationListListener conversationListListener, SwipeableListView listView,
+            final List<ConversationSpecialItemView> specialViews,
             final ObjectCursor<Folder> childFolders) {
         super(context, -1, cursor, UIProvider.CONVERSATION_PROJECTION, null, 0);
         mContext = context;
         mBatchConversations = batch;
         setAccount(mAccountListener.initialize(activity.getAccountController()));
         mActivity = activity;
+        mConversationListListener = conversationListListener;
         mShowFooter = false;
         mListView = listView;
         mFolderViews = getNestedFolders(childFolders);
@@ -349,12 +383,12 @@
     }
 
     public View createConversationItemView(SwipeableConversationItemView view, Context context,
-            Conversation conv) {
+            Conversation conv, final int position) {
         if (view == null) {
             view = new SwipeableConversationItemView(context, mAccount.name);
         }
-        view.bind(conv, mActivity, mBatchConversations, mFolder, getCheckboxSetting(),
-                mSwipeEnabled, mPriorityMarkersEnabled, this);
+        view.bind(conv, mActivity, mConversationListListener, mBatchConversations, mFolder,
+                getCheckboxSetting(), mSwipeEnabled, mPriorityMarkersEnabled, this, position);
         return view;
     }
 
@@ -515,7 +549,7 @@
             ((SwipeableConversationItemView) convertView).reset();
         }
         final View v = createConversationItemView((SwipeableConversationItemView) convertView,
-                mContext, conv);
+                mContext, conv, position);
         Utils.traceEndSection();
         return v;
     }
@@ -730,8 +764,8 @@
         SwipeableConversationItemView view = (SwipeableConversationItemView) super.getView(
                 position, null, parent);
         view.reset();
-        view.bind(conversation, mActivity, mBatchConversations, mFolder, getCheckboxSetting(),
-                mSwipeEnabled, mPriorityMarkersEnabled, this);
+        view.bind(conversation, mActivity, mConversationListListener, mBatchConversations, mFolder,
+                getCheckboxSetting(), mSwipeEnabled, mPriorityMarkersEnabled, this, position);
         mAnimatingViews.put(conversation.id, view);
         return view;
     }
@@ -1053,4 +1087,85 @@
             specialView.onCabModeEntered();
         }
     }
+
+    private final ConversationSetObserver mConversationSetObserver = new ConversationSetObserver() {
+        @Override
+        public void onSetPopulated(final ConversationSelectionSet set) {
+            pruneEntries();
+
+            for (int i = 0; i < mItemViewSetObservers.size(); i++) {
+                final WeakReference<ConversationSetObserver> ref = mItemViewSetObservers.valueAt(i);
+                final ConversationSetObserver observer = ref.get();
+
+                if (observer == null) {
+                    LogUtils.wtf(LOG_TAG, "ConversationSetObserver null after pruneEntries()");
+                } else {
+                    observer.onSetPopulated(set);
+                }
+            }
+        }
+
+        @Override
+        public void onSetEmpty() {
+            pruneEntries();
+
+            for (int i = 0; i < mItemViewSetObservers.size(); i++) {
+                final WeakReference<ConversationSetObserver> ref = mItemViewSetObservers.valueAt(i);
+                final ConversationSetObserver observer = ref.get();
+
+                if (observer == null) {
+                    LogUtils.wtf(LOG_TAG, "ConversationSetObserver null after pruneEntries()");
+                } else {
+                    observer.onSetEmpty();
+                }
+            }
+        }
+
+        @Override
+        public void onSetChanged(final ConversationSelectionSet set) {
+            pruneEntries();
+
+            for (int i = 0; i < mItemViewSetObservers.size(); i++) {
+                final WeakReference<ConversationSetObserver> ref = mItemViewSetObservers.valueAt(i);
+                final ConversationSetObserver observer = ref.get();
+
+                if (observer == null) {
+                    LogUtils.wtf(LOG_TAG, "ConversationSetObserver null after pruneEntries()");
+                } else {
+                    observer.onSetChanged(set);
+                }
+            }
+        }
+
+        private void pruneEntries() {
+            final int[] deadKeys = new int[mItemViewSetObservers.size()];
+            int deadKeyIndex = 0;
+
+            for (int i = 0; i < mItemViewSetObservers.size(); i++) {
+                final WeakReference<ConversationSetObserver> ref = mItemViewSetObservers.valueAt(i);
+                final ConversationSetObserver observer = ref.get();
+
+                if (observer == null) {
+                    deadKeys[deadKeyIndex++] = mItemViewSetObservers.keyAt(i);
+                }
+            }
+
+            for (int i = deadKeyIndex - 1; i >= 0; i--) {
+                mItemViewSetObservers.delete(deadKeys[i]);
+            }
+        }
+    };
+
+    public ConversationSetObserver getConversationSetObserver() {
+        return mConversationSetObserver;
+    }
+
+    public void registerConversationSetObserver(final ConversationSetObserver observer) {
+        mItemViewSetObservers.put(observer.hashCode(),
+                new WeakReference<ConversationSetObserver>(observer));
+    }
+
+    public void unregisterConversationSetObserver(final ConversationSetObserver observer) {
+        mItemViewSetObservers.delete(observer.hashCode());
+    }
 }
diff --git a/src/com/android/mail/ui/ConversationListFragment.java b/src/com/android/mail/ui/ConversationListFragment.java
index ddb52d7..34f7625 100644
--- a/src/com/android/mail/ui/ConversationListFragment.java
+++ b/src/com/android/mail/ui/ConversationListFragment.java
@@ -56,10 +56,10 @@
 import com.android.mail.providers.Settings;
 import com.android.mail.providers.UIProvider;
 import com.android.mail.providers.UIProvider.AccountCapabilities;
-import com.android.mail.providers.UIProvider.ConversationListIcon;
 import com.android.mail.providers.UIProvider.FolderCapabilities;
 import com.android.mail.providers.UIProvider.FolderType;
 import com.android.mail.providers.UIProvider.Swipe;
+import com.android.mail.ui.AnimatedAdapter.ConversationListListener;
 import com.android.mail.ui.SwipeableListView.ListItemSwipedListener;
 import com.android.mail.ui.SwipeableListView.ListItemsRemovedListener;
 import com.android.mail.ui.ViewMode.ModeChangeListener;
@@ -148,6 +148,13 @@
     /** Hash of the Conversation Cursor we last obtained from the controller. */
     private int mConversationCursorHash;
 
+    /** Duration, in milliseconds, of the CAB mode (peek icon) animation. */
+    private static long sSelectionModeAnimationDuration = -1;
+    /** The time at which we last entered CAB mode. */
+    private long mSelectionModeEnteredTimestamp = -1;
+    /** The time at which we last exited CAB mode. */
+    private long mSelectionModeExitedTimestamp = -1;
+
     /**
      * If the current list is for a folder with children, this set of loader callbacks will
      * create a loader for all the child folders, and will return an {@link ObjectCursor} over the
@@ -284,6 +291,12 @@
     @Override
     public void onActivityCreated(Bundle savedState) {
         super.onActivityCreated(savedState);
+
+        if (sSelectionModeAnimationDuration < 0) {
+            sSelectionModeAnimationDuration = getResources().getInteger(
+                    R.integer.conv_item_view_cab_anim_duration);
+        }
+
         // Strictly speaking, we get back an android.app.Activity from
         // getActivity. However, the
         // only activity creating a ConversationListContext is a MailActivity
@@ -336,7 +349,8 @@
         }
 
         mListAdapter = new AnimatedAdapter(mActivity.getApplicationContext(), conversationCursor,
-                        mActivity.getSelectedSet(), mActivity, mListView, specialItemViews, null);
+                mActivity.getSelectedSet(), mActivity, mConversationListListener, mListView,
+                specialItemViews, null);
         mListAdapter.addFooter(mFooterView);
         mListView.setAdapter(mListAdapter);
         mSelectedSet = mActivity.getSelectedSet();
@@ -568,7 +582,7 @@
      * <pre>
      *              | Checkboxes | No Checkboxes
      *    ----------+------------+---------------
-     *    CAB mode  |    Peek    |     Select
+     *    CAB mode  |   Select   |     Select
      *    List mode |    Peek    |      Peek
      * </pre>
      *
@@ -582,12 +596,10 @@
             final FolderSelector selector = mActivity.getFolderSelector();
             selector.onFolderSelected(((NestedFolderView) view).getFolder());
         } else if (view instanceof ToggleableItem) {
-            final boolean showSenderImage =
-                    (mAccount.settings.convListIcon == ConversationListIcon.SENDER_IMAGE);
-            if (!showSenderImage && !mSelectedSet.isEmpty()) {
+            if (!mSelectedSet.isEmpty()) {
                 ((ToggleableItem) view).toggleSelectedState();
             } else {
-                viewConversation(position);
+                mConversationListListener.viewConversation(position);
             }
         } else {
             // Ignore anything that is not a conversation item. Could be a footer.
@@ -609,11 +621,15 @@
         if (conversationCursor != null) {
             conversationCursor.handleNotificationActions();
         }
+
+        mSelectedSet.addObserver(mConversationSetObserver);
     }
 
     @Override
     public void onPause() {
         super.onPause();
+
+        mSelectedSet.removeObserver(mConversationSetObserver);
     }
 
     @Override
@@ -674,34 +690,49 @@
         onConversationListStatusUpdated();
     }
 
-    /**
-     * View the message at the given position.
-     *
-     * @param position The position of the conversation in the list (as opposed to its position in
-     *        the cursor)
-     */
-    protected void viewConversation(final int position) {
-        LogUtils.d(LOG_TAG, "ConversationListFragment.viewConversation(%d)", position);
+    private final ConversationListListener mConversationListListener =
+            new ConversationListListener() {
+        @Override
+        public void viewConversation(final int position) {
+            LogUtils.d(LOG_TAG, "ConversationListFragment.viewConversation(%d)", position);
 
-        final ConversationCursor cursor =
-                (ConversationCursor) getAnimatedAdapter().getItem(position);
+            final ConversationCursor cursor =
+                    (ConversationCursor) getAnimatedAdapter().getItem(position);
 
-        if (cursor == null) {
-            LogUtils.e(LOG_TAG,
-                    "unable to open conv at cursor pos=%s cursor=%s getPositionOffset=%s",
-                    position, cursor, getAnimatedAdapter().getPositionOffset(position));
-            return;
+            if (cursor == null) {
+                LogUtils.e(LOG_TAG,
+                        "unable to open conv at cursor pos=%s cursor=%s getPositionOffset=%s",
+                        position, cursor, getAnimatedAdapter().getPositionOffset(position));
+                return;
+            }
+
+            final Conversation conv = cursor.getConversation();
+            /*
+             * The cursor position may be different than the position method parameter because of
+             * special views in the list.
+             */
+            conv.position = cursor.getPosition();
+            setSelected(conv.position, true);
+            mCallbacks.onConversationSelected(conv, false /* inLoaderCallbacks */);
         }
 
-        final Conversation conv = cursor.getConversation();
-        /*
-         * The cursor position may be different than the position method parameter because of
-         * special views in the list.
-         */
-        conv.position = cursor.getPosition();
-        setSelected(conv.position, true);
-        mCallbacks.onConversationSelected(conv, false /* inLoaderCallbacks */);
-    }
+        @Override
+        public boolean isInSelectionMode() {
+            return !mSelectedSet.isEmpty();
+        }
+
+        @Override
+        public boolean isEnteringSelectionMode() {
+            return System.currentTimeMillis() <
+                    (mSelectionModeEnteredTimestamp + sSelectionModeAnimationDuration);
+        }
+
+        @Override
+        public boolean isExitingSelectionMode() {
+            return System.currentTimeMillis() <
+                    (mSelectionModeExitedTimestamp + sSelectionModeAnimationDuration);
+        }
+    };
 
     /**
      * Sets the selected conversation to the position given here.
@@ -950,4 +981,25 @@
     public void clear() {
         mListView.setAdapter(null);
     }
+
+    private final ConversationSetObserver mConversationSetObserver = new ConversationSetObserver() {
+        @Override
+        public void onSetPopulated(final ConversationSelectionSet set) {
+            mSelectionModeEnteredTimestamp = System.currentTimeMillis();
+
+            mListAdapter.getConversationSetObserver().onSetPopulated(set);
+        }
+
+        @Override
+        public void onSetEmpty() {
+            mSelectionModeExitedTimestamp = System.currentTimeMillis();
+
+            mListAdapter.getConversationSetObserver().onSetEmpty();
+        }
+
+        @Override
+        public void onSetChanged(final ConversationSelectionSet set) {
+            mListAdapter.getConversationSetObserver().onSetChanged(set);
+        }
+    };
 }
diff --git a/src/com/android/mail/ui/ConversationListHelper.java b/src/com/android/mail/ui/ConversationListHelper.java
index f7a6862..dec28a3 100644
--- a/src/com/android/mail/ui/ConversationListHelper.java
+++ b/src/com/android/mail/ui/ConversationListHelper.java
@@ -19,9 +19,12 @@
 import com.google.common.collect.Lists;
 
 import android.content.Context;
+import android.view.LayoutInflater;
 
 import com.android.mail.providers.Account;
 
+import com.android.mail.R;
+
 import java.util.ArrayList;
 
 public class ConversationListHelper {
@@ -30,8 +33,14 @@
      */
     public ArrayList<ConversationSpecialItemView> makeConversationListSpecialViews(Context context,
             Account account, FolderSelector listener) {
-        // TODO: Move conversation photo teaser view here once
-        // getConversationListIcon() is moved out of Persistence
-        return Lists.newArrayList();
+        // Conversation photo teaser view
+        final ConversationPhotoTeaserView conversationPhotoTeaser =
+                (ConversationPhotoTeaserView) LayoutInflater.from(context)
+                        .inflate(R.layout.conversation_photo_teaser_view, null);
+
+
+        final ArrayList<ConversationSpecialItemView> itemViews = Lists.newArrayList();
+        itemViews.add(conversationPhotoTeaser);
+        return itemViews;
     }
 }
diff --git a/src/com/android/mail/ui/ConversationListView.java b/src/com/android/mail/ui/ConversationListView.java
index fcfce47..25ac4a6 100644
--- a/src/com/android/mail/ui/ConversationListView.java
+++ b/src/com/android/mail/ui/ConversationListView.java
@@ -416,7 +416,7 @@
                 attr.recycle();
             } else {
                 // Default color
-                setBackgroundColor(R.color.list_background_color);
+                setBackgroundColor(getResources().getColor(R.color.list_background_color));
             }
         }
 
diff --git a/src/com/android/mail/ui/ConversationPhotoTeaserView.java b/src/com/android/mail/ui/ConversationPhotoTeaserView.java
index 0b21883..8665c9e 100644
--- a/src/com/android/mail/ui/ConversationPhotoTeaserView.java
+++ b/src/com/android/mail/ui/ConversationPhotoTeaserView.java
@@ -167,7 +167,7 @@
     }
 
     protected boolean shouldShowSenderImage() {
-        return false;
+        return mMailPrefs.getShowSenderImages();
     }
 
     @Override
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 74ac38a..80eb4e3 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -85,7 +85,7 @@
 /**
  * The conversation view UI component.
  */
-public final class ConversationViewFragment extends AbstractConversationViewFragment implements
+public class ConversationViewFragment extends AbstractConversationViewFragment implements
         SuperCollapsedBlock.OnClickListener, OnLayoutChangeListener,
         MessageHeaderView.MessageHeaderViewCallbacks {
 
@@ -118,9 +118,9 @@
      */
     private final int LOAD_WAIT_UNTIL_VISIBLE = 2;
 
-    private ConversationContainer mConversationContainer;
+    protected ConversationContainer mConversationContainer;
 
-    private ConversationWebView mWebView;
+    protected ConversationWebView mWebView;
 
     private ScrollIndicatorsView mScrollIndicators;
 
@@ -128,11 +128,11 @@
 
     private View mNewMessageBar;
 
-    private HtmlConversationTemplates mTemplates;
+    protected HtmlConversationTemplates mTemplates;
 
     private final MailJsBridge mJsBridge = new MailJsBridge();
 
-    private ConversationViewAdapter mAdapter;
+    protected ConversationViewAdapter mAdapter;
 
     private boolean mViewsCreated;
     // True if we attempted to render before the views were laid out
@@ -149,7 +149,7 @@
 
     private int  mMaxAutoLoadMessages;
 
-    private int mSideMarginPx;
+    protected int mSideMarginPx;
 
     /**
      * If this conversation fragment is not visible, and it's inappropriate to load up front,
@@ -359,9 +359,11 @@
         // content is loaded and ready to draw, since WebView delays firing this event until the
         // layers are composited and everything is ready to draw.
         // This signal does not seem to be reliable, so just use the old method for now.
-        mEnableContentReadySignal = Utils.isRunningJellybeanOrLater();
-        mWebView.setUseSoftwareLayer(!mEnableContentReadySignal);
-        mWebView.onUserVisibilityChanged(isUserVisible());
+        final boolean isJBOrLater = Utils.isRunningJellybeanOrLater();
+        final boolean isUserVisible = isUserVisible();
+        mWebView.setUseSoftwareLayer(!isJBOrLater);
+        mEnableContentReadySignal = isJBOrLater && isUserVisible;
+        mWebView.onUserVisibilityChanged(isUserVisible);
         mWebView.setWebViewClient(mWebViewClient);
         final WebChromeClient wcc = new WebChromeClient() {
             @Override
@@ -390,6 +392,22 @@
     }
 
     @Override
+    public void onResume() {
+        super.onResume();
+        if (mWebView != null) {
+            mWebView.onResume();
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (mWebView != null) {
+            mWebView.onPause();
+        }
+    }
+
+    @Override
     public void onDestroyView() {
         super.onDestroyView();
         mConversationContainer.setOverlayAdapter(null);
@@ -578,7 +596,7 @@
      * conversation header), and return an HTML document with spacer divs inserted for all overlays.
      *
      */
-    private String renderMessageBodies(MessageCursor messageCursor,
+    protected String renderMessageBodies(MessageCursor messageCursor,
             boolean enableContentReadySignal) {
         int pos = -1;
 
@@ -763,7 +781,7 @@
         return mTemplates.emit();
     }
 
-    private int measureOverlayHeight(int position) {
+    protected int measureOverlayHeight(int position) {
         return measureOverlayHeight(mAdapter.getItem(position));
     }
 
@@ -920,7 +938,7 @@
         return positions;
     }
 
-    private Address getAddress(String rawFrom) {
+    protected Address getAddress(String rawFrom) {
         Address addr;
         synchronized (mAddressCache) {
             addr = mAddressCache.get(rawFrom);
@@ -949,7 +967,7 @@
         mWebView.setContentSizeChangeListener(mWebViewSizeChangeListener);
     }
 
-    private static boolean isOverviewMode(Account acct) {
+    public static boolean isOverviewMode(Account acct) {
         return acct.settings.isOverviewMode();
     }
 
@@ -1466,5 +1484,4 @@
         }
 
     }
-
 }
diff --git a/src/com/android/mail/ui/ConversationViewState.java b/src/com/android/mail/ui/ConversationViewState.java
index dc7dca8..2d733fa 100644
--- a/src/com/android/mail/ui/ConversationViewState.java
+++ b/src/com/android/mail/ui/ConversationViewState.java
@@ -34,7 +34,7 @@
  * A small class to keep state for conversation view when restoring.
  *
  */
-class ConversationViewState implements Parcelable {
+public class ConversationViewState implements Parcelable {
 
     // N.B. don't serialize entire Messages because they contain body HTML/text
 
diff --git a/src/com/android/mail/ui/DividedImageCanvas.java b/src/com/android/mail/ui/DividedImageCanvas.java
index 2880ea4..b45e88b 100644
--- a/src/com/android/mail/ui/DividedImageCanvas.java
+++ b/src/com/android/mail/ui/DividedImageCanvas.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.PorterDuffXfermode;
@@ -378,6 +379,15 @@
         }
     }
 
+    /**
+     * Draw the contents of the DividedImageCanvas to the supplied canvas.
+     */
+    public void draw(final Canvas canvas, final Matrix matrix) {
+        if (mDividedBitmap != null && mBitmapValid) {
+            canvas.drawBitmap(mDividedBitmap, matrix, null);
+        }
+    }
+
     @Override
     public void reset() {
         if (mCanvas != null && mDividedBitmap != null) {
diff --git a/src/com/android/mail/ui/FolderDisplayer.java b/src/com/android/mail/ui/FolderDisplayer.java
index 2e12074..019c662 100644
--- a/src/com/android/mail/ui/FolderDisplayer.java
+++ b/src/com/android/mail/ui/FolderDisplayer.java
@@ -17,11 +17,11 @@
 
 package com.android.mail.ui;
 
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.LogTag;
 import com.google.common.collect.Sets;
 
 import android.content.Context;
-import android.net.Uri;
 
 import com.android.mail.R;
 import com.android.mail.providers.Conversation;
@@ -57,7 +57,7 @@
      * @param ignoreFolderUri (optional) folder to omit from the displayed set
      * @param ignoreFolderType -1, or the {@link FolderType} to omit from the displayed set
      */
-    public void loadConversationFolders(Conversation conv, final Uri ignoreFolderUri,
+    public void loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri,
             final int ignoreFolderType) {
         mFoldersSortedSet.clear();
         for (Folder folder : conv.getRawFolders()) {
@@ -66,7 +66,7 @@
                 continue;
             }
             // skip the ignoreFolder
-            if (ignoreFolderUri != null && ignoreFolderUri.equals(folder.uri)) {
+            if (ignoreFolderUri != null && ignoreFolderUri.equals(folder.folderUri)) {
                 continue;
             }
             mFoldersSortedSet.add(folder);
diff --git a/src/com/android/mail/ui/FolderItemView.java b/src/com/android/mail/ui/FolderItemView.java
index ef0cfee..1a4cf75 100644
--- a/src/com/android/mail/ui/FolderItemView.java
+++ b/src/com/android/mail/ui/FolderItemView.java
@@ -103,7 +103,7 @@
             // a is not null because it would have returned above.
             return false;
         }
-        return (a == b || (a.uri.equals(b.uri)
+        return (a == b || (a.folderUri.equals(b.folderUri)
                 && a.name.equals(b.name)
                 && a.hasChildren == b.hasChildren
                 && a.unseenCount == b.unseenCount
diff --git a/src/com/android/mail/ui/FolderListFragment.java b/src/com/android/mail/ui/FolderListFragment.java
index 55a0924..b153715 100644
--- a/src/com/android/mail/ui/FolderListFragment.java
+++ b/src/com/android/mail/ui/FolderListFragment.java
@@ -46,6 +46,7 @@
 import com.android.mail.providers.RecentFolderObserver;
 import com.android.mail.providers.UIProvider;
 import com.android.mail.providers.UIProvider.FolderType;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
 
@@ -109,7 +110,7 @@
     private AccountController mAccountController;
 
     /** The currently selected folder (the folder being viewed).  This is never null. */
-    private Uri mSelectedFolderUri = Uri.EMPTY;
+    private FolderUri mSelectedFolderUri = FolderUri.EMPTY;
     /**
      * The current folder from the controller.  This is meant only to check when the unread count
      * goes out of sync and fixing it.
@@ -268,7 +269,8 @@
             selectedFolder = currentFolder;
         }
         // Is the selected folder fresher than the one we have restored from a bundle?
-        if (selectedFolder != null && !selectedFolder.uri.equals(mSelectedFolderUri)) {
+        if (selectedFolder != null
+                && !selectedFolder.folderUri.equals(mSelectedFolderUri)) {
             setSelectedFolder(selectedFolder);
         }
 
@@ -352,10 +354,11 @@
             mListView.onRestoreInstanceState(savedState.getParcelable(BUNDLE_LIST_STATE));
         }
         if (savedState != null && savedState.containsKey(BUNDLE_SELECTED_FOLDER)) {
-            mSelectedFolderUri = Uri.parse(savedState.getString(BUNDLE_SELECTED_FOLDER));
+            mSelectedFolderUri =
+                    new FolderUri(Uri.parse(savedState.getString(BUNDLE_SELECTED_FOLDER)));
             mSelectedFolderType = savedState.getInt(BUNDLE_SELECTED_TYPE);
         } else if (mParentFolder != null) {
-            mSelectedFolderUri = mParentFolder.uri;
+            mSelectedFolderUri = mParentFolder.folderUri;
             // No selected folder type required for hierarchical lists.
         }
 
@@ -486,7 +489,7 @@
             // Not changing the account.
             final Account nextAccount = null;
             // Go to the conversation list for this folder.
-            if (!folder.uri.equals(mSelectedFolderUri)) {
+            if (!folder.folderUri.equals(mSelectedFolderUri)) {
                 mNextFolder = folder;
                 mAccountController.closeDrawer(true, nextAccount, folder);
             } else {
@@ -942,7 +945,7 @@
 
         private static final int PARENT = 0;
         private static final int CHILD = 1;
-        private final Uri mParentUri;
+        private final FolderUri mParentUri;
         private final Folder mParent;
         private final FolderItemView.DropHandler mDropHandler;
 
@@ -950,7 +953,7 @@
             super(mActivity.getActivityContext(), R.layout.folder_item);
             mDropHandler = mActivity;
             mParent = parentFolder;
-            mParentUri = parentFolder.uri;
+            mParentUri = parentFolder.folderUri;
             setCursor(c);
         }
 
@@ -963,14 +966,14 @@
         @Override
         public int getItemViewType(int position) {
             final Folder f = getItem(position);
-            return f.uri.equals(mParentUri) ? PARENT : CHILD;
+            return f.folderUri.equals(mParentUri) ? PARENT : CHILD;
         }
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             final FolderItemView folderItemView;
             final Folder folder = getItem(position);
-            boolean isParent = folder.uri.equals(mParentUri);
+            boolean isParent = folder.folderUri.equals(mParentUri);
             if (convertView != null) {
                 folderItemView = (FolderItemView) convertView;
             } else {
@@ -979,7 +982,7 @@
                         mActivity.getActivityContext()).inflate(resId, null);
             }
             folderItemView.bind(folder, mDropHandler);
-            if (folder.uri.equals(mSelectedFolderUri)) {
+            if (folder.folderUri.equals(mSelectedFolderUri)) {
                 getListView().setItemChecked(position, true);
                 // If this is the current folder, also check to verify that the unread count
                 // matches what the action bar shows.
@@ -1045,7 +1048,7 @@
      */
     private void setSelectedFolder(Folder folder) {
         if (folder == null) {
-            mSelectedFolderUri = Uri.EMPTY;
+            mSelectedFolderUri = FolderUri.EMPTY;
             mCurrentFolderForUnreadCheck = null;
             LogUtils.e(LOG_TAG, "FolderListFragment.setSelectedFolder(null) called!");
             return;
@@ -1062,13 +1065,13 @@
         //    default inbox already, back exits the app.)
         // In both these cases, the selected folder type is not set, and must be set.
         if (mSelectedFolderType == DrawerItem.UNSET || (mCurrentAccount != null
-                && folder.uri.equals(mCurrentAccount.settings.defaultInbox))) {
+                && folder.folderUri.equals(mCurrentAccount.settings.defaultInbox))) {
             mSelectedFolderType =
                     folder.isInbox() ? DrawerItem.FOLDER_INBOX : DrawerItem.FOLDER_OTHER;
         }
 
         mCurrentFolderForUnreadCheck = folder;
-        mSelectedFolderUri = folder.uri;
+        mSelectedFolderUri = folder.folderUri;
         if (mCursorAdapter != null && viewChanged) {
             mCursorAdapter.notifyDataSetChanged();
         }
diff --git a/src/com/android/mail/ui/FolderOperation.java b/src/com/android/mail/ui/FolderOperation.java
index 28fef50..3dc61b8 100644
--- a/src/com/android/mail/ui/FolderOperation.java
+++ b/src/com/android/mail/ui/FolderOperation.java
@@ -68,7 +68,7 @@
      */
     public static boolean isDestructive(Collection<FolderOperation> folderOps, Folder folder) {
         for (FolderOperation op : folderOps) {
-            if (Objects.equal(op.mFolder.uri, folder.uri) && !op.mAdd) {
+            if (Objects.equal(op.mFolder, folder) && !op.mAdd) {
                 return true;
             }
             if (folder.isTrash() && op.mFolder.isInbox()) {
diff --git a/src/com/android/mail/ui/FolderSelectionActivity.java b/src/com/android/mail/ui/FolderSelectionActivity.java
index 743afc7..93c3f08 100644
--- a/src/com/android/mail/ui/FolderSelectionActivity.java
+++ b/src/com/android/mail/ui/FolderSelectionActivity.java
@@ -248,8 +248,9 @@
      * Create a widget for the specified account and folder
      */
     protected void createWidget(int id, Account account, Folder selectedFolder) {
-        WidgetProvider.updateWidget(this, id, account, selectedFolder.type, selectedFolder.uri,
-                selectedFolder.conversationListUri, selectedFolder.name);
+        WidgetProvider.updateWidget(this, id, account, selectedFolder.type,
+                selectedFolder.folderUri.fullUri, selectedFolder.conversationListUri,
+                selectedFolder.name);
         final Intent result = new Intent();
         result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
         setResult(RESULT_OK, result);
@@ -279,8 +280,8 @@
                  * account, calculate the human readable name of the folder and
                  * use it as the shortcut name, etc...
                  */
-                final Intent clickIntent = Utils.createViewFolderIntent(this, mSelectedFolder.uri,
-                        mAccount);
+                final Intent clickIntent = Utils.createViewFolderIntent(this,
+                        mSelectedFolder.folderUri.fullUri, mAccount);
                 resultIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, clickIntent);
                 resultIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                         Intent.ShortcutIconResource.fromContext(this,
diff --git a/src/com/android/mail/ui/FolderSelectorAdapter.java b/src/com/android/mail/ui/FolderSelectorAdapter.java
index 96e1d56..30451ad 100644
--- a/src/com/android/mail/ui/FolderSelectorAdapter.java
+++ b/src/com/android/mail/ui/FolderSelectorAdapter.java
@@ -115,7 +115,8 @@
             do {
                 final Folder folder = new Folder(folders);
                 final boolean isSelected = initiallySelected != null
-                        && initiallySelected.contains(folder.uri.toString());
+                        && initiallySelected.contains(
+                                folder.folderUri.getComparisonUri().toString());
                 if (meetsRequirements(folder) && !Objects.equal(folder, mExcludedFolder)) {
                     final FolderRow row = new FolderRow(folder, isSelected);
                     // Add the currently selected first.
diff --git a/src/com/android/mail/ui/MailActionBarView.java b/src/com/android/mail/ui/MailActionBarView.java
index 8df8320..15105c5 100644
--- a/src/com/android/mail/ui/MailActionBarView.java
+++ b/src/com/android/mail/ui/MailActionBarView.java
@@ -337,11 +337,6 @@
                 mActionBar.setDisplayHomeAsUpEnabled(true);
                 setEmptyMode();
                 break;
-            case ViewMode.FOLDER_LIST:
-                closeSearchField();
-                mActionBar.setDisplayHomeAsUpEnabled(true);
-                setFoldersMode();
-                break;
             case ViewMode.WAITING_FOR_ACCOUNT_INITIALIZATION:
                 // We want the user to be able to switch accounts while waiting for an account
                 // to sync.
@@ -559,16 +554,6 @@
         setFolderAndAccount(false);
     }
 
-    /**
-     * Put the ActionBar in standard mode, and show the word "Folders" along with the account name
-     * (if user has multiple accounts)
-     */
-    private void setFoldersMode() {
-        setTitle(R.string.folders);
-        setSubtitle(mAccount.name);
-        setTitleModeFlags(ActionBar.DISPLAY_SHOW_TITLE);
-    }
-
     private void setSubtitle(CharSequence subtitle) {
         if (!TextUtils.equals(subtitle, mActionBar.getSubtitle())) {
             mActionBar.setSubtitle(subtitle);
@@ -578,13 +563,6 @@
         }
     }
 
-    private void setTitle(int res) {
-        mActionBar.setTitle(res);
-        if (mLegacyTitle != null) {
-            mLegacyTitle.setText(res);
-        }
-    }
-
     private void setTitle(CharSequence title) {
         if (!TextUtils.equals(title, mActionBar.getTitle())) {
             mActionBar.setTitle(title);
@@ -770,7 +748,7 @@
             return;
         }
         /** True if we are changing folders. */
-        final boolean changingFolders = (mFolder == null || !mFolder.uri.equals(folder.uri));
+        final boolean changingFolders = (mFolder == null || !mFolder.equals(folder));
         mFolder = folder;
         setFolderAndAccount(changingFolders);
         final ConversationListContext listContext = mController == null ? null :
diff --git a/src/com/android/mail/ui/MailActivity.java b/src/com/android/mail/ui/MailActivity.java
index 036d32b..860a279 100644
--- a/src/com/android/mail/ui/MailActivity.java
+++ b/src/com/android/mail/ui/MailActivity.java
@@ -60,6 +60,8 @@
     private boolean mAccessibilityEnabled;
     private AccessibilityManager mAccessibilityManager;
 
+    protected ConversationListHelper mConversationListHelper;
+
     /**
      * The account name currently in use. Used to construct the NFC mailto: message. This needs
      * to be static since the {@link ComposeActivity} needs to statically change the account name
@@ -105,6 +107,7 @@
 
     public MailActivity() {
         super();
+        mConversationListHelper = new ConversationListHelper();
     }
 
     @Override
@@ -423,8 +426,7 @@
     }
 
     @Override
-    public ConversationListHelper getConversationListHelper() {
-        // Unsupported
-        return null;
+    public final ConversationListHelper getConversationListHelper() {
+        return mConversationListHelper;
     }
 }
diff --git a/src/com/android/mail/ui/MultiFoldersSelectionDialog.java b/src/com/android/mail/ui/MultiFoldersSelectionDialog.java
index b1b9059..3fb378b 100644
--- a/src/com/android/mail/ui/MultiFoldersSelectionDialog.java
+++ b/src/com/android/mail/ui/MultiFoldersSelectionDialog.java
@@ -88,7 +88,7 @@
                 } else {
                     // There are no folders for this conversation, so it must
                     // belong to the folder we are currently looking at.
-                    checked.add(mCurrentFolder.uri.toString());
+                    checked.add(mCurrentFolder.folderUri.fullUri.toString());
                 }
             }
             // TODO(mindyp) : bring this back in UR8 when Email providers
@@ -142,14 +142,15 @@
                 if (item instanceof FolderRow) {
                    ((FolderRow)item).setIsPresent(false);
                    final Folder folder = ((FolderRow)item).getFolder();
-                   mOperations.put(folder.uri, new FolderOperation(folder, false));
+                   mOperations.put(folder.folderUri.fullUri,
+                           new FolderOperation(folder, false));
                 }
             }
         }
         row.setIsPresent(add);
         mAdapter.notifyDataSetChanged();
         final Folder folder = row.getFolder();
-        mOperations.put(folder.uri, new FolderOperation(folder, add));
+        mOperations.put(folder.folderUri.fullUri, new FolderOperation(folder, add));
     }
 
     @Override
diff --git a/src/com/android/mail/ui/OnePaneController.java b/src/com/android/mail/ui/OnePaneController.java
index df198ae..eaaaedb 100644
--- a/src/com/android/mail/ui/OnePaneController.java
+++ b/src/com/android/mail/ui/OnePaneController.java
@@ -34,6 +34,7 @@
 import com.android.mail.providers.Conversation;
 import com.android.mail.providers.Folder;
 import com.android.mail.providers.UIProvider;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.LogUtils;
 import com.android.mail.utils.Utils;
 
@@ -44,8 +45,6 @@
 
 // Called OnePaneActivityController in Gmail.
 public final class OnePaneController extends AbstractActivityController {
-    /** Key used to store {@link #mLastFolderListTransactionId}. */
-    private static final String FOLDER_LIST_TRANSACTION_KEY = "folder-list-transaction";
     /** Key used to store {@link #mLastInboxConversationListTransactionId} */
     private static final String INBOX_CONVERSATION_LIST_TRANSACTION_KEY =
             "inbox_conversation-list-transaction";
@@ -65,7 +64,6 @@
     private int mLastInboxConversationListTransactionId = INVALID_ID;
     private int mLastConversationListTransactionId = INVALID_ID;
     private int mLastConversationTransactionId = INVALID_ID;
-    private int mLastFolderListTransactionId = INVALID_ID;
     private Folder mInbox;
     /** Whether a conversation list for this account has ever been shown.*/
     private boolean mConversationListNeverShown = true;
@@ -80,7 +78,6 @@
         if (inState == null) {
             return;
         }
-        mLastFolderListTransactionId = inState.getInt(FOLDER_LIST_TRANSACTION_KEY, INVALID_ID);
         mLastInboxConversationListTransactionId =
                 inState.getInt(INBOX_CONVERSATION_LIST_TRANSACTION_KEY, INVALID_ID);
         mLastConversationListTransactionId =
@@ -94,7 +91,6 @@
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putInt(FOLDER_LIST_TRANSACTION_KEY, mLastFolderListTransactionId);
         outState.putInt(INBOX_CONVERSATION_LIST_TRANSACTION_KEY,
                 mLastInboxConversationListTransactionId);
         outState.putInt(CONVERSATION_LIST_TRANSACTION_KEY, mLastConversationListTransactionId);
@@ -117,7 +113,7 @@
      * @param account the account whose default Inbox the candidate might be
      * @return true if the candidate is indeed the default inbox for the given account.
      */
-    private static boolean isDefaultInbox(Uri candidate, Account account) {
+    private static boolean isDefaultInbox(FolderUri candidate, Account account) {
         return (candidate != null && account != null)
                 && candidate.equals(account.settings.defaultInbox);
     }
@@ -131,7 +127,7 @@
         // If we don't have valid state, then we are not in the inbox.
         return !(account == null || context == null || context.folder == null
                 || account.settings == null) && !ConversationListContext.isSearchResult(context)
-                && isDefaultInbox(context.folder.uri, account);
+                && isDefaultInbox(context.folder.folderUri, account);
     }
 
     /**
@@ -180,8 +176,6 @@
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder(super.toString());
-        sb.append("{lastFolderListTransId=");
-        sb.append(mLastFolderListTransactionId);
         sb.append(" lastInboxTransId=");
         sb.append(mLastInboxConversationListTransactionId);
         sb.append(" lastConvListTransId=");
@@ -217,11 +211,6 @@
             mLastInboxConversationListTransactionId = replaceFragmentWithBack(
                     conversationListFragment, transition, TAG_CONVERSATION_LIST, R.id.content_pane);
 
-            // FIXME: "forgetting" the folder list entry in the back stack doesn't remove it from
-            // the back stack. only popping past it can remove it.
-            // Maybe we should clear the back stack prior to opening a folder.
-            mLastFolderListTransactionId = INVALID_ID;
-
             // If we ever to to the inbox, we want to unset the transation id for any other
             // non-inbox folder.
             mLastConversationListTransactionId = INVALID_ID;
@@ -357,43 +346,10 @@
     public boolean handleBackPress() {
         final int mode = mViewMode.getMode();
 
-        //TODO(shahrk): Remove the folder list standalone view
-        if (mode == ViewMode.FOLDER_LIST) {
-            final Folder hierarchyFolder = getHierarchyFolder();
-            final FolderListFragment folderListFragment = getFolderListFragment();
-            final boolean parentHasChildren = folderListFragment != null &&
-                    folderListFragment.showingHierarchy() && hierarchyFolder != null
-                    && hierarchyFolder.parent != Uri.EMPTY;
-            if (parentHasChildren) {
-                // If we are showing the folder list and the user is exploring
-                // the children of a single parent folder,
-                // back should display the parent folder's parent and siblings.
-                goUpFolderHierarchy(hierarchyFolder);
-            } else {
-                // We are at the topmost list of folders: go back
-                mLastFolderListTransactionId = INVALID_ID;
-                transitionToInbox();
-            }
-        } else if (mode == ViewMode.SEARCH_RESULTS_LIST) {
+        if (mode == ViewMode.SEARCH_RESULTS_LIST) {
             mActivity.finish();
         } else if (mViewMode.isListMode() && !inInbox(mAccount, mConvListContext)) {
-            if (mLastFolderListTransactionId != INVALID_ID) {
-                // Set the hierarchy folder to what it will be once we go up
-
-                // The hierarchy folder stuff is not required. We need to clean this stuff up.
-                // TODO: http://b/9694899
-//                final Folder hierarchyFolder = getHierarchyFolder();
-//                if (hierarchyFolder != null && hierarchyFolder.parent != null) {
-//                    setHierarchyFolder(hierarchyFolder.parent);
-//                }
-
-                // If the user got here by navigating via the folder list, back
-                // should bring them back to the folder list.
-                mViewMode.enterFolderListMode();
-                mActivity.getFragmentManager().popBackStack(mLastFolderListTransactionId, 0);
-            } else {
-                transitionToInbox();
-            }
+            transitionToInbox();
         } else if (mViewMode.isConversationMode()) {
             transitionBackToConversationListMode(false /* inLoaderCallbacks */);
         } else {
@@ -441,7 +397,7 @@
      */
     private void transitionToInbox() {
         // The inbox could have changed, in which case we should load it again.
-        if (mInbox == null || !isDefaultInbox(mInbox.uri, mAccount)) {
+        if (mInbox == null || !isDefaultInbox(mInbox.folderUri, mAccount)) {
             loadAccountInbox();
         } else {
             onFolderChanged(mInbox);
@@ -487,27 +443,11 @@
 
             return true;
         }
-        if (mode == ViewMode.CONVERSATION
-                || mode == ViewMode.SEARCH_RESULTS_CONVERSATION) {
+        if (mode == ViewMode.CONVERSATION || mode == ViewMode.SEARCH_RESULTS_CONVERSATION) {
             // Same as go back.
             handleBackPress();
             return true;
         }
-        if (mode == ViewMode.FOLDER_LIST) {
-            // If the folder is the top level of an heirarchy or flat, toggle the
-            // state of the drawer. Otherwise, let it pass on as a back press.
-            // We don't want this code in back press, otherwise pressing back
-            // will exhibit the same behavior
-            final FolderListFragment folderListFragment = getFolderListFragment();
-            if (folderListFragment != null) {
-                final Folder parentFolder = folderListFragment.getParentFolder();
-                if (parentFolder == null || parentFolder.parent == Uri.EMPTY) {
-                    toggleFolderListState();
-                    return true;
-                }
-            }
-            handleBackPress();
-        }
         return true;
     }
 
@@ -628,16 +568,6 @@
         }
     }
 
-    @Override
-    public String getHelpContext() {
-        final int mode = mViewMode.getMode();
-        switch (mode) {
-            case ViewMode.FOLDER_LIST:
-                return mContext.getString(R.string.one_pane_folder_list_help_context);
-        }
-        return super.getHelpContext();
-    }
-
     private final class PopBackStackRunnable implements Runnable {
 
         private final int mTransactionId;
diff --git a/src/com/android/mail/ui/RecentFolderList.java b/src/com/android/mail/ui/RecentFolderList.java
index e09b08a..25f3568 100644
--- a/src/com/android/mail/ui/RecentFolderList.java
+++ b/src/com/android/mail/ui/RecentFolderList.java
@@ -26,6 +26,7 @@
 import com.android.mail.providers.AccountObserver;
 import com.android.mail.providers.Folder;
 import com.android.mail.providers.Settings;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.LogUtils;
 import com.android.mail.utils.LruCache;
 import com.android.mail.utils.Utils;
@@ -112,7 +113,7 @@
                 ContentValues values = new ContentValues();
                 // Only the folder URIs are provided. Providers are free to update their specific
                 // information, though most will probably write the current timestamp.
-                values.put(mFolder.uri.toString(), 0);
+                values.put(mFolder.folderUri.fullUri.toString(), 0);
                 LogUtils.i(TAG, "Save: %s", mFolder.name);
                 mContext.getContentResolver().update(uri, values, null, null);
             }
@@ -176,7 +177,7 @@
         do {
             final Folder folder = c.getModel();
             final RecentFolderListEntry entry = new RecentFolderListEntry(folder);
-            mFolderCache.putElement(folder.uri.toString(), entry);
+            mFolderCache.putElement(folder.folderUri.fullUri.toString(), entry);
             LogUtils.v(TAG, "Account %s, Recent: %s", mAccount.name, folder.name);
         } while (c.moveToPrevious());
     }
@@ -205,7 +206,7 @@
         }
 
         final RecentFolderListEntry entry = new RecentFolderListEntry(folder);
-        mFolderCache.putElement(folder.uri.toString(), entry);
+        mFolderCache.putElement(folder.folderUri.fullUri.toString(), entry);
         new StoreRecent(mAccount, folder).execute();
     }
 
@@ -216,14 +217,15 @@
      * Returns a list of size {@value #MAX_RECENT_FOLDERS} or smaller.
      * @param excludedFolderUri the uri of folder to be excluded (typically the current folder)
      */
-    public ArrayList<Folder> getRecentFolderList(Uri excludedFolderUri) {
-        final ArrayList<Uri> excludedUris = new ArrayList<Uri>();
+    public ArrayList<Folder> getRecentFolderList(final FolderUri excludedFolderUri) {
+        final ArrayList<FolderUri> excludedUris = new ArrayList<FolderUri>();
         if (excludedFolderUri != null) {
             excludedUris.add(excludedFolderUri);
         }
-        final Uri defaultInbox = (mAccount == null) ?
-                Uri.EMPTY : Settings.getDefaultInboxUri(mAccount.settings);
-        if (!defaultInbox.equals(Uri.EMPTY)) {
+        final FolderUri defaultInbox = (mAccount == null)
+                ? FolderUri.EMPTY
+                : new FolderUri(Settings.getDefaultInboxUri(mAccount.settings));
+        if (!defaultInbox.equals(FolderUri.EMPTY)) {
             excludedUris.add(defaultInbox);
         }
         final List<RecentFolderListEntry> recent = Lists.newArrayList();
@@ -232,7 +234,7 @@
 
         final ArrayList<Folder> recentFolders = Lists.newArrayList();
         for (final RecentFolderListEntry entry : recent) {
-            if (!excludedUris.contains(entry.mFolder.uri)) {
+            if (!excludedUris.contains(entry.mFolder.folderUri)) {
                 recentFolders.add(entry.mFolder);
             }
             if (recentFolders.size() == MAX_RECENT_FOLDERS) {
diff --git a/src/com/android/mail/ui/SecureConversationViewController.java b/src/com/android/mail/ui/SecureConversationViewController.java
index f049168..56f590e 100644
--- a/src/com/android/mail/ui/SecureConversationViewController.java
+++ b/src/com/android/mail/ui/SecureConversationViewController.java
@@ -18,6 +18,7 @@
 package com.android.mail.ui;
 
 import android.app.Fragment;
+import android.app.FragmentManager;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.view.LayoutInflater;
@@ -206,5 +207,10 @@
         return null;
     }
 
+    @Override
+    public FragmentManager getFragmentManager() {
+        return mCallbacks.getFragment().getFragmentManager();
+    }
+
     // End MessageHeaderViewCallbacks implementations
 }
diff --git a/src/com/android/mail/ui/SuppressNotificationReceiver.java b/src/com/android/mail/ui/SuppressNotificationReceiver.java
index a2d94e7..685edd0 100644
--- a/src/com/android/mail/ui/SuppressNotificationReceiver.java
+++ b/src/com/android/mail/ui/SuppressNotificationReceiver.java
@@ -146,7 +146,7 @@
         final Uri intentFolderUri =
                 (Uri)intent.getParcelableExtra(UIProvider.UpdateNotificationExtras.EXTRA_FOLDER);
 
-        if (!listContextFolder.uri.equals(intentFolderUri)) {
+        if (!listContextFolder.folderUri.equals(intentFolderUri)) {
             return;
         }
         final int count = intent.getIntExtra(
diff --git a/src/com/android/mail/ui/SwipeableListView.java b/src/com/android/mail/ui/SwipeableListView.java
index 24189fd..e184e41 100644
--- a/src/com/android/mail/ui/SwipeableListView.java
+++ b/src/com/android/mail/ui/SwipeableListView.java
@@ -79,11 +79,11 @@
 
     public SwipeableListView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        setOnScrollListener(this);
         float densityScale = getResources().getDisplayMetrics().density;
         float pagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
         mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, densityScale,
                 pagingTouchSlop);
-        setOnScrollListener(this);
     }
 
     @Override
@@ -224,12 +224,12 @@
                 FolderOperation folderOp = new FolderOperation(mFolder, false);
                 HashMap<Uri, Folder> targetFolders = Folder
                         .hashMapForFolders(conv.getRawFolders());
-                targetFolders.remove(folderOp.mFolder.uri);
+                targetFolders.remove(folderOp.mFolder.folderUri.fullUri);
                 final FolderList folders = FolderList.copyOf(targetFolders.values());
                 conv.setRawFolders(folders);
                 final ContentValues values = new ContentValues();
                 folderUris = new ArrayList<Uri>();
-                folderUris.add(mFolder.uri);
+                folderUris.add(mFolder.folderUri.fullUri);
                 adds = new ArrayList<Boolean>();
                 adds.add(Boolean.FALSE);
                 ConversationCursor.addFolderUpdates(folderUris, adds, values);
@@ -341,11 +341,9 @@
         // Superclass method modifies the selection set
         final boolean handled = super.performItemClick(view, pos, id);
 
-        // If we are in CAB mode with no checkboxes then a click shouldn't
+        // If we are in CAB mode then a click shouldn't
         // activate the new item, it should only add it to the selection set
-        final boolean showSenderImage = mAccount != null
-                && (mAccount.settings.convListIcon == ConversationListIcon.SENDER_IMAGE);
-        if (!showSenderImage && !selectionSetEmpty && previousPosition != -1) {
+        if (!selectionSetEmpty && previousPosition != -1) {
             setItemChecked(previousPosition, true);
         }
         // Commit any existing destructive actions when the user selects a
diff --git a/src/com/android/mail/ui/TwoPaneController.java b/src/com/android/mail/ui/TwoPaneController.java
index e579292..91a3ccf 100644
--- a/src/com/android/mail/ui/TwoPaneController.java
+++ b/src/com/android/mail/ui/TwoPaneController.java
@@ -423,7 +423,7 @@
                 }
                 final boolean shouldLoadInbox = mode == ViewMode.CONVERSATION_LIST &&
                         mAccount != null && mFolder != null &&
-                        !mAccount.settings.defaultInbox.equals(mFolder.uri) &&
+                        !mFolder.folderUri.equals(mAccount.settings.defaultInbox) &&
                         mLayout != null && !mLayout.isExpansiveLayout();
                 if (shouldLoadInbox) {
                     loadAccountInbox();
diff --git a/src/com/android/mail/ui/ViewMode.java b/src/com/android/mail/ui/ViewMode.java
index ec43039..aee794d 100644
--- a/src/com/android/mail/ui/ViewMode.java
+++ b/src/com/android/mail/ui/ViewMode.java
@@ -50,21 +50,17 @@
      */
     public static final int CONVERSATION_LIST = 2;
     /**
-     * Mode when showing a list of folders.
+     * Mode when showing results from user search.
      */
-    public static final int FOLDER_LIST = 3;
+    public static final int SEARCH_RESULTS_LIST = 3;
     /**
      * Mode when showing results from user search.
      */
-    public static final int SEARCH_RESULTS_LIST = 4;
-    /**
-     * Mode when showing results from user search.
-     */
-    public static final int SEARCH_RESULTS_CONVERSATION = 5;
+    public static final int SEARCH_RESULTS_CONVERSATION = 4;
     /**
      * Mode when showing the "waiting for sync" message.
      */
-    public static final int WAITING_FOR_ACCOUNT_INITIALIZATION = 6;
+    public static final int WAITING_FOR_ACCOUNT_INITIALIZATION = 5;
     /**
      * Uncertain mode. The mode has not been initialized.
      */
@@ -127,14 +123,6 @@
     }
 
     /**
-     * Requests a transition of the mode to show the folder list as the prominent view.
-     *
-     */
-    public void enterFolderListMode() {
-        setModeInternal(FOLDER_LIST);
-    }
-
-    /**
      * Requests a transition of the mode to show a list of search results as the
      * prominent view.
      *
diff --git a/src/com/android/mail/utils/AttachmentUtils.java b/src/com/android/mail/utils/AttachmentUtils.java
index b66be9b..26adee8 100644
--- a/src/com/android/mail/utils/AttachmentUtils.java
+++ b/src/com/android/mail/utils/AttachmentUtils.java
@@ -30,6 +30,7 @@
 import com.android.mail.providers.Attachment;
 
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.IOException;
@@ -190,6 +191,13 @@
                 // Get the input stream from the file descriptor
                 inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
             } else {
+                if (attachment.contentUri == null) {
+                    // The contentUri of the attachment is null.  This can happen when sending a
+                    // message that has been previously saved, and the attachments had been
+                    // uploaded.
+                    LogUtils.d(LOG_TAG, "contentUri is null in attachment: %s", attachment);
+                    throw new FileNotFoundException("Missing contentUri in attachment");
+                }
                 // Attempt to open the file
                 inputStream = context.getContentResolver().openInputStream(attachment.contentUri);
             }
diff --git a/src/com/android/mail/utils/FolderUri.java b/src/com/android/mail/utils/FolderUri.java
new file mode 100644
index 0000000..d4d43ee
--- /dev/null
+++ b/src/com/android/mail/utils/FolderUri.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mail.utils;
+
+import android.net.Uri;
+
+/**
+ * A holder for a Folder {@link Uri} that can be compared, ignoring any query parameters.
+ */
+public class FolderUri {
+    public static final FolderUri EMPTY = new FolderUri(Uri.EMPTY);
+
+    /**
+     * The full {@link Uri}. This should be used for any queries.
+     */
+    public final Uri fullUri;
+    /**
+     * Equivalent to {@link #fullUri}, but without any query parameters, and can safely be used in
+     * comparisons to determine if two {@link Uri}s point to the same object.
+     */
+    private Uri mComparisonUri = null;
+
+    public FolderUri(final Uri uri) {
+        fullUri = uri;
+    }
+
+    private static Uri buildComparisonUri(final Uri fullUri) {
+        final Uri.Builder builder = new Uri.Builder();
+        builder.scheme(fullUri .getScheme());
+        builder.encodedAuthority(fullUri.getEncodedAuthority());
+        builder.encodedPath(fullUri.getEncodedPath());
+
+        return builder.build();
+    }
+
+    public Uri getComparisonUri() {
+        if (mComparisonUri == null) {
+            mComparisonUri = buildComparisonUri(fullUri);
+        }
+
+        return mComparisonUri;
+    }
+
+    @Override
+    public int hashCode() {
+        return getComparisonUri().hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (o instanceof FolderUri) {
+            return getComparisonUri().equals(((FolderUri) o).getComparisonUri());
+        }
+
+        return getComparisonUri().equals(o);
+    }
+
+    @Override
+    public String toString() {
+        return fullUri.toString();
+    }
+}
diff --git a/src/com/android/mail/utils/NotificationActionUtils.java b/src/com/android/mail/utils/NotificationActionUtils.java
index f3246f9..3c0e42a 100644
--- a/src/com/android/mail/utils/NotificationActionUtils.java
+++ b/src/com/android/mail/utils/NotificationActionUtils.java
@@ -632,8 +632,8 @@
                     // Not inbox, so remove label
                     final ContentValues values = new ContentValues(1);
 
-                    final String removeFolderUri =
-                            folder.uri.buildUpon().appendPath(Boolean.FALSE.toString()).toString();
+                    final String removeFolderUri = folder.folderUri.fullUri.buildUpon()
+                            .appendPath(Boolean.FALSE.toString()).toString();
                     values.put(ConversationOperations.FOLDERS_UPDATED, removeFolderUri);
 
                     contentResolver.update(uri, values, null, null);
@@ -729,7 +729,7 @@
         final Intent intent = new Intent(MailIntentService.ACTION_RESEND_NOTIFICATIONS);
         intent.setPackage(context.getPackageName()); // Make sure we only deliver this to ourself
         intent.putExtra(Utils.EXTRA_ACCOUNT_URI, account.uri);
-        intent.putExtra(Utils.EXTRA_FOLDER_URI, folder.uri);
+        intent.putExtra(Utils.EXTRA_FOLDER_URI, folder.folderUri.fullUri);
         context.startService(intent);
     }
 
diff --git a/src/com/android/mail/utils/NotificationUtils.java b/src/com/android/mail/utils/NotificationUtils.java
index e38a64e..4889651 100644
--- a/src/com/android/mail/utils/NotificationUtils.java
+++ b/src/com/android/mail/utils/NotificationUtils.java
@@ -218,7 +218,7 @@
                 final Integer unseenCount = value.second;
                 if (unreadCount != null && unseenCount != null) {
                     final String[] partValues = new String[] {
-                            key.account.uri.toString(), key.folder.uri.toString(),
+                            key.account.uri.toString(), key.folder.folderUri.fullUri.toString(),
                             unreadCount.toString(), unseenCount.toString()};
                     notificationSet.add(TextUtils.join(NOTIFICATION_PART_SEPARATOR, partValues));
                 }
@@ -291,7 +291,7 @@
      *                  upon which an action occurred.
      */
     public static void resendNotifications(Context context, final boolean cancelExisting,
-            final Uri accountUri, final Uri folderUri) {
+            final Uri accountUri, final FolderUri folderUri) {
         LogUtils.d(LOG_TAG, "NotificationUtils: resendNotifications ");
 
         if (cancelExisting) {
@@ -311,15 +311,15 @@
             // Only resend notifications if the notifications are from the same folder
             // and same account as the undo notification that was previously displayed.
             if (accountUri != null && !Objects.equal(accountUri, notification.account.uri) &&
-                    folderUri != null && !Objects.equal(folderUri, folder.uri)) {
+                    folderUri != null && !Objects.equal(folderUri, folder.folderUri)) {
                 LogUtils.d(LOG_TAG, "NotificationUtils: resendNotifications - not resending %s / %s"
                         + " because it doesn't match %s / %s",
-                        notification.account.uri, folder.uri, accountUri, folderUri);
+                        notification.account.uri, folder.folderUri, accountUri, folderUri);
                 continue;
             }
 
             LogUtils.d(LOG_TAG, "NotificationUtils: resendNotifications - resending %s / %s",
-                    notification.account.uri, folder.uri);
+                    notification.account.uri, folder.folderUri);
 
             final NotificationAction undoableAction =
                     NotificationActionUtils.sUndoNotifications.get(notificationId);
@@ -361,8 +361,8 @@
                     // If notification is not enabled for this label, remember this NotificationKey
                     // to later cancel the notification, and remove the entry from the map
                     final Folder folder = notification.folder;
-                    final boolean isInbox =
-                            notification.account.settings.defaultInbox.equals(folder.uri);
+                    final boolean isInbox = folder.folderUri.equals(
+                            notification.account.settings.defaultInbox);
                     final FolderPreferences folderPreferences = new FolderPreferences(
                             context, notification.account.name, folder, isInbox);
 
@@ -400,7 +400,7 @@
             final boolean getAttention) {
         LogUtils.d(LOG_TAG, "NotificationUtils: setNewEmailIndicator unreadCount = %d, "
             + "unseenCount = %d, account = %s, folder = %s, getAttention = %b", unreadCount,
-            unseenCount, account.name, folder.uri, getAttention);
+            unseenCount, account.name, folder.folderUri, getAttention);
 
         boolean ignoreUnobtrusiveSetting = false;
 
@@ -535,7 +535,7 @@
                     new Intent(MailIntentService.ACTION_CLEAR_NEW_MAIL_NOTIFICATIONS);
             cancelNotificationIntent.setPackage(context.getPackageName());
             cancelNotificationIntent.setData(Utils.appendVersionQueryParameter(context,
-                    folder.uri));
+                    folder.folderUri.fullUri));
             cancelNotificationIntent.putExtra(Utils.EXTRA_ACCOUNT, account);
             cancelNotificationIntent.putExtra(Utils.EXTRA_FOLDER, folder);
 
@@ -547,7 +547,7 @@
 
             boolean eventInfoConfigured = false;
 
-            final boolean isInbox = account.settings.defaultInbox.equals(folder.uri);
+            final boolean isInbox = folder.folderUri.equals(account.settings.defaultInbox);
             final FolderPreferences folderPreferences =
                     new FolderPreferences(context, account.name, folder, isInbox);
 
@@ -659,15 +659,15 @@
         final Intent intent;
 
         if (cursor == null) {
-            intent = Utils.createViewFolderIntent(context, folder.uri, account);
+            intent = Utils.createViewFolderIntent(context, folder.folderUri.fullUri, account);
         } else {
             // A conversation cursor has been specified, so this intent is intended to be go
             // directly to the one new conversation
 
             // Get the Conversation object
             final Conversation conversation = new Conversation(cursor);
-            intent = Utils.createViewConversationIntent(context, conversation, folder.uri,
-                    account);
+            intent = Utils.createViewConversationIntent(context, conversation,
+                    folder.folderUri.fullUri, account);
         }
 
         return intent;
@@ -719,7 +719,7 @@
         String notificationTicker = null;
 
         // Boolean indicating that this notification is for a non-inbox label.
-        final boolean isInbox = account.settings.defaultInbox.equals(folder.uri);
+        final boolean isInbox = folder.folderUri.fullUri.equals(account.settings.defaultInbox);
 
         // Notification label name for user label notifications.
         final String notificationLabelName = isInbox ? null : folder.name;
@@ -1376,7 +1376,7 @@
     }
 
     public static void markSeen(final Context context, final Folder folder) {
-        final Uri uri = folder.uri;
+        final Uri uri = folder.folderUri.fullUri;
 
         final ContentValues values = new ContentValues(1);
         values.put(UIProvider.ConversationColumns.SEEN, 1);
diff --git a/src/com/android/mail/utils/Utils.java b/src/com/android/mail/utils/Utils.java
index 4fa8f7d..251e95e 100644
--- a/src/com/android/mail/utils/Utils.java
+++ b/src/com/android/mail/utils/Utils.java
@@ -99,6 +99,8 @@
     public static final String EXTRA_COMPOSE_URI = "composeUri";
     public static final String EXTRA_CONVERSATION = "conversationUri";
 
+    private static final String MAILTO_SCHEME = "mailto";
+
     /** Extra tag for debugging the blank fragment problem. */
     public static final String VIEW_DEBUGGING_TAG = "MailBlankFragment";
 
@@ -1285,6 +1287,15 @@
     }
 
     /**
+     * Adds the Account extra to mailto intents.
+     */
+    public static void addAccountToMailtoIntent(Intent intent, Account account) {
+        if (TextUtils.equals(MAILTO_SCHEME, intent.getData().getScheme())) {
+            intent.putExtra(Utils.EXTRA_ACCOUNT, account);
+        }
+    }
+
+    /**
      * Gets the specified {@link Folder} object.
      *
      * @param folderUri The {@link Uri} for the folder
diff --git a/src/com/android/mail/widget/WidgetConversationViewBuilder.java b/src/com/android/mail/widget/WidgetConversationViewBuilder.java
index 45c4cd9..77c1992 100644
--- a/src/com/android/mail/widget/WidgetConversationViewBuilder.java
+++ b/src/com/android/mail/widget/WidgetConversationViewBuilder.java
@@ -20,13 +20,13 @@
 import com.android.mail.providers.Conversation;
 import com.android.mail.providers.Folder;
 import com.android.mail.ui.FolderDisplayer;
+import com.android.mail.utils.FolderUri;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Typeface;
-import android.net.Uri;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.style.AbsoluteSizeSpan;
@@ -66,7 +66,7 @@
          * Load Conversation Labels
          */
         @Override
-        public void loadConversationFolders(Conversation conv, final Uri ignoreFolderUri,
+        public void loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri,
                 final int ignoreFolderType) {
             super.loadConversationFolders(conv, ignoreFolderUri, ignoreFolderType);
         }
@@ -147,8 +147,8 @@
      * Return the full View
      */
     public RemoteViews getStyledView(CharSequence date, Conversation conversation,
-            final Uri folderUri, final int ignoreFolderType, SpannableStringBuilder senders,
-            String filteredSubject) {
+            final FolderUri folderUri, final int ignoreFolderType,
+            SpannableStringBuilder senders, String filteredSubject) {
 
         final boolean isUnread = !conversation.read;
         String snippet = conversation.getSnippet();
diff --git a/src/com/android/mail/widget/WidgetService.java b/src/com/android/mail/widget/WidgetService.java
index 7d19c68..a8a45f3 100644
--- a/src/com/android/mail/widget/WidgetService.java
+++ b/src/com/android/mail/widget/WidgetService.java
@@ -48,6 +48,7 @@
 import com.android.mail.providers.UIProvider.ConversationListQueryParameters;
 import com.android.mail.providers.UIProvider.FolderType;
 import com.android.mail.utils.AccountUtils;
+import com.android.mail.utils.FolderUri;
 import com.android.mail.utils.DelayedTaskHandler;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
@@ -241,7 +242,7 @@
                 String folderString = intent.getStringExtra(Utils.EXTRA_FOLDER);
                 Folder folder = Folder.fromString(folderString);
                 if (folder != null) {
-                    mFolderUri = folder.uri;
+                    mFolderUri = folder.folderUri.fullUri;
                     mFolderConversationListUri = folder.conversationListUri;
                 } else {
                     mFolderUri = Uri.EMPTY;
@@ -414,8 +415,8 @@
 
                 // Load up our remote view.
                 RemoteViews remoteViews = mWidgetConversationViewBuilder.getStyledView(date,
-                        conversation, mFolderUri, ignoreFolderType, senderBuilder,
-                                filterTag(conversation.subject));
+                        conversation, new FolderUri(mFolderUri), ignoreFolderType,
+                        senderBuilder, filterTag(conversation.subject));
 
                 // On click intent.
                 remoteViews.setOnClickFillInIntent(R.id.widget_conversation,
diff --git a/tests/src/com/android/mail/compose/ComposeActivityTest.java b/tests/src/com/android/mail/compose/ComposeActivityTest.java
index f7662e9..c2c55de 100644
--- a/tests/src/com/android/mail/compose/ComposeActivityTest.java
+++ b/tests/src/com/android/mail/compose/ComposeActivityTest.java
@@ -16,6 +16,9 @@
 
 package com.android.mail.compose;
 
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
@@ -25,38 +28,47 @@
 import android.text.TextUtils;
 import android.text.util.Rfc822Tokenizer;
 
+import com.android.mail.compose.ComposeActivity;
 import com.android.mail.providers.Account;
 import com.android.mail.providers.Attachment;
+import com.android.mail.providers.MailAppProvider;
 import com.android.mail.providers.Message;
 import com.android.mail.providers.ReplyFromAccount;
 import com.android.mail.providers.UIProvider;
 import com.android.mail.utils.AccountUtils;
+import com.android.mail.utils.LogUtils;
 import com.android.mail.utils.MatrixCursorWithCachedColumns;
+import com.android.mail.utils.Utils;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 
+import java.lang.Deprecated;
+import java.lang.Throwable;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashSet;
 
 @SmallTest
 public class ComposeActivityTest extends ActivityInstrumentationTestCase2<ComposeActivity> {
+    // TODO: Remove usages of FromAddressSpinner#initialize and ComposeActivity#initReplyRecipients.
+    // The internal state of the activity instance may have the wrong mReplyFromAccount as
+    // this is set when handling the initial intent.  Theses tests should
+    // instantiate the ComposeActivity with the correct reply all intent
 
-    private ComposeActivity mActivity;
+    // This varible shouldn't be used, as it may not match the state of the ComposeActivity
+    // TODO: remove usage of this variable
+    @Deprecated
     private Account mAccount;
 
+    private static final Account[] EMPTY_ACCOUNT_LIST = new Account[0];
+
     public ComposeActivityTest() {
         super(ComposeActivity.class);
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        mActivity = getActivity();
-        super.setUp();
-    }
-
-    private Message getRefMessage() {
-        Cursor foldersCursor = mActivity.getContentResolver().query(mAccount.folderListUri,
+    private Message getRefMessage(ContentResolver resolver, Uri folderListUri) {
+        Cursor foldersCursor = resolver.query(folderListUri,
                 UIProvider.FOLDERS_PROJECTION, null, null, null);
         Uri convUri = null;
         if (foldersCursor != null) {
@@ -65,7 +77,8 @@
                     .getString(UIProvider.FOLDER_CONVERSATION_LIST_URI_COLUMN));
             foldersCursor.close();
         }
-        Cursor convCursor = mActivity.getContentResolver().query(convUri,
+
+        Cursor convCursor = resolver.query(convUri,
                 UIProvider.CONVERSATION_PROJECTION, null, null, null);
         Uri messagesUri = null;
         if (convCursor != null) {
@@ -74,7 +87,8 @@
                     .getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN));
             convCursor.close();
         }
-        Cursor msgCursor = mActivity.getContentResolver().query(messagesUri,
+
+        Cursor msgCursor = resolver.query(messagesUri,
                 UIProvider.MESSAGE_PROJECTION, null, null, null);
         if (msgCursor != null) {
             msgCursor.moveToFirst();
@@ -82,16 +96,32 @@
         return new Message(msgCursor);
     }
 
-    public void setAccount(String accountName) {
+
+    private Message getRefMessage(ContentResolver resolver) {
+        return getRefMessage(resolver, mAccount.folderListUri);
+    }
+
+    public void setAccount(ComposeActivity activity, String accountName) {
         // Get a mock account.
-        Account[] results = AccountUtils.getSyncingAccounts(mActivity);
+        final Account account = getAccountForName(activity, accountName);
+        if (account != null) {
+            mAccount = account;
+            activity.setAccount(mAccount);
+        }
+    }
+
+    private Account[] getAccounts(Context context) {
+        return AccountUtils.getSyncingAccounts(context);
+    }
+
+    private Account getAccountForName(Context context, String accountName) {
+        Account[] results = getAccounts(context);
         for (Account account : results) {
             if (account.name.equals(accountName)) {
-                mAccount = account;
-                mActivity.setAccount(mAccount);
-                break;
+                return account;
             }
         }
+        return null;
     }
 
     /**
@@ -99,17 +129,17 @@
      * and they are replying all to a message where their custom from was a
      * recipient. TODO: verify web behavior
      */
-    public void testRecipientsRefReplyAllCustomFromReplyTo() {
-        setAccount("account3@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefReplyAllCustomFromReplyTo() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account3@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         final String customFrom = "CUSTOMaccount3@mockuiprovider.com";
         refMessage.setFrom("account3@mockuiprovider.com");
         refMessage.setTo("someotheraccount1@mockuiprovider.com, "
                 + "someotheraccount2@mockuiprovider.com, someotheraccount3@mockuiprovider.com, "
                 + customFrom);
         refMessage.setReplyTo(customFrom);
-        final ComposeActivity activity = mActivity;
-        mActivity.mFromSpinner = new FromAddressSpinner(mActivity);
+        activity.mFromSpinner = new FromAddressSpinner(activity);
         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
                 customFrom, customFrom, true, true);
         JSONArray array = new JSONArray();
@@ -117,10 +147,11 @@
         mAccount.accountFromAddresses = array.toString();
         ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
                 mAccount.name, mAccount.name, customFrom, true, false);
-        mActivity.mFromSpinner.setCurrentAccount(currentAccount);
-        mActivity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
-                currentAccount.account, null, null);
-        mActivity.runOnUiThread(new Runnable() {
+        activity.mFromSpinner.setCurrentAccount(currentAccount);
+
+        activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
+                currentAccount.account, EMPTY_ACCOUNT_LIST, null);
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -140,20 +171,21 @@
      * Test the cases where: The user sent a message to one of
      * their custom froms and just replied to that message
      */
-    public void testRecipientsRefReplyAllOnlyAccount() {
-        setAccount("account3@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefReplyAllOnlyAccount() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account3@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("account3@mockuiprovider.com");
         refMessage.setTo("account3@mockuiprovider.com");
-        final ComposeActivity activity = mActivity;
         final Account account = mAccount;
-        mActivity.mFromSpinner = new FromAddressSpinner(mActivity);
+        activity.mFromSpinner = new FromAddressSpinner(activity);
         ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
                 mAccount.name, mAccount.name, mAccount.name, true, false);
-        mActivity.mFromSpinner.setCurrentAccount(currentAccount);
-        mActivity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
-                currentAccount.account, null, null);
-        mActivity.runOnUiThread(new Runnable() {
+        activity.mFromSpinner.setCurrentAccount(currentAccount);
+
+        activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
+                currentAccount.account, EMPTY_ACCOUNT_LIST, null);
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -173,14 +205,14 @@
      * Test the cases where: The user sent a message to one of
      * their custom froms and just replied to that message
      */
-    public void testRecipientsRefReplyAllOnlyCustomFrom() {
-        setAccount("account3@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefReplyAllOnlyCustomFrom() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account3@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         final String customFrom = "CUSTOMaccount3@mockuiprovider.com";
         refMessage.setFrom("account3@mockuiprovider.com");
         refMessage.setTo(customFrom);
-        final ComposeActivity activity = mActivity;
-        mActivity.mFromSpinner = new FromAddressSpinner(mActivity);
+        activity.mFromSpinner = new FromAddressSpinner(activity);
         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
                 customFrom, customFrom, true, true);
         JSONArray array = new JSONArray();
@@ -188,10 +220,11 @@
         mAccount.accountFromAddresses = array.toString();
         ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
                 mAccount.name, mAccount.name, customFrom, true, false);
-        mActivity.mFromSpinner.setCurrentAccount(currentAccount);
-        mActivity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
-                currentAccount.account, null, null);
-        mActivity.runOnUiThread(new Runnable() {
+        activity.mFromSpinner.setCurrentAccount(currentAccount);
+
+        activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
+                currentAccount.account, EMPTY_ACCOUNT_LIST, null);
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -207,13 +240,13 @@
         });
     }
 
-    public void testReply() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testReply() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         final String refMessageFromAccount = refMessage.getFrom();
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
@@ -229,14 +262,14 @@
         });
     }
 
-    public void testReplyWithReplyTo() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testReplyWithReplyTo() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setReplyTo("replytofromaccount1@mock.com");
-        final ComposeActivity activity = mActivity;
         final String refReplyToAccount = refMessage.getReplyTo();
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
@@ -255,13 +288,13 @@
     /**
      * Reply to a message you sent yourself to some recipients in the to field.
      */
-    public void testReplyToSelf() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testReplyToSelf() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("Account Test <account1@mockuiprovider.com>");
         refMessage.setTo("test1@gmail.com");
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
@@ -280,13 +313,13 @@
     /**
      * Reply-all to a message you sent.
      */
-    public void testReplyAllToSelf() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testReplyAllToSelf() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("Account Test <account1@mockuiprovider.com>");
         refMessage.setTo("test1@gmail.com, test2@gmail.com");
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -306,14 +339,14 @@
     /**
      * Reply-all to a message you sent with some to and some CC recips.
      */
-    public void testReplyAllToSelfWithCc() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testReplyAllToSelfWithCc() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("Account Test <account1@mockuiprovider.com>");
         refMessage.setTo("test1@gmail.com, test2@gmail.com");
         refMessage.setCc("testcc@gmail.com");
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -332,14 +365,14 @@
         });
     }
 
-    public void testReplyAll() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testReplyAll() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         final String[] refMessageTo = TextUtils.split(refMessage.getTo(), ",");
         final String refMessageFromAccount = refMessage.getFrom();
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -355,15 +388,15 @@
         });
     }
 
-    public void testReplyAllWithReplyTo() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testReplyAllWithReplyTo() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setReplyTo("replytofromaccount1@mock.com");
-        final ComposeActivity activity = mActivity;
         final String[] refMessageTo = TextUtils.split(refMessage.getTo(), ",");
         final String refReplyToAccount = refMessage.getReplyTo();
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -401,15 +434,15 @@
         return new Message(cursor);
     }
 
-    public void testReplyAllWithCc() {
-        setAccount("account1@mockuiprovider.com");
+    public void testReplyAllWithCc() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
         final Message refMessage = getRefMessageWithCc(0, false);
-        final ComposeActivity activity = mActivity;
         final String[] refMessageTo = TextUtils.split(refMessage.getTo(), ",");
         final String[] refMessageCc = TextUtils.split(refMessage.getCc(), ",");
         final String refMessageFromAccount = refMessage.getFrom();
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -417,7 +450,8 @@
                 String[] cc = activity.getCcAddresses();
                 String[] bcc = activity.getBccAddresses();
                 assertTrue(to.length == 1);
-                assertEquals(refMessageFromAccount, Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
+                assertEquals(refMessageFromAccount,
+                        Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
                 assertEquals(cc.length, refMessageTo.length + refMessageCc.length);
                 HashSet<String> ccMap = new HashSet<String>();
                 for (String recip : cc) {
@@ -434,12 +468,12 @@
         });
     }
 
-    public void testForward() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testForward() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.FORWARD);
@@ -453,12 +487,12 @@
         });
     }
 
-    public void testCompose() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
-        final ComposeActivity activity = mActivity;
+    public void testCompose() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.COMPOSE);
@@ -475,14 +509,14 @@
     /**
      * Test the cases where: The user is replying to a message they sent
      */
-    public void testRecipientsRefMessageReplyToSelf() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefMessageReplyToSelf() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("account0@mockuiprovider.com");
         refMessage.setTo("someotheraccount@mockuiprovider.com");
-        final ComposeActivity activity = mActivity;
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
@@ -501,13 +535,13 @@
      * Test the cases where:
      * The user is replying to a message sent from one of their custom froms
      */
-    public void testRecipientsRefMessageReplyToCustomFrom() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefMessageReplyToCustomFrom() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("CUSTOMaccount1@mockuiprovider.com");
         refMessage.setTo("someotheraccount@mockuiprovider.com");
-        final ComposeActivity activity = mActivity;
-        mActivity.mFromSpinner = new FromAddressSpinner(mActivity);
+        activity.mFromSpinner = new FromAddressSpinner(activity);
         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, refMessage.getFrom(),
                 refMessage.getFrom(), refMessage.getFrom(), true, true);
         JSONArray array = new JSONArray();
@@ -515,11 +549,11 @@
         mAccount.accountFromAddresses = array.toString();
         ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
                 mAccount.name, mAccount.name, mAccount.name, true, false);
-        mActivity.mFromSpinner.setCurrentAccount(currentAccount);
-        mActivity.mFromSpinner.initialize(ComposeActivity.REPLY, currentAccount.account,
-                null, null);
+        activity.mFromSpinner.setCurrentAccount(currentAccount);
+        activity.mFromSpinner.initialize(ComposeActivity.REPLY, currentAccount.account,
+                EMPTY_ACCOUNT_LIST, null);
 
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
@@ -538,16 +572,16 @@
      * Test the cases where:
      * The user is replying to a message sent from one of their custom froms
      */
-    public void testRecipientsRefMessageReplyAllCustomFrom() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefMessageReplyAllCustomFrom() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         final String customFrom = "CUSTOMaccount1@mockuiprovider.com";
         refMessage.setFrom("senderaccount@mockuiprovider.com");
         refMessage.setTo("someotheraccount@mockuiprovider.com, "
                 + "someotheraccount2@mockuiprovider.com, someotheraccount4@mockuiprovider.com, "
                 + customFrom);
-        final ComposeActivity activity = mActivity;
-        mActivity.mFromSpinner = new FromAddressSpinner(mActivity);
+        activity.mFromSpinner = new FromAddressSpinner(activity);
         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
                 customFrom, customFrom, true, true);
         JSONArray array = new JSONArray();
@@ -555,10 +589,10 @@
         mAccount.accountFromAddresses = array.toString();
         ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
                 mAccount.name, mAccount.name, mAccount.name, true, false);
-        mActivity.mFromSpinner.setCurrentAccount(currentAccount);
-        mActivity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
-                currentAccount.account, null, null);
-        mActivity.runOnUiThread(new Runnable() {
+        activity.mFromSpinner.setCurrentAccount(currentAccount);
+        activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
+                currentAccount.account, EMPTY_ACCOUNT_LIST, null);
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -580,16 +614,16 @@
      * Test the cases where:
      * The user is replying to a message sent from one of their custom froms
      */
-    public void testRecipientsRefMessageReplyAllCustomFromThisAccount() {
-        setAccount("account1@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testRecipientsRefMessageReplyAllCustomFromThisAccount() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account1@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         final String customFrom = "CUSTOMaccount1@mockuiprovider.com";
         refMessage.setFrom("account1@mockuiprovider.com");
         refMessage.setTo("someotheraccount@mockuiprovider.com, "
                 + "someotheraccount2@mockuiprovider.com, someotheraccount4@mockuiprovider.com, "
                 + customFrom);
-        final ComposeActivity activity = mActivity;
-        mActivity.mFromSpinner = new FromAddressSpinner(mActivity);
+        activity.mFromSpinner = new FromAddressSpinner(activity);
         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
                 customFrom, customFrom, true, true);
         JSONArray array = new JSONArray();
@@ -597,10 +631,10 @@
         mAccount.accountFromAddresses = array.toString();
         ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
                 mAccount.name, mAccount.name, mAccount.name, true, false);
-        mActivity.mFromSpinner.setCurrentAccount(currentAccount);
-        mActivity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
-                currentAccount.account, null, null);
-        mActivity.runOnUiThread(new Runnable() {
+        activity.mFromSpinner.setCurrentAccount(currentAccount);
+        activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
+                currentAccount.account, EMPTY_ACCOUNT_LIST, null);
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
@@ -619,6 +653,153 @@
         });
     }
 
+    // Test replying to a message in the first account in the list, and verify that
+    // the Compose Activity's from account for the reply is correct
+    public void testReplySendingAccount0() throws Throwable {
+        final Context context = getInstrumentation().getContext();
+        // Get the test account
+        final Account currentAccount = getAccountForName(context, "account0@mockuiprovider.com");
+
+        // Get the message to be replied to
+        final Message refMessage =
+                getRefMessage(context.getContentResolver(), currentAccount.folderListUri);
+
+        // Create the reply intent
+        final Intent replyIntent =
+                ComposeActivity.updateActionIntent(currentAccount, refMessage.uri,
+                        ComposeActivity.REPLY, new Intent());
+
+        setActivityIntent(replyIntent);
+
+        final ComposeActivity activity = getActivity();
+        final String refMessageFromAccount = refMessage.getFrom();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                String[] to = activity.getToAddresses();
+                String[] cc = activity.getCcAddresses();
+                String[] bcc = activity.getBccAddresses();
+                Account fromAccount = activity.getFromAccount();
+                assertEquals(1, to.length);
+                assertEquals(refMessageFromAccount,
+                        Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
+                assertEquals(0, cc.length);
+                assertEquals(0, bcc.length);
+                assertEquals("account0@mockuiprovider.com", fromAccount.name);
+            }
+        });
+    }
+
+    // Test replying to a message in the third account in the list, and verify that
+    // the Compose Activity's from account for the reply is correct
+    public void testReplySendingAccount1() throws Throwable {
+        final Context context = getInstrumentation().getContext();
+        // Get the test account
+        final Account currentAccount = getAccountForName(context, "account2@mockuiprovider.com");
+
+        // Get the message to be replied to
+        final Message refMessage =
+                getRefMessage(context.getContentResolver(), currentAccount.folderListUri);
+
+        // Create the reply intent
+        final Intent replyIntent =
+                ComposeActivity.updateActionIntent(currentAccount, refMessage.uri,
+                        ComposeActivity.REPLY, new Intent());
+
+        setActivityIntent(replyIntent);
+
+        final ComposeActivity activity = getActivity();
+        Account fromAccount = activity.getFromAccount();
+
+        final String refMessageFromAccount = refMessage.getFrom();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                String[] to = activity.getToAddresses();
+                String[] cc = activity.getCcAddresses();
+                String[] bcc = activity.getBccAddresses();
+                Account fromAccount = activity.getFromAccount();
+                assertEquals(1, to.length);
+                assertEquals(refMessageFromAccount,
+                        Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
+                assertEquals(0, cc.length);
+                assertEquals(0, bcc.length);
+                assertEquals("account2@mockuiprovider.com", fromAccount.name);
+            }
+        });
+    }
+
+    // Test a mailto VIEW Intent, with an account specified
+    public void testMailToAccount() throws Throwable {
+        final Context context = getInstrumentation().getContext();
+        // Get the test account
+        final Account currentAccount = getAccountForName(context, "account2@mockuiprovider.com");
+
+        // Create the mailto intent
+        final Intent mailtoIntent =
+                new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:test@localhost.com"));
+        Utils.addAccountToMailtoIntent(mailtoIntent, currentAccount);
+
+        setActivityIntent(mailtoIntent);
+
+        final ComposeActivity activity = getActivity();
+        Account fromAccount = activity.getFromAccount();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                String[] to = activity.getToAddresses();
+                String[] cc = activity.getCcAddresses();
+                String[] bcc = activity.getBccAddresses();
+                Account fromAccount = activity.getFromAccount();
+                assertEquals( 1, to.length);
+                assertEquals("test@localhost.com",
+                        Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
+                assertEquals(0, cc.length);
+                assertEquals(0, bcc.length);
+                assertEquals("account2@mockuiprovider.com", fromAccount.name);
+            }
+        });
+    }
+
+    // Test a mailto VIEW Intent, with no account specified.  The fromAccount should default to the
+    // last sent account.
+    public void testMailToAccountWithLastSentAccount() throws Throwable {
+        final Context context = getInstrumentation().getContext();
+
+        // Set the last sent account to account0
+        final Account lastSentAccount = getAccountForName(context, "account1@mockuiprovider.com");
+        MailAppProvider appProvider = MailAppProvider.getInstance();
+        appProvider.setLastSentFromAccount(lastSentAccount.uri.toString());
+
+        // Create the mailto intent
+        final Intent mailtoIntent =
+                new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:test@localhost.com"));
+
+        setActivityIntent(mailtoIntent);
+
+        final ComposeActivity activity = getActivity();
+        Account fromAccount = activity.getFromAccount();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                String[] to = activity.getToAddresses();
+                String[] cc = activity.getCcAddresses();
+                String[] bcc = activity.getBccAddresses();
+                Account fromAccount = activity.getFromAccount();
+                assertEquals( 1, to.length);
+                assertEquals("test@localhost.com",
+                        Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
+                assertEquals(0, cc.length);
+                assertEquals(0, bcc.length);
+                assertEquals("account1@mockuiprovider.com", fromAccount.name);
+            }
+        });
+    }
+
     private static String createAttachmentsJson() {
         Attachment attachment1 = new Attachment();
         attachment1.contentUri = Uri.parse("www.google.com");
@@ -639,14 +820,14 @@
     }
 
     // First test: switch reply to reply all to fwd, 1 to recipient, 1 cc recipient.
-    public void testChangeModes0() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testChangeModes0() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("fromaccount@mockuiprovider.com");
         refMessage.setTo("account0@mockuiprovider.com");
         refMessage.setCc("ccaccount@mockuiprovider.com");
-        final ComposeActivity activity = mActivity;
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.mRefMessage = refMessage;
@@ -673,14 +854,14 @@
     }
 
     // Switch reply to reply all to fwd, 2 to recipients, 1 cc recipient.
-    public void testChangeModes1() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testChangeModes1() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("fromaccount@mockuiprovider.com");
         refMessage.setTo("account0@mockuiprovider.com, toaccount0@mockuiprovider.com");
         refMessage.setCc("ccaccount@mockuiprovider.com");
-        final ComposeActivity activity = mActivity;
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.mRefMessage = refMessage;
@@ -700,7 +881,7 @@
                         || activity.getCcAddresses()[1].contains(refMessage.getCc()));
                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0@mockuiprovider.com")
                         || activity.getCcAddresses()[1]
-                                .contains("toaccount0@mockuiprovider.com"));
+                        .contains("toaccount0@mockuiprovider.com"));
                 assertEquals(activity.getBccAddresses().length, 0);
                 activity.onNavigationItemSelected(2, ComposeActivity.FORWARD);
                 assertEquals(activity.getToAddresses().length, 0);
@@ -711,14 +892,14 @@
     }
 
     // Switch reply to reply all to fwd, 2 to recipients, 2 cc recipients.
-    public void testChangeModes2() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testChangeModes2() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.setFrom("fromaccount@mockuiprovider.com");
         refMessage.setTo("account0@mockuiprovider.com, toaccount0@mockuiprovider.com");
         refMessage.setCc("ccaccount@mockuiprovider.com, ccaccount2@mockuiprovider.com");
-        final ComposeActivity activity = mActivity;
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.mRefMessage = refMessage;
@@ -745,9 +926,9 @@
                         || activity.getCcAddresses()[2].contains("toaccount0@mockuiprovider.com"));
                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0@mockuiprovider.com")
                         || activity.getCcAddresses()[1]
-                                .contains("toaccount0@mockuiprovider.com")
+                        .contains("toaccount0@mockuiprovider.com")
                         || activity.getCcAddresses()[2]
-                                .contains("toaccount0@mockuiprovider.com"));
+                        .contains("toaccount0@mockuiprovider.com"));
                 assertEquals(activity.getBccAddresses().length, 0);
                 activity.onNavigationItemSelected(2, ComposeActivity.FORWARD);
                 assertEquals(activity.getToAddresses().length, 0);
@@ -758,13 +939,13 @@
     }
 
     // Switch reply to reply all to fwd, 2 attachments.
-    public void testChangeModes3() {
-        setAccount("account0@mockuiprovider.com");
-        final Message refMessage = getRefMessage();
+    public void testChangeModes3() throws Throwable {
+        final ComposeActivity activity = getActivity();
+        setAccount(activity, "account0@mockuiprovider.com");
+        final Message refMessage = getRefMessage(activity.getContentResolver());
         refMessage.hasAttachments = true;
         refMessage.attachmentsJson = createAttachmentsJson();
-        final ComposeActivity activity = mActivity;
-        mActivity.runOnUiThread(new Runnable() {
+        runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
                 activity.mRefMessage = refMessage;