am 26106360: (-s ours) Merge "Check the parent for null in deleteEditor"

* commit '261063609aa80010baad4dffe591f2f28b8a0f67':
  Check the parent for null in deleteEditor
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d06fe1d..996bc78 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -23,6 +23,8 @@
     <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_CALL_LOG" />
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
@@ -45,6 +47,7 @@
     <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
     <uses-permission android:name="com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL" />
     <uses-permission android:name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK" />
+    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
     <!-- allow broadcasting secret code intents that reboot the phone -->
     <uses-permission android:name="android.permission.REBOOT" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -118,7 +121,7 @@
             android:launchMode="singleTask"
             android:clearTaskOnLaunch="true"
             android:icon="@mipmap/ic_launcher_phone"
-            android:screenOrientation="nosensor"
+            android:screenOrientation="portrait"
             android:enabled="@*android:bool/config_voice_capable"
             android:taskAffinity="android.task.contacts.phone"
             android:windowSoftInputMode="stateAlwaysHidden|adjustNothing">
@@ -404,7 +407,7 @@
             android:launchMode="singleTop"
             android:excludeFromRecents="true"
             android:noHistory="true"
-            android:taskAffinity="android.task.quickcontact"
+            android:taskAffinity=""
             android:windowSoftInputMode="stateUnchanged">
 
             <intent-filter>
@@ -415,6 +418,10 @@
             </intent-filter>
         </activity>
 
+        <receiver
+            android:name=".quickcontact.QuickContactBroadcastReceiver"
+            android:exported="false" />
+
         <activity-alias android:name="ContactShortcut"
             android:targetActivity=".activities.ContactSelectionActivity"
             android:label="@string/shortcutContact"
@@ -471,7 +478,8 @@
         <!-- Views the details of a single contact -->
         <activity android:name=".activities.ContactDetailActivity"
             android:label="@string/viewContactTitle"
-            android:theme="@style/DetailActivityTheme">
+            android:theme="@style/DetailActivityTheme"
+            android:parentActivityName=".activities.PeopleActivity">
 
             <intent-filter android:label="@string/viewContactDesription">
                 <action android:name="android.intent.action.VIEW" />
@@ -545,7 +553,18 @@
                 <data android:mimeType="image/*" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
-            />
+        </activity>
+
+        <!--
+            Internal photo selection activity.  This activity handles all configuration changes by
+            itself.
+        -->
+        <activity android:name=".activities.PhotoSelectionActivity"
+            android:theme="@style/Theme.PhotoSelector"
+            android:launchMode="singleTop"
+            android:windowSoftInputMode="stateUnchanged"
+            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
+            >
         </activity>
 
         <!-- Interstitial activity that shows a phone disambig dialog -->
@@ -556,13 +575,13 @@
         <!-- vCard related -->
         <activity android:name=".vcard.ImportVCardActivity"
             android:configChanges="orientation|screenSize|keyboardHidden"
+            android:screenOrientation="nosensor"
             android:theme="@style/BackgroundOnlyTheme">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <data android:mimeType="text/directory" />
                 <data android:mimeType="text/vcard" />
                 <data android:mimeType="text/x-vcard" />
-                <data android:mimeType="text/x-vCard" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
@@ -574,7 +593,6 @@
                 <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                 <data android:mimeType="text/vcard" />
                 <data android:mimeType="text/x-vcard" />
-                <data android:mimeType="text/x-vCard" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
@@ -610,7 +628,8 @@
                     android:resource="@xml/social_widget_info" />
         </receiver>
 
-        <receiver android:name=".calllog.CallLogReceiver">
+        <receiver android:name=".calllog.CallLogReceiver"
+            android:enabled="@*android:bool/config_voice_capable">
             <intent-filter>
                 <action android:name="android.intent.action.NEW_VOICEMAIL" />
                 <data
@@ -636,5 +655,16 @@
             android:name=".calllog.CallLogNotificationsService"
             android:exported="false"
         />
+
+        <!-- Service that is exclusively for the Phone application that sends out a view
+             notification. This service might be removed in future versions of the app  -->
+        <service android:name=".ViewNotificationService"
+            android:permission="android.permission.WRITE_CONTACTS"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.contacts.VIEW_NOTIFICATION" />
+                <data android:mimeType="vnd.android.cursor.item/contact" />
+            </intent-filter>
+        </service>
     </application>
 </manifest>
diff --git a/proguard.flags b/proguard.flags
index f4ec4b2..39784b1 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -9,24 +9,12 @@
   public void *(android.view.MenuItem);
 }
 
-# TODO: Instead of keeping the following two functions we could as well just remove them completely
-# as they are only used in test code
-
--keep class com.android.contacts.model.EntityDelta {
-  public com.android.contacts.model.EntityDelta$ValuesDelta getSuperPrimaryEntry(java.lang.String,boolean);
-}
-
--keep class com.android.contacts.model.EntityDelta$ValuesDelta {
-  public android.content.ContentValues getAfter();
-}
-
-# Any methods whose name is '*ForTest' are preserved.
--keep class ** {
-  *** *ForTest(...);
-}
-
-# Any class or method annotated with NeededForTesting.
+# Any class or method annotated with NeededForTesting or NeededForReflection.
 -keep @com.android.contacts.test.NeededForTesting class *
+-keep @com.android.contacts.test.NeededForReflection class *
 -keepclassmembers class * {
 @com.android.contacts.test.NeededForTesting *;
+@com.android.contacts.test.NeededForReflection *;
 }
+
+-verbose
diff --git a/res/color/kind_title.xml b/res/color/kind_title.xml
deleted file mode 100644
index 7489f75..0000000
--- a/res/color/kind_title.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@*android:color/bright_foreground_dark" />
-</selector>
diff --git a/res/drawable-hdpi/ab_bottom_opaque_dark_holo.9.png b/res/drawable-hdpi/ab_bottom_opaque_dark_holo.9.png
deleted file mode 100644
index 4991dff..0000000
--- a/res/drawable-hdpi/ab_bottom_opaque_dark_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/aggregation_suggestions_bg.9.png b/res/drawable-hdpi/aggregation_suggestions_bg.9.png
index 687cc08..d279fb1 100644
--- a/res/drawable-hdpi/aggregation_suggestions_bg.9.png
+++ b/res/drawable-hdpi/aggregation_suggestions_bg.9.png
Binary files differ
diff --git a/res/drawable-hdpi/bg_blk_search_contact.9.png b/res/drawable-hdpi/bg_blk_search_contact.9.png
deleted file mode 100644
index db83477..0000000
--- a/res/drawable-hdpi/bg_blk_search_contact.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_textfield_normal.9.png b/res/drawable-hdpi/btn_dial_textfield_normal.9.png
deleted file mode 100644
index 1718372..0000000
--- a/res/drawable-hdpi/btn_dial_textfield_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_textfield_pressed.9.png b/res/drawable-hdpi/btn_dial_textfield_pressed.9.png
deleted file mode 100644
index eb1fda0..0000000
--- a/res/drawable-hdpi/btn_dial_textfield_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_dial_textfield_selected.9.png b/res/drawable-hdpi/btn_dial_textfield_selected.9.png
deleted file mode 100644
index 5ad7b56..0000000
--- a/res/drawable-hdpi/btn_dial_textfield_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_star_off_normal_holo_light.png b/res/drawable-hdpi/btn_star_off_normal_holo_light.png
new file mode 100644
index 0000000..cc17004
--- /dev/null
+++ b/res/drawable-hdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_star_on_normal_holo_light.png b/res/drawable-hdpi/btn_star_on_normal_holo_light.png
new file mode 100644
index 0000000..ce97262
--- /dev/null
+++ b/res/drawable-hdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_0_blk.png b/res/drawable-hdpi/dial_num_0_blk.png
deleted file mode 100644
index f2dcf02..0000000
--- a/res/drawable-hdpi/dial_num_0_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_2_blk.png b/res/drawable-hdpi/dial_num_2_blk.png
deleted file mode 100644
index 852de4e..0000000
--- a/res/drawable-hdpi/dial_num_2_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_3_blk.png b/res/drawable-hdpi/dial_num_3_blk.png
deleted file mode 100644
index 69fd333..0000000
--- a/res/drawable-hdpi/dial_num_3_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_4_blk.png b/res/drawable-hdpi/dial_num_4_blk.png
deleted file mode 100644
index aab94de..0000000
--- a/res/drawable-hdpi/dial_num_4_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_5_blk.png b/res/drawable-hdpi/dial_num_5_blk.png
deleted file mode 100644
index de35f1f..0000000
--- a/res/drawable-hdpi/dial_num_5_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_6_blk.png b/res/drawable-hdpi/dial_num_6_blk.png
deleted file mode 100644
index 407ff2e..0000000
--- a/res/drawable-hdpi/dial_num_6_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_7_blk.png b/res/drawable-hdpi/dial_num_7_blk.png
deleted file mode 100644
index 7a5a38c..0000000
--- a/res/drawable-hdpi/dial_num_7_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_8_blk.png b/res/drawable-hdpi/dial_num_8_blk.png
deleted file mode 100644
index a29b24d..0000000
--- a/res/drawable-hdpi/dial_num_8_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_9_blk.png b/res/drawable-hdpi/dial_num_9_blk.png
deleted file mode 100644
index a402147..0000000
--- a/res/drawable-hdpi/dial_num_9_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_pound_blk.png b/res/drawable-hdpi/dial_num_pound_blk.png
deleted file mode 100644
index 0de2ab4..0000000
--- a/res/drawable-hdpi/dial_num_pound_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_star_blk.png b/res/drawable-hdpi/dial_num_star_blk.png
deleted file mode 100644
index b25eb9b..0000000
--- a/res/drawable-hdpi/dial_num_star_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_contacts.png b/res/drawable-hdpi/ic_launcher_contacts.png
deleted file mode 100644
index f2657dc..0000000
--- a/res/drawable-hdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_phone.png b/res/drawable-hdpi/ic_launcher_phone.png
deleted file mode 100644
index 37ffb9c..0000000
--- a/res/drawable-hdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_shortcut_contact.png b/res/drawable-hdpi/ic_launcher_shortcut_contact.png
deleted file mode 100644
index 2dc1014..0000000
--- a/res/drawable-hdpi/ic_launcher_shortcut_contact.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_shortcut_directdial.png b/res/drawable-hdpi/ic_launcher_shortcut_directdial.png
deleted file mode 100644
index b5c0dd9..0000000
--- a/res/drawable-hdpi/ic_launcher_shortcut_directdial.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_shortcut_directmessage.png b/res/drawable-hdpi/ic_launcher_shortcut_directmessage.png
deleted file mode 100644
index 10720e4..0000000
--- a/res/drawable-hdpi/ic_launcher_shortcut_directmessage.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_2sec_pause.png b/res/drawable-hdpi/ic_menu_2sec_pause.png
deleted file mode 100644
index 3951948..0000000
--- a/res/drawable-hdpi/ic_menu_2sec_pause.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_accounts_holo_light.png b/res/drawable-hdpi/ic_menu_accounts_holo_light.png
deleted file mode 100644
index 59496c9..0000000
--- a/res/drawable-hdpi/ic_menu_accounts_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_add_contact_holo_light.png b/res/drawable-hdpi/ic_menu_add_contact_holo_light.png
deleted file mode 100644
index 616dd2a..0000000
--- a/res/drawable-hdpi/ic_menu_add_contact_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_contacts_holo_light.png b/res/drawable-hdpi/ic_menu_contacts_holo_light.png
deleted file mode 100644
index 6327545..0000000
--- a/res/drawable-hdpi/ic_menu_contacts_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_display_all_holo_light.png b/res/drawable-hdpi/ic_menu_display_all_holo_light.png
deleted file mode 100644
index 59631f0..0000000
--- a/res/drawable-hdpi/ic_menu_display_all_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_import_export_holo_light.png b/res/drawable-hdpi/ic_menu_import_export_holo_light.png
deleted file mode 100644
index a67386f..0000000
--- a/res/drawable-hdpi/ic_menu_import_export_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_mark.png b/res/drawable-hdpi/ic_menu_mark.png
deleted file mode 100755
index 1c09175..0000000
--- a/res/drawable-hdpi/ic_menu_mark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_merge_holo_light.png b/res/drawable-hdpi/ic_menu_merge_holo_light.png
deleted file mode 100644
index eaf32d2..0000000
--- a/res/drawable-hdpi/ic_menu_merge_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_share_holo_light.png b/res/drawable-hdpi/ic_menu_share_holo_light.png
deleted file mode 100644
index 2ba6fb7..0000000
--- a/res/drawable-hdpi/ic_menu_share_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_split_holo_light.png b/res/drawable-hdpi/ic_menu_split_holo_light.png
deleted file mode 100644
index 3784544..0000000
--- a/res/drawable-hdpi/ic_menu_split_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_trash_holo_light.png b/res/drawable-hdpi/ic_menu_trash_holo_light.png
deleted file mode 100644
index 481eb65..0000000
--- a/res/drawable-hdpi/ic_menu_trash_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_wait.png b/res/drawable-hdpi/ic_menu_wait.png
deleted file mode 100644
index 6886e5d..0000000
--- a/res/drawable-hdpi/ic_menu_wait.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_selected_contacts.png b/res/drawable-hdpi/ic_tab_selected_contacts.png
deleted file mode 100644
index 7c92375..0000000
--- a/res/drawable-hdpi/ic_tab_selected_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_tab_unselected_contacts.png b/res/drawable-hdpi/ic_tab_unselected_contacts.png
deleted file mode 100644
index ee09bf1..0000000
--- a/res/drawable-hdpi/ic_tab_unselected_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/list_item_divider.9.png b/res/drawable-hdpi/list_item_divider.9.png
deleted file mode 100644
index 60e2cb2..0000000
--- a/res/drawable-hdpi/list_item_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/list_pressed_holo.9.png b/res/drawable-hdpi/list_pressed_holo.9.png
deleted file mode 100644
index dd183c0..0000000
--- a/res/drawable-hdpi/list_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/magnifying_glass.png b/res/drawable-hdpi/magnifying_glass.png
deleted file mode 100755
index ac88fb4..0000000
--- a/res/drawable-hdpi/magnifying_glass.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png b/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
new file mode 100644
index 0000000..db4ce80
--- /dev/null
+++ b/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png b/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
new file mode 100644
index 0000000..f399920
--- /dev/null
+++ b/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/spinner_default_holo_dark.9.png b/res/drawable-hdpi/spinner_default_holo_dark.9.png
new file mode 100644
index 0000000..34a88df
--- /dev/null
+++ b/res/drawable-hdpi/spinner_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/tab_focused.9.png b/res/drawable-hdpi/tab_focused.9.png
deleted file mode 100644
index a65b8f5..0000000
--- a/res/drawable-hdpi/tab_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_focused_bottom.9.png b/res/drawable-hdpi/tab_focused_bottom.9.png
deleted file mode 100644
index 2fe4a9b..0000000
--- a/res/drawable-hdpi/tab_focused_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_left_arrow.png b/res/drawable-hdpi/tab_left_arrow.png
deleted file mode 100644
index c2274f1..0000000
--- a/res/drawable-hdpi/tab_left_arrow.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_pressed.9.png b/res/drawable-hdpi/tab_pressed.9.png
deleted file mode 100644
index 0f90065..0000000
--- a/res/drawable-hdpi/tab_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_pressed_bottom.9.png b/res/drawable-hdpi/tab_pressed_bottom.9.png
deleted file mode 100644
index 00361aa..0000000
--- a/res/drawable-hdpi/tab_pressed_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_right_arrow.png b/res/drawable-hdpi/tab_right_arrow.png
deleted file mode 100644
index 8a847e0..0000000
--- a/res/drawable-hdpi/tab_right_arrow.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected.9.png b/res/drawable-hdpi/tab_selected.9.png
deleted file mode 100644
index 08a39ff..0000000
--- a/res/drawable-hdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_bottom.9.png b/res/drawable-hdpi/tab_selected_bottom.9.png
deleted file mode 100644
index 3cc26bc..0000000
--- a/res/drawable-hdpi/tab_selected_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected.9.png b/res/drawable-hdpi/tab_unselected.9.png
deleted file mode 100644
index 6150b5b..0000000
--- a/res/drawable-hdpi/tab_unselected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ab_bottom_opaque_dark_holo.9.png b/res/drawable-mdpi/ab_bottom_opaque_dark_holo.9.png
deleted file mode 100644
index 15bef5d..0000000
--- a/res/drawable-mdpi/ab_bottom_opaque_dark_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/aggregation_suggestions_bg.9.png b/res/drawable-mdpi/aggregation_suggestions_bg.9.png
index 687cc08..6cce274 100644
--- a/res/drawable-mdpi/aggregation_suggestions_bg.9.png
+++ b/res/drawable-mdpi/aggregation_suggestions_bg.9.png
Binary files differ
diff --git a/res/drawable-mdpi/bg_blk_search_contact.9.png b/res/drawable-mdpi/bg_blk_search_contact.9.png
deleted file mode 100644
index 2694b5c..0000000
--- a/res/drawable-mdpi/bg_blk_search_contact.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_textfield_normal.9.png b/res/drawable-mdpi/btn_dial_textfield_normal.9.png
deleted file mode 100644
index 277400b..0000000
--- a/res/drawable-mdpi/btn_dial_textfield_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_textfield_pressed.9.png b/res/drawable-mdpi/btn_dial_textfield_pressed.9.png
deleted file mode 100644
index 57a8dd9..0000000
--- a/res/drawable-mdpi/btn_dial_textfield_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_dial_textfield_selected.9.png b/res/drawable-mdpi/btn_dial_textfield_selected.9.png
deleted file mode 100644
index 5956668..0000000
--- a/res/drawable-mdpi/btn_dial_textfield_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_star_off_normal_holo_light.png b/res/drawable-mdpi/btn_star_off_normal_holo_light.png
new file mode 100644
index 0000000..70483d9
--- /dev/null
+++ b/res/drawable-mdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_star_on_normal_holo_light.png b/res/drawable-mdpi/btn_star_on_normal_holo_light.png
new file mode 100644
index 0000000..3a52c18
--- /dev/null
+++ b/res/drawable-mdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_0_blk.png b/res/drawable-mdpi/dial_num_0_blk.png
deleted file mode 100644
index d04add7..0000000
--- a/res/drawable-mdpi/dial_num_0_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_2_blk.png b/res/drawable-mdpi/dial_num_2_blk.png
deleted file mode 100644
index 1d8a35c..0000000
--- a/res/drawable-mdpi/dial_num_2_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_3_blk.png b/res/drawable-mdpi/dial_num_3_blk.png
deleted file mode 100644
index cf78e04..0000000
--- a/res/drawable-mdpi/dial_num_3_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_4_blk.png b/res/drawable-mdpi/dial_num_4_blk.png
deleted file mode 100644
index c9c12c2..0000000
--- a/res/drawable-mdpi/dial_num_4_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_5_blk.png b/res/drawable-mdpi/dial_num_5_blk.png
deleted file mode 100644
index a89dd8f..0000000
--- a/res/drawable-mdpi/dial_num_5_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_6_blk.png b/res/drawable-mdpi/dial_num_6_blk.png
deleted file mode 100644
index c282afb..0000000
--- a/res/drawable-mdpi/dial_num_6_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_7_blk.png b/res/drawable-mdpi/dial_num_7_blk.png
deleted file mode 100644
index df273a2..0000000
--- a/res/drawable-mdpi/dial_num_7_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_8_blk.png b/res/drawable-mdpi/dial_num_8_blk.png
deleted file mode 100644
index 9e5654f..0000000
--- a/res/drawable-mdpi/dial_num_8_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_9_blk.png b/res/drawable-mdpi/dial_num_9_blk.png
deleted file mode 100644
index 6ae1943..0000000
--- a/res/drawable-mdpi/dial_num_9_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_pound_blk.png b/res/drawable-mdpi/dial_num_pound_blk.png
deleted file mode 100644
index add133e..0000000
--- a/res/drawable-mdpi/dial_num_pound_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_star_blk.png b/res/drawable-mdpi/dial_num_star_blk.png
deleted file mode 100644
index f649f14..0000000
--- a/res/drawable-mdpi/dial_num_star_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_contacts.png b/res/drawable-mdpi/ic_launcher_contacts.png
deleted file mode 100644
index 6b06cac..0000000
--- a/res/drawable-mdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_phone.png b/res/drawable-mdpi/ic_launcher_phone.png
deleted file mode 100644
index 5ef8c40..0000000
--- a/res/drawable-mdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_shortcut_contact.png b/res/drawable-mdpi/ic_launcher_shortcut_contact.png
deleted file mode 100644
index bce245c..0000000
--- a/res/drawable-mdpi/ic_launcher_shortcut_contact.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_shortcut_directdial.png b/res/drawable-mdpi/ic_launcher_shortcut_directdial.png
deleted file mode 100644
index e4649cf..0000000
--- a/res/drawable-mdpi/ic_launcher_shortcut_directdial.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_shortcut_directmessage.png b/res/drawable-mdpi/ic_launcher_shortcut_directmessage.png
deleted file mode 100644
index 4be34e5..0000000
--- a/res/drawable-mdpi/ic_launcher_shortcut_directmessage.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_2sec_pause.png b/res/drawable-mdpi/ic_menu_2sec_pause.png
deleted file mode 100644
index dcaa5ff..0000000
--- a/res/drawable-mdpi/ic_menu_2sec_pause.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_accounts_holo_light.png b/res/drawable-mdpi/ic_menu_accounts_holo_light.png
deleted file mode 100644
index ae291d8..0000000
--- a/res/drawable-mdpi/ic_menu_accounts_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_add_contact_holo_light.png b/res/drawable-mdpi/ic_menu_add_contact_holo_light.png
deleted file mode 100644
index 0cfb71b..0000000
--- a/res/drawable-mdpi/ic_menu_add_contact_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_contacts_holo_light.png b/res/drawable-mdpi/ic_menu_contacts_holo_light.png
deleted file mode 100644
index 4a15754..0000000
--- a/res/drawable-mdpi/ic_menu_contacts_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_display_all_holo_light.png b/res/drawable-mdpi/ic_menu_display_all_holo_light.png
deleted file mode 100644
index 9781312..0000000
--- a/res/drawable-mdpi/ic_menu_display_all_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_import_export_holo_light.png b/res/drawable-mdpi/ic_menu_import_export_holo_light.png
deleted file mode 100644
index e31ec6b..0000000
--- a/res/drawable-mdpi/ic_menu_import_export_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_mark.png b/res/drawable-mdpi/ic_menu_mark.png
deleted file mode 100644
index 41ccddf..0000000
--- a/res/drawable-mdpi/ic_menu_mark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_merge_holo_light.png b/res/drawable-mdpi/ic_menu_merge_holo_light.png
deleted file mode 100644
index a650c4d..0000000
--- a/res/drawable-mdpi/ic_menu_merge_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_share_holo_light.png b/res/drawable-mdpi/ic_menu_share_holo_light.png
deleted file mode 100644
index 6b42585..0000000
--- a/res/drawable-mdpi/ic_menu_share_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_split_holo_light.png b/res/drawable-mdpi/ic_menu_split_holo_light.png
deleted file mode 100644
index 56afbc9..0000000
--- a/res/drawable-mdpi/ic_menu_split_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_trash_holo_light.png b/res/drawable-mdpi/ic_menu_trash_holo_light.png
deleted file mode 100644
index 29801b4..0000000
--- a/res/drawable-mdpi/ic_menu_trash_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_wait.png b/res/drawable-mdpi/ic_menu_wait.png
deleted file mode 100644
index c20457a..0000000
--- a/res/drawable-mdpi/ic_menu_wait.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_selected_contacts.png b/res/drawable-mdpi/ic_tab_selected_contacts.png
deleted file mode 100644
index b3e23b7..0000000
--- a/res/drawable-mdpi/ic_tab_selected_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_tab_unselected_contacts.png b/res/drawable-mdpi/ic_tab_unselected_contacts.png
deleted file mode 100644
index b3f5ae0..0000000
--- a/res/drawable-mdpi/ic_tab_unselected_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/list_item_divider.9.png b/res/drawable-mdpi/list_item_divider.9.png
deleted file mode 100644
index 60e2cb2..0000000
--- a/res/drawable-mdpi/list_item_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/list_pressed_holo.9.png b/res/drawable-mdpi/list_pressed_holo.9.png
deleted file mode 100644
index 9358dd8..0000000
--- a/res/drawable-mdpi/list_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/magnifying_glass.png b/res/drawable-mdpi/magnifying_glass.png
deleted file mode 100755
index 2592ae0..0000000
--- a/res/drawable-mdpi/magnifying_glass.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png b/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
new file mode 100644
index 0000000..886b044
--- /dev/null
+++ b/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png b/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
new file mode 100644
index 0000000..1ac24be
--- /dev/null
+++ b/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/spinner_default_holo_dark.9.png b/res/drawable-mdpi/spinner_default_holo_dark.9.png
new file mode 100644
index 0000000..48af192
--- /dev/null
+++ b/res/drawable-mdpi/spinner_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/tab_focused.9.png b/res/drawable-mdpi/tab_focused.9.png
deleted file mode 100644
index 6190694..0000000
--- a/res/drawable-mdpi/tab_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_focused_bottom.9.png b/res/drawable-mdpi/tab_focused_bottom.9.png
deleted file mode 100644
index 0e3bdb0..0000000
--- a/res/drawable-mdpi/tab_focused_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_left_arrow.png b/res/drawable-mdpi/tab_left_arrow.png
deleted file mode 100644
index e35d58d..0000000
--- a/res/drawable-mdpi/tab_left_arrow.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_pressed.9.png b/res/drawable-mdpi/tab_pressed.9.png
deleted file mode 100644
index dbada51..0000000
--- a/res/drawable-mdpi/tab_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_pressed_bottom.9.png b/res/drawable-mdpi/tab_pressed_bottom.9.png
deleted file mode 100644
index 4bf95d5..0000000
--- a/res/drawable-mdpi/tab_pressed_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_right_arrow.png b/res/drawable-mdpi/tab_right_arrow.png
deleted file mode 100644
index 8acbba0..0000000
--- a/res/drawable-mdpi/tab_right_arrow.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected.9.png b/res/drawable-mdpi/tab_selected.9.png
deleted file mode 100644
index b3c9fb1..0000000
--- a/res/drawable-mdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_bottom.9.png b/res/drawable-mdpi/tab_selected_bottom.9.png
deleted file mode 100644
index f69f08e..0000000
--- a/res/drawable-mdpi/tab_selected_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected.9.png b/res/drawable-mdpi/tab_unselected.9.png
deleted file mode 100644
index a79fa2a..0000000
--- a/res/drawable-mdpi/tab_unselected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ab_bottom_opaque_dark_holo.9.png b/res/drawable-xhdpi/ab_bottom_opaque_dark_holo.9.png
deleted file mode 100644
index 454e8b4..0000000
--- a/res/drawable-xhdpi/ab_bottom_opaque_dark_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/bg_blk_search_contact.9.png b/res/drawable-xhdpi/bg_blk_search_contact.9.png
deleted file mode 100644
index fc3a05e..0000000
--- a/res/drawable-xhdpi/bg_blk_search_contact.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_textfield_normal.9.png b/res/drawable-xhdpi/btn_dial_textfield_normal.9.png
deleted file mode 100644
index 9903624..0000000
--- a/res/drawable-xhdpi/btn_dial_textfield_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_textfield_pressed.9.png b/res/drawable-xhdpi/btn_dial_textfield_pressed.9.png
deleted file mode 100644
index 00e2e7e..0000000
--- a/res/drawable-xhdpi/btn_dial_textfield_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_dial_textfield_selected.9.png b/res/drawable-xhdpi/btn_dial_textfield_selected.9.png
deleted file mode 100644
index bf2e27f..0000000
--- a/res/drawable-xhdpi/btn_dial_textfield_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_star_off_normal_holo_light.png b/res/drawable-xhdpi/btn_star_off_normal_holo_light.png
new file mode 100644
index 0000000..ff718a7
--- /dev/null
+++ b/res/drawable-xhdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_star_on_normal_holo_light.png b/res/drawable-xhdpi/btn_star_on_normal_holo_light.png
new file mode 100644
index 0000000..282145f
--- /dev/null
+++ b/res/drawable-xhdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_0_blk.png b/res/drawable-xhdpi/dial_num_0_blk.png
deleted file mode 100644
index db3d157..0000000
--- a/res/drawable-xhdpi/dial_num_0_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_2_blk.png b/res/drawable-xhdpi/dial_num_2_blk.png
deleted file mode 100644
index 2893683..0000000
--- a/res/drawable-xhdpi/dial_num_2_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_3_blk.png b/res/drawable-xhdpi/dial_num_3_blk.png
deleted file mode 100644
index 7ba26fa..0000000
--- a/res/drawable-xhdpi/dial_num_3_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_4_blk.png b/res/drawable-xhdpi/dial_num_4_blk.png
deleted file mode 100644
index bff80f8..0000000
--- a/res/drawable-xhdpi/dial_num_4_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_5_blk.png b/res/drawable-xhdpi/dial_num_5_blk.png
deleted file mode 100644
index b2a9e75..0000000
--- a/res/drawable-xhdpi/dial_num_5_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_6_blk.png b/res/drawable-xhdpi/dial_num_6_blk.png
deleted file mode 100644
index 34e88ed..0000000
--- a/res/drawable-xhdpi/dial_num_6_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_7_blk.png b/res/drawable-xhdpi/dial_num_7_blk.png
deleted file mode 100644
index c7abc7e..0000000
--- a/res/drawable-xhdpi/dial_num_7_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_8_blk.png b/res/drawable-xhdpi/dial_num_8_blk.png
deleted file mode 100644
index 156e276..0000000
--- a/res/drawable-xhdpi/dial_num_8_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_9_blk.png b/res/drawable-xhdpi/dial_num_9_blk.png
deleted file mode 100644
index 4d77bd0..0000000
--- a/res/drawable-xhdpi/dial_num_9_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_pound_blk.png b/res/drawable-xhdpi/dial_num_pound_blk.png
deleted file mode 100644
index 9946f61..0000000
--- a/res/drawable-xhdpi/dial_num_pound_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_star_blk.png b/res/drawable-xhdpi/dial_num_star_blk.png
deleted file mode 100644
index 2d9baab..0000000
--- a/res/drawable-xhdpi/dial_num_star_blk.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_contacts.png b/res/drawable-xhdpi/ic_launcher_contacts.png
deleted file mode 100644
index a2ba3bc..0000000
--- a/res/drawable-xhdpi/ic_launcher_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_phone.png b/res/drawable-xhdpi/ic_launcher_phone.png
deleted file mode 100644
index 2226b7b..0000000
--- a/res/drawable-xhdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_shortcut_contact.png b/res/drawable-xhdpi/ic_launcher_shortcut_contact.png
deleted file mode 100644
index a5a71fa..0000000
--- a/res/drawable-xhdpi/ic_launcher_shortcut_contact.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_shortcut_directdial.png b/res/drawable-xhdpi/ic_launcher_shortcut_directdial.png
deleted file mode 100644
index b839084..0000000
--- a/res/drawable-xhdpi/ic_launcher_shortcut_directdial.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_shortcut_directmessage.png b/res/drawable-xhdpi/ic_launcher_shortcut_directmessage.png
deleted file mode 100644
index 35e1467..0000000
--- a/res/drawable-xhdpi/ic_launcher_shortcut_directmessage.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_2sec_pause.png b/res/drawable-xhdpi/ic_menu_2sec_pause.png
deleted file mode 100644
index 56f68b3..0000000
--- a/res/drawable-xhdpi/ic_menu_2sec_pause.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_accounts_holo_light.png b/res/drawable-xhdpi/ic_menu_accounts_holo_light.png
deleted file mode 100644
index e58c7c8..0000000
--- a/res/drawable-xhdpi/ic_menu_accounts_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_add_contact_holo_light.png b/res/drawable-xhdpi/ic_menu_add_contact_holo_light.png
deleted file mode 100644
index f018afd..0000000
--- a/res/drawable-xhdpi/ic_menu_add_contact_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_contacts_holo_light.png b/res/drawable-xhdpi/ic_menu_contacts_holo_light.png
deleted file mode 100644
index c054505..0000000
--- a/res/drawable-xhdpi/ic_menu_contacts_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_display_all_holo_light.png b/res/drawable-xhdpi/ic_menu_display_all_holo_light.png
deleted file mode 100644
index 0aa4cad..0000000
--- a/res/drawable-xhdpi/ic_menu_display_all_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_import_export_holo_light.png b/res/drawable-xhdpi/ic_menu_import_export_holo_light.png
deleted file mode 100644
index 7b7d9da..0000000
--- a/res/drawable-xhdpi/ic_menu_import_export_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_mark.png b/res/drawable-xhdpi/ic_menu_mark.png
deleted file mode 100644
index a24adc5..0000000
--- a/res/drawable-xhdpi/ic_menu_mark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_merge_holo_light.png b/res/drawable-xhdpi/ic_menu_merge_holo_light.png
deleted file mode 100644
index 31bc346..0000000
--- a/res/drawable-xhdpi/ic_menu_merge_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_share_holo_light.png b/res/drawable-xhdpi/ic_menu_share_holo_light.png
deleted file mode 100644
index 1c88e0e..0000000
--- a/res/drawable-xhdpi/ic_menu_share_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_split_holo_light.png b/res/drawable-xhdpi/ic_menu_split_holo_light.png
deleted file mode 100644
index 16c6ade..0000000
--- a/res/drawable-xhdpi/ic_menu_split_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_trash_holo_light.png b/res/drawable-xhdpi/ic_menu_trash_holo_light.png
deleted file mode 100644
index d234d73..0000000
--- a/res/drawable-xhdpi/ic_menu_trash_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_wait.png b/res/drawable-xhdpi/ic_menu_wait.png
deleted file mode 100644
index ee5ee68..0000000
--- a/res/drawable-xhdpi/ic_menu_wait.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tab_selected_contacts.png b/res/drawable-xhdpi/ic_tab_selected_contacts.png
deleted file mode 100644
index f8e6085..0000000
--- a/res/drawable-xhdpi/ic_tab_selected_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tab_unselected_contacts.png b/res/drawable-xhdpi/ic_tab_unselected_contacts.png
deleted file mode 100644
index 7adc0f5..0000000
--- a/res/drawable-xhdpi/ic_tab_unselected_contacts.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/list_item_divider.9.png b/res/drawable-xhdpi/list_item_divider.9.png
deleted file mode 100644
index fd799ef..0000000
--- a/res/drawable-xhdpi/list_item_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/list_pressed_holo.9.png b/res/drawable-xhdpi/list_pressed_holo.9.png
deleted file mode 100644
index d0fc7e0..0000000
--- a/res/drawable-xhdpi/list_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/magnifying_glass.png b/res/drawable-xhdpi/magnifying_glass.png
deleted file mode 100644
index 9066772..0000000
--- a/res/drawable-xhdpi/magnifying_glass.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png b/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
new file mode 100644
index 0000000..2d3e5c8
--- /dev/null
+++ b/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png b/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
new file mode 100644
index 0000000..a2d6ca1
--- /dev/null
+++ b/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/spinner_default_holo_dark.9.png b/res/drawable-xhdpi/spinner_default_holo_dark.9.png
new file mode 100644
index 0000000..e94ce80
--- /dev/null
+++ b/res/drawable-xhdpi/spinner_default_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/tab_focused.9.png b/res/drawable-xhdpi/tab_focused.9.png
deleted file mode 100644
index b9aba3e..0000000
--- a/res/drawable-xhdpi/tab_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_focused_bottom.9.png b/res/drawable-xhdpi/tab_focused_bottom.9.png
deleted file mode 100644
index d404f0b..0000000
--- a/res/drawable-xhdpi/tab_focused_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_left_arrow.png b/res/drawable-xhdpi/tab_left_arrow.png
deleted file mode 100644
index 9a2eef2..0000000
--- a/res/drawable-xhdpi/tab_left_arrow.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_pressed.9.png b/res/drawable-xhdpi/tab_pressed.9.png
deleted file mode 100644
index 4a26f77..0000000
--- a/res/drawable-xhdpi/tab_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_pressed_bottom.9.png b/res/drawable-xhdpi/tab_pressed_bottom.9.png
deleted file mode 100644
index a7e1668..0000000
--- a/res/drawable-xhdpi/tab_pressed_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_right_arrow.png b/res/drawable-xhdpi/tab_right_arrow.png
deleted file mode 100644
index 64a20ff..0000000
--- a/res/drawable-xhdpi/tab_right_arrow.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected.9.png b/res/drawable-xhdpi/tab_selected.9.png
deleted file mode 100644
index 045a9c7..0000000
--- a/res/drawable-xhdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_bottom.9.png b/res/drawable-xhdpi/tab_selected_bottom.9.png
deleted file mode 100644
index 64ff016..0000000
--- a/res/drawable-xhdpi/tab_selected_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected.9.png b/res/drawable-xhdpi/tab_unselected.9.png
deleted file mode 100644
index c11a765..0000000
--- a/res/drawable-xhdpi/tab_unselected.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_tab_contacts.xml b/res/drawable/ab_dropdown_navigation_item_background.xml
similarity index 73%
rename from res/drawable/ic_tab_contacts.xml
rename to res/drawable/ab_dropdown_navigation_item_background.xml
index 3341f41..c144996 100644
--- a/res/drawable/ic_tab_contacts.xml
+++ b/res/drawable/ab_dropdown_navigation_item_background.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<!-- Copyright (C) 2012 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.
@@ -15,7 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_selected_contacts" />
-    <item android:drawable="@drawable/ic_tab_unselected_contacts" />
+    <item android:state_pressed="true"
+        android:drawable="@drawable/ab_dropdown_navigation_item_background_pressed"/>
+    <item android:drawable="@drawable/spinner_default_holo_dark" />
 </selector>
-
diff --git a/res/layout/empty.xml b/res/drawable/ab_dropdown_navigation_item_background_pressed.xml
similarity index 67%
copy from res/layout/empty.xml
copy to res/drawable/ab_dropdown_navigation_item_background_pressed.xml
index 8e70c24..d075a05 100644
--- a/res/layout/empty.xml
+++ b/res/drawable/ab_dropdown_navigation_item_background_pressed.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2012 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.
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/empty"
-    android:layout_width="0dip"
-    android:layout_height="0dip" />
+<layer-list
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <item android:drawable="@drawable/action_bar_item_pressed_holo_light" />
+    <item android:drawable="@drawable/spinner_default_holo_dark" />
+</layer-list>
diff --git a/res/drawable/action_bar_item_background.xml b/res/drawable/action_bar_item_background.xml
index 8dd8d9b..7ccc3a9 100644
--- a/res/drawable/action_bar_item_background.xml
+++ b/res/drawable/action_bar_item_background.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true" android:drawable="@drawable/action_bar_item_pressed_holo_light"/>
     <item android:drawable="@android:color/transparent" />
 </selector>
diff --git a/res/drawable/btn_call.xml b/res/drawable/btn_call.xml
index 73ff87b..abce983 100644
--- a/res/drawable/btn_call.xml
+++ b/res/drawable/btn_call.xml
@@ -17,8 +17,7 @@
 <!-- Background resource for call button in the various dialpads.
      Almost a copy from framework's item_background_holo_dark.xml, but has different pressed effect
   -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
 
diff --git a/res/drawable/btn_dial_textfield.xml b/res/drawable/btn_dial_textfield.xml
deleted file mode 100644
index de914cf..0000000
--- a/res/drawable/btn_dial_textfield.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true"
-        android:drawable="@drawable/btn_dial_textfield_pressed" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/btn_dial_textfield_selected" />
-    <item
-        android:drawable="@drawable/btn_dial_textfield_normal" />
-</selector>
-
diff --git a/res/drawable/btn_star_holo_dark.xml b/res/drawable/btn_star_holo_dark.xml
deleted file mode 100644
index 2949de9..0000000
--- a/res/drawable/btn_star_holo_dark.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:drawable="@drawable/btn_star_on_normal_holo_dark"/>
-    <item android:drawable="@drawable/btn_star_off_normal_holo_dark"/>
-</selector>
\ No newline at end of file
diff --git a/res/drawable/call_background.xml b/res/drawable/call_background.xml
deleted file mode 100644
index fbc9b3c..0000000
--- a/res/drawable/call_background.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_window_focused="false"
-        android:drawable="@android:color/transparent" />
-    <item android:state_focused="false" android:state_pressed="true"
-        android:drawable="@*android:drawable/list_selector_background_transition" />
-    <item android:state_focused="false" android:state_pressed="false"
-        android:drawable="@android:drawable/screen_background_dark"/>
-
-</selector>
diff --git a/res/drawable/dial_num_0.xml b/res/drawable/dial_num_0.xml
deleted file mode 100644
index cc82dcf..0000000
--- a/res/drawable/dial_num_0.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_0_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_0_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_0_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_1.xml b/res/drawable/dial_num_1.xml
deleted file mode 100644
index a102ac8..0000000
--- a/res/drawable/dial_num_1.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_1" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_1" /> -->
-    <item
-        android:drawable="@drawable/dial_num_1_wht" />
-</selector>
diff --git a/res/drawable/dial_num_2.xml b/res/drawable/dial_num_2.xml
deleted file mode 100644
index 57c3ce6..0000000
--- a/res/drawable/dial_num_2.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_2_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_2_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_2_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_3.xml b/res/drawable/dial_num_3.xml
deleted file mode 100644
index e2b4b40..0000000
--- a/res/drawable/dial_num_3.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_3_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_3_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_3_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_4.xml b/res/drawable/dial_num_4.xml
deleted file mode 100644
index 814b16a..0000000
--- a/res/drawable/dial_num_4.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_4_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_4_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_4_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_5.xml b/res/drawable/dial_num_5.xml
deleted file mode 100644
index e9cc3ad..0000000
--- a/res/drawable/dial_num_5.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_5_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_5_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_5_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_6.xml b/res/drawable/dial_num_6.xml
deleted file mode 100644
index 8f78add..0000000
--- a/res/drawable/dial_num_6.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_6_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_6_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_6_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_7.xml b/res/drawable/dial_num_7.xml
deleted file mode 100644
index 1d255a2..0000000
--- a/res/drawable/dial_num_7.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_7_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_7_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_7_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_8.xml b/res/drawable/dial_num_8.xml
deleted file mode 100644
index 2b7eb11..0000000
--- a/res/drawable/dial_num_8.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_8_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_8_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_8_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_9.xml b/res/drawable/dial_num_9.xml
deleted file mode 100644
index ae019ed..0000000
--- a/res/drawable/dial_num_9.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_9_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_9_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_9_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_pound.xml b/res/drawable/dial_num_pound.xml
deleted file mode 100644
index c9c1e6f..0000000
--- a/res/drawable/dial_num_pound.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_pound_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_pound_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_pound_wht" />
-</selector>
-
diff --git a/res/drawable/dial_num_star.xml b/res/drawable/dial_num_star.xml
deleted file mode 100644
index af3c20e..0000000
--- a/res/drawable/dial_num_star.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- <item android:state_pressed="true"
-        android:drawable="@drawable/dial_num_star_blk" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/dial_num_star_blk" /> -->
-    <item
-        android:drawable="@drawable/dial_num_star_wht" />
-</selector>
-
diff --git a/res/drawable/frame_thumbnail_contact_widget_holo.xml b/res/drawable/frame_thumbnail_contact_widget_holo.xml
index 2da03da..9f8edbe 100644
--- a/res/drawable/frame_thumbnail_contact_widget_holo.xml
+++ b/res/drawable/frame_thumbnail_contact_widget_holo.xml
@@ -16,7 +16,7 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
-        android:drawable="@*android:drawable/quickcontact_badge_overlay_pressed_light" />
+        android:drawable="@drawable/quickcontact_badge_overlay_pressed_light" />
     <item
-        android:drawable="@*android:drawable/quickcontact_badge_overlay_normal_light" />
+        android:drawable="@drawable/quickcontact_badge_overlay_normal_light" />
 </selector>
diff --git a/res/drawable/gray_action_bar_background.xml b/res/drawable/gray_action_bar_background.xml
index 7ebf604..4192313 100644
--- a/res/drawable/gray_action_bar_background.xml
+++ b/res/drawable/gray_action_bar_background.xml
@@ -14,8 +14,9 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true" android:drawable="@drawable/action_bar_item_pressed_holo_light"/>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_pressed="true"
+        android:drawable="@drawable/ab_solid_custom_blue_inverse_holo"/>
     <item android:drawable="@drawable/ab_stacked_solid_inverse_holo" />
 </selector>
diff --git a/res/drawable/group_list_item_background.xml b/res/drawable/group_list_item_background.xml
index 345117f..70cd308 100644
--- a/res/drawable/group_list_item_background.xml
+++ b/res/drawable/group_list_item_background.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_activated="true" android:drawable="@drawable/list_activated_holo" />
     <item android:state_pressed="true" android:drawable="@drawable/list_pressed_holo_light" />
     <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
diff --git a/res/drawable/tab_bottom.xml b/res/drawable/tab_bottom.xml
deleted file mode 100644
index 96f1a24..0000000
--- a/res/drawable/tab_bottom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!--
-    <item android:state_pressed="true" android:drawable="@drawable/tab_pressed_bottom"/>
-    <item android:state_focused="false" android:drawable="@drawable/tab_selected_bottom"/>
-    <item android:state_focused="true" android:drawable="@drawable/tab_focused_bottom"/>
-    -->
-    
-    <item 
-        android:state_focused="false" 
-        android:state_selected="true" 
-        android:state_pressed="false" 
-        android:drawable="@drawable/tab_selected_bottom" />
-
-    <!-- Focused states -->
-    <item 
-        android:state_focused="true" 
-        android:state_selected="true" 
-        android:state_pressed="false" 
-        android:drawable="@drawable/tab_focused_bottom" />
-
-    <!-- Pressed -->
-    <item 
-        android:state_pressed="true" 
-        android:drawable="@drawable/tab_pressed_bottom" />
-</selector>
\ No newline at end of file
diff --git a/res/drawable/tab_indicator_bg.xml b/res/drawable/tab_indicator_bg.xml
deleted file mode 100644
index fb54954..0000000
--- a/res/drawable/tab_indicator_bg.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Non focused states -->
-    <item 
-        android:state_focused="false" 
-        android:state_selected="false" 
-        android:state_pressed="false" 
-        android:drawable="@drawable/tab_unselected" />
-    <item 
-        android:state_focused="false" 
-        android:state_selected="true" 
-        android:state_pressed="false" 
-        android:drawable="@drawable/tab_selected" />
-
-    <!-- Focused states -->
-    <item 
-        android:state_focused="true" 
-        android:state_selected="true" 
-        android:state_pressed="false" 
-        android:drawable="@drawable/tab_focused" />
-
-    <!-- Pressed -->
-    <item 
-        android:state_pressed="true" 
-        android:drawable="@drawable/tab_pressed" />
-        
-</selector>
\ No newline at end of file
diff --git a/res/layout-land/dialpad_fragment.xml b/res/layout-land/dialpad_fragment.xml
index 4dc87cc..c5f3056 100644
--- a/res/layout-land/dialpad_fragment.xml
+++ b/res/layout-land/dialpad_fragment.xml
@@ -36,7 +36,7 @@
         android:scrollHorizontally="true"
         android:textSize="@dimen/dialpad_digits_text_size"
         android:freezesText="true"
-        android:background="@drawable/btn_dial_textfield"
+        android:background="@drawable/dialpad_background"
         android:textColor="@color/dialer_button_text"
         android:hint="@string/dialerKeyboardHintText"
      />
diff --git a/res/layout-sw580dp-w940dp/contact_detail_container.xml b/res/layout-sw580dp-w940dp/contact_detail_container.xml
new file mode 100644
index 0000000..e653d9d
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/contact_detail_container.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.android.contacts.detail.ContactDetailFragmentCarousel
+        android:id="@+id/fragment_carousel"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="16dip"/>
+
+</FrameLayout>
diff --git a/res/layout-sw580dp-w940dp/contact_detail_fragment.xml b/res/layout-sw580dp-w940dp/contact_detail_fragment.xml
new file mode 100644
index 0000000..9f32584
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/contact_detail_fragment.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_detail"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/background_primary">
+
+    <!-- Placeholder for empty list -->
+    <include
+        android:id="@android:id/empty"
+        layout="@layout/contact_detail_empty"
+        android:visibility="gone" />
+
+    <!-- Real list -->
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_weight="1"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:baselineAligned="false">
+
+        <include android:id="@+id/static_photo_container"
+            layout="@layout/photo_selector_view"
+            android:layout_width="@dimen/detail_contact_photo_size"
+            android:layout_height="@dimen/detail_contact_photo_size"
+            android:layout_marginTop="@dimen/detail_contact_photo_margin"
+            android:layout_marginRight="@dimen/detail_contact_photo_margin" />
+
+        <ListView android:id="@android:id/list"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:paddingTop="16dip"
+            android:clipToPadding="false"
+            android:fadingEdge="none"
+            android:layout_weight="1"
+            android:divider="@null"
+            android:scrollbarStyle="outsideOverlay"
+            android:paddingRight="16dip"/>
+
+    </LinearLayout>
+
+    <!-- "QuickFix"- button (Copy to local contact, add to group) -->
+    <Button
+        android:id="@+id/contact_quick_fix"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:layout_gravity="center"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip" />
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml b/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml
new file mode 100644
index 0000000..3b4b422
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/list"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/background_social_updates"
+    android:fadingEdge="none"
+    android:divider="@null"
+    android:paddingTop="@dimen/contact_detail_list_top_padding"
+    android:paddingLeft="16dip"
+    android:paddingRight="16dip"
+    android:scrollbarStyle="outsideOverlay"
+    android:clipToPadding="false"/>
diff --git a/res/layout-sw580dp-w1000dp/contact_editor_activity.xml b/res/layout-sw580dp-w940dp/contact_editor_activity.xml
similarity index 92%
rename from res/layout-sw580dp-w1000dp/contact_editor_activity.xml
rename to res/layout-sw580dp-w940dp/contact_editor_activity.xml
index d2e0d22..5c405d5 100644
--- a/res/layout-sw580dp-w1000dp/contact_editor_activity.xml
+++ b/res/layout-sw580dp-w940dp/contact_editor_activity.xml
@@ -22,8 +22,9 @@
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="horizontal">
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:baselineAligned="false">
 
         <!-- Empty view to represent the left margin -->
         <View
@@ -45,4 +46,4 @@
 
     </LinearLayout>
 
-</ScrollView>
\ No newline at end of file
+</ScrollView>
diff --git a/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml b/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml
new file mode 100644
index 0000000..32eecc9
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!--
+  This is a header entry in the contact details list for when the contact has social updates. The
+  entry shows the contact's basic info and maintains vertical padding to ensure that the first
+  contact detail is visible (and below the tab carousel). The photo is not displayed here
+  because it will be shown in the tab carousel.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <include layout="@layout/photo_selector_view"
+        android:layout_width="@dimen/detail_contact_photo_size"
+        android:layout_height="@dimen/detail_contact_photo_size" />
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingLeft="16dip"
+        android:paddingRight="4dip">
+
+        <TextView
+            android:id="@+id/name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textSize="@dimen/detail_header_name_text_size" />
+
+        <TextView
+            android:id="@+id/company"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary" />
+
+    </LinearLayout>
+
+    <include
+        layout="@layout/favorites_star" />
+
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml b/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml
new file mode 100644
index 0000000..57a2820
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!--
+  This is a header entry in the contact details list for when the contact does not have social
+  updates, which means that the contact's basic info will scroll with the list of details. The
+  photo is not included because it will be displayed in a static place elsewhere.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="8dip"
+    android:paddingBottom="16dip"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingRight="16dip">
+
+        <TextView
+            android:id="@+id/name"
+            android:layout_width="0dip"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textSize="@dimen/detail_header_name_text_size"
+            android:paddingRight="16dip" />
+
+        <include
+            layout="@layout/favorites_star" />
+
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/company"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorSecondary" />
+
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/group_browse_list_account_header.xml b/res/layout-sw580dp-w940dp/group_browse_list_account_header.xml
new file mode 100644
index 0000000..af60c79
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/group_browse_list_account_header.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <!-- Only visible when it is the first element in the list. -->
+    <View
+        android:id="@+id/header_extra_top_padding"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/list_header_extra_top_padding" />
+
+    <include layout="@layout/group_account_header_horizontal" />
+
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/people_activity.xml b/res/layout-sw580dp-w940dp/people_activity.xml
new file mode 100644
index 0000000..3a86842
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/people_activity.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:id="@+id/main_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:splitMotionEvents="true"
+        android:baselineAligned="false">
+
+        <!-- Left panel browse list for Groups or All tabs -->
+        <FrameLayout
+            android:id="@+id/browse_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@drawable/list_background_holo"
+            android:visibility="gone">
+
+            <!-- All -->
+            <fragment
+                android:id="@+id/all_fragment"
+                class="com.android.contacts.list.DefaultContactBrowseListFragment"
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
+
+            <!-- Groups -->
+            <fragment
+                android:id="@+id/groups_fragment"
+                class="com.android.contacts.group.GroupBrowseListFragment"
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
+        </FrameLayout>
+
+        <!-- Right panel detail view for All tab -->
+        <view
+            class="com.android.contacts.widget.TransitionAnimationView"
+            android:id="@+id/contact_details_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="2"
+            android:background="@color/background_primary"
+            android:visibility="gone">
+
+            <!-- This layout includes all possible views needed for a contact detail page -->
+            <include
+                android:id="@+id/contact_detail_container"
+                layout="@layout/contact_detail_container"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"/>
+
+            <!-- This invisible worker fragment loads the contact's details -->
+            <fragment
+                android:id="@+id/contact_detail_loader_fragment"
+                class="com.android.contacts.detail.ContactLoaderFragment"
+                android:layout_height="0dip"
+                android:layout_width="0dip"
+                android:visibility="gone"/>
+        </view>
+
+        <!-- Right panel detail view for Groups tab -->
+        <view
+            class="com.android.contacts.widget.TransitionAnimationView"
+            android:id="@+id/group_details_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="2"
+            android:background="@color/background_primary"
+            android:visibility="gone">
+
+            <!-- This is the group detail page -->
+            <fragment
+                android:id="@+id/group_detail_fragment"
+                class="com.android.contacts.group.GroupDetailFragment"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:visibility="gone" />
+        </view>
+
+        <!-- Two-panel view under the Favorites tab -->
+        <LinearLayout
+            android:id="@+id/favorites_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@drawable/list_background_holo"
+            android:baselineAligned="false">
+
+            <!-- Starred -->
+            <FrameLayout
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="2"
+                android:background="@drawable/panel_favorites_holo_light">
+
+                <fragment
+                    android:id="@+id/favorites_fragment"
+                    class="com.android.contacts.list.ContactTileListFragment"
+                    android:layout_height="match_parent"
+                    android:layout_width="match_parent"
+                    android:layout_marginRight="16dip"
+                    android:layout_marginLeft="16dip"/>
+
+            </FrameLayout>
+
+            <!-- Most Frequent -->
+            <fragment
+                android:id="@+id/frequent_fragment"
+                class="com.android.contacts.list.ContactTileFrequentFragment"
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:layout_marginTop="16dip"
+                android:layout_marginRight="16dip"/>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <com.android.contacts.widget.InterpolatingLayout
+        android:id="@+id/contacts_unavailable_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+
+        <FrameLayout
+            android:id="@+id/contacts_unavailable_container"
+            android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            ex:layout_narrowParentWidth="800dip"
+            ex:layout_narrowMarginLeft="80dip"
+            ex:layout_narrowMarginRight="80dip"
+            ex:layout_wideParentWidth="1280dip"
+            ex:layout_wideMarginLeft="200dip"
+            ex:layout_wideMarginRight="200dip"
+            android:paddingBottom="20dip" />
+
+    </com.android.contacts.widget.InterpolatingLayout>
+</FrameLayout>
diff --git a/res/layout-sw580dp-w940dp/quickcontact_activity.xml b/res/layout-sw580dp-w940dp/quickcontact_activity.xml
new file mode 100644
index 0000000..5c38309
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/quickcontact_activity.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+<view
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.android.contacts.quickcontact.FloatingChildLayout"
+    android:id="@+id/floating_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
+    android:descendantFocusability="afterDescendants">
+    <LinearLayout
+        android:id="@android:id/content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="32dip"
+        android:orientation="horizontal">
+        <FrameLayout
+            android:layout_width="360dip"
+            android:layout_height="360dip">
+            <include layout="@layout/quickcontact_photo_container" />
+        </FrameLayout>
+        <LinearLayout
+            android:layout_width="360dip"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+            <include layout="@layout/quickcontact_track" />
+            <View
+                android:id="@+id/line_after_track"
+                android:layout_width="match_parent"
+                android:layout_height="2dip"
+                android:background="@color/quickcontact_tab_indicator" />
+            <android.support.v4.view.ViewPager
+                android:id="@+id/item_list_pager"
+                android:background="@color/quickcontact_list_background"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+        </LinearLayout>
+    </LinearLayout>
+</view>
diff --git a/res/layout-sw580dp-w1000dp/quickcontact_list_fragment_bottom.xml b/res/layout-sw580dp-w940dp/quickcontact_list_fragment_bottom.xml
similarity index 100%
rename from res/layout-sw580dp-w1000dp/quickcontact_list_fragment_bottom.xml
rename to res/layout-sw580dp-w940dp/quickcontact_list_fragment_bottom.xml
diff --git a/res/layout-sw580dp-w940dp/updates_header_contact.xml b/res/layout-sw580dp-w940dp/updates_header_contact.xml
new file mode 100644
index 0000000..1ffdcaa
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/updates_header_contact.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!--
+  This is a header entry in the contact updates list.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:focusable="false">
+
+    <TextView
+        style="?android:attr/listSeparatorTextViewStyle"
+        android:layout_height="32dip"
+        android:paddingLeft="8dip"
+        android:paddingRight="8dip"
+        android:background="@drawable/list_section_divider_holo_custom"
+        android:text="@string/recent_updates"
+        android:textColor="@color/people_app_theme_color"
+        android:textAllCaps="true"
+        android:singleLine="true"
+        android:ellipsize="end" />
+
+</FrameLayout>
diff --git a/res/layout-sw580dp/contact_detail_container.xml b/res/layout-sw580dp/contact_detail_container.xml
index cdb789f..fc09dfb 100644
--- a/res/layout-sw580dp/contact_detail_container.xml
+++ b/res/layout-sw580dp/contact_detail_container.xml
@@ -16,8 +16,7 @@
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
     <android.support.v4.view.ViewPager
         android:id="@+id/pager"
diff --git a/res/layout-sw580dp/contact_detail_fragment.xml b/res/layout-sw580dp/contact_detail_fragment.xml
index 28a6bb9..fd6390e 100644
--- a/res/layout-sw580dp/contact_detail_fragment.xml
+++ b/res/layout-sw580dp/contact_detail_fragment.xml
@@ -16,7 +16,6 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@+id/contact_detail"
     android:orientation="vertical"
     android:layout_width="match_parent"
@@ -36,7 +35,8 @@
         android:fadingEdge="none"
         android:cacheColorHint="#00000000"
         android:divider="@null"
-    />
+        android:scrollbarStyle="outsideOverlay"
+        android:paddingRight="12dip" />
 
     <!-- "QuickFix"- button (Copy to local contact, add to group) -->
     <Button
diff --git a/res/layout-sw580dp/contact_detail_updates_fragment.xml b/res/layout-sw580dp/contact_detail_updates_fragment.xml
index 3bcb01c..a154936 100644
--- a/res/layout-sw580dp/contact_detail_updates_fragment.xml
+++ b/res/layout-sw580dp/contact_detail_updates_fragment.xml
@@ -16,7 +16,6 @@
 
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@+id/contact_detail_updates_fragment"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
@@ -25,21 +24,8 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:fadingEdge="none"
-        android:divider="@null"/>
-
-    <View
-        android:id="@+id/alpha_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@android:color/black"
-        android:alpha=".50"
-        android:visibility="gone"/>
-
-    <View
-        android:id="@+id/touch_intercept_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@android:color/transparent"
-        android:visibility="gone"/>
+        android:divider="@null"
+        android:scrollbarStyle="outsideOverlay"
+        android:paddingRight="12dip" />
 
 </FrameLayout>
diff --git a/res/layout-sw580dp/contact_editor_activity.xml b/res/layout-sw580dp/contact_editor_activity.xml
index c33a3c0..526fe2b 100644
--- a/res/layout-sw580dp/contact_editor_activity.xml
+++ b/res/layout-sw580dp/contact_editor_activity.xml
@@ -23,6 +23,6 @@
     <fragment class="com.android.contacts.editor.ContactEditorFragment"
         android:id="@+id/contact_editor_fragment"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
+        android:layout_height="wrap_content"/>
 
 </ScrollView>
diff --git a/res/layout-sw580dp/detail_header_contact_with_updates.xml b/res/layout-sw580dp/detail_header_contact_with_updates.xml
index 43cf4c0..f732b23 100644
--- a/res/layout-sw580dp/detail_header_contact_with_updates.xml
+++ b/res/layout-sw580dp/detail_header_contact_with_updates.xml
@@ -27,14 +27,14 @@
     android:layout_height="wrap_content"
     android:orientation="vertical"
     android:layout_marginTop="30dip"
-    android:paddingBottom="8dip">
+    android:paddingBottom="16dip">
 
     <!-- Add a first item that gives us enough space to show the carousel -->
     <view
         class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        ex:ratio="0.66"
+        ex:ratio="0.6667"
         ex:direction="widthToHeight">
 
         <!-- Put a dummy view here because the ProportionalLayout requires one -->
diff --git a/res/layout-sw580dp/detail_header_contact_without_updates.xml b/res/layout-sw580dp/detail_header_contact_without_updates.xml
index 9261f11..3c01b16 100644
--- a/res/layout-sw580dp/detail_header_contact_without_updates.xml
+++ b/res/layout-sw580dp/detail_header_contact_without_updates.xml
@@ -32,7 +32,7 @@
         class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        ex:ratio="0.66"
+        ex:ratio="0.6667"
         ex:direction="widthToHeight">
 
         <LinearLayout
@@ -40,9 +40,7 @@
             android:layout_height="match_parent"
             android:orientation="horizontal">
 
-            <ImageView
-                android:id="@+id/photo"
-                android:scaleType="centerCrop"
+            <include layout="@layout/photo_selector_view"
                 android:layout_width="0dip"
                 android:layout_height="match_parent"
                 android:layout_weight="2" />
diff --git a/res/layout-sw580dp/favorites_star.xml b/res/layout-sw580dp/favorites_star.xml
index 7959df3..22b9339 100644
--- a/res/layout-sw580dp/favorites_star.xml
+++ b/res/layout-sw580dp/favorites_star.xml
@@ -14,19 +14,12 @@
      limitations under the License.
 -->
 
-<FrameLayout
+<!-- The favorite star, shown outside of the ActionBar -->
+<ImageView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:minHeight="50dip">
-
-    <CheckBox
-        android:id="@+id/star"
-        android:duplicateParentState="true"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:contentDescription="@string/description_star"
-        style="?android:attr/starStyle"/>
-
-</FrameLayout>
+    android:id="@+id/star"
+    android:layout_width="48dip"
+    android:layout_height="48dip"
+    android:scaleType="center"
+    android:background="?android:attr/selectableItemBackground"
+    android:src="@drawable/btn_star_off_normal_holo_light" />
diff --git a/res/layout-sw580dp/group_browse_list_account_header.xml b/res/layout-sw580dp/group_browse_list_account_header.xml
new file mode 100644
index 0000000..cca6ed9
--- /dev/null
+++ b/res/layout-sw580dp/group_browse_list_account_header.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <!-- Only visible when it is the first element in the list. -->
+    <View
+        android:id="@+id/header_extra_top_padding"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/list_header_extra_top_padding" />
+
+    <include layout="@layout/group_account_header_vertical" />
+
+</LinearLayout>
diff --git a/res/layout-sw580dp/join_contact_picker.xml b/res/layout-sw580dp/join_contact_picker.xml
new file mode 100644
index 0000000..3d9127b
--- /dev/null
+++ b/res/layout-sw580dp/join_contact_picker.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.android.contacts.widget.FullHeightLinearLayout"
+    style="@style/ContactPickerLayout"
+    android:orientation="vertical">
+    <!-- See also comments in contact_picker.xml -->
+    <view
+        class="android.widget.SearchView"
+        android:id="@+id/search_view"
+        android:layout_width="match_parent"
+        android:maxWidth="@dimen/contact_picker_search_view_max_width"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="0dip"
+        android:layout_marginRight="@dimen/list_visible_scrollbar_padding"
+        android:paddingRight="0dip"
+        android:iconifiedByDefault="false" />
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:id="@+id/list_container" />
+</view>
diff --git a/res/layout-sw580dp/people_activity.xml b/res/layout-sw580dp/people_activity.xml
index 59a218d..42c6afc 100644
--- a/res/layout-sw580dp/people_activity.xml
+++ b/res/layout-sw580dp/people_activity.xml
@@ -25,14 +25,15 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="horizontal"
-        android:splitMotionEvents="true">
+        android:splitMotionEvents="true"
+        android:baselineAligned="false">
 
-        <LinearLayout
+        <!-- Left panel browse list for Groups or All tabs -->
+        <FrameLayout
             android:id="@+id/browse_view"
             android:layout_width="0dip"
             android:layout_height="match_parent"
             android:layout_weight="1"
-            android:orientation="vertical"
             android:background="@drawable/list_background_holo"
             android:visibility="gone">
 
@@ -40,9 +41,8 @@
             <fragment
                 android:id="@+id/all_fragment"
                 class="com.android.contacts.list.DefaultContactBrowseListFragment"
-                android:layout_height="0dip"
-                android:layout_width="match_parent"
-                android:layout_weight="1" />
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
 
             <!-- Groups -->
             <fragment
@@ -50,22 +50,16 @@
                 class="com.android.contacts.group.GroupBrowseListFragment"
                 android:layout_height="match_parent"
                 android:layout_width="match_parent" />
-        </LinearLayout>
+        </FrameLayout>
 
+        <!-- Right panel detail view for All tab -->
         <view
             class="com.android.contacts.widget.TransitionAnimationView"
-            android:id="@+id/details_view"
+            android:id="@+id/contact_details_view"
             android:layout_width="0dip"
             android:layout_height="match_parent"
-            android:layout_weight="1"
+            android:layout_weight="2"
             android:background="@color/background_primary"
-            ex:clipMarginLeft="0dip"
-            ex:clipMarginTop="3dip"
-            ex:clipMarginRight="3dip"
-            ex:clipMarginBottom="9dip"
-            ex:enterAnimation="@android:animator/fade_in"
-            ex:exitAnimation="@android:animator/fade_out"
-            ex:animationDuration="200"
             android:visibility="gone">
 
             <!-- This layout includes all possible views needed for a contact detail page -->
@@ -74,9 +68,9 @@
                 layout="@layout/contact_detail_container"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:layout_marginTop="16dip"
                 android:layout_marginLeft="16dip"
-                android:layout_marginRight="16dip"/>
+                android:layout_marginTop="16dip"
+                android:layout_marginRight="16dip" />
 
             <!-- This invisible worker fragment loads the contact's details -->
             <fragment
@@ -84,7 +78,18 @@
                 class="com.android.contacts.detail.ContactLoaderFragment"
                 android:layout_height="0dip"
                 android:layout_width="0dip"
-                android:visibility="gone"/>
+                android:visibility="gone" />
+        </view>
+
+        <!-- Right panel detail view for Groups tab -->
+        <view
+            class="com.android.contacts.widget.TransitionAnimationView"
+            android:id="@+id/group_details_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="2"
+            android:background="@color/background_primary"
+            android:visibility="gone">
 
             <!-- This is the group detail page -->
             <fragment
@@ -95,53 +100,21 @@
                 android:visibility="gone" />
         </view>
 
-        <view
-            class="com.android.contacts.widget.TransitionAnimationView"
+        <!-- Single panel view under the Favorites tab (Strequent) -->
+        <FrameLayout
             android:id="@+id/favorites_view"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            ex:clipMarginLeft="0dip"
-            ex:clipMarginTop="3dip"
-            ex:clipMarginRight="3dip"
-            ex:clipMarginBottom="9dip"
-            ex:enterAnimation="@android:animator/fade_in"
-            ex:exitAnimation="@android:animator/fade_out"
-            ex:animationDuration="200">
+            android:layout_height="match_parent">
 
-            <LinearLayout
-                android:layout_width="match_parent"
+            <fragment
+                android:id="@+id/favorites_fragment"
+                class="com.android.contacts.list.ContactTileListFragment"
                 android:layout_height="match_parent"
-                android:background="@drawable/list_background_holo">
+                android:layout_width="match_parent"
+                android:layout_marginRight="16dip"
+                android:layout_marginLeft="16dip" />
 
-                <!-- Starred -->
-                <FrameLayout
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="10"
-                    android:background="@drawable/panel_favorites_holo_light">
-
-                    <fragment
-                        android:id="@+id/favorites_fragment"
-                        class="com.android.contacts.list.ContactTileListFragment"
-                        android:layout_height="match_parent"
-                        android:layout_width="match_parent"
-                        android:layout_marginRight="16dip"
-                        android:layout_marginLeft="16dip"/>
-
-                </FrameLayout>
-
-                <!-- Most Frequent -->
-                <fragment
-                    android:id="@+id/frequent_fragment"
-                    class="com.android.contacts.list.ContactTileFrequentFragment"
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="8"
-                    android:layout_marginTop="16dip"
-                    android:layout_marginRight="16dip"/>
-
-            </LinearLayout>
-        </view>
+        </FrameLayout>
 
     </LinearLayout>
 
diff --git a/res/layout-sw580dp/quickcontact_activity.xml b/res/layout-sw580dp/quickcontact_activity.xml
index ba9c9ab..a97d86c 100644
--- a/res/layout-sw580dp/quickcontact_activity.xml
+++ b/res/layout-sw580dp/quickcontact_activity.xml
@@ -15,6 +15,7 @@
 -->
 <view
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     class="com.android.contacts.quickcontact.FloatingChildLayout"
     android:id="@+id/floating_layout"
     android:layout_width="match_parent"
@@ -26,9 +27,10 @@
         android:id="@android:id/content"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:orientation="vertical">
+        android:padding="32dip"
+        android:orientation="vertical" >
         <FrameLayout
-            android:layout_width="400dip"
+            android:layout_width="360dip"
             android:layout_height="@dimen/quick_contact_photo_container_height">
             <include layout="@layout/quickcontact_photo_container" />
         </FrameLayout>
diff --git a/res/layout-sw580dp/search_header.xml b/res/layout-sw580dp/search_header.xml
index e543883..85f0169 100644
--- a/res/layout-sw580dp/search_header.xml
+++ b/res/layout-sw580dp/search_header.xml
@@ -14,29 +14,12 @@
      limitations under the License.
 -->
 
-<RelativeLayout
+<TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="DirectoryHeader"
     android:layout_width="match_parent"
-    android:layout_height="56dip">
-    <TextView
-        android:id="@+id/totalContactsText"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_alignParentLeft="true"
-        android:layout_marginLeft="8dip"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/textColorTertiary"
-        android:textStyle="bold" />
-
-    <ProgressBar
-        android:id="@+id/progress"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        style="?android:attr/progressBarStyleSmall"
-        android:layout_alignParentRight="true"
-        android:layout_centerVertical="true"
-        android:layout_marginRight="10dip" />
-
-</RelativeLayout>
+    android:layout_height="match_parent"
+    android:id="@+id/totalContactsText"
+    android:minHeight="@dimen/contact_filter_header_min_height"
+    android:paddingTop="24dip"
+    android:textAppearance="?android:attr/textAppearanceMedium"
+    android:textColor="?android:attr/textColorTertiary" />
diff --git a/res/layout-sw580dp/updates_header_contact.xml b/res/layout-sw580dp/updates_header_contact.xml
index 00e3d1b..b8b3278 100644
--- a/res/layout-sw580dp/updates_header_contact.xml
+++ b/res/layout-sw580dp/updates_header_contact.xml
@@ -29,8 +29,8 @@
         class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingBottom="8dip"
-        ex:ratio="0.66"
+        android:layout_marginBottom="8dip"
+        ex:ratio="0.6667"
         ex:direction="widthToHeight">
 
         <!-- Put a dummy view here because the ProportionalLayout requires one -->
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_container.xml b/res/layout-sw680dp-w1000dp/contact_detail_container.xml
index 6b1d094..8180e92 100644
--- a/res/layout-sw680dp-w1000dp/contact_detail_container.xml
+++ b/res/layout-sw680dp-w1000dp/contact_detail_container.xml
@@ -24,7 +24,8 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:scrollbars="none"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:baselineAligned="false">
 
     <!--
       Container for the "About" fragment on the contact card for a contact
@@ -53,6 +54,7 @@
         android:id="@+id/updates_fragment_container"
         android:layout_width="0dip"
         android:layout_weight="2"
-        android:layout_height="match_parent" />
+        android:layout_height="match_parent"
+        android:visibility="gone" />
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_fragment.xml b/res/layout-sw680dp-w1000dp/contact_detail_fragment.xml
index ecf8130..b3f13a6 100644
--- a/res/layout-sw680dp-w1000dp/contact_detail_fragment.xml
+++ b/res/layout-sw680dp-w1000dp/contact_detail_fragment.xml
@@ -16,14 +16,12 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@+id/contact_detail"
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/background_primary"
-    android:paddingLeft="16dip"
-    android:paddingRight="16dip">
+    android:paddingLeft="16dip">
 
     <!-- Placeholder for empty list -->
     <include
@@ -36,14 +34,15 @@
         android:orientation="horizontal"
         android:layout_weight="1"
         android:layout_width="match_parent"
-        android:layout_height="0dip">
+        android:layout_height="0dip"
+        android:baselineAligned="false">
 
-        <ImageView android:id="@+id/photo"
-            android:scaleType="centerCrop"
+        <include android:id="@+id/static_photo_container"
+            layout="@layout/photo_selector_view"
             android:layout_width="@dimen/detail_contact_photo_size"
             android:layout_height="@dimen/detail_contact_photo_size"
             android:layout_marginTop="@dimen/detail_contact_photo_margin"
-            android:layout_marginRight="@dimen/detail_contact_photo_margin"/>
+            android:layout_marginRight="@dimen/detail_contact_photo_margin" />
 
         <ListView android:id="@android:id/list"
             android:layout_width="0dip"
@@ -52,9 +51,11 @@
             android:clipToPadding="false"
             android:fadingEdge="none"
             android:layout_weight="1"
-            android:divider="@null"/>
+            android:divider="@null"
+            android:paddingRight="16dip"
+            android:scrollbarStyle="outsideOverlay"/>
 
-   </LinearLayout>
+    </LinearLayout>
 
     <!-- "QuickFix"- button (Copy to local contact, add to group) -->
     <Button
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_list_item.xml b/res/layout-sw680dp-w1000dp/contact_detail_list_item.xml
index 98ffce6..2016131 100644
--- a/res/layout-sw680dp-w1000dp/contact_detail_list_item.xml
+++ b/res/layout-sw680dp-w1000dp/contact_detail_list_item.xml
@@ -50,15 +50,6 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:textAppearance="?android:attr/textAppearanceMedium" />
-
-            <TextView
-                android:id="@+id/footer"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?android:attr/textColorSecondary"
-                android:visibility="gone" />
-
         </LinearLayout>
 
         <ImageView
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_updates_fragment.xml b/res/layout-sw680dp-w1000dp/contact_detail_updates_fragment.xml
index 439b8f0..d809258 100644
--- a/res/layout-sw680dp-w1000dp/contact_detail_updates_fragment.xml
+++ b/res/layout-sw680dp-w1000dp/contact_detail_updates_fragment.xml
@@ -24,4 +24,5 @@
     android:paddingTop="@dimen/contact_detail_list_top_padding"
     android:paddingLeft="16dip"
     android:paddingRight="16dip"
+    android:scrollbarStyle="outsideOverlay"
     android:clipToPadding="false"/>
diff --git a/res/layout-sw680dp-w1000dp/detail_header_contact_with_updates.xml b/res/layout-sw680dp-w1000dp/detail_header_contact_with_updates.xml
index dfba659..7758a21 100644
--- a/res/layout-sw680dp-w1000dp/detail_header_contact_with_updates.xml
+++ b/res/layout-sw680dp-w1000dp/detail_header_contact_with_updates.xml
@@ -27,9 +27,7 @@
     android:paddingBottom="8dip"
     android:orientation="horizontal">
 
-    <ImageView
-        android:id="@+id/photo"
-        android:scaleType="centerCrop"
+    <include layout="@layout/photo_selector_view"
         android:layout_width="@dimen/detail_contact_photo_size"
         android:layout_height="@dimen/detail_contact_photo_size" />
 
diff --git a/res/layout-sw680dp-w1000dp/detail_header_contact_without_updates.xml b/res/layout-sw680dp-w1000dp/detail_header_contact_without_updates.xml
index f9dcf3d..9e53df0 100644
--- a/res/layout-sw680dp-w1000dp/detail_header_contact_without_updates.xml
+++ b/res/layout-sw680dp-w1000dp/detail_header_contact_without_updates.xml
@@ -50,7 +50,6 @@
         android:id="@+id/company"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingTop="16dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorSecondary" />
 
diff --git a/res/layout-sw680dp-w1000dp/people_activity.xml b/res/layout-sw680dp-w1000dp/people_activity.xml
index a288ff0..2dea4eb 100644
--- a/res/layout-sw680dp-w1000dp/people_activity.xml
+++ b/res/layout-sw680dp-w1000dp/people_activity.xml
@@ -26,11 +26,10 @@
         android:layout_height="match_parent"
         android:splitMotionEvents="true">
 
-        <LinearLayout
+        <FrameLayout
             android:id="@+id/browse_view"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:orientation="vertical"
             android:minWidth="100dip"
             ex:layout_narrowParentWidth="1000dip"
             ex:layout_narrowWidth="276dip"
@@ -43,9 +42,8 @@
             <fragment
                 android:id="@+id/all_fragment"
                 class="com.android.contacts.list.DefaultContactBrowseListFragment"
-                android:layout_height="0dip"
-                android:layout_width="match_parent"
-                android:layout_weight="1" />
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
 
             <!-- Groups -->
             <fragment
@@ -53,11 +51,11 @@
                 class="com.android.contacts.group.GroupBrowseListFragment"
                 android:layout_height="match_parent"
                 android:layout_width="match_parent" />
-        </LinearLayout>
+        </FrameLayout>
 
         <view
             class="com.android.contacts.widget.TransitionAnimationView"
-            android:id="@+id/details_view"
+            android:id="@+id/contact_details_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             ex:layout_narrowParentWidth="800dip"
@@ -66,13 +64,6 @@
             ex:layout_wideParentWidth="1280dip"
             ex:layout_wideMarginLeft="0dip"
             ex:layout_wideMarginRight="0dip"
-            ex:clipMarginLeft="0dip"
-            ex:clipMarginTop="3dip"
-            ex:clipMarginRight="3dip"
-            ex:clipMarginBottom="9dip"
-            ex:enterAnimation="@android:animator/fade_in"
-            ex:exitAnimation="@android:animator/fade_out"
-            ex:animationDuration="200"
             android:visibility="gone">
 
             <!-- This layout includes all possible views needed for a contact detail page -->
@@ -89,6 +80,20 @@
                 android:layout_height="0dip"
                 android:layout_width="0dip"
                 android:visibility="gone"/>
+        </view>
+
+        <view
+            class="com.android.contacts.widget.TransitionAnimationView"
+            android:id="@+id/group_details_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            ex:layout_narrowParentWidth="800dip"
+            ex:layout_narrowMarginLeft="0dip"
+            ex:layout_narrowMarginRight="0dip"
+            ex:layout_wideParentWidth="1280dip"
+            ex:layout_wideMarginLeft="0dip"
+            ex:layout_wideMarginRight="0dip"
+            android:visibility="gone">
 
             <!-- This is the group detail page -->
             <fragment
@@ -99,53 +104,41 @@
                 android:visibility="gone" />
         </view>
 
-        <view
-            class="com.android.contacts.widget.TransitionAnimationView"
+        <LinearLayout
             android:id="@+id/favorites_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            ex:clipMarginLeft="0dip"
-            ex:clipMarginTop="3dip"
-            ex:clipMarginRight="3dip"
-            ex:clipMarginBottom="9dip"
-            ex:enterAnimation="@android:animator/fade_in"
-            ex:exitAnimation="@android:animator/fade_out"
-            ex:animationDuration="200">
+            android:background="@drawable/list_background_holo"
+            android:baselineAligned="false">
 
-            <LinearLayout
-                android:layout_width="match_parent"
+            <!-- Starred -->
+            <FrameLayout
+                android:layout_width="0dip"
                 android:layout_height="match_parent"
-                android:background="@drawable/list_background_holo">
+                android:layout_weight="7"
+                android:background="@drawable/panel_favorites_holo_light">
 
-                <!-- Starred -->
-                <FrameLayout
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="7"
-                    android:background="@drawable/panel_favorites_holo_light">
-
-                    <fragment
-                        android:id="@+id/favorites_fragment"
-                        class="com.android.contacts.list.ContactTileListFragment"
-                        android:layout_height="match_parent"
-                        android:layout_width="match_parent"
-                        android:layout_marginRight="32dip"
-                        android:layout_marginLeft="32dip"/>
-
-                </FrameLayout>
-
-                <!-- Most Frequent -->
                 <fragment
-                    android:id="@+id/frequent_fragment"
-                    class="com.android.contacts.list.ContactTileFrequentFragment"
-                    android:layout_width="0dip"
+                    android:id="@+id/favorites_fragment"
+                    class="com.android.contacts.list.ContactTileListFragment"
                     android:layout_height="match_parent"
-                    android:layout_weight="3"
-                    android:layout_marginTop="32dip"
-                    android:layout_marginRight="16dip"/>
+                    android:layout_width="match_parent"
+                    android:layout_marginRight="32dip"
+                    android:layout_marginLeft="32dip"/>
 
-            </LinearLayout>
-        </view>
+            </FrameLayout>
+
+            <!-- Most Frequent -->
+            <fragment
+                android:id="@+id/frequent_fragment"
+                class="com.android.contacts.list.ContactTileFrequentFragment"
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="3"
+                android:layout_marginTop="32dip"
+                android:layout_marginRight="16dip"/>
+
+        </LinearLayout>
 
     </com.android.contacts.widget.InterpolatingLayout>
 
diff --git a/res/layout-sw680dp-w1000dp/quickcontact_activity.xml b/res/layout-sw680dp-w1000dp/quickcontact_activity.xml
new file mode 100644
index 0000000..5c38309
--- /dev/null
+++ b/res/layout-sw680dp-w1000dp/quickcontact_activity.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+<view
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.android.contacts.quickcontact.FloatingChildLayout"
+    android:id="@+id/floating_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
+    android:descendantFocusability="afterDescendants">
+    <LinearLayout
+        android:id="@android:id/content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="32dip"
+        android:orientation="horizontal">
+        <FrameLayout
+            android:layout_width="360dip"
+            android:layout_height="360dip">
+            <include layout="@layout/quickcontact_photo_container" />
+        </FrameLayout>
+        <LinearLayout
+            android:layout_width="360dip"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+            <include layout="@layout/quickcontact_track" />
+            <View
+                android:id="@+id/line_after_track"
+                android:layout_width="match_parent"
+                android:layout_height="2dip"
+                android:background="@color/quickcontact_tab_indicator" />
+            <android.support.v4.view.ViewPager
+                android:id="@+id/item_list_pager"
+                android:background="@color/quickcontact_list_background"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+        </LinearLayout>
+    </LinearLayout>
+</view>
diff --git a/res/layout-sw680dp/contact_detail_container.xml b/res/layout-sw680dp/contact_detail_container.xml
new file mode 100644
index 0000000..dfbd0d0
--- /dev/null
+++ b/res/layout-sw680dp/contact_detail_container.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.v4.view.ViewPager
+        android:id="@+id/pager"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <include
+        android:id="@+id/tab_carousel"
+        layout="@layout/contact_detail_tab_carousel"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"/>
+
+</RelativeLayout>
diff --git a/res/layout-sw680dp/contact_detail_fragment.xml b/res/layout-sw680dp/contact_detail_fragment.xml
new file mode 100644
index 0000000..4c6315e
--- /dev/null
+++ b/res/layout-sw680dp/contact_detail_fragment.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_detail"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <!-- Placeholder for empty list -->
+    <include
+        android:id="@android:id/empty"
+        layout="@layout/contact_detail_empty"
+        android:visibility="gone" />
+
+    <!-- Real list -->
+    <ListView android:id="@android:id/list"
+        android:layout_weight="1"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:fadingEdge="none"
+        android:cacheColorHint="#00000000"
+        android:divider="@null"
+        android:scrollbarStyle="outsideOverlay"
+        android:paddingRight="12dip" />
+
+    <!-- "QuickFix"- button (Copy to local contact, add to group) -->
+    <Button
+        android:id="@+id/contact_quick_fix"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:layout_gravity="center"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip" />
+</LinearLayout>
diff --git a/res/layout-sw680dp/contact_detail_updates_fragment.xml b/res/layout-sw680dp/contact_detail_updates_fragment.xml
new file mode 100644
index 0000000..a2d1abb
--- /dev/null
+++ b/res/layout-sw680dp/contact_detail_updates_fragment.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_detail_updates_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ListView android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fadingEdge="none"
+        android:divider="@null"
+        android:scrollbarStyle="outsideOverlay"
+        android:paddingRight="12dip" />
+
+</FrameLayout>
diff --git a/res/layout-sw680dp/group_browse_list_account_header.xml b/res/layout-sw680dp/group_browse_list_account_header.xml
new file mode 100644
index 0000000..af60c79
--- /dev/null
+++ b/res/layout-sw680dp/group_browse_list_account_header.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <!-- Only visible when it is the first element in the list. -->
+    <View
+        android:id="@+id/header_extra_top_padding"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/list_header_extra_top_padding" />
+
+    <include layout="@layout/group_account_header_horizontal" />
+
+</LinearLayout>
diff --git a/res/layout-sw680dp/people_activity.xml b/res/layout-sw680dp/people_activity.xml
new file mode 100644
index 0000000..f604f9b
--- /dev/null
+++ b/res/layout-sw680dp/people_activity.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:id="@+id/main_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:splitMotionEvents="true"
+        android:baselineAligned="false">
+
+        <!-- Left panel browse list for Groups or All tabs -->
+        <FrameLayout
+            android:id="@+id/browse_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@drawable/list_background_holo"
+            android:visibility="gone">
+
+            <!-- All -->
+            <fragment
+                android:id="@+id/all_fragment"
+                class="com.android.contacts.list.DefaultContactBrowseListFragment"
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
+
+            <!-- Groups -->
+            <fragment
+                android:id="@+id/groups_fragment"
+                class="com.android.contacts.group.GroupBrowseListFragment"
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
+        </FrameLayout>
+
+        <!-- Right panel detail view for All tab -->
+        <view
+            class="com.android.contacts.widget.TransitionAnimationView"
+            android:id="@+id/contact_details_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@color/background_primary"
+            android:visibility="gone">
+
+            <!-- This layout includes all possible views needed for a contact detail page -->
+            <include
+                android:id="@+id/contact_detail_container"
+                layout="@layout/contact_detail_container"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="16dip"
+                android:layout_marginTop="16dip"
+                android:layout_marginRight="16dip" />
+
+            <!-- This invisible worker fragment loads the contact's details -->
+            <fragment
+                android:id="@+id/contact_detail_loader_fragment"
+                class="com.android.contacts.detail.ContactLoaderFragment"
+                android:layout_height="0dip"
+                android:layout_width="0dip"
+                android:visibility="gone"/>
+        </view>
+
+        <!-- Right panel detail view for Groups tab -->
+        <view
+            class="com.android.contacts.widget.TransitionAnimationView"
+            android:id="@+id/group_details_view"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:background="@color/background_primary"
+            android:visibility="gone">
+
+            <!-- This is the group detail page -->
+            <fragment
+                android:id="@+id/group_detail_fragment"
+                class="com.android.contacts.group.GroupDetailFragment"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:visibility="gone" />
+        </view>
+
+        <!-- Two-panel view under the Favorites tab -->
+        <LinearLayout
+            android:id="@+id/favorites_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@drawable/list_background_holo"
+            android:baselineAligned="false">
+
+            <!-- Starred -->
+            <FrameLayout
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="10"
+                android:background="@drawable/panel_favorites_holo_light">
+
+                <fragment
+                    android:id="@+id/favorites_fragment"
+                    class="com.android.contacts.list.ContactTileListFragment"
+                    android:layout_height="match_parent"
+                    android:layout_width="match_parent"
+                    android:layout_marginRight="16dip"
+                    android:layout_marginLeft="16dip"/>
+
+            </FrameLayout>
+
+            <!-- Most Frequent -->
+            <fragment
+                android:id="@+id/frequent_fragment"
+                class="com.android.contacts.list.ContactTileFrequentFragment"
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="8"
+                android:layout_marginTop="16dip"
+                android:layout_marginRight="16dip"/>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <com.android.contacts.widget.InterpolatingLayout
+        android:id="@+id/contacts_unavailable_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+
+        <FrameLayout
+            android:id="@+id/contacts_unavailable_container"
+            android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            ex:layout_narrowParentWidth="800dip"
+            ex:layout_narrowMarginLeft="80dip"
+            ex:layout_narrowMarginRight="80dip"
+            ex:layout_wideParentWidth="1280dip"
+            ex:layout_wideMarginLeft="200dip"
+            ex:layout_wideMarginRight="200dip"
+            android:paddingBottom="20dip" />
+
+    </com.android.contacts.widget.InterpolatingLayout>
+</FrameLayout>
diff --git a/res/layout-sw680dp/quickcontact_activity.xml b/res/layout-sw680dp/quickcontact_activity.xml
new file mode 100644
index 0000000..8843fc9
--- /dev/null
+++ b/res/layout-sw680dp/quickcontact_activity.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+<view
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+    class="com.android.contacts.quickcontact.FloatingChildLayout"
+    android:id="@+id/floating_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
+    android:descendantFocusability="afterDescendants">
+    <LinearLayout
+        android:id="@android:id/content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="32dip"
+        android:orientation="vertical" >
+        <FrameLayout
+            android:layout_width="360dip"
+            android:layout_height="@dimen/quick_contact_photo_container_height">
+            <include layout="@layout/quickcontact_photo_container" />
+        </FrameLayout>
+        <include layout="@layout/quickcontact_track" />
+        <View
+            android:id="@+id/line_after_track"
+            android:layout_width="match_parent"
+            android:layout_height="2dip"
+            android:background="@color/quickcontact_tab_indicator" />
+        <android.support.v4.view.ViewPager
+            android:id="@+id/item_list_pager"
+            android:layout_width="match_parent"
+            android:layout_height="160dip" />
+    </LinearLayout>
+</view>
diff --git a/res/layout-w470dp/contact_detail_container.xml b/res/layout-w470dp/contact_detail_container.xml
index a8ee0a5..fc401b7 100644
--- a/res/layout-w470dp/contact_detail_container.xml
+++ b/res/layout-w470dp/contact_detail_container.xml
@@ -16,8 +16,7 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
     <com.android.contacts.detail.ContactDetailFragmentCarousel
         android:id="@+id/fragment_carousel"
diff --git a/res/layout-w470dp/contact_detail_fragment.xml b/res/layout-w470dp/contact_detail_fragment.xml
index 415bb56..86692d8 100644
--- a/res/layout-w470dp/contact_detail_fragment.xml
+++ b/res/layout-w470dp/contact_detail_fragment.xml
@@ -19,7 +19,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-     <!-- "QuickFix"- button (Copy to local contact, add to group) -->
+    <!-- "QuickFix"- button (Copy to local contact, add to group) -->
     <Button
         android:id="@+id/contact_quick_fix"
         android:layout_width="wrap_content"
@@ -35,14 +35,16 @@
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_above="@id/contact_quick_fix"
-        android:layout_height="match_parent" >
+        android:layout_height="match_parent"
+        android:baselineAligned="false"
+        android:background="@android:color/white">
 
-        <ImageView android:id="@+id/photo"
-            android:scaleType="centerCrop"
-            android:layout_width="128dip"
-            android:layout_height="128dip"
+        <include android:id="@+id/static_photo_container"
+            layout="@layout/photo_selector_view"
+            android:layout_width="@dimen/detail_contact_photo_size"
+            android:layout_height="@dimen/detail_contact_photo_size"
             android:layout_marginLeft="@dimen/detail_contact_photo_margin"
-            android:layout_marginTop="@dimen/detail_contact_photo_margin"/>
+            android:layout_marginTop="@dimen/detail_contact_photo_margin" />
 
         <ListView android:id="@android:id/list"
             android:layout_width="0dip"
@@ -70,20 +72,5 @@
             android:lineSpacingMultiplier="0.92"/>
     </ScrollView>
 
-    <View
-        android:id="@+id/alpha_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"/>
-
-    <View
-        android:id="@+id/touch_intercept_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:background="?android:attr/selectableItemBackground"
-        android:visibility="gone"/>
 </RelativeLayout>
 
diff --git a/res/layout-w470dp/contact_detail_updates_fragment.xml b/res/layout-w470dp/contact_detail_updates_fragment.xml
index 50536de..801f2bb 100644
--- a/res/layout-w470dp/contact_detail_updates_fragment.xml
+++ b/res/layout-w470dp/contact_detail_updates_fragment.xml
@@ -15,31 +15,16 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@+id/contact_detail_updates_fragment"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@color/background_social_updates">
 
     <ListView android:id="@android:id/list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:fadingEdge="none"
-        android:divider="@null"/>
-
-    <View
-        android:id="@+id/alpha_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"/>
-
-    <View
-        android:id="@+id/touch_intercept_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:background="?android:attr/selectableItemBackground"
-        android:visibility="gone"/>
+        android:divider="@null"
+        android:background="@android:color/transparent"/>
 
 </FrameLayout>
diff --git a/res/layout/account_filter_header.xml b/res/layout/account_filter_header.xml
index ef0a9c2..0ffb7e1 100644
--- a/res/layout/account_filter_header.xml
+++ b/res/layout/account_filter_header.xml
@@ -23,7 +23,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:paddingTop="@dimen/account_filter_header_top_padding"
+    android:paddingTop="@dimen/list_header_extra_top_padding"
     android:layout_marginLeft="@dimen/contact_browser_list_header_left_margin"
     android:layout_marginRight="@dimen/contact_browser_list_header_right_margin"
     android:background="?android:attr/selectableItemBackground"
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
index 13124f2..1d0a285 100644
--- a/res/layout/call_detail.xml
+++ b/res/layout/call_detail.xml
@@ -20,6 +20,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:visibility="gone"
+    android:background="@android:color/black"
 >
     <!--
       The list view is under everything.
@@ -32,7 +33,6 @@
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
-        android:background="@android:color/black"
     />
 
     <!-- All the controls which are part of the pinned header are in this layout. -->
@@ -128,52 +128,56 @@
             android:layout_height="wrap_content"
             android:paddingBottom="@dimen/call_detail_button_spacing"
             android:layout_below="@id/blue_separator"
-            android:background="@android:color/black"
         >
             <!-- The voicemail fragment will be put here. -->
         </LinearLayout>
-        <FrameLayout android:id="@+id/call_and_sms_container"
+        <FrameLayout
+            android:id="@+id/call_and_sms"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
+            android:layout_height="@dimen/call_log_list_item_height"
             android:layout_marginBottom="@dimen/call_detail_button_spacing"
             android:layout_below="@id/voicemail_container"
-            android:background="@android:color/black"
+            android:gravity="center_vertical"
+            android:background="@drawable/dialpad_background"
         >
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:id="@+id/call_and_sms"
+            <LinearLayout
+                android:id="@+id/call_and_sms_main_action"
                 android:layout_width="match_parent"
-                android:layout_height="@dimen/call_log_list_item_height"
+                android:layout_height="match_parent"
                 android:orientation="horizontal"
-                android:gravity="center_vertical"
-                android:background="@drawable/dialpad_background"
-            >
+                android:focusable="true"
+                android:background="?android:attr/selectableItemBackground"
+                >
 
-                <LinearLayout android:id="@+id/call_and_sms_main_action"
+                <LinearLayout
                     android:layout_width="0dip"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
                     android:paddingLeft="@dimen/call_log_indent_margin"
                     android:orientation="vertical"
                     android:gravity="center_vertical"
-                    android:focusable="true"
-                    android:background="?android:attr/selectableItemBackground"
                 >
 
                     <TextView android:id="@+id/call_and_sms_text"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
+                        android:paddingRight="@dimen/call_log_icon_margin"
                         android:textAppearance="?android:attr/textAppearanceMedium"
                         android:textColor="?attr/call_log_primary_text_color"
+                        android:singleLine="true"
+                        android:ellipsize="end"
                     />
 
                     <TextView android:id="@+id/call_and_sms_label"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
+                        android:paddingRight="@dimen/call_log_icon_margin"
                         android:textAppearance="?android:attr/textAppearanceSmall"
                         android:textColor="?attr/call_log_primary_text_color"
                         android:textAllCaps="true"
+                        android:singleLine="true"
+                        android:ellipsize="end"
                     />
-
                 </LinearLayout>
 
                 <View android:id="@+id/call_and_sms_divider"
@@ -207,7 +211,7 @@
         android:layout_height="match_parent"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
-        android:background="#000000"
+        android:background="@android:color/black"
         android:visibility="gone"
         android:clickable="true"
     />
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index d652ad7..9e88c49 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -35,8 +35,7 @@
     </FrameLayout>
     <FrameLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-    >
+        android:layout_height="match_parent">
         <ListView android:id="@android:id/list"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/res/layout/call_log_incoming_call_icon.xml b/res/layout/call_log_incoming_call_icon.xml
deleted file mode 100644
index 8361655..0000000
--- a/res/layout/call_log_incoming_call_icon.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/call_log_incoming_call_icon"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_marginRight="@dimen/call_log_icon_margin"
-    android:src="@drawable/ic_call_incoming_holo_dark"
-    android:contentDescription="@string/description_call_log_incoming_call"
-/>
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index 777c7af..4040c28 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -69,18 +69,38 @@
                     android:id="@+id/name"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_marginRight="@dimen/call_log_icon_margin"
                     android:textColor="?attr/call_log_primary_text_color"
                     android:textSize="18sp"
                     android:singleLine="true"
                 />
-                <TextView
-                    android:id="@+id/number"
+                <LinearLayout
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:textColor="?attr/call_log_secondary_text_color"
-                    android:textSize="14sp"
-                    android:singleLine="true"
-                />
+                    android:orientation="horizontal"
+                >
+                    <TextView
+                        android:id="@+id/number"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginRight="@dimen/call_log_icon_margin"
+                        android:textColor="?attr/call_log_secondary_text_color"
+                        android:textSize="14sp"
+                        android:singleLine="true"
+                        android:ellipsize="marquee"
+                        />
+                    <TextView
+                        android:id="@+id/label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginRight="@dimen/call_log_icon_margin"
+                        android:textColor="?attr/call_log_secondary_text_color"
+                        android:textStyle="bold"
+                        android:textSize="14sp"
+                        android:singleLine="true"
+                        android:ellipsize="marquee"
+                        />
+                    </LinearLayout>
                 <LinearLayout
                     android:id="@+id/call_type"
                     android:layout_width="wrap_content"
@@ -99,6 +119,7 @@
                         android:id="@+id/call_count_and_date"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
+                        android:layout_marginRight="@dimen/call_log_icon_margin"
                         android:layout_gravity="center_vertical"
                         android:textColor="?attr/call_log_secondary_text_color"
                         android:textSize="14sp"
diff --git a/res/layout/call_log_missed_call_icon.xml b/res/layout/call_log_missed_call_icon.xml
deleted file mode 100644
index 49177cd..0000000
--- a/res/layout/call_log_missed_call_icon.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/call_log_missed_call_icon"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_marginRight="@dimen/call_log_icon_margin"
-    android:src="@drawable/ic_call_missed_holo_dark"
-    android:contentDescription="@string/description_call_log_missed_call"
-/>
diff --git a/res/layout/call_log_outgoing_call_icon.xml b/res/layout/call_log_outgoing_call_icon.xml
deleted file mode 100644
index f109eb4..0000000
--- a/res/layout/call_log_outgoing_call_icon.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/call_log_outgoing_call_icon"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_marginRight="@dimen/call_log_icon_margin"
-    android:src="@drawable/ic_call_outgoing_holo_dark"
-    android:contentDescription="@string/description_call_log_outgoing_call"
-/>
diff --git a/res/layout/call_log_voicemail_icon.xml b/res/layout/call_log_voicemail_icon.xml
deleted file mode 100644
index 4fddcf0..0000000
--- a/res/layout/call_log_voicemail_icon.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/call_log_voicemail_icon"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_marginRight="@dimen/call_log_icon_margin"
-    android:src="@drawable/ic_call_voicemail_holo_dark"
-    android:contentDescription="@string/description_call_log_voicemail"
-/>
diff --git a/res/layout/carousel_about_tab.xml b/res/layout/carousel_about_tab.xml
index c5d4114..dc261d2 100644
--- a/res/layout/carousel_about_tab.xml
+++ b/res/layout/carousel_about_tab.xml
@@ -21,49 +21,54 @@
     android:layout_height="match_parent"
     android:layout_weight="1">
 
-    <ImageView android:id="@+id/photo"
-        android:scaleType="centerCrop"
+    <RelativeLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"/>
+        android:layout_height="match_parent" >
 
-    <!-- Transparent view to overlay on the contact's photo
-    (to allow white text to appear over a white photo). -->
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentBottom="true"
-        android:background="#7F000000" />
+        <ImageView android:id="@+id/photo"
+            android:scaleType="centerCrop"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"/>
 
-    <View
-        android:id="@+id/alpha_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginBottom="@dimen/detail_tab_carousel_tab_label_height"/>
+        <View android:id="@+id/photo_overlay"
+            android:background="?android:attr/selectableItemBackground"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"/>
 
-    <TextView
-        android:id="@+id/label"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentBottom="true"
-        android:paddingLeft="@dimen/detail_tab_carousel_tab_label_indent"
-        android:singleLine="true"
-        android:gravity="left|center_vertical"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="@color/detail_tab_carousel_tab_label_color"
-        style="@android:style/Widget.Holo.ActionBar.TabView" />
+        <!-- Transparent view to overlay on the contact's photo
+        (to allow white text to appear over a white photo). -->
+        <View android:id="@+id/label_background"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentBottom="true"
+            android:background="#7F000000" />
 
-    <View
-        android:id="@+id/touch_intercept_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:background="?android:attr/selectableItemBackground"
-        android:visibility="gone"/>
+        <View
+            android:id="@+id/alpha_overlay"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginBottom="@dimen/detail_tab_carousel_tab_label_height"/>
+
+        <TextView
+            android:id="@+id/label"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentBottom="true"
+            android:paddingLeft="@dimen/detail_tab_carousel_tab_label_indent"
+            android:singleLine="true"
+            android:gravity="left|center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/detail_tab_carousel_tab_label_color"
+            style="@android:style/Widget.Holo.ActionBar.TabView" />
+
+    </RelativeLayout>
+
 </view>
diff --git a/res/layout/carousel_updates_tab.xml b/res/layout/carousel_updates_tab.xml
index d23f650..67ea582 100644
--- a/res/layout/carousel_updates_tab.xml
+++ b/res/layout/carousel_updates_tab.xml
@@ -26,68 +26,65 @@
     android:layout_weight="1"
     android:background="@drawable/bg_people_updates_holo">
 
-    <ImageView android:id="@+id/status_photo"
-        android:scaleType="centerCrop"
+    <RelativeLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"
-        android:visibility="gone" />
+        android:layout_height="match_parent" >
 
-    <!-- Transparent view to overlay on the update photo
-    (to allow white text to appear over a white photo). -->
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentBottom="true"
-        android:layout_above="@id/status_photo"
-        android:background="#7F000000" />
+        <ImageView android:id="@+id/status_photo"
+            android:scaleType="centerCrop"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:visibility="gone" />
 
-    <TextView android:id="@+id/status"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"
-        android:layout_above="@id/label"
-        android:gravity="center_vertical"
-        android:paddingLeft="@dimen/detail_update_tab_side_padding"
-        android:paddingRight="@dimen/detail_update_tab_side_padding"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:textColor="@color/detail_update_tab_text_color"
-        android:textStyle="bold"
-        android:maxLines="@integer/updates_tab_snippet_max_lines"
-        android:ellipsize="end" />
+        <!-- Transparent view to overlay on the update photo
+        (to allow white text to appear over a white photo). -->
+        <View android:id="@+id/label_background"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentBottom="true"
+            android:layout_above="@id/status_photo"
+            android:background="#7F000000" />
 
-    <View
-        android:id="@+id/alpha_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginBottom="@dimen/detail_tab_carousel_tab_label_height"/>
+        <TextView android:id="@+id/status"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:layout_above="@id/label"
+            android:gravity="center_vertical"
+            android:paddingLeft="@dimen/detail_update_tab_side_padding"
+            android:paddingRight="@dimen/detail_update_tab_side_padding"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textColor="@color/detail_update_tab_text_color"
+            android:textStyle="bold"
+            android:maxLines="@integer/updates_tab_snippet_max_lines"
+            android:ellipsize="end" />
 
-    <TextView
-        android:id="@+id/label"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentBottom="true"
-        android:layout_above="@id/status_photo"
-        android:paddingLeft="@dimen/detail_tab_carousel_tab_label_indent"
-        android:singleLine="true"
-        android:gravity="left|center_vertical"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="@color/detail_tab_carousel_tab_label_color"
-        style="@android:style/Widget.Holo.ActionBar.TabView" />
+        <View
+            android:id="@+id/alpha_overlay"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginBottom="@dimen/detail_tab_carousel_tab_label_height"/>
 
-    <View
-        android:id="@+id/touch_intercept_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:background="?android:attr/selectableItemBackground"
-        android:visibility="gone"/>
+        <TextView
+            android:id="@+id/label"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/detail_tab_carousel_tab_label_height"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentBottom="true"
+            android:layout_above="@id/status_photo"
+            android:paddingLeft="@dimen/detail_tab_carousel_tab_label_indent"
+            android:singleLine="true"
+            android:gravity="left|center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/detail_tab_carousel_tab_label_color"
+            style="@android:style/Widget.Holo.ActionBar.TabView" />
+
+    </RelativeLayout>
 
 </view>
diff --git a/res/layout/confirm_add_detail_activity.xml b/res/layout/confirm_add_detail_activity.xml
index 70e2b47..7ee16cf 100644
--- a/res/layout/confirm_add_detail_activity.xml
+++ b/res/layout/confirm_add_detail_activity.xml
@@ -17,7 +17,6 @@
 <!-- Layout for confirming the addition of a piece of information to an existing contact. -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@+id/root_view"
     android:orientation="vertical"
     android:visibility="invisible"
diff --git a/res/layout/contact_detail_activity.xml b/res/layout/contact_detail_activity.xml
index 1e63aa7..9765a71 100644
--- a/res/layout/contact_detail_activity.xml
+++ b/res/layout/contact_detail_activity.xml
@@ -27,11 +27,11 @@
         android:layout_width="0dip"
         android:visibility="gone"/>
 
-      <!-- This layout includes all possible views needed for a contact detail page -->
-      <include
-          android:id="@+id/contact_detail_container"
-          layout="@layout/contact_detail_container"
-          android:layout_width="match_parent"
-          android:layout_height="match_parent"/>
+    <!-- This layout includes all possible views needed for a contact detail page -->
+    <include
+        android:id="@+id/contact_detail_container"
+        layout="@layout/contact_detail_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
 
 </FrameLayout>
diff --git a/res/layout/contact_detail_add_connection_entry_view.xml b/res/layout/contact_detail_add_connection_entry_view.xml
new file mode 100644
index 0000000..208a8d4
--- /dev/null
+++ b/res/layout/contact_detail_add_connection_entry_view.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2012, 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.
+ */
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="@dimen/detail_item_side_margin"
+    android:paddingRight="@dimen/detail_item_side_margin">
+    <LinearLayout
+        android:id="@+id/primary_action_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="@dimen/detail_item_vertical_margin"
+        android:paddingBottom="@dimen/detail_item_vertical_margin"
+        android:focusable="true"
+        android:background="?android:attr/selectableItemBackground"
+        android:minHeight="@dimen/detail_min_line_item_height"
+        android:orientation="horizontal"
+        android:gravity="center_vertical">
+
+        <ImageView
+            android:id="@+id/add_connection_icon"
+            android:layout_width="@dimen/detail_network_icon_size"
+            android:layout_height="@dimen/detail_network_icon_size"
+            android:layout_marginLeft="@dimen/detail_item_icon_margin"
+            android:layout_marginRight="@dimen/detail_item_icon_margin"
+            android:layout_gravity="center_vertical"
+            android:scaleType="centerInside" />
+
+        <TextView
+            android:id="@+id/add_connection_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium"/>
+    </LinearLayout>
+</FrameLayout>
diff --git a/res/layout/contact_detail_container.xml b/res/layout/contact_detail_container.xml
index ff2eab1..a59ada4 100644
--- a/res/layout/contact_detail_container.xml
+++ b/res/layout/contact_detail_container.xml
@@ -25,8 +25,7 @@
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
     <android.support.v4.view.ViewPager
         android:id="@+id/pager"
diff --git a/res/layout/contact_detail_fragment_carousel.xml b/res/layout/contact_detail_fragment_carousel.xml
index 2572cc4..0695511 100644
--- a/res/layout/contact_detail_fragment_carousel.xml
+++ b/res/layout/contact_detail_fragment_carousel.xml
@@ -19,14 +19,16 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:scrollbars="none"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:baselineAligned="false">
 
     <!--
       Container for the "About" page fragment on the contact card for a contact
       with social updates. This view ID must match with a view ID in the layout
       that is used after an orientation change.
     -->
-    <FrameLayout
+    <view
+        class="com.android.contacts.widget.FrameLayoutWithOverlay"
         android:id="@+id/about_fragment_container"
         android:layout_width="0dip"
         android:layout_height="match_parent"
@@ -39,13 +41,14 @@
       with social updates. This view ID must match with a view ID in the layout
       that is used after an orientation change.
     -->
-    <FrameLayout
+    <view
+        class="com.android.contacts.widget.FrameLayoutWithOverlay"
         android:id="@+id/updates_fragment_container"
         android:layout_width="0dip"
         android:layout_height="match_parent"
         android:layout_weight="1"
-        android:visibility="gone"
         android:focusable="true"
-        android:focusableInTouchMode="true" />
+        android:focusableInTouchMode="true"
+        android:visibility="gone" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/contact_detail_list_item.xml b/res/layout/contact_detail_list_item.xml
index 44f5a53..666b67c 100644
--- a/res/layout/contact_detail_list_item.xml
+++ b/res/layout/contact_detail_list_item.xml
@@ -82,15 +82,6 @@
 
             </LinearLayout>
 
-            <TextView
-                android:id="@+id/footer"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?android:attr/textColorSecondary"
-                android:visibility="gone" />
-
         </LinearLayout>
 
         <View
diff --git a/res/layout/contact_detail_list_padding.xml b/res/layout/contact_detail_list_padding.xml
index 8095731..c5dbd06 100644
--- a/res/layout/contact_detail_list_padding.xml
+++ b/res/layout/contact_detail_list_padding.xml
@@ -23,6 +23,5 @@
     <View
         android:id="@+id/contact_detail_list_padding"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/contact_browser_list_top_margin" />
+        android:layout_height="@dimen/list_header_extra_top_padding" />
 </FrameLayout>
-
diff --git a/res/layout/contact_detail_network_title_entry_view.xml b/res/layout/contact_detail_network_title_entry_view.xml
index 1907a7a..09b8b34 100644
--- a/res/layout/contact_detail_network_title_entry_view.xml
+++ b/res/layout/contact_detail_network_title_entry_view.xml
@@ -49,6 +49,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
-            android:textAppearance="?android:attr/textAppearanceMedium" />
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary" />
     </LinearLayout>
 </FrameLayout>
diff --git a/res/layout/contact_detail_tab_carousel.xml b/res/layout/contact_detail_tab_carousel.xml
index 28463a2..711a6c3 100644
--- a/res/layout/contact_detail_tab_carousel.xml
+++ b/res/layout/contact_detail_tab_carousel.xml
@@ -23,26 +23,48 @@
     android:fadingEdge="none">
 
     <LinearLayout
-        android:id="@+id/tab_container"
+        android:id="@+id/tab_and_shadow_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="horizontal">
+        android:orientation="vertical">
 
-        <!-- "About" tab -->
-        <include
-            android:id="@+id/tab_about"
-            layout="@layout/carousel_about_tab" />
+        <LinearLayout
+            android:id="@+id/tab_container"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:orientation="horizontal"
+            android:baselineAligned="false">
 
-        <!-- Vertical divider -->
+            <!-- "About" tab -->
+            <include
+                android:id="@+id/tab_about"
+                layout="@layout/carousel_about_tab" />
+
+            <!-- Vertical divider -->
+            <View
+                android:id="@+id/tab_divider"
+                android:layout_width="1dip"
+                android:layout_height="match_parent"
+                android:background="@android:color/white"/>
+
+            <!-- "Updates" tab -->
+            <include
+                android:id="@+id/tab_update"
+                layout="@layout/carousel_updates_tab" />
+
+        </LinearLayout>
+
+        <!--
+          Shadow below the carousel. The ContactDetailTabCarousel increases its height to
+          account for this shadow, and the class assumes the height of this shadow to be
+          @dimen/detail_contact_photo_shadow_height.
+        -->
         <View
-            android:layout_width="1dip"
-            android:layout_height="match_parent"
-            android:background="@android:color/white"/>
-
-        <!-- "Updates" tab -->
-        <include
-            android:id="@+id/tab_update"
-            layout="@layout/carousel_updates_tab" />
+            android:id="@+id/shadow"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/detail_contact_photo_shadow_height"
+            android:background="?android:attr/windowContentOverlay"/>
 
     </LinearLayout>
 
diff --git a/res/layout/contact_detail_updates_fragment.xml b/res/layout/contact_detail_updates_fragment.xml
index 30f09b9..02e906c 100644
--- a/res/layout/contact_detail_updates_fragment.xml
+++ b/res/layout/contact_detail_updates_fragment.xml
@@ -16,7 +16,6 @@
 
 <ListView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:id="@android:id/list"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/res/layout/contact_detail_updates_fragment_container.xml b/res/layout/contact_detail_updates_fragment_container.xml
index fb3a8ac..7414f61 100644
--- a/res/layout/contact_detail_updates_fragment_container.xml
+++ b/res/layout/contact_detail_updates_fragment_container.xml
@@ -22,4 +22,5 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/updates_fragment_container"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"/>
\ No newline at end of file
+    android:layout_height="match_parent"
+    android:visibility="gone" />
diff --git a/res/layout/contact_editor_fragment.xml b/res/layout/contact_editor_fragment.xml
index 913a5e0..f174a3d 100644
--- a/res/layout/contact_editor_fragment.xml
+++ b/res/layout/contact_editor_fragment.xml
@@ -14,24 +14,18 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:fillViewport="true"
+    android:fadingEdge="none"
     android:background="@color/background_primary"
 >
 
-    <ScrollView
+    <LinearLayout android:id="@+id/editors"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:fillViewport="true"
-        android:fadingEdge="none"
-    >
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+    />
 
-        <LinearLayout android:id="@+id/editors"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical"
-        />
-
-    </ScrollView>
-</FrameLayout>
+</ScrollView>
diff --git a/res/layout/contact_editor_label_name_dialog.xml b/res/layout/contact_editor_label_name_dialog.xml
new file mode 100644
index 0000000..8960869
--- /dev/null
+++ b/res/layout/contact_editor_label_name_dialog.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingTop="25dip"
+    android:paddingRight="25dip"
+    android:paddingBottom="25dip"
+    android:paddingLeft="25dip">
+    <EditText
+        android:id="@+id/custom_dialog_content"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</FrameLayout>
diff --git a/res/layout/contact_list_content.xml b/res/layout/contact_list_content.xml
index 05f1930..b268102 100644
--- a/res/layout/contact_list_content.xml
+++ b/res/layout/contact_list_content.xml
@@ -33,21 +33,32 @@
         android:id="@+id/account_filter_header_container"
         layout="@layout/account_filter_header" />
 
-    <view
-        class="com.android.contacts.widget.PinnedHeaderListView"
-        android:id="@android:id/list"
+    <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="0dip"
-        android:layout_marginLeft="?attr/contact_browser_list_padding_left"
-        android:layout_marginRight="?attr/contact_browser_list_padding_right"
-        android:fastScrollEnabled="true"
-        android:fadingEdge="none"
-        android:layout_weight="1" />
+        android:layout_weight="1" >
+        <view
+            class="com.android.contacts.widget.PinnedHeaderListView"
+            android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="?attr/contact_browser_list_padding_left"
+            android:layout_marginRight="?attr/contact_browser_list_padding_right"
+            android:fastScrollEnabled="true"
+            android:fadingEdge="none" />
+        <ProgressBar
+            android:id="@+id/search_progress"
+            style="?android:attr/progressBarStyleLarge"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:visibility="gone" />
+    </FrameLayout>
 
-   <ViewStub
-       android:id="@+id/footer_stub"
-       android:layout="@layout/footer_panel"
-       android:layout_width="fill_parent"
-       android:layout_height="wrap_content" />
+    <ViewStub
+        android:id="@+id/footer_stub"
+        android:layout="@layout/footer_panel"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
 
 </LinearLayout>
diff --git a/res/layout/contact_list_filter_item.xml b/res/layout/contact_list_filter_item.xml
index b27cab8..7814565 100644
--- a/res/layout/contact_list_filter_item.xml
+++ b/res/layout/contact_list_filter_item.xml
@@ -17,29 +17,50 @@
 <view
     xmlns:android="http://schemas.android.com/apk/res/android"
     class="com.android.contacts.list.ContactListFilterView"
+    android:descendantFocusability="blocksDescendants"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="@dimen/contact_filter_item_min_height">
-
-    <View
-        android:id="@+id/indent"
-        android:layout_width="32dip"
-        android:layout_height="fill_parent" />
+    android:minHeight="@dimen/contact_filter_item_min_height"
+    android:gravity="center_vertical">
 
     <ImageView
         android:id="@+id/icon"
         android:scaleType="fitCenter"
         android:layout_width="@dimen/contact_filter_icon_size"
-        android:layout_height="@dimen/contact_filter_icon_size"
-        android:layout_gravity="center_vertical" />
+        android:layout_height="@dimen/contact_filter_icon_size"/>
 
-    <TextView
-        android:id="@+id/label"
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:layout_marginLeft="8dip">
+
+        <TextView
+            android:id="@+id/accountType"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:singleLine="true"
+            android:ellipsize="end"/>
+
+        <TextView
+            android:id="@+id/accountUserName"
+            android:layout_marginTop="-3dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorTertiary"
+            android:singleLine="true"
+            android:ellipsize="end"/>
+    </LinearLayout>
+
+    <RadioButton
+        android:id="@+id/radioButton"
+        android:clickable="false"
+        android:layout_marginTop="1dip"
         android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_marginLeft="8dip"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:gravity="center_vertical"
-        android:ellipsize="end" />
+        android:layout_height="wrap_content"
+        android:layout_gravity="right|center_vertical" />
 </view>
 
diff --git a/res/layout/contact_tile_frequent.xml b/res/layout/contact_tile_frequent.xml
index 5b51c78..9219f56 100644
--- a/res/layout/contact_tile_frequent.xml
+++ b/res/layout/contact_tile_frequent.xml
@@ -15,7 +15,7 @@
 -->
 <view
     xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.contacts.list.ContactTileView"
+    class="com.android.contacts.list.ContactTileFrequentView"
     android:focusable="true"
     android:background="?android:attr/selectableItemBackground"
     android:nextFocusRight="@+id/contact_tile_quick">
@@ -24,19 +24,13 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
 
-        <view
-            android:id="@+id/image_container"
-            class="com.android.contacts.list.ContactTileImageContainer"
+        <com.android.contacts.widget.LayoutSuppressingQuickContactBadge
+            android:id="@+id/contact_tile_quick"
             android:layout_width="64dip"
             android:layout_height="64dip"
-            android:layout_alignParentRight="true">
-            <QuickContactBadge
-                android:id="@+id/contact_tile_quick"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop"
-                android:focusable="true" />
-        </view>
+            android:layout_alignParentRight="true"
+            android:scaleType="centerCrop"
+            android:focusable="true" />
 
         <LinearLayout
             android:layout_width="match_parent"
@@ -77,7 +71,7 @@
             android:layout_width="match_parent"
             android:layout_height="1px"
             android:background="?android:attr/listDivider"
-            android:layout_below="@id/image_container" />
+            android:layout_below="@id/contact_tile_quick" />
 
     </RelativeLayout>
 
diff --git a/res/layout/contact_tile_frequent_phone.xml b/res/layout/contact_tile_frequent_phone.xml
index aa2d9a8..cae5ec2 100644
--- a/res/layout/contact_tile_frequent_phone.xml
+++ b/res/layout/contact_tile_frequent_phone.xml
@@ -18,7 +18,7 @@
 <view
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contact_tile_frequent_phone"
-    class="com.android.contacts.list.ContactTileDarkFrequentView"
+    class="com.android.contacts.list.ContactTilePhoneFrequentView"
     android:focusable="true"
     android:background="?android:attr/selectableItemBackground"
     android:nextFocusLeft="@+id/contact_tile_quick">
@@ -27,20 +27,14 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
 
-        <view
-            android:id="@+id/image_container"
-            class="com.android.contacts.list.ContactTileImageContainer"
+        <com.android.contacts.widget.LayoutSuppressingQuickContactBadge
+            android:id="@id/contact_tile_quick"
             android:layout_width="64dip"
             android:layout_height="64dip"
-            android:layout_alignParentLeft="true">
-            <QuickContactBadge
-                android:id="@id/contact_tile_quick"
-                android:nextFocusRight="@id/contact_tile_frequent_phone"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop"
-                android:focusable="true" />
-        </view>
+            android:layout_alignParentLeft="true"
+            android:nextFocusRight="@id/contact_tile_frequent_phone"
+            android:scaleType="centerCrop"
+            android:focusable="true" />
 
         <TextView
             android:id="@+id/contact_tile_name"
@@ -49,7 +43,7 @@
             android:layout_marginLeft="8dip"
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:layout_marginTop="8dip"
-            android:layout_toRightOf="@id/image_container"
+            android:layout_toRightOf="@id/contact_tile_quick"
             android:singleLine="true"
             android:fadingEdge="horizontal"
             android:fadingEdgeLength="3dip"
@@ -60,7 +54,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_below="@id/contact_tile_name"
-            android:layout_toRightOf="@id/image_container"
+            android:layout_toRightOf="@id/contact_tile_quick"
             android:gravity="center_vertical">
 
             <TextView
@@ -96,7 +90,7 @@
             android:layout_width="match_parent"
             android:layout_height="1px"
             android:background="?android:attr/listDivider"
-            android:layout_below="@id/image_container" />
+            android:layout_below="@id/contact_tile_quick" />
 
     </RelativeLayout>
 
diff --git a/res/layout/contact_tile_starred_secondary_target.xml b/res/layout/contact_tile_phone_starred.xml
similarity index 85%
rename from res/layout/contact_tile_starred_secondary_target.xml
rename to res/layout/contact_tile_phone_starred.xml
index 27ef3a3..053ffa6 100644
--- a/res/layout/contact_tile_starred_secondary_target.xml
+++ b/res/layout/contact_tile_phone_starred.xml
@@ -18,22 +18,17 @@
     android:background="@null"
     android:paddingBottom="1dip"
     android:paddingRight="1dip"
-    class="com.android.contacts.list.ContactTileSecondaryTargetView" >
+    class="com.android.contacts.list.ContactTilePhoneStarredView" >
 
     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
 
-        <view
-            class="com.android.contacts.list.ContactTileImageContainer"
+        <com.android.contacts.widget.LayoutSuppressingImageView
+            android:id="@+id/contact_tile_image"
             android:layout_width="match_parent"
-            android:layout_height="match_parent">
-            <ImageView
-                android:id="@+id/contact_tile_image"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop" />
-        </view>
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop" />
 
         <TextView
             android:id="@+id/contact_tile_name"
diff --git a/res/layout/contact_tile_starred.xml b/res/layout/contact_tile_starred.xml
index 4116157..cfc74d8 100644
--- a/res/layout/contact_tile_starred.xml
+++ b/res/layout/contact_tile_starred.xml
@@ -25,16 +25,11 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
 
-        <view
-            class="com.android.contacts.list.ContactTileImageContainer"
+        <com.android.contacts.widget.LayoutSuppressingImageView
+            android:id="@+id/contact_tile_image"
             android:layout_width="match_parent"
-            android:layout_height="match_parent">
-            <ImageView
-                 android:id="@+id/contact_tile_image"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop" />
-        </view>
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop" />
 
         <LinearLayout
             android:layout_width="match_parent"
@@ -73,7 +68,7 @@
 
         </LinearLayout>
 
-       <View
+        <View
             android:id="@+id/contact_tile_push_state"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/res/layout/contact_tile_starred_quick_contact.xml b/res/layout/contact_tile_starred_quick_contact.xml
index 223f1b8..a396c41 100644
--- a/res/layout/contact_tile_starred_quick_contact.xml
+++ b/res/layout/contact_tile_starred_quick_contact.xml
@@ -24,16 +24,11 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
 
-        <view
-            class="com.android.contacts.list.ContactTileImageContainer"
+        <com.android.contacts.widget.LayoutSuppressingImageView
+            android:id="@+id/contact_tile_image"
             android:layout_width="match_parent"
-            android:layout_height="match_parent">
-            <ImageView
-                android:id="@+id/contact_tile_image"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop" />
-        </view>
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop" />
 
         <LinearLayout
             android:layout_width="match_parent"
diff --git a/res/layout/contacts_unavailable_fragment.xml b/res/layout/contacts_unavailable_fragment.xml
index 9f28a55..c3c9bc4 100644
--- a/res/layout/contacts_unavailable_fragment.xml
+++ b/res/layout/contacts_unavailable_fragment.xml
@@ -16,13 +16,12 @@
 
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
     android:layout_width="match_parent"
     android:fillViewport="true">
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:gravity="center_horizontal"
         android:background="@drawable/panel_message">
         <TextView
@@ -62,13 +61,12 @@
                 android:layout_marginBottom="15dip"
                 android:text="@string/contacts_unavailable_add_account" />
 
-            <!-- TODO: Use a string that says "Import" instead of "Import/export contacts"-->
             <Button
                 android:id="@+id/import_contacts_button"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginBottom="15dip"
-                android:text="@string/dialog_import_export" />
+                android:text="@string/contacts_unavailable_import_contacts" />
 
             <Button
                 android:id="@+id/import_failure_uninstall_button"
diff --git a/res/layout/date_picker.xml b/res/layout/date_picker.xml
index 4fb2318..4be95c0 100644
--- a/res/layout/date_picker.xml
+++ b/res/layout/date_picker.xml
@@ -19,12 +19,13 @@
 
 <!-- Layout of date picker-->
 
-<!-- Warning: everything within the parent is removed and re-ordered depending
-     on the date format selected by the user. -->
+<!-- The width of this container is manually set a little bigger than the one of the children
+     contained in it. This helps to prevent rounding errors when toggling the "Show year" option -->
+
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_gravity="center_horizontal"
-    android:layout_width="wrap_content"
+    android:layout_width="270dip"
     android:layout_height="wrap_content">
 
     <CheckBox
@@ -33,8 +34,11 @@
         android:paddingTop="5dip"
         android:paddingBottom="5dip"
         android:textAppearance="?android:attr/textAppearanceLarge"
+        android:layout_gravity="center_horizontal"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
+    <!-- Warning: everything within the parent is removed and re-ordered depending
+         on the date format selected by the user. -->
     <LinearLayout
         android:id="@+id/parent"
         android:orientation="horizontal"
diff --git a/res/layout/detail_header_contact_with_updates.xml b/res/layout/detail_header_contact_with_updates.xml
index 8d18963..39f0582 100644
--- a/res/layout/detail_header_contact_with_updates.xml
+++ b/res/layout/detail_header_contact_with_updates.xml
@@ -18,16 +18,22 @@
   This is a header entry in the contact details list for when the contact has social updates. The
   entry maintains vertical padding to ensure that the first contact detail is visible (and below
   the tab carousel). No information has to be displayed in this header.
+  The FrameLayout is used to apply additional padding which is needed for the shadow
 -->
-<view
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
-    class="com.android.contacts.widget.ProportionalLayout"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    ex:ratio="0.5"
-    ex:direction="widthToHeight">
-    <FrameLayout
+    android:layout_height="wrap_content">
+    <view
+        class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
-</view>
\ No newline at end of file
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/detail_contact_photo_shadow_height"
+        ex:ratio="0.5"
+        ex:direction="widthToHeight">
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+    </view>
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/detail_header_contact_without_updates.xml b/res/layout/detail_header_contact_without_updates.xml
index 2de7711..7e5037e 100644
--- a/res/layout/detail_header_contact_without_updates.xml
+++ b/res/layout/detail_header_contact_without_updates.xml
@@ -18,17 +18,29 @@
   This is a header entry in the contact details list for when the contact does not have social
   updates, which means that the contact's photo will scroll with the list of details.
 -->
-<view
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
-    class="com.android.contacts.widget.ProportionalLayout"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    ex:ratio="0.5"
-    ex:direction="widthToHeight">
-    <ImageView
-        android:id="@+id/photo"
-        android:scaleType="centerCrop"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <!-- Contact photo -->
+    <view
+        class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-</view>
\ No newline at end of file
+        android:layout_height="wrap_content"
+        ex:ratio="0.5"
+        ex:direction="widthToHeight">
+
+        <include layout="@layout/photo_selector_view" />
+
+    </view>
+
+    <!-- Shadow -->
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/detail_contact_photo_shadow_height"
+        android:background="?android:attr/windowContentOverlay"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialpad.xml b/res/layout/dialpad.xml
index 45f40f6..54b7955 100644
--- a/res/layout/dialpad.xml
+++ b/res/layout/dialpad.xml
@@ -31,56 +31,68 @@
     <TableRow
          android:layout_height="0px"
          android:layout_weight="1">
-        <ImageButton android:id="@+id/one" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_1"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/one" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_1_wht"
             android:contentDescription="@string/description_image_button_one" />
-        <ImageButton android:id="@+id/two" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_2"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/two" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_2_wht"
             android:contentDescription="@string/description_image_button_two" />
-        <ImageButton android:id="@+id/three" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_3"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/three" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_3_wht"
             android:contentDescription="@string/description_image_button_three" />
     </TableRow>
 
     <TableRow
          android:layout_height="0px"
          android:layout_weight="1">
-        <ImageButton android:id="@+id/four" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_4"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/four" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_4_wht"
             android:contentDescription="@string/description_image_button_four" />
-        <ImageButton android:id="@+id/five" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_5"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/five" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_5_wht"
             android:contentDescription="@string/description_image_button_five" />
-        <ImageButton android:id="@+id/six" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_6"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/six" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_6_wht"
             android:contentDescription="@string/description_image_button_six" />
     </TableRow>
 
     <TableRow
          android:layout_height="0px"
          android:layout_weight="1">
-        <ImageButton android:id="@+id/seven" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_7"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/seven" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_7_wht"
             android:contentDescription="@string/description_image_button_seven" />
-        <ImageButton android:id="@+id/eight" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_8"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/eight" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_8_wht"
             android:contentDescription="@string/description_image_button_eight" />
-        <ImageButton android:id="@+id/nine" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_9"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/nine" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_9_wht"
             android:contentDescription="@string/description_image_button_nine" />
     </TableRow>
 
     <TableRow
          android:layout_height="0px"
          android:layout_weight="1">
-        <ImageButton android:id="@+id/star" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_star"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/star" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_star_wht"
             android:contentDescription="@string/description_image_button_star" />
-        <ImageButton android:id="@+id/zero" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_0"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/zero" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_0_wht"
             android:contentDescription="@string/description_image_button_zero" />
-        <ImageButton android:id="@+id/pound" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_pound"
+        <com.android.contacts.dialpad.DialpadImageButton
+            android:id="@+id/pound" style="@style/DialtactsDialpadButtonStyle"
+            android:src="@drawable/dial_num_pound_wht"
             android:contentDescription="@string/description_image_button_pound" />
     </TableRow>
 </TableLayout>
diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml
index df13372..796eb28 100644
--- a/res/layout/dialpad_fragment.xml
+++ b/res/layout/dialpad_fragment.xml
@@ -64,27 +64,18 @@
        android:layout_height="@dimen/dialpad_vertical_margin"
        android:background="#66000000"/>
 
-    <LinearLayout
+    <!-- left and right paddings will be modified by the code. See DialpadFragment. -->
+    <FrameLayout
         android:id="@+id/dialButtonContainer"
         android:layout_width="match_parent"
         android:layout_height="0px"
         android:layout_weight="@integer/dialpad_layout_weight_additional_buttons"
         android:layout_gravity="center_horizontal"
         android:background="@drawable/dialpad_background">
-        <ImageButton
-            android:id="@+id/searchButton"
-            android:layout_width="wrap_content"
-            android:layout_height="?android:attr/actionBarSize"
-            android:layout_gravity="bottom|center_horizontal"
-            android:state_enabled="false"
-            android:background="?android:attr/selectableItemBackground"
-            android:contentDescription="@string/description_search_button"
-            android:src="@drawable/ic_dial_action_search"/>
 
         <ImageButton
             android:id="@+id/dialButton"
-            android:layout_width="0px"
-            android:layout_weight="1"
+            android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="center"
             android:state_enabled="false"
@@ -92,16 +83,7 @@
             android:contentDescription="@string/description_dial_button"
             android:src="@drawable/ic_dial_action_call" />
 
-        <ImageButton
-            android:id="@+id/overflow_menu"
-            android:layout_width="wrap_content"
-            android:layout_height="?android:attr/actionBarSize"
-            android:layout_gravity="bottom|center_horizontal"
-            android:src="@drawable/ic_menu_overflow"
-            android:contentDescription="@*android:string/action_menu_overflow_description"
-            android:nextFocusLeft="@id/digits"
-            android:background="?android:attr/selectableItemBackground"/>
-    </LinearLayout>
+    </FrameLayout>
 
     <!-- "Dialpad chooser" UI, shown only when the user brings up the
          Dialer while a call is already in progress.
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
index d1af632..35fa00f 100644
--- a/res/layout/dialtacts_activity.xml
+++ b/res/layout/dialtacts_activity.xml
@@ -20,8 +20,28 @@
     android:layout_marginTop="?android:attr/actionBarSize"
     android:id="@+id/dialtacts_frame"
     >
-    <com.android.contacts.activities.DialtactsViewPager
+    <android.support.v4.view.ViewPager
         android:id="@+id/pager"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
+
+    <ImageButton
+         android:id="@+id/searchButton"
+         android:layout_width="wrap_content"
+         android:layout_height="?android:attr/actionBarSize"
+         android:layout_gravity="bottom|left"
+         android:state_enabled="false"
+         android:background="?android:attr/selectableItemBackground"
+         android:contentDescription="@string/description_search_button"
+         android:src="@drawable/ic_dial_action_search"/>
+
+    <ImageButton
+         android:id="@+id/overflow_menu"
+         android:layout_width="wrap_content"
+         android:layout_height="?android:attr/actionBarSize"
+         android:layout_gravity="bottom|right"
+         android:src="@drawable/ic_menu_overflow"
+         android:contentDescription="@string/action_menu_overflow_description"
+         android:nextFocusLeft="@id/digits"
+         android:background="?android:attr/selectableItemBackground"/>
 </FrameLayout>
diff --git a/res/layout/directory_header.xml b/res/layout/directory_header.xml
index a2adf48..fcd255e 100644
--- a/res/layout/directory_header.xml
+++ b/res/layout/directory_header.xml
@@ -15,50 +15,53 @@
 -->
 
 <!-- Layout used for list section separators. -->
-<RelativeLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     style="@style/DirectoryHeader"
+    android:id="@+id/directory_header"
+    android:paddingLeft="?attr/list_item_padding_left"
+    android:paddingRight="?attr/list_item_padding_right"
+    android:minHeight="@dimen/list_section_divider_min_height"
+    android:layout_marginTop="@dimen/list_header_extra_top_padding"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="@dimen/list_section_divider_min_height"
-    android:background="@drawable/list_section_divider_holo_custom"
-    android:paddingTop="@dimen/contact_browser_list_top_margin"
-    android:paddingLeft="?attr/list_item_padding_left"
-    android:paddingRight="?attr/list_item_padding_right">
-    <TextView
-        android:id="@+id/label"
-        android:layout_width="wrap_content"
+    >
+    <LinearLayout
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"
-        android:layout_centerVertical="true"
-        android:layout_marginLeft="8dip"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="@color/people_app_theme_color"
-        android:singleLine="true"
-        android:textStyle="bold"
-        android:textAllCaps="true" />
-    <TextView
-        android:id="@+id/count"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_alignBaseline="@id/label"
-        android:singleLine="true"
-        android:textSize="12sp"
-        android:textColor="@color/contact_count_text_color" />
-    <TextView
-        android:id="@+id/display_name"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toRightOf="@id/label"
-        android:layout_toLeftOf="@id/count"
-        android:layout_alignBaseline="@id/label"
-        android:layout_marginLeft="8dip"
-        android:layout_marginRight="8dip"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="@color/people_app_theme_color"
-        android:singleLine="true"
-        android:textStyle="bold"
-        android:textAllCaps="true" />
-</RelativeLayout>
+        android:gravity="center_vertical"
+        android:background="@drawable/list_section_divider_holo_custom"
+        >
+        <TextView
+            android:id="@+id/label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="8dip"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="@color/people_app_theme_color"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:textAllCaps="true" />
+        <TextView
+            android:id="@+id/display_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="8dip"
+            android:layout_marginRight="8dip"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="@color/people_app_theme_color"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:textAllCaps="true" />
+        <TextView
+            android:id="@+id/count"
+            android:paddingTop="1dip"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="right"
+            android:singleLine="true"
+            android:textSize="12sp"
+            android:textColor="@color/contact_count_text_color" />
+    </LinearLayout>
+</FrameLayout>
diff --git a/res/layout/edit_add_field.xml b/res/layout/edit_add_field.xml
index 0b62ac1..ea334da 100644
--- a/res/layout/edit_add_field.xml
+++ b/res/layout/edit_add_field.xml
@@ -17,7 +17,7 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="40dip"
+    android:minHeight="48dip"
     android:paddingLeft="@dimen/editor_add_field_label_left_padding"
     android:background="?android:attr/selectableItemBackground">
     <TextView
diff --git a/res/layout/group_account_header_horizontal.xml b/res/layout/group_account_header_horizontal.xml
new file mode 100644
index 0000000..5043f25
--- /dev/null
+++ b/res/layout/group_account_header_horizontal.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?attr/list_item_header_height"
+    android:layout_marginLeft="?attr/list_item_padding_left"
+    android:layout_marginRight="?attr/list_item_padding_right"
+    android:background="@drawable/list_section_divider_holo_custom"
+    android:orientation="horizontal">
+
+    <TextView
+        android:id="@+id/account_type"
+        android:layout_width="0px"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:paddingLeft="?attr/list_item_header_text_indent"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textColor="@color/people_app_theme_color"
+        android:textStyle="bold"
+        android:textAllCaps="true"
+        android:singleLine="true"/>
+
+    <!-- TODO: Should use correct color with a correct name (content should be same).
+         can use "?android:attr/textColorTertiary" -->
+    <TextView
+        android:id="@+id/account_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:textColor="@color/contact_count_text_color"
+        android:textSize="12sp"
+        android:singleLine="true"
+        android:ellipsize="middle" />
+</LinearLayout>
diff --git a/res/layout/group_account_header_vertical.xml b/res/layout/group_account_header_vertical.xml
new file mode 100644
index 0000000..8edbb8b
--- /dev/null
+++ b/res/layout/group_account_header_vertical.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?attr/list_item_header_height"
+    android:layout_marginLeft="?attr/list_item_padding_left"
+    android:layout_marginRight="?attr/list_item_padding_right"
+    android:paddingBottom="4dip"
+    android:background="@drawable/list_section_divider_holo_custom"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/account_type"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:paddingLeft="?attr/list_item_header_text_indent"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textColor="@color/people_app_theme_color"
+        android:textStyle="bold"
+        android:textAllCaps="true"
+        android:singleLine="true"/>
+
+    <!-- TODO: Should use correct color with a correct name (content should be same).
+         can use "?android:attr/textColorTertiary" -->
+    <TextView
+        android:id="@+id/account_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:paddingLeft="?attr/list_item_header_text_indent"
+        android:textColor="@color/contact_count_text_color"
+        android:textSize="12sp"
+        android:singleLine="true"
+        android:ellipsize="middle" />
+</LinearLayout>
diff --git a/res/layout/group_browse_list_account_header.xml b/res/layout/group_browse_list_account_header.xml
index 709c276..7bfbd07 100644
--- a/res/layout/group_browse_list_account_header.xml
+++ b/res/layout/group_browse_list_account_header.xml
@@ -24,41 +24,8 @@
     <View
         android:id="@+id/header_extra_top_padding"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/contact_browser_list_top_margin" />
+        android:layout_height="@dimen/list_header_extra_top_padding" />
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="?attr/list_item_header_height"
-        android:layout_marginLeft="?attr/list_item_padding_left"
-        android:layout_marginRight="?attr/list_item_padding_right"
-        android:background="@drawable/list_section_divider_holo_custom"
-        android:orientation="horizontal">
-
-        <TextView
-            android:id="@+id/account_type"
-            android:layout_width="0px"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_gravity="center_vertical"
-            android:paddingLeft="?attr/list_item_header_text_indent"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="@color/people_app_theme_color"
-            android:textStyle="bold"
-            android:textAllCaps="true"
-            android:singleLine="true"/>
-
-        <!-- TODO: Shold use correct color with a correct name (content should be same).
-             can use "?android:attr/textColorTertiary" -->
-        <TextView
-            android:id="@+id/account_name"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:textColor="@color/contact_count_text_color"
-            android:textSize="12sp"
-            android:singleLine="true"
-            android:ellipsize="middle" />
-    </LinearLayout>
+    <include layout="@layout/group_account_header_horizontal" />
 
 </LinearLayout>
diff --git a/res/layout/group_browse_list_item.xml b/res/layout/group_browse_list_item.xml
index 45f444f..42bd8eb 100644
--- a/res/layout/group_browse_list_item.xml
+++ b/res/layout/group_browse_list_item.xml
@@ -47,43 +47,33 @@
         layout="@layout/group_browse_list_account_header"
         android:visibility="gone" />
 
-    <RelativeLayout
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:paddingTop="8dip"
         android:paddingLeft="8dip"
         android:paddingBottom="8dip"
+        android:orientation="vertical"
         android:duplicateParentState="true"
-        android:background="@drawable/group_list_item_background"
-        >
+        android:background="@drawable/group_list_item_background">
 
-        <LinearLayout
-            android:layout_width="match_parent"
+        <TextView
+            android:id="@+id/label"
             android:layout_height="wrap_content"
-            android:layout_marginRight="?attr/list_item_padding_right"
-            android:orientation="vertical"
-            android:layout_toLeftOf="@+id/icons"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true">
+            android:layout_width="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:ellipsize="end"
+            android:singleLine="true" />
 
-            <TextView
-                android:id="@+id/label"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:ellipsize="end"
-                android:singleLine="true" />
+        <TextView
+            android:id="@+id/count"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorSecondary"
+            android:ellipsize="end"
+            android:singleLine="true" />
 
-            <TextView
-                android:id="@+id/count"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?android:attr/textColorSecondary"
-                android:ellipsize="end"
-                android:singleLine="true" />
-
-        </LinearLayout>
-    </RelativeLayout>
+    </LinearLayout>
 </LinearLayout>
 
diff --git a/res/layout/item_group_membership.xml b/res/layout/item_group_membership.xml
index 47f99b2..91480cc 100644
--- a/res/layout/item_group_membership.xml
+++ b/res/layout/item_group_membership.xml
@@ -16,6 +16,7 @@
 
 <com.android.contacts.editor.GroupMembershipView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/group_membership_view"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical">
diff --git a/res/layout/item_photo_editor.xml b/res/layout/item_photo_editor.xml
index a22a535..b1af745 100644
--- a/res/layout/item_photo_editor.xml
+++ b/res/layout/item_photo_editor.xml
@@ -17,25 +17,38 @@
 <view
     class="com.android.contacts.editor.PhotoEditorView"
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="48dip"
-    android:layout_height="48dip"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
     >
+    <FrameLayout
+        android:layout_width="48dip"
+        android:layout_height="48dip"
+    >
+        <ImageView
+            android:id="@+id/photo"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_contact_picture_holo_light"
+            android:cropToPadding="true"
+            android:scaleType="centerCrop"
+            android:gravity="left"
+        />
+        <View
+            android:id="@+id/frame"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clickable="true"
+            android:focusable="true"
+            android:contentDescription="@string/description_contact_photo"
+            android:background="?android:attr/selectableItemBackground"
+        />
+    </FrameLayout>
     <ImageView
-        android:id="@+id/photo"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:src="@drawable/ic_contact_picture_holo_light"
-        android:cropToPadding="true"
-        android:scaleType="centerCrop"
-        android:gravity="left"
-    />
-    <View
-        android:id="@+id/frame"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clickable="true"
-        android:focusable="true"
-        android:contentDescription="@string/description_contact_photo"
-        android:background="?android:attr/selectableItemBackground"
+        android:id="@+id/photo_triangle_affordance"
+        android:src="@drawable/account_spinner_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
     />
 </view>
diff --git a/res/layout/join_contact_picker.xml b/res/layout/join_contact_picker.xml
index ea0deaf..ee30525 100644
--- a/res/layout/join_contact_picker.xml
+++ b/res/layout/join_contact_picker.xml
@@ -14,23 +14,13 @@
      limitations under the License.
 -->
 
-<view
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<view xmlns:android="http://schemas.android.com/apk/res/android"
     class="com.android.contacts.widget.FullHeightLinearLayout"
     style="@style/ContactPickerLayout"
     android:orientation="vertical">
-
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="0dip"
         android:layout_weight="1"
         android:id="@+id/list_container" />
-
-    <View
-        android:id="@+id/divider"
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:layout_marginLeft="?attr/contact_browser_list_padding_left"
-        android:layout_marginRight="?attr/contact_browser_list_padding_right"
-        android:background="?android:attr/dividerHorizontal" />
 </view>
diff --git a/res/layout/organization_editor_view_switcher.xml b/res/layout/organization_editor_view_switcher.xml
index 810634c..a0085b2 100644
--- a/res/layout/organization_editor_view_switcher.xml
+++ b/res/layout/organization_editor_view_switcher.xml
@@ -22,20 +22,18 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="40dip"
-    android:background="?android:attr/selectableItemBackground">
+    android:layout_height="wrap_content">
 
     <TextView
         android:id="@+id/add_organization_button"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="48dip"
         android:paddingLeft="@dimen/editor_add_field_label_left_padding"
         android:paddingRight="16dip"
-        android:layout_gravity="center_vertical"
-        android:duplicateParentState="true"
+        android:gravity="center_vertical"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorSecondary"
+        android:background="?android:attr/selectableItemBackground"
         android:text="@string/add_organization"/>
 
     <!-- This is later populated with the actual editable text fields for "organization" -->
diff --git a/res/layout/people_navigation_item.xml b/res/layout/people_navigation_item.xml
new file mode 100644
index 0000000..b7d86d2
--- /dev/null
+++ b/res/layout/people_navigation_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!-- This is the text view layout that is shown in the spinner for the navigation drop down menu on
+     tablet devices.  The text appearance is governed via two styles:
+     PeopleNavigationDropDownHeaderTextAppearance - text appearance of the item in the header part
+         of navigation drop down list of the action bar.
+     PeopleNavigationDropDownTextAppearance - text appearance of the item in the drop down part of
+         the navigation drop down list of the action bar. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center_vertical"
+    android:paddingLeft="18dip"
+    android:paddingRight="18dip"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+/>
diff --git a/res/layout/phone_contact_tile_list.xml b/res/layout/phone_contact_tile_list.xml
index 29ceb19..57dd66c 100644
--- a/res/layout/phone_contact_tile_list.xml
+++ b/res/layout/phone_contact_tile_list.xml
@@ -39,7 +39,7 @@
             android:id="@+id/contact_tile_list_empty"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="center_horizontal"
+            android:gravity="center"
             android:layout_marginTop="@dimen/empty_message_top_margin"
             android:textColor="?android:attr/textColorSecondary"
             android:textAppearance="?android:attr/textAppearanceLarge"/>
diff --git a/res/layout/phone_loading_contacts.xml b/res/layout/phone_loading_contacts.xml
new file mode 100644
index 0000000..f0d3328
--- /dev/null
+++ b/res/layout/phone_loading_contacts.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!-- "Loading" text with a spinner, which is used in PhoneFavorite screen -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:orientation="horizontal"
+    android:gravity="left|center_vertical">
+
+    <ProgressBar
+        android:indeterminate="true"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/progress_spinner"/>
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/contact_list_loading"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:layout_marginLeft="4dip" />
+
+</LinearLayout>
diff --git a/res/layout/photo_selector_view.xml b/res/layout/photo_selector_view.xml
new file mode 100644
index 0000000..0006559
--- /dev/null
+++ b/res/layout/photo_selector_view.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!--
+  View for displaying photos that show a photo selector when clicked.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/photo"
+        android:scaleType="centerCrop"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <View
+        android:id="@+id/photo_touch_intercept_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="?android:attr/selectableItemBackground"
+        android:visibility="gone" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/favorites_star.xml b/res/layout/photoselection_activity.xml
similarity index 65%
rename from res/layout/favorites_star.xml
rename to res/layout/photoselection_activity.xml
index 2ac3039..e7ef901 100644
--- a/res/layout/favorites_star.xml
+++ b/res/layout/photoselection_activity.xml
@@ -13,21 +13,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:paddingLeft="10dip"
-    android:paddingRight="10dip">
-
-    <CheckBox
-        android:id="@+id/star"
-        android:duplicateParentState="true"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <View
+        android:id="@+id/backdrop"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#000000" />
+    <view
+        android:id="@+id/photo"
+        class="com.android.contacts.detail.TransformableImageView"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:contentDescription="@string/description_star"
-        android:visibility="invisible"
-        android:button="@drawable/btn_star_holo_dark"/>
-</FrameLayout>
+        android:scaleType="centerCrop" />
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/quickcontact_list_fragment.xml b/res/layout/quickcontact_list_fragment.xml
index 5ade104..e542f7a 100755
--- a/res/layout/quickcontact_list_fragment.xml
+++ b/res/layout/quickcontact_list_fragment.xml
@@ -14,28 +14,19 @@
      limitations under the License.
 -->
 
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
-    <!-- Line that looks like a list divider -->
-    <View
+    <ListView
+        android:id="@+id/list"
         android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:background="@color/quickcontact_list_divider" />
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-        <ListView
-            android:id="@+id/list"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:divider="@drawable/quickcontact_list_item_divider"
-            android:dividerHeight="1dip"
-            android:background="@color/quickcontact_list_background"
-            android:cacheColorHint="@null"
-            android:layout_alignParentTop="true" />
-        <include layout="@layout/quickcontact_list_fragment_bottom"/>
-    </RelativeLayout>
-</LinearLayout>
+        android:layout_height="wrap_content"
+        android:divider="@drawable/quickcontact_list_item_divider"
+        android:dividerHeight="1dip"
+        android:background="@color/quickcontact_list_background"
+        android:cacheColorHint="@null"
+        android:layout_alignParentTop="true"
+    />
+    <include layout="@layout/quickcontact_list_fragment_bottom"/>
+</RelativeLayout>
diff --git a/res/layout/quickcontact_list_item.xml b/res/layout/quickcontact_list_item.xml
index ee3a89f..1b66ec3 100755
--- a/res/layout/quickcontact_list_item.xml
+++ b/res/layout/quickcontact_list_item.xml
@@ -27,13 +27,27 @@
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:singleLine="true"
             android:ellipsize="end" />
-        <TextView
-            android:id="@android:id/text2"
+        <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textColor="@color/secondary_text_color"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceSmall" />
+            android:orientation="horizontal">
+            <ImageView
+                android:id="@+id/presence_icon"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="1dip"
+                android:layout_marginRight="4dip"
+                android:layout_gravity="center_vertical"
+                android:gravity="center"
+                android:scaleType="centerInside" />
+            <TextView
+                android:id="@android:id/text2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textColor="@color/secondary_text_color"
+                android:textAllCaps="true"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+        </LinearLayout>
     </LinearLayout>
     <include layout="@layout/quickcontact_list_item_base"/>
 </LinearLayout>
diff --git a/res/layout/quickcontact_list_item_address.xml b/res/layout/quickcontact_list_item_address.xml
index 9773b10..cb99673 100755
--- a/res/layout/quickcontact_list_item_address.xml
+++ b/res/layout/quickcontact_list_item_address.xml
@@ -28,13 +28,27 @@
             android:layout_height="wrap_content"
             android:textColor="@color/primary_text_color"
             android:textAppearance="?android:attr/textAppearanceMedium" />
-        <TextView
-            android:id="@android:id/text2"
+        <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textColor="@color/secondary_text_color"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceSmall" />
+            android:orientation="horizontal">
+            <ImageView
+                android:id="@+id/presence_icon"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="1dip"
+                android:layout_marginRight="4dip"
+                android:layout_gravity="center_vertical"
+                android:gravity="center"
+                android:scaleType="centerInside" />
+            <TextView
+                android:id="@android:id/text2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textColor="@color/secondary_text_color"
+                android:textAllCaps="true"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+        </LinearLayout>
     </LinearLayout>
     <include layout="@layout/quickcontact_list_item_base"/>
 </LinearLayout>
diff --git a/res/layout/quickcontact_list_item_base.xml b/res/layout/quickcontact_list_item_base.xml
index 329df78..bc60396 100644
--- a/res/layout/quickcontact_list_item_base.xml
+++ b/res/layout/quickcontact_list_item_base.xml
@@ -33,7 +33,6 @@
         android:duplicateParentState="false"
         android:nextFocusLeft="@id/actions_view_container"/>
     <View
-        android:id="@+id/vertical_divider"
         android:layout_width="1dip"
         android:layout_height="match_parent"
         android:layout_gravity="center_vertical"
diff --git a/res/layout/quickcontact_track.xml b/res/layout/quickcontact_track.xml
index bf25cb3..3df7af0 100644
--- a/res/layout/quickcontact_track.xml
+++ b/res/layout/quickcontact_track.xml
@@ -23,7 +23,7 @@
         android:background="@drawable/quickcontact_track_background"
         android:scrollbars="none">
         <RelativeLayout
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content">
             <LinearLayout
                 android:id="@+id/track"
diff --git a/res/layout/raw_contact_editor_view.xml b/res/layout/raw_contact_editor_view.xml
index 5180557..c8aa9da 100644
--- a/res/layout/raw_contact_editor_view.xml
+++ b/res/layout/raw_contact_editor_view.xml
@@ -52,24 +52,10 @@
 
             </LinearLayout>
 
-            <LinearLayout
-                android:id="@+id/stub_photo"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+            <include
+                android:id="@+id/edit_photo"
                 android:layout_marginRight="8dip"
-                android:orientation="horizontal">
-
-                <include
-                    android:id="@+id/edit_photo"
-                    layout="@layout/item_photo_editor" />
-
-                <ImageView
-                    android:src="@drawable/account_spinner_icon"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="bottom" />
-
-            </LinearLayout>
+                layout="@layout/item_photo_editor" />
 
         </LinearLayout>
 
@@ -77,7 +63,8 @@
             android:id="@+id/sect_fields"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical"/>
+            android:orientation="vertical"
+            android:layout_marginBottom="16dip"/>
 
         <Button
             android:id="@+id/button_add_field"
@@ -85,7 +72,6 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
-            android:layout_marginTop="16dip"
             android:layout_marginBottom="32dip"/>
 
     </LinearLayout>
diff --git a/res/layout/raw_contact_readonly_editor_view.xml b/res/layout/raw_contact_readonly_editor_view.xml
index aa7d705..998d392 100644
--- a/res/layout/raw_contact_readonly_editor_view.xml
+++ b/res/layout/raw_contact_readonly_editor_view.xml
@@ -42,24 +42,10 @@
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:textColor="?android:attr/textColorSecondary" />
 
-        <LinearLayout
-            android:id="@+id/stub_photo"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+        <include
+            android:id="@+id/edit_photo"
             android:layout_marginRight="8dip"
-            android:orientation="horizontal">
-
-            <include
-                android:id="@+id/edit_photo"
-                layout="@layout/item_photo_editor" />
-
-            <ImageView
-                android:src="@drawable/account_spinner_icon"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="bottom" />
-
-        </LinearLayout>
+            layout="@layout/item_photo_editor" />
 
     </LinearLayout>
 
diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml
deleted file mode 100644
index 7dfd8ec..0000000
--- a/res/layout/search_bar.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/search_bar"
-    android:layout_width="match_parent"
-    android:layout_height="64dip"
-    android:orientation="vertical"
-    android:focusable="true"
-    android:descendantFocusability="afterDescendants"
-    android:background="@drawable/bg_blk_search_contact">
-
-    <!-- Outer layout defines the entire search bar at the top of the screen -->
-    <LinearLayout
-        android:id="@+id/search_plate"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingLeft="4dip"
-        android:paddingRight="10dip"
-        android:paddingTop="6dip"
-        android:paddingBottom="0dip"        
-        >
-
-        <!-- Inner layout contains the app icon, button(s) and EditText -->
-        <LinearLayout
-            android:id="@+id/search_edit_frame"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal">
-
-            <ImageView 
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content" 
-                android:src="@mipmap/ic_launcher_contacts"
-                android:layout_marginRight="7dip"
-                android:layout_gravity="center_vertical"
-                android:scaleType="centerInside" />
-              
-            <view
-                class="com.android.contacts.widget.SearchEditText"
-                android:id="@+id/search_src_text"
-                android:layout_height="wrap_content"
-                android:layout_width="0dip"
-                android:layout_weight="1.0"
-                android:layout_marginLeft="4dip"
-                android:layout_marginBottom="0dip"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:inputType="textNoSuggestions"
-                android:imeOptions="flagNoExtractUi"
-                android:hint="@string/search_bar_hint"
-                android:drawableRight="@drawable/magnifying_glass"
-                android:freezesText="true"
-            />
-        </LinearLayout>
-        
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/search_header.xml b/res/layout/search_header.xml
index b1ba00f..6907a62 100644
--- a/res/layout/search_header.xml
+++ b/res/layout/search_header.xml
@@ -14,28 +14,13 @@
      limitations under the License.
 -->
 
-<RelativeLayout
+<TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
+    android:id="@+id/totalContactsText"
     android:minHeight="@dimen/contact_filter_header_min_height"
-    android:background="@android:color/transparent">
-    <TextView
-        android:id="@+id/totalContactsText"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_alignParentLeft="true"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/textColorSecondary" />
-
-    <ProgressBar
-        android:id="@+id/progress"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toRightOf="@id/totalContactsText"
-        style="?android:attr/progressBarStyleSmall"
-        android:layout_alignParentRight="true"
-        android:layout_centerVertical="true" />
-
-</RelativeLayout>
+    android:paddingTop="24dip"
+    android:gravity="center_horizontal"
+    android:textAppearance="?android:attr/textAppearanceLarge"
+    android:textColor="?android:attr/textColorSecondary" />
diff --git a/res/layout/stream_item_container.xml b/res/layout/stream_item_container.xml
index de4f87d..c5d2c0e 100644
--- a/res/layout/stream_item_container.xml
+++ b/res/layout/stream_item_container.xml
@@ -21,6 +21,7 @@
     android:paddingLeft="@dimen/detail_update_section_side_padding"
     android:paddingRight="@dimen/detail_update_section_side_padding">
 
+    <!-- Clickable area -->
     <LinearLayout
         android:id="@+id/stream_item_content"
         android:layout_width="match_parent"
@@ -30,9 +31,52 @@
         android:paddingTop="@dimen/detail_update_section_item_vertical_padding"
         android:paddingBottom="@dimen/detail_update_section_item_vertical_padding"
         android:background="?android:attr/selectableItemBackground"
-        android:layout_gravity="center_vertical"
         android:orientation="vertical"
-        />
+        >
+
+        <!-- Images -->
+        <LinearLayout
+            android:id="@+id/stream_item_image_rows"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="@dimen/detail_update_section_between_items_vertical_padding"
+            android:layout_gravity="center_vertical"
+            android:orientation="vertical"
+            >
+        </LinearLayout>
+
+        <!-- Text -->
+        <TextView android:id="@+id/stream_item_html"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="16sp"
+            android:textColor="?android:attr/textColorPrimary" />
+        <!--
+        Attribution (e.g. timestamp) and comments (e.g. +1, like) should align horizontally.
+        Can't merge this with the parent list view.
+        -->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            >
+            <TextView android:id="@+id/stream_item_attribution"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorSecondary"
+                android:ellipsize="end"
+                android:maxLines="1" />
+            <TextView android:id="@+id/stream_item_comments"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft=
+                    "@dimen/detail_update_section_attribution_comments_padding"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorSecondary"
+                android:maxLines="1"/>
+        </LinearLayout>
+    </LinearLayout>
 
     <View
         android:id="@+id/horizontal_divider"
diff --git a/res/layout/stream_item_photo.xml b/res/layout/stream_item_photo.xml
index 1fc3d0b..2649828 100644
--- a/res/layout/stream_item_photo.xml
+++ b/res/layout/stream_item_photo.xml
@@ -15,7 +15,7 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
-    <ImageView
+    <com.android.contacts.widget.LayoutSuppressingImageView
         android:id="@+id/image"
         android:layout_width="match_parent"
         android:layout_height="match_parent"/>
diff --git a/res/layout/stream_item_row_two_images.xml b/res/layout/stream_item_row_images.xml
similarity index 97%
rename from res/layout/stream_item_row_two_images.xml
rename to res/layout/stream_item_row_images.xml
index 7858f6f..46e1f4f 100644
--- a/res/layout/stream_item_row_two_images.xml
+++ b/res/layout/stream_item_row_images.xml
@@ -37,6 +37,7 @@
     </view>
 
     <view
+        android:id="@+id/second_image_container"
         class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="0dip"
         android:layout_height="wrap_content"
diff --git a/res/layout/stream_item_row_one_image.xml b/res/layout/stream_item_row_one_image.xml
deleted file mode 100644
index 03dcedf..0000000
--- a/res/layout/stream_item_row_one_image.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginTop="@dimen/detail_update_section_between_items_padding"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:weightSum="2">
-
-        <view
-            class="com.android.contacts.widget.ProportionalLayout"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_marginRight="@dimen/detail_update_section_between_items_padding"
-            ex:ratio="1"
-            ex:direction="widthToHeight">
-
-            <include
-                android:id="@+id/stream_item_first_image"
-                layout="@layout/stream_item_photo"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"/>
-
-        </view>
-
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/stream_item_row_text.xml b/res/layout/stream_item_row_text.xml
deleted file mode 100644
index 919ee52..0000000
--- a/res/layout/stream_item_row_text.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <TextView android:id="@+id/stream_item_html"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="16sp"
-        android:textColor="?android:attr/textColorPrimary" />
-
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <TextView android:id="@+id/stream_item_attribution"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="?android:attr/textColorSecondary"
-            android:ellipsize="end"
-            android:maxLines="1" />
-        <TextView android:id="@+id/stream_item_comments"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="@dimen/detail_update_section_attribution_comments_padding"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="?android:attr/textColorSecondary"
-            android:maxLines="1"/>
-
-    </LinearLayout>
-</LinearLayout>
diff --git a/res/layout/tab_left_arrow.xml b/res/layout/tab_left_arrow.xml
deleted file mode 100644
index 0ed2e57..0000000
--- a/res/layout/tab_left_arrow.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/arrow"
-    android:layout_width="32dip"
-    android:layout_height="37dip"
-    android:layout_alignParentLeft="true"
-    android:layout_alignParentTop="true"
-    android:layout_weight="1"
-    android:background="@drawable/tab_indicator_bg"
-    android:scaleType="centerInside"
-    android:src="@drawable/tab_left_arrow"
-    />
diff --git a/res/layout/tab_right_arrow.xml b/res/layout/tab_right_arrow.xml
deleted file mode 100644
index de69d8e..0000000
--- a/res/layout/tab_right_arrow.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/arrow"
-    android:layout_width="32dip"
-    android:layout_height="37dip"
-    android:layout_alignParentRight="true"
-    android:layout_alignParentTop="true"
-    android:layout_weight="1"
-    android:background="@drawable/tab_indicator_bg"
-    android:scaleType="centerInside"
-    android:src="@drawable/tab_right_arrow"
-    />
diff --git a/res/layout/updates_header_contact.xml b/res/layout/updates_header_contact.xml
index 774fa7b..bfcd6e0 100644
--- a/res/layout/updates_header_contact.xml
+++ b/res/layout/updates_header_contact.xml
@@ -29,6 +29,7 @@
         class="com.android.contacts.widget.ProportionalLayout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/detail_contact_photo_shadow_height"
         ex:ratio="0.5"
         ex:direction="widthToHeight">
 
diff --git a/res/layout/user_profile_header.xml b/res/layout/user_profile_header.xml
index 6867dea..67b64d5 100644
--- a/res/layout/user_profile_header.xml
+++ b/res/layout/user_profile_header.xml
@@ -17,49 +17,42 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/user_profile_header"
-    android:orientation="vertical"
+    android:orientation="horizontal"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?attr/list_item_header_height"
-    android:paddingTop="@dimen/contact_browser_list_top_margin"
+    android:paddingTop="@dimen/list_header_extra_top_padding"
     android:paddingLeft="?attr/list_item_padding_left"
-    android:paddingRight="?attr/list_item_padding_right" >
+    android:paddingRight="?attr/list_item_padding_right" 
+    android:background="@drawable/list_section_divider_holo_custom"
+    android:minHeight="?attr/list_item_header_height"
+    >
 
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+    <TextView
+        android:id="@+id/profile_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:text="@string/user_profile_contacts_list_header"
+        android:textStyle="bold"
+        android:ellipsize="end"
+        android:layout_gravity="left|bottom"
+        android:layout_marginBottom="2dip"
+        android:layout_weight="1"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:paddingLeft="?attr/list_item_text_indent"
+        android:textColor="@color/people_app_theme_color" />
 
-        <TextView
-            android:id="@+id/profile_title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:text="@string/user_profile_contacts_list_header"
-            android:textStyle="bold"
-            android:ellipsize="end"
-            android:gravity="left|center_vertical"
-            android:layout_weight="1"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:paddingLeft="?attr/list_item_text_indent"
-            android:textColor="@color/people_app_theme_color" />
-
-        <TextView
-            android:id="@+id/contacts_count"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:ellipsize="end"
-            android:layout_gravity="right|center_vertical"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textSize="12sp"
-            android:textColor="@color/contact_count_text_color" />
-    </LinearLayout>
-
-    <View
-        android:background="@color/people_app_theme_color"
-        android:layout_width="match_parent"
-        android:layout_height="?attr/list_item_header_underline_height" />
+    <TextView
+        android:id="@+id/contacts_count"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:layout_gravity="right|bottom"
+        android:layout_marginBottom="2dip"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textSize="12sp"
+        android:textColor="@color/contact_count_text_color" />
 
 </LinearLayout>
diff --git a/res/menu-sw580dp-w720dp/actions.xml b/res/menu-sw580dp-w720dp/actions.xml
deleted file mode 100644
index 8735d89..0000000
--- a/res/menu-sw580dp-w720dp/actions.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:id="@+id/menu_search"
-        android:icon="@drawable/ic_ab_search_holo_dark"
-        android:title="@string/menu_search"
-        android:showAsAction="always" />
-
-    <item
-        android:id="@+id/menu_add_contact"
-        android:icon="@drawable/ic_add_contact_holo_dark"
-        android:title="@string/menu_new_contact_action_bar"
-        android:showAsAction="always" />
-
-    <item
-        android:id="@+id/menu_custom_add_group"
-        android:icon="@drawable/ic_add_group_holo_dark"
-        android:title="@string/menu_new_group_action_bar"
-        android:showAsAction="always" />
-
-    <item
-        android:id="@+id/menu_contacts_filter"
-        android:icon="@drawable/ic_menu_settings_holo_light"
-        android:orderInCategory="1"
-        android:title="@string/menu_contacts_filter" />
-
-    <item
-        android:id="@+id/menu_import_export"
-        android:icon="@drawable/ic_menu_import_export_holo_light"
-        android:orderInCategory="2"
-        android:title="@string/menu_import_export" />
-
-    <item
-        android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
-        android:orderInCategory="3"
-        android:title="@string/menu_accounts" />
-
-    <item
-        android:id="@+id/menu_settings"
-        android:icon="@drawable/ic_menu_settings_holo_light"
-        android:orderInCategory="4"
-        android:title="@string/menu_settings" />
-</menu>
diff --git a/res/menu-sw580dp-w720dp/view_contact.xml b/res/menu-sw580dp-w720dp/view_contact.xml
deleted file mode 100644
index 734e6b2..0000000
--- a/res/menu-sw580dp-w720dp/view_contact.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:id="@+id/menu_edit"
-        android:icon="@drawable/ic_menu_compose_holo_dark"
-        android:title="@string/menu_editContact"
-        android:alphabeticShortcut="e"
-        android:showAsAction="always" />
-
-    <item
-        android:id="@+id/menu_share"
-        android:icon="@drawable/ic_menu_share_holo_light"
-        android:title="@string/menu_share"
-        android:alphabeticShortcut="s" />
-
-    <item
-        android:id="@+id/menu_delete"
-        android:icon="@drawable/ic_menu_trash_holo_light"
-        android:title="@string/menu_deleteContact" />
-
-</menu>
diff --git a/res/menu-sw580dp/actions.xml b/res/menu-sw580dp/people_options.xml
similarity index 81%
rename from res/menu-sw580dp/actions.xml
rename to res/menu-sw580dp/people_options.xml
index 35a9c0a..5d05752 100644
--- a/res/menu-sw580dp/actions.xml
+++ b/res/menu-sw580dp/people_options.xml
@@ -23,12 +23,14 @@
     <item
         android:id="@+id/menu_add_contact"
         android:icon="@drawable/ic_add_contact_holo_dark"
-        android:title="@string/menu_new_contact_action_bar" />
+        android:title="@string/menu_new_contact_action_bar"
+        android:showAsAction="ifRoom" />
 
     <item
         android:id="@+id/menu_add_group"
         android:icon="@drawable/ic_add_group_holo_dark"
-        android:title="@string/menu_new_group_action_bar" />
+        android:title="@string/menu_new_group_action_bar"
+        android:showAsAction="ifRoom" />
 
     <!-- Added orderInCategory to keep the following buttons at the end of the menu
          Buttons will be added in the order added/inflated. Ordered buttons will be added
@@ -37,25 +39,31 @@
     -->
     <item
         android:id="@+id/menu_contacts_filter"
-        android:icon="@drawable/ic_menu_settings_holo_light"
         android:orderInCategory="1"
         android:title="@string/menu_contacts_filter" />
 
     <item
         android:id="@+id/menu_import_export"
-        android:icon="@drawable/ic_menu_import_export_holo_light"
         android:orderInCategory="2"
         android:title="@string/menu_import_export" />
 
     <item
-        android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
+        android:id="@+id/menu_clear_frequents"
         android:orderInCategory="3"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
+        android:id="@+id/menu_accounts"
+        android:orderInCategory="4"
         android:title="@string/menu_accounts" />
 
     <item
         android:id="@+id/menu_settings"
-        android:icon="@drawable/ic_menu_settings_holo_light"
-        android:orderInCategory="4"
+        android:orderInCategory="5"
         android:title="@string/menu_settings" />
+
+    <item
+        android:id="@+id/menu_help"
+        android:orderInCategory="6"
+        android:title="@string/menu_help" />
 </menu>
diff --git a/res/menu-sw580dp/view_contact.xml b/res/menu-sw580dp/view_contact.xml
index 1279601..a2ff00d 100644
--- a/res/menu-sw580dp/view_contact.xml
+++ b/res/menu-sw580dp/view_contact.xml
@@ -19,17 +19,20 @@
         android:id="@+id/menu_edit"
         android:icon="@drawable/ic_menu_compose_holo_dark"
         android:title="@string/menu_editContact"
-        android:alphabeticShortcut="e" />
+        android:alphabeticShortcut="e"
+        android:showAsAction="always"/>
 
     <item
         android:id="@+id/menu_share"
-        android:icon="@drawable/ic_menu_share_holo_light"
         android:title="@string/menu_share"
         android:alphabeticShortcut="s" />
 
     <item
         android:id="@+id/menu_delete"
-        android:icon="@drawable/ic_menu_trash_holo_light"
         android:title="@string/menu_deleteContact" />
 
+    <item
+        android:id="@+id/menu_create_contact_shortcut"
+        android:title="@string/menu_create_contact_shortcut" />
+
 </menu>
diff --git a/res/menu-sw580dp/view_group.xml b/res/menu-sw580dp/view_group.xml
index cd52030..3836c0f 100644
--- a/res/menu-sw580dp/view_group.xml
+++ b/res/menu-sw580dp/view_group.xml
@@ -19,10 +19,10 @@
         android:id="@+id/menu_edit_group"
         android:icon="@drawable/ic_menu_compose_holo_dark"
         android:title="@string/menu_editGroup"
-        android:alphabeticShortcut="e" />
+        android:alphabeticShortcut="e"
+        android:showAsAction="always" />
 
     <item
         android:id="@+id/menu_delete_group"
-        android:icon="@drawable/ic_menu_trash_holo_light"
         android:title="@string/menu_deleteGroup" />
 </menu>
diff --git a/res/layout/empty.xml b/res/menu/call_details_cab.xml
similarity index 67%
rename from res/layout/empty.xml
rename to res/menu/call_details_cab.xml
index 8e70c24..7de675f 100644
--- a/res/layout/empty.xml
+++ b/res/menu/call_details_cab.xml
@@ -1,20 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2012 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.
 -->
-
-<View xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/empty"
-    android:layout_width="0dip"
-    android:layout_height="0dip" />
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/copy_phone_number"
+        android:icon="?android:attr/actionModeCopyDrawable"
+        android:title="@string/menu_copy"
+    />
+</menu>
diff --git a/res/menu/call_details_options.xml b/res/menu/call_details_options.xml
index ed0111b..63ce8f5 100644
--- a/res/menu/call_details_options.xml
+++ b/res/menu/call_details_options.xml
@@ -23,7 +23,6 @@
     />
     <item
         android:id="@+id/menu_remove_from_call_log"
-        android:icon="@android:drawable/ic_menu_close_clear_cancel"
         android:title="@string/recentCalls_removeFromRecentList"
         android:onClick="onMenuRemoveFromCallLog"
     />
diff --git a/res/menu/call_log_options.xml b/res/menu/call_log_options.xml
index 3d0fb6a..c41f9da 100644
--- a/res/menu/call_log_options.xml
+++ b/res/menu/call_log_options.xml
@@ -29,7 +29,6 @@
 
     <item
         android:id="@+id/delete_all"
-        android:icon="@android:drawable/ic_menu_close_clear_cancel"
         android:title="@string/recentCalls_deleteAll"
         android:showAsAction="withText"
         android:orderInCategory="1" />
diff --git a/res/menu/dialpad_options.xml b/res/menu/dialpad_options.xml
index 02b1f7f..6dda8fc 100644
--- a/res/menu/dialpad_options.xml
+++ b/res/menu/dialpad_options.xml
@@ -16,20 +16,17 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:id="@+id/menu_add_contacts"
-        android:icon="@android:drawable/ic_menu_add"
         android:title="@string/recentCalls_addToContact"
         android:showAsAction="withText"
         android:orderInCategory="1" />
     <item
         android:id="@+id/menu_2s_pause"
-        android:icon="@drawable/ic_menu_2sec_pause"
         android:title="@string/add_2sec_pause"
         android:showAsAction="withText"
         android:orderInCategory="1" />
 
     <item
         android:id="@+id/menu_add_wait"
-        android:icon="@drawable/ic_menu_wait"
         android:title="@string/add_wait"
         android:showAsAction="withText"
         android:orderInCategory="1" />
@@ -37,7 +34,6 @@
     <item
         android:id="@+id/menu_call_settings_dialpad"
         android:title="@string/call_settings"
-        android:icon="@drawable/ic_menu_settings_holo_light"
         android:showAsAction="withText"
         android:orderInCategory="1" />
 </menu>
diff --git a/res/menu/dialtacts_options.xml b/res/menu/dialtacts_options.xml
index d8c79e4..8eaa915 100644
--- a/res/menu/dialtacts_options.xml
+++ b/res/menu/dialtacts_options.xml
@@ -16,7 +16,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:id="@+id/search_on_action_bar"
-        android:title="@string/menu_all_contacts"
+        android:title="@string/menu_search"
         android:icon="@drawable/ic_dial_action_search"
         android:showAsAction="ifRoom" />
 
@@ -24,7 +24,6 @@
     <item
         android:id="@+id/menu_call_settings"
         android:title="@string/call_settings"
-        android:icon="@drawable/ic_menu_settings_holo_light"
         android:showAsAction="withText"
         android:orderInCategory="2" />
 
@@ -35,8 +34,9 @@
 
     <item
         android:id="@+id/add_contact"
+        android:icon="@drawable/ic_add_contact_holo_dark"
         android:title="@string/menu_newContact"
-        android:showAsAction="withText" />
+        android:showAsAction="ifRoom" />
 
     <!-- Ugly hack: empty item never clickable.
          This is for forcing search icon on left even when there's a single item
@@ -46,7 +46,7 @@
 
          TODO: look for better idea. -->
     <item
-        android:id="@+id/fake_menu_item"
+        android:id="@+id/empty_right_menu_item"
         android:actionLayout="@layout/empty2"
         android:showAsAction="ifRoom" />
 </menu>
diff --git a/res/menu/edit_contact.xml b/res/menu/edit_contact.xml
index 26b89df..51d9ab0 100644
--- a/res/menu/edit_contact.xml
+++ b/res/menu/edit_contact.xml
@@ -22,16 +22,18 @@
 
     <item
         android:id="@+id/menu_split"
-        android:icon="@drawable/ic_menu_split_holo_light"
         android:title="@string/menu_splitAggregate" />
 
     <item
         android:id="@+id/menu_join"
-        android:icon="@drawable/ic_menu_merge_holo_light"
         android:title="@string/menu_joinAggregate" />
 
     <item
         android:id="@+id/menu_discard"
         android:alphabeticShortcut="q"
         android:title="@string/menu_discard" />
+
+    <item
+        android:id="@+id/menu_help"
+        android:title="@string/menu_help" />
 </menu>
diff --git a/res/menu/list.xml b/res/menu/list.xml
deleted file mode 100644
index 56d92f8..0000000
--- a/res/menu/list.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:id="@+id/menu_search"
-        android:icon="@android:drawable/ic_menu_search"
-        android:title="@string/menu_search" />
-
-    <item
-        android:id="@+id/menu_add"
-        android:icon="@drawable/ic_menu_add_contact_holo_light"
-        android:title="@string/menu_newContact"
-        android:alphabeticShortcut="n" />
-
-    <item
-        android:id="@+id/menu_settings"
-        android:icon="@drawable/ic_menu_settings_holo_light"
-        android:title="@string/menu_settings" />
-
-    <item
-        android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
-        android:title="@string/menu_accounts" />
-
-    <item
-        android:id="@+id/menu_import_export"
-        android:icon="@drawable/ic_menu_import_export_holo_light"
-        android:title="@string/menu_import_export" />
-
-</menu>
diff --git a/res/menu/actions.xml b/res/menu/people_options.xml
similarity index 87%
rename from res/menu/actions.xml
rename to res/menu/people_options.xml
index 9067a46..8c91e88 100644
--- a/res/menu/actions.xml
+++ b/res/menu/people_options.xml
@@ -34,21 +34,25 @@
 
     <item
         android:id="@+id/menu_contacts_filter"
-        android:icon="@drawable/ic_menu_settings_holo_light"
         android:title="@string/menu_contacts_filter" />
 
     <item
         android:id="@+id/menu_import_export"
-        android:icon="@drawable/ic_menu_import_export_holo_light"
         android:title="@string/menu_import_export" />
 
     <item
+        android:id="@+id/menu_clear_frequents"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
         android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
         android:title="@string/menu_accounts" />
 
     <item
         android:id="@+id/menu_settings"
-        android:icon="@drawable/ic_menu_settings_holo_light"
         android:title="@string/menu_settings" />
+
+    <item
+        android:id="@+id/menu_help"
+        android:title="@string/menu_help" />
 </menu>
diff --git a/res/menu-sw580dp-w720dp/view_group.xml b/res/menu/phone_favorite_options.xml
similarity index 66%
rename from res/menu-sw580dp-w720dp/view_group.xml
rename to res/menu/phone_favorite_options.xml
index 1348d84..e37759c 100644
--- a/res/menu-sw580dp-w720dp/view_group.xml
+++ b/res/menu/phone_favorite_options.xml
@@ -13,17 +13,16 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:id="@+id/menu_edit_group"
-        android:icon="@drawable/ic_menu_compose_holo_dark"
-        android:title="@string/menu_editGroup"
-        android:alphabeticShortcut="e"
-        android:showAsAction="always" />
+        android:id="@+id/menu_import_export"
+        android:title="@string/menu_import_export" />
 
     <item
-        android:id="@+id/menu_delete_group"
-        android:icon="@drawable/ic_menu_trash_holo_light"
-        android:title="@string/menu_deleteGroup" />
+        android:id="@+id/menu_clear_frequents"
+        android:title="@string/menu_clear_frequents" />
+
+    <item
+        android:id="@+id/menu_accounts"
+        android:title="@string/menu_accounts" />
 </menu>
diff --git a/res/menu/view_contact.xml b/res/menu/view_contact.xml
index 2ae4806..8c36924 100644
--- a/res/menu/view_contact.xml
+++ b/res/menu/view_contact.xml
@@ -17,28 +17,28 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:id="@+id/menu_edit"
-        android:icon="@drawable/ic_menu_compose_holo_dark"
         android:title="@string/menu_editContact"
         android:alphabeticShortcut="e" />
 
     <item
         android:id="@+id/menu_share"
-        android:icon="@drawable/ic_menu_share_holo_light"
         android:title="@string/menu_share"
         android:alphabeticShortcut="s" />
 
     <item
         android:id="@+id/menu_delete"
-        android:icon="@drawable/ic_menu_trash_holo_light"
         android:title="@string/menu_deleteContact" />
 
     <item
         android:id="@+id/menu_set_ringtone"
-        android:icon="@drawable/ic_menu_mark"
         android:title="@string/menu_set_ring_tone" />
 
     <item
         android:id="@+id/menu_send_to_voicemail"
         android:checkable="true"
         android:title="@string/menu_redirect_calls_to_vm" />
+
+    <item
+        android:id="@+id/menu_create_contact_shortcut"
+        android:title="@string/menu_create_contact_shortcut" />
 </menu>
diff --git a/res/menu/view_group.xml b/res/menu/view_group.xml
index cd52030..669f401 100644
--- a/res/menu/view_group.xml
+++ b/res/menu/view_group.xml
@@ -17,12 +17,10 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:id="@+id/menu_edit_group"
-        android:icon="@drawable/ic_menu_compose_holo_dark"
         android:title="@string/menu_editGroup"
         android:alphabeticShortcut="e" />
 
     <item
         android:id="@+id/menu_delete_group"
-        android:icon="@drawable/ic_menu_trash_holo_light"
         android:title="@string/menu_deleteGroup" />
 </menu>
diff --git a/res/mipmap-hdpi/ic_launcher_contacts.png b/res/mipmap-hdpi/ic_launcher_contacts.png
index fa60a53..e0136f6 100644
--- a/res/mipmap-hdpi/ic_launcher_contacts.png
+++ b/res/mipmap-hdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/res/mipmap-hdpi/ic_launcher_shortcut_contact.png b/res/mipmap-hdpi/ic_launcher_shortcut_contact.png
index c867181..e132cd0 100644
--- a/res/mipmap-hdpi/ic_launcher_shortcut_contact.png
+++ b/res/mipmap-hdpi/ic_launcher_shortcut_contact.png
Binary files differ
diff --git a/res/mipmap-hdpi/ic_launcher_shortcut_directdial.png b/res/mipmap-hdpi/ic_launcher_shortcut_directdial.png
index c515815..f6ec866 100644
--- a/res/mipmap-hdpi/ic_launcher_shortcut_directdial.png
+++ b/res/mipmap-hdpi/ic_launcher_shortcut_directdial.png
Binary files differ
diff --git a/res/mipmap-hdpi/ic_launcher_shortcut_directmessage.png b/res/mipmap-hdpi/ic_launcher_shortcut_directmessage.png
index a347fa1..c8eb467 100644
--- a/res/mipmap-hdpi/ic_launcher_shortcut_directmessage.png
+++ b/res/mipmap-hdpi/ic_launcher_shortcut_directmessage.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_contacts.png b/res/mipmap-mdpi/ic_launcher_contacts.png
index b50d7dd..3d490c3 100644
--- a/res/mipmap-mdpi/ic_launcher_contacts.png
+++ b/res/mipmap-mdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_shortcut_contact.png b/res/mipmap-mdpi/ic_launcher_shortcut_contact.png
index dd3c8ff..218c915 100644
--- a/res/mipmap-mdpi/ic_launcher_shortcut_contact.png
+++ b/res/mipmap-mdpi/ic_launcher_shortcut_contact.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_shortcut_directdial.png b/res/mipmap-mdpi/ic_launcher_shortcut_directdial.png
index 1dfe8cc..50278c3 100644
--- a/res/mipmap-mdpi/ic_launcher_shortcut_directdial.png
+++ b/res/mipmap-mdpi/ic_launcher_shortcut_directdial.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_shortcut_directmessage.png b/res/mipmap-mdpi/ic_launcher_shortcut_directmessage.png
index c7dc525..698971b 100644
--- a/res/mipmap-mdpi/ic_launcher_shortcut_directmessage.png
+++ b/res/mipmap-mdpi/ic_launcher_shortcut_directmessage.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_contacts.png b/res/mipmap-xhdpi/ic_launcher_contacts.png
index 4b7eaaa..dde3cbb 100644
--- a/res/mipmap-xhdpi/ic_launcher_contacts.png
+++ b/res/mipmap-xhdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_shortcut_contact.png b/res/mipmap-xhdpi/ic_launcher_shortcut_contact.png
index baeb41f..8a5e25a 100644
--- a/res/mipmap-xhdpi/ic_launcher_shortcut_contact.png
+++ b/res/mipmap-xhdpi/ic_launcher_shortcut_contact.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_shortcut_directdial.png b/res/mipmap-xhdpi/ic_launcher_shortcut_directdial.png
index 39d039a..e060bc5 100644
--- a/res/mipmap-xhdpi/ic_launcher_shortcut_directdial.png
+++ b/res/mipmap-xhdpi/ic_launcher_shortcut_directdial.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_shortcut_directmessage.png b/res/mipmap-xhdpi/ic_launcher_shortcut_directmessage.png
index 7dd5d39..3222dc8 100644
--- a/res/mipmap-xhdpi/ic_launcher_shortcut_directmessage.png
+++ b/res/mipmap-xhdpi/ic_launcher_shortcut_directmessage.png
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 428fed8..2c5135a 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Soek"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nuwe kontak"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Bekyk kontak"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Bel <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Bel <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Voeg by gunstelinge"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Verwyder van gunstelinge"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Redigeer"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Vee uit"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopieer"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Plaas op tuisskerm"</string>
     <string name="menu_call" msgid="3992595586042260618">"Bel kontak"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Teks - kontak"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Skei"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Voorgestelde kontakte"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Alle kontakte"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontakte saamgevoeg"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Vee kontak uit?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Stel luitoon op"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Alle oproepe na stempos"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Jy kan nie kontakte uit leesalleen-rekeninge uitvee nie, maar jy kan hulle wel in jou kontaklyste versteek."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Maatskappy"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titel"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Die kontak bestaan ​​nie."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontak-legstuk by tuisskerm gevoeg."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Skep nuwe kontak"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Skep nuwe kontak"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Foon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> gevind"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Meer as <xliff:g id="COUNT">%d</xliff:g> gevind."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Geen gevind nie."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Geen kontakte nie"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 gevind"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> gevind"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Alle"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Alle kontakte"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Groepe"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Gunstelinge"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Foon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vee oproeprekord uit?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Al jou oproeprekords sal uitgevee word."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Vee tans oproeprekord uit..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vee dikwels-gebruikte kontakte uit?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Jy gaan die lys van dikwels-gebruikte kontakte in die Mense- en Foonprogramme uitvee, en e-posprogramme dwing om jou adresvoorkeure van nuuts af te leer."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Vee tans dikwels-gebruikte kontakte uit..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Stemboodskap"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sek."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Gereeld gekontak"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Gereeld gebel"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Voeg kontak by"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Voeg \"<xliff:g id="EMAIL">%s</xliff:g>\" by kontakte?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"een"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"twee"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Bekyk kontak"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Berging nie beskikbaar nie"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Geen SD-kaart nie"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Geen berging gevind nie."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Geen SD-kaart gevind nie."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Soek vir vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Voer in van SIM-kaart"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Voer in uit berging"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Voer uit na berging"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Voer alle vCard-lêers in"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Soek  tans vir vCard-data in berging..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Soek tans vir vCard-data op SD-kaart..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Kon berging nie skandeer nie."</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Kon nie SD-kaart skandeer nie"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Die berging kon nie geskandeer word nie. (Rede: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Die SD-kaart kon nie geskandeer word nie. (Rede: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"T/A-fout"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> sal binnekort uitgevoer word."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard-uitvoerversoek is verwerp. Probeer asseblief later."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontak"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Voer kontakte uit?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Jou kontaklys sal uitgevoer word na die lêer: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Kon nie uitvoer nie"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Die vCard-opsteller het nie behoorlik begin nie."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Kon nie \"<xliff:g id="FILE_NAME">%s</xliff:g>\" open nie: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> van <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontakte"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Kanselleer vCard-invoer"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Kanselleer invoer van <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Kanselleer vCard-uitvoer"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Kanselleer uitvoer van <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Kon nie vCard invoer/uitvoer kanselleer nie"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Name van jou kontakte"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Voeg 2-sek.-pouse by"</string>
     <string name="add_wait" msgid="3360818652790319634">"Voeg wagtyd by"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Bel met"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Kies nommer"</string>
     <string name="call_settings" msgid="7666474782093693667">"Instellings"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Teks met"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Kies nommer"</string>
     <string name="make_primary" msgid="5829291915305113983">"Onthou hierdie keuse"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Geen program is gevind om hierdie aksie te hanteer nie."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Geen naam nie)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Rekeninge"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Vee dikwels-gebruiktes uit"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakte om te wys"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Voer in/uit"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Voer kontakte in/uit"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Voer kontakte in"</string>
     <string name="menu_share" msgid="943789700636542260">"Deel"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Alle kontakte"</string>
     <string name="share_via" msgid="563121028023030093">"Deel kontak met"</string>
     <string name="share_error" msgid="948429331673358107">"Hierdie kontak kan nie gedeel word nie."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Naam"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Sien kontakname as"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Voornaam eerste"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Van eerste"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Deursoek kontakte"</string>
     <string name="take_photo" msgid="7496128293167402354">"Neem foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Neem nuwe foto"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Kies foto ui die galery"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"saamgevoeg uit <xliff:g id="COUNT">%0$d</xliff:g> bronne"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Ander"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Voeg kontakte saam"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Voeg die huidige kontak by die gekose kontak saam?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Redigeer gekose kontakte"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Wissel na redigering van die gekose kontak? Inligting wat jy tot dusver ingevoer het, sal gekopieer word."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopieer na My kontakte"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Voeg by My kontakte"</string>
@@ -453,7 +448,7 @@
     <string name="toast_making_personal_copy" msgid="288549957278065542">"Skep tans \'n persoonlike kopie..."</string>
     <string name="list_filter_all_accounts" msgid="8908683398914322369">"Alle kontakte"</string>
     <string name="list_filter_all_starred" msgid="5031734941601931356">"Gester"</string>
-    <string name="list_filter_custom" msgid="8910173055702057002">"Gepasmaakte"</string>
+    <string name="list_filter_custom" msgid="8910173055702057002">"Gepasmaak"</string>
     <string name="list_filter_customize" msgid="4789963356004169321">"Pasmaak"</string>
     <string name="list_filter_phones" msgid="735313795643493365">"Alle kontakte met telefoonnommers"</string>
     <string name="list_filter_single" msgid="5871400283515893087">"Kontak"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Instellings"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakte om te wys"</string>
     <string name="menu_settings" msgid="377929915873428211">"Instellings"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Hulp"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Vertoonopsies"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Vind kontakte"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Laai tans…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Skep \'n nuwe kontak"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Meld aan by \'n rekening"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Voer kontakte van \'n lêer in"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Voer kontakte in"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Skep nuwe groep"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Skep nuwe groep]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Vee groep uit"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Skep nuwe groep"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 groep"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> groepe"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Stel verstek op"</string>
     <string name="clear_default" msgid="7193185801596678067">"Vee verstek uit"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Teks gekopieer"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Ontdoen wysigings"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Verwerp jou veranderings?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Stel my profiel op"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Voer persoon se naam in"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Sien opdaterings"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Stemboodskap"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> stemboodskappe"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Speel"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nuwe stemboodskap van <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Kon nie stemboodskap speel nie."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Hou plaaslik"</string>
     <string name="add_account" msgid="8201790677994503186">"Voeg rekening by"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Voeg nuwe rekening by"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Oproep nie gestuur nie."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Stemboodskapnommer nie beskikbaar nie"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Oproep nie gestuur nie"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Om stemboodskapdiens op te stel, gaan na Kieslys &gt; Instellings."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Om stemboodskapdiens te bel, skakel eers vliegtuigmodus af."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Meer opsies"</string>
 </resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index c338395..7bc0b56 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"ፍለጋ"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"አዲስ ዕውቅያ"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"ዕውቂያ ዕይ"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"ጥሪ <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"ደውል<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"ወደ ተወዳጅ አክል"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"ከተወዳጆች አስወግድ"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"አርትዕ"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"ሰርዝ"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"ቅዳ"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"መነሻ የማያ ገጽ ላይ አስቀምጥ"</string>
     <string name="menu_call" msgid="3992595586042260618">"የጥሪ ዕውቂያ"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"ዕውቂያ ፃፍ"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"ለይ"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"አስተያየት የተሰጠባቸው እውቅያዎች"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"ሁሉም እውቅያዎች"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"ዕውቂያዎች ተገናኝተዋል"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"ዕውቅያ  ሰርዝ?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"የጥሪ ድምፅ አዘጋጅ"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"ሁሉንም ጥሪዎች ወደ ድምፅ መልዕክት"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"ዕውቂያዎችን ከንባብ-ብቻ መለያዎች መሰረዝ አትችልም፤ ነገር ግን በዕውቂያ ዝርዝሮች ውስጥ መደበቅ ትችላለህ።"</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"ኩባንያ"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"አርዕስት"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"ዕውቅያው የለም።"</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"የእውቂያ መግብር መነሻ ማያ ገጽ ላይ ታክሏል።"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"አዲስ ዕውቂያ ፍጠር"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"አዲስ እውቂያ ፍጠር"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"ስልክ"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> ተገኝቷል"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"ከ<xliff:g id="COUNT">%d</xliff:g> የበለጠ ተገኝቷል"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"ምንም አልተገኘም፡፡"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"እውቅያዎች የሉም"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 ተገኝቷል"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> ተገኝቷል"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"ሁሉም"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"ሁሉም እውቂያዎች"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"ቡድኖች"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"ተወዳጆች"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"ስልክ"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"የጥሪ ማስታወሻ አጥራ"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"ሁሉም የጥሪ ማህደሮችህ ይሰረዛሉ፡፡"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"የጥሪ ምዝግብ ማስታወሻ በማጥራት ላይ…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"በተደጋጋሚ ያገኘሃቸው ይጠረጉ?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"በሰዎች እና በስልክ መተግበሪያዎች ውስጥ በተደጋጋሚ ያገኘሃቸውን ዝርዝር ጠርገህ የኢሜይል መተግበሪያዎች ምርጫዎችህን ከባዶ ተነስተው እንያውቁ ታስገድዳለህ።"</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"በተደጋጋሚ ያገኘሃቸውን በመጥረግ ላይ…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"የድምፅ መልዕክት"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g>ደቂቃዎች <xliff:g id="SECONDS">%s</xliff:g> ሰከንዶች"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"በተደጋጋሚ የሚገናኙ"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"በተደጋጋሚ የተደወለ"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"እውቅያዎች አክል"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"<xliff:g id="EMAIL">%s</xliff:g> ወደ እውቅያዎች ዝርዝር ይታከል"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"አንድ"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"ሁለት"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"ሲቀነስ"</string>
     <string name="description_plus_button" msgid="515164827856229880">"ተጨማሪ"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"ዕውቂያ ዕይ"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"ማከማቻ አልተገኘም"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"ምንምSD ካርድ የለም"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"ምንም ማከማቻ አልተገኘም፡፡"</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"ምንም SD ካርድ አልተገኘም፡፡"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard ፍለጋ"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"ከSIM ካርድ አስመጣ"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"ከማከማቻ አስገባ"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"ወደማከማቻ ላክ"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"ሁሉም vCard ፋይሎችን አስገባ"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"በማከማቻ ውስጥ የvCard ውሂብ በመፈለግ ላይ"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"በSD ካርድ ላይ vCard ፍለጋ"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"ማከማቻን መቃኘት አልተቻለም"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD ካርድን መቃኘት አልተቻለም"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"ማከማቻው  ሊቀረጽ አልተቻለም:: (ምክንያት: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD ካርዱ ሊቀረጽ አልተቻለም:: (ምክንያት: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O ስህተት"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> ከአፍታ ቆይታ በኋላ ይላካል።"</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"የvCard ላክ ጥየቃ ውድቅ ተደርጓል። እባክህ ትንሽ ቆይተህ ሞክር።"</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"እውቅያ"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"እውቅያዎች ላክ"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"የእውቂያ ዝርዝርህ ወደዚህ ፋይል ይላካል: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"ወደ ውጭ መላክ አልተቻለም"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"የ vCard  አቀናባሪው በትክክል አልጀመረም::"</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" ፡<xliff:g id="EXACT_REASON">%s</xliff:g> መክፈት አልተቻለም"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> ከ <xliff:g id="TOTAL_NUMBER">%s</xliff:g> እውቂያዎች"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard አስመጣ በመሰረዝ ላይ"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"የ<xliff:g id="FILENAME">%s</xliff:g>ወደ ውስጥ ማስገባት ይተው?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard ላክበመሰረዝላይ"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"የ<xliff:g id="FILENAME">%s</xliff:g> ወደ ውጭ መላክ ይተው?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCard ማስመጣት/ወደ ውጪ መላክ መተው አልተቻለም"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"የዕውቂያዎችዎ ስሞች"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2 ሰከንድ ፋታ አክል"</string>
     <string name="add_wait" msgid="3360818652790319634">"ጠብቅአክል"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"ጥሪ በመጠቀም"</string>
-    <string name="call_settings" msgid="7666474782093693667">"ቅንጅቶች"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"ፅሁፍበመጠቀም"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"ቁጥር ምረጥ"</string>
+    <string name="call_settings" msgid="7666474782093693667">"ቅንብሮች"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"ቁጥር ምረጥ"</string>
     <string name="make_primary" msgid="5829291915305113983">"ይህን ምርጫ አስታውስ"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"ይህን እርምጃ ለማስተናገድ ምንም መተግበሪያ አልተገኘም፡፡"</string>
     <string name="missing_name" msgid="8745511583852904385">"(ስም የለም)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"መለያዎች"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"ተደጋጋሚዎችን ጥረግ"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"ዕውቂያዎች አሳይ"</string>
     <string name="menu_import_export" msgid="26217871113229507">"አስመጣ/ላክ"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"ዕውቂያዎች አስመጣ/ላክ"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"እውቅያዎችን ከውጭ አስመጣ"</string>
     <string name="menu_share" msgid="943789700636542260">"መጋሪያ"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"ሁሉም እውቅያዎች"</string>
     <string name="share_via" msgid="563121028023030093">"ዕውቂያበ በኩል አጋራ"</string>
     <string name="share_error" msgid="948429331673358107">"ይህ ዕውቂያ መጋራት አይችልም።"</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"ስም"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"የእውቂያ ስሞችን እንደ እይ"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"መጠሪያ ስም መጀመሪያ"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"የቤተሰብ መነሻስም"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"እውቅያዎችዎን ይፈልጉ"</string>
     <string name="take_photo" msgid="7496128293167402354">"ፎቶ አንሳ"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"አዲስ ፎቶ አንሳ"</string>
     <string name="pick_photo" msgid="3746334626214970837">"ፎቶ ከማዕከለ ስዕላት ምረጥ"</string>
@@ -435,15 +432,13 @@
     <string name="contact_status_update_attribution" msgid="752179367353018597">"በ<xliff:g id="SOURCE">%1$s</xliff:g> በኩል"</string>
     <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g>በ<xliff:g id="SOURCE">%2$s</xliff:g> በኩል"</string>
     <string name="description_star" msgid="2605854427360036550">"ተወዳጅ"</string>
-    <string name="edit_contact" msgid="7529281274005689512">"እውቅያ አርትእ"</string>
+    <string name="edit_contact" msgid="7529281274005689512">"እውቅያ አርትዕ"</string>
   <plurals name="merge_info">
     <item quantity="one" msgid="148365587896371969">"አልተዋሃደም"</item>
     <item quantity="other" msgid="425683718017380845">"ከ<xliff:g id="COUNT">%0$d</xliff:g> ምንጮች የተዋሃደ"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"ሌላ"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"ዕውቂያዎችን አገናኝ"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"የአሁኑ ዕውቂያ ከተመረጠው ዕውቂያ ጋር ይገናኝ?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"የተመረጡ  ዕውቂያዎችን አርትዕ"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"የተመረጠው ዕውቂያ ወደ አርትዕ ይቀየር? እስከ አሁን ያስገቡት መረጃ ይገለበጣል።"</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"ወደ ዕውቂያዎቼ ቅዳ"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"ወደ እኔ ዕውቂያዎች አክል"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"ቅንብሮች"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"ዕውቂያዎች አሳይ"</string>
     <string name="menu_settings" msgid="377929915873428211">"ቅንብሮች"</string>
+    <string name="menu_help" msgid="5123887102216637725">"እገዛ"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"ማሳያ አማራጮች"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>፣ <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"ዕውቂያዎች አግኝ"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"በመስቀል ላይ…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"አዲስ ዕውቂያ ፍጠር"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"ወደ መለያ ግባ"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"ከፋይል ዕውቂያዎች አስመጣ"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"እውቅያዎችን ከውጭ አስመጣ"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"አዲስ ቡድን ፍጠር"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[አዲስ ቡድን ፍጠር]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"ቡድን ሰርዝ"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"አዲስ ቡድን ፍጠር"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 ቡድን"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g>ቡድኖች"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"ነባሪ አዘጋጅ"</string>
     <string name="clear_default" msgid="7193185801596678067">"ነባሪ አጥራ"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"ፅሁፍ ገልብጧል"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"ለውጦች አስወግድ"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">" ለውጦችህ ይወገዱ?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"መገለጫዬን አዘጋጅ"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"የግለሰቡን ስም ተይብ"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"አዘምኖችን ዕይ"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"የድምፅ መልዕክት"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> የድምፅ መልዕክቶች"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"አጫውት"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>፤<xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"ከ<xliff:g id="CALLER">%1$s</xliff:g> አዲስ የድምፅመልዕክት"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"ድምፅ ደብዳቤን ማጫወት አልተቻለም፡፡"</string>
@@ -553,7 +548,7 @@
     <string name="external_profile_title" msgid="8034998767621359438">"የእኔ የ<xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g> መገለጫ"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"ሁሉንም ዕውቂያዎች በማሳየት ላይ"</string>
     <string name="no_account_prompt" msgid="7061052512446855192">"ሰዎች በGoogle መለያ የተሻለ ይሰራሉ።"\n\n"• ከማንኛውም የድረ ማሰሻ ላይ ይድረሱበት።"\n"• ዝግጅቶችዎን በደንብ ያስጠብቁ"</string>
-    <string name="generic_no_account_prompt" msgid="7218827704367325460">"ስልክህ ቢጠፋብህ እንኳ ዕውቂያዎችህን ደህንነታቸው እንደተጠበቀ እንዲቆዩ አድርግ ከመስመር ላይ አገልገሎት ጋር አመሳስለው::"</string>
+    <string name="generic_no_account_prompt" msgid="7218827704367325460">"ስልክህ ቢጠፋብህ እንኳን  ዕውቂያዎችህን ደህንነታቸው እንደተጠበቀ እንዲቆዩ አድርግ ከመስመር ላይ አገልገሎት ጋር አመሳስለው::"</string>
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"መለያ አክል"</string>
     <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"አዲሱ  ዕውቅያ ምትክ አይቀመጥለትም:: በመስመር ላይ ዕውቅያዎች በምትክ የሚያስቀምጥ መለያ አክል?"</string>
     <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"አዲሱ ዕውቅያህ ከ <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g> ጋር ይመሳሰላል፡፡"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"በአካባቢው አቆይ"</string>
     <string name="add_account" msgid="8201790677994503186">"መለያ አክል"</string>
     <string name="add_new_account" msgid="5748627740680940264">"አዲስ መለያ አክል"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"ጥሪ አልተላከም።"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"የድምጽ መልዕክት ቁጥር አይገኝም::"</string>
-    <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ድምጽ መልዕክትን ለማደራጀት ወደ ምናሌ &gt; ቅንጅቶች ሂድ::"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"ጥሪ አልተላከም"</string>
+    <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ድምጽ መልዕክትን ለማደራጀት ወደ ምናሌ &gt; ቅንብሮች  ሂድ::"</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"የድምጽ መልዕክት ጥሪ ለማድረግ፣ በመጀመሪያ የአውሮፕላን ሁነታን አጥፋ።"</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"ተጨማሪ አማራጮች"</string>
 </resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 7e9db74..a43fda8 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"بحث"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"جهة اتصال جديدة"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"عرض جهة الاتصال"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"الاتصال بـ <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"الاتصال بالرقم <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"إضافة إلى المفضلة"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"إزالة من المفضلة"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"تعديل"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"حذف"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"نسخ"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"وضع على الشاشة الرئيسية"</string>
     <string name="menu_call" msgid="3992595586042260618">"الاتصال بجهة الاتصال"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"إرسال رسالة لجهة الاتصال"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"فصل"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"جهات الاتصال المقترحة"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"جميع جهات الاتصال"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"جهات الاتصال المنضمة"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"حذف جهة الاتصال؟"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"تعيين نغمة رنين"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"جميع المكالمات إلى البريد الصوتي"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"لا يمكنك حذف جهات الاتصال من حسابات للقراءة فقط، ولكن يمكنك إخفاؤها في قوائم جهات الاتصال."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"شركة"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"المسمى الوظيفي"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"جهة الاتصال غير موجودة."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"تمت إضافة أداة جهات الاتصال إلى الشاشة الرئيسية."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"إنشاء جهة اتصال جديدة"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"إنشاء جهة اتصال جديدة"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"الهاتف"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"تم العثور على <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"تم العثور على أكثر من <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"ليس هناك أية جهات اتصال."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"ليست هناك جهات اتصال"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"تم العثور على جهة اتصال واحدة"</item>
     <item quantity="other" msgid="7988132539476575389">"تم العثور على <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"الكل"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"جميع جهات الاتصال"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"المجموعات"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"المفضلة"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"الهاتف"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"محو سجل المكالمات؟"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"سيتم حذف جميع سجلات المكالمات."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"جارٍ محو سجل المكالمات..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"هل تريد محو قائمة من يُتصل بهم كثيرًا؟"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"ستمحو قائمة من يتم الاتصال بهم كثيرًا في تطبيقي الأشخاص والهاتف، وستفرض على تطبيقات البريد الإلكتروني التعرف على تفضيلات توجيه الرسائل من البداية."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"جارٍ محو قائمة المُتصل بهم كثيرًا…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"البريد الصوتي"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"عدد الدقائق:<xliff:g id="MINUTES">%s</xliff:g>، عددالثواني: <xliff:g id="SECONDS">%s</xliff:g>"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"يتم الاتصال بهم بشكل متكرر"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"الأكثر اتصالاً"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"إضافة جهة اتصال"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"هل ترغب في إضافة \"<xliff:g id="EMAIL">%s</xliff:g>\" إلى جهات الاتصال؟"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"واحد"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"اثنان"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"علامة الطرح"</string>
     <string name="description_plus_button" msgid="515164827856229880">"علامة زائد"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"عرض جهة الاتصال"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"وحدة التخزين غير متوفرة."</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"لا بطاقة SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"لم يتم العثور على وحدة تخزين."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"لم يتم العثور على بطاقة SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"البحث عن vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"استيراد من بطاقة SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"استيراد من وحدة التخزين"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"تصدير إلى وحدة التخزين"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"استيراد جميع ملفات vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"جارٍ البحث عن بيانات vCard في وحدة التخزين..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"جارٍ البحث عن بيانات vCard على بطاقة SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"تعذر فحص وحدة التخزين"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"تعذر فحص بطاقة SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"تعذر فحص وحدة التخزين. (السبب: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"تعذر فحص بطاقة SD. (السبب: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"خطأ I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"سيتم تصدير <xliff:g id="FILENAME">%s</xliff:g> بعد قليل."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"تم رفض طلب تصدير vCard. أعد المحاولة لاحقًا."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"جهة اتصال"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"تصدير جهات الاتصال؟"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"سيتم تصدير قائمة جهات الاتصال إلى الملف: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"تعذر التصدير"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"لم يبدأ مؤلف vCard بشكل صحيح."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"تعذر فتح \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> من <xliff:g id="TOTAL_NUMBER">%s</xliff:g> من جهات الاتصال"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"إلغاء استيراد ملف vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"هل تريد إلغاء استيراد <xliff:g id="FILENAME">%s</xliff:g>؟"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"إلغاء تصدير ملف vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"هل تريد إلغاء تصدير <xliff:g id="FILENAME">%s</xliff:g>؟"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"تعذر إلغاء استيراد/تصدير vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"أسماء جهات الاتصال"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"إضافة فترة إيقاف مؤقت مدتها ثانيتان"</string>
     <string name="add_wait" msgid="3360818652790319634">"إضافة انتظار"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"اتصال باستخدام"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"اختيار رقم"</string>
     <string name="call_settings" msgid="7666474782093693667">"الإعدادات"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"إرسال رسالة نصية قصيرة باستخدام"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"اختيار رقم"</string>
     <string name="make_primary" msgid="5829291915305113983">"تذكر هذا الاختيار"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"لم يتم العثور على تطبيق يمكنه مباشرة هذا الإجراء."</string>
     <string name="missing_name" msgid="8745511583852904385">"(بلا اسم)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"الحسابات"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"محو قائمة من يتصل بهم كثيرًا"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"جهات الاتصال التي يتم عرضها"</string>
     <string name="menu_import_export" msgid="26217871113229507">"استيراد/تصدير"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"استيراد/تصدير جهات اتصال"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"استيراد جهات الاتصال"</string>
     <string name="menu_share" msgid="943789700636542260">"مشاركة"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"جميع جهات الاتصال"</string>
     <string name="share_via" msgid="563121028023030093">"مشاركة جهة الاتصال عبر"</string>
     <string name="share_error" msgid="948429331673358107">"لا يمكن مشاركة جهة الاتصال هذه."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"الاسم"</string>
@@ -385,12 +383,12 @@
     <string name="postal_postcode" msgid="572136414136673751">"الرمز البريدي"</string>
     <string name="postal_country" msgid="7638264508416368690">"البلد"</string>
     <string name="full_name" msgid="6602579550613988977">"الاسم"</string>
-    <string name="name_given" msgid="1687286314106019813">"الاسم الممنوح"</string>
+    <string name="name_given" msgid="1687286314106019813">"الاسم الأول"</string>
     <string name="name_family" msgid="3416695586119999058">"اسم العائلة"</string>
     <string name="name_prefix" msgid="59756378548779822">"بادئة الاسم"</string>
     <string name="name_middle" msgid="8467433655992690326">"الاسم الأوسط"</string>
     <string name="name_suffix" msgid="3855278445375651441">"لاحقة الاسم"</string>
-    <string name="name_phonetic_given" msgid="6853570431394449191">"الاسم الصوتي الممنوح"</string>
+    <string name="name_phonetic_given" msgid="6853570431394449191">"الاسم الأول - صوتي"</string>
     <string name="name_phonetic_middle" msgid="8643721493320405200">"الاسم الصوتي الأوسط"</string>
     <string name="name_phonetic_family" msgid="462095502140180305">"اسم الأسرة الصوتي"</string>
     <string name="name_phonetic" msgid="4259595234312430484">"الاسم"</string>
@@ -406,12 +404,11 @@
     <string name="no_contact_details" msgid="6636856378019344497">"ليس هناك أية معلومات إضافية لجهة الاتصال هذه."</string>
     <string name="group_read_only" msgid="1061762906115697637">"غير قابلة للتعديل على هذا الجهاز."</string>
     <string name="display_options_sort_list_by" msgid="6080091755852211076">"تصنيف القائمة بحسب"</string>
-    <string name="display_options_sort_by_given_name" msgid="184916793466387067">"الاسم الممنوح"</string>
+    <string name="display_options_sort_by_given_name" msgid="184916793466387067">"الاسم الأول"</string>
     <string name="display_options_sort_by_family_name" msgid="7857986975275712622">"اسم العائلة"</string>
-    <string name="display_options_view_names_as" msgid="18022868169627979">"عرض أسماء جهات الاتصال كـ"</string>
-    <string name="display_options_view_given_name_first" msgid="6968288511197363292">"الاسم الممنوح أولاً"</string>
+    <string name="display_options_view_names_as" msgid="18022868169627979">"كيفية عرض الأسماء"</string>
+    <string name="display_options_view_given_name_first" msgid="6968288511197363292">"الاسم الأول أولاً"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"الاسم العائلة أولاً"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"البحث في جهات الاتصال"</string>
     <string name="take_photo" msgid="7496128293167402354">"التقاط صورة"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"التقاط صورة جديدة"</string>
     <string name="pick_photo" msgid="3746334626214970837">"اختيار صورة من المعرض"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"تم دمجها من <xliff:g id="COUNT">%0$d</xliff:g> من المصادر"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"غير ذلك"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"ضم جهات الاتصال"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"هل تريد ضم جهة الاتصال الحالية إلى جهة الاتصال المحددة؟"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"تعديل جهات الاتصال المحددة"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"هل تريد التبديل إلى تعديل جهة الاتصال المحددة؟ سيتم نسخ المعلومات التي أدخلتها حتى الآن."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"نسخ إلى جهات الاتصال الخاصة بي"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"إضافة إلى \"جهات الاتصال الخاصة بي\""</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"الإعدادات"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"جهات الاتصال التي يتم عرضها"</string>
     <string name="menu_settings" msgid="377929915873428211">"الإعدادات"</string>
+    <string name="menu_help" msgid="5123887102216637725">"مساعدة"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"خيارات العرض"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>، <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"البحث عن جهات اتصال"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"جارٍ التحميل…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"إنشاء جهة اتصال جديدة"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"تسجيل الدخول إلى حساب"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"استيراد جهات الاتصال من ملف"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"استيراد جهات الاتصال"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"إنشاء مجموعة جديدة"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[إنشاء مجموعة جديدة]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"حذف المجموعة"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"إنشاء مجموعة جديدة"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"مجموعة واحدة"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> من المجموعات"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"تعيين كافتراضي"</string>
     <string name="clear_default" msgid="7193185801596678067">"محو الإعدادات الافتراضية"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"تم نسخ النص"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"إلغاء التغييرات"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"هل تريد تجاهل التغييرات؟"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"إعداد الملف الشخصي"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"اكتب اسم الشخص"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"عرض التحديثات"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"البريد الصوتي"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> من رسائل البريد الصوتي"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"تشغيل"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>، <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"بريد صوتي جديد من <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"تعذر تشغيل البريد الصوتي."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"الاحتفاظ بها محليًا"</string>
     <string name="add_account" msgid="8201790677994503186">"إضافة حساب"</string>
     <string name="add_new_account" msgid="5748627740680940264">"إضافة حساب جديد"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"لم يتم إرسال المكالمة"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"رقم البريد الصوتي غير متاح"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"لم يتم إرسال المكالمة"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"لإعداد البريد الصوتي، انتقل إلى القائمة &gt; الإعدادات."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"للاتصال بالبريد الصوتي، يجب أولاً إيقاف وضع الطائرة."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"مزيد من الخيارات"</string>
 </resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 6441565..d52e6ae 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Пошук"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Новы кантакт"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Прагледзець кантакт"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Выклік карыст. <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Выклікаць <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Дадаць да любімых"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Выдаліць з Выбранага"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Рэдагаваць"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Выдаліць"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Капіраваць"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Размясціць на галоўным экране"</string>
     <string name="menu_call" msgid="3992595586042260618">"Выклікаць кантакт"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Паведамленне кантакту"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Падзяліць"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Прапанаваныя кантакты"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Усе кантакты"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Кантакты аб\'яднаныя"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Выдаліць кантакт?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Устал. рынгтон"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Усе выклікі на гал. пошту"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Вы не можаце выдаляць кантакты з улiковых запiсаў толькі для чытання, але вы можаце хаваць іх у спісах кантактаў."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Кампанія"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Назва"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Кантакт не існуе."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Звязацца з віджэтам, даданым на галоўны экран."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Стварыць новы кантакт"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Стварыць новы кантакт"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Тэлефон"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Знойдзеныя: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Знойдзена вынікаў: больш за <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Нічога не знойдзена."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Кантактаў няма"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"знойдзены 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Знойдзеныя: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Усе"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Усе кантакты"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Групы"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Выбранае"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Тэлефон"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ачысціць спіс выклікаў?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Усе вашы запісы выклікаў будуць выдалены."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Выдаленне гiсторыi выклiкаў..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Выдалiць частыя кантакты?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Вы выдалiце найбольш частыя кантакты ў прыкладаннях \"Кантакты\" i \"Тэлефон\" i прымусiце прыкладаннi па працы з электроннай поштай вывучыць вашы налады адрасацыi з нуля."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Выдаленне частых кантактаў..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Галасавая пошта"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> хв. <xliff:g id="SECONDS">%s</xliff:g> с."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Частая сувязь"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Частыя званкi"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Дадаць кантакт"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Дадаць адрас \"<xliff:g id="EMAIL">%s</xliff:g>\" у кантакты?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"адзін"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"два"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"мінус"</string>
     <string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Прагледзець кантакт"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Назапашвальнік недаступны"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Няма SD-карты"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Назапашвальнiк не знойдзены."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SD-карта не знойдзена"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Пошук файла vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Імпарт з SIM-карты"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Імпарт з назапашвальніка"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Экспарт на назапашвальнік"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Імпарт усіх файлаў vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Пошук дадзеных vCard на назапашвальніку..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Пошук дадзеных vCard на SD-карце..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Немагчыма сканаваць сховішча"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Немагчыма сканаваць SD-карту"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Не атрымалася праверыць назапашвальнiк. (Прычына: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Не атрымалася праверыць SD-карту. (Прычына: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Памылка ўводу/вываду"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Файл <xliff:g id="FILENAME">%s</xliff:g> будзе экспартаваны ў бліжэйшы час."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Запыт экспарту vCard адхілены. Паспрабуйце пазней."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"кантакт"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Экспартаваць кантакты?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Спіс кантактаў будзе экспартавацца ў файл <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Не атрымалася экспартаваць"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Памылка запуску складальнiка файлаў vCard."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Немагчыма адкрыць файл \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> з <xliff:g id="TOTAL_NUMBER">%s</xliff:g> кантактаў"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Адмена імпарту vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Адмянiць iмпарт файла <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Адмена экспарту vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Адмянiць экспарт файла <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Немагчыма адмяніць імпарт/экспарт vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Імёны вашых кантактаў"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Дадаць 2-секундную паўзу"</string>
     <string name="add_wait" msgid="3360818652790319634">"Дадаецца, чакайце"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Выклік з дапамогай"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Выбар нумару"</string>
     <string name="call_settings" msgid="7666474782093693667">"Налады"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Напісаць з выкарыстаннем"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Выбар нумару"</string>
     <string name="make_primary" msgid="5829291915305113983">"Запомніць гэты выбар"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Не знойдзена прыкладанне для гэтага дзеяння."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Без назвы)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Уліковыя запісы"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Выдалiць частыя кантакты"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Паказаць кантакты"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Імпарт/экспарт"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Імпарт/экспарт кантактаў"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Імпартаваць кантакты"</string>
     <string name="menu_share" msgid="943789700636542260">"Апублікаваць"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Усе кантакты"</string>
     <string name="share_via" msgid="563121028023030093">"Апублікаваць кантакт з дапамогай"</string>
     <string name="share_error" msgid="948429331673358107">"Нельга падзялiцца гэтым кантактам."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Імя"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Паглядзець імёны кантактаў як"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Спачатку імя"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Спачатку прозвішча"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Шукаць у кантактах"</string>
     <string name="take_photo" msgid="7496128293167402354">"Зрабіць фота"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Зрабiце новую фатаграфію"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Выберыце фатаграфію з галерэі"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"аб\'яднаныя з розных крыніц (<xliff:g id="COUNT">%0$d</xliff:g>)"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Іншае"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Аб\'яднаць кантакты"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Аб\'яднаць бягучы кантакт з выбраным кантактам?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Рэдагаваць выбраныя кантакты"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Пераключыцца ў рэжым рэдагавання выбранага кантакту? Інфармацыя, якую вы ўвялі да гэтага часу, будзе скапіявана."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Капіяваць у мае кантакты"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Дадаць да Маіх кантактаў"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Налады"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Кантакты для адлюстр."</string>
     <string name="menu_settings" msgid="377929915873428211">"Налады"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Даведка"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Паказаць параметры"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Знайсці кантакты"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Загрузка..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Стварыць новы кантакт"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Увайсці ва ўліковы запіс"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Імпартаваць кантакты з файла?"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Імпартаваць кантакты"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Стварыць новую групу"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Стварыць новую групу]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Выдаліць групу"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Стварыць новую групу"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 група"</item>
     <item quantity="other" msgid="1276758425904917367">"Груп: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Усталяваць па змаўчанні"</string>
     <string name="clear_default" msgid="7193185801596678067">"Скінуць налады па змаўчанні"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Тэкст скапіяваны"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Скасаваць змены"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Адмяніць змены?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Наладзіць мой профіль"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Тып імя чалавека"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Прагл. абнаўленняў"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Галас. пошта"</item>
     <item quantity="other" msgid="5513481419205061254">"Галасавых паведамленняў: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Прайграць"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Новае паведамл. ад <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Немагчыма прайгр. пав. галасавой пошты"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Захоўваць лакальна"</string>
     <string name="add_account" msgid="8201790677994503186">"Дадаць уліковы запіс"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Дадаць новы ўліковы запіс"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Выклік не зроблены"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Нумар галасавой пошты недаступны"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Выклік не зроблены"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Каб наладзіць галасавую пошту, націсніце \"Меню\" i перайдзiце ў налады."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Каб зрабiць выклік галасавой пошты, спачатку адключыце рэжым палёту."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Дадатковыя параметры"</string>
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index ab14f83..f34fdc1 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Търсене"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Нов контакт"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Преглед на контакт"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Обаждане на <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Обаждане на <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Добавяне към предпочитани"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Премахване от любими"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Редактиране"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Изтриване"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Копиране"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Поставяне на началния екран"</string>
     <string name="menu_call" msgid="3992595586042260618">"Обаждане на контакт"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Изпращaне на SMS на контакт"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Разделяне"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Предлагани контакти"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Всички контакти"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Контактите са слети"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Да се изтрие ли контактът?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Мелодия: Задав."</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Всички обаждания до гл. поща"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Не можете да изтриете контакти от профили само за четене, но можете да ги скриете в списъците си с контакти."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Фирма"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Заглавие"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Контактът не съществува."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Приспособлението за контакти е добавено към началния екран."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Създаване на нов контакт"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Създаване на нов контакт"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Телефон"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> намерени"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Намерени са повече от <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Няма намерени."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Няма контакти"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 намерен"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> намерени"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Всички"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Всички контакти"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Групи"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Любими"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Телефон"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Да се изчисти ли списъкът с обаждания?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Всичките ви записи на обажданията ще бъдат изтрити."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Списъкът с обаждания се изчиства..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Да се изчистят ли често търсените?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Ще изчистите списъка с често търсените в приложенията Хора и Телефон и ще принудите приложенията за имейл да научат предпочитанията ви за адресите, започвайки отначало."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Често търсените се изчистват…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Гласова поща"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> мин <xliff:g id="SECONDS">%s</xliff:g> сек"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Често търсени"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Чести обаждания"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Добавяне на контакт"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Да се добави ли „<xliff:g id="EMAIL">%s</xliff:g>“ към контакти?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"едно"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"две"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"минус"</string>
     <string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Преглед на контакта"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Няма хранилище"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Няма SD карта"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Не бе намерено хранилище."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Не бе намерена SD карта."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Търсене на vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Импортиране от SIM карта"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Импорт. от хранилището"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Експорт. в хранилището"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Импортиране на всички vCard файлове"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Търсят се данни за vCard в хранилището..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Търсят се данни за vCard в SD картата..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Хранилището не можа да бъде сканирано"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD картата не можа да бъде сканирана"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Хранилището не можа да бъде сканирано. (Причина: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD картата не можа да бъде сканирана. (Причина: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O грешка"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> ще се експортира скоро."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Заявката за експортиране на vCard бе отхвърлена. Опитайте отново по-късно."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"контакт"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Да се експортират ли контактите?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Списъкът ви с контакти ще се експортира във файла: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Не се експортира"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Създателят на vCard не се стартира правилно."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"„<xliff:g id="FILE_NAME">%s</xliff:g>“ не можа да се отвори: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> от <xliff:g id="TOTAL_NUMBER">%s</xliff:g> контакта"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Анулиране на импортирането на vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Да се анулира ли импортирането на <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Анулиране на експортирането на vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Да се анулира ли експортирането на <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Импорт./експорт. не можа да се анулира"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Имена на контактите ви"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Добавяне на 2-сек пауза"</string>
     <string name="add_wait" msgid="3360818652790319634">"Добавяне на изчакване"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Обаждане на"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Избиране на номер"</string>
     <string name="call_settings" msgid="7666474782093693667">"Настройки"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Изпращaне на SMS чрез"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Избиране на номер"</string>
     <string name="make_primary" msgid="5829291915305113983">"Запомняне на този избор"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Не бе намерено приложение за извършване на това действие."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Няма име)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Профили"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Изчистване на често търсените"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Контакти за показване"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Импортиране/Експортиране"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Импортиране/Експортиране на контакти"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Импортиране на контактите"</string>
     <string name="menu_share" msgid="943789700636542260">"Споделяне"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Всички контакти"</string>
     <string name="share_via" msgid="563121028023030093">"Споделяне на контакт чрез"</string>
     <string name="share_error" msgid="948429331673358107">"Този контакт не може да бъде споделен."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Име"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Преглед на имената на контакти като"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Първо собственото име"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Първо фамилията"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Търсене в контактите"</string>
     <string name="take_photo" msgid="7496128293167402354">"Снимане"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Заснемане на нова снимка"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Избор на снимка от галерията"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"обединено от <xliff:g id="COUNT">%0$d</xliff:g> източник/а"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Други"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Сливане на контакти"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Да се слее ли текущият контакт с избрания?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Редактиране на избраните контакти"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Да се превключи ли към редактиране на избрания контакт? Въведената досега информация ще бъде копирана."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Копиране в моите контакти"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Добавяне в „Моите контакти“"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Настройки"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Контакти за показване"</string>
     <string name="menu_settings" msgid="377929915873428211">"Настройки"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Помощ"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Опции за показване"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Намиране на контакти"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Зарежда се…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Създаване на нов контакт"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Вход в профил"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Импортиране на контакти от файл"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Импортиране на контактите"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Създаване на нова група"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Създаване на нова група]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Изтриване на групата"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Създаване на нова група"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 група"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> групи"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Задаване като стандартна настройка"</string>
     <string name="clear_default" msgid="7193185801596678067">"Изчистване на стандартната настройка"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Текстът бе копиран"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Отхвърляне на промените"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Да се отхвърлят ли направените от вас промени?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Настройка на потребителския ми профил"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Въведете името на човека"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Актуализации"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Гласова поща"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> гл. съобщения"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Пускане"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Нова гласова поща от <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Гласовата поща не можа да бъде пусната."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Съхраняване локално"</string>
     <string name="add_account" msgid="8201790677994503186">"Добавяне на профил"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Добавяне на нов профил"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Обаждането не е извършено"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Номерът за гласова поща не е налице"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Обаждането не е извършено"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"За да настроите гласовата поща, отворете „Меню“ &gt; „Настройки“."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"За да чуете гласовата си поща, първо изключете самолетния режим."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Още опции"</string>
 </resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 59127b0..de92f5f 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Cerca"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Contacte nou"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Visualitza el contacte"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Truca a <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Truca al <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Afegeix als preferits"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Elimina dels preferits"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Edita"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Suprimeix"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copia"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Posa-ho a la pantalla d\'inici"</string>
     <string name="menu_call" msgid="3992595586042260618">"Truca al contacte"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Envia un SMS al contacte"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separa"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contactes suggerits"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Tots els contactes"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contactes units"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Vols suprimir el contacte?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Est. to trucada"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Trucades a la bústia de veu"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"No pots suprimir cap contacte dels comptes de només lectura, però pots amagar-los a les llistes de contactes."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Empresa"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Títol"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"El contacte no existeix."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"El widget de contacte s\'ha afegit a la pantalla d\'inici."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Crea un contacte nou"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Crea un contacte nou"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telèfon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> contactes"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Se n\'han trobat més de <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"No se n\'ha trobat cap."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"No hi ha cap contacte"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 contacte"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> contactes"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tots"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Tots els contactes"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grups"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Preferits"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telèfon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Esborrament registre"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Se suprimiran tots els registres de trucades."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Esborrant registre de trucades..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vols esborrar contac. més freqüents?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"S\'esborrarà la llista de contactes més freqüents a les aplicacions de contactes i del telèfon i es forçarà les aplicacions de correu electrònic a obtenir informació sobre les preferències de direccionament des de zero."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"S\'està esb. cont. més freqüents..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Correu de veu"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Contactats sovint"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Trucats sovint"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Addició d\'un contacte"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Voleu afegir \"<xliff:g id="EMAIL">%s</xliff:g>\" als contactes?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"un"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dos"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"menys"</string>
     <string name="description_plus_button" msgid="515164827856229880">"més"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Mostra el contacte"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Emmagatzematge no dispon."</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"No hi ha cap targeta SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No s\'ha trobat emmagatzematge."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"No s\'ha trobat cap targeta SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"S\'està cercant la vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importa des de la targeta SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importa de l\'emmagatzematge"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exporta a emmagatzematge"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importa tots els fitxers vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"S\'estan cercant dades de vCard a l\'emmagatzematge..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"S\'estan cercant les dades de vCard a la targeta SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"No s\'ha pogut explorar l\'emmagatzematge"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"No s\'ha pogut explorar la targeta SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"No s\'ha pogut explorar l\'emmagatzematge. (Motiu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"No s\'ha pogut explorar la targeta SD. (Motiu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Error d\'E/S"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> s\'exportarà en breu."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"S\'ha rebutjat la sol·licitud per exportar vCard. Torna-ho a provar més tard."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contacte"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportació contactes"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"La llista de contactes s\'exportarà al fitxer: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Error en exportar"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"No s\'ha iniciat correctament el creador de vCard."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"No s\'ha pogut obrir \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> de <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contactes"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Cancel·lació de la importació de la vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Vols cancel·lar la importació de: <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Cancel·lació de l\'exportació de la vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Vols cancel·lar l\'exportació de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"No es pot cancel·lar la imp./exp. vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Noms dels contactes"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Afegeix una pausa de 2 segons"</string>
     <string name="add_wait" msgid="3360818652790319634">"Afegeix espera"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Trucada mitjançant"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Tria d\'un número"</string>
     <string name="call_settings" msgid="7666474782093693667">"Configuració"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Envia un SMS amb"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Tria d\'un número"</string>
     <string name="make_primary" msgid="5829291915305113983">"Recorda aquesta selecció"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"No s\'ha trobat cap aplicació per processar aquesta acció."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Sense nom)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Comptes"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Esborra els freqüents"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contactes per mostrar"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importa/exporta"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importació/exportació de contactes"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importació de contactes"</string>
     <string name="menu_share" msgid="943789700636542260">"Comparteix"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Tots els contactes"</string>
     <string name="share_via" msgid="563121028023030093">"Comparteix el contacte mitjançant"</string>
     <string name="share_error" msgid="948429331673358107">"No es pot compartir aquest contacte."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nom"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Visualitza els noms dels contactes com a"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nom primer"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Cognoms primer"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Cerca als contactes"</string>
     <string name="take_photo" msgid="7496128293167402354">"Fes una foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Fes una foto nova"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Tria una foto de la galeria"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"combinat de <xliff:g id="COUNT">%0$d</xliff:g> fonts"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Altres"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Ajunta els contactes"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Vols ajuntar el contacte actual amb el contacte seleccionat?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Edita els contactes seleccionats"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Vols canviar per editar el contacte seleccionat? Es copiarà la informació que hagis introduït fins ara."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copia a Els meus contactes"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Afegeix a Els meus contactes"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Configuració"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contactes per mostrar"</string>
     <string name="menu_settings" msgid="377929915873428211">"Configuració"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ajuda"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opcions de visualització"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Cerca contactes"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"S\'està carregant…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Crea un contacte nou"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Inicia la sessió a un compte"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importa contactes d\'un fitxer"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importa contactes"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Creació d\'un grup nou"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Crea un grup nou]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Supressió d\'un grup"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Crea un grup nou"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Un grup"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grups"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Predeterminat"</string>
     <string name="clear_default" msgid="7193185801596678067">"Esborra els valors predeterminats"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Text copiat"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Descarta els canvis"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Vols descartar els canvis?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configura el meu perfil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Escriu el nom de la persona"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Mostra actualitzac."</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Missatge de veu"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> missatges de veu"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reprodueix"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nou missatge de veu de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"No s\'ha pogut reproduir correu de veu."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Conserva localment"</string>
     <string name="add_account" msgid="8201790677994503186">"Afegeix un compte"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Afegeix un compte nou"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"No s\'ha enviat la trucada"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Número de la bústia de veu no disponible"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"No s\'ha enviat la trucada"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Per configurar la bústia de veu, vés a Menú &gt; Configuració."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Per trucar al correu de veu, primer has de desactivar el mode d\'avió."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Més opcions"</string>
 </resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 3846714..609604f 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Hledat"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nový kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Zobrazit kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Volat kontakt <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Zavolat na číslo <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Přidat k oblíbeným položkám"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Odebrat z oblíbených položek"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Upravit"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Smazat"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopírovat"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Umístit na plochu"</string>
     <string name="menu_call" msgid="3992595586042260618">"Volat kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Odeslat zprávu kontaktu"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Oddělit"</string>
@@ -62,21 +64,21 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Navrhované kontakty"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Všechny kontakty"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontakty byly spojeny"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Smazat kontakt?"</string>
-    <string name="menu_set_ring_tone" msgid="8728345772068064946">"Nast. vyzvánění"</string>
-    <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Všechny hovory do hlas. schr."</string>
+    <string name="menu_set_ring_tone" msgid="8728345772068064946">"Nastavit vyzvánění"</string>
+    <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Hovory do hlas. schránky"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Z účtů pouze pro čtení není možné kontakty mazat, můžete je však ve svých seznamech kontaktů skrýt."</string>
     <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"Tento kontakt obsahuje informace z několika účtů. Informace z účtů pouze pro čtení budou v seznamech kontaktů skryty, ale nebudou smazány."</string>
     <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"Smazáním tohoto kontaktu smažete informace z více účtů."</string>
     <string name="deleteConfirmation" msgid="811706994761610640">"Tento kontakt bude smazán."</string>
     <string name="menu_done" msgid="796017761764190697">"Hotovo"</string>
     <string name="menu_doNotSave" msgid="58593876893538465">"Zrušit"</string>
-    <string name="menu_discard" msgid="6456087569315685632">"Zrušit"</string>
+    <string name="menu_discard" msgid="6456087569315685632">"Zahodit"</string>
     <string name="label_notes" msgid="8337354953278341042">"Poznámky"</string>
     <string name="label_sip_address" msgid="124073911714324974">"Internetový hovor"</string>
     <string name="ghostData_company" msgid="5414421120553765775">"Společnost"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Název"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakt neexistuje."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget Kontakt byl přidán na plochu."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Vytvořit nový kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Vytvořit nový kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -108,12 +110,12 @@
     <string name="groupSavedErrorToast" msgid="7984466936615304740">"Změny skupiny nelze uložit."</string>
   <plurals name="listTotalPhoneContacts">
     <item quantity="one" msgid="3015357862286673986">"1 kontakt s telefonním číslem"</item>
-    <item quantity="other" msgid="3299954047880968205">"Počet kontaktů s telefonními čísly: <xliff:g id="COUNT">%d</xliff:g>"</item>
+    <item quantity="other" msgid="3299954047880968205">"Kontakty s telefonními čísly: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="listTotalPhoneContactsZero" msgid="6968813857632984319">"Ke kontaktům nejsou přiřazena žádná telefonní čísla"</string>
   <plurals name="listTotalAllContacts">
     <item quantity="one" msgid="3405747744700823280">"1 kontakt"</item>
-    <item quantity="other" msgid="3578469907265375314">"Počet kontaktů: <xliff:g id="COUNT">%d</xliff:g>"</item>
+    <item quantity="other" msgid="3578469907265375314">"Kontakty: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="listTotalAllContactsZero" msgid="5513001821794568211">"Žádné kontakty."</string>
     <string name="listTotalAllContactsZeroCustom" msgid="5004974705699445044">"Žádné kontakty nejsou viditelné."</string>
@@ -123,16 +125,16 @@
     <string name="listSingleContact" msgid="6067813698903535563">"Jeden kontakt"</string>
     <string name="listCustomView" msgid="6950713892532194050">"Kontakty ve vlastním zobrazení"</string>
   <plurals name="listFoundAllContacts">
-    <item quantity="one" msgid="5517063038754171134">"Počet nalezených položek: 1"</item>
-    <item quantity="other" msgid="3852668542926965042">"Počet nalezených položek: <xliff:g id="COUNT">%d</xliff:g>"</item>
+    <item quantity="one" msgid="5517063038754171134">"Nalezeno: 1"</item>
+    <item quantity="other" msgid="3852668542926965042">"Nalezeno: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Nalezeno více kontaktů než <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nebyl nalezen žádný kontakt."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Žádné kontakty"</string>
   <plurals name="searchFoundContacts">
-    <item quantity="one" msgid="4826918429708286628">"Počet nalezených položek: 1"</item>
-    <item quantity="other" msgid="7988132539476575389">"Počet nalezených položek: <xliff:g id="COUNT">%d</xliff:g>"</item>
+    <item quantity="one" msgid="4826918429708286628">"Nalezeno: 1"</item>
+    <item quantity="other" msgid="7988132539476575389">"Nalezeno: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Vše"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Všechny kontakty"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Skupiny"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Oblíbené"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vymazat hovory?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Všechny záznamy hovorů budou smazány."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Vymazání hovorů..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vymazat často kontaktované osoby?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Vymažete seznam často kontaktovaných osob v aplikacích Lidé a Telefon a e-mailové aplikace budou muset nastavení adresátů vytvořit znovu."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Mazání často kontaktovaných osob..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Hlasová schránka"</string>
@@ -157,14 +162,14 @@
     <string name="payphone" msgid="4864313342828942922">"Veřejný telefon"</string>
     <string name="dialerKeyboardHintText" msgid="5401660096579787344">"Číslo vytočíte pomocí klávesnice."</string>
     <string name="dialerDialpadHintText" msgid="5824490365898349041">"Přidáváte hovor"</string>
-    <string name="simContacts_emptyLoading" msgid="6700035985448642408">"Načítání z karty SIM..."</string>
-    <string name="simContacts_title" msgid="27341688347689769">"Kontakty na kartě SIM"</string>
+    <string name="simContacts_emptyLoading" msgid="6700035985448642408">"Načítání ze SIM karty..."</string>
+    <string name="simContacts_title" msgid="27341688347689769">"Kontakty na SIM kartě"</string>
     <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Nemáte uloženy žádné kontakty, které by bylo možno zobrazit. (Pokud jste účet přidali právě teď, může synchronizace kontaktů trvat několik minut.)"</string>
     <string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Nemáte uloženy žádné kontakty, které by bylo možno zobrazit."</string>
-    <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"Nemáte žádné kontakty, které by bylo možné zobrazit."\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s tabletem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit zcela nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty z karty SIM nebo SD."\n</li></string>
-    <string name="noContactsHelpText" product="default" msgid="4405064135698982080">"Nemáte žádné kontakty, které by bylo možné zobrazit."\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s telefonem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit zcela nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty z karty SIM nebo SD."\n</li></string>
-    <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"Nemáte žádné kontakty, které by bylo možné zobrazit. (Pokud jste právě přidali účet, může synchronizace kontaktů trvat několik minut.)"\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s tabletem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Možnosti zobrazení"</b></font>", pokud chcete změnit, které kontakty budou zobrazeny;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit úplně nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo Exportovat"</b></font>", pokud chcete importovat kontakty z karty SIM nebo SD."\n</li></string>
-    <string name="noContactsHelpTextWithSync" product="default" msgid="7016825676090327312">"Nemáte žádné kontakty, které by bylo možné zobrazit. (Pokud jste právě přidali účet, může synchronizace kontaktů trvat několik minut.)"\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" a potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s telefonem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Možnosti zobrazení"</b></font>", pokud chcete změnit, které kontakty budou zobrazeny;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit úplně nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty z karty SIM nebo SD."\n</li></string>
+    <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"Nemáte žádné kontakty, které by bylo možné zobrazit."\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s tabletem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit zcela nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty ze SIM karty nebo SD."\n</li></string>
+    <string name="noContactsHelpText" product="default" msgid="4405064135698982080">"Nemáte žádné kontakty, které by bylo možné zobrazit."\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s telefonem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit zcela nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty ze SIM karty nebo SD."\n</li></string>
+    <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"Nemáte žádné kontakty, které by bylo možné zobrazit. (Pokud jste právě přidali účet, může synchronizace kontaktů trvat několik minut.)"\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s tabletem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Možnosti zobrazení"</b></font>", pokud chcete změnit, které kontakty budou zobrazeny;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit úplně nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo Exportovat"</b></font>", pokud chcete importovat kontakty ze SIM karty nebo SD."\n</li></string>
+    <string name="noContactsHelpTextWithSync" product="default" msgid="7016825676090327312">"Nemáte žádné kontakty, které by bylo možné zobrazit. (Pokud jste právě přidali účet, může synchronizace kontaktů trvat několik minut.)"\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" a potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s telefonem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Možnosti zobrazení"</b></font>", pokud chcete změnit, které kontakty budou zobrazeny;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit úplně nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty ze SIM karty nebo SD."\n</li></string>
     <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"Nemáte žádné kontakty, které by bylo možné zobrazit."\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" a potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s tabletem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit úplně nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty z karty SD."\n</li></string>
     <string name="noContactsNoSimHelpText" product="default" msgid="6224952277619986841">"Nemáte žádné kontakty, které by bylo možné zobrazit."\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s telefonem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nový kontakt"</b></font>", pokud chcete vytvořit zcela nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty z karty SD."\n</li></string>
     <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"Nemáte žádné kontakty, které by bylo možné zobrazit. (Pokud jste právě přidali účet, může synchronizace kontaktů trvat několik minut.)"\n\n"Chcete-li přidat kontakty, dotkněte se možnosti "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", potom se dotkněte položky:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Účty"</b></font>", pokud chcete přidat nebo nastavit účet a kontakty v něm synchronizovat s tabletem;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Možnosti zobrazení"</b></font>", pokud chcete změnit, které kontakty budou zobrazeny;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"/}Nový kontakt"</b></font>", pokud chcete vytvořit úplně nový kontakt;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importovat nebo exportovat"</b></font>", pokud chcete importovat kontakty z karty SD."\n</li></string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Často používané kontakty"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Často volané"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Přidat kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Chcete přidat „<xliff:g id="EMAIL">%s</xliff:g>“ do kontaktů?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"jedna"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dvě"</string>
@@ -209,12 +213,9 @@
     <string name="description_minus_button" msgid="387136707700230172">"mínus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Zobrazit kontakt"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Úložiště je nedostupné"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Žádná karta SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nebylo nalezeno žádné úložiště."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nebyla nalezena žádná karta SD"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Vyhledávání karty vCard"</string>
-    <string name="import_from_sim" msgid="3859272228033941659">"Importovat z karty SIM"</string>
+    <string name="import_from_sim" msgid="3859272228033941659">"Importovat ze SIM karty"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importovat z úložiště"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportovat do úložiště"</string>
     <string name="share_visible_contacts" msgid="890150378880783797">"Sdílet viditelné kontakty"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importovat všechny soubory vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Vyhledávání dat souboru vCard v úložišti..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Vyhledávání dat souboru vCard na kartě SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Úložiště se nepodařilo prohledat"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Kartu SD se nepodařilo prohledat"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Nepodařilo se naskenovat úložiště. (Důvod: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Nepodařilo se naskenovat kartu SD. (Důvod: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Chyba I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Soubor <xliff:g id="FILENAME">%s</xliff:g> bude za okamžik exportován."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Požadavek na export souborů vCard byl zamítnut. Zkuste to prosím později."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s %%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportovat kontakty?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Seznam kontaktů bude exportován do souboru <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Export se nezdařil"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Editor souboru vCard nebyl správně spuštěn."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Soubor <xliff:g id="FILE_NAME">%s</xliff:g> nelze otevřít: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> z <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontaktů"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Rušení importu souboru vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Zrušit import souboru <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Rušení exportu souboru vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Zrušit export souboru <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Import/export vizitky vCard nelze zrušit"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Jména vašich kontaktů"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Přidat 2s pauzu"</string>
     <string name="add_wait" msgid="3360818652790319634">"Přidat čekání"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Volat pomocí"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Zvolte číslo"</string>
     <string name="call_settings" msgid="7666474782093693667">"Nastavení"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Odeslat zprávu pomocí"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Zvolte číslo"</string>
     <string name="make_primary" msgid="5829291915305113983">"Zapamatovat tuto volbu"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Aplikace potřebná k provedení této akce nebyla nalezena."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Žádné jméno)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Účty"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Vymazat často kontaktované os."</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakty k zobrazení"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importovat/Exportovat"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importovat nebo exportovat kontakty"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importovat kontakty"</string>
     <string name="menu_share" msgid="943789700636542260">"Sdílet"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Všechny kontakty"</string>
     <string name="share_via" msgid="563121028023030093">"Sdílet kontakt pomocí"</string>
     <string name="share_error" msgid="948429331673358107">"Tento kontakt nelze sdílet."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Jméno"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Zobrazení jmen kontaktů"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nejprve křestní jméno"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Nejprve příjmení"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Vyhledat kontakty"</string>
     <string name="take_photo" msgid="7496128293167402354">"Vyfotit"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Pořídit novou fotografii"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Vybrat fotografii z Galerie"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"sloučeno ze <xliff:g id="COUNT">%0$d</xliff:g> zdrojů"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Ostatní"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Spojit kontakty"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Spojit aktuální kontakt s vybraným kontaktem?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Upravit vybrané kontakty"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Přepnout do režimu úpravy vybraného kontaktu? Doposud zadané informace budou zkopírovány."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Zkopírovat do kontaktů"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Přidat do skupiny Moje kontakty"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Nastavení"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakty k zobrazení"</string>
     <string name="menu_settings" msgid="377929915873428211">"Nastavení"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Nápověda"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Možnosti zobrazení"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Najít kontakty"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Načítá se..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Vytvořit nový kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Přihlásit se do účtu"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importovat kontakty ze souboru"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importovat kontakty"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Vytvořit novou skupinu"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Vytvořit novou skupinu]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Smazat skupinu"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Vytvořit novou skupinu"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 skupina"</item>
     <item quantity="other" msgid="1276758425904917367">"Skupiny: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,16 +492,16 @@
     <string name="set_default" msgid="4417505153468300351">"Výchozí nastavení"</string>
     <string name="clear_default" msgid="7193185801596678067">"Vymazat výchozí nastavení"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Text zkopírován"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Zrušit změny"</string>
-    <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Zrušit změny?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Zahodit změny?"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Nastavit profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Zadejte jméno osoby"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Zobrazit aktualizace"</string>
   <plurals name="notification_voicemail_title">
     <item quantity="one" msgid="1746619685488504230">"Hlasová schránka"</item>
-    <item quantity="other" msgid="5513481419205061254">"Počet hlasových zpráv: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="5513481419205061254">"Hlasové zprávy: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Přehrát"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nová hlasová zpráva – <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Hlasovou zprávu nelze přehrát."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Zachovat jako místní"</string>
     <string name="add_account" msgid="8201790677994503186">"Přidat účet"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Přidat nový účet"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Hovor nebyl odeslán"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Číslo hlasové schránky není dostupné"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Hovor nebyl odeslán"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Chcete-li nastavit hlasovou schránku, přejděte do části Menu &gt; Nastavení."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Chcete-li volat hlasovou schránku, nejdříve vypněte režim V letadle."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Více možností"</string>
 </resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 85bdd00..73c2c84 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Søg"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Ny kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Vis kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Ring til <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Ring til <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Føj til favoritter"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Fjern fra favoritter"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Rediger"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Slet"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiér"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Placer på startskærmen"</string>
     <string name="menu_call" msgid="3992595586042260618">"Ring til kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Send sms til kontakt"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Opdel"</string>
@@ -62,14 +64,13 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Foreslåede kontakter"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Alle kontakter"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Tilføjede kontakter"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Slet kontaktperson?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Indstil ringetone"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Alle opkald til telefonsvareren"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Du kan ikke slette kontaktpersoner fra skrivebeskyttede konti, men du kan skjule dem på listerne over dine kontaktpersoner."</string>
     <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"Denne kontakt indeholder oplysninger fra flere konti. Oplysningerne fra skrivebeskyttede konti vil blive skjult i dine lister over kontakter, men ikke slettet."</string>
     <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"Sletning af denne kontakt sletter oplysninger fra flere konti."</string>
     <string name="deleteConfirmation" msgid="811706994761610640">"Denne kontakt slettes."</string>
-    <string name="menu_done" msgid="796017761764190697">"Udfør"</string>
+    <string name="menu_done" msgid="796017761764190697">"Gem"</string>
     <string name="menu_doNotSave" msgid="58593876893538465">"Annuller"</string>
     <string name="menu_discard" msgid="6456087569315685632">"Kassér"</string>
     <string name="label_notes" msgid="8337354953278341042">"Noter"</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Virksomhed"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titel"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontaktpersonen findes ikke."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontaktwidgetten føjes til startskærmen."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Opret ny kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Opret ny kontaktperson"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -100,8 +102,8 @@
     <string name="noContactsWithPhoneNumbers" msgid="1605457050218824269">"Der er ingen kontakter med telefonnumre."</string>
     <string name="emptyGroup" msgid="7502116218697177370">"Ingen personer i denne gruppe."</string>
     <string name="addPeopleToGroup" msgid="7879585947222263516">"Rediger gruppen for at tilføje nogen."</string>
-    <string name="savingContact" msgid="4075751076741924939">"Gemmer kontakt ..."</string>
-    <string name="savingDisplayGroups" msgid="2133152192716475939">"Gemmer indstillinger for visning …"</string>
+    <string name="savingContact" msgid="4075751076741924939">"Gemmer kontakt..."</string>
+    <string name="savingDisplayGroups" msgid="2133152192716475939">"Gemmer indstillinger for visning…"</string>
     <string name="contactSavedToast" msgid="7152589189385441091">"Kontakten er gemt."</string>
     <string name="contactSavedErrorToast" msgid="3207250533172944892">"Der kunne ikke gemmes ændringer i kontaktpersoner."</string>
     <string name="groupSavedToast" msgid="1168756874239833756">"Gruppen er gemt."</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> fundet"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Der er fundet mere end <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Der blev ikke fundet nogen."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Ingen kontaktpersoner"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 fundet"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> fundet"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Alle"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Alle kontaktpersoner"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupper"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favorit"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ryd opkaldsliste?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Alle registrerede opkald slettes."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Rydder opkaldslisten..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vil du rydde de ofte kontaktede?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Hvis du gør dette, rydder du listen over personer, som du ofte kontakter, i appene Personer og Telefon. Du vil samtidig tvinge e-mailapps til at lære dine adressepræferencer fra bunden."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Rydder ofte kontaktede personer…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI-nummer"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sek."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Jævnligt kontaktet"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Ofte ringet til"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Tilføj kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Føj \"<xliff:g id="EMAIL">%s</xliff:g>\" til kontaktpersoner?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"et"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"to"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Vis kontaktperson"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Lager ikke tilgængeligt"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Der er intet SD-kort"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Intet lager blev fundet."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Ingen SD-kort fundet."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Søger efter vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importer fra SIM-kort"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importer fra lager"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Eksporter til lager"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importer alle VCard-filer"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Søger efter vCard-data på lager..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Søger efter vCard-data på SD-kortet..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Lagring kunne ikke scannes"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD-kortet kunne ikke scannes"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Lageret kunne ikke scannes. (Årsag: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD-kortet kunne ikke scannes. (Årsag: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O-fejl"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> eksporteres om et øjeblik."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Anmodningen om eksport af vCard blev afvist. Prøv igen senere."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Eksporter kontakter?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Listen over dine kontaktpersoner eksporteres til filen: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Eksport ikke mulig"</string>
@@ -273,32 +272,31 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Oprettelsen af vCard startede ikke korrekt."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" kunne ikke åbnes: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> af <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontakter"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Annullerer import af vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Vil du annullere import af <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Annullerer eksport af vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Vil du annullere eksport af <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Import/eksport af vCard kunne ikke annulleres"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Navne på dine kontakter"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Tilføj pause på 2 sek."</string>
     <string name="add_wait" msgid="3360818652790319634">"Tilføj Vent"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Ring ved hjælp af"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Vælg nummer"</string>
     <string name="call_settings" msgid="7666474782093693667">"Indstillinger"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Send sms ved hjælp af"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Vælg nummer"</string>
     <string name="make_primary" msgid="5829291915305113983">"Husk dette valg"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Der blev ikke fundet nogen app, der kan håndtere denne handling."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Intet navn)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Konti"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Ryd hyppige"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakter, der skal vises"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importer og eksporter"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import/eksport kontakter"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importer kontaktpersoner"</string>
     <string name="menu_share" msgid="943789700636542260">"Del"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Alle kontaktpersoner"</string>
     <string name="share_via" msgid="563121028023030093">"Del kontakt via"</string>
     <string name="share_error" msgid="948429331673358107">"Denne kontaktperson kan ikke deles."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Navn"</string>
     <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Kaldenavn"</string>
     <string name="organizationLabelsGroup" msgid="2478611760751832035">"Organisation"</string>
-    <string name="websiteLabelsGroup" msgid="4202998982804009261">"Websted"</string>
+    <string name="websiteLabelsGroup" msgid="4202998982804009261">"Website"</string>
     <string name="eventLabelsGroup" msgid="3695433812142818803">"Begivenheder"</string>
     <string name="relationLabelsGroup" msgid="1854373894284572781">"Forhold"</string>
     <string name="groupsLabel" msgid="8573535366319059326">"Grupper"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Vis personers navne som"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Fornavn først"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Efternavn først"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Søg i kontakter"</string>
     <string name="take_photo" msgid="7496128293167402354">"Tag billede"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Tag nyt billede"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Vælg billede fra Galleri"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"flettet fra <xliff:g id="COUNT">%0$d</xliff:g> kilder"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Andre"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Saml kontaktpersoner"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Forbind den aktuelle kontaktperson med den valgte kontaktperson?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Rediger valgte kontaktpersoner"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Vil du redigere den valgte kontaktperson? Dine indtastninger kopieres."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopier til Mine kontaktpersoner"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Føj til mine kontaktpersoner"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Indstillinger"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Viste kontaktpersoner"</string>
     <string name="menu_settings" msgid="377929915873428211">"Indstillinger"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Hjælp"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Indstillinger for visning"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Find kontaktpersoner"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Indlæser…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Opret ny kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Log ind på en konto"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importer kontrakter fra en fil"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importer kontaktpersoner"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Opret en ny gruppe"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Opret en ny gruppe]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Slet gruppe"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Opret en ny gruppe"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 gruppe"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupper"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Indstil standard"</string>
     <string name="clear_default" msgid="7193185801596678067">"Ryd standarder"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Kopieret tekst"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Kasser ændringer"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Skal ændringerne slettes?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Opret min profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Indtast personens navn"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Se opdateringer"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Telefonsvarer"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> telefonsvarerbeskeder"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Spil"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nye besked fra <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Telefonbeskeden kunne ikke afspilles."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Gem lokalt"</string>
     <string name="add_account" msgid="8201790677994503186">"Tilføj konto"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Tilføj ny konto"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Opkaldet blev ikke sendt"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Nummer til telefonsvarer utilgængeligt"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Opkaldet blev ikke sendt"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Hvis du vil konfigurere telefonsvareren, skal du gå til Menu &gt; Indstillinger."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Hvis du vil ringe til telefonsvareren, skal du først slå Flytilstand fra."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Flere valgmuligheder"</string>
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 704ccae..41431bd 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Suche"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Neuer Kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Kontakt anzeigen"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"<xliff:g id="NAME">%s</xliff:g> anrufen"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"<xliff:g id="NUMBER">%s</xliff:g> wählen"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Zu Favoriten hinzufügen"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Aus Favoriten entfernen"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Bearbeiten"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Löschen"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopieren"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Auf Startbildschirm platzieren"</string>
     <string name="menu_call" msgid="3992595586042260618">"Kontakt anrufen"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"SMS an Kontakt"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Trennen"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Vorgeschlagene Kontakte"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Alle Kontakte"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontakte wurden verknüpft."</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Kontakt löschen?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Klingeltonwahl"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Alle Anrufe an Mailbox"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Sie können keine Kontakte aus schreibgeschützten Konten löschen. Sie können sie aber in Ihren Kontaktlisten ausblenden."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Unternehmen"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titel"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Dieser Kontakt existiert nicht."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontakt-Widget zum Startbildschirm hinzugefügt"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Neuen Kontakt erstellen"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Neuen Kontakt erstellen"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> gefunden"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Mehr als <xliff:g id="COUNT">%d</xliff:g> gefunden"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Keine Kontakte gefunden"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Keine Kontakte"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 gefunden"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> gefunden"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Alle"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Alle Kontakte"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Gruppen"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriten"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Anrufliste löschen?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Ihre gesamte Anrufliste wird gelöscht."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Anrufliste wird gelöscht..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Liste \"Häufig kontaktiert\" löschen?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Sie löschen die Liste \"Häufig kontaktiert\" in den Apps \"Kontakte\" und \"Telefon\" und geben Ihre Adresseinstellungen für E-Mail-Apps neu ein."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"\"Häufig kontaktiert\" wird gelöscht…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Mailbox"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> Minuten, <xliff:g id="SECONDS">%s</xliff:g> Sekunden"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Häufig kontaktiert"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Häufig angerufen"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Kontakt hinzufügen"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"\"<xliff:g id="EMAIL">%s</xliff:g>\" zu den Kontakten hinzufügen?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"eins"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"zwei"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Kontakt anzeigen"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Kein Speicher verfügbar"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Keine SD-Karte"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Kein Speicher gefunden"</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Keine SD-Karte gefunden"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard wird gesucht."</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Von SIM-Karte importieren"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Aus Speicher importieren"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"In Speicher exportieren"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Alle vCard-Dateien importieren"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Suche nach vCard-Daten im Speicher..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Suche nach vCard-Daten auf der SD-Karte..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Scannen des Speichers nicht möglich"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Scannen der SD-Karte nicht möglich"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Der Speicher konnte nicht gelesen werden. (Grund: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Die SD-Karte konnte nicht gelesen werden. (Grund: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"E/A-Fehler"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> wird demnächst exportiert."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Die vCard-Exportanfrage wurde abgelehnt. Bitte versuchen Sie es später erneut."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"Kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s %%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Kontakte exportieren?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Ihre Kontaktliste wird in die Datei \"<xliff:g id="VCARD_FILENAME">%s</xliff:g>\" exportiert."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Export nicht möglich"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Das Programm zum Erstellen der vCard wurde nicht richtig gestartet."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" konnte nicht geöffnet werden: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> von <xliff:g id="TOTAL_NUMBER">%s</xliff:g> Kontakten"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard-Import wird abgebrochen."</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Import von <xliff:g id="FILENAME">%s</xliff:g> abbrechen?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard-Export wird abgebrochen."</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Export von <xliff:g id="FILENAME">%s</xliff:g> abbrechen?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCard-Import/-Export nicht abgebrochen"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Namen meiner Kontakte"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2 Sekunden Pause hinzufügen"</string>
     <string name="add_wait" msgid="3360818652790319634">"Warten hinzufügen"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Anruf bei"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Nummer auswählen"</string>
     <string name="call_settings" msgid="7666474782093693667">"Einstellungen"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"SMS schreiben an"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Nummer auswählen"</string>
     <string name="make_primary" msgid="5829291915305113983">"Diese Auswahl speichern"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Für diese Aktion wurde keine App gefunden."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Kein Name)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Konten"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"\"Häufig kontaktiert\" löschen"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakte zum Anzeigen"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importieren/Exportieren"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import/Export von Kontakten"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Kontakte importieren"</string>
     <string name="menu_share" msgid="943789700636542260">"Teilen"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Alle Kontakte"</string>
     <string name="share_via" msgid="563121028023030093">"Kontakt teilen über"</string>
     <string name="share_error" msgid="948429331673358107">"Dieser Kontakt kann nicht geteilt werden."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Name"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Kontaktnamen-Anzeige:"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Vorname zuerst"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Nachname zuerst"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"In Kontakten suchen"</string>
     <string name="take_photo" msgid="7496128293167402354">"Foto machen"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Neues Foto aufnehmen"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Foto aus Galerie auswählen"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"aus <xliff:g id="COUNT">%0$d</xliff:g> Quellen zusammengeführt"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Sonstige"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Kontakte zusammenführen"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Aktuellen Kontakt mit ausgewähltem Kontakt zusammenführen?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Ausgewählte Kontakte bearbeiten"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Zur Bearbeitung des ausgewählten Kontakts wechseln? Die bisher eingegebenen Informationen werden kopiert."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"In meine Kontakte kopieren"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Zu meinen Kontakten hinzufügen"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Einstellungen"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakte zum Anzeigen"</string>
     <string name="menu_settings" msgid="377929915873428211">"Einstellungen"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Hilfe"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Anzeigeoptionen"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Kontakte suchen"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Wird geladen…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Neuen Kontakt erstellen"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"In einem Konto anmelden"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Kontakte aus einer Datei importieren"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Kontakte importieren"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Neue Gruppe erstellen"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Neue Gruppe erstellen]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Gruppe löschen"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Neue Gruppe erstellen"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 Gruppe"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> Gruppen"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Als Standard festlegen"</string>
     <string name="clear_default" msgid="7193185801596678067">"Als Standard löschen"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Text kopiert"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Änderungen verwerfen"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Sollen die Änderungen verworfen werden?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Mein Profil einrichten"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Name der Person eingeben"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Updates anzeigen"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Mailbox-Nachricht"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Mailbox-Nachrichten"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Anhören"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Neue Mailbox-Nachricht von <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Abhören der Mailbox nicht möglich"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Lokal speichern"</string>
     <string name="add_account" msgid="8201790677994503186">"Konto hinzufügen"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Neues Konto hinzufügen"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Anruf nicht verbunden"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Mailbox-Nummer nicht verfügbar"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Anruf nicht verbunden"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Konfigurieren Sie Ihre Mailbox unter \"Menü\" &gt; \"Einstellungen\"."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Deaktivieren Sie zunächst den Flugmodus, um die Mailbox anzurufen."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Mehr Optionen"</string>
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 15b7b91..9010745 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Αναζήτηση"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Νέα επαφή"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Προβολή επαφής"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Κλήση <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Κλήση του αριθμού <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Προσθήκη στα αγαπημένα"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Κατάργηση από τα αγαπημένα"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Επεξεργασία"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Διαγραφή"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Αντιγραφή"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Τοποθέτηση στην αρχική οθόνη"</string>
     <string name="menu_call" msgid="3992595586042260618">"Κλήση επαφής"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Αποστολή μηνύματος κειμένου σε επαφή"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Διαχωρισμός"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Προτεινόμενες επαφές"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Όλες οι επαφές"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Οι επαφές συνδέθηκαν"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Διαγραφή επαφής;"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Ήχος κλήσης"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Κλήσεις στον τηλεφωνητή"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Δεν μπορείτε να διαγράψετε επαφές από λογαριασμούς οι οποίοι προορίζονται μόνο για ανάγνωση, αλλά μπορείτε να τις αποκρύψετε στις λίστες επαφών σας."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Εταιρεία"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Τίτλος"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Η επαφή δεν υπάρχει."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Το γραφικό στοιχείο επαφών προστέθηκε στην αρχική οθόνη."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Δημιουργία νέας επαφής"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Δημιουργία νέας επαφής"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Τηλέφωνο"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Βρέθηκαν <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Βρέθηκαν περισσότερα από <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Δεν βρέθηκε καμία."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Δεν υπάρχουν επαφές"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Βρέθηκε 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Βρέθηκαν <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Όλα"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Όλες οι επαφές"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Ομάδες"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Αγαπ."</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Τηλέφωνο"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Εκκαθάριση αρχείου;"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Όλα τα αρχεία κλήσεων θα διαγραφούν."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Εκκαθάριση αρχ. καταγραφής κλήσεων…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Διαγραφή ατόμων με συχνή επικοινωνία;"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Θα διαγράψετε τη λίστα ατόμων με τα οποία είχατε συχνή επικοινωνία στις εφαρμογές \"Άτομα\" και \"Τηλέφωνο\" και θα κάνετε τις εφαρμογές ηλεκτρονικού ταχυδρομείου να μάθουν τις προτιμήσεις επικοινωνίας σας από την αρχή."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Διαγρ. ατόμων με συχνή επικοινωνία…"</string>
     <string name="imei" msgid="3045126336951684285">"Αριθμός ΙΜΕΙ"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Αυτόματος τηλεφωνητής"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> λεπτά <xliff:g id="SECONDS">%s</xliff:g> δευτερόλεπτα"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Επαφές που έχετε συχνή επικοινωνία"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Συχνές κλήσεις"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Προσθήκη επαφής"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Προσθήκη του \"<xliff:g id="EMAIL">%s</xliff:g>\" στις επαφές?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"ένα"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"δύο"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"μείον"</string>
     <string name="description_plus_button" msgid="515164827856229880">"συν"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Προβολή επαφής"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Μη διαθέσιμος χώρος αποθ."</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Δεν υπάρχει κάρτα SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Δεν βρέθηκε χώρος αποθήκευσης."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Δεν βρέθηκε κάρτα SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Αναζήτηση κάρτας vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Εισαγωγή από κάρτα SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Εισαγωγή από τον χώρο αποθ."</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Εξαγωγή στον χώρο αποθ."</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Εισαγωγή όλων των αρχείων vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Αναζήτηση δεδομένων vCard στον χώρο αποθήκευσης..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Αναζήτηση για δεδομένα vCard στην κάρτα SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Δεν ήταν δυνατή η σάρωση του χώρου αποθήκευσης"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Δεν ήταν δυνατή η σάρωση της κάρτας SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Δεν ήταν δυνατή η σάρωση του χώρου αποθήκευσης. (Αιτία: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Δεν ήταν δυνατή η σάρωση της κάρτας SD. (Αιτία: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Σφάλμα I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Η <xliff:g id="FILENAME">%s</xliff:g> θα εξαχθεί σύντομα."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Το αίτημα εξαγωγής vCard απορρίφθηκε. Δοκιμάστε ξανά αργότερα."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"επαφή"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Εξαγωγή επαφών;"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Η λίστα επαφών σας θα εξαχθεί στο αρχείο: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Αδυναμία εξαγωγής"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Η έναρξη της vCard δεν ήταν σωστή."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Δεν ήταν δυνατό το άνοιγμα του αρχείου \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> από <xliff:g id="TOTAL_NUMBER">%s</xliff:g> επαφές"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Ακύρωση εισαγωγής της vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Να ακυρωθεί η εισαγωγή του αρχείου <xliff:g id="FILENAME">%s</xliff:g>;"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Ακύρωση εξαγωγής της vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Να ακυρωθεί η εξαγωγή του αρχείου <xliff:g id="FILENAME">%s</xliff:g>;"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Αδ.ακύρ.εισαγ./εξαγ.vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Ονόματα ων επαφών σας"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Προσθήκη παύσης 2 δευτερολέπτων"</string>
     <string name="add_wait" msgid="3360818652790319634">"Προσθήκη αναμονής"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Κλήση με τη χρήση"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Επιλέξτε αριθμό"</string>
     <string name="call_settings" msgid="7666474782093693667">"Ρυθμίσεις"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Αποστολή κειμένου με χρήση"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Επιλέξτε αριθμό"</string>
     <string name="make_primary" msgid="5829291915305113983">"Διατήρηση αυτής της ρύθμισης"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Δεν βρέθηκε εφαρμογή για τη διαχείριση αυτής της ενέργειας."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Χωρίς όνομα)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Λογαριασμοί"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Διαγραφή ατόμ. με συχνή επικ."</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Επαφές για εμφάνιση"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Εισαγωγή/Εξαγωγή"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Εισαγωγή/Εξαγωγή επαφών"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Εισαγωγή επαφών"</string>
     <string name="menu_share" msgid="943789700636542260">"Κοινή χρήση"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Όλες οι επαφές"</string>
     <string name="share_via" msgid="563121028023030093">"Κοινή χρήση μέσω"</string>
     <string name="share_error" msgid="948429331673358107">"Δεν είναι δυνατή η κοινή χρήση αυτής της επαφής."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Όνομα"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Προβολή ονομάτων επαφών ως"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Πρώτα το όνομα"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Πρώτα το επίθετο"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Αναζήτηση επαφών"</string>
     <string name="take_photo" msgid="7496128293167402354">"Λήψη φωτογραφίας"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Λήψη νέας φωτογραφίας"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Επιλογή φωτογραφιών από τη Συλλογή"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"συγχώνευση από <xliff:g id="COUNT">%0$d</xliff:g> προελεύσεις"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Άλλο"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Ένωση επαφών"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Να γίνει ένωση της τρέχουσας επαφής με την επιλεγμένη επαφή;"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Επεξεργασία επιλεγμένων επαφών"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Να γίνει μετάβαση σε επεξεργασία της επιλεγμένης επαφής; Θα γίνει αντιγραφή των στοιχείων που έχετε εισαγάγει μέχρι τώρα."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Αντιγραφή στις Επαφές μου"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Προσθήκη στις Επαφές μου"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Ρυθμίσεις"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Επαφές για προβολή"</string>
     <string name="menu_settings" msgid="377929915873428211">"Ρυθμίσεις"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Βοήθεια"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Επιλογές προβολής"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Εύρεση επαφών"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Φόρτωση…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Δημιουργία νέας επαφής"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Σύνδεση σε έναν λογαριασμό"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Εισαγωγή επαφών από ένα αρχείο"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Εισαγωγή επαφών"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Δημιουργία νέας ομάδας"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Δημιουργία νέας ομάδας]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Διαγραφή ομάδας"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Δημιουργία νέας ομάδας"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 ομάδα"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> ομάδες"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Ορισμός ως προεπιλογή"</string>
     <string name="clear_default" msgid="7193185801596678067">"Εκκαθάριση προεπιλεγμένων"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Το κείμενο αντιγράφηκε"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Απόρριψη αλλαγών"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Να απορριφθούν οι αλλαγές σας;"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Ρύθμιση του προφίλ μου"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Πληκτρολογήστε το όνομα του ατόμου"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Προβολή ενημερώσεων"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Αυτόματος τηλεφωνητής"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> μηνύμ. αυτόμ. τηλεφωνητή"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Αναπαραγωγή"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Νέα μην. αυτ. τηλεφ. από <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Δεν αναπαράχθηκαν τα μην. αυτ. τηλεφ."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Αποθήκευση τοπικά"</string>
     <string name="add_account" msgid="8201790677994503186">"Προσθήκη λογαριασμού"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Προσθήκη νέου λογαριασμού"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Η κλήση δεν πραγματοποιήθηκε."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Μη διαθέσιμος αριθμός αυτόμ. τηλεφωνητή"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Η κλήση δεν πραγματοποιήθηκε"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Για τη r;yumish του αυτόματου τηλεφωνητή, μεταβείτε στο στοιχείο Μενού &gt; Ρυθμίσεις."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Για κλήση αυτόματου τηλεφωνητή, πρώτα απενεργοποιήστε τη λειτουργία πτήσης."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Περισσότερες επιλογές"</string>
 </resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 72a67b3..a601cda 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Search"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"New contact"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"View contact"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Call <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Call <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Add to favourites"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Remove from favourites"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Edit"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Delete"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copy"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Place on Home screen"</string>
     <string name="menu_call" msgid="3992595586042260618">"Call contact"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Text contact"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separate"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Suggested Contacts"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"All contacts"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contacts joined"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Delete contact?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Set ringtone"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"All calls to voicemail"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"You can\'t delete contacts from read-only accounts, but you can hide them in your contacts lists."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Company"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Title"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"The contact doesn\'t exist."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Contact widget added to Home screen."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Create new contact"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Create new contact"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Phone"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> found"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"More than <xliff:g id="COUNT">%d</xliff:g> found."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"None found."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"No contacts"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 found"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> found"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"All"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"All contacts"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Groups"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favourites"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Phone"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Clear call log?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"All your call records will be deleted."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Clearing call log…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Clear frequently contacted?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"You\'ll clear the frequently contacted list in the People and Phone apps and force email apps to learn your addressing preferences from scratch."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Clearing frequently contacted…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> mins <xliff:g id="SECONDS">%s</xliff:g> secs"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Frequently contacted"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Frequently called"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Add contact"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Add \"<xliff:g id="EMAIL">%s</xliff:g>\" to contacts?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"one"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"two"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"View contact"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Storage unavailable"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"No SD card"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No storage was found."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"No SD card was found."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Searching for vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Import from SIM card"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Import from storage"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Export to storage"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Import all vCard files"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Searching for vCard data in storage…"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Searching for vCard data on SD card"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Couldn\'t scan storage"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Couldn\'t scan SD card"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"The storage couldn\'t be scanned. (Reason: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"The SD card couldn\'t be scanned. (Reason: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O error"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> will be exported shortly."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard export request was rejected. Try again later."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contact"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Export contacts?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Your contact list will be exported to file: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Couldn\'t export"</string>
@@ -273,28 +272,27 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"The vCard composer didn\'t start properly."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Couldn\'t open \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> of <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contacts"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Cancelling vCard import"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Cancel import of <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Cancelling vCard export"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Cancel export of <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Couldn\'t cancel vCard import/export"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Names of your contacts"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Add 2-sec pause"</string>
     <string name="add_wait" msgid="3360818652790319634">"Add wait"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Call using"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Choose number"</string>
     <string name="call_settings" msgid="7666474782093693667">"Settings"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Text using"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Choose number"</string>
     <string name="make_primary" msgid="5829291915305113983">"Remember this choice"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"No app was found to handle this action."</string>
     <string name="missing_name" msgid="8745511583852904385">"(No name)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Accounts"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Clear frequents"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contacts to display"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Import/export"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import/export contacts"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Import contacts"</string>
     <string name="menu_share" msgid="943789700636542260">"Share"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"All contacts"</string>
     <string name="share_via" msgid="563121028023030093">"Share contact via"</string>
-    <string name="share_error" msgid="948429331673358107">"This contact can\'t be shared."</string>
+    <string name="share_error" msgid="948429331673358107">"This contact cannot be shared."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Name"</string>
     <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Nickname"</string>
     <string name="organizationLabelsGroup" msgid="2478611760751832035">"Organisation"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"View contact names as"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"First name first"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Surname first"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Search contacts"</string>
     <string name="take_photo" msgid="7496128293167402354">"Take photo"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Take new photo"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Choose photo from Gallery"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"merged from <xliff:g id="COUNT">%0$d</xliff:g> sources"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Other"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Join contacts"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Join the current contact with the selected contact?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Edit selected contacts"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Switch to editing the selected contact? Information that you\'ve entered so far will be copied."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copy to My Contacts"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Add to My Contacts"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Settings"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contacts to display"</string>
     <string name="menu_settings" msgid="377929915873428211">"Settings"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Help"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Display options"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Find contacts"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Loading…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Create a new contact"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Sign in to an account"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Import contacts from a file"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Import contacts"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Create new group"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Create new group]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Delete group"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Create new group"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 group"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> groups"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Set default"</string>
     <string name="clear_default" msgid="7193185801596678067">"Clear default"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Text copied"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Discard changes"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Discard your changes?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Set up my profile"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Type person\'s name"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"View updates"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Voicemail"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Voicemails"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Play"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"New voicemail from <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Couldn\'t play voicemail."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Keep locally"</string>
     <string name="add_account" msgid="8201790677994503186">"Add account"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Add new account"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Call not sent."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Voicemail number unavailable"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Call not sent"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"To set up voicemail, go to Menu &gt; Settings."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"To call voicemail, first turn off Aeroplane mode."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"More options"</string>
 </resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index edb441d..738822c 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Buscar"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nuevo contacto"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Ver contacto"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Llamar a <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Llamar al <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Agregar a favoritos"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Eliminar de favoritos"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Editar"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Eliminar"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copiar"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Colocar en pantalla principal"</string>
     <string name="menu_call" msgid="3992595586042260618">"Llamar al contacto"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Enviar texto al contacto"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separar"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contactos sugeridos"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Todos los contactos"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Unión de contactos"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"¿Eliminar contacto?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Establecer tono"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Llamadas al buzón de voz"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"No puedes eliminar contactos de cuentas de solo lectura, pero puedes ocultarlos en tus listas de contactos."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Empresa"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Título"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"El contacto no existe."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"El widget de contactos se agregó a la pantalla principal."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Crear nuevo contacto"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Crear contacto nuevo"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Teléfono"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> encontrado(s)"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Se encontraron más de <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"No se encontró ninguno."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"No hay contactos"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Se encontró uno (1)"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> encontrado(s)"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Todos"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Todos los contactos"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Teléfono"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"¿Eliminar registro?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Se eliminarán todos tus registros de llamadas."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Borrando registro de llamadas..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"¿Borrar los contactos frecuentes?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Estás a punto de borrar la lista de contactos frecuentes de las aplicaciones Personas y Teléfono y harás que las aplicaciones de correo deban aprender nuevamente tus preferencias."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Borrando contactos frecuentes…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Correo de voz"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> seg."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Contactado con frecuencia"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Llamados con frecuencia"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Agregar contacto"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"¿Deseas agregar \"<xliff:g id="EMAIL">%s</xliff:g>\" a los contactos?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"uno"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dos"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
     <string name="description_plus_button" msgid="515164827856229880">"más"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Ver contacto"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"No se dispone de espacio de almacenamiento."</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"No hay tarjeta SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No se encontró almacenamiento."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"No se encontró una tarjeta SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Buscando vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importar de la tarjeta SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importar desde el almacenamiento"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportar al almacenamiento"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importar todos los archivos de vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Buscando datos de vCard en el almacenamiento..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Buscando datos de vCard en la tarjeta SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"No se pudo explorar el almacenamiento."</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"No se pudo explorar la tarjeta SD."</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"No se pudo examinar el almacenamiento. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")."</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"No se pudo examinar la tarjeta SD. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Error de E/S"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> se exportará en breve."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Se rechazó la solicitud de exportación de la vCard. Vuelve a intentarlo más tarde."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contacto"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"¿Exportar contactos?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Tu lista de contactos se exportará al archivo: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"No se pudo exportar"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"El compositor de la vCard no se inició correctamente."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"No se pudo abrir \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> de <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contactos"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Cancelación de importación de vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"¿Deseas cancelar la importación de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Cancelación de exportación de vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"¿Deseas cancelar la exportación de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"No se canceló la impor./expor. de vCard."</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Nombres de tus contactos"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Agregar pausa de 2 segundos"</string>
     <string name="add_wait" msgid="3360818652790319634">"Agregar espera"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Llamar con"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Elije un número"</string>
     <string name="call_settings" msgid="7666474782093693667">"Configuración"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Texto con"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Elije un número"</string>
     <string name="make_primary" msgid="5829291915305113983">"Recuerda esta opción"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"No se encontró ninguna aplicación que pueda realizar esta acción."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Sin nombre)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Cuentas"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Borrar contactos frecuentes"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contactos para mostrar"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importar/Exportar"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Imp./exp. contactos"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importar contactos"</string>
     <string name="menu_share" msgid="943789700636542260">"Compartir"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Todos los contactos"</string>
     <string name="share_via" msgid="563121028023030093">"Compartir un contacto a través de"</string>
     <string name="share_error" msgid="948429331673358107">"No es posible compartir este contacto."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nombre"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Mostrar contactos por"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nombre Apellido"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Apellido Nombre"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Buscar contactos"</string>
     <string name="take_photo" msgid="7496128293167402354">"Tomar foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Tomar nueva foto"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Elige una foto de la Galería."</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"combinado a partir de fuentes <xliff:g id="COUNT">%0$d</xliff:g>"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Otro"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Agrupar contactos"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"¿Deseas agrupar el contacto actual con el contacto seleccionado?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Modificar contactos seleccionados"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"¿Optar por modificar contacto seleccionado? Se copiará la información que ingresaste hasta ahora."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copiar en Mis contactos"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Agregar a Mis contactos"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Configuración"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contactos para mostrar"</string>
     <string name="menu_settings" msgid="377929915873428211">"Configuración"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ayuda"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opciones de visualización"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Buscar contactos"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Cargando..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Crear un contacto nuevo"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Accede a una cuenta"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importar contactos desde un archivo"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importar contactos"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Crear grupo nuevo"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Crear grupo nuevo]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Eliminar grupo"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Crear grupo nuevo"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupo"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupos"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Establecer como predeterminado"</string>
     <string name="clear_default" msgid="7193185801596678067">"Eliminar predeterminado"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Texto copiado"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Descartar cambios"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"¿Deseas descartar los cambios?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configurar mi perfil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Escribe el nombre de la persona."</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Ver actualizaciones"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Mensaje de voz"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> mensajes de voz"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproducir"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nuevo mensaje de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"No se pudo reproducir el mensaje de voz."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Guardar localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Agregar una cuenta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Agregar una cuenta nueva"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"No se realizó la llamada."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Número de buzón de voz no disponible"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"No se realizó la llamada."</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar el buzón de voz, ve a a Menú &gt; Configuración."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para escuchar los mensajes de tu buzón de voz, desactiva primero el modo de avión."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Más opciones"</string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 0f06f92..33a3b36 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Buscar"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Contacto nuevo"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Ver contacto"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Llamar a <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Llamar a <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Añadir a \"Favoritos\""</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Eliminar de \"Favoritos\""</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Editar"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Eliminar"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copiar"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Añadir al escritorio"</string>
     <string name="menu_call" msgid="3992595586042260618">"Llamar al contacto"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Enviar SMS al contacto"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Dividir"</string>
@@ -62,9 +64,8 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contactos sugeridos"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Todos los contactos"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contactos agrupados"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"¿Eliminar contacto?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Establecer tono"</string>
-    <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Llamadas al buzón de voz"</string>
+    <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Al buzón de voz"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"No puedes eliminar los contactos procedentes de las cuentas de solo lectura, pero puedes ocultarlos en las listas de contactos."</string>
     <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"Este contacto contiene información de varias cuentas. La información de las cuentas de solo lectura se ocultará en las listas de contactos, pero no se eliminará."</string>
     <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"Si se elimina este contacto, se eliminará la información de varias cuentas."</string>
@@ -75,13 +76,14 @@
     <string name="label_notes" msgid="8337354953278341042">"Notas"</string>
     <string name="label_sip_address" msgid="124073911714324974">"Llamada por Internet"</string>
     <string name="ghostData_company" msgid="5414421120553765775">"Empresa"</string>
-    <string name="ghostData_title" msgid="7496735200318496110">"Título"</string>
+    <string name="ghostData_title" msgid="7496735200318496110">"Cargo"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Este contacto no existe."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"El widget de contactos se ha añadido al escritorio."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Crear contacto nuevo"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Crear contacto nuevo"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Teléfono"</string>
     <string name="emailLabelsGroup" msgid="8389931313045344406">"Correo"</string>
-    <string name="imLabelsGroup" msgid="3898238486262614027">"Nombre de chat"</string>
+    <string name="imLabelsGroup" msgid="3898238486262614027">"Chat"</string>
     <string name="postalLabelsGroup" msgid="3487738141112589324">"Dirección"</string>
   <string-array name="otherLabels">
     <item msgid="8287841928119937597">"Organización"</item>
@@ -90,7 +92,7 @@
     <string name="photoPickerNotFoundText" product="tablet" msgid="6247290728908599701">"No hay ninguna imagen disponible en el tablet."</string>
     <string name="photoPickerNotFoundText" product="default" msgid="431331662154342581">"No hay ninguna imagen disponible en el teléfono."</string>
     <string name="attach_photo_dialog_title" msgid="5599827035558557169">"Foto de contacto"</string>
-    <string name="customLabelPickerTitle" msgid="1081475101983255212">"Nombre de etiqueta personalizada"</string>
+    <string name="customLabelPickerTitle" msgid="1081475101983255212">"Nombre de campo personalizado"</string>
     <string name="send_to_voicemail_checkbox" msgid="9001686764070676353">"Enviar llamadas directamente al buzón de voz"</string>
     <string name="removePhoto" msgid="4898105274130284565">"Eliminar foto"</string>
     <string name="noContacts" msgid="8579310973261953559">"No hay ningún contacto."</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> encontrados"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Se han encontrado más de <xliff:g id="COUNT">%d</xliff:g> contactos."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"No hay contactos."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"No hay contactos."</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 encontrado"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> encontrados"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Todos"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Todos los contactos"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Teléfono"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"¿Borrar registro?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Se eliminarán todos los registros de llamadas."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Borrando registro de llamadas..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"¿Borrar contactos frecuentes?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Vas a borrar la lista de contactos frecuentes de las aplicaciones Contactos y Teléfono y obligarás a las aplicaciones de correo electrónico a que memoricen tus preferencias de nuevo."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Borrando contactos frecuentes…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Buzón de voz"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. y <xliff:g id="SECONDS">%s</xliff:g> seg."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Contactos frecuentes"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Más llamados"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Añadir contacto"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"¿Quieres añadir \"<xliff:g id="EMAIL">%s</xliff:g>\" a Contactos?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"uno"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dos"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
     <string name="description_plus_button" msgid="515164827856229880">"más"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Ver contacto"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Almacenamiento no disponible"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Falta la tarjeta SD."</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No hay ningún almacenamiento."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"No se ha detectado ninguna tarjeta SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Buscando vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importar contactos desde la tarjeta SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importar de USB"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportar a almacenamiento"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importar todos los archivos de vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Buscando datos de vCard en el almacenamiento..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Buscando datos de vCard en la tarjeta SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"No se ha podido analizar el almacenamiento."</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"No se ha podido analizar la tarjeta SD."</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"No se ha podido analizar el almacenamiento (motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")."</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"No se ha podido analizar la tarjeta SD (motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")."</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Error de E/S"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> se exportará en breve."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Se ha rechazado la solicitud de exportación de vCard. Inténtalo de nuevo más tarde."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contacto"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"¿Exportar contactos?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Tu lista de contactos se exportará al archivo <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Error al exportar"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"El redactor de vCard no se ha iniciado correctamente."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"No se ha podido abrir el archivo \"<xliff:g id="FILE_NAME">%s</xliff:g>\" (<xliff:g id="EXACT_REASON">%s</xliff:g>)."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> de <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contactos"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Cancelando importación de vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"¿Seguro que quieres cancelar la importación de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Cancelando exportación de vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"¿Seguro que quieres cancelar la exportación de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Error al cancelar la importación/exportación de vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Nombres de tus contactos"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Añadir pausa de dos segundos"</string>
     <string name="add_wait" msgid="3360818652790319634">"Añadir espera"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Llamar a través de"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Elige un número"</string>
     <string name="call_settings" msgid="7666474782093693667">"Ajustes"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Enviar SMS a través de"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Elige un número"</string>
     <string name="make_primary" msgid="5829291915305113983">"Recordar esta opción"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"No se ha detectado ninguna aplicación que pueda hacer esta acción."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Sin nombre)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Cuentas"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Borrar frecuentes"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contactos que mostrar"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importar/exportar"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importar/exportar contactos"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importar contactos"</string>
     <string name="menu_share" msgid="943789700636542260">"Compartir"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Todos los contactos"</string>
     <string name="share_via" msgid="563121028023030093">"Compartir contacto a través de"</string>
     <string name="share_error" msgid="948429331673358107">"No se puede compartir este contacto."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nombre"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Ver nombres de contactos por"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nombre primero"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Apellidos primero"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Buscar contactos"</string>
     <string name="take_photo" msgid="7496128293167402354">"Hacer una foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Hacer una foto nueva"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Seleccionar foto de la galería"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"fusionados desde <xliff:g id="COUNT">%0$d</xliff:g> fuentes"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Otro"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Agrupar contactos"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"¿Quieres agrupar el contacto actual con el contacto seleccionado?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Editar contactos seleccionados"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"¿Quieres editar el contacto seleccionado? Se copiará la información que hayas introducido hasta el momento."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copiar en mis contactos"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Añadir a Mis contactos"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Ajustes"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contactos que mostrar"</string>
     <string name="menu_settings" msgid="377929915873428211">"Ajustes"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ayuda"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opciones de visualización"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Buscar contactos"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Cargando..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Crear contacto nuevo"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Acceder a una cuenta"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importar contactos de un archivo"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importar contactos"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Crear grupo nuevo"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Crear grupo nuevo]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Eliminar grupo"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Crear grupo nuevo"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Un grupo"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupos"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Establecer como predeterminado"</string>
     <string name="clear_default" msgid="7193185801596678067">"Borrar predeterminado"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Texto copiado"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Descartar cambios"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"¿Seguro que quieres descartar los cambios?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configurar mi perfil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Escribe el nombre de la persona"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Ver actualizaciones"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Mensaje de voz"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> mensajes de voz"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproducir"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nuevo mensaje de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"No se ha podido reproducir el mensaje."</string>
@@ -560,8 +555,9 @@
     <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Puedes sincronizar tu nuevo contacto con una de las siguientes cuentas. ¿Cuál quieres usar?"</string>
     <string name="keep_local" msgid="1258761699192993322">"Guardar localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Añadir cuenta"</string>
-    <string name="add_new_account" msgid="5748627740680940264">"Añadir una cuenta nueva"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Llamada no enviada"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Número del buzón de voz no disponible"</string>
+    <string name="add_new_account" msgid="5748627740680940264">"Añadir una cuenta"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Llamada no enviada"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar el buzón de voz, toca la tecla de menú y, a continuación, toca Ajustes."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para llamar al buzón de voz, debes desactivar el modo avión."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Más opciones"</string>
 </resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 087fb7a..013febb 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Otsing"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Uus kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Kuva kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Helista kasutajale <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Helistage: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Lisa lemmikutesse"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Eemalda lemmikutest"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Muuda"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Kustuta"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopeeri"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Paiguta avalehele"</string>
     <string name="menu_call" msgid="3992595586042260618">"Helista kontaktile"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Saada kontaktile SMS"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Eralda"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Soovitatud kontaktid"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Kõik kontaktid"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontaktid ühendatud"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Kustutada kontakt?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Määrake helin"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Kõik kõned kõneposti"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Te ei saa kontakte kirjutuskaitstud kontodest kustutada, kuid saate need oma kontaktide loendis peita."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Ettevõte"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Pealkiri"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakti ei ole olemas."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontaktividin lisati avalehele."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Loo uus kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Loo uus kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> leitud"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Leitud rohkem kui <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Puuduvad."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Kontakte pole"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 leitud"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> leitud"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Kõik"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Kõik kontaktid"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupid"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Lemmikud"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Kustutada kõnelogi?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Kõik teie kõnesalvestised kustutatakse."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Kõnelogi kustutamine ..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Kas kustutada sagedased kontaktid?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Kustutate jaotistes Inimesed ja Telefonirakendused loendi Sagedased kontaktid ning meilirakendused peavad teie adresseerimiseelistused uuesti omandama."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Saged. kontaktide kustutamine ..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Kõnepost"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Sageli valitud kontaktid"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Sageli valitud üksus"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Lisa kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Kas lisada „<xliff:g id="EMAIL">%s</xliff:g>” kontaktidesse?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"üks"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"kaks"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"miinus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"pluss"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Vaadake kontakti"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Mäluseade pole saadaval"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"SD-kaart puudub"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Mäluruumi ei leitud."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SD-kaarti ei leitud."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCardi otsimine"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Impordi SIM-kaardilt"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Impordi mäluseadmest"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Ekspordi mäluseadmesse"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Impordi kõik vCardi failid"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Mäluruumist vCardi andmete otsimine ..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"SD-kaardilt vCardi andmete otsimine ..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Mäluseadme skaneering ebaõnnestus"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD-kaardi skaneering ebaõnnestus"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Mäluruumi ei saa kontrollida. (Põhjus: „<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD-kaarti ei saa kontrollida. (Põhjus: „<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O viga"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Fail <xliff:g id="FILENAME">%s</xliff:g> eksporditakse peagi."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCardi eksportimistaotlus lükati tagasi. Proovige hiljem uuesti."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Eksportida kontakt?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Teie kontaktide loend eksporditakse faili: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Eksport ebaõnnestus"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCardi helilooja ei käivitunud korralikult."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Faili „<xliff:g id="FILE_NAME">%s</xliff:g>” ei saa avada: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontaktist"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCardi importimise tühistamine"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Kas tühistada faili <xliff:g id="FILENAME">%s</xliff:g> importimine?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCardi eksportimise tühistamine"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Kas tühistada faili <xliff:g id="FILENAME">%s</xliff:g> eksportimine?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCardi impordi/ekspordi tühist. ebaõnn."</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Teie kontaktide nimed"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Lisa 2-sekundiline paus"</string>
     <string name="add_wait" msgid="3360818652790319634">"Lisa ootama"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Helistamine"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Valige number"</string>
     <string name="call_settings" msgid="7666474782093693667">"Seaded"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Saada SMS:"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Valige number"</string>
     <string name="make_primary" msgid="5829291915305113983">"Pea see valik meeles"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Selle toimingu käsitsemiseks ei leitud ühtegi rakendust."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Nimi puudub)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Kontod"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Sagedaste kustutamine"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kuvatavad kontaktisikud"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Import/eksport"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Kontaktide import/eksport"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Kontaktide importimine"</string>
     <string name="menu_share" msgid="943789700636542260">"Jaga"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Kõik kontaktid"</string>
     <string name="share_via" msgid="563121028023030093">"Kontakti jagamisvalikud"</string>
     <string name="share_error" msgid="948429331673358107">"Seda kontakti ei saa jagada."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nimi"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Kuva kontaktinimed:"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Eesnimi kõigepealt"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Perekonnanimi kõigepealt"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Otsi kontakte"</string>
     <string name="take_photo" msgid="7496128293167402354">"Tee foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Tee uus foto"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Vali foto galeriist"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"ühendati <xliff:g id="COUNT">%0$d</xliff:g> allikast"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Muu"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Kontaktide ühendamine"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Kas ühendada praegune kontakt valitud kontaktiga?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Valitud kontaktide muutmine"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Kas lülituda valitud kontakti muutmisse? Seni sisestatud andmed kopeeritakse."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopeeri valikusse Minu kontaktid"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Lisa lehele Minu kontaktid"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Seaded"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kuvatavad kontaktid"</string>
     <string name="menu_settings" msgid="377929915873428211">"Seaded"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Abi"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Kuvamisvalikud"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Otsige kontakte"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Laadimine ..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Loo uus kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Logi kontole sisse"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Impordi kontaktid failist"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Impordi kontaktid"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Uue grupi loomine"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Uue grupi loomine]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Grupi kustutamine"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Loo uus rühm"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupp"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> rühma"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Määra vaikeseadeks"</string>
     <string name="clear_default" msgid="7193185801596678067">"Kustuta vaikeseaded"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst on kopeeritud"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Loobu muudatustest"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Kas loobute oma muudatustest?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Minu profiili seadistamine"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Sisestage isiku nimi"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Kuva värskendused"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Kõnepost"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> kõnepostisõnumit"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Esitamine"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Uus kõnepostisõnum kasutajalt <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Kõnepostisõnumi esitamine ebaõnnestus."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Hoia kohalikuna"</string>
     <string name="add_account" msgid="8201790677994503186">"Lisa konto"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Lisa uus konto"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Kõnet ei tehtud"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Kõneposti number pole saadaval"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Kõnet ei tehtud"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Kõneposti seadistamiseks minge valikusse Menüü &gt; Seaded."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Kõneposti kuulamiseks lülitage lennurežiim välja."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Rohkem valikuid"</string>
 </resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 2bacc4e..3967d87 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"جستجو"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"مخاطب جدید"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"مشاهده مخاطب"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"تماس با <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"تماس با <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"افزودن به موارد دلخواه"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"حذف از موارد دلخواه"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"ویرایش"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"حذف"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"کپی"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"محل بر روی صفحه اصلی"</string>
     <string name="menu_call" msgid="3992595586042260618">"تماس با مخاطب"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"ارسال متن به مخاطب"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"تفکیک"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"مخاطبین پیشنهادی"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"همه مخاطبین"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"مخاطبین ملحق شده"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"مخاطب حذف شود؟"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"تنظیم آهنگ زنگ"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"همه تماس‌ها به پست صوتی"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"شما نمی‌توانید مخاطبین را از حساب‌های فقط خواندنی حذف کنید اما می‌توانید آن‌ها را در لیست‌های مخاطبین خود پنهان کنید."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"شرکت"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"عنوان"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"مخاطبی موجود نیست."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"ابزارک مخاطب به صفحه اصلی شما اضافه شد."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"ایجاد مخاطب جدید"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"ایجاد مخاطب جدید"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"تلفن"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> یافت شد"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"بیش از <xliff:g id="COUNT">%d</xliff:g> مورد پیدا شد."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"چیزی پیدا نشد."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"مخاطبی موجود نیست"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 مورد پیدا شد"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> یافت شد"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"همه"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"همه مخاطبین"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"گروه ها"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"موارد دلخواه"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"تلفن"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"گزارش تماس پاک شود؟"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"تمام سابقه تماس شما حذف خواهد شد."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"در حال پاک کردن گزارش تماس..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"لیست تماس مکرر با مخاطب پاک شود؟"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"با این کار شما در برنامه «افراد» و «تلفن»، لیست افرادی را که با آن‌ها بیشترین تماس را داشته‌اید پاک خواهید کرد و برنامه‌های ایمیل مجبور می‌شوند تنظیمات برگزیده آدرس‌دهی شما را از اول یاد بگیرند."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"در حال پاک کردن لیست تماس مکرر..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"پست صوتی"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> دقیقه و <xliff:g id="SECONDS">%s</xliff:g> ثانیه"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"اغلب تماس گرفته شده"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"اغلب به نام"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"افزودن مخاطب"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"\"<xliff:g id="EMAIL">%s</xliff:g>\" به مخاطبین افزوده شود؟"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"یک"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"دو"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"منها"</string>
     <string name="description_plus_button" msgid="515164827856229880">"به اضافه"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"مشاهده مخاطب"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"حافظه در دسترس نیست"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"کارت SD موجود نیست"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"هیچ دستگاه ذخیره‌ای یافت نشد."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"کارت SD یافت نشد."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"جستجوی کارت ویزیت"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"وارد کردن از سیم کارت"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"وارد کردن از حافظه"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"صادر کردن به حافظه"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"وارد کردن همه فایل های کارت ویزیت"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"جستجوی داده کارت ویزیت در دستگاه ذخیره..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"درحال جستجوی داده‌های کارت ویزیت در کارت SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"اسکن کردن محل ذخیره ممکن نیست"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"اسکن کارت SD ممکن نیست"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"دستگاه ذخیره نمی‌تواند بررسی شود. (علت: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"کارت SD نمی‌تواند بررسی شود. (علت: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"خطای ورودی/خروجی"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> به زودی صادر می شود."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"درخواست صدور کارت ویزیت رد شد. لطفاً بعداً امتحان کنید."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"مخاطب"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"مخاطبین صادر شوند؟"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"لیست مخاطبین شما به این فایل صادر می‌شود: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"صادر نمی‌شود"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"سازنده فایل کارت ویزیت به درستی اجرا نشد."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" باز نشد: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> از <xliff:g id="TOTAL_NUMBER">%s</xliff:g> مخاطب"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"لغو وارد کردن کارت ویزیت"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"وارد کردن <xliff:g id="FILENAME">%s</xliff:g> لغو شود؟"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"لغو صادر کردن کارت ویزیت"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"صادر کردن <xliff:g id="FILENAME">%s</xliff:g> لغو شود؟"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"نمی‌توان وارد کردن/ صادر کردن کارت ویزیت را لغو کرد"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"نام های مخاطبین شما"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"افزودن یک مکث 2 ثانیه ای"</string>
     <string name="add_wait" msgid="3360818652790319634">"افزودن انتظار"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"تماس با استفاده از"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"انتخاب شماره"</string>
     <string name="call_settings" msgid="7666474782093693667">"تنظیمات"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"ارسال متن با استفاده از"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"انتخاب شماره"</string>
     <string name="make_primary" msgid="5829291915305113983">"این گزینه را به خاطر بسپار"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"برنامه‌ای برای انجام این عملکرد یافت نشد."</string>
     <string name="missing_name" msgid="8745511583852904385">"(بدون نام)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"حساب‌ها"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"پاک کردن تماس‌های مکرر"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"مخاطبین جهت نمایش"</string>
     <string name="menu_import_export" msgid="26217871113229507">"وارد کردن/صادر کردن"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"وارد کردن/صادر کردن مخاطبین"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"وارد کردن مخاطبین"</string>
     <string name="menu_share" msgid="943789700636542260">"اشتراک گذاری"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"همه مخاطبین"</string>
     <string name="share_via" msgid="563121028023030093">"اشتراک گذاری مخاطب از طریق"</string>
     <string name="share_error" msgid="948429331673358107">"این مخاطب قابل اشتراک‌گذاری نیست."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"نام"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"مشاهده نام های مخاطب بعنوان"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"ابتدا نام"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"ابتدا نام خانوادگی"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"جستجوی مخاطبین"</string>
     <string name="take_photo" msgid="7496128293167402354">"عکسبرداری"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"گرفتن عکس جدید"</string>
     <string name="pick_photo" msgid="3746334626214970837">"انتخاب عکس از گالری"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"ادغام شده از منابع <xliff:g id="COUNT">%0$d</xliff:g>"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"سایر موارد"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"پیوستن به مخاطبین"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"پیوستن به مخاطب فعلی با مخاطب انتخابی؟"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"ویرایش محتویات انتخابی"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"به ویرایش مخاطب انتخابی می روید؟ اطلاعاتی که تا حال وارد کرده اید کپی خواهد شد."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"کپی در مخاطبین من"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"افزودن به مخاطبین من"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"تنظیمات"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"مخاطبین جهت نمایش"</string>
     <string name="menu_settings" msgid="377929915873428211">"تنظیمات"</string>
+    <string name="menu_help" msgid="5123887102216637725">"راهنمایی"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"گزینه های نمایش"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>، <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"پیدا کردن مخاطبین"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"درحال بارگیری..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"ایجاد مخاطب جدید"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"وارد شدن به یک حساب"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"وارد کردن مخاطبین از یک فایل"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"وارد کردن مخاطبین"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"ایجاد گروه جدید"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[ایجاد گروه جدید]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"حذف گروه"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"ایجاد گروه جدید"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 گروه"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> گروه"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"تنظیم پیش فرض"</string>
     <string name="clear_default" msgid="7193185801596678067">"پاک کردن پیش فرض‌ها"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"متن کپی شده"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"صرفنظر از تغییرات"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"از تغییرات شما صرفنظر شود؟"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"راه‌اندازی نمایه من"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"نام شخص را تایپ کنید"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"مشاهده به‌روزرسانی‌ها"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"پست صوتی"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> پست صوتی"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"پخش"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>، <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"پست صوتی جدید از <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"پخش پست صوتی ممکن نیست."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"ذخیره بصورت محلی"</string>
     <string name="add_account" msgid="8201790677994503186">"افزودن حساب"</string>
     <string name="add_new_account" msgid="5748627740680940264">"اافزودن حساب جدید"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"تماس ارسال نشد"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"شماره پست صوتی در دسترس نیست"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"تماس ارسال نشد"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"برای راه‌اندازی پست صوتی به منو &gt; تنظیمات بروید."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"برای تماس با پست صوتی، ابتدا حالت هواپیما را غیرفعال کنید."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"گزینه‌های بیشتر"</string>
 </resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 33db52f..623de8f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Haku"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Uusi yhteystieto"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Näytä yhteystieto"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Soita: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Soita <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Lisää suosikkeihin"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Poista suosikeista"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Muokkaa"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Poista"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopioi"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Paikka aloitusruudussa"</string>
     <string name="menu_call" msgid="3992595586042260618">"Soita"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Lähetä tekstiviesti yhteystiedolle"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Erota"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Ehdotetut yhteystiedot"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Kaikki yhteystiedot"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Yhteystiedot yhdistetty"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Poista yhteystieto?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Aseta soittoääni"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Kaikki puhelut vastaajaan"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Et voi poistaa yhteystietoja vain luku -tilassa olevista tileistä. Voit kuitenkin piilottaa yhteystietoja yhteystietoluetteloissasi."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Yritys"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Nimi"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Yhteystietoa ei ole olemassa."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Yhteystiedot-widget lisätty aloitusruutuun."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Luo uusi yhteystieto"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Luo uusi yhteystieto"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Puhelin"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Löytyi <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Löytyi yli <xliff:g id="COUNT">%d</xliff:g> yhteystietoa."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Yhteystietoja ei löytynyt."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Ei kontakteja"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Löytyi 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Löytyi <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Kaikki"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Kaikki kontaktit"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Ryhmät"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Suosikit"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Puhelin"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Tyhjennä puheluloki?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Kaikki puhelutallenteet poistetaan."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Tyhjennetään puhelulokia..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Tyhjennetäänkö usein käytetyt?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Toiminto tyhjentää Henkilöt- ja Puhelin-sovellusten usein käytettyjen kontaktien luettelon. Lisäksi sähköpostisovellukset pakotetaan opettelemaan osoiteasetuksesi uudestaan."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Tyhjennetään usein käytetyt..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI-koodi"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Vastaaja"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Usein käytetyt"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Soitettu usein"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Lisää yhteystieto"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Lisätäänkö <xliff:g id="EMAIL">%s</xliff:g> yhteystietoihin?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"yksi"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"kaksi"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"miinus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Näytä yhteystieto"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Tallennustila ei käytettävissä"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Ei SD-korttia"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Tallennustilaa ei löydy."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SD-korttia ei löydy."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Etsitään vCardia"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Tuo SIM-kortilta"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Tuo tallennustilasta"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Vie tallennustilaan"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Tuo kaikki vCard-tiedostot"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Etsitään vCard-tietoja tallennustilasta..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Etsitään vCard-tietoja SD-kortilta..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Tallennustilan luku epäonnistui."</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD-korttia ei voi lukea."</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Tallennustilan luku epäonnistui. (Syy: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD-korttia ei voi lukea. (Syy: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O-virhe"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> viedään pian."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard-vientipyyntö hylättiin. Yritä myöhemmin uudelleen."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"yhteystieto"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Vie yhteystietoja?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Yhteystietoluettelosi viedään tiedostoon: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Vieminen epäonnistui"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard-luonti ei käynnistynyt oikein."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Tiedostoa \"<xliff:g id="FILE_NAME">%s</xliff:g>\" ei voi avata: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> / <xliff:g id="TOTAL_NUMBER">%s</xliff:g> yhteystietoa"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Peruutetaan vCardin tuontia"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Peruuta kohteen <xliff:g id="FILENAME">%s</xliff:g> tuonti?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Peruutetaan vCardin vientiä"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Peruuta kohteen <xliff:g id="FILENAME">%s</xliff:g> vienti?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCardin tuonnin/viennin peruutus epäonn."</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Yhteystietojen nimet"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Lisää 2 sekunnin tauko"</string>
     <string name="add_wait" msgid="3360818652790319634">"Lisää tauko"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Soita"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Valitse numero"</string>
     <string name="call_settings" msgid="7666474782093693667">"Asetukset"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Lähetä tekstiviesti"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Valitse numero"</string>
     <string name="make_primary" msgid="5829291915305113983">"Muista valinta"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Tätä toimintoa käsittelevää sovellusta ei löydy."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Ei nimeä)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Tilit"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Tyhjennä usein käytetyt"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Näytettävät yhteystiedot"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Tuo/Vie"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Tuo/Vie yhteystietoja"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Tuo yhteystietoja"</string>
     <string name="menu_share" msgid="943789700636542260">"Jaa"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Kaikki kontaktit"</string>
     <string name="share_via" msgid="563121028023030093">"Jaa yhteystieto"</string>
     <string name="share_error" msgid="948429331673358107">"Tätä yhteystietoa ei voi jakaa."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nimi"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Näytä yhteystietojen nimet"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Etunimi ensin"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Sukunimi ensin"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Hae yhteystiedoista"</string>
     <string name="take_photo" msgid="7496128293167402354">"Ota valokuva"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Ota uusi kuva"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Valitse valokuva galleriasta"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"yhdistetty <xliff:g id="COUNT">%0$d</xliff:g> lähteestä"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Muu"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Yhdistä yhteystiedot"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Yhdistetäänkö nykyiset yhteystiedot valittujen yhteystietojen kanssa?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Muokkaa valittuja yhteystietoja"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Haluatko muokata valittuja yhteystietoja? Antamasi tiedot kopioidaan."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopioi yhteystietoihini"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Lisää kontakteihin"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Asetukset"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Näytettävät yhteystiedot"</string>
     <string name="menu_settings" msgid="377929915873428211">"Asetukset"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ohje"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Näyttövalinnat"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Etsi yhteystietoja"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Ladataan..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Luo uusi yhteystieto"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Kirjaudu tiliin"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Tuo yhteystietoja tiedostosta"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Tuo yhteystietoja"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Luo uusi ryhmä"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Luo uusi ryhmä]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Poista ryhmä"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Luo uusi ryhmä"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 ryhmä"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> ryhmää"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Aseta oletukseksi"</string>
     <string name="clear_default" msgid="7193185801596678067">"Poista oletus"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Teksti kopioitu"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Hylkää muutokset"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Hylätäänkö muutokset?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Luo profiili"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Kirjoita henkilön nimi"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Näytä päivitykset"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Vastaaja"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> vastaajaviestiä"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Toista"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Uusi vastaajaviesti: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Vastaajaviestin toisto ei onnistu."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Säilytä paikallisena"</string>
     <string name="add_account" msgid="8201790677994503186">"Lisää tili"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Lisää uusi tili"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Puhelua ei soitettu."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Vastaajan numero ei saatavilla"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Puhelua ei soitettu"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Määritä puhelinvastaajan asetukset kohdassa Valikko &gt; Asetukset."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Poista lentokonetila käytöstä ennen vastaajaan soittamista."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Lisää vaihtoehtoja"</string>
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 98ce13e..c6191bd 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Rechercher"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nouveau contact"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Afficher le contact"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Appeler <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Appeler le <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Ajouter aux favoris"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Supprimer des favoris"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Modifier"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Supprimer"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copier"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Placer sur l\'écran d\'accueil"</string>
     <string name="menu_call" msgid="3992595586042260618">"Appeler le contact"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Envoyer un SMS au contact"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Séparer"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contacts suggérés"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Tous les contacts"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contacts joints"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Supprimer contact ?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Régler sonnerie"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Tous appels vers messag. voc."</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Impossible de supprimer les contacts des comptes en lecture seule. Vous pouvez les masquer dans la liste des contacts."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Entreprise"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titre"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Ce contact n\'existe pas."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget de contact ajouté à l\'écran d\'accueil."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Créer un nouveau contact"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Créer un nouveau contact"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Téléphone"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> contact(s) trouvé(s)"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Plus de <xliff:g id="COUNT">%d</xliff:g> résultats trouvés."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Aucun contact trouvé."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Aucun contact"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 contact trouvé"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> contact(s) trouvé(s)"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tous"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Tous les contacts"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Groupes"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoris"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Tél."</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Effacer les appels ?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Votre journal d\'appels va être supprimé."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Effacement des appels…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Effacer les contacts fréquents ?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Cette opération efface la liste des personnes que vous contactez le plus souvent dans les applications Contacts et Téléphone, et oblige vos applications de messagerie électronique à apprendre à nouveau les adresses que vous utilisez le plus souvent."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Suppression des contacts fréquents"</string>
     <string name="imei" msgid="3045126336951684285">"Code IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Messagerie vocale"</string>
@@ -183,10 +188,9 @@
     <string name="callBack" msgid="5498224409038809224">"Rappeler"</string>
     <string name="callAgain" msgid="3197312117049874778">"Renouveler l\'appel"</string>
     <string name="returnCall" msgid="8171961914203617813">"Rappeler"</string>
-    <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> mn <xliff:g id="SECONDS">%s</xliff:g> s"</string>
+    <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Contacts fréquents"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Appels fréquents"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Ajouter un contact"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Ajouter \"<xliff:g id="EMAIL">%s</xliff:g>\" aux contacts ?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"un"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"deux"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"moins"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Afficher le contact"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Mémoire non disponible"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Aucune carte SD trouvée"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Aucune mémoire stock. trouvée."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Aucune carte SD détectée."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Recherche des données VCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importer à partir de la carte SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importer depuis mémoire"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exporter vers la mémoire"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importer tous les fichiers vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Recherche de données vCard dans la mémoire de stockage…"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Recherche de données vCard sur la carte SD…"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Impossible d\'analyser la mémoire de stockage"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Impossible d\'analyser la carte SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Impossible d\'explorer la mémoire de stockage pour la raison suivante : <xliff:g id="FAIL_REASON">%s</xliff:g>."</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Impossible d\'explorer la carte SD pour la raison suivante : <xliff:g id="FAIL_REASON">%s</xliff:g>."</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Erreur d\'E/S."</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Exportation du fichier <xliff:g id="FILENAME">%s</xliff:g> imminente"</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"La demande d\'exportation du fichier vCard a été rejetée. Veuillez réessayer ultérieurement."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contact"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exporter contacts ?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Votre liste de contacts va être exportée vers le fichier \"<xliff:g id="VCARD_FILENAME">%s</xliff:g>\"."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Échec exportation"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Le système de composition vCard n\'a pas démarré correctement."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Impossible d\'ouvrir \"<xliff:g id="FILE_NAME">%s</xliff:g>\" pour la raison suivante : <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> sur <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contacts"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Annulation importation fichier vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Annuler l\'importation de \"<xliff:g id="FILENAME">%s</xliff:g>\" ?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Annulation exportation fichier vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Annuler l\'exportation de \"<xliff:g id="FILENAME">%s</xliff:g>\" ?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Impossible annuler import./export. vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Noms de vos contacts"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Ajouter une pause de 2 s"</string>
     <string name="add_wait" msgid="3360818652790319634">"Ajouter Attendre"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Appeler via"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Sélectionner un numéro"</string>
     <string name="call_settings" msgid="7666474782093693667">"Paramètres"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Envoyer un SMS via"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Sélectionner un numéro"</string>
     <string name="make_primary" msgid="5829291915305113983">"Mémoriser ce choix"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Aucune application pouvant gérer cette action n\'a été trouvée."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Sans nom)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Comptes"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Effacer les contacts fréquents"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contacts à afficher"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importer/Exporter"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import/Export contacts"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importer des contacts"</string>
     <string name="menu_share" msgid="943789700636542260">"Partager"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Tous les contacts"</string>
     <string name="share_via" msgid="563121028023030093">"Partager contact via"</string>
     <string name="share_error" msgid="948429331673358107">"Impossible de partager ce contact."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nom"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Afficher les contacts par"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Le prénom en premier"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Le nom en premier"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Rechercher..."</string>
     <string name="take_photo" msgid="7496128293167402354">"Prendre une photo"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Prendre une autre photo"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Sélectionner une photo dans la galerie"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"1 contact fusionné à partir de <xliff:g id="COUNT">%0$d</xliff:g> sources"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Autre"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Joindre les contacts"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Associer ce contact au contact sélectionné ?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Modifier les contacts sélectionnés"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Modifier le contact sélectionné ? Les informations saisies jusqu\'ici seront copiées."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copier dans \"Mes contacts\""</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Ajouter à \"Mes contacts\""</string>
@@ -462,9 +457,10 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Paramètres"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contacts à afficher"</string>
     <string name="menu_settings" msgid="377929915873428211">"Paramètres"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Aide"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Options d\'affichage"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
-    <string name="hint_findContacts" msgid="1808681193458772072">"Rechercher des contacts"</string>
+    <string name="hint_findContacts" msgid="1808681193458772072">"Rechercher contacts"</string>
     <string name="non_phone_caption" msgid="1541655052330027380">"Numéro de téléphone"</string>
     <string name="non_phone_add_to_contacts" msgid="6590985286250471169">"Ajouter aux contacts"</string>
     <string name="activity_title_confirm_add_detail" msgid="4065089866210730616">"Ajouter au contact"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Chargement…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Créer un contact"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Se connecter à un compte"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importer les contacts d\'un fichier"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importer des contacts"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Créer un groupe"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Créer un groupe]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Supprimer le groupe"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Créer un groupe"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Un groupe"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> groupes"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Définir par défaut"</string>
     <string name="clear_default" msgid="7193185801596678067">"Effacer les valeurs par défaut"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Texte copié"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Supprimer les modifications"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Annuler les modifications ?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g> "</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configurer mon profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Saisissez le nom de la personne"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Afficher mises à jour"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Messages vocaux"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> messages vocaux"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Lire"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nouveau message vocal de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Impossible d\'écouter le message vocal."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Enregistrer localement"</string>
     <string name="add_account" msgid="8201790677994503186">"Ajouter un compte"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Ajouter un compte"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Appel non effectué"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Messagerie vocale indisponible"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Appel non effectué."</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Pour configurer la messagerie vocale, accédez à Menu &gt; Paramètres."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Veuillez désactiver le mode Avion avant d\'appeler la messagerie vocale."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Plus d\'options"</string>
 </resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 5690338..50dc01f 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"खोज"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"नया संपर्क"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"संपर्क देखें"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"<xliff:g id="NAME">%s</xliff:g> को कॉल करें"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"<xliff:g id="NUMBER">%s</xliff:g> पर कॉल करें"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"पसंदीदा में जोड़ें"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"पसंदीदा से निकालें"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"संपादित करें"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"हटाएं"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"प्रतिलिपि"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"मुखपृष्ठ स्क्रीन पर रखें"</string>
     <string name="menu_call" msgid="3992595586042260618">"संपर्क को कॉल करें"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"इस संपर्क को SMS भेजें"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"अलग करें"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"सुझाए गए संपर्क"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"सभी संपर्क"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"संपर्क जुड़ गए"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"संपर्क हटाएं?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"रिंगटोन सेट करें"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"ध्‍वनि‍मेल से सभी कॉल"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"आप केवल-पढ़ने के लिए खातों से संपर्क नहीं हटा सकते, लेकिन आप उन्‍हें अपनी संपर्क सूचियों में छुपा सकते हैं."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"कंपनी"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"शीर्षक"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"संपर्क मौजूद नहीं है."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"मुखपृष्ठ स्क्रीन पर संपर्क विजेट जोड़ा गया."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"नया संपर्क बनाएं"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"नया संपर्क बनाएं"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"फ़ोन"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> मिले"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"<xliff:g id="COUNT">%d</xliff:g> से अधिक मिले."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"कोई नहीं मिला."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"कोई संपर्क नहीं"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 मिला"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> मिले"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"सभी"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"सभी संपर्क"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"समूह"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"पसंदीदा"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"फ़ोन"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"कॉल लॉग साफ़ करें?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"आपके सभी कॉल रिकॉर्ड हटा दिए जाएंगे."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"कॉल लॉग साफ़ हो रहा है..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"अक्‍सर किए जाने वाले संपर्क साफ करें?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"आपको लोग और फ़ोन एप्‍लिकेशन में अक्‍सर संपर्क करने की सूची साफ़ करनी होगी, और अपने ईमेल एप्लिकेशन को आपकी प्राथमिकताओं को प्रारंभ से जानने के लिए बाध्‍य करना होगा."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"अक्‍सर किए जाने वाले संपर्क साफ़ कर रहा है…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"ध्वनिमेल"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> मिनट <xliff:g id="SECONDS">%s</xliff:g> सेकंड"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"बार-बार संपर्क किया गया"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"बार-बार कॉल किया गया"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"संपर्क जोड़ें"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"\"<xliff:g id="EMAIL">%s</xliff:g>\" को संपर्कों में जोड़ें?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"एक"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"दो"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"निकालें"</string>
     <string name="description_plus_button" msgid="515164827856229880">"जोड़ें"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"संपर्क देखें"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"संग्रहण अनुपलब्ध"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"कोई SD कार्ड नहीं"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"कोई संग्रहण नहीं मिला."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"कोई SD कार्ड नहीं मिला."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard खोज रहा है"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"सिम कार्ड से आयात करें"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"संग्रहण से आयात करें"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"संग्रहण में निर्यात करें"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"सभी vCard फ़ाइलें आयात करें"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"संग्रहण में vCard डेटा खोज रहा है..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"SD कार्ड पर vCard डेटा खोज रहा है…"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"संग्रहण स्‍कैन नहीं हो सका"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD कार्ड स्‍कैन नहीं हो सका"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"संग्रहण स्‍कैन नहीं किया जा सका. (कारण: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD कार्ड स्कैन नहीं किया जा सका. (कारण: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O त्रुटि"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> को जल्‍दी ही निर्यात किया जाएगा."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard आयात अनुरोध अस्‍वीकार हो गया था. बाद में पुन: प्रयास करें."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"संपर्क"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"संपर्क निर्यात करें?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"आपकी संपर्क सूची इस फ़ाइल में निर्यात कर दी जाएगी: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"निर्यात नहीं कर सका"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard कंपोज़र ठीक से शुरू नहीं हुआ."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" नहीं खोली जा सकी: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="TOTAL_NUMBER">%s</xliff:g> में से <xliff:g id="CURRENT_NUMBER">%s</xliff:g> संपर्क"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard आयात रद्द कर रहा है"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"<xliff:g id="FILENAME">%s</xliff:g> का आयात रद्द करें?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard निर्यात रद्द किया जा रहा है"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"<xliff:g id="FILENAME">%s</xliff:g> का निर्यात रद्द करें?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCard आयात/निर्यात रद्द नहीं हो सका"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"आपके संपर्कों के नाम"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2-सेकंड का विराम जोड़ें"</string>
     <string name="add_wait" msgid="3360818652790319634">"प्रतीक्षा का समय बढ़ाएं"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"इसका उपयोग करके कॉल करें"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"नंबर चुनें"</string>
     <string name="call_settings" msgid="7666474782093693667">"सेटिंग"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"इसका उपयोग कर SMS करें"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"नंबर चुनें"</string>
     <string name="make_primary" msgid="5829291915305113983">"यह विकल्प याद रखें"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"यह कार्यवाही प्रबंधित करने के लिए कोई एप्लिकेशन नहीं मिला."</string>
     <string name="missing_name" msgid="8745511583852904385">"(कोई नाम नहीं)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"खाते"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"अक्सर किए जाने वाले साफ़ करें"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"प्रदर्शन के लिए संपर्क"</string>
     <string name="menu_import_export" msgid="26217871113229507">"आयात करें/निर्यात करें"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"संपर्क आयात/निर्यात करें"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"संपर्क आयात करें"</string>
     <string name="menu_share" msgid="943789700636542260">"शेयर करें"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"सभी संपर्क"</string>
     <string name="share_via" msgid="563121028023030093">"इसके द्वारा संपर्क शेयर करें"</string>
     <string name="share_error" msgid="948429331673358107">"यह संपर्क साझा नहीं किया जा सकता."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"नाम"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"संपर्क नामों को इस रूप में देखें"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"दिया गया नाम पहले"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"कुलनाम पहले"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"संपर्क खोजें"</string>
     <string name="take_photo" msgid="7496128293167402354">"फ़ोटो लें"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"नया फ़ोटो लें"</string>
     <string name="pick_photo" msgid="3746334626214970837">"गैलरी से फ़ोटो चुनें"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"<xliff:g id="COUNT">%0$d</xliff:g> स्रोतों से मर्ज किया गया"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"अन्य"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"संपर्क जोड़ें"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"वर्तमान संपर्क को चयनित संपर्क से जोड़ें?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"चयनित संपर्कों को संपादित करें"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"चयनित संपर्क के संपादन पर जाएं? आपके द्वारा अभी तक दर्ज की गई जानकारी की प्रतिलिपि बनाई जाएगी."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"मेरे संपर्क में प्रतिलिपि बनाएं"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"मेरे संपर्क में जोड़ें"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"सेटिंग"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"प्रदर्शन के लिए संपर्क"</string>
     <string name="menu_settings" msgid="377929915873428211">"सेटिंग"</string>
+    <string name="menu_help" msgid="5123887102216637725">"सहायता"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"प्रदर्शन विकल्प"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"संपर्क ढूंढें"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"लोड हो रहा है..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"एक नया संपर्क बनाएं"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"किसी खाते में साइन इन करें"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"फ़ाइल से संपर्क आयात करें"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"संपर्क आयात करें"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"नया समूह बनाएं"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[नया समूह बनाएं]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"समूह हटाएं"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"नया समूह बनाएं"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 समूह"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> समूह"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"डिफ़ॉल्ट सेट करें"</string>
     <string name="clear_default" msgid="7193185801596678067">"डिफ़ॉल्‍ट साफ़ करें"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"पाठ की प्रतिलिपि बनाई गई"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"परिवर्तन छोड़ें"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"आपके परिवर्तन छोड़ें?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"मेरी प्रोफ़ाइल सेट करें"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"व्‍यक्ति‍ का नाम लिखें"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"अपडेट देखें"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"ध्वनिमेल"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> ध्‍वनिमेल"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"चलाएं"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"<xliff:g id="CALLER">%1$s</xliff:g> की ओर से नया ध्‍वनिमेल"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"ध्वनिमेल नहीं चलाया जा सका."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"स्‍थानीय रखें"</string>
     <string name="add_account" msgid="8201790677994503186">"खाता जोड़ें"</string>
     <string name="add_new_account" msgid="5748627740680940264">"नया खाता जोड़ें"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"कॉल नहीं भेजा गया"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"ध्‍वनिमेल नंबर अनुपलब्‍ध"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"कॉल नहीं भेजा गया"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ध्‍वनिमेल सेट करने के लिए, मेनू &gt; सेटिंग पर जाएं."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"ध्‍वनिमेल कॉल करने के लिए, पहले हवाई जहाज़ मोड बंद करें."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"अधिक विकल्प"</string>
 </resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index da85680..c8b2785 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Pretraži"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Novi kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Prikaži kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Nazovi <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Nazovite <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Dodaj u favorite"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Ukloni iz favorita"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Uredi"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Izbriši"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiranje"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Mjesto na početnom zaslonu"</string>
     <string name="menu_call" msgid="3992595586042260618">"Nazovi kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Poruka kontaktu"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Zasebno"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Predloženi kontakti"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Svi kontakti"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontakti su pridruženi"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Izbrisati kontakt?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Postavi zvuk zvona"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Svi pozivi na govornu poštu"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Ne možete izbrisati kontakte s računa samo za čitanje, ali možete ih sakriti na svojim popisima kontakata."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Tvrtka"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Naslov"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakt ne postoji."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget za kontakte dodan je na vaš početni zaslon."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Izrada novog kontakta"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Stvori novi kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Pronađeno kontakata: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Pronađeno je više od ovoliko kontakata: <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nijedan nije pronađen."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nema kontakata"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 pronađen"</item>
     <item quantity="other" msgid="7988132539476575389">"Pronađeno kontakata: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Sve"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Svi kontakti"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupe"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriti"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Izbrisati dnevnik poziva?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Svi vaši zapisi poziva bit će izbrisani."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Brisanje dnevnika poziva..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Brisati podatke o čestim kontaktima?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Obrisat ćete popis osoba s kojima često kontaktirate u aplikacijama Osobe i Telefoni tako da će aplikacije e-pošte morati naučiti vaše preference adresiranja od početka."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Brisanje često kontaktiranih..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Govorna pošta"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> minuta <xliff:g id="SECONDS">%s</xliff:g> sekundi"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Često kontaktirani"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Često nazivani"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Dodaj kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Dodati \"<xliff:g id="EMAIL">%s</xliff:g>\" kontaktima?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"jedan"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dva"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Prikaži kontakt"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Prostor za pohranu nedostupan"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nema SD kartice"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nije pronađena nijedna pohrana."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nije pronađena SD kartica."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Traženje kartice vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Uvezi sa SIM kartice"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Uvoz iz pohrane"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Izvoz u pohranu"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Uvezi sve vCard datoteke"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Traženje vCard podataka u pohrani..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Pretraživanje vCard podataka na SD kartici..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Skeniranje pohrane nije uspjelo"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Skeniranje SD kartice nije uspjelo"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Pohrana se ne može skenirati. (Razlog: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD kartica ne može se skenirati. (Razlog: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O pogreška"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Datoteka <xliff:g id="FILENAME">%s</xliff:g> uskoro će biti izvezena."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Zahtjev za izvoz formata vCard odbijen je. Pokušajte ponovo kasnije."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Izvesti kontakte?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Vaš popis kontakata bit će izvezen u datoteku: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Izvoz nije uspio"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Sastavljač za vCard nije se ispravno pokrenuo."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Datoteku \"<xliff:g id="FILE_NAME">%s</xliff:g>\" nije moguće otvoriti radi: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> od <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontakata"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Otkazivanje uvoza kartice vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Otkazati uvoz datoteke <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Otkazivanje izvoza kartice vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Otkazati izvoz datoteke <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Uvoz/izvoz kartice vCard nije otkazan"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Nazivi vaših kontakata"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Dodaj pauzu od 2 sek."</string>
     <string name="add_wait" msgid="3360818652790319634">"Dodaj čekanje"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Nazovi koristeći"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Odaberite broj"</string>
     <string name="call_settings" msgid="7666474782093693667">"Postavke"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Poruka korištenjem"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Odaberite broj"</string>
     <string name="make_primary" msgid="5829291915305113983">"Zapamti ovaj izbor"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nije pronađena nijedna aplikacija koja može provesti ovu radnju."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Bez imena)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Računi"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Briši često kontaktirane"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakti za prikaz"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Uvoz/izvoz"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Uvoz/izvoz kontakata"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Uvezi kontakte"</string>
     <string name="menu_share" msgid="943789700636542260">"Podijeli"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Svi kontakti"</string>
     <string name="share_via" msgid="563121028023030093">"Dijeli kontakt putem"</string>
     <string name="share_error" msgid="948429331673358107">"Ovaj kontakt nije moguće dijeliti."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Ime"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Prikaži nazive kontakata kao"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Najprije ime"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Najprije prezime"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Pretraži kontakte"</string>
     <string name="take_photo" msgid="7496128293167402354">"Snimi fotografiju"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Snimi novu fotografiju"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Iz Galerije odaberite fotografiju"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"spojen s <xliff:g id="COUNT">%0$d</xliff:g> izvora"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Drugo"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Pridruživanje kontakata"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Pridružiti trenutačni kontakt odabranom kontaktu?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Uredi odabrane kontakte"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Prebaciti se na uređivanje odabranog kontakta? Informacije koje ste unijeli dosad kopirat će se."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopiraj u Moje kontakte"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Dodaj u Moje kontakte"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Postavke"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakti za prikaz"</string>
     <string name="menu_settings" msgid="377929915873428211">"Postavke"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Pomoć"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opcije prikaza"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Pronađi kontakte"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Učitavanje..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Izradi novi kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Prijavi se na račun"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Uvezi kontakte iz datoteke"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Uvezi kontakte"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Izrada nove grupe"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Izradi novu grupu]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Izbriši grupu"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Izrada nove grupe"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupa"</item>
     <item quantity="other" msgid="1276758425904917367">"Br. grupa: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Postavi zadano"</string>
     <string name="clear_default" msgid="7193185801596678067">"Izbriši zadano"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst kopiran"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Odbaci promjene"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Odbaciti promjene?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Postavi moj profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Upišite ime osobe"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Prikaži ažuriranja"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Govorna pošta"</item>
     <item quantity="other" msgid="5513481419205061254">"Br. govornih pošta: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproduciraj"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nova govorna pošta od kontakta <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Reprodukcija govorne pošte nije uspjela"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Zadrži lokalno"</string>
     <string name="add_account" msgid="8201790677994503186">"Dodaj račun"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Dodaj novi račun"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Poziv nije poslan"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Broj govorne pošte nedostupan je"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Poziv nije poslan"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Da biste postavili govornu poštu, idite na Izbornik &gt; Postavke."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Da biste nazvali govornu poštu, najprije isključite način rada u zrakoplovu."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Više opcija"</string>
 </resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 0f99b0f..11126b9 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Keresés"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Új névjegy"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Névjegy megtekintése"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"<xliff:g id="NAME">%s</xliff:g> hívása"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Hívás: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Hozzáadás a kedvencekhez"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Eltávolítás a kedvencek közül"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Szerkesztés"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Törlés"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Másolás"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Helyezze el a kezdőképernyőn"</string>
     <string name="menu_call" msgid="3992595586042260618">"Ismerős hívása"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"SMS küldése ismerősnek"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Szétválasztás"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Javasolt névjegyek"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Összes névjegy"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"A névjegyek összekapcsolása megtörtént"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Törli a névjegyet?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Csengőhang"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Minden hívás a hangpostára"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Írásvédett fiókból nem törölhet névjegyet, de saját címtárában elrejtheti azokat."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Cég"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Beosztás"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"A névjegy nem létezik."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"A Névjegy modul felkerült a kezdőképernyőre."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Új névjegy létrehozása"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Új névjegy létrehozása"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> találat"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Több mint <xliff:g id="COUNT">%d</xliff:g> találat."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nincs találat."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nincsenek névjegyek"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 találat"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> találat"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Összes"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Az összes névjegy"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Csoportok"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Kedvencek"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Törli a híváslistát?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Minden telefonhívás törlésre kerül."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Híváslista törlése..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Törli a gyakran keresetteket?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Törölni fogja a gyakran keresett személyek listáját a Személyek és a Telefon alkalmazásokban, és arra kényszeríti az e-mail alkalmazásokat, hogy újra, elölről megtanulják az Ön címzési preferenciáit."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Gyakran keresettek törlése..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Hangposta"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> perc <xliff:g id="SECONDS">%s</xliff:g> másodperc"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Gyakran keresett"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Gyakran hívott"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Névjegy hozzáadása"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Hozzáadja a(z) \"<xliff:g id="EMAIL">%s</xliff:g>\"címet a Címtárhoz?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"egy"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"kettő"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"mínusz"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plusz"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Névjegy megtekintése"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"A tárhely nem érhető el"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Hiányzó SD-kártya"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nem található tárhely."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nem található SD-kártya."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard keresése"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importálás a SIM-kártyáról"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importálás a tárhelyről"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportálás a tárhelyre"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Az összes vCard fájl importálása"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"vCard-adatok keresése a tárhelyen..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"vCard-adatok keresése az SD-kártyán..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Nem sikerült beolvasni a tárolót"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Nem lehet beolvasni az SD-kártyát"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"A tárhelyet nem lehet beolvasni. (Indok: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Az SD-kártyát nem lehet beolvasni. (Ok: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O hiba"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"A(z) <xliff:g id="FILENAME">%s</xliff:g> hamarosan exportálásra kerül."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"A vCard-exportálási kérelem elutasítva. Próbálja újra később."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kapcsolat"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportálni szeretné?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"A névjegyek listájának exportálása a(z) <xliff:g id="VCARD_FILENAME">%s</xliff:g> fájlba."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Sikertelen export"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"A vCard-készítő nem megfelelően indult el."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"A(z) \"<xliff:g id="FILE_NAME">%s</xliff:g>\" fájl nem nyitható meg: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g> névjegy"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard importálásának megszakítása"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Megszakítja <xliff:g id="FILENAME">%s</xliff:g> importálását?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard exportálásának megszakítása"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Megszakítja <xliff:g id="FILENAME">%s</xliff:g> exportálását?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCard imp./exp. megszakítása sikertelen"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Ismerősök nevei"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2 mp-es szünet hozzáadása"</string>
     <string name="add_wait" msgid="3360818652790319634">"Várakozás hozzáadása"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Hívás a következő használatával:"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Válassza ki a számot"</string>
     <string name="call_settings" msgid="7666474782093693667">"Beállítások"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"SMS küldése a következővel:"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Válassza ki a számot"</string>
     <string name="make_primary" msgid="5829291915305113983">"Választás megjegyzése"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nincs megfelelő alkalmazás a művelet elvégzésére."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Nincs név)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Fiókok"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Gyakran keresettek törlése"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Megjelenítendő névjegyek"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importálás/exportálás"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Névjegyek importálása/exportálása"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Névjegyek importálása"</string>
     <string name="menu_share" msgid="943789700636542260">"Megosztás"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Összes névjegy"</string>
     <string name="share_via" msgid="563121028023030093">"Névjegy megosztása a következőn:"</string>
     <string name="share_error" msgid="948429331673358107">"Ez a névjegy nem osztható meg."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Név"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Nevek megtekintése mint"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Utónév előre"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Vezetéknév elöl"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Keresés a névjegyek között"</string>
     <string name="take_photo" msgid="7496128293167402354">"Fotó készítése"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Új fénykép készítése"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Fotó kiválasztása a Galériából"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"egyesítve <xliff:g id="COUNT">%0$d</xliff:g> forrásból"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Egyéb"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Névjegyek összekapcsolása"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Összekapcsolja a jelenlegi névjegyet a kiválasztott névjeggyel?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"A kiválasztott névjegyek szerkesztése"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"A kiválasztott névjegy szerkesztésére vált? Az eddig beírt információk át lesznek másolva."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Másolás a saját névjegyeim közé"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Hozzáadás a Címtárhoz"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Beállítások"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Megjelenítendő névjegyek"</string>
     <string name="menu_settings" msgid="377929915873428211">"Beállítások"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Súgó"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Megjelenítési beállítások"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Névjegy keresése"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Betöltés..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Új névjegy létrehozása"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Jelentkezzen be fiókjába"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Névjegyek importálása fájlból"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Névjegyek importálása"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Új csoport létrehozása"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Új csoport létrehozása]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Csoport törlése"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Új csoport létrehozása"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 csoport"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> csoport"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Beállítás alapértelmezettként"</string>
     <string name="clear_default" msgid="7193185801596678067">"Alapértelmezés törlése"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Másolt szöveg"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Módosítások elvetése"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Elveti a módosításokat?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> -- <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Saját profil beállítása"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Írja be a személy nevét"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Frissítések"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Hangposta"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> hangüzenet"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Lejátszás"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Új hangüzenet tőle: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Nem lehet lejátszani a hangpostát."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Tárolás helyben"</string>
     <string name="add_account" msgid="8201790677994503186">"Fiók hozzáadása"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Új fiók hozzáadása"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"A hívás nem indítható."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"A hangpostaszám nem érhető el"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"A hívás nem indítható."</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"A hangposta beállításához válassza a Menü &gt; Beállítások pontot."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Hangposta hívásához kapcsolja ki a Repülőgép üzemmódot."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"További beállítások"</string>
 </resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 6d3f29c..1d51c8e 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -18,57 +18,58 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="launcherDialer" msgid="8636288196618486553">"Telepon"</string>
     <string name="people" msgid="1048457247435785074">"Orang"</string>
-    <string name="contactsList" msgid="8661624236494819731">"Kenalan"</string>
-    <string name="shortcutContact" msgid="749243779392912958">"Kenalan"</string>
+    <string name="contactsList" msgid="8661624236494819731">"Kontak"</string>
+    <string name="shortcutContact" msgid="749243779392912958">"Kontak"</string>
     <string name="shortcutDialContact" msgid="746622101599186779">"Panggilan langsung"</string>
     <string name="shortcutMessageContact" msgid="2460337253595976198">"Pesan langsung"</string>
-    <string name="shortcutActivityTitle" msgid="6642877210643565436">"Pilih pintasan kenalan"</string>
+    <string name="shortcutActivityTitle" msgid="6642877210643565436">"Pilih pintasan kontak"</string>
     <string name="callShortcutActivityTitle" msgid="6065749861423648991">"Pilih nomor untuk dipanggil"</string>
     <string name="messageShortcutActivityTitle" msgid="3084542316620335911">"Pilih nomor untuk dikirimi pesan"</string>
-    <string name="contactPickerActivityTitle" msgid="4301062192337417640">"Pilih kenalan"</string>
+    <string name="contactPickerActivityTitle" msgid="4301062192337417640">"Pilih kontak"</string>
     <string name="starredList" msgid="4817256136413959463">"Yang berkilau bintangnya"</string>
     <string name="frequentList" msgid="7154768136473953056">"Sering"</string>
     <string name="strequentList" msgid="5640192862059373511">"Favorit"</string>
-    <string name="viewContactTitle" msgid="7989394521836644384">"Detail kenalan"</string>
-    <string name="viewContactDesription" msgid="214186610887547860">"Lihat kenalan"</string>
-    <string name="editContactDescription" msgid="2947202828256214947">"Edit data kenalan"</string>
-    <string name="insertContactDescription" msgid="4709878105452681987">"Buat kenalan"</string>
+    <string name="viewContactTitle" msgid="7989394521836644384">"Detail kontak"</string>
+    <string name="viewContactDesription" msgid="214186610887547860">"Lihat kontak"</string>
+    <string name="editContactDescription" msgid="2947202828256214947">"Edit kontak"</string>
+    <string name="insertContactDescription" msgid="4709878105452681987">"Buat kontak"</string>
     <string name="editGroupDescription" msgid="6321161304201540561">"Edit grup"</string>
     <string name="insertGroupDescription" msgid="5658512271662210139">"Buat grup"</string>
     <string name="contactDetailAbout" msgid="5430408883907061400">"Tentang"</string>
     <string name="contactDetailUpdates" msgid="3780588624763446941">"Pembaruan"</string>
-    <string name="searchHint" msgid="8482945356247760701">"Telusuri kenalan"</string>
+    <string name="searchHint" msgid="8482945356247760701">"Telusuri kontak"</string>
     <string name="menu_search" msgid="9147752853603483719">"Telusuri"</string>
-    <string name="menu_newContact" msgid="1209922412763274638">"Kenalan baru"</string>
-    <string name="menu_viewContact" msgid="2795575601596468581">"Lihat kenalan"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Panggil <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_newContact" msgid="1209922412763274638">"Kontak baru"</string>
+    <string name="menu_viewContact" msgid="2795575601596468581">"Lihat kontak"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Panggil <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Tambahkan ke favorit"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Hapus dari favorit"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Edit"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Hapus"</string>
-    <string name="menu_call" msgid="3992595586042260618">"Hubungi kenalan"</string>
-    <string name="menu_sendSMS" msgid="5535886767547006515">"SMS kenalan"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Salin"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Letakkan di layar Utama"</string>
+    <string name="menu_call" msgid="3992595586042260618">"Hubungi kontak"</string>
+    <string name="menu_sendSMS" msgid="5535886767547006515">"SMS kontak"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Pisahkan"</string>
     <string name="menu_editGroup" msgid="5062005185370983720">"Edit"</string>
     <string name="menu_deleteGroup" msgid="3486380004411482874">"Hapus"</string>
     <string name="menu_new_contact_action_bar" msgid="8887818026717394343">"Baru"</string>
     <string name="menu_new_group_action_bar" msgid="5055346725617932394">"Baru"</string>
-    <string name="splitConfirmation_title" msgid="633640935430370530">"Pisahkan data kenalan?"</string>
-    <string name="splitConfirmation" msgid="740190210499587175">"Data kenalan ini akan dipisahkan menjadi beberapa data kenalan."</string>
+    <string name="splitConfirmation_title" msgid="633640935430370530">"Pisahkan kontak?"</string>
+    <string name="splitConfirmation" msgid="740190210499587175">"Kontak ini akan dipisahkan menjadi beberapa kontak."</string>
     <string name="menu_joinAggregate" msgid="5027981918265667970">"Gabung"</string>
-    <string name="titleJoinContactDataWith" msgid="7684875775798635354">"Gabungkan kenalan"</string>
-    <string name="blurbJoinContactDataWith" msgid="8736488417422708236">"Pilih data kenalan ingin Anda gabungkan dengan <xliff:g id="NAME">%s</xliff:g>:"</string>
-    <string name="showAllContactsJoinItem" msgid="2189695051430392383">"Tampilkan semua kenalan"</string>
-    <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Kenalan yang disarankan"</string>
-    <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Semua kenalan"</string>
-    <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kenalan telah bergabung"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Hapus data kenalan?"</string>
+    <string name="titleJoinContactDataWith" msgid="7684875775798635354">"Gabungkan kontak"</string>
+    <string name="blurbJoinContactDataWith" msgid="8736488417422708236">"Pilih kontak ingin Anda gabungkan dengan <xliff:g id="NAME">%s</xliff:g>:"</string>
+    <string name="showAllContactsJoinItem" msgid="2189695051430392383">"Tampilkan semua kontak"</string>
+    <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Kontak yang disarankan"</string>
+    <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Semua kontak"</string>
+    <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontak telah bergabung"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Setel nada dering"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Semua panggilan ke kotak pesan"</string>
-    <string name="readOnlyContactWarning" msgid="7808825687289848259">"Anda tidak dapat menghapus data kenalan dari akun hanya-baca, namun Anda dapat menyembunyikannya dalam daftar data kenalan Anda."</string>
-    <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"Kenalan ini berisi informasi dari beberapa akun. Informasi dari akun hanya-baca akan disembunyikan dalam daftar kenalan Anda, tidak dihapus."</string>
-    <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"Menghapus kenalan ini akan menghapus informasi dari beberapa akun."</string>
-    <string name="deleteConfirmation" msgid="811706994761610640">"Kenalan ini akan dihapus."</string>
+    <string name="readOnlyContactWarning" msgid="7808825687289848259">"Anda tidak dapat menghapus kontak dari akun hanya-baca, namun Anda dapat menyembunyikannya dalam daftar kontak Anda."</string>
+    <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"Kontak ini berisi informasi dari beberapa akun. Informasi dari akun hanya-baca akan disembunyikan dalam daftar kontak Anda, tidak dihapus."</string>
+    <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"Menghapus kontak ini akan menghapus informasi dari beberapa akun."</string>
+    <string name="deleteConfirmation" msgid="811706994761610640">"Kontak ini akan dihapus."</string>
     <string name="menu_done" msgid="796017761764190697">"Selesai"</string>
     <string name="menu_doNotSave" msgid="58593876893538465">"Batal"</string>
     <string name="menu_discard" msgid="6456087569315685632">"Buang"</string>
@@ -76,9 +77,10 @@
     <string name="label_sip_address" msgid="124073911714324974">"Panggilan internet"</string>
     <string name="ghostData_company" msgid="5414421120553765775">"Perusahaan"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Judul"</string>
-    <string name="invalidContactMessage" msgid="8215051456181842274">"Data kenalan tidak ada."</string>
-    <string name="pickerNewContactHeader" msgid="7750705279843568147">"Buat kenalan baru"</string>
-    <string name="pickerNewContactText" msgid="6166997164401048211">"Buat data kenalan baru"</string>
+    <string name="invalidContactMessage" msgid="8215051456181842274">"Kontak tidak ada."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget kontak ditambahkan ke layar Utama."</string>
+    <string name="pickerNewContactHeader" msgid="7750705279843568147">"Buat kontak baru"</string>
+    <string name="pickerNewContactText" msgid="6166997164401048211">"Buat kontak baru"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telepon"</string>
     <string name="emailLabelsGroup" msgid="8389931313045344406">"Email"</string>
     <string name="imLabelsGroup" msgid="3898238486262614027">"IM"</string>
@@ -89,50 +91,50 @@
   </string-array>
     <string name="photoPickerNotFoundText" product="tablet" msgid="6247290728908599701">"Tidak ada gambar yang tersedia pada tablet."</string>
     <string name="photoPickerNotFoundText" product="default" msgid="431331662154342581">"Tidak ada gambar pada ponsel."</string>
-    <string name="attach_photo_dialog_title" msgid="5599827035558557169">"Foto kenalan"</string>
-    <string name="customLabelPickerTitle" msgid="1081475101983255212">"Nama label ubahsuaian"</string>
+    <string name="attach_photo_dialog_title" msgid="5599827035558557169">"Foto kontak"</string>
+    <string name="customLabelPickerTitle" msgid="1081475101983255212">"Nama label khusus"</string>
     <string name="send_to_voicemail_checkbox" msgid="9001686764070676353">"Kirim panggilan ke kotak pesan secara langsung"</string>
     <string name="removePhoto" msgid="4898105274130284565">"Hapus foto"</string>
-    <string name="noContacts" msgid="8579310973261953559">"Tidak ada kenalan."</string>
+    <string name="noContacts" msgid="8579310973261953559">"Tidak ada kontak."</string>
     <string name="noGroups" msgid="8614664663561385253">"Tidak ada grup."</string>
     <string name="noAccounts" msgid="7768267764545265909">"Untuk membuat grup, Anda memerlukan sebuah akun."</string>
-    <string name="noMatchingContacts" msgid="4266283206853990471">"Tidak ditemukan kenalan yang cocok."</string>
-    <string name="noContactsWithPhoneNumbers" msgid="1605457050218824269">"Tidak ada kenalan dengan nomor telepon."</string>
+    <string name="noMatchingContacts" msgid="4266283206853990471">"Tidak ditemukan kontak yang cocok."</string>
+    <string name="noContactsWithPhoneNumbers" msgid="1605457050218824269">"Tidak ada kontak dengan nomor telepon."</string>
     <string name="emptyGroup" msgid="7502116218697177370">"Tidak ada orang dalam grup ini."</string>
     <string name="addPeopleToGroup" msgid="7879585947222263516">"Untuk menambah beberapa orang, edit grup tersebut."</string>
-    <string name="savingContact" msgid="4075751076741924939">"Menyimpan kenalan..."</string>
+    <string name="savingContact" msgid="4075751076741924939">"Menyimpan kontak..."</string>
     <string name="savingDisplayGroups" msgid="2133152192716475939">"Menyimpan opsi tampilan..."</string>
-    <string name="contactSavedToast" msgid="7152589189385441091">"Kenalan disimpan."</string>
-    <string name="contactSavedErrorToast" msgid="3207250533172944892">"Tidak dapat menyimpan perubahan data kenalan."</string>
+    <string name="contactSavedToast" msgid="7152589189385441091">"Kontak disimpan."</string>
+    <string name="contactSavedErrorToast" msgid="3207250533172944892">"Tidak dapat menyimpan perubahan kontak."</string>
     <string name="groupSavedToast" msgid="1168756874239833756">"Grup disimpan."</string>
     <string name="groupSavedErrorToast" msgid="7984466936615304740">"Tidak dapat menyimpan perubahan grup."</string>
   <plurals name="listTotalPhoneContacts">
-    <item quantity="one" msgid="3015357862286673986">"1 kenalan dengan nomor telepon"</item>
-    <item quantity="other" msgid="3299954047880968205">"<xliff:g id="COUNT">%d</xliff:g> kenalan dengan nomor telepon"</item>
+    <item quantity="one" msgid="3015357862286673986">"1 kontak dengan nomor telepon"</item>
+    <item quantity="other" msgid="3299954047880968205">"<xliff:g id="COUNT">%d</xliff:g> kontak dengan nomor telepon"</item>
   </plurals>
-    <string name="listTotalPhoneContactsZero" msgid="6968813857632984319">"Tidak ada kenalan dengan nomor telepon"</string>
+    <string name="listTotalPhoneContactsZero" msgid="6968813857632984319">"Tidak ada kontak dengan nomor telepon"</string>
   <plurals name="listTotalAllContacts">
-    <item quantity="one" msgid="3405747744700823280">"1 kenalan"</item>
-    <item quantity="other" msgid="3578469907265375314">"<xliff:g id="COUNT">%d</xliff:g> kenalan"</item>
+    <item quantity="one" msgid="3405747744700823280">"1 kontak"</item>
+    <item quantity="other" msgid="3578469907265375314">"<xliff:g id="COUNT">%d</xliff:g> kontak"</item>
   </plurals>
-    <string name="listTotalAllContactsZero" msgid="5513001821794568211">"Tidak ada data kenalan."</string>
-    <string name="listTotalAllContactsZeroCustom" msgid="5004974705699445044">"Tidak ada data kenalan yang terlihat."</string>
+    <string name="listTotalAllContactsZero" msgid="5513001821794568211">"Tidak ada kontak."</string>
+    <string name="listTotalAllContactsZeroCustom" msgid="5004974705699445044">"Tidak ada kontak yang terlihat."</string>
     <string name="listTotalAllContactsZeroStarred" msgid="3173820905501592808">"Tidak ada favorit."</string>
-    <string name="listTotalAllContactsZeroGroup" msgid="5448979458248027615">"Tidak ada kenalan di <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="listAllContactsInAccount" msgid="7496143179265311758">"Kenalan di <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="listSingleContact" msgid="6067813698903535563">"Kenalan tunggal"</string>
-    <string name="listCustomView" msgid="6950713892532194050">"Data Kenalan dalam tampilan ubahsuaian"</string>
+    <string name="listTotalAllContactsZeroGroup" msgid="5448979458248027615">"Tidak ada kontak di <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="listAllContactsInAccount" msgid="7496143179265311758">"Kontak di <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="listSingleContact" msgid="6067813698903535563">"Kontak tunggal"</string>
+    <string name="listCustomView" msgid="6950713892532194050">"Kontak dalam tampilan khusus"</string>
   <plurals name="listFoundAllContacts">
     <item quantity="one" msgid="5517063038754171134">"Ada 1"</item>
     <item quantity="other" msgid="3852668542926965042">"Ada <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Ditemukan lebih dari <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Tidak ditemukan satu pun."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Tidak ada kontak"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Ada 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Ada <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Semua"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Semua kontak"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grup"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favorit"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telepon"</string>
@@ -140,7 +142,7 @@
     <string name="menu_sendTextMessage" msgid="6937343460284499306">"Kirim SMS"</string>
     <string name="recentCalls_callNumber" msgid="1756372533999226126">"Panggil <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Edit nomor sebelum memanggil"</string>
-    <string name="recentCalls_addToContact" msgid="1429899535546487008">"Tambahkan ke kenalan"</string>
+    <string name="recentCalls_addToContact" msgid="1429899535546487008">"Tambahkan ke kontak"</string>
     <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Hapus dari log panggilan"</string>
     <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Hapus log panggilan"</string>
     <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Hapus pesan suara"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Hapus log panggilan?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Semua catatan panggilan Anda akan dihapus."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Menghapus log panggilan..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Hapus yang sering dihubungi?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Anda akan menghapus daftar yang sering dihubungi pada aplikasi Orang dan Ponsel, serta memaksa aplikasi email untuk mempelajari preferensi penanganan Anda dari awal."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Menghapus yang sering dihubungi..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Kotak Pesan"</string>
@@ -158,18 +163,18 @@
     <string name="dialerKeyboardHintText" msgid="5401660096579787344">"Gunakan keyboard untuk memanggil"</string>
     <string name="dialerDialpadHintText" msgid="5824490365898349041">"Panggil untuk menambahkan panggilan"</string>
     <string name="simContacts_emptyLoading" msgid="6700035985448642408">"Memuat dari kartu SIM..."</string>
-    <string name="simContacts_title" msgid="27341688347689769">"Kenalan pada kartu SIM"</string>
-    <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Anda tidak memiliki kenalan untuk ditampilkan. (Jika Anda baru saja menambahkan akun, diperlukan waktu beberapa menit untuk menyinkronkan kenalan.)"</string>
-    <string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Anda tak memiliki kenalan untuk ditampilkan."</string>
-    <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"Anda tidak memiliki data kenalan untuk ditampilkan."\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kenalan dari kartu SIM atau kartu SD"\n</li></string>
-    <string name="noContactsHelpText" product="default" msgid="4405064135698982080">"Anda tidak memiliki data kenalan untuk ditampilkan."\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke ponsel"\n</li>\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kenalan dari kartu SIM atau kartu SD"\n</li></string>
-    <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"Anda tidak memiliki data kenalan untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan data kenalan)"\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah data kenalan mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor data kenalan dari kartu SD"\n</li></string>
-    <string name="noContactsHelpTextWithSync" product="default" msgid="7016825676090327312">"Anda tidak memiliki data kenalan untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan data kenalan)"\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke ponsel"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah data kenalan mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor data kenalan dari kartu SD"\n</li></string>
-    <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"Anda tidak memiliki data kenalan untuk ditampilkan."\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kenalan dari kartu SIM atau kartu SD"\n</li></string>
-    <string name="noContactsNoSimHelpText" product="default" msgid="6224952277619986841">"Anda tidak memiliki data kenalan untuk ditampilkan."\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke ponsel"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kenalan dari kartu SIM atau kartu SD"\n</li></string>
-    <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"Anda tidak memiliki data kenalan untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan data kenalan)"\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah data kenalan mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor data kenalan dari kartu SD"\n</li></string>
-    <string name="noContactsNoSimHelpTextWithSync" product="default" msgid="7443705129830284440">"Anda tidak memiliki data kenalan untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan data kenalan)"\n\n"Untuk menambahkan data kenalan, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan data kenalan yang dapat Anda sinkronkan ke ponsel"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah data kenalan mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Data kenalan baru"</b></font>" untuk membuat data kenalan baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor data kenalan dari kartu SD"\n</li></string>
-    <string name="noFavoritesHelpText" msgid="3744655776704833277">"Anda tidak memiliki favorit."\n\n"Untuk menambahkan kenalan ke daftar favorit:"\n\n"        "<li>"Sentuh tab "<b>"Kenalan"</b>\n</li>" "\n<li>"Sentuh kenalan yang ingin Anda tambahkan ke favorit"\n</li>" "\n<li>"Sentuh bintang di samping nama kenalan"\n</li></string>
+    <string name="simContacts_title" msgid="27341688347689769">"Kontak pada kartu SIM"</string>
+    <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Anda tidak memiliki kontak untuk ditampilkan. (Jika Anda baru saja menambahkan akun, diperlukan waktu beberapa menit untuk menyinkronkan kontak.)"</string>
+    <string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Anda tak memiliki kontak untuk ditampilkan."</string>
+    <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"Anda tidak memiliki kontak untuk ditampilkan."\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SIM atau kartu SD"\n</li></string>
+    <string name="noContactsHelpText" product="default" msgid="4405064135698982080">"Anda tidak memiliki kontak untuk ditampilkan."\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke ponsel"\n</li>\n<li><font fgcolor="#ffffffff"><b>"Data kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SIM atau kartu SD"\n</li></string>
+    <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"Anda tidak memiliki kontak untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan kontak)"\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah kontak mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SD"\n</li></string>
+    <string name="noContactsHelpTextWithSync" product="default" msgid="7016825676090327312">"Anda tidak memiliki kontak untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan kontak)"\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke ponsel"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah kontak mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SD"\n</li></string>
+    <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"Anda tidak memiliki kontak untuk ditampilkan."\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SIM atau kartu SD"\n</li></string>
+    <string name="noContactsNoSimHelpText" product="default" msgid="6224952277619986841">"Anda tidak memiliki kontak untuk ditampilkan."\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", kemudian sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambah atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke ponsel"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SIM atau kartu SD"\n</li></string>
+    <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"Anda tidak memiliki kontak untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan kontak)"\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke tablet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah kontak mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SD"\n</li></string>
+    <string name="noContactsNoSimHelpTextWithSync" product="default" msgid="7443705129830284440">"Anda tidak memiliki kontak untuk ditampilkan. (Jika Anda baru saja menambahkan akun, dibutuhkan beberapa menit untuk menyinkronkan kontak)"\n\n"Untuk menambahkan kontak, sentuh "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", lalu sentuh:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Akun"</b></font>" untuk menambahkan atau menyiapkan akun dengan kontak yang dapat Anda sinkronkan ke ponsel"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Opsi tampilan"</b></font>" untuk mengubah kontak mana yang dapat dilihat"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Kontak baru"</b></font>" untuk membuat kontak baru dari awal"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Impor/Ekspor"</b></font>" untuk mengimpor kontak dari kartu SD"\n</li></string>
+    <string name="noFavoritesHelpText" msgid="3744655776704833277">"Anda tidak memiliki favorit."\n\n"Untuk menambahkan kontak ke daftar favorit:"\n\n"        "<li>"Sentuh tab "<b>"Kontak"</b>\n</li>" "\n<li>"Sentuh kontak yang ingin Anda tambahkan ke favorit"\n</li>" "\n<li>"Sentuh bintang di samping nama kontak"\n</li></string>
     <string name="dialer_useDtmfDialpad" msgid="1707548397435075040">"Gunakan keypad nada sentuh"</string>
     <string name="dialer_returnToInCallScreen" msgid="3719386377550913067">"Kembali ke panggilan sedang berlangsung"</string>
     <string name="dialer_addAnotherCall" msgid="4205688819890074468">"Tambahkan panggilan"</string>
@@ -186,8 +191,7 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> menit <xliff:g id="SECONDS">%s</xliff:g> detik"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Paling sering dihubungi"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Paling sering dipanggil"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Tambahkan kenalan"</string>
-    <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Tambahkan \"<xliff:g id="EMAIL">%s</xliff:g>\" ke kenalan?"</string>
+    <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Tambahkan \"<xliff:g id="EMAIL">%s</xliff:g>\" ke kontak?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"satu"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dua"</string>
     <string name="description_image_button_three" msgid="8709731759376015180">"tiga"</string>
@@ -205,41 +209,36 @@
     <string name="description_dial_button" msgid="1274091017188142646">"panggil"</string>
     <string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
     <string name="description_digits_edittext" msgid="8760207516497016437">"nomor untuk dipanggil"</string>
-    <string name="description_contact_photo" msgid="3387458082667894062">"foto kenalan"</string>
+    <string name="description_contact_photo" msgid="3387458082667894062">"foto kontak"</string>
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
-    <string name="description_view_contact_detail" msgid="9133251213656414807">"Lihat kenalan"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Penyimpanan tidak tersedia"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Tidak ada kartu SD"</string>
+    <string name="description_view_contact_detail" msgid="9133251213656414807">"Lihat kontak"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Tidak ditemukan penyimpanan."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Tidak ditemukan kartu SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Menelusuri vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Impor dari kartu SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Impor dari penyimpanan"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Ekspor ke penyimpanan"</string>
-    <string name="share_visible_contacts" msgid="890150378880783797">"Bagikan kenalan yang terlihat"</string>
-    <string name="import_one_vcard_string" msgid="9059163467020328433">"Impor satu berkas vCard"</string>
-    <string name="import_multiple_vcard_string" msgid="3810226492811062392">"Impor beberapa berkas vCard"</string>
-    <string name="import_all_vcard_string" msgid="5518136113853448474">"Impor semua berkas vCard"</string>
+    <string name="share_visible_contacts" msgid="890150378880783797">"Bagikan kontak yang terlihat"</string>
+    <string name="import_one_vcard_string" msgid="9059163467020328433">"Impor satu file vCard"</string>
+    <string name="import_multiple_vcard_string" msgid="3810226492811062392">"Impor beberapa file vCard"</string>
+    <string name="import_all_vcard_string" msgid="5518136113853448474">"Impor semua file vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Menelusuri data vCard dalam penyimpanan..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Menelusuri data vCard pada kartu SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Tidak dapat memindai penyimpanan"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Tidak dapat memindai kartu SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Penyimpanan tidak dapat dipindai. (Alasan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Kartu SD tidak dapat dipindai. (Alasan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
-    <string name="fail_reason_io_error" msgid="6748358842976073255">"Galat I/O"</string>
-    <string name="fail_reason_low_memory_during_import" msgid="875222757734882898">"Memori tidak cukup. Berkas mungkin terlalu besar."</string>
+    <string name="fail_reason_io_error" msgid="6748358842976073255">"Kesalahan I/O"</string>
+    <string name="fail_reason_low_memory_during_import" msgid="875222757734882898">"Memori tidak cukup. File mungkin terlalu besar."</string>
     <string name="fail_reason_vcard_parse_error" msgid="888263542360355784">"Tidak dapat mengurai vCard karena alasan yang tak terduga."</string>
     <string name="fail_reason_not_supported" msgid="8219562769267148825">"Format tidak didukung."</string>
     <string name="vcard_import_failed" msgid="5223531255894842406">"Tidak dapat mengimpor vCard."</string>
-    <string name="import_failure_no_vcard_file" product="nosdcard" msgid="2071820850017305867">"Tidak ditemukan berkas vCard dalam penyimpanan."</string>
-    <string name="import_failure_no_vcard_file" product="default" msgid="1754014167874286173">"Tidak ditemukan berkas vCard pada kartu SD."</string>
-    <string name="fail_reason_failed_to_collect_vcard_meta_info" msgid="6427931733267328564">"Tidak dapat mengumpulkan informasi meta dari berkas vCard yang diberikan."</string>
-    <string name="fail_reason_failed_to_read_files" msgid="5823434810622484922">"Satu berkas atau lebih tidak dapat diimpor (%s)."</string>
-    <string name="fail_reason_unknown" msgid="1714092345030570863">"Galat tidak dikenal."</string>
-    <string name="select_vcard_title" msgid="7791371083694672861">"Pilih berkas vCard"</string>
-    <string name="caching_vcard_title" msgid="1226272312940516605">"Menyimpan ke tembolok"</string>
-    <string name="caching_vcard_message" msgid="4926308675041506756">"Menyimpan vCard ke tembolok untuk penyimpanan lokal sementara. Impor yang sebenarnya akan segera dimulai."</string>
+    <string name="import_failure_no_vcard_file" product="nosdcard" msgid="2071820850017305867">"Tidak ditemukan file vCard dalam penyimpanan."</string>
+    <string name="import_failure_no_vcard_file" product="default" msgid="1754014167874286173">"Tidak ditemukan file vCard pada kartu SD."</string>
+    <string name="fail_reason_failed_to_collect_vcard_meta_info" msgid="6427931733267328564">"Tidak dapat mengumpulkan informasi meta dari file vCard yang diberikan."</string>
+    <string name="fail_reason_failed_to_read_files" msgid="5823434810622484922">"Satu file atau lebih tidak dapat diimpor (%s)."</string>
+    <string name="fail_reason_unknown" msgid="1714092345030570863">"Kesalahan tidak dikenal."</string>
+    <string name="select_vcard_title" msgid="7791371083694672861">"Pilih file vCard"</string>
+    <string name="caching_vcard_title" msgid="1226272312940516605">"Menyimpan ke cache"</string>
+    <string name="caching_vcard_message" msgid="4926308675041506756">"Menyimpan vCard ke cache untuk penyimpanan lokal sementara. Impor yang sebenarnya akan segera dimulai."</string>
     <string name="progress_notifier_message" msgid="2311011466908220528">"Mengimpor <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="importing_vcard_description" msgid="4245275224298571351">"Mengimpor <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="reading_vcard_failed_title" msgid="4251647443358422855">"Tidak dapat membaca data vCard"</string>
@@ -247,69 +246,68 @@
     <string name="importing_vcard_finished_title" msgid="3341541727268747967">"Selesai mengimpor vCard <xliff:g id="FILENAME">%s</xliff:g>"</string>
     <string name="importing_vcard_canceled_title" msgid="2147475978165599336">"Mengimpor <xliff:g id="FILENAME">%s</xliff:g> dibatalkan"</string>
     <string name="vcard_import_will_start_message" msgid="2804911199145873396">"<xliff:g id="FILENAME">%s</xliff:g> akan segera diimpor."</string>
-    <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"Berkas akan diimpor segera."</string>
+    <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"File akan diimpor segera."</string>
     <string name="vcard_import_request_rejected_message" msgid="2890471184508516011">"Permintaan impor vCard ditolak. Coba lagi nanti."</string>
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> akan segera diekspor."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Permintaan ekspor vCard ditolak. Coba lagi nanti."</string>
-    <string name="vcard_unknown_filename" msgid="7171709890959915954">"kenalan"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
-    <string name="confirm_export_title" msgid="6834385377255286349">"Ekspor data kenalan?"</string>
-    <string name="confirm_export_message" msgid="2423421354816428708">"Daftar data kenalan Anda akan diekspor ke berkas: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
+    <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontak"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
+    <string name="confirm_export_title" msgid="6834385377255286349">"Ekspor kontak?"</string>
+    <string name="confirm_export_message" msgid="2423421354816428708">"Daftar kontak Anda akan diekspor ke file: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Tak dapat mengekspor"</string>
-    <string name="exporting_contact_failed_message" msgid="4938527850142003141">"Data kenalan tidak diekspor."\n"Alasan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\""</string>
-    <string name="fail_reason_no_exportable_contact" msgid="8728506011371262065">"Tidak ada data kenalan yang dapat diekspor."</string>
-    <string name="fail_reason_too_many_vcard" product="nosdcard" msgid="590645599157376285">"Terlalu banyak berkas vCard dalam penyimpanan."</string>
-    <string name="fail_reason_too_many_vcard" product="default" msgid="4887177369627277474">"Terlalu banyak berkas vCard di kartu SD."</string>
-    <string name="fail_reason_too_long_filename" msgid="3393764245254738333">"Nama berkas yang diperlukan terlalu panjang (\"<xliff:g id="FILENAME">%s</xliff:g>\")."</string>
+    <string name="exporting_contact_failed_message" msgid="4938527850142003141">"Kontak tidak diekspor."\n"Alasan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\""</string>
+    <string name="fail_reason_no_exportable_contact" msgid="8728506011371262065">"Tidak ada kontak yang dapat diekspor."</string>
+    <string name="fail_reason_too_many_vcard" product="nosdcard" msgid="590645599157376285">"Terlalu banyak file vCard dalam penyimpanan."</string>
+    <string name="fail_reason_too_many_vcard" product="default" msgid="4887177369627277474">"Terlalu banyak file vCard di kartu SD."</string>
+    <string name="fail_reason_too_long_filename" msgid="3393764245254738333">"Nama file yang diperlukan terlalu panjang (\"<xliff:g id="FILENAME">%s</xliff:g>\")."</string>
     <string name="exporting_vcard_finished_title" msgid="4767045779458185251">"Selesai mengekspor <xliff:g id="FILENAME">%s</xliff:g>."</string>
     <string name="exporting_vcard_canceled_title" msgid="2652222370493306887">"Mengekspor <xliff:g id="FILENAME">%s</xliff:g> dibatalkan."</string>
-    <string name="exporting_contact_list_title" msgid="9072240631534457415">"Mengekspor data kenalan"</string>
-    <string name="exporting_contact_list_message" msgid="7181663157672374569">"Data kenalan Anda sedang diekspor ke: <xliff:g id="FILE_NAME">%s</xliff:g>."</string>
+    <string name="exporting_contact_list_title" msgid="9072240631534457415">"Mengekspor kontak"</string>
+    <string name="exporting_contact_list_message" msgid="7181663157672374569">"Kontak Anda sedang diekspor ke: <xliff:g id="FILE_NAME">%s</xliff:g>."</string>
     <string name="fail_reason_could_not_initialize_exporter" msgid="707260459259688510">"Tidak dapat memulai pengeskpor: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
-    <string name="fail_reason_error_occurred_during_export" msgid="3018855323913649063">"Terjadi galat saat ekspor: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
+    <string name="fail_reason_error_occurred_during_export" msgid="3018855323913649063">"Terjadi kesalahan saat ekspor: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
     <string name="composer_failed_to_get_database_infomation" msgid="1765944280846236723">"Tidak dapat memperoleh informasi basis data."</string>
-    <string name="composer_has_no_exportable_contact" product="tablet" msgid="6991449891825077743">"Tidak ada data kenalan yang dapat diekspor. Jika Anda menyimpan data kenalan di tablet, beberapa penyedia data mungkin tidak mengizinkan data kenalan untuk diekspor dari tablet."</string>
-    <string name="composer_has_no_exportable_contact" product="default" msgid="3296493229040294335">"Tidak ada data kenalan yang dapat diekspor. Jika Anda menyimpan data kenalan pada ponsel, beberapa penyedia data tidak mengizinkan data kenalan diekspor dari ponsel."</string>
+    <string name="composer_has_no_exportable_contact" product="tablet" msgid="6991449891825077743">"Tidak ada kontak yang dapat diekspor. Jika Anda menyimpan kontak di tablet, beberapa penyedia data mungkin tidak mengizinkan kontak untuk diekspor dari tablet."</string>
+    <string name="composer_has_no_exportable_contact" product="default" msgid="3296493229040294335">"Tidak ada kontak yang dapat diekspor. Jika Anda menyimpan kontak pada ponsel, beberapa penyedia data tidak mengizinkan kontak diekspor dari ponsel."</string>
     <string name="composer_not_initialized" msgid="2321648986367005254">"Penyusun vCard tidak memulai dengan semestinya."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Tidak dapat membuka \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
-    <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> dari <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kenalan"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Membatalkan impor vCard"</string>
+    <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> dari <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontak"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Batalkan impor <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Membatalkan ekspor vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Batalkan ekspor <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Tidak dpt membatalkan impor/ekspor vCard"</string>
-    <string name="search_settings_description" msgid="2675223022992445813">"Nama kenalan Anda"</string>
+    <string name="search_settings_description" msgid="2675223022992445813">"Nama kontak Anda"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Tambahkan jeda 2-det"</string>
     <string name="add_wait" msgid="3360818652790319634">"Tambahkan tunggu"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Panggil menggunakan"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Pilih nomor"</string>
     <string name="call_settings" msgid="7666474782093693667">"Setelan"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"SMS menggunakan"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Pilih nomor"</string>
     <string name="make_primary" msgid="5829291915305113983">"Ingat pilihan ini"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Tidak ada apl yang ditemukan untuk menangani tindakan ini."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Tanpa nama)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Akun"</string>
-    <string name="menu_contacts_filter" msgid="2165153460860262501">"Kenalan untuk ditampilkan"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Hapus yang sering"</string>
+    <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontak untuk ditampilkan"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Impor/ekspor"</string>
-    <string name="dialog_import_export" msgid="4360648034889921624">"Impor/ekspor data kenalan"</string>
+    <string name="dialog_import_export" msgid="4360648034889921624">"Impor/ekspor kontak"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Impor kontak"</string>
     <string name="menu_share" msgid="943789700636542260">"Bagikan"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Semua kenalan"</string>
-    <string name="share_via" msgid="563121028023030093">"Bagikan kenalan melalui"</string>
-    <string name="share_error" msgid="948429331673358107">"Data kenalan ini tidak dapat dibagi."</string>
+    <string name="share_via" msgid="563121028023030093">"Bagikan kontak melalui"</string>
+    <string name="share_error" msgid="948429331673358107">"Kontak ini tidak dapat dibagi."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nama"</string>
-    <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Nama julukan"</string>
+    <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Nama panggilan"</string>
     <string name="organizationLabelsGroup" msgid="2478611760751832035">"Organisasi"</string>
     <string name="websiteLabelsGroup" msgid="4202998982804009261">"Situs web"</string>
     <string name="eventLabelsGroup" msgid="3695433812142818803">"Acara"</string>
     <string name="relationLabelsGroup" msgid="1854373894284572781">"Hubungan"</string>
     <string name="groupsLabel" msgid="8573535366319059326">"Grup"</string>
-    <string name="dialog_new_contact_account" msgid="9044704073286262197">"Buat kenalan di bawah akun"</string>
+    <string name="dialog_new_contact_account" msgid="9044704073286262197">"Buat kontak di bawah akun"</string>
     <string name="dialog_new_group_account" msgid="2318032089273496830">"Buat grup dalam akun"</string>
     <string name="menu_sync_remove" msgid="3266725887008450161">"Hapus grup sinkronisasi"</string>
     <string name="dialog_sync_add" msgid="8267045393119375803">"Tambahkan grup sinkronisasi"</string>
     <string name="display_more_groups" msgid="2682547080423434170">"Grup lainnya..."</string>
-    <string name="display_ungrouped" msgid="6885954210243119591">"Semua data kenalan lainnya"</string>
-    <string name="display_all_contacts" msgid="2031647544742889505">"Semua data kenalan"</string>
-    <string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"Menghapus \"<xliff:g id="GROUP">%s</xliff:g>\" dari sinkronisasi juga akan menghapus setiap data kenalan yang tidak berada dalam grup dari sinkronisasi."</string>
+    <string name="display_ungrouped" msgid="6885954210243119591">"Semua kontak lainnya"</string>
+    <string name="display_all_contacts" msgid="2031647544742889505">"Semua kontak"</string>
+    <string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"Menghapus \"<xliff:g id="GROUP">%s</xliff:g>\" dari sinkronisasi juga akan menghapus setiap kontak yang tidak berada dalam grup dari sinkronisasi."</string>
     <string name="account_phone" product="tablet" msgid="7946049152658522054">"Tablet saja, tidak disinkronkan"</string>
     <string name="account_phone" product="default" msgid="3682950835276226870">"Ponsel saja, tidak disinkronkan"</string>
     <string name="call_custom" msgid="7756571794763171802">"Panggil <xliff:g id="CUSTOM">%s</xliff:g>"</string>
@@ -398,27 +396,26 @@
     <string name="add_connection_button" msgid="4861308615789601727">"Tambahkan hubungan"</string>
     <string name="recent" msgid="2659189233141493004">"Terbaru"</string>
     <string name="recent_updates" msgid="4267258535615860710">"Pembaruan terkini"</string>
-    <string name="account_type_format" msgid="718948015590343010">"<xliff:g id="SOURCE">%1$s</xliff:g> kenalan"</string>
+    <string name="account_type_format" msgid="718948015590343010">"<xliff:g id="SOURCE">%1$s</xliff:g> kontak"</string>
     <!-- no translation found for from_account_format (4469138575127580203) -->
     <skip />
     <string name="use_photo_as_primary" msgid="8807110122951157246">"Gunakan foto ini"</string>
     <string name="contact_read_only" msgid="7421346527289472273">"Tidak dapat diedit dari apl ini."</string>
-    <string name="no_contact_details" msgid="6636856378019344497">"Tidak ada informasi tambahan untuk data kenalan ini."</string>
+    <string name="no_contact_details" msgid="6636856378019344497">"Tidak ada informasi tambahan untuk kontak ini."</string>
     <string name="group_read_only" msgid="1061762906115697637">"Tidak dapat diedit pada perangkat ini."</string>
     <string name="display_options_sort_list_by" msgid="6080091755852211076">"Sortir daftar menurut"</string>
     <string name="display_options_sort_by_given_name" msgid="184916793466387067">"Nama depan"</string>
     <string name="display_options_sort_by_family_name" msgid="7857986975275712622">"Nama keluarga"</string>
-    <string name="display_options_view_names_as" msgid="18022868169627979">"Tampilkan nama kenalan sebagai"</string>
+    <string name="display_options_view_names_as" msgid="18022868169627979">"Tampilkan nama kontak sebagai"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nama depan pertama"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Nama keluarga pertama"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Telusuri kenalan"</string>
     <string name="take_photo" msgid="7496128293167402354">"Ambil foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Ambil foto baru"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Pilih foto dari Galeri"</string>
     <string name="pick_new_photo" msgid="7962368009197147617">"Pilih foto baru dari Galeri"</string>
-    <string name="locale_change_in_progress" msgid="7583992153091537467">"Daftar kenalan sedang diperbarui untuk mencerminkan perubahan bahasa."</string>
-    <string name="upgrade_in_progress" msgid="474511436863451061">"Daftar kenalan sedang diperbarui."</string>
-    <string name="upgrade_out_of_memory" msgid="1209994418877625940">"Data kenalan sedang dalam proses peningkatan versi. "\n\n"Proses peningkatan versi memerlukan sekitar <xliff:g id="SIZE_IN_MEGABYTES">%s</xliff:g> MB dari penyimpanan internal."\n\n"Pilih salah satu opsi berikut:"</string>
+    <string name="locale_change_in_progress" msgid="7583992153091537467">"Daftar kontak sedang diperbarui untuk mencerminkan perubahan bahasa."</string>
+    <string name="upgrade_in_progress" msgid="474511436863451061">"Daftar kontak sedang diperbarui."</string>
+    <string name="upgrade_out_of_memory" msgid="1209994418877625940">"Kontak sedang dalam proses peningkatan versi. "\n\n"Proses peningkatan versi memerlukan sekitar <xliff:g id="SIZE_IN_MEGABYTES">%s</xliff:g> MB dari penyimpanan internal."\n\n"Pilih salah satu opsi berikut:"</string>
     <string name="upgrade_out_of_memory_uninstall" msgid="1721798828992091432">"Copot pemasangan beberapa aplikasi"</string>
     <string name="upgrade_out_of_memory_retry" msgid="8431289830472724609">"Coba peningkatan versi sekali lagi"</string>
     <string name="search_results_searching" msgid="3984833028938569930">"Menelusuri..."</string>
@@ -426,7 +423,7 @@
     <string name="menu_display_all" msgid="8887488642609786198">"Tampilkan semua"</string>
     <string name="menu_select_all" msgid="621719255150713545">"Pilih semua"</string>
     <string name="menu_select_none" msgid="7093222469852132345">"Batal pilih semua"</string>
-    <string name="no_contacts_selected" msgid="5877803471037324613">"Tidak ada kenalan yang dipilih."</string>
+    <string name="no_contacts_selected" msgid="5877803471037324613">"Tidak ada kontak yang dipilih."</string>
     <string name="add_field" msgid="2384260056674995230">"Tambahkan bidang lain"</string>
     <string name="add_new_entry_for_section" msgid="5223080690667565044">"Tambah baru"</string>
     <string name="add_organization" msgid="7311893231158291197">"Tambahkan organisasi"</string>
@@ -435,55 +432,53 @@
     <string name="contact_status_update_attribution" msgid="752179367353018597">"melalui <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
     <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g> melalui <xliff:g id="SOURCE">%2$s</xliff:g>"</string>
     <string name="description_star" msgid="2605854427360036550">"favorit"</string>
-    <string name="edit_contact" msgid="7529281274005689512">"Edit kenalan"</string>
+    <string name="edit_contact" msgid="7529281274005689512">"Edit kontak"</string>
   <plurals name="merge_info">
     <item quantity="one" msgid="148365587896371969">"tidak digabung"</item>
     <item quantity="other" msgid="425683718017380845">"digabungkan dari <xliff:g id="COUNT">%0$d</xliff:g> sumber"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Lainnya"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Gabungkan kenalan"</string>
-    <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Gabungkan kenalan ini dengan kenalan yang dipilih?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Edit kenalan yang dipilih"</string>
-    <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Beralih ke mengedit kenalan yang dipilih? Informasi yang telah Anda masukkan sejauh ini akan disalin."</string>
-    <string name="menu_copyContact" msgid="1573960845106822639">"Salin ke Data Kenalan Saya"</string>
-    <string name="add_to_my_contacts" msgid="1068274916793627723">"Tambahkan ke Kenalan Saya"</string>
+    <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Gabungkan kontak ini dengan kontak yang dipilih?"</string>
+    <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Beralih ke mengedit kontak yang dipilih? Informasi yang telah Anda masukkan sejauh ini akan disalin."</string>
+    <string name="menu_copyContact" msgid="1573960845106822639">"Salin ke Kontak Saya"</string>
+    <string name="add_to_my_contacts" msgid="1068274916793627723">"Tambahkan ke Kontak Saya"</string>
     <string name="contact_directory_description" msgid="683398073603909119">"Direktori <xliff:g id="TYPE">%1$s</xliff:g>"</string>
     <string name="directory_search_label" msgid="1887759056597975053">"Direktori"</string>
-    <string name="local_search_label" msgid="2551177578246113614">"Semua kenalan"</string>
+    <string name="local_search_label" msgid="2551177578246113614">"Semua kontak"</string>
     <string name="toast_making_personal_copy" msgid="288549957278065542">"Membuat salinan pribadi..."</string>
-    <string name="list_filter_all_accounts" msgid="8908683398914322369">"Semua kenalan"</string>
+    <string name="list_filter_all_accounts" msgid="8908683398914322369">"Semua kontak"</string>
     <string name="list_filter_all_starred" msgid="5031734941601931356">"Yang berkilau bintangnya"</string>
-    <string name="list_filter_custom" msgid="8910173055702057002">"Ubahsuaian"</string>
-    <string name="list_filter_customize" msgid="4789963356004169321">"Ubahsuaian"</string>
-    <string name="list_filter_phones" msgid="735313795643493365">"Semua kenalan dengan nomor telepon"</string>
-    <string name="list_filter_single" msgid="5871400283515893087">"Kenalan"</string>
-    <string name="custom_list_filter" msgid="7836035257402013957">"Tentukan tampilan ubahsuaian"</string>
+    <string name="list_filter_custom" msgid="8910173055702057002">"Khusus"</string>
+    <string name="list_filter_customize" msgid="4789963356004169321">"Khusus"</string>
+    <string name="list_filter_phones" msgid="735313795643493365">"Semua kontak dengan nomor telepon"</string>
+    <string name="list_filter_single" msgid="5871400283515893087">"Kontak"</string>
+    <string name="custom_list_filter" msgid="7836035257402013957">"Tentukan tampilan khusus"</string>
     <string name="contact_list_loading" msgid="5488620820563977329">"Memuat..."</string>
     <string name="activity_title_settings" msgid="5464130076132770781">"Setelan"</string>
-    <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kenalan untuk ditampilkan"</string>
+    <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontak untuk ditampilkan"</string>
     <string name="menu_settings" msgid="377929915873428211">"Setelan"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Bantuan"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opsi tampilan"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
-    <string name="hint_findContacts" msgid="1808681193458772072">"Temukan kenalan"</string>
+    <string name="hint_findContacts" msgid="1808681193458772072">"Temukan kontak"</string>
     <string name="non_phone_caption" msgid="1541655052330027380">"Nomor telepon"</string>
-    <string name="non_phone_add_to_contacts" msgid="6590985286250471169">"Tambahkan ke kenalan"</string>
-    <string name="activity_title_confirm_add_detail" msgid="4065089866210730616">"Tambahkan ke kenalan"</string>
+    <string name="non_phone_add_to_contacts" msgid="6590985286250471169">"Tambahkan ke kontak"</string>
+    <string name="activity_title_confirm_add_detail" msgid="4065089866210730616">"Tambahkan ke kontak"</string>
     <string name="non_phone_close" msgid="7608506439725515667">"Tutup"</string>
     <string name="widget_name_and_phonetic" msgid="8739586586600099979">"<xliff:g id="DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="PHONETIC_NAME">%2$s</xliff:g>)"</string>
     <string name="date_year_toggle" msgid="7356532842767854606">"Berikan tahun"</string>
-    <string name="social_widget_label" msgid="6378905543028924592">"Kenalan"</string>
+    <string name="social_widget_label" msgid="6378905543028924592">"Kontak"</string>
     <string name="social_widget_loading" msgid="5327336597364074608">"Memuat..."</string>
-    <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Buat kenalan baru"</string>
+    <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Buat kontak baru"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Masuk ke akun."</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Mengimpor data kenalan dari berkas"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Impor kontak"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Buat grup baru"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Buat grup baru]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Hapus grup"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Buat grup baru"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grup"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grup"</item>
   </plurals>
-    <string name="delete_group_dialog_message" msgid="7586856514337560529">"Menghapus grup \"<xliff:g id="GROUP_LABEL">%1$s</xliff:g>\"? (Data kenalan itu sendiri tidak akan dihapus.)"</string>
+    <string name="delete_group_dialog_message" msgid="7586856514337560529">"Menghapus grup \"<xliff:g id="GROUP_LABEL">%1$s</xliff:g>\"? (Kontak itu sendiri tidak akan dihapus.)"</string>
   <plurals name="num_contacts_in_group">
     <item quantity="one" msgid="1352418549951013448">"<xliff:g id="COUNT_0">%1$d</xliff:g> orang dari <xliff:g id="ACCOUNT_TYPE">%2$s</xliff:g>"</item>
     <item quantity="other" msgid="8146027769011086349">"<xliff:g id="COUNT_0">%1$d</xliff:g> orang dari <xliff:g id="ACCOUNT_TYPE">%2$s</xliff:g>"</item>
@@ -492,14 +487,13 @@
     <item quantity="one" msgid="3323065321661972446">"<xliff:g id="COUNT">%1$d</xliff:g> orang"</item>
     <item quantity="other" msgid="6251996206137048525">"<xliff:g id="COUNT">%1$d</xliff:g> orang"</item>
   </plurals>
-    <string name="toast_join_with_empty_contact" msgid="2238581529864542985">"Ketik nama kenalan sebelum menggabungkan dengan lainnya."</string>
+    <string name="toast_join_with_empty_contact" msgid="2238581529864542985">"Ketik nama kontak sebelum menggabungkan dengan lainnya."</string>
     <string name="copy_text" msgid="3257145021583508761">"Salin ke papan klip"</string>
-    <string name="set_default" msgid="4417505153468300351">"Setel sebagai bawaan"</string>
-    <string name="clear_default" msgid="7193185801596678067">"Hapus bawaan"</string>
+    <string name="set_default" msgid="4417505153468300351">"Setel sebagai default"</string>
+    <string name="clear_default" msgid="7193185801596678067">"Hapus default"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Teks disalin"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Singkirkan perubahan"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Buang perubahan Anda?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Siapkan profil saya"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Ketik nama seseorang"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Lihat pembaruan"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Pesan suara"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Pesan suara"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Putar"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Pesan suara baru dari <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Tidak dapat memutar pesan suara."</string>
@@ -528,7 +523,7 @@
     <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Kecepatan tertinggi"</string>
     <string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
     <string name="group_name_hint" msgid="238359485263401293">"Nama grup"</string>
-    <string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kenalan yang diterima lewat NFC"</string>
+    <string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontak yang diterima lewat NFC"</string>
     <string name="menu_show_voicemails_only" msgid="1898421289561435703">"Tampilkan pesan suara saja"</string>
     <string name="menu_show_all_calls" msgid="7560347482073345885">"Tampilkan semua panggilan"</string>
     <string name="status_available" msgid="5586870015822828392">"Tersedia"</string>
@@ -539,29 +534,30 @@
     <string name="description_call_log_outgoing_call" msgid="604831756853471658">"Panggilan keluar"</string>
     <string name="description_call_log_missed_call" msgid="2242805209983708825">"Panggilan tak terjawab"</string>
     <string name="description_call_log_voicemail" msgid="4600798771975158948">"Pesan suara"</string>
-    <string name="description_add_contact" msgid="3103414772502485851">"Tambahkan kenalan"</string>
-    <string name="description_view_contact" msgid="5205669345700598415">"Lihat kenalan <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="description_add_contact" msgid="3103414772502485851">"Tambahkan kontak"</string>
+    <string name="description_view_contact" msgid="5205669345700598415">"Lihat kontak <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_call" msgid="3443678121983852666">"Panggil <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_send_text_message" msgid="7803126439934046891">"Kirim SMS ke <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"Pesan suara yang belum didengar"</string>
     <string name="description_send_message" msgid="6046623392322890962">"Kirim pesan ke <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_dial_phone_number" msgid="8831647331642648637">"Panggil nomor telepon <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="description_quick_contact_for" msgid="6737516415168327789">"Data kenalan cepat untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="description_quick_contact_for" msgid="6737516415168327789">"Kontak cepat untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="call_log_empty_gecode" msgid="5588904744812100846">"-"</string>
     <string name="user_profile_contacts_list_header" msgid="5582421742835006940">"Saya"</string>
     <string name="local_profile_title" msgid="2021416826991393684">"Profil lokal saya"</string>
     <string name="external_profile_title" msgid="8034998767621359438">"Profil <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g> saya"</string>
-    <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Menampilkan semua kenalan"</string>
-    <string name="no_account_prompt" msgid="7061052512446855192">"Orang bekerja lebih baik dengan Akun Google."\n\n"• Akses dari peramban web mana pun."\n"• Cadangkan data kenalan Anda dengan aman."</string>
-    <string name="generic_no_account_prompt" msgid="7218827704367325460">"Tetap amankan data kenalan Anda jika kehilangan ponsel: sinkronkan dengan layanan daring."</string>
+    <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Menampilkan semua kontak"</string>
+    <string name="no_account_prompt" msgid="7061052512446855192">"Orang bekerja lebih baik dengan Akun Google."\n\n"• Akses dari browser web mana pun."\n"• Cadangkan kontak Anda dengan aman."</string>
+    <string name="generic_no_account_prompt" msgid="7218827704367325460">"Tetap amankan kontak Anda jika kehilangan ponsel: sinkronkan dengan layanan online."</string>
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"Tambahkan akun"</string>
-    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Data kenalan baru Anda tidak akan dicadangkan. Tambahkan akun yang mencadangkan data kenalan secara daring?"</string>
-    <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"Data kenalan baru Anda akan disinkronkan dengan <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
-    <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Anda dapat menyinkronkan data kenalan baru dengan salah satu akun berikut. Akun mana yang ingin Anda gunakan?"</string>
+    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Kontak baru Anda tidak akan dicadangkan. Tambahkan akun yang mencadangkan kontak secara online?"</string>
+    <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"Kontak baru Anda akan disinkronkan dengan <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
+    <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Anda dapat menyinkronkan kontak baru dengan salah satu akun berikut. Akun mana yang ingin Anda gunakan?"</string>
     <string name="keep_local" msgid="1258761699192993322">"Simpan secara lokal"</string>
     <string name="add_account" msgid="8201790677994503186">"Tambahkan akun"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Tambahkan akun baru"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Panggilan tidak terkirim"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Nomor pesan suara tidak tersedia"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Panggilan tidak terkirim"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Untuk menyiapkan kotak pesan, buka Menu &gt; Setelan."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Untuk memanggil pesan suara, pertama-tama matikan mode Pesawat."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Opsi lainnya"</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 32b8522..cd73640 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Cerca"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nuovo contatto"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Visualizza contatto"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Chiama <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Chiama <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Aggiungi a preferiti"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Rimuovi dai preferiti"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Modifica"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Elimina"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copia"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Aggiungi a schermata Home"</string>
     <string name="menu_call" msgid="3992595586042260618">"Chiama"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Invia SMS"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separa"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contatti suggeriti"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Tutti i contatti"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contatti uniti"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Eliminare contatto?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Imposta suoneria"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Tutte le chiamate a segreteria"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Non puoi eliminare contatti da account di sola lettura, ma puoi nasconderli nei tuoi elenchi di contatti."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Società"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titolo"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Contatto non esistente."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget del contatto aggiunto alla schermata Home."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Crea nuovo contatto"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Crea nuovo contatto"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefono"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> trovati"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Ne sono stati trovati più di <xliff:g id="COUNT">%d</xliff:g>"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nessun contatto trovato."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nessun contatto"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 trovato"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> trovati"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tutti"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Tutti i contatti"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Gruppi"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Preferiti"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefono"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Cancellare registro?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tutte le voci nel registro chiamate verranno eliminate."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Cancellazione registro chiamate..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Cancellare contattati di frequente?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Cancellerai l\'elenco degli utenti contattati di frequente nelle applicazioni Persone e Telefono e imposterai l\'acquisizione forzata delle tue preferenze di indirizzamento da zero nelle applicazioni email."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Cancellazione contattati di frequente…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Segreteria"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sec."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Contattati spesso"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Numeri più chiamati"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Aggiungi contatto"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Aggiungi \"<xliff:g id="EMAIL">%s</xliff:g>\" ai contatti?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"uno"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"due"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"meno"</string>
     <string name="description_plus_button" msgid="515164827856229880">"più"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Visualizza contatto"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Archivio non disponibile"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nessuna scheda SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nessun archivio trovato."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nessuna scheda SD trovata."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Ricerca vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importa da scheda SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importa da archivio"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Esporta in archivio"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importa tutti i file vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Ricerca di dati vCard nell\'archivio..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Ricerca dati vCard su scheda SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Scansione archivio non riuscita"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Scansione scheda SD non riuscita"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Scansione dell\'archivio non riuscita. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Scansione della scheda SD non riuscita. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Errore I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"La vCard <xliff:g id="FILENAME">%s</xliff:g> verrà esportata a breve."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Richiesta esportazione vCard rifiutata. Riprova più tardi."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contatto"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Esportare contatti?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"L\'elenco dei contatti verrà esportato nel file: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Impossibile esportare"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Il compositore di vCard non si è avviato correttamente."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Apertura di \"<xliff:g id="FILE_NAME">%s</xliff:g>\" non riuscita: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> contatti su <xliff:g id="TOTAL_NUMBER">%s</xliff:g>"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Annullamento importazione vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Annullare l\'importazione di <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Annullamento esportazione vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Annullare l\'esportazione di <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Annullam. import./esport. vCard non riuscito"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"I nomi dei tuoi contatti"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Aggiungi pausa 2 sec"</string>
     <string name="add_wait" msgid="3360818652790319634">"Aggiungi attesa"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Chiama utilizzando"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Scegli numero"</string>
     <string name="call_settings" msgid="7666474782093693667">"Impostazioni"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Invia SMS utilizzando"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Scegli numero"</string>
     <string name="make_primary" msgid="5829291915305113983">"Memorizza questa scelta"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nessuna applicazione trovata per gestire questa azione."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Nessun nome)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Account"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Cancella frequenti"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contatti da visualizzare"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importa/esporta"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importa/esporta contatti"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importa contatti"</string>
     <string name="menu_share" msgid="943789700636542260">"Condividi"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Tutti i contatti"</string>
     <string name="share_via" msgid="563121028023030093">"Condividi contatto tramite"</string>
     <string name="share_error" msgid="948429331673358107">"Questo contatto non può essere condiviso."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nome"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Visualizza nomi contatti con"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Prima il nome"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Prima il cognome"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Cerca contatti"</string>
     <string name="take_photo" msgid="7496128293167402354">"Scatta foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Scatta nuova foto"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Scegli la foto dalla Galleria"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"uniti da <xliff:g id="COUNT">%0$d</xliff:g> origini"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Altro"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Unisci contatti"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Unire il contatto corrente al contatto selezionato?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Modifica i contatti selezionati"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Passare alla modifica del contatto selezionato? Le informazioni inserite finora verranno copiate."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copia nei miei contatti"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Aggiungi ai contatti personali"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Impostazioni"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contatti da visualizzare"</string>
     <string name="menu_settings" msgid="377929915873428211">"Impostazioni"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Guida"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opzioni di visualizzazione"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Trova contatti"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Caricamento..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Crea nuovo contatto"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Accedi a un account"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importa contatti da file"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importa contatti"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Crea nuovo gruppo"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Crea nuovo gruppo]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Elimina gruppo"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Crea nuovo gruppo"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 gruppo"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> gruppi"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Imposta come predefinito"</string>
     <string name="clear_default" msgid="7193185801596678067">"Cancella impostazione predefinita"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Testo copiato"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Ignora modifiche"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Annullare le modifiche?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g> "</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Imposta il mio profilo"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Digita il nome della persona"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Visualizza aggiornamenti"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Segreteria"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> messaggi vocali"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Riproduci"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nuovo messaggio vocale da <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Riproduzione messaggio vocale non riuscita."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Memorizza in locale"</string>
     <string name="add_account" msgid="8201790677994503186">"Aggiungi account"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Aggiungi nuovo account"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Chiamata non inviata"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Numero segreteria non disponibile"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Chiamata non inviata"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Per configurare la segreteria, seleziona Menu &gt; Impostazioni."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Per chiamare la segreteria, disattiva la modalità aereo."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Altre opzioni"</string>
 </resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 6403596..1340f07 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"חפש"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"איש קשר חדש"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"הצג איש קשר"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"התקשר אל <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"התקשר אל <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"הוסף למועדפים"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"הסר מהמועדפים"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"ערוך"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"מחק"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"העתק"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"הצב במסך הבית"</string>
     <string name="menu_call" msgid="3992595586042260618">"התקשר לאיש קשר"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"שלח הודעת טקסט לאיש קשר"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"הפרד"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"אנשי קשר מוצעים"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"כל אנשי הקשר"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"אנשי קשר צורפו"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"למחוק את איש הקשר?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"הגדר רינגטון"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"כל השיחות לתא הקולי"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"לא ניתן למחוק אנשי קשר מחשבונות לקריאה בלבד, אך ניתן להסתיר אותם ברשימות אנשי הקשר."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"חברה"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"שם"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"איש הקשר לא קיים."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"widget של אנשי קשר נוסף למסך הבית."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"צור איש קשר חדש"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"צור איש קשר חדש"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"טלפון"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> נמצאו"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"נמצאו יותר מ-<xliff:g id="COUNT">%d</xliff:g> פריטים."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"לא נמצאו פריטים."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"אין אנשי קשר"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"נמצא אחד"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> נמצאו"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"הכל"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"כל אנשי הקשר"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"קבוצות"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"מועדפים"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"טלפון"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"לנקות את יומן השיחות?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"כל רשומות השיחה שלך יימחקו."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"מנקה את יומן השיחות..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"האם למחוק אנשי קשר קבועים?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"פעולה זו תמחק את רשימת האנשים שאתה יוצר איתם קשר בתדירות הגבוהה ביותר ביישומים \'אנשים\' ו\'טלפון\' ותאלץ יישומי דוא\"ל ללמוד מהתחלה את העדפות הכתובות שלך."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"מוחק אנשי קשר קבועים…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"דואר קולי"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> דקות <xliff:g id="SECONDS">%s</xliff:g> שניות"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"בקשר לעתים קרובות"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"התקשרות לעתים קרובות"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"הוסף איש קשר"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"להוסיף את \"<xliff:g id="EMAIL">%s</xliff:g>\" לאנשי הקשר?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"אחד"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"שתיים"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"חיסור"</string>
     <string name="description_plus_button" msgid="515164827856229880">"חיבור"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"הצג איש קשר"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"אמצעי אחסון אינו זמין"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"אין כרטיס SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"לא נמצאו התקני אחסון."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"לא נמצא כרטיס SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"מחפש vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"ייבא מכרטיס SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"ייבא מאמצעי אחסון"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"ייצא לאמצעי אחסון"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"ייבא את כל קובצי vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"מחפש נתוני vCard באמצעי האחסון..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"מחפש נתוני vCard בכרטיס ה-SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"לא ניתן לסרוק אחסון"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"לא ניתן לסרוק כרטיס SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"לא ניתן לסרוק את אמצעי האחסון. (סיבה: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"לא ניתן לסרוק את כרטיס ה-SD. (סיבה: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"שגיאת קלט/פלט"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"הייצוא של <xliff:g id="FILENAME">%s</xliff:g> יתבצע תוך זמן קצר."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"הבקשה לייצוא ה-vCard נדחתה. נסה שוב מאוחר יותר."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"איש קשר"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"לייצא את אנשי הקשר?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"רשימת אנשי הקשר שלך תיוצא לקובץ: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"לא ניתן לייצא"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"יישום היצירה של ה-vCard לא הופעל כהלכה."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"לא ניתן לפתוח את \"<xliff:g id="FILE_NAME">%s</xliff:g>\"‏: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> מתוך <xliff:g id="TOTAL_NUMBER">%s</xliff:g> אנשי קשר"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"מבטל יבוא של vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"לבטל את הייבוא של <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"מבטל יצוא של vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"לבטל את הייצוא של <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"לא ניתן לבטל ייבוא/ייצוא של vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"השמות של אנשי הקשר"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"הוסף השהיה של 2 שניות"</string>
     <string name="add_wait" msgid="3360818652790319634">"הוסף המתנה"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"התקשר באמצעות"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"בחר מספר"</string>
     <string name="call_settings" msgid="7666474782093693667">"הגדרות"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"שלח הודעת טקסט באמצעות"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"בחר מספר"</string>
     <string name="make_primary" msgid="5829291915305113983">"זכור בחירה זו"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"לא נמצא יישום שיכול לטפל בפעולה זו."</string>
     <string name="missing_name" msgid="8745511583852904385">"(ללא שם)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"חשבונות Google"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"מחק אנשי קשר קבועים"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"אנשי קשר להצגה"</string>
     <string name="menu_import_export" msgid="26217871113229507">"ייבוא/ייצוא"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"יבא/יצא אנשי קשר"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"יבוא אנשי קשר"</string>
     <string name="menu_share" msgid="943789700636542260">"שתף"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"כל אנשי הקשר"</string>
     <string name="share_via" msgid="563121028023030093">"שתף איש קשר באמצעות"</string>
     <string name="share_error" msgid="948429331673358107">"לא ניתן לשתף איש קשר זה."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"שם"</string>
@@ -310,7 +308,7 @@
     <string name="display_ungrouped" msgid="6885954210243119591">"כל אנשי הקשר האחרים"</string>
     <string name="display_all_contacts" msgid="2031647544742889505">"כל אנשי הקשר"</string>
     <string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"הסרת \"<xliff:g id="GROUP">%s</xliff:g>\" מהסנכרון תסיר מהסנכרון גם אנשי קשר שאינם מקובצים."</string>
-    <string name="account_phone" product="tablet" msgid="7946049152658522054">"טבלט בלבד, לא מסונכרן"</string>
+    <string name="account_phone" product="tablet" msgid="7946049152658522054">"טאבלט בלבד, לא מסונכרן"</string>
     <string name="account_phone" product="default" msgid="3682950835276226870">"טלפון בלבד, לא מסונכרן"</string>
     <string name="call_custom" msgid="7756571794763171802">"התקשר אל <xliff:g id="CUSTOM">%s</xliff:g>"</string>
     <string name="call_home" msgid="1990519474420545392">"התקשר לבית"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"הצג שמות אנשי קשר בתור"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"תחילה שם פרטי"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"שם משפחה תחילה"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"חפש אנשי קשר"</string>
     <string name="take_photo" msgid="7496128293167402354">"צלם תמונה"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"צלם תמונה חדשה"</string>
     <string name="pick_photo" msgid="3746334626214970837">"בחר תמונה מתוך \'גלריה\'"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"מוזגו מ-<xliff:g id="COUNT">%0$d</xliff:g> מקורות"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"אחר"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"צרף אנשי קשר"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"לצרף את איש הקשר הנוכחי לאיש הקשר שנבחר?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"ערוך את אנשי הקשר שנבחרו"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"לעבור לעריכה של איש הקשר שנבחר? המידע שהזנת עד עכשיו יועתק."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"העתק אל \'אנשי הקשר שלי\'"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"הוסף ל\'אנשי הקשר שלי\'"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"הגדרות"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"אנשי קשר להצגה"</string>
     <string name="menu_settings" msgid="377929915873428211">"הגדרות"</string>
+    <string name="menu_help" msgid="5123887102216637725">"עזרה"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"אפשרויות תצוגה"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"חפש אנשי קשר"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"טוען..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"צור איש קשר חדש"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"היכנס לחשבון"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"ייבא אנשי קשר מקובץ"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"יבא אנשי קשר"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"צור קבוצה חדשה"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[צור קבוצה חדשה]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"מחק את הקבוצה"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"צור קבוצה חדשה"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"קבוצה אחת"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> קבוצות"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"קבע כברירת מחדל"</string>
     <string name="clear_default" msgid="7193185801596678067">"נקה ברירת מחדל"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"טקסט שהועתק"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"מחק שינויים"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"למחוק את השינויים שביצעת?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"הגדר את הפרופיל שלי"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"הקלד שם של אדם"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"הצג עדכונים"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"דואר קולי"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> הודעות קוליות"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"הפעל"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"דואר קולי חדש מאת <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"לא ניתן להפעיל דואר קולי."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"שמור באופן מקומי"</string>
     <string name="add_account" msgid="8201790677994503186">"הוסף חשבון"</string>
     <string name="add_new_account" msgid="5748627740680940264">"הוסף חשבון חדש"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"השיחה לא נשלחה."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"המספר של הדואר הקולי אינו זמין"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"השיחה לא נשלחה."</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"כדי להגדיר את הדואר הקולי, עבור אל \'תפריט\' &gt; \'הגדרות\'."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"כדי להתקשר לדואר קולי, ראשית כבה את מצב הטיסה."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"אפשרויות נוספות"</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index a96f32c..bd2185f 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="launcherDialer" msgid="8636288196618486553">"電話"</string>
-    <string name="people" msgid="1048457247435785074">"ユーザー"</string>
+    <string name="people" msgid="1048457247435785074">"People"</string>
     <string name="contactsList" msgid="8661624236494819731">"連絡先"</string>
     <string name="shortcutContact" msgid="749243779392912958">"連絡先"</string>
     <string name="shortcutDialContact" msgid="746622101599186779">"直接発信"</string>
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"検索"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"連絡先を新規登録"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"連絡先詳細"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"<xliff:g id="NAME">%s</xliff:g>に発信"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"<xliff:g id="NUMBER">%s</xliff:g>に発信"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"お気に入りに追加"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"お気に入りから削除"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"編集"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"削除"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"コピー"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"ホーム画面に配置"</string>
     <string name="menu_call" msgid="3992595586042260618">"連絡先に発信"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"連絡先にSMS"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"分割"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"連絡先候補"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"すべての連絡先"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"連絡先を結合しました"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"連絡先を削除しますか?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"着信音を設定"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"すべての通話をボイスメールへ"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"読み取り専用アカウントの連絡先は削除できません。ただし、連絡先リストで非表示にすることができます。"</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"会社"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"役職"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"連絡先が存在しません。"</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"ホーム画面に連絡先ウィジェットを追加しました。"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"連絡先を新規登録"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"新しい連絡先を作成"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"電話番号"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g>件見つかりました"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"<xliff:g id="COUNT">%d</xliff:g>件以上見つかりました。"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"何も見つかりませんでした。"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"連絡先はありません"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1件見つかりました"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g>件見つかりました"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"すべて"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"すべての連絡先"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"グループ"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"お気入り"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"電話"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"通話履歴を消しますか?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"すべての通話記録は削除されます。"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"通話履歴を消去しています..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"よく使う連絡先をクリアしますか?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Peopleアプリや電話アプリのよく使う連絡先リストをクリアし、メールアプリがアドレス設定を初めから保存していくようにします。"</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"よく使う連絡先をクリアしています…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI(端末識別番号)"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"ボイスメール"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g>分<xliff:g id="SECONDS">%s</xliff:g>秒"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"よく使う連絡先"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"よく使う連絡先"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"連絡先を追加"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"<xliff:g id="EMAIL">%s</xliff:g> を連絡先に追加しますか?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"1"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"2"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"マイナス"</string>
     <string name="description_plus_button" msgid="515164827856229880">"プラス"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"連絡先を表示"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"ストレージ使用不可"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"SDカードがありません"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"ストレージはありませんでした。"</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SDカードが見つかりませんでした。"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCardを検索中"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"SIMカードからインポート"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"ストレージからインポート"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"ストレージにエクスポート"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"すべてのvCardファイルをインポート"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"ストレージ内でvCardデータを検索しています..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"SDカードでvCardデータを検索しています..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"ストレージをスキャンできませんでした"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SDカードをスキャンできませんでした"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"ストレージをスキャンできませんでした(理由: 「<xliff:g id="FAIL_REASON">%s</xliff:g>」)。"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SDカードをスキャンできませんでした(理由: 「<xliff:g id="FAIL_REASON">%s</xliff:g>」)。"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"送受信エラー"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g>はまもなくエクスポートされます。"</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCardのエクスポートリクエストは拒否されました。しばらくしてからもう一度お試しください。"</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"連絡先"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"エクスポートしますか?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"連絡先リストをファイル「<xliff:g id="VCARD_FILENAME">%s</xliff:g>」にエクスポートします。"</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"エクスポート失敗"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCardコンポーザーが正しく起動しませんでした。"</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"「<xliff:g id="FILE_NAME">%s</xliff:g>」を開けませんでした: <xliff:g id="EXACT_REASON">%s</xliff:g>。"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>件のファイル"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCardインポートのキャンセル"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"<xliff:g id="FILENAME">%s</xliff:g>のインポートをキャンセルしますか?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCardエクスポートのキャンセル"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"<xliff:g id="FILENAME">%s</xliff:g>のエクスポートをキャンセルしますか?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCardインポート/エクスポート取り消し不可"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"連絡先の名前"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2秒間の停止を追加"</string>
     <string name="add_wait" msgid="3360818652790319634">"待機を追加"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"使用している発信"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"番号を選択"</string>
     <string name="call_settings" msgid="7666474782093693667">"設定"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"使用しているSMS"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"番号を選択"</string>
     <string name="make_primary" msgid="5829291915305113983">"この選択を保存"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"この操作を行うアプリが見つかりませんでした。"</string>
     <string name="missing_name" msgid="8745511583852904385">"(名前なし)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"アカウント"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"よく使う連絡先のクリア"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"表示する連絡先"</string>
     <string name="menu_import_export" msgid="26217871113229507">"インポート/エクスポート"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"連絡先のインポート/エクスポート"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"連絡先のインポート"</string>
     <string name="menu_share" msgid="943789700636542260">"共有"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"すべての連絡先"</string>
     <string name="share_via" msgid="563121028023030093">"連絡先の共有ツール"</string>
     <string name="share_error" msgid="948429331673358107">"この連絡先は共有できません。"</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"名前"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"名前の表示形式"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"名が先"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"姓が先"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"連絡先を検索"</string>
     <string name="take_photo" msgid="7496128293167402354">"写真を撮影"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"新しい写真を撮る"</string>
     <string name="pick_photo" msgid="3746334626214970837">"ギャラリーから画像を選ぶ"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"<xliff:g id="COUNT">%0$d</xliff:g>件の連絡先が結合されました"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"その他"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"連絡先の統合"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"現在の連絡先を選択した連絡先に統合しますか?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"選択した連絡先の編集"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"選択した連絡先の編集に切り替えますか?これまでに入力した情報はコピーされます。"</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Myコンタクトにコピー"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Myコンタクトに追加"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"設定"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"表示する連絡先"</string>
     <string name="menu_settings" msgid="377929915873428211">"設定"</string>
+    <string name="menu_help" msgid="5123887102216637725">"ヘルプ"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"表示オプション"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>、<xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"連絡先を検索"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"読み込んでいます..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"新しい連絡先を作成"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"アカウントにログイン"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"ファイルから連絡先をインポート"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"連絡先をインポート"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"新しいグループの作成"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[新しいグループを作成]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"グループの削除"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"新しいグループを作成"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1グループ"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g>グループ"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"デフォルトに設定"</string>
     <string name="clear_default" msgid="7193185801596678067">"デフォルトを解除"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"テキストをコピーしました"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"変更を破棄"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"変更を破棄しますか?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"プロフィールを設定"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"名前を入力"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"更新情報を表示"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"ボイスメール"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g>件のボイスメール"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"再生"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>、<xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"<xliff:g id="CALLER">%1$s</xliff:g>から新着ボイスメール"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"ボイスメールを再生できませんでした。"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"ローカルに保存"</string>
     <string name="add_account" msgid="8201790677994503186">"アカウントを追加"</string>
     <string name="add_new_account" msgid="5748627740680940264">"新しいアカウントを追加"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"発信できません"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"ボイスメールの番号を利用できません"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"発信できません"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ボイスメールをセットアップするには、MENUキー&gt;[設定]をタップします。"</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"機内モードをOFFにしてからボイスメールを呼び出してください。"</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"その他のオプション"</string>
 </resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index c0fd67d..9c1f197 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"검색"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"새 연락처"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"연락처 보기"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"<xliff:g id="NAME">%s</xliff:g>님에게 전화걸기"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"<xliff:g id="NUMBER">%s</xliff:g>에 전화"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"즐겨찾기에 추가"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"즐겨찾기에서 삭제"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"수정"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"삭제"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"복사"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"홈 화면에 만들기"</string>
     <string name="menu_call" msgid="3992595586042260618">"연락처로 전화 걸기"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"연락처에 문자 보내기"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"분리"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"추천 연락처"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"모든 연락처"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"연락처 결합됨"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"연락처를 삭제하시겠습니까?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"벨소리 설정"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"음성사서함 자동 연결"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"연락처를 읽기 전용 계정에서 삭제할 수는 없지만 주소록에서 숨길 수는 있습니다."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"회사"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"직함"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"연락처가 없습니다."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"주소록 위젯이 홈 화면에 추가됨"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"새 연락처 만들기"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"새 연락처 만들기"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"전화"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g>개를 찾았습니다."</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"<xliff:g id="COUNT">%d</xliff:g>개 이상 찾았습니다."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"없음"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"주소록 없음"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1개를 찾았습니다."</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g>개를 찾았습니다."</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"전체"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"모든 연락처"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"그룹"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"즐겨찾기"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"휴대전화"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"통화기록을 지우시겠습니까?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"모든 통화 기록을 삭제합니다."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"통화기록을 지우는 중..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"자주 연락하는 사람들 목록을 삭제하시겠습니까?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"피플 및 휴대전화 앱에서 자주 연락하는 사람들 목록을 삭제하고 이메일 앱이 주소록 환경설정을 처음부터 다시 반영하도록 합니다."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"자주 연락하는 사람들 목록을 삭제하는 중…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"음성사서함"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g>분 <xliff:g id="SECONDS">%s</xliff:g>초"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"자주 연락하는 사람들의 연락처"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"자주 통화한 목록"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"연락처 추가"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"\'<xliff:g id="EMAIL">%s</xliff:g>\'을(를) 주소록에 추가하겠습니까?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"1"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"2"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"빼기"</string>
     <string name="description_plus_button" msgid="515164827856229880">"더하기"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"연락처 보기"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"저장장치 없음"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"SD 카드 없음"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"저장공간을 찾을 수 없습니다."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SD 카드가 없습니다."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard 검색"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"SIM 카드에서 가져오기"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"저장소에서 가져오기"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"저장소로 내보내기"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"모든 vCard 파일 가져오기"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"저장장치에서 vCard 데이터 검색 중..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"SD 카드의 vCard 데이터 검색 중..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"저장소를 검색하지 못했습니다."</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD 카드를 검색하지 못했습니다."</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"저장소를 검색할 수 없습니다(이유: \'<xliff:g id="FAIL_REASON">%s</xliff:g>\')."</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD 카드를 검색할 수 없습니다(이유: \'<xliff:g id="FAIL_REASON">%s</xliff:g>\')."</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O 오류"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g>을(를) 곧 내보냅니다."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard 내보내기 요청이 거부되었습니다. 나중에 다시 시도해 주세요."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"연락처"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"주소록을 내보내시겠습니까?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"연락처 목록을 <xliff:g id="VCARD_FILENAME">%s</xliff:g> 파일로 내보냅니다."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"내보내기 실패"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard 작성기가 제대로 시작되지 않았습니다."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\'<xliff:g id="FILE_NAME">%s</xliff:g>\'을(를) 열 수 없습니다(이유: <xliff:g id="EXACT_REASON">%s</xliff:g>)."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"연락처 <xliff:g id="CURRENT_NUMBER">%s</xliff:g>개(총 <xliff:g id="TOTAL_NUMBER">%s</xliff:g>개) 내보내는 중"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard 가져오기 취소 중"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"<xliff:g id="FILENAME">%s</xliff:g> 가져오기를 취소하시겠습니까?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard 내보내기 취소 중"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"<xliff:g id="FILENAME">%s</xliff:g> 내보내기를 취소하시겠습니까?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"vCard 가져오기/내보내기를 취소하지 못했습니다."</string>
     <string name="search_settings_description" msgid="2675223022992445813">"연락처 명단"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2초 간 일시 정지 추가"</string>
     <string name="add_wait" msgid="3360818652790319634">"대기 시간 추가"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"전화 걸기:"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"번호 선택"</string>
     <string name="call_settings" msgid="7666474782093693667">"설정"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"다음을 사용하여 문자 보내기:"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"번호 선택"</string>
     <string name="make_primary" msgid="5829291915305113983">"이 선택사항 저장"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"이 작업을 처리하는 앱을 찾을 수 없습니다."</string>
     <string name="missing_name" msgid="8745511583852904385">"(이름 없음)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"계정"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"자주 연락하는 사람들 목록 삭제"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"표시할 연락처"</string>
     <string name="menu_import_export" msgid="26217871113229507">"가져오기/내보내기"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"주소록 가져오기/내보내기"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"주소록 가져오기"</string>
     <string name="menu_share" msgid="943789700636542260">"공유"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"모든 연락처"</string>
     <string name="share_via" msgid="563121028023030093">"연락처 공유에 사용할 애플리케이션:"</string>
     <string name="share_error" msgid="948429331673358107">"연락처를 공유할 수 없습니다."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"이름"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"연락처 이름 표시 방법:"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"이름 먼저 표시"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"성 먼저 표시"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"연락처 검색"</string>
     <string name="take_photo" msgid="7496128293167402354">"사진 찍기"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"새 사진 가져오기"</string>
     <string name="pick_photo" msgid="3746334626214970837">"갤러리에서 사진 선택"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"<xliff:g id="COUNT">%0$d</xliff:g>개 출처에서 병합했습니다."</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"기타"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"연락처 통합"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"이 연락처와 선택한 연락처를 통합하시겠습니까?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"선택한 연락처 수정"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"선택한 연락처를 수정하시겠습니까? 지금까지 입력하신 정보는 복사됩니다."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"내 주소록에 복사"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"내 주소록에 추가"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"설정"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"표시할 연락처"</string>
     <string name="menu_settings" msgid="377929915873428211">"설정"</string>
+    <string name="menu_help" msgid="5123887102216637725">"도움말"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"표시 옵션"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"연락처 찾기"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"로드 중…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"새 연락처 만들기"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"계정에 로그인"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"파일에서 주소록 가져오기"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"주소록 가져오기"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"새 그룹 만들기"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[새 그룹 만들기]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"그룹 삭제"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"새 그룹 만들기"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"그룹 1개"</item>
     <item quantity="other" msgid="1276758425904917367">"그룹 <xliff:g id="COUNT">%0$d</xliff:g>개"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"기본으로 설정"</string>
     <string name="clear_default" msgid="7193185801596678067">"기본 설정 지우기"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"텍스트 복사됨"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"변경사항 취소"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"변경사항을 삭제하시겠습니까?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g> "</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"내 프로필 설정"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"이름 입력"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"업데이트 보기"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"음성사서함"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g>개의 음성사서함"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"재생"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"<xliff:g id="CALLER">%1$s</xliff:g>님이 보낸 새 음성사서함"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"음성메시지를 재생할 수 없습니다."</string>
@@ -541,11 +536,11 @@
     <string name="description_call_log_voicemail" msgid="4600798771975158948">"음성사서함"</string>
     <string name="description_add_contact" msgid="3103414772502485851">"연락처 추가"</string>
     <string name="description_view_contact" msgid="5205669345700598415">"<xliff:g id="NAME">%1$s</xliff:g>님의 연락처 보기"</string>
-    <string name="description_call" msgid="3443678121983852666">"<xliff:g id="NAME">%1$s</xliff:g>님에게 전화걸기"</string>
+    <string name="description_call" msgid="3443678121983852666">"전화하기:<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_send_text_message" msgid="7803126439934046891">"<xliff:g id="NAME">%1$s</xliff:g>님에게 문자 메시지 보내기"</string>
     <string name="description_call_log_unheard_voicemail" msgid="118101684236996786">"듣지 않은 음성사서함"</string>
     <string name="description_send_message" msgid="6046623392322890962">"<xliff:g id="NAME">%1$s</xliff:g>님에게 메시지 보내기"</string>
-    <string name="description_dial_phone_number" msgid="8831647331642648637">"<xliff:g id="NAME">%1$s</xliff:g>님에게 전화걸기"</string>
+    <string name="description_dial_phone_number" msgid="8831647331642648637">"전화하기:<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="description_quick_contact_for" msgid="6737516415168327789">"<xliff:g id="NAME">%1$s</xliff:g>님의 빠른 주소록"</string>
     <string name="call_log_empty_gecode" msgid="5588904744812100846">"-"</string>
     <string name="user_profile_contacts_list_header" msgid="5582421742835006940">"나"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"오프라인 보관"</string>
     <string name="add_account" msgid="8201790677994503186">"계정 추가"</string>
     <string name="add_new_account" msgid="5748627740680940264">"새 계정 추가"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"전화를 걸 수 없음"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"음성사서함 번호를 사용할 수 없음"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"전화를 걸 수 없음"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"음성사서함을 설정하려면 메뉴 &gt; 설정으로 이동하세요."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"음성사서함에 메시지를 남기려면 먼저 비행기 모드를 해제하세요."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"옵션 더보기"</string>
 </resources>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 841eb75..350693a 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -16,6 +16,5 @@
 <resources>
     <dimen name="dialpad_digits_height">66dip</dimen>
     <dimen name="dialpad_digits_text_size">28sp</dimen>
-    <dimen name="dialpad_digits_margin_top">1dip</dimen>
     <dimen name="dialpad_digits_margin_bottom">50dip</dimen>
 </resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 0145168..4b83caa 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Ieškoti"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Naujas adresatas"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Žiūrėti adresatą"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Skambinti <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Skambinti <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Pridėti prie adresyno"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Pašalinti iš adresyno"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Redaguoti"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Ištrinti"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopijuoti"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Padėti pagrindiniame ekrane"</string>
     <string name="menu_call" msgid="3992595586042260618">"Skambinti adresatui"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Siųsti pranešimą adresatui"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Atskiras"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Siūlomi adresatai"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Visi adresatai"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Sujungti adresatai"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Ištrinti kontaktą?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Nustat. sk. toną"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Visi skamb. į balso paštą"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Negalite ištrinti kontaktų iš tik skaitomų paskyrų, bet galite paslėpti juos savo kontaktų sąrašuose."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Įmonė"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Pareigos"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontaktas neegzistuoja."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontaktų valdiklis pridėtas prie pagrindinio ekrano."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Kurti naują adresatą"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Kurti naują kontaktą"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefonas"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Rasta <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Rasta daugiau nei <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nieko nerasta."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Kontaktų nėra"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"rastas 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Rasta <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Visi"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Visi kontaktai"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupės"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Adresynas"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefonas"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Išv. skamb. žurnalą?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Visi jūsų skambučių įrašai bus ištrinti."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Valomas skambučių žurnalas…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Išvalyti dažniaus. naud. kontaktus?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Išvalysite dažniausiai naudojamų kontaktų sąrašą Žmonių ir Telefono programose, o el. pašto programoms reikės iš naujo gauti adresavimo nuostatas."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Valomi dažniaus. naud. kontaktai…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Balso paštas"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sek."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Dažnai susisiekiama"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Dažniausiai skambinta"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Pridėti adresatą"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Pridėti „<xliff:g id="EMAIL">%s</xliff:g>“ prie adresatų?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"vienas"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"du"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plius"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Peržiūrėti kontaktą"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Saugykla neprieinama"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nėra SD kortelės"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nerasta jokių atmintinių."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nerasta jokių SD kortelių."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Ieškoma „vCard“ kortelės"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importuoti iš SIM kortelės"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importuoti iš saugyklos"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Eksportuoti į saugyklą"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importuoti visus „VCard“ kortelės failus"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Ieškoma el. vizitinės kortelės duomenų saugykloje..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"SD kortelėje ieškoma el. vizitinės kortelės duomenų..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Nepavyko nuskaityti atminties"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Nepavyko nuskaityti SD kortelės"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Atmintinės negalima žvalgyti. (Priežastis: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD kortelės negalima žvalgyti. (Priežastis: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Įvesties / išvesties klaida"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> bus netrukus eksportuotas."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"El. vizitinės kortelės eksportavimo užklausa buvo atmesta. Bandykite vėliau."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontaktas"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Eksp. kontaktus?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Jūsų kontaktų sąrašas bus eksportuotas į failą „<xliff:g id="VCARD_FILENAME">%s</xliff:g>“."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Nepavyko eksportuoti"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"El. vizitinių kortelių rengyklė nebuvo tinkamai paleista."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Nepavyko atidaryti „<xliff:g id="FILE_NAME">%s</xliff:g>“: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> iš <xliff:g id="TOTAL_NUMBER">%s</xliff:g> adresatų"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Atšaukiamas el. vizitinės kortelės importavimas"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Atšaukti <xliff:g id="FILENAME">%s</xliff:g> importavimą?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Atšaukiamas el. vizitinės kortelės eksportavimas"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Atšaukti <xliff:g id="FILENAME">%s</xliff:g> eksportavimą?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Nepavyko atš. „vCard“ imp. / eksp."</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Adresatų vardai"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Pridėti 2 sek. pauzę"</string>
     <string name="add_wait" msgid="3360818652790319634">"Pridėti laukimą"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Skambinti naudojant"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Pasirinkite numerį"</string>
     <string name="call_settings" msgid="7666474782093693667">"Nustatymai"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Siųsti pranešimą naudojant"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Pasirinkite numerį"</string>
     <string name="make_primary" msgid="5829291915305113983">"Atsiminti šį pasirinkimą"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nerasta jokių programų šiam veiksmui apdoroti."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Nėra pavadinimo)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Paskyros"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Valyti dažniausiai naudojamus"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Pateiktini kontaktai"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importuoti / eksportuoti"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import. / eksport. kont."</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importuoti kontaktus"</string>
     <string name="menu_share" msgid="943789700636542260">"Bendrinti"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Visi kontaktai"</string>
     <string name="share_via" msgid="563121028023030093">"Bendrinti adresatą naudojant"</string>
     <string name="share_error" msgid="948429331673358107">"Šio kontakto negalima bendrinti."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Pavadinimas"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Žiūrėti adresatų vardus kaip"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Pirmiausia suteiktas pavadinimas"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Pirmiausia pavardė"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Ieškoti adresatų"</string>
     <string name="take_photo" msgid="7496128293167402354">"Fotografuoti"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Iš naujo fotografuoti"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Pasirinkti nuotrauką iš galerijos."</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"sujungta iš <xliff:g id="COUNT">%0$d</xliff:g> šaltinių (-io)"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Kita"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Sujungti kontaktus"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Sujungti dabartinį kontaktą su pasirinktu?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Redaguoti pasirinktus kontaktus"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Perjungti į pasirinkto kontakto redagavimą? Iki šiol įvesta informacija bus nukopijuota."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopijuoti į „Mano kontaktus“"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Pridėti prie „Mano kontaktų“"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Nustatymai"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Pateiktini kontaktai"</string>
     <string name="menu_settings" msgid="377929915873428211">"Nustatymai"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Pagalba"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Pateikties parinktys"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"„<xliff:g id="COMPANY_0">%2$s</xliff:g>“, „<xliff:g id="COMPANY_1">%1$s</xliff:g>“"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Ieškoti kontaktų"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Įkeliama..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Sukurti naują kontaktą"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Prisijunkite prie paskyros"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importuoti kontaktus iš failo"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importuoti kontaktus"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Sukurti naują grupę"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Sukurti naują grupę]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Ištrinti grupę"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Sukurti naują grupę"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupė"</item>
     <item quantity="other" msgid="1276758425904917367">"Grupių: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Nustatyti numatytuosius nustatymus"</string>
     <string name="clear_default" msgid="7193185801596678067">"Išvalyti numatytuosius nustatymus"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekstas nukopijuotas"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Atmesti pakeitimus"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Atmesti pakeitimus?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Nustatyti mano profilį"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Įveskite asmens vardą ir (arba) pavardę"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Žiūrėti naujinius"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Balso paštas"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> balso pašto pranešim."</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Paleisti"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nauji b. pašto pran. iš <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Nepavyko paleisti balso pašto praneš."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Išsaug. kaip vietinį"</string>
     <string name="add_account" msgid="8201790677994503186">"Pridėkite paskyrą"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Pridėkite naują paskyrą"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Skambutis neišsiųstas"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Balso pašto numeris nepasiekiamas"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Skambutis neišsiųstas"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Jei norite nustatyti balso paštą, eikite į „Meniu“ &gt; „Nustatymai“."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Jei norite skambinti į balso paštą, išjunkite lėktuvo režimą."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Daugiau parinkčių"</string>
 </resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 50172d8..fa38a53 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Meklēt"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Jauna kontaktpersona"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Skatīt kontaktpersonu"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Zvanīt: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Zvaniet: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Pievienot izlasei"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Noņemt no izlases"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Rediģēt"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Dzēst"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopēt"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Novietot sākuma ekrānā"</string>
     <string name="menu_call" msgid="3992595586042260618">"Zvanīt kontaktpersonai"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Sūtīt īsziņu kontaktpersonai"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Sadalīt"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Ieteiktās kontaktpersonas"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Visas kontaktpersonas"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontaktpersonas ir apvienotas."</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Vai dzēst kontaktp.?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Iest. zv. sign."</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Visi zvani uz balss pastu"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Jūs nevarat dzēst kontaktpersonas no tikai lasāmiem kontiem, taču varat tās slēpt kontaktpersonu sarakstos."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Uzņēmums"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Nosaukums"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Šāda kontaktpersona nepastāv."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontaktpersonas logrīks pievienots sākuma ekrānam."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Izveidot jaunu kontaktpersonu"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Izveidot jaunu kontaktpersonu"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Tālrunis"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Atrastas <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Ir atrastas vairāk nekā <xliff:g id="COUNT">%d</xliff:g> kontaktpersonas."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nav atrasta neviena kontaktp."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nav kontaktpersonu"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Atrasta 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Atrastas <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Visas"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Visas kontaktpersonas"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupas"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Izlase"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Zvanīt"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vai not. zv. žurn.?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Visi zvanu ieraksti tiks dzēsti."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Notiek zvanu žurnāla tīrīšana..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vai dzēst bieži lietotos kontaktus?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Tiks dzēsts bieži lietoto kontaktpersonu saraksts lietotnēs Personas un Tālrunis, un e-pasta lietotnēs adrešu preferenču saglabāšana tiks sākta no sākuma."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Bieži lietoto kontaktu dzēšana..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Balss pasts"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Bieža saziņa"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Bieži zvanīti"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Pievienot kontaktpersonu"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Vai pievienot “<xliff:g id="EMAIL">%s</xliff:g>” kontaktpersonām?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"viens"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"divi"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"mīnuss"</string>
     <string name="description_plus_button" msgid="515164827856229880">"pluss"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Skatīt kontaktpersonu"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"USB atmiņa nav pieejama"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nav SD kartes"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Netika atrasta atmiņa."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Netika atrasta SD karte."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard faila meklēšana"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importēt no SIM kartes"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importēt no USB atmiņas"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Eksportēt uz USB atmiņu"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importēt visus vCard failus"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Notiek vCard datu meklēšana atmiņā..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Notiek vCard datu meklēšana SD kartē..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Nevarēja skenēt atmiņu."</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Nevarēja skenēt SD karti."</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Atmiņu nevarēja skenēt. (Iemesls: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD karti nevarēja skenēt. (Iemesls: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Ievades/izvades kļūda."</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Fails <xliff:g id="FILENAME">%s</xliff:g> tiks drīzumā eksportēts."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Tika noraidīts vCard faila eksportēšanas pieprasījums. Vēlāk mēģiniet vēlreiz."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontaktpersona"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Vai eksp. kontaktp.?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Kontaktpersonu saraksts tiks eksportēts uz failu <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Nevarēja eksportēt"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Netika pareizi startēts vCard veidotājs."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Nevarēja atvērt failu <xliff:g id="FILE_NAME">%s</xliff:g>: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> no <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontaktpersonas(-ām)"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard importēšanas atcelšana"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Vai atcelt faila <xliff:g id="FILENAME">%s</xliff:g> importēšanu?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard eksportēšanas atcelšana"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Vai atcelt faila <xliff:g id="FILENAME">%s</xliff:g> eksportēšanu?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Nevarēja atcelt vCard f. import./eksp."</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Kontaktpersonu vārdi"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Pievienot 2 sekundes ilgu pauzi"</string>
     <string name="add_wait" msgid="3360818652790319634">"Pievienot gaidīšanu"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Zvanīt, izmantojot"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Numura izvēlēšanās"</string>
     <string name="call_settings" msgid="7666474782093693667">"Iestatījumi"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Sūtīt īsziņu, izmantojot"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Numura izvēlēšanās"</string>
     <string name="make_primary" msgid="5829291915305113983">"Atcerēties šo izvēli"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Netika atrasta neviena lietotne šīs darbības veikšanai."</string>
     <string name="missing_name" msgid="8745511583852904385">"(nav vārda)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Konti"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Dzēst bieži lietotos kontaktus"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Attēlojamās kontaktpersonas"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importēt/eksportēt"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"K. pers. imports/eksports"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Kontaktpersonu importēšana"</string>
     <string name="menu_share" msgid="943789700636542260">"Kopīgot"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Visas kontaktpersonas"</string>
     <string name="share_via" msgid="563121028023030093">"Kopīgot kontaktpersonu, izmantojot"</string>
     <string name="share_error" msgid="948429331673358107">"Šo kontaktpersonu nevar kopīgot."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Vārds"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Kontaktpersonu vārdu attēlošana:"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Vispirms rādīt vārdu"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Vispirms rādīt uzvārdu"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Meklēt kontaktpersonas"</string>
     <string name="take_photo" msgid="7496128293167402354">"Uzņemt fotoattēlu"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Uzņemt jaunu fotoattēlu"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Izvēlēties fotoattēlu no galerijas"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"sapludināts no <xliff:g id="COUNT">%0$d</xliff:g> avotiem"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Cits"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Kontaktpersonu savienošana"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Vai savienot pašreizējo saturu ar atlasīto kontaktpersonu?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Atlasīto kontaktpersonu rediģēšana"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Vai pāriet uz atlasītās kontaktpersonas rediģēšanu? Līdz šim ievadītā informācija tiks kopēta."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopēt uz manām kontaktpersonām"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Pievienot mapē Manas kontaktpersonas"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Iestatījumi"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Attēlojamās kontaktpers."</string>
     <string name="menu_settings" msgid="377929915873428211">"Iestatījumi"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Palīdzība"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Attēlošanas opcijas"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Meklēt kontaktpersonas"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Notiek ielāde..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Izveidot jaunu kontaktpersonu"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Pierakstīties kontā"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importēt kontaktpersonas no faila"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importēt kontaktpersonas"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Jaunas grupas izveide"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Izveidot jaunu grupu]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Grupas dzēšana"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Izveidot jaunu grupu"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupa"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupas"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Iestatīt kā noklusējumu"</string>
     <string name="clear_default" msgid="7193185801596678067">"Notīrīt noklusējuma iestatījumus"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Teksts ir nokopēts"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Atmest izmaiņas"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Vai atmest veiktās izmaiņas?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g><xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> — <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Iestatīt savu profilu"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Rakstiet personas vārdu."</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Skatīt atjaunināj."</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Balss pasts"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> balss pasta ziņojums(-i)"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Atskaņot"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Jauns b. pasta ziņ. no: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Nevarēja atskaņot balss pasta ziņojumu."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Saglabāt vietēji"</string>
     <string name="add_account" msgid="8201790677994503186">"Pievienot kontu"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Pievienot jaunu kontu"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Nenosūtīts zvans"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Nepieejams balss pasta numurs"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Nenosūtīts zvans"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Lai iestatītu balss pastu, atveriet sadaļu Izvēlne &gt; Iestatījumi."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Lai piezvanītu balss pastam, vispirms izslēdziet lidojuma režīmu."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Vairāk opciju"</string>
 </resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 2a6190f..384d3f0 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Cari"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Kenalan baru"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Papar kenalan"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Panggil <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Panggil <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Tambah ke kegemaran"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Alih keluar daripada kegemaran"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Edit"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Padam"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Salin"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Letakkan pada skrin Utama"</string>
     <string name="menu_call" msgid="3992595586042260618">"Panggil kenalan"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"SMS kepada kenalan"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Asingkan"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Kenalan cadangan"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Semua kenalan"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kenalan digabungkan"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Padamkan kenalan?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Ttpkn nd dering"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Semua panggilan ke mel suara"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Anda tidak boleh memadamkan kenalan daripada akaun baca sahaja, tetapi anda boleh menyembunyikan mereka dalam senarai kenalan anda."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Syarikat"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Tajuk"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kenalan tidak wujud."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget kenalan telah ditambahkan ke skrin Utama."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Wujudkan kenalan baru"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Buat kenalan baharu"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> ditemui"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"lebih daripada <xliff:g id="COUNT">%d</xliff:g> ditemui."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Tiada dijumpai."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Tiada kenalan"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 ditemui"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> ditemui"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Semua"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Semua kenalan"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Kumpulan"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Kegemaran"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Padam bersih log panggilan?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Semua rekod panggilan anda akan dipadamkan."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Memadam bersih log panggilan..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Padam bersih senarai kerap dihubungi?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Anda akan mengosongkan senarai orang yang kerap dihubungi dalam apl Orang dan Telefon serta memaksa apl e-mel untuk mempelajari pilihan alamat anda dari awal."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Memadam bersih senarai kerap dihubungi..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Mel suara"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> saat"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Kerap dihubungi"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Kerap dipanggil"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Tambah kenalan"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Tambah \"<xliff:g id="EMAIL">%s</xliff:g>\" kepada kenalan?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"satu"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dua"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"tolak"</string>
     <string name="description_plus_button" msgid="515164827856229880">"tambah"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Lihat kenalan"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Storan tidak tersedia"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Tiada kad SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Tiada storan ditemui."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Tiada kad SD ditemui."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Mencari vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Import daripada kad SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Import dari storan"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Eksport ke storan"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Import semua fail vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Mencari data vCard pada storan..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Mencari data vCard pada kad SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Tidak dapat mengimbas storan"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Tidak dapat mengimbas kad SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Storan tidak boleh diimbas. (Alasan: \" <xliff:g id="FAIL_REASON">%s</xliff:g> \")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Kad SD tidak boleh diimbas. (Alasan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Ralat I/O"</string>
@@ -254,7 +253,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> akan dieksport sebentar lagi."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Permintaan eksport vCard telah ditolak. Cuba lagi nanti."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kenalan"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Eksport kenalan?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Senarai kenalan anda akan dieksport ke: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Tidak boleh mengeksport"</string>
@@ -275,26 +274,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Komposer vCard tidak bermula dengan betul."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Tidak dapat membuka \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> daripada <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kenalan"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Membatalkan mengimport vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Batalkan pengimportan <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Membatalkan mengeksport vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Batalkan pengeksportan <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Tidak dapat membatalkan import/eksport vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Nama kenalan anda"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Tambah jeda 2 saat"</string>
     <string name="add_wait" msgid="3360818652790319634">"Tambah penungguan"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Panggil menggunakan"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Pilih nombor"</string>
     <string name="call_settings" msgid="7666474782093693667">"Tetapan"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"SMS menggunakan"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Pilih nombor"</string>
     <string name="make_primary" msgid="5829291915305113983">"Ingat pilihan ini"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Tiada aplikasi ditemui untuk mengendalikan tindakan ini."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Tiada nama)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Akaun"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Padam bersih kerap dihubungi"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kenalan untuk dipaparkan"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Import/eksport"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import/Eksport kenalan"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Import kenalan"</string>
     <string name="menu_share" msgid="943789700636542260">"Kongsi"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Semua kenalan"</string>
     <string name="share_via" msgid="563121028023030093">"Kongsi gambar melalui"</string>
     <string name="share_error" msgid="948429331673358107">"Kenalan ini tidak boleh dikongsi."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nama"</string>
@@ -413,7 +411,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Lihat nama kenalan sebagai"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nama berian dahulu"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Nama keluarga dahulu"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Cari dalam kenalan"</string>
     <string name="take_photo" msgid="7496128293167402354">"Ambil foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Ambil foto baru"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Pilih foto dari Galeri"</string>
@@ -443,9 +440,7 @@
     <item quantity="other" msgid="425683718017380845">"digabungkan daripada <xliff:g id="COUNT">%0$d</xliff:g> sumber"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Lain-lain"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Gabungkan kenalan"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Gabungkan kenalan semasa dengan kenalan pilihan?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Edit kenalan pilihan"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Bertukar kepada mengedit kenalan pilihan? Maklumat yang anda masukkan setakat ini akan disalin."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Salin ke Kenalan Saya"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Tambahkan pada Kenalan Saya"</string>
@@ -464,6 +459,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Tetapan"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kenalan untuk dipaparkan"</string>
     <string name="menu_settings" msgid="377929915873428211">"Tetapan"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Bantuan"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Pilihan paparan"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Cari kenalan"</string>
@@ -477,10 +473,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Memuatkan…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Buat kenalan baru"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Log masuk ke akaun"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Import kenalan dari fail"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Import kenalan"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Buat kumpulan baru"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Buat kumpulan baru]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Padam kumpulan"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Buat kumpulan baharu"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 kumpulan"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> kumpulan"</item>
@@ -499,9 +494,8 @@
     <string name="set_default" msgid="4417505153468300351">"Tetapkan lalai"</string>
     <string name="clear_default" msgid="7193185801596678067">"Kosongkan lalai"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Teks disalin"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Buang perubahan"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Buang perubahan anda?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Sediakan profil saya"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Taip nama orang"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Lihat kemas kini"</string>
@@ -509,6 +503,7 @@
     <item quantity="one" msgid="1746619685488504230">"Mel suara"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Mel suara"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Main"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Mel suara baru daripada <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Tidak dapat memainkan mel suara."</string>
@@ -563,7 +558,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Simpan setempat"</string>
     <string name="add_account" msgid="8201790677994503186">"Tambah akaun"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Tambah akaun baharu"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Panggilan tidak dihantar"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Nombor mel suara tidak tersedia"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Panggilan tidak dihantar"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Untuuk menyediakan mel suara, pergi ke Menu &gt; Tetapan."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Untuk membuat panggilan ke mel suara, mula-mula matikan mod Pesawat."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Lagi pilihan"</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 37e4946..b435f1f 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Søk"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Ny kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Se på kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Ring <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Ring <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Legg til som favoritt"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Fjern fra favoritter"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Rediger"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Slett"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiér"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Plassér på startsiden"</string>
     <string name="menu_call" msgid="3992595586042260618">"Ring kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Send SMS til kontakt"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Del"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Forslag"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Alle kontakter"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontaktene er forent"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Slette kontakten?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Angi ringetone"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Alle samtaler til talepost"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Du kan ikke slette kontakter fra skrivebeskyttede kontoer, men du kan skjule dem i kontaktlisten."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Firma"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Tittel"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakten finnes ikke."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kontaktmodulen ble lagt til på startsiden."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Opprett ny kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Opprett ny kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -89,7 +91,7 @@
   </string-array>
     <string name="photoPickerNotFoundText" product="tablet" msgid="6247290728908599701">"Ingen bilder er tilgjengelige på nettbrettet."</string>
     <string name="photoPickerNotFoundText" product="default" msgid="431331662154342581">"Det er ingen bilder på telefonen."</string>
-    <string name="attach_photo_dialog_title" msgid="5599827035558557169">"Kontaktens bilde"</string>
+    <string name="attach_photo_dialog_title" msgid="5599827035558557169">"Kontaktbilde"</string>
     <string name="customLabelPickerTitle" msgid="1081475101983255212">"Egendefinert etikett"</string>
     <string name="send_to_voicemail_checkbox" msgid="9001686764070676353">"Send anrop direkte til telefonsvarer."</string>
     <string name="removePhoto" msgid="4898105274130284565">"Fjern bilde"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> funnet"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Fant over <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Fant ingen."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Ingen kontakter"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 funnet"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> funnet"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Alle"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Alle kontakter"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupper"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritter"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Tømme samtaleloggen?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Alle samtalelogger kommer til å slettes."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Tømmer anropsloggen …"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Fjerne ofte kontaktede personer?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Du fjerner listen over ofte kontaktede personer i Personer-appen og Telefon-appen, og tvinger e-postappene til å bli kjent med adresseinnstillingene fra grunnen av."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Fjerner ofte kontaktede personer"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Telefonsvarer"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> sek"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Ofte kontaktet"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Ofte oppringt"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Legg til kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Legg til «<xliff:g id="EMAIL">%s</xliff:g>» som kontakt?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"en"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"to"</string>
@@ -205,15 +209,12 @@
     <string name="description_dial_button" msgid="1274091017188142646">"ring"</string>
     <string name="description_delete_button" msgid="6263102114033407382">"tilbaketast"</string>
     <string name="description_digits_edittext" msgid="8760207516497016437">"ring til"</string>
-    <string name="description_contact_photo" msgid="3387458082667894062">"kontaktens bilde"</string>
+    <string name="description_contact_photo" msgid="3387458082667894062">"kontaktbilde"</string>
     <string name="description_minus_button" msgid="387136707700230172">"minusknapp"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plussknapp"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Se kontakt"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Lagring utilgjengelig"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Mangler minnekort"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Finner ikke lagringsplass."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Finner ikke SD-kort."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Leter etter VCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importér fra SIM-kort"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importér fra lagring"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Eksportér til lagring"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importer alle vCard-filer"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Søker etter vCard-data i lagringsenheten …"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Søker etter vCard-data på SD-kortet …"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Kunne ikke skanne lagring"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Kunne ikke skanne SD-kort"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Lagringsenheten kunne ikke skannes. (Grunn: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD-kortet kan ikke skannes. (Grunn: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Inn-/ut-feil"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> vil eksporteres snart."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Forespørselen om eksport av vCard ble avvist. Prøv på nytt senere."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Eksp. kontaktene?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Kontaktlisten din blir eksportert til: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Eksport mislyktes"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard-oppretteren startet ikke som den skulle."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Kan ikke åpne «<xliff:g id="FILE_NAME">%s</xliff:g>»: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> av <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontakter"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Avbryt import av vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Vil du avbryte importen av <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Avbryt eksport av vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Vil du avbryte eksporten av <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Kunne ikke kansellere imp./eksp. av vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Navn på kontakter"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Legg til pause på 2 sek."</string>
     <string name="add_wait" msgid="3360818652790319634">"Legg til Vent"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Ring med"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Velg nummer"</string>
     <string name="call_settings" msgid="7666474782093693667">"Innstillinger"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Send SMS med"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Velg nummer"</string>
     <string name="make_primary" msgid="5829291915305113983">"Husk dette valget"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Det ble ikke funnet noen app som kan håndtere denne handlingen."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Uten navn)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Kontoer"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Fjern ofte kontaktede personer"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakter i visning"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importér/eksportér"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Imp./eksp. kontakter"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importer kontakter"</string>
     <string name="menu_share" msgid="943789700636542260">"Del"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Alle kontakter"</string>
     <string name="share_via" msgid="563121028023030093">"Del kontakt via"</string>
     <string name="share_error" msgid="948429331673358107">"Denne kontakten kan ikke deles."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Navn"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Vis kontaktnavn som"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Fornavn først"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Etternavn først"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Søk etter kontakter"</string>
     <string name="take_photo" msgid="7496128293167402354">"Ta bilde"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Ta nytt bilde"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Velg bilde fra galleriet"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"sammenslått fra <xliff:g id="COUNT">%0$d</xliff:g> kilder"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Andre"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Slå sammen kontakter"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Slå sammen gjeldende kontakt med valgt kontakt?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Rediger valgte kontakter"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Bytt til redigering av gjeldende kontakt? Informasjonen du har lagt til så langt blir kopiert."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopiér til mine kontakter"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Legg til i Mine kontakter"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Innstillinger"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakter i visning"</string>
     <string name="menu_settings" msgid="377929915873428211">"Innstillinger"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Hjelp"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Vis grupper"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Finn kontakter"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Laster inn …"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Opprett en ny kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Logg deg på en konto"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importer kontakter fra en fil"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importer kontakter"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Opprett ny gruppe"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Opprett ny gruppe]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Slett gruppe"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Opprett en ny gruppe"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Én gruppe"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupper"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Angi som standard"</string>
     <string name="clear_default" msgid="7193185801596678067">"Fjern som standard"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst kopiert"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Forkast endringer"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Vil du forkaste endringene?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Konfigurer profilen min"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Tast inn personens navn"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Se oppdateringer"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Talepostkasse"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> talemeldinger"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Spill av"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nye talemeldinger fra <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Kunne ikke spille av talemelding."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Behold lokalt"</string>
     <string name="add_account" msgid="8201790677994503186">"Legg til konto"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Legg til ny konto"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Anrop ikke foretatt"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Talepostkassenummer utilgjengelig"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Anrop ikke utført"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Du konfigurerer talepost ved å gå til Meny &amp;gt Innstillinger"</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Du må slå av flymodus før du kan sjekke talepostkassen."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Flere alternativer"</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index b4a7617..8827837 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Zoeken"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nieuw contact"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Contact weergeven"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"<xliff:g id="NAME">%s</xliff:g> bellen"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Bel <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Toevoegen aan favorieten"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Uit favorieten verwijderen"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Bewerken"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Verwijderen"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiëren"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Op startscherm plaatsen"</string>
     <string name="menu_call" msgid="3992595586042260618">"Contact bellen"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Sms\'en naar contact"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Scheiden"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Mogelijke contacten"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Alle contacten"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contacten zijn samengevoegd"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Contact verwijderen?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Beltoon instellen"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Alle oproepen naar voicemail"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"U kunt contacten niet verwijderen uit alleen-lezen-accounts, maar u kunt ze verbergen in uw contactenlijst."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Bedrijf"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titel"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Het contact bestaat niet."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget voor contacten toegevoegd aan het startscherm."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Nieuw contact maken"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Nieuw contact maken"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefoon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> gevonden"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Meer dan <xliff:g id="COUNT">%d</xliff:g> gevonden."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Niets gevonden."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Geen contacten"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 gevonden"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> gevonden"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Alle"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Alle contacten"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Groepen"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriet"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefoon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Oproeplog wissen?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Al uw oproepgegevens worden verwijderd."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Oproeplogboek wissen..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Lijst met regelmatige contacten wissen?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"U wist de lijst met contacten waarmee u regelmatig contact opneemt in de apps Personen en Telefoon, en e-mailapps moeten uw voorkeursadressen weer opnieuw leren."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Regelmatige contacten wissen..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI-nummer"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sec."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Regelmatig contact"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Vaak gebeld"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Contact toevoegen"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Voeg \"<xliff:g id="EMAIL">%s</xliff:g>\" toe aan contactpersonen?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"één"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"twee"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"min"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Contact weergeven"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Opslag niet beschikbaar"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Geen SD-kaart"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Er is geen opslag gevonden."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Geen SD-kaart gevonden."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Zoeken naar vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importeren van SIM-kaart"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importeren uit opslag"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exporteren naar opslag"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Alle vCard-bestanden importeren"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Zoeken naar vCard-gegevens in opslag..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Zoeken naar vCard-gegevens op SD-kaart..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Kan opslag niet scannen"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Kan SD-kaart niet scannen"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"De opslag kan niet worden gescand. (Reden: \'<xliff:g id="FAIL_REASON">%s</xliff:g>\')"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"De SD-kaart kan niet worden gescand. (Reden: \'<xliff:g id="FAIL_REASON">%s</xliff:g>\')"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O-fout"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> wordt binnenkort geëxporteerd."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Verzoek voor vCard-export is geweigerd. Probeer het later opnieuw."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contact"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Contacten export.?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Uw lijst met contacten wordt geëxporteerd naar het bestand: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Kan niet exporteren"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"De vCard-editor is niet correct gestart."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Kan \'<xliff:g id="FILE_NAME">%s</xliff:g>\' niet openen: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> van <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contacten"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Importeren van vCard annuleren"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Import van <xliff:g id="FILENAME">%s</xliff:g> annuleren?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Exporteren van vCard annuleren"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Export van <xliff:g id="FILENAME">%s</xliff:g> annuleren?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Kan vCard-import/export niet annuleren"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Namen van uw contacten"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Pauze van 2 seconden toevoegen"</string>
     <string name="add_wait" msgid="3360818652790319634">"Wachten toevoegen"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Bellen met"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Nummer kiezen"</string>
     <string name="call_settings" msgid="7666474782093693667">"Instellingen"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Sms\'en met"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Nummer kiezen"</string>
     <string name="make_primary" msgid="5829291915305113983">"Deze keuze onthouden"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Er is geen app gevonden om deze actie uit te voeren."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Geen naam)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Accounts"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Regelmatige contacten wissen"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Zichtbare contacten"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importeren/exporteren"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Contacten importeren/exporteren"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Contacten importeren"</string>
     <string name="menu_share" msgid="943789700636542260">"Delen"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Alle contacten"</string>
     <string name="share_via" msgid="563121028023030093">"Contact delen via"</string>
     <string name="share_error" msgid="948429331673358107">"Dit contact kan niet worden gedeeld."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Naam"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Contactnamen weergeven als"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Roepnaam eerst"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Achternaam eerst"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Contacten zoeken"</string>
     <string name="take_photo" msgid="7496128293167402354">"Foto maken"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Nieuwe foto nemen"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Foto kiezen in Galerij"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"samengevoegd uit <xliff:g id="COUNT">%0$d</xliff:g> bronnen"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Overig"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Contacten samenvoegen"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Wilt u het huidige contact samenvoegen met het geselecteerde contact?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Geselecteerde contacten bewerken"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Wilt u overschakelen naar het bewerken van het geselecteerde contact? Gegevens die u tot nu toe heeft ingevoerd, worden gekopieerd."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopiëren naar mijn contacten"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Toevoegen aan Mijn contacten"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Instellingen"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Zichtbare contacten"</string>
     <string name="menu_settings" msgid="377929915873428211">"Instellingen"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Help"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Weergaveopties"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Contacten vinden"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Laden..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Een nieuw contact maken"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Aanmelden bij een account"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Contacten importeren uit een bestand"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Contacten importeren"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Nieuwe groep maken"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Nieuwe groep maken]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Groep verwijderen"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Nieuwe groep maken"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 groep"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> groepen"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Standaard instellen"</string>
     <string name="clear_default" msgid="7193185801596678067">"Standaardwaarden wissen"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst gekopieerd"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Wijzigingen annuleren"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Uw wijzigingen annuleren?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Mijn profiel instellen"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Typ de naam van de persoon"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Updates bekijken"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Voicemail"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> voicemails"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Afspelen"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nieuwe voicemail van <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Kan voicemail niet afspelen."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Lokaal opslaan"</string>
     <string name="add_account" msgid="8201790677994503186">"Account toevoegen"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Nieuw account toevoegen"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Oproep niet verzonden"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Voicemailnummer niet beschikbaar"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Oproep niet uitgevoerd"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Voor het instellen van voicemail, gaat u naar \'Menu\' &gt; \'Instellingen\'."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Als u uw voicemail wilt bellen, moet u eerst de Vliegmodus uitschakelen."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Meer opties"</string>
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index de6c6bd..699a908 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Szukaj"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nowy kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Wyświetl kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Zadzwoń do: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Zadzwoń: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Dodaj do ulubionych"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Usuń z ulubionych"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Edytuj"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Usuń"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiuj"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Umieść na ekranie głównym"</string>
     <string name="menu_call" msgid="3992595586042260618">"Zadzwoń do kontaktu"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Wyślij tekst do kontaktu"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Podziel"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Sugerowane kontakty"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Wszystkie kontakty"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontakty zostały połączone"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Usunąć kontakt?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Ustaw dzwonek"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Łącz na pocztę głosową"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Nie możesz usunąć kontaktów z kont tylko do odczytu, ale możesz ukryć je na swoich listach kontaktów."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Firma"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Stanowisko"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakt nie istnieje."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widżet kontaktu dodany do ekranu głównego."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Utwórz nowy kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Utwórz nowy kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Znaleziono: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Znaleziono więcej niż <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Brak wyników"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Brak kontaktów"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Znaleziono: 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Znaleziono: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Wszystkie"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Wszystkie kontakty"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupy"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Ulubione"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Usunąć rejestr połączeń?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Wszystkie dane połączeń zostaną usunięte."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Czyszczenie rejestru połączeń…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Wyczyścić częste kontakty?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Wyczyścisz listę częstych kontaktów w aplikacjach Osoby i Telefon. Aplikacje pocztowe będą musiały od nowa poznawać Twoje preferencje adresowe."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Czyszczę częste kontakty…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"Numer MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Poczta głosowa"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Częste kontakty"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Częste połączenia"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Dodaj kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Czy dodać adres „<xliff:g id="EMAIL">%s</xliff:g>” do kontaktów?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"jeden"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dwa"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Wyświetl kontakt"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Nośnik nie jest dostępny"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Brak karty SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nie znaleziono nośnika."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nie znaleziono karty SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Wyszukiwanie danych vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importuj z karty SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importuj z nośnika"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Eksportuj na nośnik"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importuj wszystkie pliki vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Wyszukiwanie danych vCard na nośniku…"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Wyszukiwanie danych vCard na karcie SD…"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Nie można przeskanować pamięci"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Nie można przeskanować karty SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Nie można przejrzeć nośnika. (Przyczyna: „<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Nie można przejrzeć karty SD. (Przyczyna: „<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Błąd wejścia/wyjścia"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Plik <xliff:g id="FILENAME">%s</xliff:g> zostanie za chwilę wyeksportowany."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Żądanie eksportu danych vCard zostało odrzucone. Spróbuj ponownie później."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Eksport kontaktów?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Lista kontaktów zostanie wyeksportowana do pliku: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Eksport nieudany"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Obiekt tworzenia danych vCard nie został uruchomiony poprawnie."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Nie można otworzyć pliku „<xliff:g id="FILE_NAME">%s</xliff:g>”: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"Kontakt <xliff:g id="CURRENT_NUMBER">%s</xliff:g> z <xliff:g id="TOTAL_NUMBER">%s</xliff:g>"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Anulowanie importowania pliku vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Anulować import: <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Anulowanie eksportowania pliku vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Anulować eksport: <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Nie można anulować importu/eksportu vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Imiona i nazwiska oraz nazwy w Twoich kontaktach"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Dodaj 2-sekundową pauzę"</string>
     <string name="add_wait" msgid="3360818652790319634">"Dodaj oczekiwanie"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Zadzwoń przy użyciu"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Wybierz numer"</string>
     <string name="call_settings" msgid="7666474782093693667">"Ustawienia"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Wyślij SMS przy użyciu"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Wybierz numer"</string>
     <string name="make_primary" msgid="5829291915305113983">"Zapamiętaj ten wybór"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nie znaleziono aplikacji do obsługi tego działania."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Bez nazwy)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Konta"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Wyczyść częste kontakty"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakty do wyświetlenia"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importuj/eksportuj"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importuj/eksportuj kontakty"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importuj kontakty"</string>
     <string name="menu_share" msgid="943789700636542260">"Udostępnij"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Wszystkie kontakty"</string>
     <string name="share_via" msgid="563121028023030093">"Udostępnij kontakt przez"</string>
     <string name="share_error" msgid="948429331673358107">"Tego kontaktu nie można udostępniać."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nazwa"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Wyświetl nazwy kontaktów jako"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Najpierw imię"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Najpierw nazwisko"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Szukaj kontaktów"</string>
     <string name="take_photo" msgid="7496128293167402354">"Zrób zdjęcie"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Zrób nowe zdjęcie"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Wybierz zdjęcie z galerii"</string>
@@ -432,8 +429,8 @@
     <string name="add_organization" msgid="7311893231158291197">"Dodaj organizację"</string>
     <string name="event_edit_field_hint_text" msgid="5794424930242630477">"Data"</string>
     <string name="group_edit_field_hint_text" msgid="3966441850870457808">"Nazwa grupy"</string>
-    <string name="contact_status_update_attribution" msgid="752179367353018597">"za pośrednictwem: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
-    <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g>, za pośrednictwem: <xliff:g id="SOURCE">%2$s</xliff:g>"</string>
+    <string name="contact_status_update_attribution" msgid="752179367353018597">"przez: <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
+    <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g>, przez: <xliff:g id="SOURCE">%2$s</xliff:g>"</string>
     <string name="description_star" msgid="2605854427360036550">"ulubione"</string>
     <string name="edit_contact" msgid="7529281274005689512">"Edytuj kontakt"</string>
   <plurals name="merge_info">
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"scalono z <xliff:g id="COUNT">%0$d</xliff:g> źródeł"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Inne"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Połącz kontakty"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Czy połączyć bieżący kontakt z wybranym?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Edytuj wybrane kontakty"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Czy chcesz edytować wybrany kontakt? Wprowadzone dotąd informacje zostaną skopiowane."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopiuj do moich kontaktów"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Dodaj do moich kontaktów"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Ustawienia"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakty do wyświetlenia"</string>
     <string name="menu_settings" msgid="377929915873428211">"Ustawienia"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Pomoc"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opcje wyświetlania"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Znajdź kontakty"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Wczytywanie…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Utwórz nowy kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Zaloguj się na konto"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Zaimportuj kontakty z pliku"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importuj kontakty"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Utwórz nową grupę"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Utwórz nową grupę]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Usuń grupę"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Utwórz nową grupę"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupa"</item>
     <item quantity="other" msgid="1276758425904917367">"Grupy: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Ustaw jako wartość domyślną"</string>
     <string name="clear_default" msgid="7193185801596678067">"Wyczyść wartość domyślną"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst skopiowany"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Odrzuć zmiany"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Odrzucić zmiany?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Konfiguruj profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Wpisz imię osoby"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Pokaż aktualizacje"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Poczta głosowa"</item>
     <item quantity="other" msgid="5513481419205061254">"Wiadomości głosowe: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Odtwórz"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nowa poczta głosowa od: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Nie można odtworzyć poczty głosowej."</string>
@@ -557,11 +552,12 @@
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"Dodaj konto"</string>
     <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Kopia zapasowa nowego kontaktu nie zostanie utworzona. Dodać konto, na którym kopie zapasowe kontaktów będą tworzone online?"</string>
     <string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"Nowy kontakt zostanie zsynchronizowany z kontem <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
-    <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Nowy kontakt możesz zsynchronizować z jednym z następujących kont. Którego z nich chcesz użyć?"</string>
+    <string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Nowy kontakt możesz zsynchronizować z dowolnym kontem. Którego chcesz użyć?"</string>
     <string name="keep_local" msgid="1258761699192993322">"Przechowuj lokalnie"</string>
     <string name="add_account" msgid="8201790677994503186">"Dodaj konto"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Dodaj nowe konto"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Połączenie nie zostało zrealizowane"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Numer poczty głosowej niedostępny"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Połączenie nie zostało zrealizowane"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Aby skonfigurować pocztę głosową, przejdź do Menu &gt; Ustawienia."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Aby połączyć się z pocztą głosową, najpierw wyłącz tryb samolotowy."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Więcej opcji"</string>
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 72be05f..98f6a06 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Pesquisar"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Novo contacto"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Visualizar contacto"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Ligar a <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Telefonar para <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Adicionar aos favoritos"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Remover dos favoritos"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Editar"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Eliminar"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copiar"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Colocar no Ecrã principal"</string>
     <string name="menu_call" msgid="3992595586042260618">"Ligar para contacto"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Enviar SMS/MMS para contacto"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separar"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contactos sugeridos"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Todos os contactos"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contactos associados"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Eliminar contacto?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Definir toque"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Todas chm. para corr. de voz"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Não pode eliminar contactos de contas só de leitura, mas pode ocultá-los nas suas listas de contactos."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Empresa"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Título"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"O contacto não existe."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget de contacto adicionado ao seu Ecrã principal."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Criar novo contacto"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Criar novo contacto"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefone"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> encontrado(s)"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Foram encontrados mais de <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Não foi encontrado nenhum."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Sem contactos"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 encontrado"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> encontrado(s)"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tudo"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Todos os contactos"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefone"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Limpar reg. de cham.?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Todos os registos de chamadas serão eliminados."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"A limpar registo de chamadas..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Limpar contactos frequentes?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Irá limpar a lista de contactos frequentes nas aplicações Pessoas e Telemóvel e forçar as aplicações de email a aprenderem as suas preferências de endereço de raiz."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"A limpar contactos frequentes..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Correio de voz"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> seg"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Contactos frequentes"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Números de marcação frequente"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Adicionar contacto"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Adicionar \"<xliff:g id="EMAIL">%s</xliff:g>\" aos contactos?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"um"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dois"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
     <string name="description_plus_button" msgid="515164827856229880">"mais"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Ver contacto"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Armazen. indisponível"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nenhum cartão SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nenhum armazen. encontrado."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Não foi encontrado nenhum cartão SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"A procurar vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importar do cartão SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importar do armazenamento"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportar para o armazen."</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importar todos os ficheiros VCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"A pesquisar dados de vCard no armazenamento..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"A pesquisar dados de vCard no cartão SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Não foi possível analisar o armazenamento"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Não foi possível analisar o cartão SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Não foi possível analisar o armazenamento. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Não foi possível analisar o cartão SD. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Erro de E/S"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> será exportado em breve."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"O pedido de exportação do vCard foi rejeitado. Tente novamente mais tarde."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contacto"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportar contactos?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"A sua lista de contactos será exportada para o ficheiro: <xliff:g id="VCARD_FILENAME">%s</xliff:g> ."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Impossível exportar"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"O compositor vCard não iniciou corretamente."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Não foi possível abrir \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> de <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contactos"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"A cancelar importação do vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Cancelar a importação de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"A cancelar exportação do vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Cancelar a exportação de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Imposs. cancel. import./export. do vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Nomes dos contactos"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Adicionar pausa de 2 seg."</string>
     <string name="add_wait" msgid="3360818652790319634">"Adicionar espera"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Ligar utilizando"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Selecionar número"</string>
     <string name="call_settings" msgid="7666474782093693667">"Definições"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Enviar SMS utilizando"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Selecionar número"</string>
     <string name="make_primary" msgid="5829291915305113983">"Memorizar esta escolha"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Não foram encontradas aplicações para executar esta ação"</string>
     <string name="missing_name" msgid="8745511583852904385">"(Sem nome)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Contas"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Limpar frequentes"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contactos a apresentar"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importar/exportar"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importar/export. contactos"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importar contactos"</string>
     <string name="menu_share" msgid="943789700636542260">"Partilhar"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Todos os contactos"</string>
     <string name="share_via" msgid="563121028023030093">"Partilhar contacto através de"</string>
     <string name="share_error" msgid="948429331673358107">"Não é possível partilhar este contacto."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nome"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Visualizar nomes de contactos como"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nome próprio em primeiro lugar"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Apelido em primeiro lugar"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Pesquisar contactos"</string>
     <string name="take_photo" msgid="7496128293167402354">"Tirar fotografia"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Tirar nova fotografia"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Escolher fotografia da Galeria"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"intercalado a partir de <xliff:g id="COUNT">%0$d</xliff:g> origens"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Outro"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Associar contactos"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Associar o contacto actual ao contacto selecionado?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Editar contactos seleccionados"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Alternar para edição do contacto selecionado? A informação introduzida até agora vai ser copiada."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copiar para Os Meus Contactos"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Adicionar aos Meus Contactos"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Definições"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contactos a apresentar"</string>
     <string name="menu_settings" msgid="377929915873428211">"Definições"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ajuda"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opções de visualização"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Localizar contactos"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"A carregar…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Criar novo contacto"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Iniciar sessão numa conta"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importar contactos de um ficheiro"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importar contactos"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Criar novo grupo"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Criar novo grupo]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Eliminar grupo"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Criar novo grupo"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupo"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupos"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Definir a predefinição"</string>
     <string name="clear_default" msgid="7193185801596678067">"Limpar predefinição"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Texto copiado"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Rejeitar alterações"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Rejeitar as suas alterações?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149"></string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configurar o meu perfil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Introduza o nome da pessoa"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Ver atualizações"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Correio de voz"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Mensagens de correio de voz"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproduzir"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g> , <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nova msg de correio de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Não foi possível reprod. correio de voz."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Manter localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Adicionar conta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Adicionar nova conta"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Chamada não efetuada"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Número do correio de voz indisponível"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Chamada não efetuada"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar o correio de voz, aceda a Menu &gt; Definições."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para efetuar uma chamada para o correio de voz, desative primeiro o Modo de avião."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Mais opções"</string>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 4457755..a5acbbc 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Pesquisa"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Novo contato"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Ver contato"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Chamar <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Ligar para <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Adicionar aos favoritos"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Remover dos favoritos"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Editar"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Excluir"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copiar"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Colocar na tela inicial"</string>
     <string name="menu_call" msgid="3992595586042260618">"Chamar contato"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Enviar SMS/MMS para o contato"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separar"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contatos sugeridos"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Todos os contatos"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contatos unificados"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Excluir contato?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Definir toque"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Todas as cham. p/ correio voz"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Não é possível excluir os contatos das contas somente leitura, mas você pode ocultá-los nas suas listas de contatos."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Empresa"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Título"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"O contato não existe."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget Contato adicionado à tela inicial."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Criar novo contato"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Criar novo contato"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefone"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> encontrados"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Mais de <xliff:g id="COUNT">%d</xliff:g> encontrados."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nenhum encontrado."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nenhum contato"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Um encontrado"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> encontrados"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tudo"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Todos os contatos"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefone"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Limpar registro de chamadas?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Todos os registros de chamada serão eliminados."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Limpando o registro de chamadas..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Apagar contatos frequentes?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Você apagará a lista de contatos frequentes nos aplicativos Pessoas e Telefone, fazendo com que os aplicativos de e-mail tenham que descobrir suas preferências de endereço."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Apagando contatos frequentes…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Correio de voz"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Chamados frequentemente"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Frequentemente chamado"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Adicionar contato"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Adicionar \"<xliff:g id="EMAIL">%s</xliff:g>\" aos contatos?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"um"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dois"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
     <string name="description_plus_button" msgid="515164827856229880">"mais"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Visualizar contato"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Armazenamento não disponível"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nenhum cartão SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nenhum armazenamento foi encontrado."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nenhum cartão SD foi encontrado."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Pesquisando vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importar do cartão SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importar do armazenamento"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportar para o armazenamento"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importar todos os arquivos do vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Procurando dados do vCard no armazenamento..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Procurando dados do vCard no cartão SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Não foi possível verificar o armazenamento"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Não foi possível verificar o cartão SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Não foi possível verificar o armazenamento. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Não foi possível ler o cartão SD. (Motivo: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Erro E/S"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> será exportado em breve."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Pedido de exportação vCard foi rejeitado. Tente novamente mais tarde."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contato"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportar contatos?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Sua lista de contatos será exportada para o arquivo: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Não foi possível exportar"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"O criador do vCard não iniciou corretamente."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Não foi possível abrir \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> de <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contatos"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Cancelando a importação do vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Cancelar importação de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Cancelando a exportação do vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Cancelar exportação de <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Não foi poss. canc. imp./export. vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Nomes dos seus contatos"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Adicionar pausa de 2 segundos"</string>
     <string name="add_wait" msgid="3360818652790319634">"Adicionar espera"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Chamar usando"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Escolher número"</string>
     <string name="call_settings" msgid="7666474782093693667">"Configurações"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Enviar SMS usando"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Escolher número"</string>
     <string name="make_primary" msgid="5829291915305113983">"Lembrar desta escolha"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nenhum aplicativo foi encontrado para executar esta ação."</string>
     <string name="missing_name" msgid="8745511583852904385">"Sem nome"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Contas"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Apagar frequentes"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Contatos para exibição"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importar/exportar"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importar/Exportar contatos"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importar contatos"</string>
     <string name="menu_share" msgid="943789700636542260">"Compartilhar"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Todos os contatos"</string>
     <string name="share_via" msgid="563121028023030093">"Compartilhar contato via"</string>
     <string name="share_error" msgid="948429331673358107">"Este contato não pode ser compartilhado."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nome"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Visualizar nomes de contato como"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Nome primeiro"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Sobrenome primeiro"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Pesquisar contatos"</string>
     <string name="take_photo" msgid="7496128293167402354">"Tirar foto"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Tirar outra foto"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Escolha fotos da Galeria"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"mesclado a partir de <xliff:g id="COUNT">%0$d</xliff:g> origens"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Outros"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Unir contatos"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Unir o contato atual ao contato selecionado?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Editar contatos selecionados"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Alternar para a edição do contato selecionado? As informações inseridas até agora serão copiadas."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copiar para Meus contatos"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Adicionar a Meus contatos"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Configurações"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Contatos a exibir"</string>
     <string name="menu_settings" msgid="377929915873428211">"Configurações"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ajudar"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opções de exibição"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Localizar contatos"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Carregando…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Criar um novo contato"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Faça login em uma conta"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importar contatos de um arquivo"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importar contatos"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Criar um novo grupo"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Criar um novo grupo]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Excluir grupo"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Criar novo grupo"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Um grupo"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupos"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Definir padrão"</string>
     <string name="clear_default" msgid="7193185801596678067">"Limpar padrão"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Texto copiado"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Descartar alterações"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Descartar as alterações?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g> "</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configurar meu perfil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Digite o nome da pessoa"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Ver atualizações"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Mensagem de voz"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> mensagens de voz"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproduzir"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nova mensagem de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Não foi possível reprod. mens. de voz."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Manter localmente"</string>
     <string name="add_account" msgid="8201790677994503186">"Adicionar conta"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Adicionar nova conta"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Chamada não realizada"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Número de correio de voz indisponível"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Chamada não realizada"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar o correio de voz, vá para Menu &gt; Configurações."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para chamar o correio de voz, primeiro desative o modo avião."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Mais opções"</string>
 </resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index c68d667..43386ba 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -47,13 +47,18 @@
     <string name="menu_search" msgid="9147752853603483719">"Tschertgar"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nov contact"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Mussar il contact"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Telefonar a(d) <xliff:g id="NAME">%s</xliff:g>"</string>
+    <!-- no translation found for menu_callNumber (997146291983360266) -->
+    <skip />
     <string name="menu_addStar" msgid="2908478235715404876">"Agiuntar als favurits"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Allontanar dals favurits"</string>
     <!-- no translation found for menu_editContact (9042415603857662633) -->
     <skip />
     <!-- no translation found for menu_deleteContact (6788644058868189393) -->
     <skip />
+    <!-- no translation found for menu_copy (6108677035381940698) -->
+    <skip />
+    <!-- no translation found for menu_create_contact_shortcut (1217971915748509640) -->
+    <skip />
     <string name="menu_call" msgid="3992595586042260618">"Telefonar al contact"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Trametter in SMS al contact"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Divider"</string>
@@ -77,8 +82,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Contacts proponids"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Tut ils contacts"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Contacts unids"</string>
-    <!-- no translation found for deleteConfirmation_title (1418215926447642260) -->
-    <skip />
     <!-- no translation found for menu_set_ring_tone (8728345772068064946) -->
     <skip />
     <!-- no translation found for menu_redirect_calls_to_vm (4181789196416396656) -->
@@ -100,6 +103,8 @@
     <string name="ghostData_title" msgid="7496735200318496110">"Titel"</string>
     <!-- no translation found for invalidContactMessage (8215051456181842274) -->
     <skip />
+    <!-- no translation found for createContactShortcutSuccessful (7874133287558150877) -->
+    <skip />
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Crear in nov contact"</string>
     <!-- no translation found for pickerNewContactText (6166997164401048211) -->
     <skip />
@@ -167,13 +172,13 @@
   </plurals>
     <!-- no translation found for foundTooManyContacts (5163335650920020220) -->
     <skip />
-    <!-- no translation found for listFoundAllContactsZero (7132202364587656501) -->
+    <!-- no translation found for listFoundAllContactsZero (922980883593159444) -->
     <skip />
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"chattà 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Chattà <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <!-- no translation found for contactsAllLabel (6178225597569649305) -->
+    <!-- no translation found for contactsAllLabel (6479708629170672169) -->
     <skip />
     <!-- no translation found for contactsGroupsLabel (2841971472518003524) -->
     <skip />
@@ -197,6 +202,12 @@
     <skip />
     <!-- no translation found for clearCallLogProgress_title (8365943000154295771) -->
     <skip />
+    <!-- no translation found for clearFrequentsConfirmation_title (766292372438450432) -->
+    <skip />
+    <!-- no translation found for clearFrequentsConfirmation (3254215748990281318) -->
+    <skip />
+    <!-- no translation found for clearFrequentsProgress_title (5157001637482794212) -->
+    <skip />
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Mailbox"</string>
@@ -245,7 +256,6 @@
     <skip />
     <!-- no translation found for favoritesFrequentCalled (6128306889600696124) -->
     <skip />
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Agiuntar in contact"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Agiuntar «<xliff:g id="EMAIL">%s</xliff:g>» als contacts?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"in"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dus"</string>
@@ -268,17 +278,11 @@
     <string name="description_contact_photo" msgid="3387458082667894062">"foto dal contact"</string>
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
-    <!-- no translation found for description_view_contact_detail (9133251213656414807) -->
-    <!-- no translation found for description_view_contact_detail (2795575601596468581) -->
-    <skip />
-    <!-- no translation found for no_sdcard_title (8543619259870877473) -->
-    <skip />
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Nagina carta SD"</string>
+    <string name="description_view_contact_detail" msgid="9133251213656414807">"Mussar il contact"</string>
     <!-- no translation found for no_sdcard_message (5242558018442357189) -->
     <skip />
     <!-- no translation found for no_sdcard_message (3357810406684913482) -->
     <skip />
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Tschertgar datas vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importar da la carta SIM"</string>
     <!-- no translation found for import_from_sdcard (8668347930577565175) -->
     <skip />
@@ -292,10 +296,6 @@
     <skip />
     <!-- no translation found for searching_vcard_message (3962269894118092049) -->
     <skip />
-    <!-- no translation found for scanning_sdcard_failed_title (4944932641334764942) -->
-    <skip />
-    <!-- no translation found for scanning_sdcard_failed_title (6664940444476572612) -->
-    <skip />
     <!-- no translation found for scanning_sdcard_failed_message (7221682312959229201) -->
     <skip />
     <!-- no translation found for scanning_sdcard_failed_message (189023067829510792) -->
@@ -348,7 +348,8 @@
     <skip />
     <!-- no translation found for vcard_unknown_filename (7171709890959915954) -->
     <skip />
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <!-- no translation found for percentage (1044592438199055502) -->
+    <skip />
     <!-- no translation found for confirm_export_title (6834385377255286349) -->
     <skip />
     <!-- no translation found for confirm_export_message (2423421354816428708) -->
@@ -387,12 +388,8 @@
     <!-- no translation found for fail_reason_could_not_open_file (2067725459821997463) -->
     <skip />
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> da <xliff:g id="TOTAL_NUMBER">%s</xliff:g> contacts"</string>
-    <!-- no translation found for cancel_import_confirmation_title (5578683596010294836) -->
-    <skip />
     <!-- no translation found for cancel_import_confirmation_message (3929951040347726757) -->
     <skip />
-    <!-- no translation found for cancel_export_confirmation_title (6516467140276768528) -->
-    <skip />
     <!-- no translation found for cancel_export_confirmation_message (1995462401949262638) -->
     <skip />
     <!-- no translation found for cancel_vcard_import_or_export_failed (6139900383366166706) -->
@@ -400,25 +397,29 @@
     <string name="search_settings_description" msgid="2675223022992445813">"Num da Voss contacts"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Agiuntar ina pausa da 2 secundas"</string>
     <string name="add_wait" msgid="3360818652790319634">"Agiuntar Spetgar"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Telefonar cun"</string>
+    <!-- no translation found for call_disambig_title (4392886850104795739) -->
+    <skip />
     <!-- no translation found for call_settings (7666474782093693667) -->
     <skip />
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Trametter in SMS sur"</string>
+    <!-- no translation found for sms_disambig_title (5846266399240630846) -->
+    <skip />
     <string name="make_primary" msgid="5829291915305113983">"Memorisar questa tscherna"</string>
     <!-- no translation found for quickcontact_missing_app (358168575340921552) -->
     <skip />
     <!-- no translation found for missing_name (8745511583852904385) -->
     <skip />
     <string name="menu_accounts" msgid="8499114602017077970">"Contos"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <!-- no translation found for menu_contacts_filter (2165153460860262501) -->
     <skip />
     <!-- no translation found for menu_import_export (26217871113229507) -->
     <skip />
     <!-- no translation found for dialog_import_export (4360648034889921624) -->
     <skip />
-    <string name="menu_share" msgid="943789700636542260">"Cundivider"</string>
-    <!-- no translation found for menu_all_contacts (5101735431586050711) -->
+    <!-- no translation found for dialog_import (2431698729761448759) -->
     <skip />
+    <string name="menu_share" msgid="943789700636542260">"Cundivider"</string>
     <string name="share_via" msgid="563121028023030093">"Cundivider in contact sur"</string>
     <!-- no translation found for share_error (948429331673358107) -->
     <skip />
@@ -560,7 +561,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Mussar ils nums da contacts sco"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"L\'emprim il prenum"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"L\'emprim il num da famiglia"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Retschertgar ils contacts"</string>
     <string name="take_photo" msgid="7496128293167402354">"Far ina foto"</string>
     <!-- no translation found for take_new_photo (7341354729436576304) -->
     <skip />
@@ -602,12 +602,8 @@
     <item quantity="other" msgid="425683718017380845">"1 contact fusiunà ord <xliff:g id="COUNT">%0$d</xliff:g> funtaunas"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Auter"</string>
-    <!-- no translation found for aggregation_suggestion_join_dialog_title (5276699501316246253) -->
-    <skip />
     <!-- no translation found for aggregation_suggestion_join_dialog_message (3842757977671434836) -->
     <skip />
-    <!-- no translation found for aggregation_suggestion_edit_dialog_title (1064042382692091314) -->
-    <skip />
     <!-- no translation found for aggregation_suggestion_edit_dialog_message (6549585283910518095) -->
     <skip />
     <!-- no translation found for menu_copyContact (1573960845106822639) -->
@@ -645,6 +641,8 @@
     <!-- no translation found for menu_settings (377929915873428211) -->
     <!-- no translation found for menu_settings (377929915873428211) -->
     <skip />
+    <!-- no translation found for menu_help (5123887102216637725) -->
+    <skip />
     <!-- no translation found for preference_displayOptions (1341720270148252393) -->
     <skip />
     <!-- no translation found for organization_company_and_title (6718207751363732025) -->
@@ -671,13 +669,11 @@
     <skip />
     <!-- no translation found for contacts_unavailable_add_account (7911101713860139754) -->
     <skip />
-    <!-- no translation found for contacts_unavailable_import_contacts (4456440183590517471) -->
+    <!-- no translation found for contacts_unavailable_import_contacts (4957393255392437529) -->
     <skip />
     <!-- no translation found for create_group_dialog_title (6874527142828424475) -->
     <skip />
-    <!-- no translation found for create_group_item_label (5218022006186243310) -->
-    <skip />
-    <!-- no translation found for delete_group_dialog_title (7368429698398624427) -->
+    <!-- no translation found for create_group_item_label (4411981763169654825) -->
     <skip />
     <!-- no translation found for num_groups_in_account:one (2944819210288517794) -->
     <!-- no translation found for num_groups_in_account:other (1276758425904917367) -->
@@ -697,11 +693,9 @@
     <skip />
     <!-- no translation found for toast_text_copied (5143776250008541719) -->
     <skip />
-    <!-- no translation found for cancel_confirmation_dialog_title (3950463632415908534) -->
-    <skip />
     <!-- no translation found for cancel_confirmation_dialog_message (5885724679874403115) -->
     <skip />
-    <!-- no translation found for call_type_and_date (1766269584078149149) -->
+    <!-- no translation found for call_type_and_date (747163730039311423) -->
     <skip />
     <!-- no translation found for profile_display_name (4127389543625918771) -->
     <skip />
@@ -711,6 +705,8 @@
     <skip />
     <!-- no translation found for notification_voicemail_title:one (1746619685488504230) -->
     <!-- no translation found for notification_voicemail_title:other (5513481419205061254) -->
+    <!-- no translation found for notification_action_voicemail_play (6113133136977996863) -->
+    <skip />
     <!-- no translation found for notification_voicemail_callers_list (1153954809339404149) -->
     <skip />
     <!-- no translation found for notification_new_voicemail_ticker (895342132049452081) -->
@@ -820,11 +816,12 @@
     <skip />
     <!-- no translation found for add_new_account (5748627740680940264) -->
     <skip />
-    <!-- no translation found for dialog_phone_call_prohibited_title (2111395432187079579) -->
-    <!-- no translation found for dialog_phone_call_prohibited_title (4313552620858880999) -->
-    <skip />
-    <!-- no translation found for dialog_voicemail_not_ready_title (7258109862329777060) -->
-    <skip />
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Il clom n\'è betg vegnì exequì."</string>
     <!-- no translation found for dialog_voicemail_not_ready_message (4384716252789515378) -->
     <skip />
+    <!-- no translation found for dialog_voicemail_airplane_mode_message (530922773669546093) -->
+    <skip />
+    <!-- no translation found for action_menu_overflow_description (2303272250613084574) -->
+    <!-- no translation found for action_menu_overflow_description (2295659037509008453) -->
+    <skip />
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 0133be3..4cd53dc 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Căutaţi"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Persoană nouă în agendă"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Vizualizaţi persoana din agendă"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Apelaţi <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Apelaţi <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Adăugaţi la lista de favorite"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Eliminaţi din lista de favorite"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Editaţi"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Ştergeţi"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Copiaţi"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Plasaţi în ecranul de pornire"</string>
     <string name="menu_call" msgid="3992595586042260618">"Apelaţi persoana din agendă"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Trimiteţi mesaj text către o persoană din agendă"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Separaţi"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Persoane din agendă sugerate"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Toate persoanele din agendă"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Persoanele din agendă au fost unite"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Ştergeţi contactul?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Setaţi ton apel"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Toate apel. către mesag. voc."</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Nu puteţi şterge persoane din agendă, din conturi cu permisiuni doar de citire, însă puteţi să le ascundeţi în lista dvs. de persoane din agendă."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Companie"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titlu"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Persoana nu există în agendă."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widgetul Agendă a fost adăugat la ecranul de pornire."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Creaţi o persoană nouă în agendă"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Creaţi o intrare nouă în Agendă"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Au fost găsite <xliff:g id="COUNT">%d</xliff:g> (de) persoane din agendă"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"S-au găsit peste <xliff:g id="COUNT">%d</xliff:g> (de) persoane din agendă."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nu s-au găsit contacte."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nu există persoane în agendă"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"A fost găsită 1 persoană din agendă"</item>
     <item quantity="other" msgid="7988132539476575389">"Au fost găsite <xliff:g id="COUNT">%d</xliff:g> (de) persoane din agendă"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Toate"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Toată Agenda"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupuri"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favorite"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ştergeţi apelurile?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Toate înregistrările apelurilor dvs. vor fi şterse."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Se goleşte jurnalul de apeluri..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Ştergeţi persoane frecvent contactate?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Veţi şterge lista cu persoanele contactate cel mai frecvent din aplicaţiile Persoane şi Telefon şi veţi forţa aplicaţiile de e-mail să reţină preferinţele dvs. pentru adrese de la zero."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Ştergeți persoane frecv. contactate…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Mesagerie vocală"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> m <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Frecvent contactate"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Frecvent apelate"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Adăugaţi o persoană în agendă"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Adăugaţi „<xliff:g id="EMAIL">%s</xliff:g>” la persoanele din agendă?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"unu"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"doi"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Afişaţi persoana din agendă"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Stocare indisponibilă"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Niciun card SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nu s-a găsit o stocare."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nu s-a găsit un card SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Se caută date în format vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importaţi de pe cardul SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importaţi din stocare"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportaţi în stocare"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importaţi toate fişierele vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Se caută date vCard în spaţiul de stocare..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Se caută date vCard pe cardul SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Nu s-a putut scana stocarea"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Nu s-a putut scana cardul SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Stocarea nu s-a putut scana. (Motivul: „<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Cardul SD nu a putut fi scanat. (Motivul: „<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Eroare I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> va fi exportat în curând."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Solicitarea de exportare a fişierului vCard a fost respinsă. Încercaţi din nou mai târziu."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contact"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportaţi Agenda?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Lista dvs. cu persoane de contact va fi exportată în fişierul: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Nu s-a putut exporta"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Compozitorul vCard nu a pornit în mod corespunzător."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Nu s-a putut deschide fişierul „<xliff:g id="FILE_NAME">%s</xliff:g>”: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> din <xliff:g id="TOTAL_NUMBER">%s</xliff:g> (de) persoane din agendă"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Se anulează importul vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Anulaţi importul fişierului <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Se anulează exportul vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Anulaţi exportul fişierului <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Anulare import/export vCard nereuşită"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Numele persoanelor din agenda dvs."</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Pauză 2 secunde"</string>
     <string name="add_wait" msgid="3360818652790319634">"Adăugaţi interval de aşteptare"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Apelaţi utilizând"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Selectaţi numărul"</string>
     <string name="call_settings" msgid="7666474782093693667">"Setări"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Mesaj text utilizând"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Selectaţi numărul"</string>
     <string name="make_primary" msgid="5829291915305113983">"Reţineţi această alegere"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Nu s-a găsit o aplicaţie care să gestioneze această acţiune."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Fără nume)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Conturi"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Şterg. pers. frecv. contact."</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Persoane de contact de afişat"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importaţi/exportaţi"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Import/export contacte"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importaţi Agenda"</string>
     <string name="menu_share" msgid="943789700636542260">"Distribuiţi"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Toată agenda"</string>
     <string name="share_via" msgid="563121028023030093">"Distribuiţi persoana din agendă prin"</string>
     <string name="share_error" msgid="948429331673358107">"Această persoană de contact nu poate fi distribuită."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Nume"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Vizualizaţi numele persoanei din agendă ca"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Întâi prenumele"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Întâi numele de familie"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Căutaţi în persoanele din agendă"</string>
     <string name="take_photo" msgid="7496128293167402354">"Fotografiaţi"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Creaţi o fotografie nouă"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Alegeţi o fotografie din Galerie"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"au fost îmbinate din <xliff:g id="COUNT">%0$d</xliff:g> surse"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Altul"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Asociaţi intrările din Agendă"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Asociaţi intrarea curentă din agendă cu intrarea selectată?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Editaţi persoanele din agendă selectate"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Comutaţi la funcţia de editare a persoanei din agendă selectate? Informaţiile introduse până acum vor fi copiate."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Copiaţi în Agendă"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Adăugaţi în Agendă"</string>
@@ -462,9 +457,10 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Setări"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Pers. din agendă de afiş."</string>
     <string name="menu_settings" msgid="377929915873428211">"Setări"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Ajutor"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Opţiuni de afişare"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
-    <string name="hint_findContacts" msgid="1808681193458772072">"Găsiţi persoane din agendă"</string>
+    <string name="hint_findContacts" msgid="1808681193458772072">"Găsiţi contacte"</string>
     <string name="non_phone_caption" msgid="1541655052330027380">"Număr de telefon"</string>
     <string name="non_phone_add_to_contacts" msgid="6590985286250471169">"Adăugaţi în Agendă"</string>
     <string name="activity_title_confirm_add_detail" msgid="4065089866210730616">"Adăug. la pers. din ag."</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Se încarcă..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Creaţi o intrare nouă în Agendă"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Conectaţi-vă la un cont"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importaţi agenda din fişier"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importaţi Agenda"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Creaţi un grup nou"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Creaţi un grup nou]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Ştergeţi grupul"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Creaţi un grup nou"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grup"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> (de) grupuri"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Setaţi ca prestabilit"</string>
     <string name="clear_default" msgid="7193185801596678067">"Ştergeţi datele prestabilite"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Text copiat"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Renunţaţi la modificări"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Renunţaţi la modificări?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Configuraţi profilul"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Introduceţi numele persoanei"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Afişaţi actualizări"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Mesaj vocal"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> (de) mesaje vocale"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Redaţi"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Mesaj vocal nou de la <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Nu s-a putut reda mesajul vocal."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Păstraţi local"</string>
     <string name="add_account" msgid="8201790677994503186">"Adăugaţi un cont"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Adăugaţi un cont nou"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Apelul nu a fost trimis"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Număr de mesagerie vocală indisponibil"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Apelul nu a fost trimis"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Pentru a configura mesageria vocală, accesaţi Meniu &gt; Setări."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Pentru a apela mesageria vocală, mai întâi dezactivaţi modul Avion."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Mai multe opţiuni"</string>
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 82e5d07..6602038 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Поиск"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Новый контакт"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Просмотреть контакт"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Вызов: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Позвонить: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Добавить в избранное"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Удалить из избранных"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Изменить"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Удалить"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Копировать"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Поместить на главный экран"</string>
     <string name="menu_call" msgid="3992595586042260618">"Позвонить"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Отправить SMS/MMS"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Разделить"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Предлагаемые контакты"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Все контакты"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Контакты объединены"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Удаление контакта"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Задать рингтон"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Только голос. почта"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Невозможно удалить контакты из аккаунта, доступного только для чтения, однако их можно скрыть в списках контактов."</string>
@@ -74,9 +75,10 @@
     <string name="menu_discard" msgid="6456087569315685632">"Отменить"</string>
     <string name="label_notes" msgid="8337354953278341042">"Примечания"</string>
     <string name="label_sip_address" msgid="124073911714324974">"Интернет-вызов"</string>
-    <string name="ghostData_company" msgid="5414421120553765775">"Компания"</string>
-    <string name="ghostData_title" msgid="7496735200318496110">"Название"</string>
+    <string name="ghostData_company" msgid="5414421120553765775">"Название"</string>
+    <string name="ghostData_title" msgid="7496735200318496110">"Должность"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Контакт удален."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Виджет \"Контакты\" добавлен на главный экран."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Создать новый контакт"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Добавить контакт"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Телефон"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Найдено: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Найдено более <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Ничего не найдено."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Нет контактов"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Найдено: 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Найдено: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Все"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Все контакты"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Группы"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Избранное"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Кнопки"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Удаление данных"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Журнал звонков будет очищен."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Очистка списка вызовов..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Очистить список популярных контактов?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Список популярных контактов в приложениях \"Контакты\" и \"Телефон\" будет очищен, и почтовые приложения начнут создавать этот список заново."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Подождите…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Голосовая почта"</string>
@@ -156,7 +161,7 @@
     <string name="private_num" msgid="6374339738119166953">"Скрытый номер"</string>
     <string name="payphone" msgid="4864313342828942922">"Телефон-автомат"</string>
     <string name="dialerKeyboardHintText" msgid="5401660096579787344">"Наберите номер с клавиатуры"</string>
-    <string name="dialerDialpadHintText" msgid="5824490365898349041">"Наберите номер, чтобы добавить вызов"</string>
+    <string name="dialerDialpadHintText" msgid="5824490365898349041">"Наберите номер"</string>
     <string name="simContacts_emptyLoading" msgid="6700035985448642408">"Загрузка с SIM-карты…"</string>
     <string name="simContacts_title" msgid="27341688347689769">"Контакты на SIM-карте"</string>
     <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Отсутствуют контакты для отображения. (Если аккаунт был только что добавлен, потребуется несколько минут для синхронизации контактов.)"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g>:<xliff:g id="SECONDS">%s</xliff:g>"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Часто набираемые"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Часто вызываемые"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Добавить контакт"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Добавить в контакты <xliff:g id="EMAIL">%s</xliff:g>?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"один"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"два"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"минус"</string>
     <string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Данные контакта"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Накопитель недоступен"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Нет SD-карты"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Хранилище не найдено."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SD-карта не обнаружена."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Поиск vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Импортировать с SIM-карты"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Импорт из накопителя"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Экспорт на накопитель"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Импорт всех файлов VCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Поиск данных vCard на накопителе..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Поиск данных vCard на SD-карте..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Накопитель не просканирован"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD-карта не просканирована"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Не удалось просканировать накопитель. Причина: <xliff:g id="FAIL_REASON">%s</xliff:g>"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Не удалось просканировать SD-карту. Причина: <xliff:g id="FAIL_REASON">%s</xliff:g>"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Ошибка ввода-вывода"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Экспорт <xliff:g id="FILENAME">%s</xliff:g> начнется в ближайшее время."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Запрос на экспорт данных vCard отклонен. Повторите попытку позже."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"контакт"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Экспорт контактов"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Список контактов будет экспортирован в файл \"<xliff:g id="VCARD_FILENAME">%s</xliff:g>\"."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Сбой экспорта"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Сбой при запуске редактора vCard."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Не удалось открыть файл \"<xliff:g id="FILE_NAME">%s</xliff:g>\". Причина: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"Контакт <xliff:g id="CURRENT_NUMBER">%s</xliff:g> из <xliff:g id="TOTAL_NUMBER">%s</xliff:g>"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Отмена импорта vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Отменить импорт файла \"<xliff:g id="FILENAME">%s</xliff:g>\"?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Отмена экспорта vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Отменить экспорт файла \"<xliff:g id="FILENAME">%s</xliff:g>\"?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Не удалось отменить импорт/экспорт vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Имена контактов"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Добавить двухсекундную паузу"</string>
     <string name="add_wait" msgid="3360818652790319634">"Добавить паузу"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Вызов"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Выбор номера"</string>
     <string name="call_settings" msgid="7666474782093693667">"Настройки"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Отправить SMS с помощью"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Выбор номера"</string>
     <string name="make_primary" msgid="5829291915305113983">"Запомнить выбранное"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Действие не поддерживается ни в одном приложении."</string>
     <string name="missing_name" msgid="8745511583852904385">"Имя не указано"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Аккаунты"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Очистить популярные контакты"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Фильтр контактов"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Импорт/экспорт"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Импорт/экспорт контактов"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Импорт контактов"</string>
     <string name="menu_share" msgid="943789700636542260">"Отправить"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Все контакты"</string>
     <string name="share_via" msgid="563121028023030093">"Способ отправки"</string>
     <string name="share_error" msgid="948429331673358107">"Не удалось передать данные."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Имя"</string>
@@ -411,11 +409,10 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Показывать в контактах"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Сначала имя"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Сначала фамилию"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Поиск в контактах"</string>
     <string name="take_photo" msgid="7496128293167402354">"Сфотографировать"</string>
-    <string name="take_new_photo" msgid="7341354729436576304">"Создать новое фото"</string>
-    <string name="pick_photo" msgid="3746334626214970837">"Выбрать фото из галереи"</string>
-    <string name="pick_new_photo" msgid="7962368009197147617">"Выбрать новое фото из Галереи"</string>
+    <string name="take_new_photo" msgid="7341354729436576304">"Сфотографировать"</string>
+    <string name="pick_photo" msgid="3746334626214970837">"Выбрать из Галереи"</string>
+    <string name="pick_new_photo" msgid="7962368009197147617">"Выбрать из Галереи"</string>
     <string name="locale_change_in_progress" msgid="7583992153091537467">"Список контактов обновляется после смены языка интерфейса."</string>
     <string name="upgrade_in_progress" msgid="474511436863451061">"Список контактов обновляется..."</string>
     <string name="upgrade_out_of_memory" msgid="1209994418877625940">"Контакты обновляются."\n\n"Для этого требуется около <xliff:g id="SIZE_IN_MEGABYTES">%s</xliff:g> МБ внутренней памяти."\n\n"Выберите подходящую опцию:"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"объединено из нескольких источников (<xliff:g id="COUNT">%0$d</xliff:g>)"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Другое"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Объединить контакты"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Объединить текущий контакт с выбранным контактом?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Редактировать выбранные контакты"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Переключиться на редактирование выбранного контакта? Введенная информация будет скопирована."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Копировать в \"Мои контакты\""</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Добавить в группу \"Мои контакты\""</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Настройки"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Фильтр контактов"</string>
     <string name="menu_settings" msgid="377929915873428211">"Настройки"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Справка"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Варианты отображения"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Найти контакты"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Загрузка..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Создать новый контакт"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Войдите в аккаунт"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Импорт контактов из файла"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Импортировать контакты"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Создание новой группы"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Создать новую группу]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Удаление группы"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Создать группу"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 группа"</item>
     <item quantity="other" msgid="1276758425904917367">"Групп: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Установить по умолчанию"</string>
     <string name="clear_default" msgid="7193185801596678067">"Удалить настройки по умолчанию"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Текст скопирован"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Отмена изменений"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Отменить изменения?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g>, <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> (<xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>)"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Настроить профиль"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Имя контакта"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Обновления"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Голосовая почта"</item>
     <item quantity="other" msgid="5513481419205061254">"Голосовые сообщения: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Прослушать"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Новое гол. сообщение: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Не удалось воспроизвести сообщение."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Сохранить локально"</string>
     <string name="add_account" msgid="8201790677994503186">"Добавить аккаунт"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Добавить аккаунт"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Вызов не осуществляется"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Номер недоступен"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Вызов невозможен"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Чтобы настроить голосовую почту, выберите \"Меню &gt; Настройки\"."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Сначала отключите режим полета."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Ещё"</string>
 </resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 831be68..1707fb5 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Hľadať"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nový kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Zobraziť kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Zavolať kontakt <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Volať <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Pridať medzi obľúbené položky"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Odstrániť z obľúbených"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Upraviť"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Odstrániť"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopírovať"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Umiestniť na plochu"</string>
     <string name="menu_call" msgid="3992595586042260618">"Zavolať kontaktu"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Odoslať správu kontaktu"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Oddeliť"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Navrhnuté kontakty"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Všetky kontakty"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kontakty boli spojené"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Odstrániť kontakt?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Nastaviť zvonenie"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Všetky hovory do hl. schránky"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Z účtov, ktoré sú iba na čítanie, nie je možné odstrániť kontakty. Tieto kontakty však môžete v zozname kontaktov skryť."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Spoločnosť"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titul"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakt neexistuje."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Miniaplikácia Kontakty bola pridaná na plochu."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Vytvoriť nový kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Vytvoriť nový kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefón"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Počet nájdených položiek: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Našlo sa viac ako <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Nenašli sa žiadne kontakty."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Žiadne kontakty"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Počet nájdených položiek: 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Počet nájdených položiek: <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Všetky"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Všetky kontakty"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Skupiny"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Obľúbené"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefón"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vymazať záznam hov.?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Všetky záznamy o hovoroch budú odstránené."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Vymazávanie denníka hovorov..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vymazať často kontaktované osoby?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Vymažete zoznam často kontaktovaných osôb v aplikáciách Ľudia a Telefón a použijete odznova predvoľby adresátov v e-mailových aplikáciách."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Mazanie často kontaktovaných osôb."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Hlasová schránka"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Najčastejšie používané kontakty"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Najčastejšie volané kontakty"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Pridať kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Chcete pridať „<xliff:g id="EMAIL">%s</xliff:g>“ medzi kontakty?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"jedna"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dva"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"mínus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Zobraziť kontakt"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Uklad. pr. je nedostupný"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Žiadna karta SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Ukladací priestor sa nenašiel."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Nenašla sa žiadna karta SD."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Vyhľadávanie karty vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importovať z karty SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Import z ukl. priestoru"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Export do uklad. priest."</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importovať všetky súbory vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Prebieha hľadanie údajov vizitky vCard v ukladacom priestore..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Prebieha hľadanie údajov vizitky vCard na karte SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Nepodarilo sa prehľadať ukladací priestor"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Nepodarilo sa prehľadať kartu SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Ukladací priestor sa nepodarilo prehľadať. (Dôvod: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Kartu SD sa nepodarilo prehľadať. (Dôvod: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Chyba I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Vizitka <xliff:g id="FILENAME">%s</xliff:g> bude čoskoro exportovaná."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Žiadosť o exportovanie vizitky vCard bola odmietnutá. Skúste to znova neskôr."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportovať kontakty?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Váš zoznam kontaktov bude exportovaný do súboru: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Export sa nepodaril"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Nástroj na tvorbu vizitiek vCard sa nespustil správne."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Súbor „<xliff:g id="FILE_NAME">%s</xliff:g>“ sa nepodarilo otvoriť: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> z <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontaktov"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Prebieha rušenie importu vizitky vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Zrušiť importovanie súboru <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Prebieha rušenie exportu vizitky vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Zrušiť exportovanie súboru <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Importovanie/exportovanie karty vizitky vCard zlyhalo"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Mená vašich kontaktov"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Pridať dvojsekundovú pauzu"</string>
     <string name="add_wait" msgid="3360818652790319634">"Pridať čakanie"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Zavolať pomocou"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Zvoľte číslo"</string>
     <string name="call_settings" msgid="7666474782093693667">"Nastavenia"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Odoslať správu pomocou"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Zvoľte číslo"</string>
     <string name="make_primary" msgid="5829291915305113983">"Zapamätať si túto voľbu"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Bez mena)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Účty"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Vymazať často kontakt. osoby"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakty na zobrazenie"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Import a export"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importovať alebo exportovať kontakty"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Import kontaktov"</string>
     <string name="menu_share" msgid="943789700636542260">"Zdieľať"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Všetky kontakty"</string>
     <string name="share_via" msgid="563121028023030093">"Zdieľať kontakt pomocou"</string>
     <string name="share_error" msgid="948429331673358107">"Tento kontakt nie je možné zdieľať."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Meno"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Zobrazenie mien kontaktov"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Najskôr krstné meno"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Najskôr priezvisko"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Hľadať v kontaktoch"</string>
     <string name="take_photo" msgid="7496128293167402354">"Zaznamenať fotografiu"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Urobiť novú fotografiu"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Vybrať fotografiu z Galérie"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"zlúčené z <xliff:g id="COUNT">%0$d</xliff:g> zdrojov"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Iné"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Spojiť kontakty"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Spojiť aktuálny kontakt s vybraným kontaktom?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Upraviť vybrané kontakty"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Prepnúť do režimu úpravy vybraného kontaktu? Doposiaľ zadané informácie budú skopírované."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Skopírovať do priečinka Moje kontakty"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Pridať medzi moje kontakty"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Nastavenia"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakty na zobrazenie"</string>
     <string name="menu_settings" msgid="377929915873428211">"Nastavenia"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Pomocník"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Možnosti zobrazenia"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Nájsť kontakty"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Načítava sa…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Vytvoriť nový kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Prihlásiť sa do účtu"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importovať kontakty zo súboru"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importovať kontakty"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Vytvoriť novú skupinu"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Vytvoriť novú skupinu]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Odstrániť skupinu"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Vytvoriť novú skupinu"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Počet skupín: 1"</item>
     <item quantity="other" msgid="1276758425904917367">"Počet skupín: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Nastaviť ako predvolené"</string>
     <string name="clear_default" msgid="7193185801596678067">"Vymazať predvolené nastavenia"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Text bol skopírovaný"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Zahodiť zmeny"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Zahodiť zmeny?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Nastaviť môj profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Zadajte meno osoby"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Zobraziť aktualizácie"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Hlasová správa"</item>
     <item quantity="other" msgid="5513481419205061254">"Počet hlasových správ: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Prehrať"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nová hlasová správa – <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Nepodarilo sa prehrať hlasovú správu."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Zachovať miestne"</string>
     <string name="add_account" msgid="8201790677994503186">"Pridať účet"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Pridať nový účet"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Hovor nebol spojený"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Číslo hlasovej schránky je nedostupné"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Hovor nebol spojený"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Ak chcete nastaviť hlasovú schránku, prejdite na položku Menu &gt; Nastavenia."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Ak chcete volať hlasovú schránku, najprv vypnite režim V lietadle."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Ďalšie možnosti"</string>
 </resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 7c988e3..6ff2ed1 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Iskanje"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Nov stik"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Ogled stika"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Pokliči <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Pokliči <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Dodaj k priljubljenim"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Odstrani iz priljubljenih"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Uredi"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Izbriši"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiraj"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Postavi na začetni zaslon"</string>
     <string name="menu_call" msgid="3992595586042260618">"Pokliči stik"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Pošlji SMS stiku"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Razdruži"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Predlagani stiki"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Vsi stiki"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Stiki pridruženi"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Želite izbris. stik?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Nastavi zvonj."</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Vsi klici na odzivnik"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Iz računov samo za branje stikov ni mogoče izbrisati, lahko pa jih skrijete na seznamih stikov."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Podjetje"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Naslov"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Stik ne obstaja."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Pripomoček za stik dodan na začetni zaslon."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Ustvari nov stik"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Ustvari nov stik"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> najdenih"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Najdenih je bilo več kot <xliff:g id="COUNT">%d</xliff:g> stikov."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Najden ni bil noben stik."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Ni stikov"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 najden"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> najdenih"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Vse"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Vsi stiki"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Skupine"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Priljubljeno"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Izbr. dnev. klicev?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Vsi vaši zapisi bodo izbrisani."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Brisanje dnevnika klicev ..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Želite izbrisati seznam pog. stikov?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Izbrisali boste seznam pogostih stikov v aplikacijah Ljudje in Telefon, zato bodo e-poštne aplikacije začele shranjevati vaše pogoste naslovnike od začetka."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Brisanje seznama pogostih stikov …"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Glasovna pošta"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min, <xliff:g id="SECONDS">%s</xliff:g> s"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Pogosti stiki"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Pogosto klicani"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Dodaj stik"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Želite »<xliff:g id="EMAIL">%s</xliff:g>« dodati stikom?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"ena"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dva"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Ogled stika"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Pomnilnik ni na voljo"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Ni kartice SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Shrambe ni bilo mogoče najti."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Kartice SD ni mogoče najti"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Iskanje vizitke vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Uvozi s kartice SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Uvoz iz pomnilnika"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Izvoz v pomnilnik"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Uvozi vse datoteke vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Iskanje podatkov vCard v pomnilniku ..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Iskanje podatkov vCard na kartici SD ..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Pomnilnika ni bilo mogoče pregledati"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Kartice SD ni bilo mogoče pregledati"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Shrambe ni bilo mogoče pregledati. (Razlog: »<xliff:g id="FAIL_REASON">%s</xliff:g>«)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Kartice SD ni bilo mogoče pregledati. (Razlog: »<xliff:g id="FAIL_REASON">%s</xliff:g>«)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Napaka I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Dat. <xliff:g id="FILENAME">%s</xliff:g> bo kmalu izvožena."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Zahteva za izvoz datoteke vCard je bila zavrnjena. Poskusite znova pozneje."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"stik"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Želite izvoz. stike?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Seznam stikov bo izvožen v datoteko: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Izvoz ni mogoč"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Urejevalnik za vCard se ni pravilno zagnal."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Datoteke »<xliff:g id="FILE_NAME">%s</xliff:g>« ni bilo mogoče odpreti: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> od <xliff:g id="TOTAL_NUMBER">%s</xliff:g> stikov"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Preklic uvoza kart. vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Želite preklicati izvoz datoteke <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Preklic izvoza kart. vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Želite preklicati izvoz datoteke <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Uvoza/izvoza vCard ni mogoče preklicati"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Imena stikov"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Dodaj 2 sekundi premora"</string>
     <string name="add_wait" msgid="3360818652790319634">"Dodaj premor"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Pokliči z"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Izberite številko"</string>
     <string name="call_settings" msgid="7666474782093693667">"Nastavitve"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Pošlji SMS z uporabo"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Izberite številko"</string>
     <string name="make_primary" msgid="5829291915305113983">"Zapomni si to izbiro"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Programa za obravnavo tega dejanja ni mogoče najti."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Ni imena)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Računi"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Izbriši seznam pogostih stikov"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Stiki, ki naj bodo prikazani"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Uvoz/izvoz"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Uvoz/izvoz stikov"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Uvoz stikov"</string>
     <string name="menu_share" msgid="943789700636542260">"Skupna raba"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Vsi stiki"</string>
     <string name="share_via" msgid="563121028023030093">"Deli stik z drugimi prek"</string>
     <string name="share_error" msgid="948429331673358107">"Tega stika ni mogoče dati v skupno rabo."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Ime"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Prikaži imena stikov kot"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Najprej ime"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Najprej priimek"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Iskanje stikov"</string>
     <string name="take_photo" msgid="7496128293167402354">"Posnemi fotografijo"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Posnemi novo fotografijo"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Izberite fotografijo iz galerije"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"spojeno iz <xliff:g id="COUNT">%0$d</xliff:g> virov"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Drugo"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Združevanje stikov"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Želite združiti stik z izbranim stikom?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Uredi izbrane stike"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Želite urejati izbrani stik? Podatki, ki ste jih doslej vnesli, bodo kopirani."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopiraj v moje stike"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Dodaj v skupino »Moji stiki«"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Nastavitve"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Stiki za prikaz"</string>
     <string name="menu_settings" msgid="377929915873428211">"Nastavitve"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Pomoč"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Možnosti prikaza"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Najdi stike"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Nalaganje …"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Ustvarjanje novega stika"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Prijava v račun"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Uvoz stikov iz datoteke"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Uvozi stike"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Ustvarjanje nove skupine"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Ustvarjanje nove skupine]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Izbris skupine"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Ustvari novo skupino"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 skupina"</item>
     <item quantity="other" msgid="1276758425904917367">"Št. skupin: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Nastavi za privzeto"</string>
     <string name="clear_default" msgid="7193185801596678067">"Počisti privzeto"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Besedilo kopirano"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Zavrzi spremembe"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Ali želite zavreči spremembe?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Nastavi moj profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Vnesite ime osebe"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Prikaz posodobitev"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Sporočila glasovne pošte"</item>
     <item quantity="other" msgid="5513481419205061254">"Št. sporočil glasovne pošte: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Predvajaj"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g> , <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nova glasovna pošta od <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Sporočil odzivn. ni mogoče predvajati."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Ohrani lokalno"</string>
     <string name="add_account" msgid="8201790677994503186">"Dodaj račun"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Dodaj nov račun"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Klic ni uspel"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Številka odzivnika ni na voljo"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Klic ni uspel"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Če želite nastaviti odzivnik, odprite Meni &gt; Nastavitve."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Če želite poklicati odzivnik, najprej izklopite način za letalo."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Več možnosti"</string>
 </resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 5b85e52..a290f82 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Претрага"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Нови контакт"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Прикажи контакт"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Позови <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Позови <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Додај у омиљене контакте"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Уклони из омиљених контаката"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Измени"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Избриши"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Копирај"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Постави на Почетни екран"</string>
     <string name="menu_call" msgid="3992595586042260618">"Позови контакт"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Пошаљи SMS контакту"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Подели"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Предложени контакти"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Сви контакти"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Придружени контакти"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Желите ли да избришете контакт?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Подеси мелодију звона"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Сви позиви у говорну пошту"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Контакте у оквиру налога који су само за читање не можете да избришете, али можете да их сакријете на листи контаката."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Предузеће"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Наслов"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Контакт не постоји."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Виџет за контакте је додат на Почетни екран."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Направите нови контакт"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Направи нови контакт"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Телефон"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> пронађено"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Пронађено је више од <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Није пронађен ниједан."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Нема контаката"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 пронађен"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> пронађено"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Све"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Сви контакти"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Групе"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Омиљено"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Телефон"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Обрисати евиденцију позива?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Све евиденције позива ће бити избрисане."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Брисање евиденције позива..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Брисање често контактираних?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Обрисаћете листу често контактираних у апликацијама Људи и Телефон, па ће апликације е-поште морати из почетка да сакупе информације о адресирању."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Брисање често контактираних..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Говорна пошта"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> мин <xliff:g id="SECONDS">%s</xliff:g> сек"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Често контактирани"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Често позивани"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Додај контакт"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Желите ли да додате адресу е-поште „<xliff:g id="EMAIL">%s</xliff:g>“ у контакте?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"један"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"два"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"минус"</string>
     <string name="description_plus_button" msgid="515164827856229880">"плус"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Прикажи контакт"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Меморија је недоступна"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Нема SD картице"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Није пронађена меморија."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Није пронађена ниједна SD картица."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Претрага дигиталне визиткарте"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Увези са SIM картице"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Увези из меморије"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Извези у меморију"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Увези све датотеке дигиталних визиткарата"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Тражење података о vCard датотеци у меморији..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"У току је претрага података о vCard датотекама на SD картици..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Није било могуће скенирати складиште"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Није било могуће скенирати SD картицу"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Није било могуће скенирати меморију. (Разлог: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Није било могуће скенирати SD картицу. (Разлог: „<xliff:g id="FAIL_REASON">%s</xliff:g>“)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O грешка"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Датотека <xliff:g id="FILENAME">%s</xliff:g> ће ускоро бити извезена."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Захтев за извоз vCard датотеке је одбијен. Покушајте касније."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"контакт"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Желите ли да извезете контакте?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Листа контаката ће бити извезена у датотеку: <xliff:g id="VCARD_FILENAME">%s</xliff:g> ."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Није могуће извести"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Програм за израду vCard датотека се није исправно покренуо."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Није било могуће отворити датотеку „<xliff:g id="FILE_NAME">%s</xliff:g>“: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> од <xliff:g id="TOTAL_NUMBER">%s</xliff:g> контак(а)та"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Отказивање увоза датотеке"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Желите ли да откажете увоз датотеке <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Отказивање извоза vCard датотеке"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Желите ли да откажете извоз датотеке <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Није могуће отказати vCard увоз/извоз"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Имена контаката"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Додај паузу од 2 секунде"</string>
     <string name="add_wait" msgid="3360818652790319634">"Додај чекање"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Позови помоћу"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Избор броја"</string>
     <string name="call_settings" msgid="7666474782093693667">"Подешавања"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Пошаљи SMS помоћу"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Избор броја"</string>
     <string name="make_primary" msgid="5829291915305113983">"Запамти овај избор"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Није пронађена ниједна апликација која би могла да изврши ову радњу."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Без имена)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Налози"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Обриши често контактиране"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Контакти за приказ"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Увоз/извоз"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Увоз/извоз контаката"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Увоз контаката"</string>
     <string name="menu_share" msgid="943789700636542260">"Дели"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Сви контакти"</string>
     <string name="share_via" msgid="563121028023030093">"Дели контакт преко"</string>
     <string name="share_error" msgid="948429331673358107">"Овај контакт не може да се дели."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Име"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Прикажи имена контаката као"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Најпре име"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Прво презиме"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Претражи контакте"</string>
     <string name="take_photo" msgid="7496128293167402354">"Сними фотографију"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Направи нову фотографију"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Изаберите фотографију из Галерије"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"обједињено од <xliff:g id="COUNT">%0$d</xliff:g> извора"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Други"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Придружи контакте"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Желите ли да тренутни контакт придружите изабраном контакту?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Измена изабраних контаката"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Желите ли да пребаците на уређивање изабраног контакта? Биће копиране информације које сте унели до сада."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Копирај у моје контакте"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Додај у Моје контакте"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Подешавања"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Контакти за приказ"</string>
     <string name="menu_settings" msgid="377929915873428211">"Подешавања"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Помоћ"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Опције приказа"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Пронађи контакте"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Учитавање…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Направи нови контакт"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Пријавите се на налог"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Увези контакте из датотеке"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Увези контакте"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Прављење нове групе"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Направи нову групу]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Избриши групу"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Направи нову групу"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 група"</item>
     <item quantity="other" msgid="1276758425904917367">"Група: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Постави на подразумевано"</string>
     <string name="clear_default" msgid="7193185801596678067">"Обриши подразумевану вредност"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Текст је копиран"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Одбацивање промена"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Желите ли да одбаците промене?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Подеси мој профил"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Унесите име особе"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Прикажи ажурирања"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Говорна пошта"</item>
     <item quantity="other" msgid="5513481419205061254">"Говорних порука: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Пусти"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Нова говорна порука од <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Није било могуће пустити говорну пошту."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Задржи локално"</string>
     <string name="add_account" msgid="8201790677994503186">"Додај налог"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Додај нови налог"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Позив није послат"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Број говорне поште није доступан"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Позив није послат"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Да бисте подесили говорну пошту, идите у Мени &gt; Подешавања."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Да бисте позвали говорну пошту, прво искључите режим авионa."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Још опција"</string>
 </resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 09f3ead..18344da 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Sök"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Ny kontakt"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Visa kontakt"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Ring <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Ring <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Lägg till i Favoriter"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Ta bort från Favoriter"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Redigera"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Ta bort"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopiera"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Placera på startsidan"</string>
     <string name="menu_call" msgid="3992595586042260618">"Ring upp kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Skicka SMS till kontakt"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Dela upp"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Föreslagna kontakter"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Alla kontakter"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Deltagande kontakter"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Ta bort kontakt?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Ställ in ringsignal"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Alla samtal till röstbrevlådan"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Du kan inte ta bort kontakter från skrivskyddade konton, men du kan dölja dem i kontaktlistorna."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Företag"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Titel"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kontakten finns inte."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Widget för kontakt har lagts till på startsidan."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Skapa ny kontakt"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Skapa ny kontakt"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> hittades"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Mer än <xliff:g id="COUNT">%d</xliff:g> hittades."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Inga kontakter hittades."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Inga kontakter"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 hittades"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> hittades"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Alla"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Alla kontakter"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupper"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriter"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Rensa samtalslista?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Alla samtalslistor kommer att tas bort."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Samtalshistoriken rensas …"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Rensa listan?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Du rensar listan över personer som du kontaktar ofta i apparna Personer och Telefon, och e-postappar tvingas lära sig dina mottagarinställningar från början."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Listan rensas …"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI-kod"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Röstbrevlåda"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> minuter <xliff:g id="SECONDS">%s</xliff:g> sekunder"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Ofta kontaktade"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Ringer ofta"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Lägg till kontakt"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Vill du lägga till <xliff:g id="EMAIL">%s</xliff:g> i Kontakter?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"ett"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"två"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Visa kontakt"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Lagring otillgänglig"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Inget SD-kort"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Ingen lagringsenhet hittades."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Inget SD-kort hittades."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Söker efter vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Importera från SIM-kort"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Importera från lagring"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Exportera till lagring"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Importera alla vCard-filer"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Sökning efter vCard-data på lagringsenheten pågår ..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Söker efter vCard-data på SD-kort ..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Det gick inte att söka igenom lagringsenheten"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Det gick inte att söka igenom SD-kortet"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Det gick inte att skanna lagringsenheten. (Orsak: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Det gick inte att skanna SD-kortet. (Orsak: <xliff:g id="FAIL_REASON">%s</xliff:g>)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O-fel"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> exporteras snart."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Begäran om vCard-export avvisades. Försök igen vid ett senare tillfälle."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g> <xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Exportera kontakter?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Kontaktlistan exporteras till filen: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Kunde inte exportera"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard-kompositören initierades inte korrekt."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Det gick inte att öppna <xliff:g id="FILE_NAME">%s</xliff:g>: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> av <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontakter"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Avbryter vCard-import"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Vill du avbryta importen av <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Avbryter vCard-export"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Vill du avbryta exporten av <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Det gick inte att avbryta importen/exporten av vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Dina kontakters namn"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Lägg till en paus på 2 sek."</string>
     <string name="add_wait" msgid="3360818652790319634">"Lägg till väntetid"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Ring upp med"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Välj nummer"</string>
     <string name="call_settings" msgid="7666474782093693667">"Inställningar"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Skicka SMS med"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Välj nummer"</string>
     <string name="make_primary" msgid="5829291915305113983">"Kom ihåg det här valet"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Ingen app som kan hantera åtgärden hittades."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Inget namn)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Konton"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Rensa listan över kontakter"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakter som ska visas"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Importera/exportera"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Importera/exportera kontakter"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Importera kontakter"</string>
     <string name="menu_share" msgid="943789700636542260">"Dela"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Alla kontakter"</string>
     <string name="share_via" msgid="563121028023030093">"Dela kontakt via"</string>
     <string name="share_error" msgid="948429331673358107">"Den här kontakten kan inte delas."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Namn"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Visa kontaktnamn som"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Förnamn först"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Efternamn först"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Sök efter kontakter"</string>
     <string name="take_photo" msgid="7496128293167402354">"Ta en bild"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Ta ny bild"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Välj ett foto från galleriet"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"kombinerade från <xliff:g id="COUNT">%0$d</xliff:g> källor"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Övrigt"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Kombinera kontakter"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Vill du kombinera kontakten med den markerade kontakten?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Redigera valda kontakter"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Vill du fortsätta att redigera den markerade kontakten? Information som du har angett hittills kommer att kopieras."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopiera till mina kontakter"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Lägg till i mina kontakter"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Inställningar"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakter som ska visas"</string>
     <string name="menu_settings" msgid="377929915873428211">"Inställningar"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Hjälp"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Visa alternativ"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Sök efter kontakter"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Läser in …"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Skapa en ny kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Logga in på ett konto"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Importera kontakter från en fil"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Importera kontakter"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Skapa ny grupp"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Skapa ny grupp]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Radera grupp"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Skapa ny grupp"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grupp"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grupper"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Ange standard"</string>
     <string name="clear_default" msgid="7193185801596678067">"Rensa standardinställningar"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Texten har kopierats"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Ignorera ändringar"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Vill du ta bort ändringarna?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Skapa min profil"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Ange personens namn"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Visa uppdateringar"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Röstmeddelanden"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> röstmeddelanden"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Spela upp"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Nytt röstmeddelande från <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Det gick inte att spela upp röstmeddelandet."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Spara lokalt"</string>
     <string name="add_account" msgid="8201790677994503186">"Lägg till ett konto"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Lägg till ett nytt konto"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Samtalet gick inte att koppla fram"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Röstbrevlådenumret är inte tillgängligt"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Samtalet gick inte att koppla fram"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Välj Meny &gt; Inställningar om du vill konfigurera röstbrevlådan."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Om du vill ringa röstbrevlådan måste du först inaktivera flygplansläget."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Fler alternativ"</string>
 </resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 8a34f62..68888d2 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Tafuta"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Anwani mpya"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Tazama anwani"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Piga simu <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Piga simu <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Ongeza kwa vipendwa"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Ondoa kutoka kwa vipendwa vyako"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Hariri"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Futa"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Nakili"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Weka kwenye skrini ya Nyumbani"</string>
     <string name="menu_call" msgid="3992595586042260618">"Mpigie"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Tuma ujumbe kwa anwani"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Kando"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Anwani zilizopendekezwa"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Anwani zote"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Anwani zimeunganishwa"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Futa mwasiliani?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Weka mlio wa simu"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Simu zote kwa barua ya sauti"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Huwezi kufuta anwani kutoka kwa akaunti ya kusoma-tu, lakini unaweza kuzificha katika orodha zako za anwani."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Kampuni"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Jina la heshima"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Mwasiliani hayupo."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Wijeti ya mawasiliano imeongezwa kwenye skrini ya Nyumbani."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Unda akaunti mpya"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Anzisha mwasiliani mpya"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Simu"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Patikana <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"zaidi ya <xliff:g id="COUNT">%d</xliff:g> zimepatikana."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Hakuna iliyopatikana."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Hakuna anwani"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Patikana 1"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> zimepatikana"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Zote"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Anwani zote"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Vikundi"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Vipendwa"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Simu"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Futa rekodi ya simu?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Kumbukumbu zako zote za simu zitafutwa."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Inafuta rekodi ya simu ..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Futa uliowasiliana nao mara kwa mara?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Utafuta orodha ya unaowasiliana nao mara kwa mara katika programu ya Watu na Simu, na ulazimishe programu za barua pepe kujifunza mapendeleo yako ya anwani kutoka mwanzo."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Inafuta uliowasiliana nao mara kwa mara..."</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Barua ya sauti"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"Dakika <xliff:g id="MINUTES">%s</xliff:g> sekunde <xliff:g id="SECONDS">%s</xliff:g>"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Unaowasiliana nao zaidi"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Zinazopigwa mara kwa mara"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Ongeza anwani"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Ongeza \"<xliff:g id="EMAIL">%s</xliff:g>\" kwa anwani?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"moja"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"mbili"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"kutoa"</string>
     <string name="description_plus_button" msgid="515164827856229880">"jumlisha"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Angalia anwani"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Hifadhi haipatikani"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Hakuna kadi ya SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Hakuna hifadhi iliyopatikana."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Hakuna kadi ya SD iliyopatikana."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Inatafuta vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Ingiza kutoka kwa SIM kadi"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Leta kutoka kwa hifadhi"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Hamisha kwa hifadhi"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Ingiza faili zote za vKadi"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Inatafuta data ya vCard katika hifadhi..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Inatafuta data ya vKadi kwenye kadi ya SD"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Haikuweza kusafisha hifadhi"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Haikuweza kusafisha kadi ya SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Hifadhi haiku tambazwa. (Sababu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Kadi ya SD haikutambazwa.(Sababu: \" <xliff:g id="FAIL_REASON">%s</xliff:g> \")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Hitilafu ya I/O"</string>
@@ -254,7 +253,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> itahamishwa hivi karibuni."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Ombi la kuhamishwa kwa vCard limekataliwa. Jaribu tena baadaye."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"anwani"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Hamisha anwani?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Orodha yako ya anwani itahamishwa kwa faili: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Imeshindwa kuhamisha"</string>
@@ -275,26 +274,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Kitunzi cha vCard hakikuanza vizuri."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Haikuweza kufungua \"{<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> ya anwani <xliff:g id="TOTAL_NUMBER">%s</xliff:g>"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Inaghairi uletaji vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Ghairi kuletwa kwa <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Inaghairi uhamishaji wa vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Ghairi kuhamishwa kwa <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Haikuweza kughairiwa kuleta/kuhamisha vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Majina ya anwani zako"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Ongeza usitishaji wa sekunde 2"</string>
     <string name="add_wait" msgid="3360818652790319634">"Ongeza kusubiri"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Piga simu kwa kutumia"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Chagua nambari"</string>
     <string name="call_settings" msgid="7666474782093693667">"Mipangilio"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Tuma ujumbe kwa kutumia"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Chagua nambari"</string>
     <string name="make_primary" msgid="5829291915305113983">"Kumbuka chaguo hili"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Hakuna programu iliyopatikana ya kushughulikia tendo hili."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Hakuna jina)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Akaunti"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Futa idadi ya mara ambazo unawasiliana nao"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Anwani za kuonyesha"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Leta/hamisha"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Leta/Hamisha wawasiliani"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Ingiza wasiliani"</string>
     <string name="menu_share" msgid="943789700636542260">"Shiriki"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Wahusika wote"</string>
     <string name="share_via" msgid="563121028023030093">"Shiriki anwani kupitia"</string>
     <string name="share_error" msgid="948429331673358107">"Mwasiliani huyu hawezi kushirikishwa."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Jina"</string>
@@ -413,7 +411,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Tazama majina ya anwani kama"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Jina ulilopewa kwanza"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Jina la familia kwanza"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Tafuta anwani"</string>
     <string name="take_photo" msgid="7496128293167402354">"Piga picha"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Piga picha mpya"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Chagua picha kutoka kwa Ghala"</string>
@@ -443,9 +440,7 @@
     <item quantity="other" msgid="425683718017380845">"Zimeunganishwa kutoka kwa nyenzo <xliff:g id="COUNT">%0$d</xliff:g>"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Nyingineyo"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Unganisha anwani"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Unganisha anwani ya sasa na anwani iliyochaguliwa?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Hariri majina yaliyochaguliwa"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Badilisha kwa hariri anwani iliyochaguliwa? Maelezo uliyoyaingiza hadi sasa yatanakiliwa."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Nakili kwa Anwani Zangu"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Ongeza kwa Anwani Zangu"</string>
@@ -464,6 +459,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Mipangilio"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Anwani za uonyesha"</string>
     <string name="menu_settings" msgid="377929915873428211">"Mipangilio"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Msaada"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Onyesha machaguo"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Tafuta anwani"</string>
@@ -477,10 +473,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Inapakia…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Unda akaunti mpya"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Ingia katika akaunti"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Leta anwani kutoka kwa faili"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Ingiza wasiliani"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Unda kikundi kipya"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Unda kikundi kipya]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Futa kikundi"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Unda kikundi kipya"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"Kikundi 1"</item>
     <item quantity="other" msgid="1276758425904917367">"Vikundi <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -499,9 +494,8 @@
     <string name="set_default" msgid="4417505153468300351">"Weka chaguo-msingi"</string>
     <string name="clear_default" msgid="7193185801596678067">"Ondoa chaguo-msingi"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Maandishi yamenakiliwa"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Tupa mabadiliko"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Tupa mabadiliko yako?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"Kishika nafasi <xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Sanidi maelezo yangu mafupi"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Charaza jina la mtu"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Tazama visasisho"</string>
@@ -509,6 +503,7 @@
     <item quantity="one" msgid="1746619685488504230">"Barua ya sauti"</item>
     <item quantity="other" msgid="5513481419205061254">"Barua za sauti <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Cheza"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Barua mpya ya sauti kutoka <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Haikuweza kucheza barua ya sauti."</string>
@@ -533,7 +528,7 @@
     <string name="nfc_vcard_file_name" msgid="2823095213265993609">"Anwani imepokewa kupitia NFC"</string>
     <string name="menu_show_voicemails_only" msgid="1898421289561435703">"Onyesha barua za sauti pekee"</string>
     <string name="menu_show_all_calls" msgid="7560347482073345885">"Onyesha simu zote"</string>
-    <string name="status_available" msgid="5586870015822828392">"Anapatikana"</string>
+    <string name="status_available" msgid="5586870015822828392">"Nipo"</string>
     <string name="status_away" msgid="1838861100379804730">"Mbali"</string>
     <string name="status_busy" msgid="9147992455450257136">"Ana shughuli"</string>
     <string name="description_call_log_play_button" msgid="651182125650429846">"Cheza barua ya sauti"</string>
@@ -563,7 +558,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Weka karibu"</string>
     <string name="add_account" msgid="8201790677994503186">"Ongeza akaunti"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Ongeza akaunti mpya"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Simu haijatumwa."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Nambari ya barua ya sauti haipatikani"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Simu haijatumwa"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Ili kusanidi ujumbe wa sauti, nenda kwa Menyu &gt; Mipangilio."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Kupigia simu ujumbe wa sauti, kwanza lemaza hali ya ndege."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Chaguo zaidi"</string>
 </resources>
diff --git a/res/values-sw580dp-w1000dp/dimens.xml b/res/values-sw580dp-w940dp/dimens.xml
similarity index 74%
rename from res/values-sw580dp-w1000dp/dimens.xml
rename to res/values-sw580dp-w940dp/dimens.xml
index 1cbc395..99f749c 100644
--- a/res/values-sw580dp-w1000dp/dimens.xml
+++ b/res/values-sw580dp-w940dp/dimens.xml
@@ -15,4 +15,8 @@
 -->
 <resources>
     <dimen name="group_editor_side_padding">64dip</dimen>
+    <dimen name="quick_contact_photo_container_height">180dip</dimen>
+    <dimen name="list_visible_scrollbar_padding">32dip</dimen>
+    <dimen name="detail_contact_photo_size">192dip</dimen>
+    <dimen name="detail_contact_photo_margin">16dip</dimen>
 </resources>
diff --git a/res/values-sw580dp-w940dp/donottranslate_config.xml b/res/values-sw580dp-w940dp/donottranslate_config.xml
new file mode 100644
index 0000000..5e5be30
--- /dev/null
+++ b/res/values-sw580dp-w940dp/donottranslate_config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+
+<resources>
+    <bool name="config_browse_list_show_images">true</bool>
+    <bool name="config_use_two_panes_in_favorites">true</bool>
+</resources>
diff --git a/res/values-sw580dp-w1000dp/integers.xml b/res/values-sw580dp-w940dp/integers.xml
similarity index 85%
rename from res/values-sw580dp-w1000dp/integers.xml
rename to res/values-sw580dp-w940dp/integers.xml
index c09a1f3..191eeb8 100644
--- a/res/values-sw580dp-w1000dp/integers.xml
+++ b/res/values-sw580dp-w940dp/integers.xml
@@ -14,5 +14,7 @@
      limitations under the License.
 -->
 <resources>
+    <integer name="contact_tile_column_count">3</integer>
+    <integer name="contact_tile_column_count_in_favorites">3</integer>
     <integer name="updates_tab_snippet_max_lines">7</integer>
 </resources>
diff --git a/res/values-sw580dp-w940dp/styles.xml b/res/values-sw580dp-w940dp/styles.xml
new file mode 100644
index 0000000..d035240
--- /dev/null
+++ b/res/values-sw580dp-w940dp/styles.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+<resources>
+    <style name="PeopleTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
+        <item name="android:actionBarWidgetTheme">@style/ContactsActionBarTheme</item>
+        <item name="android:actionBarItemBackground">@drawable/action_bar_item_background</item>
+        <item name="android:actionBarTabStyle">@style/ContactsActionBarTabView</item>
+        <item name="android:actionDropDownStyle">@style/ContactsActionBarDropDownStyle</item>
+        <item name="android:textColorPrimary">@color/primary_text_color</item>
+        <item name="android:textColorSecondary">@color/secondary_text_color</item>
+        <item name="android:listViewStyle">@style/ListViewStyle</item>
+        <item name="list_item_height">?android:attr/listPreferredItemHeight</item>
+        <item name="activated_background">@drawable/list_item_activated_background</item>
+        <item name="section_header_background">@drawable/list_title_holo</item>
+        <item name="list_item_divider">?android:attr/listDivider</item>
+        <item name="list_item_padding_top">0dip</item>
+        <item name="list_item_padding_right">24dip</item>
+        <item name="list_item_padding_bottom">0dip</item>
+        <item name="list_item_padding_left">0dip</item>
+        <item name="list_item_gap_between_image_and_text">8dip</item>
+        <item name="list_item_gap_between_label_and_data">5dip</item>
+        <item name="list_item_vertical_divider_margin">5dip</item>
+        <item name="list_item_presence_icon_margin">4dip</item>
+        <item name="list_item_presence_icon_size">16dip</item>
+        <item name="list_item_photo_size">64dip</item>
+        <item name="list_item_profile_photo_size">80dip</item>
+        <item name="list_item_prefix_highlight_color">@color/people_app_theme_color</item>
+        <item name="list_item_header_text_indent">8dip</item>
+        <item name="list_item_header_text_size">14sp</item>
+        <item name="list_item_header_text_color">@color/people_app_theme_color</item>
+        <item name="list_item_header_height">32dip</item>
+        <item name="list_item_header_underline_height">1dip</item>
+        <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
+        <item name="list_item_data_width_weight">5</item>
+        <item name="list_item_label_width_weight">3</item>
+        <item name="list_item_contacts_count_text_color">@color/contact_count_text_color</item>
+        <item name="list_item_contacts_count_text_size">12sp</item>
+        <item name="contact_browser_list_padding_left">0dip</item>
+        <item name="contact_browser_list_padding_right">0dip</item>
+        <item name="contact_browser_background">@android:color/transparent</item>
+        <item name="list_item_text_indent">@dimen/contact_browser_list_item_text_indent</item>
+        <!-- Favorites -->
+        <item name="favorites_padding_bottom">0dip</item>
+    </style>
+
+</resources>
diff --git a/res/values-sw580dp/dimens.xml b/res/values-sw580dp/dimens.xml
index 3d3cb17..0c73fa4 100644
--- a/res/values-sw580dp/dimens.xml
+++ b/res/values-sw580dp/dimens.xml
@@ -33,12 +33,13 @@
     <!-- Center vertically -->
     <dimen name="quick_contact_top_position">-1px</dimen>
     <!-- Contact list (vertical scroll bar comes left) -->
-    <dimen name="directory_header_height">24dip</dimen>
     <dimen name="contact_browser_list_top_margin">16dip</dimen>
     <dimen name="contact_browser_list_header_left_margin">@dimen/list_visible_scrollbar_padding</dimen>
     <dimen name="contact_browser_list_header_right_margin">24dip</dimen>
-    <dimen name="list_visible_scrollbar_padding">48dip</dimen>
-    <dimen name="account_filter_header_top_padding">@dimen/contact_browser_list_top_margin</dimen>
+    <dimen name="list_visible_scrollbar_padding">32dip</dimen>
+    <dimen name="list_header_extra_top_padding">@dimen/contact_browser_list_top_margin</dimen>
+
+    <dimen name="quick_contact_photo_container_height">360dip</dimen>
 
     <!-- Because the "join" screen has the vertical scroll bar on right,
       we cannot use @dimen/contact_browser_list_header_left_margin as is. -->
@@ -47,12 +48,6 @@
     <dimen name="join_header_top_margin">16dip</dimen>
     <dimen name="join_header_bottom_margin">16dip</dimen>
 
-    <!-- Margins and padding for text in widget -->
-    <dimen name="widget_snippet_top_margin">5dip</dimen>
-    <dimen name="widget_snippet_bottom_margin">6dip</dimen>
-    <dimen name="widget_snippet_top_padding">6dip</dimen>
-    <dimen name="widget_snippet_bottom_padding">3dip</dimen>
-
     <!-- Left padding for a group member list item -->
     <dimen name="group_member_item_left_padding">12dip</dimen>
     <!-- Left margin for the group member list to match the built in margin in the autocomplete asset -->
diff --git a/res/values-sw580dp/donottranslate_config.xml b/res/values-sw580dp/donottranslate_config.xml
index 57db36b..3d0dea0 100644
--- a/res/values-sw580dp/donottranslate_config.xml
+++ b/res/values-sw580dp/donottranslate_config.xml
@@ -19,8 +19,10 @@
 
 <resources>
     <bool name="config_use_two_panes">true</bool>
+    <bool name="config_use_two_panes_in_favorites">false</bool>
     <bool name="show_home_icon">true</bool>
     <bool name="config_show_group_action_in_action_bar">false</bool>
-    <item name="tab_width_screen_width_percentage" type="fraction">66%</item>
-    <item name="tab_height_screen_width_percentage" type="fraction">66%</item>
+    <bool name="config_browse_list_show_images">false</bool>
+    <item name="tab_width_screen_width_percentage" type="fraction">66.67%</item>
+    <item name="tab_height_screen_width_percentage" type="fraction">66.67%</item>
 </resources>
diff --git a/res/values-sw580dp/integers.xml b/res/values-sw580dp/integers.xml
index a62fa14..cdf6e4a 100644
--- a/res/values-sw580dp/integers.xml
+++ b/res/values-sw580dp/integers.xml
@@ -15,5 +15,6 @@
 -->
 <resources>
     <integer name="contact_tile_column_count">2</integer>
+    <integer name="contact_tile_column_count_in_favorites">3</integer>
     <integer name="updates_tab_snippet_max_lines">4</integer>
 </resources>
diff --git a/res/values-sw580dp/styles.xml b/res/values-sw580dp/styles.xml
index bf5b137..a8d935b 100644
--- a/res/values-sw580dp/styles.xml
+++ b/res/values-sw580dp/styles.xml
@@ -19,6 +19,7 @@
         <item name="android:actionBarWidgetTheme">@style/ContactsActionBarTheme</item>
         <item name="android:actionBarItemBackground">@drawable/action_bar_item_background</item>
         <item name="android:actionBarTabStyle">@style/ContactsActionBarTabView</item>
+        <item name="android:actionDropDownStyle">@style/ContactsActionBarDropDownStyle</item>
         <item name="android:textColorPrimary">@color/primary_text_color</item>
         <item name="android:textColorSecondary">@color/secondary_text_color</item>
         <item name="android:listViewStyle">@style/ListViewStyle</item>
@@ -27,21 +28,21 @@
         <item name="section_header_background">@drawable/list_title_holo</item>
         <item name="list_item_divider">?android:attr/listDivider</item>
         <item name="list_item_padding_top">0dip</item>
-        <item name="list_item_padding_right">24dip</item>
+        <item name="list_item_padding_right">12dip</item>
         <item name="list_item_padding_bottom">0dip</item>
         <item name="list_item_padding_left">0dip</item>
         <item name="list_item_gap_between_image_and_text">8dip</item>
         <item name="list_item_gap_between_label_and_data">5dip</item>
-        <item name="list_item_call_button_padding">14dip</item>
         <item name="list_item_vertical_divider_margin">5dip</item>
         <item name="list_item_presence_icon_margin">4dip</item>
+        <item name="list_item_presence_icon_size">16dip</item>
         <item name="list_item_photo_size">64dip</item>
         <item name="list_item_profile_photo_size">80dip</item>
-        <item name="list_item_prefix_highlight_color">#99cc00</item>
+        <item name="list_item_prefix_highlight_color">@color/people_app_theme_color</item>
         <item name="list_item_header_text_indent">8dip</item>
         <item name="list_item_header_text_size">14sp</item>
         <item name="list_item_header_text_color">@color/people_app_theme_color</item>
-        <item name="list_item_header_height">26dip</item>
+        <item name="list_item_header_height">32dip</item>
         <item name="list_item_header_underline_height">1dip</item>
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
         <item name="list_item_data_width_weight">5</item>
@@ -68,7 +69,6 @@
         <item name="list_item_padding_left">0dip</item>
         <item name="list_item_gap_between_image_and_text">8dip</item>
         <item name="list_item_gap_between_label_and_data">5dip</item>
-        <item name="list_item_call_button_padding">14dip</item>
         <item name="list_item_vertical_divider_margin">5dip</item>
         <item name="list_item_presence_icon_margin">18dip</item>
         <item name="list_item_photo_size">64dip</item>
@@ -95,6 +95,8 @@
     <style name="JoinContactActivityTheme" parent="ContactPickerTheme" >
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
+        <!-- In the contact picker screen we're using adjustResize but we don't want it here. -->
+        <item name="android:windowSoftInputMode">adjustUnspecified</item>
     </style>
 
     <style name="ContactListFilterTheme" parent="@android:Theme.Holo.Light.Dialog">
@@ -113,7 +115,7 @@
 
     <style name="DirectoryHeader" parent="PeopleTheme">
         <item name="android:paddingTop">0dip</item>
-        <item name="android:paddingBottom">0dip</item>
+
         <item name="android:background">@android:color/transparent</item>
     </style>
 
diff --git a/res/values-sw680dp-w1000dp/dimens.xml b/res/values-sw680dp-w1000dp/dimens.xml
index e492e5b..6a2d1cc 100644
--- a/res/values-sw680dp-w1000dp/dimens.xml
+++ b/res/values-sw680dp-w1000dp/dimens.xml
@@ -15,9 +15,9 @@
 -->
 <resources>
     <dimen name="group_detail_border_padding">32dip</dimen>
-    <dimen name="group_detail_side_margin">32dip</dimen>
     <dimen name="group_editor_side_padding">64dip</dimen>
-    <dimen name="detail_contact_photo_margin">16dip</dimen>
     <dimen name="contact_detail_list_top_padding">32dip</dimen>
     <dimen name="contact_tile_list_padding_top">32dip</dimen>
+    <dimen name="list_visible_scrollbar_padding">48dip</dimen>
+    <dimen name="detail_contact_photo_size">256dip</dimen>
 </resources>
diff --git a/res/values-sw680dp-w1000dp/integers.xml b/res/values-sw680dp-w1000dp/integers.xml
index 5fda2ed..bc9b2b7 100644
--- a/res/values-sw680dp-w1000dp/integers.xml
+++ b/res/values-sw680dp-w1000dp/integers.xml
@@ -15,4 +15,5 @@
 -->
 <resources>
     <integer name="contact_tile_column_count">4</integer>
-</resources>
\ No newline at end of file
+    <integer name="contact_tile_column_count_in_favorites">4</integer>
+</resources>
diff --git a/res/values-sw680dp/dimens.xml b/res/values-sw680dp/dimens.xml
index 0bed1ae..495526d 100644
--- a/res/values-sw680dp/dimens.xml
+++ b/res/values-sw680dp/dimens.xml
@@ -18,6 +18,7 @@
     <dimen name="editor_round_button_padding_left">8dip</dimen>
     <dimen name="editor_round_button_padding_right">8dip</dimen>
     <dimen name="group_editor_side_padding">16dip</dimen>
-    <dimen name="quick_contact_photo_container_height">400dip</dimen>
+    <dimen name="quick_contact_photo_container_height">360dip</dimen>
     <dimen name="contact_picker_contact_list_min_height">650dip</dimen>
+    <dimen name="list_visible_scrollbar_padding">48dip</dimen>
 </resources>
diff --git a/res/values-sw680dp/donottranslate_config.xml b/res/values-sw680dp/donottranslate_config.xml
new file mode 100644
index 0000000..5e5be30
--- /dev/null
+++ b/res/values-sw680dp/donottranslate_config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+
+<resources>
+    <bool name="config_browse_list_show_images">true</bool>
+    <bool name="config_use_two_panes_in_favorites">true</bool>
+</resources>
diff --git a/res/values-sw680dp/integers.xml b/res/values-sw680dp/integers.xml
index eaf5971..5b348a5 100644
--- a/res/values-sw680dp/integers.xml
+++ b/res/values-sw680dp/integers.xml
@@ -15,5 +15,6 @@
 -->
 <resources>
     <integer name="contact_tile_column_count">2</integer>
+    <integer name="contact_tile_column_count_in_favorites">2</integer>
     <integer name="updates_tab_snippet_max_lines">7</integer>
 </resources>
diff --git a/res/values-sw680dp/styles.xml b/res/values-sw680dp/styles.xml
index b7a7700..fb242d9 100644
--- a/res/values-sw680dp/styles.xml
+++ b/res/values-sw680dp/styles.xml
@@ -19,6 +19,7 @@
         <item name="android:actionBarWidgetTheme">@style/ContactsActionBarTheme</item>
         <item name="android:actionBarItemBackground">@drawable/action_bar_item_background</item>
         <item name="android:actionBarTabStyle">@style/ContactsActionBarTabView</item>
+        <item name="android:actionDropDownStyle">@style/ContactsActionBarDropDownStyle</item>
         <item name="android:textColorPrimary">@color/primary_text_color</item>
         <item name="android:textColorSecondary">@color/secondary_text_color</item>
         <item name="android:listViewStyle">@style/ListViewStyle</item>
@@ -32,15 +33,15 @@
         <item name="list_item_padding_left">0dip</item>
         <item name="list_item_gap_between_image_and_text">16dip</item>
         <item name="list_item_gap_between_label_and_data">5dip</item>
-        <item name="list_item_call_button_padding">14dip</item>
         <item name="list_item_vertical_divider_margin">5dip</item>
         <item name="list_item_presence_icon_margin">4dip</item>
+        <item name="list_item_presence_icon_size">16dip</item>
         <item name="list_item_photo_size">64dip</item>
         <item name="list_item_profile_photo_size">80dip</item>
-        <item name="list_item_prefix_highlight_color">#99cc00</item>
+        <item name="list_item_prefix_highlight_color">@color/people_app_theme_color</item>
         <item name="list_item_header_text_indent">8dip</item>
         <item name="list_item_header_text_color">@color/people_app_theme_color</item>
-        <item name="list_item_header_height">24dip</item>
+        <item name="list_item_header_height">32dip</item>
         <item name="list_item_header_text_size">14sp</item>
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
         <item name="list_item_header_underline_height">1dip</item>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index bc46708..6f43ac7 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"ค้นหา"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"สร้างรายชื่อใหม่"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"ดูสมุดโทรศัพท์"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"โทรหา <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"โทร <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"เพิ่มในรายการโปรด"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"ลบจากรายการโปรด"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"แก้ไข"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"ลบ"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"คัดลอก"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"วางบนหน้าจอหลัก"</string>
     <string name="menu_call" msgid="3992595586042260618">"โทรหารายชื่อในสมุดโทรศัพท์"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"ส่งข้อความถึงรายชื่อในสมุดโทรศัพท์"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"แยก"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"รายชื่อที่แนะนำ"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"รายชื่อในสมุดโทรศัพท์ทั้งหมด"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"รายชื่อที่รวมกัน"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"ลบรายชื่อหรือไม่"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"ตั้งเสียงเรียกเข้า"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"โอนทุกสายไปยังข้อความเสียง"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"คุณไม่สามารถลบรายชื่อติดต่อจากบัญชีแบบอ่านอย่างเดียวได้ แต่ซ่อนไว้ในรายการรายชื่อได้"</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"บริษัท"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"ชื่อ"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"ไม่มีรายชื่อติดต่อนี้"</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"เพิ่มวิดเจ็ตสมุดโทรศัพท์ในหน้าจอหลักแล้ว"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"สร้างรายชื่อในสมุดโทรศัพท์ใหม่"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"สร้างรายชื่อติดต่อใหม่"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"โทรศัพท์"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"พบ <xliff:g id="COUNT">%d</xliff:g> รายการ"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"พบมากกว่า <xliff:g id="COUNT">%d</xliff:g> รายการ"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"ไม่พบรายชื่อติดต่อ"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"ไม่มีรายชื่อติดต่อ"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"พบ 1 รายการ"</item>
     <item quantity="other" msgid="7988132539476575389">"พบ <xliff:g id="COUNT">%d</xliff:g> รายการ"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"ทั้งหมด"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"ที่อยู่ติดต่อทั้งหมด"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"กลุ่ม"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"รายการโปรด"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"โทรศัพท์"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"ล้างบันทึกการโทร"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"บันทึกการโทรทั้งหมดของคุณจะถูกลบออก"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"กำลังล้างบันทึกการโทร..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"ล้างผู้ที่คุณติดต่อด้วยบ่อยๆ หรือไม่"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"คุณจะล้างรายชื่อของผู้ที่ติดต่อด้วยบ่อยๆ ในแอป People and Phone และบังคับให้แอปอีเมลเรียนรู้การกำหนดที่อยู่ของคุณใหม่ตั้งแต่ต้น"</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"กำลังล้างผู้ที่คุณติดต่อด้วยบ่อยๆ…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"ข้อความเสียง"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> นาที <xliff:g id="SECONDS">%s</xliff:g> วินาที"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"ที่ติดต่อบ่อยครั้ง"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"มีการติดต่อบ่อย"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"เพิ่มรายชื่อในสมุดโทรศัพท์"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"เพิ่ม \"<xliff:g id="EMAIL">%s</xliff:g>\" ในสมุดโทรศัพท์หรือไม่"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"หนึ่ง"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"สอง"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"ดูรายชื่อติดต่อ"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"ไม่มีที่เก็บข้อมูล"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"ไม่มีการ์ด SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"ไม่พบที่จัดเก็บข้อมูล"</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"ไม่พบการ์ด SD"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"กำลังค้นหา vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"นำเข้าจากซิมการ์ด"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"นำเข้าจากที่เก็บข้อมูล"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"ส่งออกไปยังที่เก็บข้อมูล"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"นำเข้าไฟล์ vCard ทั้งหมด"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"กำลังค้นหาข้อมูล vCard ในที่จัดเก็บข้อมูล..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"กำลังค้นหาข้อมูล vCard บนการ์ด SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"ไม่สามารถสแกนที่เก็บข้อมูล"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"ไม่สามารถสแกนการ์ด SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"ไม่สามารถสแกนที่จัดเก็บข้อมูล (สาเหตุ: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"ไม่สามารถสแกนการ์ด SD (สาเหตุ: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"ข้อผิดพลาด I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"การส่งออก <xliff:g id="FILENAME">%s</xliff:g> จะเกิดขึ้นในไม่ช้า"</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"คำขอส่งออก vCard ถูกปฏิเสธ ลองใหม่ภายหลัง"</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"สมุดโทรศัพท์"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"ส่งออกรายชื่อติดต่อ"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"รายชื่อติดต่อของคุณจะถูกส่งออกเป็นไฟล์: <xliff:g id="VCARD_FILENAME">%s</xliff:g>"</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"ไม่สามารถส่งออก"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"โปรแกรมเขียนข้อความ vCard เริ่มการทำงานไม่ถูกต้อง"</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"ไม่สามารถเปิด \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"รายชื่อในสมุดโทรศัพท์ <xliff:g id="CURRENT_NUMBER">%s</xliff:g> จาก <xliff:g id="TOTAL_NUMBER">%s</xliff:g> รายการ"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"การยกเลิกการนำเข้า vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"ยกเลิกการนำเข้า <xliff:g id="FILENAME">%s</xliff:g> หรือไม่"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"การยกเลิกการส่งออก vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"ยกเลิกการส่งออก <xliff:g id="FILENAME">%s</xliff:g> หรือไม่"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"ไม่สามารถยกเลิกการนำเข้า/ส่งออก vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"ชื่อของรายชื่อในสมุดโทรศัพท์ของคุณ"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"เพิ่มช่วงคั่น 2 วินาที"</string>
     <string name="add_wait" msgid="3360818652790319634">"เพิ่มการรอ"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"โทรออกโดยใช้"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"เลือกหมายเลข"</string>
     <string name="call_settings" msgid="7666474782093693667">"การตั้งค่า"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"ส่งข้อความโดยใช้"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"เลือกหมายเลข"</string>
     <string name="make_primary" msgid="5829291915305113983">"จำตัวเลือกนี้"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
     <string name="missing_name" msgid="8745511583852904385">"(ไม่มีชื่อ)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"บัญชี"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"ล้างผู้ที่คุณติดต่อด้วยบ่อยๆ"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"รายชื่อติดต่อที่จะแสดง"</string>
     <string name="menu_import_export" msgid="26217871113229507">"นำเข้า/ส่งออก"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"นำเข้า/ส่งออกผู้ติดต่อ"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"นำเข้าสมุดโทรศัพท์"</string>
     <string name="menu_share" msgid="943789700636542260">"ใช้ร่วมกัน"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"รายชื่อทั้งหมด"</string>
     <string name="share_via" msgid="563121028023030093">"ใช้สมุดโทรศัพท์ร่วมกันทาง"</string>
     <string name="share_error" msgid="948429331673358107">"ไม่สามารถแบ่งปันรายชื่อติดต่อนี้ได้"</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"ชื่อ"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"ดูชื่อของรายชื่อเป็น"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"ขึ้นต้นด้วยชื่อ"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"ขึ้นต้นด้วยนามสกุล"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"ค้นหารายชื่อในสมุดโทรศัพท์"</string>
     <string name="take_photo" msgid="7496128293167402354">"ถ่ายภาพ"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"ถ่ายภาพใหม่"</string>
     <string name="pick_photo" msgid="3746334626214970837">"เลือกรูปภาพจากแกลเลอรี"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"รวมจากแหล่งที่มา <xliff:g id="COUNT">%0$d</xliff:g> แหล่ง"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"อื่นๆ"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"รวมรายชื่อติดต่อ"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"รวมรายชื่อติดต่อปัจจุบันกับรายชื่อติดต่อที่เลือกหรือไม่"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"แก้ไขรายชื่อติดต่อที่เลือก"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"เปลี่ยนไปแก้ไขรายชื่อติดต่อที่เลือกหรือไม่ ข้อมูลที่คุณป้อนไว้จนถึงขณะนี้จะถูกคัดลอก"</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"คัดลอกไปยังสมุดโทรศัพท์ของฉัน"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"เพิ่มในสมุดโทรศัพท์ของฉัน"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"การตั้งค่า"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"รายชื่อติดต่อที่จะแสดง"</string>
     <string name="menu_settings" msgid="377929915873428211">"การตั้งค่า"</string>
+    <string name="menu_help" msgid="5123887102216637725">"ความช่วยเหลือ"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"ตัวเลือกการแสดงผล"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"ค้นหารายชื่อติดต่อ"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"กำลังโหลด..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"สร้างที่อยู่ติดต่อใหม่"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"ลงชื่อเข้าใช้บัญชี"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"นำเข้าที่อยู่ติดต่อจากไฟล์"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"นำเข้าสมุดโทรศัพท์"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"สร้างกลุ่มใหม่"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[สร้างกลุ่มใหม่]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"ลบกลุ่ม"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"สร้างกลุ่มใหม่"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 กลุ่ม"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> กลุ่ม"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"ตั้งเป็นค่าเริ่มต้น"</string>
     <string name="clear_default" msgid="7193185801596678067">"ล้างจากค่าเริ่มต้น"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"คัดลอกข้อความแล้ว"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"ยกเลิกการเปลี่ยนแปลง"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"ยกเลิกการเปลี่ยนแปลงหรือไม่"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"ตั้งค่าโปรไฟล์ของฉัน"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"พิมพ์ชื่อของบุคคล"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"ดูการอัปเดต"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"ข้อความเสียง"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> ข้อความเสียง"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"เล่น"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"ข้อความเสียงใหม่จาก <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"ไม่สามารถเล่นข้อความเสียง"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"จัดเก็บในตัวเครื่อง"</string>
     <string name="add_account" msgid="8201790677994503186">"เพิ่มบัญชี"</string>
     <string name="add_new_account" msgid="5748627740680940264">"เพิ่มบัญชีใหม่"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"ไม่สามารถโทรออก"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"หมายเลขข้อความเสียงไม่พร้อมใช้งาน"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"ไม่สามารถโทรออก"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"หากต้องการตั้งค่าข้อความเสียง ให้ไปที่เมนู &gt; การตั้งค่า"</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"หากต้องการฟังข้อความเสียง ให้ปิดโหมดใช้งานบนเครื่องบินก่อน"</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"ตัวเลือกเพิ่มเติม"</string>
 </resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 9518b61..b8aed4a 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Paghahanap"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Bagong contact"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Tingnan ang contact"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Tawagan si <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Tumawag sa <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Idagdag sa mga paborito"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Alisin mula sa mga paborito"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"I-edit"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Tanggalin"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopyahin"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Ilagay sa Home screen"</string>
     <string name="menu_call" msgid="3992595586042260618">"Tawagan ang contact"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Mag-text sa contact"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Hiwalay"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Mga iminumungkahing contact"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Lahat ng mga contact"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Mga pinagsamang contact"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Tanggalin ang contact?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Itakda ang ringtone"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Lahat ng tawag sa voicemail"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Hindi ka makakapagtanggal ng mga contact mula sa mga read-only na account, ngunit maitatago mo ang mga ito sa iyong mga listahan ng mga contact."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Kumpanya"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Pamagat"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Hindi umiiral ang contact."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Idinagdag sa Home screen ang widget ng contact."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Lumikha ng bagong contact"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Lumikha ng bagong contact"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telepono"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> ang nakita"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Higit sa <xliff:g id="COUNT">%d</xliff:g> ang natagpuan."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Walang natagpuan."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Walang mga contact"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 ang nakita"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> ang nakita"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Lahat"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Lahat ng contact"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Mga Pangkat"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Mga Paborito"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telepono"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"I-clear ang log ng tawag?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tatanggalin ang lahat ng iyong record ng tawag."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Kini-clear ang log ng tawag…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"I-clear ang mga madalas tinatawagan?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Iki-clear mo ang listahan ng mga madalas na tinatawagan sa Mga Tao at Telepono na mga app, at pilitin ang mga email app na matutunan ang iyong mga kagustuhan sa pag-address mula sa umpisa."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Kini-clear ang mga madalas tinatawagan…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> (na) min <xliff:g id="SECONDS">%s</xliff:g> (na) seg"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Madalas na kino-contact"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Madalas na tinatawagan"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Magdagdag ng contact"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Idagdag ang \"<xliff:g id="EMAIL">%s</xliff:g>\" sa mga contact?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"isa"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"dalawa"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Tingnan ang contact"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Hindi available ang imbakan"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Walang SD card"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Walang natagpuang storage."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Walang natagpuang SD card."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Paghahanap ng vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"I-import mula sa SIM card"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"I-import mula sa imbakan"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"I-export sa imbakan"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"I-import ang lahat ng mga vCard file"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Naghahanap ng data ng vCard sa storage…"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Naghahanap ng data ng vCard data sa SD card…"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Hindi ma-scan ang storage"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Hindi ma-scan ang SD card"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Hindi ma-scan ang storage. (Dahilan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Hindi ma-scan ang SD card. (Dahilan: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O na error"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Mae-export ang <xliff:g id="FILENAME">%s</xliff:g> sa ilang saglit."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Tinanggihan ang kahilingan sa pag-export ng vCard. Subukang muli sa ibang pagkakataon."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"contact"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"I-export ang mga contact?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Ang listahan ng iyong contact ay ie-export sa file: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Hindi ma-export"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Hindi nagsimula nang tama ang composer ng vCard."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Hindi mabuksan ang \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> ng <xliff:g id="TOTAL_NUMBER">%s</xliff:g> (na) contact"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Pagkansela ng pag-import ng vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Kanselahin ang pag-import ng <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Pagkansela ng pag-export ng vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Kanselahin ang pag-export ng <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Di makansela pag-import/pag-export vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Mga pangalan ng iyong mga contact"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Magdagdag ng pag-pause na 2-seg"</string>
     <string name="add_wait" msgid="3360818652790319634">"Magdagdag ng paghihintay"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Pagtawag gamit ang"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Pumili ng numero"</string>
     <string name="call_settings" msgid="7666474782093693667">"Mga Setting"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Paggamit ng teksto"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Pumili ng numero"</string>
     <string name="make_primary" msgid="5829291915305113983">"Tandaan ang pagpipiliang ito"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Walang natagpuang app na mangangasiwa sa pagkilos na ito."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Walang pangalan)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Mga Account"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"I-clear ang mga madadalas"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Mga contact na ipapakita"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Mag-import/mag-export"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Mag-import/mag-export ng mga contact"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Mag-import ng mga contact"</string>
     <string name="menu_share" msgid="943789700636542260">"Ibahagi"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Lahat ng contact"</string>
     <string name="share_via" msgid="563121028023030093">"Ibahagi ang contact sa pamamagitan ng"</string>
     <string name="share_error" msgid="948429331673358107">"Hindi maibabahagi ang contact na ito."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Pangalan"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Tingnan ang mga pangalan ng contact bilang"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Pangalan muna"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Apelyido muna"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Maghanap ng mga contact"</string>
     <string name="take_photo" msgid="7496128293167402354">"Kumuha ng larawan"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Kumuha ng bagong larawan"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Pumili ng larawan mula sa Gallery"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"pinagsama mula sa <xliff:g id="COUNT">%0$d</xliff:g> (na) pinagmumulan"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Iba pa"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Sumali sa mga contact"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Isama ang kasalukuyang contact sa piniling contact?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"I-edit ang napiling mga contact"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Lumipat sa pag-edit ng napiling contact? Kokopyahin ang impormasyong ipinasok mo sa ngayon."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopyahin sa Aking Mga Contact"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Idagdag sa Aking Mga Contact"</string>
@@ -462,9 +457,10 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Mga Setting"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Mga contact na ipapakita"</string>
     <string name="menu_settings" msgid="377929915873428211">"Mga Setting"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Tulong"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Mga pagpipilian sa pagpapakita"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
-    <string name="hint_findContacts" msgid="1808681193458772072">"Maghanap ng mga contact"</string>
+    <string name="hint_findContacts" msgid="1808681193458772072">"Mghanap ng contact"</string>
     <string name="non_phone_caption" msgid="1541655052330027380">"Numero ng telepono"</string>
     <string name="non_phone_add_to_contacts" msgid="6590985286250471169">"Idagdag sa mga contact"</string>
     <string name="activity_title_confirm_add_detail" msgid="4065089866210730616">"Idagdag sa contact"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Naglo-load…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Lumikha ng bagong contact"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Mag-sign in sa isang account"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Pag-import ng mga contact mula sa isang file"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Mag-import ng mga contact"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Lumikha ng bagong pangkat"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Lumikha ng bagong pangkat]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Tanggalin ang pangkat"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Lumikha ng bagong pangkat"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 pangkat"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> (na) pangkat"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Itakda ang default"</string>
     <string name="clear_default" msgid="7193185801596678067">"I-clear ang default"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Kinopya ang teksto"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Itapon ang mga pagbabago"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Itapon ang iyong mga pagbabago?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"I-set up ang aking profile"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"I-type ang pangalan ng tao"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Tingnan ang mga update"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Voicemail"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> (na) Voicemail"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"I-play"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Bagong voicemail mula kay <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Hindi ma-play ang voicemail."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Panatilihing lokal"</string>
     <string name="add_account" msgid="8201790677994503186">"Magdagdag ng account"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Magdagdag ng bagong account"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Hindi naipadala ang tawag"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Hindi available ang numero ng voicemail"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Hindi naipadala ang tawag"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Upang mag-set up ng voicemail, pumunta sa Menu &gt; Mga Setting."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Upang tumawag sa voicemail, i-off muna ang Airplane mode."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Higit pang mga pagpipilian"</string>
 </resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 92285fd..ee4723c 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Ara"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Yeni kişi"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Kişiyi görüntüle"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Ara: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Çağrı yap: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Sık kullanılanlara ekle"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Sık kullanılanlardan kaldır"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Düzenle"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Sil"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopyala"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Ana ekrana yerleştir"</string>
     <string name="menu_call" msgid="3992595586042260618">"Çağrı yap"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Kısa mesaj gönder"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Ayır"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Önerilen kişiler"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Tüm kişiler"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Kişiler birleştirildi"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Kişi silinsin mi?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Zil sesi ayarla"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Sesli mesaja gelen tüm çağrlr"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Kişileri salt okunur hesaplardan silemezsiniz, ancak bu kişileri kişiler listenizde gizleyebilirsiniz."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Şirket"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Başlık"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Kişi mevcut değil."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Kişi widget\'ı Ana ekranınıza eklendi."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Yeni kişi oluştur"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Yeni kişi oluştur"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> kişi bulundu"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"<xliff:g id="COUNT">%d</xliff:g> kişiden fazla bulundu."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Hiç bulunamadı."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Hiç kişi yok"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"1 kişi bulundu"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> kişi bulundu"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tümü"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Tüm kişiler"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Gruplar"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Sık Kullanılanlar"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Çağrı günlüğünü sil?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tüm çağrı kayıtlarınız silinecek."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Çağrı günlüğü temizleniyor..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Sık iletişim kurulanlar silinsin mi?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Kişiler ve Telefon uygulamalarındaki sık iletişim kurulanlar listesini temizleyecek ve e-posta uygulamalarını adres tercihlerinizi en baştan öğrenmeye zorlayacaksınız."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Sık iletişim kurulanlar siliniyor…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Sesli Mesaj"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> dak <xliff:g id="SECONDS">%s</xliff:g> sn"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Sık iletişim kurulanlar"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Sık arananlar"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Kişi ekle"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"\"<xliff:g id="EMAIL">%s</xliff:g>\" adresi kişilere eklensin mi?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"bir"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"iki"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"eksi"</string>
     <string name="description_plus_button" msgid="515164827856229880">"artı"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Kişiyi görüntüle"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Depolama birimi yok"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"SD kart yok"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Depolama birimi bulunamadı."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"SD kart bulunamadı."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"vCard aranıyor"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"SIM karttan içe aktar"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Depl biriminden içe aktar"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Depolama birimine aktar"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Tüm vCard dosyalarını içe aktar"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Depolama birimindeki vCard verileri aranıyor..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"SD kartta vCard verileri aranıyor..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Depolama birimi taranamadı"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"SD kart taranamadı"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Depolama biriminiz taranamadı. (Nedeni: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"SD kart taranamadı. (Nedeni: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"G/Ç Hatası"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> kısa bir süre içinde dışa aktarılacak."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard\'ı dışa aktarma isteği reddedildi. Daha sonra tekrar deneyin."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"kişi"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTSIGN">%%</xliff:g><xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Kişileri dışa aktar?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Kişi listeniz şu dosyaya aktarılacak: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Dışa aktarılamadı"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard oluşturucu düzgün başlamadı."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" açılamadı: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"Toplam <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kişiden <xliff:g id="CURRENT_NUMBER">%s</xliff:g> kişi"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"vCard içe aktarmayı iptal etme"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"<xliff:g id="FILENAME">%s</xliff:g> dosyasının içe aktarılması iptal edilsin mi?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"vCard dışa aktarmayı iptal etme"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"<xliff:g id="FILENAME">%s</xliff:g> dosyasının dışa aktarılması iptal edilsin mi?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"İçe/dışa aktrma işlmi iptl edilemedi"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Kişilerinizin adları"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"2 saniyelik duraklama ekle"</string>
     <string name="add_wait" msgid="3360818652790319634">"Bekleme ekle"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Şunu kullanarak çağrı yap"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Sayı seçin"</string>
     <string name="call_settings" msgid="7666474782093693667">"Ayarlar"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Şunu kullanarak SMS gönder:"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Sayı seçin"</string>
     <string name="make_primary" msgid="5829291915305113983">"Bu tercihi anımsa"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Bu işlemi gerçekleştirecek uygulama bulunamadı."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Adsız)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Hesaplar"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Sık iletişim kurulanları sil"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Görüntülenecek kişiler"</string>
     <string name="menu_import_export" msgid="26217871113229507">"İçe/Dışa Aktar"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Kişileri içe/dışa aktar"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Kişileri içe aktar"</string>
     <string name="menu_share" msgid="943789700636542260">"Paylaş"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Tüm kişiler"</string>
     <string name="share_via" msgid="563121028023030093">"Şunu kullanarak kişi paylaş:"</string>
     <string name="share_error" msgid="948429331673358107">"Bu kişi paylaşılamıyor."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Ad"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Kişi adlarını görüntüleme şekli:"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Önce adı"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Önce soyadı"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Kişileri ara"</string>
     <string name="take_photo" msgid="7496128293167402354">"Fotoğraf çek"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Yeni fotoğraf çek"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Galeri\'den fotoğraf seçin"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"<xliff:g id="COUNT">%0$d</xliff:g> kaynaktan birleştirildi"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Diğer"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Kişileri birleştir"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Mevcut kişi, seçili kişiyle birleştirilsin mi?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Seçili kişileri düzenle"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Seçili kişiyi düzenlemeye geçilsin mi? Şimdiye kadar girdiğiniz bilgiler kopyalanacak."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kişilerime kopyala"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Kişilerime ekle"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Ayarlar"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Görüntülenecek kişiler"</string>
     <string name="menu_settings" msgid="377929915873428211">"Ayarlar"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Yardım"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Görüntüleme seçenekleri"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Kişileri bul"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Yükleniyor..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Yeni kişi oluştur"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Bir hesapta oturum açın"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Bir dosyadaki kişileri içe aktar"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Kişileri içe aktar"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Yeni grup oluştur"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Yeni grup oluştur]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Grubu sil"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Yeni grup oluştur"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 grup"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> grup"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Varsayılan olarak ayarla"</string>
     <string name="clear_default" msgid="7193185801596678067">"Varsayılanları temizle"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Metin kopyalandı"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Değişiklikleri sil"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Değişiklikleriniz silinsin mi?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Profilimi ayarla"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Kişinin adını yazın"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Gncellmlri görüntüle"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Sesli mesaj"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Sesli mesaj"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Oynat"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Yeni sesli mesj gönderen: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Sesli mesaj yürütülemedi."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Yerel olarak sakla"</string>
     <string name="add_account" msgid="8201790677994503186">"Hesap ekle"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Yeni hesap ekle"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Çağrı yapılamadı"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Sesli mesaj numarası kullanılamıyor"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Çağrı yapılamadı"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Sesli mesajı yapılandırmak için Menü &gt; Ayarlar\'a gidin."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Sesli mesaja çağrı yapmak için öncelikle Uçak modunu kapatın."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Diğer seçenekler"</string>
 </resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index dbc26fa..347f6d5 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Пошук"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Новий контакт"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Див. контакт"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Набрати <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Телефонувати <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Додати до вибраного"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Видалити з вибраного"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Редагувати"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Видалити"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Копіювати"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Місце на головному екрані"</string>
     <string name="menu_call" msgid="3992595586042260618">"Набрати конт."</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Повід. контакт"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Розділити"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Пропоновані контакти"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Усі контакти"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Контакти об\'єднано"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Видалити контакт?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Установ.мелодію"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Усі виклики на голосову пошту"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Неможливо видалити контакти з облікових записів \"лише для читання\", але можна сховати їх у списках контактів."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Компанія"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Назва"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Контакт не існує."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Віджет контакта додано на головний екран."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Створ. новий контакт"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Створити новий контакт"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Телеф."</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Знайдено <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Знайдено понад <xliff:g id="COUNT">%d</xliff:g>."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Не знайдено."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Контактів немає"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Знайдено 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Знайдено <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Усі"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Усі контакти"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Групи"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Вибране"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Тел."</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Очистити журнал викликів?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Усі записи викликів буде видалено."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Очищення журналу викликів..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Очистити список частих контактів?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Ви очистите список користувачів, з якими часто спілкувалися, у програмах \"Телефон\" і \"Люди\" та примусите програми електронної пошти заново запам’ятовувати нові адреси."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Очищення списку частих контактів…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Голос. пошта"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> хв. <xliff:g id="SECONDS">%s</xliff:g> сек."</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Часті контакти"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Часті виклики"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Додати контакт"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Дод.\" <xliff:g id="EMAIL">%s</xliff:g>\" до контактів?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"один"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"два"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"мінус"</string>
     <string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Переглянути контакт"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Пам’ять недоступна"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Нема карти SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Пам’ять не знайдено."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Карту SD не знайдено."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Пошук даних vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Імортув. з SIM-карти"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Імпорт із пам’яті"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Експорт у пам’ять"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Імпортув. всі файли vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Пошук даних vCard у пам’яті..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Пошук даних vCard на карті SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Не вдалося просканувати пам’ять"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Не вдалося просканувати карту SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Не вдалося сканувати пам’ять. (Причина: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Не вдалося сканувати карту SD. (Причина: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Помилка вводу/виводу"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Файл <xliff:g id="FILENAME">%s</xliff:g> незабаром буде експортовано."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Запит на експорт файлу vCard відхилено. Повторіть спробу пізніше."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"контакт"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Експортув. контакти?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Ваш список контактів буде експортовано у файл: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Помилка експорту"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Майстер vCard не запущено належним чином."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Не вдалося відкрити файл \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> із <xliff:g id="TOTAL_NUMBER">%s</xliff:g> контактів"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Скасування імпорту vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Скасувати імпорт файлу <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Скасування експорту vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Скасувати експорт файлу <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Не вдалося скасув. імпорт/експорт vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Імена ваших контактів"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Дод. 2-сек. паузу"</string>
     <string name="add_wait" msgid="3360818652790319634">"Дод. очікув."</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Набрати за доп."</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Вибрати номер"</string>
     <string name="call_settings" msgid="7666474782093693667">"Налаштування"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"SMS за доп."</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Вибрати номер"</string>
     <string name="make_primary" msgid="5829291915305113983">"Пам\'ятати цей вибір"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Не знайдено програму для обробки цієї дії."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Без імені)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Обл. записи"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Очистити часті контакти"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Контакти для показу"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Імпорт або експорт"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Імпорт/експорт контактів"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Імпорт контактів"</string>
     <string name="menu_share" msgid="943789700636542260">"Надісл."</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Усі контакти"</string>
     <string name="share_via" msgid="563121028023030093">"Надісл. контакт через"</string>
     <string name="share_error" msgid="948429331673358107">"Цей контакт неможливо надіслати."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Ім\'я"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Див. імена контактів як"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Спочатку ім\'я"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Спочатку прізвище"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Пошук контактів"</string>
     <string name="take_photo" msgid="7496128293167402354">"Зробити фото"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Зробити нове фото"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Вибрати фото з галереї"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"об\'єднано з джерел: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Інші"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Об\'єднати контакти"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Об\'єднати поточний контакт із вибраним контактом?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Редагувати вибрані контакти"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Перейти до редагування вибраного контакта? Введену досі інформацію буде скопійовано."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Копіювати в мої контакти"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Додати до групи \"Мої контакти\""</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Налаштування"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Контакти для показу"</string>
     <string name="menu_settings" msgid="377929915873428211">"Налаштування"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Довідка"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Параметри відображення"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Пошук контактів"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Завантаження..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Створити новий контакт"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Увійти в обліковий запис"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Імпортувати контакти з файлу"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Імпортувати контакти"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Створити нову групу"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Створити нову групу]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Видалити групу"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Створити нову групу"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 група"</item>
     <item quantity="other" msgid="1276758425904917367">"Груп: <xliff:g id="COUNT">%0$d</xliff:g>"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Установити за умовчанням"</string>
     <string name="clear_default" msgid="7193185801596678067">"Очистити налаштування за умовчанням"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Текст скопійовано"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Відхилити зміни"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Відхилити зміни?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Налаштувати профіль"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Введіть ім’я особи"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Переглян. оновлення"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Голосова пошта"</item>
     <item quantity="other" msgid="5513481419205061254">"Повідомлень голос. пошти: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Відтворити"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Нова голосова пошта від <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Не вдалося відтворити голосову пошту."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Зберегти локально"</string>
     <string name="add_account" msgid="8201790677994503186">"Додати обліковий запис"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Додати новий обліковий запис"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Виклик не здійснено"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Номер голосової пошти не доступний"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Виклик не здійснено"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Щоб налаштувати голосову пошту, перейдіть у Меню &gt; Налаштування."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Щоб перевірити голосову пошту, спочатку вимкніть режим польоту."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Інші варіанти"</string>
 </resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 74da6cd..cc509e3 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Tìm kiếm"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Liên hệ mới"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Xem liên hệ"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Gọi <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Gọi <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Thêm vào mục ưa thích"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Xóa khỏi mục ưa thích"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Chỉnh sửa"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Xóa"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Sao chép"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Đặt trên màn hình chính"</string>
     <string name="menu_call" msgid="3992595586042260618">"Gọi liên hệ"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Nhắn tin tới liên hệ"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Tách"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Liên hệ được đề xuất"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Tất cả liên hệ"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Danh bạ đã được kết hợp"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Xóa địa chỉ liên hệ?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Đặt nhạc chuông"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Các cuộc gọi tới thư thoại"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Bạn không thể xóa địa chỉ liên hệ từ tài khoản chỉ đọc, nhưng bạn có thể ẩn chúng trong danh sách địa chỉ liên hệ của mình."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Công ty"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Tiêu đề"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Địa chỉ liên hệ không tồn tại."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Đã thêm tiện ích liên hệ vào Màn hình chính."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Tạo liên hệ mới"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Tạo địa chỉ liên hệ mới"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Điện thoại"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"Đã tìm thấy <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"Đã tìm thấy hơn <xliff:g id="COUNT">%d</xliff:g> địa chỉ liên hệ."</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Không tìm thấy đ.chỉ l.hệ nào."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Không có địa chỉ liên hệ nào"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"Đã tìm thấy 1"</item>
     <item quantity="other" msgid="7988132539476575389">"Đã tìm thấy <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Tất cả"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Tất cả liên hệ"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Nhóm"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Mục ưa thích"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Điện thoại"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Xóa nhật ký c.gọi?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tất cả bản ghi cuộc gọi của bạn sẽ bị xóa."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Đang xóa nhật ký cuộc gọi…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Xóa danh sách liên hệ thường xuyên?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Bạn sẽ xóa danh sách liên hệ thường xuyên trong ứng dụng Liên hệ và điện thoại cũng như buộc các ứng dụng email phải tìm hiểu các tùy chọn gửi của bạn lại từ đầu."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Đang xóa DS liên hệ thường xuyên…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Thư thoại"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> phút <xliff:g id="SECONDS">%s</xliff:g> giây"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Thường xuyên được liên hệ"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Thường xuyên được gọi"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Thêm liên hệ"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Thêm \"<xliff:g id="EMAIL">%s</xliff:g>\" vào danh bạ?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"một"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"hai"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"trừ"</string>
     <string name="description_plus_button" msgid="515164827856229880">"cộng"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Xem địa chỉ liên hệ"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Bộ nhớ không khả dụng"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Không có thẻ SD nào"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Không tìm thấy bộ nhớ nào."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Không tìm thấy thẻ SD nào."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Đang tìm kiếm vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Nhập từ thẻ SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Nhập từ bộ nhớ"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Xuất sang bộ nhớ"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Nhập tất cả tệp vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Đang tìm kiếm dữ liệu vCard trong bộ nhớ..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Đang tìm dữ liệu vCard trên thẻ SD..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Không thể quét bộ nhớ"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Không thể quét thẻ SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Không thể quét bộ nhớ. (Lý do: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Không thể quét thẻ SD. (Lý do: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Lỗi I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> sẽ sớm được xuất."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Yêu cầu xuất vCard bị từ chối. Hãy thử lại sau."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"địa chỉ liên hệ"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Xuất danh bạ?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Danh sách địa chỉ liên hệ của bạn sẽ được xuất sang tệp: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Không thể xuất"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Trình soạn vCard không khởi động đúng."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Không thể mở \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> trong tổng số <xliff:g id="TOTAL_NUMBER">%s</xliff:g> liên hệ"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Hủy nhập vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Hủy yêu cầu nhập <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Hủy xuất vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Hủy yêu cầu xuất <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Không thể nhập/xuất vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Tên danh bạ của bạn"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Thêm 2 giây dừng"</string>
     <string name="add_wait" msgid="3360818652790319634">"Thêm chờ"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Sử dụng cuộc gọi"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Chọn số"</string>
     <string name="call_settings" msgid="7666474782093693667">"Cài đặt"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Nhắn tin sử dụng"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Chọn số"</string>
     <string name="make_primary" msgid="5829291915305113983">"Nhớ lựa chọn này"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Không tìm thấy ứng dụng nào để xử lý tác vụ này."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Không có tên)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Tài khoản"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Xóa DS liên hệ thường xuyên"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Danh sách liên hệ để hiển thị"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Nhập/xuất"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Nhập/xuất danh bạ"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Nhập danh bạ"</string>
     <string name="menu_share" msgid="943789700636542260">"Chia sẻ"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Tất cả liên hệ"</string>
     <string name="share_via" msgid="563121028023030093">"Chia sẻ liên hệ qua"</string>
     <string name="share_error" msgid="948429331673358107">"Không thể chia sẻ địa chỉ liên hệ này."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Tên"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Xem tên liên hệ dưới dạng"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Tên trước tiên"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Họ trước tiên"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Tìm kiếm trong danh bạ"</string>
     <string name="take_photo" msgid="7496128293167402354">"Chụp ảnh"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Chụp ảnh mới"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Chọn ảnh từ Thư viện"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"được hợp nhất từ <xliff:g id="COUNT">%0$d</xliff:g> nguồn"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Khác"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Kết hợp danh bạ"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Kết hợp địa chỉ liên hệ hiện tại với địa chỉ liên hệ đã chọn?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Chỉnh sửa địa chỉ liên hệ đã chọn"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Chuyển sang chỉnh sửa liên hệ đã chọn? Thông tin bạn đã nhập đến giờ sẽ được sao chép."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Sao chép vào Danh bạ của tôi"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Thêm vào Danh bạ của tôi"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Cài đặt"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"DS liên hệ để hiển thị"</string>
     <string name="menu_settings" msgid="377929915873428211">"Cài đặt"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Trợ giúp"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Tùy chọn hiển thị"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Tìm địa chỉ liên hệ"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Đang tải…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Tạo địa chỉ liên hệ mới"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Đăng nhập vào tài khoản"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Nhập danh bạ từ một tệp"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Nhập danh bạ"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Tạo nhóm mới"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Tạo nhóm mới]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Xóa nhóm"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Tạo nhóm mới"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 nhóm"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> nhóm"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Đặt mặc định"</string>
     <string name="clear_default" msgid="7193185801596678067">"Xóa mặc định"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Đã sao chép văn bản"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Hủy thay đổi"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Hủy các thay đổi của bạn?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Thiết lập tiểu sử của tôi"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Nhập tên của người này"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Xem thông tin c.nhật"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Thư thoại"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Thư thoại"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Phát"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Thư thoại mới từ <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Không thể phát thư thoại."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Lưu trữ cục bộ"</string>
     <string name="add_account" msgid="8201790677994503186">"Thêm tài khoản"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Thêm tài khoản mới"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Không thể thực hiện cuộc gọi"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Số thư thoại không khả dụng"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Không thể thực hiện cuộc gọi"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Để thiết lập thư thoại, đi tới Trình đơn &gt; Cài đặt."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Để gọi thư thoại, trước tiên hãy tắt chế độ trên Máy bay."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Tùy chọn khác"</string>
 </resources>
diff --git a/res/values-w470dp/integers.xml b/res/values-w470dp/integers.xml
index d247e46..bc9b2b7 100644
--- a/res/values-w470dp/integers.xml
+++ b/res/values-w470dp/integers.xml
@@ -15,4 +15,5 @@
 -->
 <resources>
     <integer name="contact_tile_column_count">4</integer>
+    <integer name="contact_tile_column_count_in_favorites">4</integer>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 381ffb0..e8798e4 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -18,9 +18,9 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="launcherDialer" msgid="8636288196618486553">"拨号"</string>
     <string name="people" msgid="1048457247435785074">"联系人"</string>
-    <string name="contactsList" msgid="8661624236494819731">"通讯录"</string>
+    <string name="contactsList" msgid="8661624236494819731">"联系人"</string>
     <string name="shortcutContact" msgid="749243779392912958">"联系人"</string>
-    <string name="shortcutDialContact" msgid="746622101599186779">"直接拨打"</string>
+    <string name="shortcutDialContact" msgid="746622101599186779">"直接拨打电话"</string>
     <string name="shortcutMessageContact" msgid="2460337253595976198">"直接发送短信"</string>
     <string name="shortcutActivityTitle" msgid="6642877210643565436">"选择联系人快捷方式"</string>
     <string name="callShortcutActivityTitle" msgid="6065749861423648991">"选择一个可直接拨号的号码"</string>
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"搜索"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"新建联系人"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"查看联系人"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"呼叫<xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"拨打 <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"添加到收藏"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"从收藏中删除"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"修改"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"删除"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"复制"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"放在主屏幕上"</string>
     <string name="menu_call" msgid="3992595586042260618">"呼叫联系人"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"向联系人发送短信"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"拆分"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"建议的联系人"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"所有联系人"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"已合并联系人"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"要删除联系人吗?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"设置铃声"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"所有来电转至语音信箱"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"您无法删除只读帐户中的联系人,但可以在联系人列表中将他们隐藏。"</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"公司"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"职位"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"该联系人不存在。"</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"“联系人”窗口小部件已添加到主屏幕。"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"新建联系人"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"创建新联系人"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"电话"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"找到 <xliff:g id="COUNT">%d</xliff:g> 个联系人"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"找到的联系人超过 <xliff:g id="COUNT">%d</xliff:g> 位。"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"未找到任何联系人。"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"没有联系人"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"找到 1 个联系人"</item>
     <item quantity="other" msgid="7988132539476575389">"找到 <xliff:g id="COUNT">%d</xliff:g> 个联系人"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"全部"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"所有联系人"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"群组"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"收藏"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"拨号"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"要清除通话记录吗?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"系统将删除您的所有通话记录。"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"正在清除通话记录..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"是否清除常用联系人?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"此操作会清除“联系人”和“拨号”应用中的常用联系人列表,并强制电子邮件应用重新获取您最常使用的联系地址。"</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"正在清除常用联系人…"</string>
     <string name="imei" msgid="3045126336951684285">"移动通信国际识别码"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"语音信箱"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> 分 <xliff:g id="SECONDS">%s</xliff:g> 秒"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"经常联系的人"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"经常呼叫的联系人"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"添加联系人"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"将“<xliff:g id="EMAIL">%s</xliff:g>”添加到联系人?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"一"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"二"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"删除"</string>
     <string name="description_plus_button" msgid="515164827856229880">"添加"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"查看联系人"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"存储设备不存在"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"无 SD 卡"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"未找到任何存储设备。"</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"未找到 SD 卡。"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"正在搜索 vCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"从 SIM 卡导入"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"从存储设备导入"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"导出到存储设备"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"导入所有 vCard 文件"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"正在从存储设备中搜索 vCard 文件..."</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"正在 SD 卡中搜索 vCard 数据..."</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"无法扫描存储设备"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"无法扫描 SD 卡"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"无法扫描该存储设备。(原因:“<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"无法扫描该 SD 卡。(原因:“<xliff:g id="FAIL_REASON">%s</xliff:g>”)"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O 错误"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> 将在稍后导出。"</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard 导出请求遭拒,请稍后重试。"</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"联系人"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"要导出联系人吗?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"系统会将您的联系人列表导出到以下文件:<xliff:g id="VCARD_FILENAME">%s</xliff:g>。"</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"无法导出"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard 制作程序未正确启动。"</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"无法打开“<xliff:g id="FILE_NAME">%s</xliff:g>”:<xliff:g id="EXACT_REASON">%s</xliff:g>。"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"第 <xliff:g id="CURRENT_NUMBER">%s</xliff:g> 个联系人(共 <xliff:g id="TOTAL_NUMBER">%s</xliff:g> 个)"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"取消导入 vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"要取消导入 <xliff:g id="FILENAME">%s</xliff:g> 吗​​?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"取消导出 vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"要取消导出 <xliff:g id="FILENAME">%s</xliff:g> 吗​​?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"无法取消导入/导出 vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"联系人姓名"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"暂停时间延长 2 秒"</string>
     <string name="add_wait" msgid="3360818652790319634">"延长等待时间"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"呼叫方式"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"选择号码"</string>
     <string name="call_settings" msgid="7666474782093693667">"设置"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"短信发送方式"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"选择号码"</string>
     <string name="make_primary" msgid="5829291915305113983">"记住此选择"</string>
-    <string name="quickcontact_missing_app" msgid="358168575340921552">"未找到可处理此操作的应用程序。"</string>
+    <string name="quickcontact_missing_app" msgid="358168575340921552">"未找到可处理此操作的应用。"</string>
     <string name="missing_name" msgid="8745511583852904385">"(无姓名)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"帐户"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"清除常用联系人"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"要显示的联系人"</string>
     <string name="menu_import_export" msgid="26217871113229507">"导入/导出"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"导入/导出联系人"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"导入联系人"</string>
     <string name="menu_share" msgid="943789700636542260">"分享"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"所有联系人"</string>
     <string name="share_via" msgid="563121028023030093">"联系人分享方式"</string>
     <string name="share_error" msgid="948429331673358107">"无法分享此联系人。"</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"姓名"</string>
@@ -402,7 +400,7 @@
     <!-- no translation found for from_account_format (4469138575127580203) -->
     <skip />
     <string name="use_photo_as_primary" msgid="8807110122951157246">"使用此照片"</string>
-    <string name="contact_read_only" msgid="7421346527289472273">"无法通过此应用程序修改。"</string>
+    <string name="contact_read_only" msgid="7421346527289472273">"无法通过此应用修改。"</string>
     <string name="no_contact_details" msgid="6636856378019344497">"没有此联系人的其他信息。"</string>
     <string name="group_read_only" msgid="1061762906115697637">"无法在此设备上修改。"</string>
     <string name="display_options_sort_list_by" msgid="6080091755852211076">"列表排序依据"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"联系人姓名的显示方式"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"名字在前"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"姓氏在前"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"搜索联系人"</string>
     <string name="take_photo" msgid="7496128293167402354">"拍照"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"拍摄新照片"</string>
     <string name="pick_photo" msgid="3746334626214970837">"从图库中选择照片"</string>
@@ -419,7 +416,7 @@
     <string name="locale_change_in_progress" msgid="7583992153091537467">"正在更新联系人列表,以反映语言的变更。"</string>
     <string name="upgrade_in_progress" msgid="474511436863451061">"正在更新联系人列表。"</string>
     <string name="upgrade_out_of_memory" msgid="1209994418877625940">"正在升级“联系人”。"\n\n"升级过程大约需要 <xliff:g id="SIZE_IN_MEGABYTES">%s</xliff:g> MB 的内存空间。"\n\n"请选择以下某个选项:"</string>
-    <string name="upgrade_out_of_memory_uninstall" msgid="1721798828992091432">"卸载一些应用程序"</string>
+    <string name="upgrade_out_of_memory_uninstall" msgid="1721798828992091432">"卸载一些应用"</string>
     <string name="upgrade_out_of_memory_retry" msgid="8431289830472724609">"重新尝试升级"</string>
     <string name="search_results_searching" msgid="3984833028938569930">"正在搜索..."</string>
     <string name="menu_display_selected" msgid="6470001164297969034">"已选收件人"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"合并自 <xliff:g id="COUNT">%0$d</xliff:g> 个来源"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"其他"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"合并联系人"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"要合并当前联系人与所选联系人吗?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"编辑所选联系人"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"要切换至编辑所选联系人吗?系统会复制您到目前为止输入的所有信息。"</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"复制到“我的联系人”"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"添加到“我的联系人”"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"设置"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"要显示的联系人"</string>
     <string name="menu_settings" msgid="377929915873428211">"设置"</string>
+    <string name="menu_help" msgid="5123887102216637725">"帮助"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"显示选项"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>,<xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"查找联系人"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"正在加载..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"创建新联系人"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"登录帐户"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"从文件导入联系人"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"导入联系人"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"创建新群组"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[创建新群组]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"删除群组"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"创建新群组"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 个群组"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> 个群组"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"设置默认值"</string>
     <string name="clear_default" msgid="7193185801596678067">"清除默认值"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"文本已复制"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"舍弃更改"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"要舍弃您所做的更改吗?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"设置我的个人资料"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"键入联系人的姓名"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"查看更新"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"语音邮件"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> 封语音邮件"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"播放"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>,<xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"来自<xliff:g id="CALLER">%1$s</xliff:g>的新语音邮件"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"无法播放语音邮件。"</string>
@@ -552,7 +547,7 @@
     <string name="local_profile_title" msgid="2021416826991393684">"我的本地个人资料"</string>
     <string name="external_profile_title" msgid="8034998767621359438">"我的<xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g>个人资料"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"显示所有联系人"</string>
-    <string name="no_account_prompt" msgid="7061052512446855192">"拥有 Google 帐户可增强“分享对象”的功能。"\n\n"• 通过任意网络浏览器访问“分享对象”"\n"• 安全地备份您的联系人。"</string>
+    <string name="no_account_prompt" msgid="7061052512446855192">"联系人应用与 Google 帐户结合使用效果更佳。"\n\n"• 通过任意网络浏览器查看您的联系人信息。"\n"• 安全地备份您的联系人信息。"</string>
     <string name="generic_no_account_prompt" msgid="7218827704367325460">"即使手机丢了,也能确保您的联系人信息的安全性:与在线服务同步。"</string>
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"添加帐户"</string>
     <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"系统不会备份您的新联系人。要添加用于在线备份联系人的帐户吗?"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"本地保存"</string>
     <string name="add_account" msgid="8201790677994503186">"添加帐户"</string>
     <string name="add_new_account" msgid="5748627740680940264">"添加新帐户"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"呼叫未发出"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"语音信箱号码不可用"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"电话未拨出"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"要设置语音信箱,请转到“菜单”&gt;“设置”。"</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"要呼叫语音信箱,请先关闭飞行模式。"</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"更多选项"</string>
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 072daec..d24a7ec 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"搜尋"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"新增聯絡人"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"檢視聯絡人"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"撥打電話給 <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"撥打 <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"新增至我的最愛"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"從我的最愛中移除"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"編輯"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"刪除"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"複製"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"新增到主螢幕上"</string>
     <string name="menu_call" msgid="3992595586042260618">"去電聯絡人"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"傳送簡訊至聯絡人"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"分割"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"建議聯絡人"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"所有聯絡人"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"已合併聯絡人"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"確定要刪除聯絡人?"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"設定電話鈴聲"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"將所有來電轉到語音信箱"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"您無法刪除唯讀帳戶的聯絡人,但可在聯絡人清單中隱藏這些聯絡人。"</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"公司"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"職稱"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"聯絡人不存在。"</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"聯絡人小工具已新增到主螢幕上。"</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"建立新聯絡人"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"建立新聯絡人"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"電話"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"找到 <xliff:g id="COUNT">%d</xliff:g> 位聯絡人"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"找到 <xliff:g id="COUNT">%d</xliff:g> 位以上的聯絡人。"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"完全找不到。"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"沒有聯絡人"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"找到 1 位聯絡人"</item>
     <item quantity="other" msgid="7988132539476575389">"找到 <xliff:g id="COUNT">%d</xliff:g> 位聯絡人"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"全部"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"所有聯絡人"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"群組"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"我的最愛"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"電話"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"確定要清除通話記錄?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"即將刪除您所有的通話記錄。"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"正在清除通話記錄…"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"清除常用聯絡人?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"您將清除「使用者」應用程式和「電話」應用程式中的常用聯絡人清單,並強制電子郵件應用程式重新瞭解您的寄件偏好設定。"</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"正在清除常用聯絡人…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"語音留言"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> 分 <xliff:g id="SECONDS">%s</xliff:g> 秒"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"常用聯絡人"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"常用聯絡人"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"新增聯絡人"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"要將「<xliff:g id="EMAIL">%s</xliff:g>」加到通訊錄嗎?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"1"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"2"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"負號"</string>
     <string name="description_plus_button" msgid="515164827856229880">"加號"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"查看聯絡人"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"儲存裝置無法使用"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"無 SD 卡"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"找不到任何儲存裝置。"</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"找不到 SD 卡。"</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"正在搜尋 VCard"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"從 SIM 卡匯入"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"從儲存裝置匯入"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"匯出到儲存裝置"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"匯入所有 vCard 檔案"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"正在搜尋儲存裝置中的 vCard 資料…"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"正在 SD 卡上搜尋 vCard 資料…"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"無法掃描儲存裝置"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"無法掃描 SD 卡"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"無法掃描儲存裝置 (原因:<xliff:g id="FAIL_REASON">%s</xliff:g>)。"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"無法掃描 SD 卡 (原因:<xliff:g id="FAIL_REASON">%s</xliff:g>)。"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O 錯誤"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> 將在稍後匯出。"</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"vCard 匯出要求遭到拒絕,請稍後再試。"</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"聯絡人"</string>
-    <string name="percentage" msgid="34897865327092209">"%s%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"確定要匯出聯絡人?"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"您的聯絡人清單即將匯出至以下檔案:<xliff:g id="VCARD_FILENAME">%s</xliff:g>。"</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"無法匯出"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"vCard 編輯器並未正確啟動。"</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"無法開啟「<xliff:g id="FILE_NAME">%s</xliff:g>」:<xliff:g id="EXACT_REASON">%s</xliff:g>。"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"第 <xliff:g id="CURRENT_NUMBER">%s</xliff:g> 位聯絡人,共 <xliff:g id="TOTAL_NUMBER">%s</xliff:g> 位"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"取消匯入 vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"確定要取消匯入 <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"取消匯出 vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"確定要取消匯出 <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"無法取消匯入/匯出 vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"您的聯絡人姓名"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"新增 2 秒暫停功能"</string>
     <string name="add_wait" msgid="3360818652790319634">"新增插播功能"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"去電使用"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"選擇號碼"</string>
     <string name="call_settings" msgid="7666474782093693667">"設定"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"簡訊使用:"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"選擇號碼"</string>
     <string name="make_primary" msgid="5829291915305113983">"記住這個選擇"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"找不到可以處理這個動作的應用程式。"</string>
     <string name="missing_name" msgid="8745511583852904385">"(無姓名)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"帳戶"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"清除常用聯絡人"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"要顯示的聯絡人"</string>
     <string name="menu_import_export" msgid="26217871113229507">"匯入/匯出"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"匯入/匯出聯絡人"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"匯入聯絡人"</string>
     <string name="menu_share" msgid="943789700636542260">"分享"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"所有聯絡人"</string>
     <string name="share_via" msgid="563121028023030093">"使用下列應用程式分享聯絡人資訊:"</string>
     <string name="share_error" msgid="948429331673358107">"無法分享這位聯絡人。"</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"姓名"</string>
@@ -394,8 +392,8 @@
     <string name="name_phonetic_middle" msgid="8643721493320405200">"中間名 (拼音)"</string>
     <string name="name_phonetic_family" msgid="462095502140180305">"姓氏 (拼音)"</string>
     <string name="name_phonetic" msgid="4259595234312430484">"姓名拼音"</string>
-    <string name="connections" msgid="8098440723172028350">"人脈"</string>
-    <string name="add_connection_button" msgid="4861308615789601727">"加入人脈"</string>
+    <string name="connections" msgid="8098440723172028350">"聯絡方式"</string>
+    <string name="add_connection_button" msgid="4861308615789601727">"加入聯絡方式"</string>
     <string name="recent" msgid="2659189233141493004">"最新"</string>
     <string name="recent_updates" msgid="4267258535615860710">"最新動態"</string>
     <string name="account_type_format" msgid="718948015590343010">"<xliff:g id="SOURCE">%1$s</xliff:g> 聯絡人"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"聯絡人姓名顯示方式"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"名字在前"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"姓氏在前"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"搜尋聯絡人"</string>
     <string name="take_photo" msgid="7496128293167402354">"拍照"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"拍攝新相片"</string>
     <string name="pick_photo" msgid="3746334626214970837">"從圖片庫選擇相片"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"從 <xliff:g id="COUNT">%0$d</xliff:g> 個來源合併"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"其他"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"合併聯絡人"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"要將目前聯絡人與所選聯絡人合併嗎?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"編輯所選聯絡人"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"要切換至編輯所選聯絡人嗎?系統會為您複製目前已輸入的資訊。"</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"複製到我的通訊錄"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"新增至我的聯絡人"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"設定"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"要顯示的聯絡人"</string>
     <string name="menu_settings" msgid="377929915873428211">"設定"</string>
+    <string name="menu_help" msgid="5123887102216637725">"說明"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"顯示選項"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_1">%1$s</xliff:g> <xliff:g id="COMPANY_0">%2$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"尋找聯絡人"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"載入中…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"建立新聯絡人"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"登入帳戶"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"從檔案匯入聯絡人"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"匯入聯絡人"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"建立新群組"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[建立新群組]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"刪除群組"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"建立新群組"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 個群組"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> 個群組"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"設為預設值"</string>
     <string name="clear_default" msgid="7193185801596678067">"清除預設值"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"文字已複製"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"捨棄變更"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"確定要捨棄變更?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"設定我的個人資料"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"輸入聯絡人的名稱"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"查看更新"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"語音留言"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> 則語音留言"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"播放"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>、<xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"最新語音留言者:<xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"無法播放語音留言。"</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"儲存在本機中"</string>
     <string name="add_account" msgid="8201790677994503186">"新增帳戶"</string>
     <string name="add_new_account" msgid="5748627740680940264">"新增帳戶"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"未送出通話要求"</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"語音信箱號碼無法使用"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"無法撥號"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"如要設定語音信箱,請前往 [選單] &gt; [設定]。"</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"如要聽語音留言,請先關閉飛行模式。"</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"更多選項"</string>
 </resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 441e192..7caab69 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -41,11 +41,13 @@
     <string name="menu_search" msgid="9147752853603483719">"Sesha"</string>
     <string name="menu_newContact" msgid="1209922412763274638">"Othintana naye omusha"</string>
     <string name="menu_viewContact" msgid="2795575601596468581">"Buka othintana naye"</string>
-    <string name="menu_callNumber" msgid="5142851348489387516">"Shayela <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="menu_callNumber" msgid="997146291983360266">"Shayela u-<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="menu_addStar" msgid="2908478235715404876">"Engeza ezintandokazini"</string>
     <string name="menu_removeStar" msgid="5844227078364227030">"Susa ezintandokazini"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Hlela"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Susa"</string>
+    <string name="menu_copy" msgid="6108677035381940698">"Kopisha"</string>
+    <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"Indawo esikrinini sekhaya"</string>
     <string name="menu_call" msgid="3992595586042260618">"Shayela othintana naye"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Bhalela othintana naye"</string>
     <string name="menu_splitAggregate" msgid="8368636463748691868">"Hlukanisa"</string>
@@ -62,7 +64,6 @@
     <string name="separatorJoinAggregateSuggestions" msgid="2831414448851313345">"Othintana nabo abasikiselwayo"</string>
     <string name="separatorJoinAggregateAll" msgid="7939932265026181043">"Bonke othintana nabo"</string>
     <string name="contactsJoinedMessage" msgid="7208148163607047389">"Othintana nabo abahlanganisiwe"</string>
-    <string name="deleteConfirmation_title" msgid="1418215926447642260">"Susa othintana naye"</string>
     <string name="menu_set_ring_tone" msgid="8728345772068064946">"Hlela iringithoni"</string>
     <string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"Wonke amakholi aya kwimeyili yezwi"</string>
     <string name="readOnlyContactWarning" msgid="7808825687289848259">"Awukwazi ukususa othintana nabo ema-akhawuntini okufunda kuphela, kodwa ungabafihla ohlwini lwakho loxhumana nabo."</string>
@@ -77,6 +78,7 @@
     <string name="ghostData_company" msgid="5414421120553765775">"Inkampani"</string>
     <string name="ghostData_title" msgid="7496735200318496110">"Isihloko"</string>
     <string name="invalidContactMessage" msgid="8215051456181842274">"Oxhumana naye akekho."</string>
+    <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"isinqunjwana soxhumana nabo singeziwe esikrinini sekhaya."</string>
     <string name="pickerNewContactHeader" msgid="7750705279843568147">"Dala othintana naye omusha"</string>
     <string name="pickerNewContactText" msgid="6166997164401048211">"Dala othintana naye omusha"</string>
     <string name="phoneLabelsGroup" msgid="6468091477851199285">"Ifoni"</string>
@@ -127,12 +129,12 @@
     <item quantity="other" msgid="3852668542926965042">"<xliff:g id="COUNT">%d</xliff:g> tholakele"</item>
   </plurals>
     <string name="foundTooManyContacts" msgid="5163335650920020220">"kutholakele <xliff:g id="COUNT">%d</xliff:g>edlula"</string>
-    <string name="listFoundAllContactsZero" msgid="7132202364587656501">"Akukho okutholiwe"</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Abekho oxhumana nabo"</string>
   <plurals name="searchFoundContacts">
     <item quantity="one" msgid="4826918429708286628">"otholakele ongu-1"</item>
     <item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> tholakele"</item>
   </plurals>
-    <string name="contactsAllLabel" msgid="6178225597569649305">"Konke"</string>
+    <string name="contactsAllLabel" msgid="6479708629170672169">"Bonke oxhumana nabo"</string>
     <string name="contactsGroupsLabel" msgid="2841971472518003524">"Amaqembu"</string>
     <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Izintandokazi"</string>
     <string name="dialerIconLabel" msgid="6500826552823403796">"Ifoni"</string>
@@ -149,6 +151,9 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Sula ifayela lokungena"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Yonke imininingwane eqoshiwe iyosuswa."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Isula imininingwane yokushaya..."</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Sula oxhumana nabo njalo?"</string>
+    <string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Uzosula uhlu okuxhunyanwa nalo njalo kwizinhlelo zokusebenza zaBantu kanye Nefoni, futhi iphoqelela izinhlelo zokusebenza ze-imeyli ukufunda okukhethayo kokuthintana kusuka ekuqaleni."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Isula oxhumana nabo njalo…"</string>
     <string name="imei" msgid="3045126336951684285">"IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"I-MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Ivoyisimeyili"</string>
@@ -186,7 +191,6 @@
     <string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> amaminithi <xliff:g id="SECONDS">%s</xliff:g> amasekhondi"</string>
     <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Abathintwa njalo"</string>
     <string name="favoritesFrequentCalled" msgid="6128306889600696124">"Abashayelwa njalo"</string>
-    <string name="add_contact_dlg_title" msgid="2896685845822146494">"Faka othintana naye"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Faka  \"<xliff:g id="EMAIL">%s</xliff:g>\"  kothintana nabo?"</string>
     <string name="description_image_button_one" msgid="1740638037139856139">"kunye"</string>
     <string name="description_image_button_two" msgid="5882638439003731308">"okubili"</string>
@@ -209,11 +213,8 @@
     <string name="description_minus_button" msgid="387136707700230172">"susa"</string>
     <string name="description_plus_button" msgid="515164827856229880">"kuhlanganise"</string>
     <string name="description_view_contact_detail" msgid="9133251213656414807">"Buka othintana naye"</string>
-    <string name="no_sdcard_title" product="nosdcard" msgid="8543619259870877473">"Isitoreji asitholakali"</string>
-    <string name="no_sdcard_title" product="default" msgid="5911758680339949273">"Alikho ikhadi le-SD"</string>
     <string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Ayikho indawo yokulondoloza etholakele."</string>
     <string name="no_sdcard_message" product="default" msgid="3357810406684913482">"Alikho ikhadi le-SD elitholakele."</string>
-    <string name="searching_vcard_title" msgid="4970508055399376813">"Iseshela i-vCArd"</string>
     <string name="import_from_sim" msgid="3859272228033941659">"Ngenisa kusuka kwikhadi le-SIM"</string>
     <string name="import_from_sdcard" product="default" msgid="8668347930577565175">"Ngenisa kusuka esigcineni"</string>
     <string name="export_to_sdcard" product="default" msgid="6092815580965201089">"Thekelisa kusigcini"</string>
@@ -223,8 +224,6 @@
     <string name="import_all_vcard_string" msgid="5518136113853448474">"Ngenisa wonke amafayela e-vCard"</string>
     <string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"Isesha idatha ye-vCard kusigcini"</string>
     <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"Iseshela idatha ye-vCard ekhadini le-SD"</string>
-    <string name="scanning_sdcard_failed_title" product="nosdcard" msgid="4944932641334764942">"Yehlulekile ukufinyelela kwindawo yokugcina i-USB"</string>
-    <string name="scanning_sdcard_failed_title" product="default" msgid="6664940444476572612">"Yehlulekile ukuskena ikhadi le-SD"</string>
     <string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"Isilondolozi asiskeneknga. (Isizathu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"Ikhadi le-SD aliskenekanga. (Isizathu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
     <string name="fail_reason_io_error" msgid="6748358842976073255">"Iphutha le-I/O"</string>
@@ -252,7 +251,7 @@
     <string name="vcard_export_will_start_message" msgid="2210241345252081463">"i-<xliff:g id="FILENAME">%s</xliff:g> izothekeliswa maduze nje."</string>
     <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Isicelo sokuthekelisa i-vCard sinqatshelwe. Sicela uzame futhi emva kwesikhathi."</string>
     <string name="vcard_unknown_filename" msgid="7171709890959915954">"othintana nabo"</string>
-    <string name="percentage" msgid="34897865327092209">"%S%%"</string>
+    <string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
     <string name="confirm_export_title" msgid="6834385377255286349">"Thekelisa othintana nabo"</string>
     <string name="confirm_export_message" msgid="2423421354816428708">"Uhlu loxhumana nabo luyothunyelw efayelini: <xliff:g id="VCARD_FILENAME">%s</xliff:g>."</string>
     <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Yehlulekile ukuthumela"</string>
@@ -273,26 +272,25 @@
     <string name="composer_not_initialized" msgid="2321648986367005254">"Umqambi we-Vcard akazange aqale ngendlela efanele."</string>
     <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Ayikwazi ukuvula \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> kothintana nabo abangu-<xliff:g id="TOTAL_NUMBER">%s</xliff:g>"</string>
-    <string name="cancel_import_confirmation_title" msgid="5578683596010294836">"Ikhansela ukungenisa i-vCard"</string>
     <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Misa ukulndwa kwe <xliff:g id="FILENAME">%s</xliff:g>?"</string>
-    <string name="cancel_export_confirmation_title" msgid="6516467140276768528">"Ikhansela ukuthekelisa i-vCard"</string>
     <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Misa ukulandwa kwe <xliff:g id="FILENAME">%s</xliff:g>?"</string>
     <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Yehlulekile ukukhansela ukungenisa/thekelisa i-vCard"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Amagama othintana nabo"</string>
     <string name="add_2sec_pause" msgid="9214012315201040129">"Faka ukumisa okwesikhashana kwamasekhondi angu-2"</string>
     <string name="add_wait" msgid="3360818652790319634">"Yengeza ukulinda"</string>
-    <string name="call_disambig_title" msgid="1911302597959335178">"Shayela usebenzisa"</string>
+    <string name="call_disambig_title" msgid="4392886850104795739">"Khetha inombolo"</string>
     <string name="call_settings" msgid="7666474782093693667">"Izilungiselelo"</string>
-    <string name="sms_disambig_title" msgid="4675399294513152364">"Bhalela usebenzisa"</string>
+    <string name="sms_disambig_title" msgid="5846266399240630846">"Khetha inombolo"</string>
     <string name="make_primary" msgid="5829291915305113983">"Khumbula lokhu okukhethiwe"</string>
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Ayikho insiza etholakele ukubhekana nalengxenye."</string>
     <string name="missing_name" msgid="8745511583852904385">"(alikho igama)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Ama-akhawunti"</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Sula oxhumana nabo njalo"</string>
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Othintana nabo abazoboniswa"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Ngenisa/Thekelisa"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Ngenisa/Thekelisa othintana nabo"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Ngenisa othintana nabo"</string>
     <string name="menu_share" msgid="943789700636542260">"Yabelana"</string>
-    <string name="menu_all_contacts" msgid="5101735431586050711">"Bonke oxhumana nabo"</string>
     <string name="share_via" msgid="563121028023030093">"Abelana nothintana naye nge"</string>
     <string name="share_error" msgid="948429331673358107">"Lona oxhumana naye ngeke ukwazi ukwabelana ngaye."</string>
     <string name="nameLabelsGroup" msgid="2034640839640477827">"Igama"</string>
@@ -411,7 +409,6 @@
     <string name="display_options_view_names_as" msgid="18022868169627979">"Buka amagama othintana nabo njenge"</string>
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"Igama elinikeziwe kuqala"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"Igama lomkhaya kuqala"</string>
-    <string name="search_bar_hint" msgid="1012756309632856553">"Sesha othintana nabo"</string>
     <string name="take_photo" msgid="7496128293167402354">"Thatha isithombe"</string>
     <string name="take_new_photo" msgid="7341354729436576304">"Thatha isithombe esisha"</string>
     <string name="pick_photo" msgid="3746334626214970837">"Khetha isithombe kwiGalari"</string>
@@ -441,9 +438,7 @@
     <item quantity="other" msgid="425683718017380845">"ihlanganiswe kusuka emithombeni engu-<xliff:g id="COUNT">%0$d</xliff:g>"</item>
   </plurals>
     <string name="local_invisible_directory" msgid="6046691709127661065">"Okunye"</string>
-    <string name="aggregation_suggestion_join_dialog_title" msgid="5276699501316246253">"Joyina othintana nabo"</string>
     <string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"Joyina othintana naye wamanje nothintana naye okhethiwe?"</string>
-    <string name="aggregation_suggestion_edit_dialog_title" msgid="1064042382692091314">"Hlela ama-akhawunti akhethiwe"</string>
     <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"Shintshela ekuhleleni othintana naye okhethiwe? Ulwazi olufakile kuze kube manje luzokopishwa."</string>
     <string name="menu_copyContact" msgid="1573960845106822639">"Kopisha kwengithintana nabo"</string>
     <string name="add_to_my_contacts" msgid="1068274916793627723">"Faka Kothintana Nabo"</string>
@@ -462,6 +457,7 @@
     <string name="activity_title_settings" msgid="5464130076132770781">"Izilungiselelo"</string>
     <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Othintana nabo abazoboniswa"</string>
     <string name="menu_settings" msgid="377929915873428211">"Izilungiselelo"</string>
+    <string name="menu_help" msgid="5123887102216637725">"Usizo"</string>
     <string name="preference_displayOptions" msgid="1341720270148252393">"Izinketho zokubonisa"</string>
     <string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>, <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
     <string name="hint_findContacts" msgid="1808681193458772072">"Thola othintana nabo"</string>
@@ -475,10 +471,9 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Iyalayisha…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Dala othintana naye omusha"</string>
     <string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Ngena ngemvume kwi-akhawunti"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4456440183590517471">"Ngenisa othintana nabo kwifayela"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Ngenisa othintana nabo"</string>
     <string name="create_group_dialog_title" msgid="6874527142828424475">"Dala iqembu elisha"</string>
-    <string name="create_group_item_label" msgid="5218022006186243310">"[Yenza iqembu elisha]"</string>
-    <string name="delete_group_dialog_title" msgid="7368429698398624427">"Susa iqembu"</string>
+    <string name="create_group_item_label" msgid="4411981763169654825">"Dala iqembu elisha"</string>
   <plurals name="num_groups_in_account">
     <item quantity="one" msgid="2944819210288517794">"1 isigcawu"</item>
     <item quantity="other" msgid="1276758425904917367">"<xliff:g id="COUNT">%0$d</xliff:g> Amaqembu"</item>
@@ -497,9 +492,8 @@
     <string name="set_default" msgid="4417505153468300351">"Hlela okuzenzakalelayo"</string>
     <string name="clear_default" msgid="7193185801596678067">"Sula okuzenzakalelayo"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Umbhalo okopishiwe"</string>
-    <string name="cancel_confirmation_dialog_title" msgid="3950463632415908534">"Lahla izinguquko"</string>
     <string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"Lahla izinguquko ozenzile?"</string>
-    <string name="call_type_and_date" msgid="1766269584078149149">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
+    <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="profile_display_name" msgid="4127389543625918771">"Misa iphrofayli yami"</string>
     <string name="enter_contact_name" msgid="1738391320566349924">"Thayipha igama lomuntu"</string>
     <string name="view_updates_from_group" msgid="1782685984905600034">"Buka Okwenziwe Kabusha"</string>
@@ -507,6 +501,7 @@
     <item quantity="one" msgid="1746619685488504230">"Ivoyisimeyili"</item>
     <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> ama-meyli ezwi"</item>
   </plurals>
+    <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Dlala"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"I-imeyli entsha esuka ku <xliff:g id="CALLER">%1$s</xliff:g>"</string>
     <string name="voicemail_playback_error" msgid="1811242131549854624">"Yehlulekile ukudlala i-voicemail."</string>
@@ -561,7 +556,8 @@
     <string name="keep_local" msgid="1258761699192993322">"Gcina kuseduze"</string>
     <string name="add_account" msgid="8201790677994503186">"Engeza i-akhawunti"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Yengeza i-akhawunti enthsha"</string>
-    <string name="dialog_phone_call_prohibited_title" msgid="2111395432187079579">"Ucingo aluthunyelwanga."</string>
-    <string name="dialog_voicemail_not_ready_title" msgid="7258109862329777060">"Inombolo yomlayezo wephimbo ayikho"</string>
+    <string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"ucingo aluthunyelwanga"</string>
     <string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Ukuya emyalezweni wephimbo, yana ezisethweni &gt; zemenyu."</string>
+    <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Ukushayela i-voicemail, vala kuqala imodi Yendiza."</string>
+    <string name="action_menu_overflow_description" msgid="2303272250613084574">"Izinketho eziningi"</string>
 </resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index b9a534c..f49b0bf 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -56,16 +56,6 @@
         <attr name="ratio" format="float"/>
     </declare-styleable>
 
-    <declare-styleable name="TransitionAnimationView">
-        <attr name="clipMarginLeft" format="dimension"/>
-        <attr name="clipMarginRight" format="dimension"/>
-        <attr name="clipMarginTop" format="dimension"/>
-        <attr name="clipMarginBottom" format="dimension"/>
-        <attr name="enterAnimation" format="reference"/>
-        <attr name="exitAnimation" format="reference"/>
-        <attr name="animationDuration" format="integer"/>
-    </declare-styleable>
-
     <declare-styleable name="ContactBrowser">
         <attr name="contact_browser_list_padding_left" format="dimension"/>
         <attr name="contact_browser_list_padding_right" format="dimension"/>
@@ -84,7 +74,6 @@
         <attr name="list_item_padding_left" format="dimension"/>
         <attr name="list_item_gap_between_image_and_text" format="dimension"/>
         <attr name="list_item_gap_between_label_and_data" format="dimension"/>
-        <attr name="list_item_call_button_padding" format="dimension"/>
         <attr name="list_item_vertical_divider_margin" format="dimension"/>
         <attr name="list_item_presence_icon_margin" format="dimension"/>
         <attr name="list_item_presence_icon_size" format="dimension"/>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index bc70cbf..cb2b1ca 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -49,9 +49,6 @@
     <!-- Colour of voicemail progress bar to the left of position indicator. -->
     <color name="voicemail_playback_seek_bar_already_played">#ccffffff</color>
 
-    <!-- Colour of text that appears on the voicemail ui. -->
-    <color name="voicemail_playback_ui_text">#cc696969</color>
-
     <!-- Color of the theme of the People app -->
     <color name="people_app_theme_color">#33B5E5</color>
 
@@ -78,4 +75,8 @@
 
     <!-- Color of image view placeholder. -->
     <color name="image_placeholder">#DDDDDD</color>
+
+    <!-- Standard color for selected items. -->
+    <color name="item_selected">#660099cc</color>
+
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e856d67..5037279 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -16,8 +16,6 @@
 <resources>
     <dimen name="account_selector_popup_width">400dip</dimen>
 
-    <dimen name="photo_action_popup_width">400dip</dimen>
-
     <!-- Top position of quick contact. If this is -1, the vertical position is determined
     based on the source of the request -->
     <dimen name="quick_contact_top_position">48dip</dimen>
@@ -46,6 +44,9 @@
     <!-- Minimum height of a row in the Editor -->
     <dimen name="editor_min_line_item_height">48dip</dimen>
 
+    <!-- Height of the shadow asset under the photo on the contact detail page -->
+    <dimen name="detail_contact_photo_shadow_height">10dip</dimen>
+
     <!-- Height of the tab text label in the tab carousel on the contact detail page -->
     <dimen name="detail_tab_carousel_tab_label_height">45dip</dimen>
 
@@ -77,7 +78,17 @@
     <dimen name="detail_contact_photo_margin">8dip</dimen>
 
     <!-- Width and height of the contact photo on the contact detail page -->
-    <dimen name="detail_contact_photo_size">256dip</dimen>
+    <dimen name="detail_contact_photo_size">128dip</dimen>
+
+    <!-- Width and height of the expanded contact photo on the contact detail page -->
+    <dimen name="detail_contact_photo_expanded_size">400dip</dimen>
+
+    <!-- This is the minimum amount of space to leave underneath an expanded contact detail
+         photo -->
+    <dimen name="expanded_photo_height_offset">100dip</dimen>
+
+    <!-- Minimum width for the photo action popup options -->
+    <dimen name="photo_action_popup_min_width">300dip</dimen>
 
     <!-- Left and right padding for a contact detail item -->
     <dimen name="detail_item_icon_margin">8dip</dimen>
@@ -146,11 +157,8 @@
     <!-- Border padding for the group detail fragment -->
     <dimen name="group_detail_border_padding">0dip</dimen>
 
-    <!-- Left and right margin for the divider in the group detail fragment -->
-    <dimen name="group_detail_side_margin">0dip</dimen>
-
     <!-- Height of the quick contact photo container (for screens that are too large to use the screen width/height as a constraint)-->
-    <dimen name="quick_contact_photo_container_height">200dip</dimen>
+    <dimen name="quick_contact_photo_container_height">180dip</dimen>
 
     <!-- Height of edit text in dialpad fragment -->
     <dimen name="dialpad_horizontal_margin">0dip</dimen>
@@ -158,9 +166,7 @@
     <dimen name="dialpad_digits_text_size">35sp</dimen>
 
     <!-- Just used in landscape mode -->
-    <dimen name="dialpad_button_height">0px</dimen>
     <dimen name="dialpad_digits_height">0px</dimen>
-    <dimen name="dialpad_digits_margin_top">0px</dimen>
     <dimen name="dialpad_digits_margin_bottom">0px</dimen>
 
     <!-- Width of search view in action bar.  Use 0dip for MATCH_PARENT -->
@@ -178,7 +184,9 @@
     <dimen name="join_header_top_margin">16dip</dimen>
     <dimen name="join_header_bottom_margin">0dip</dimen>
 
-    <dimen name="account_filter_header_top_padding">0dip</dimen>
+    <!-- Padding between the action bar's bottom edge and the first header
+         in contacts/group lists. -->
+    <dimen name="list_header_extra_top_padding">0dip</dimen>
 
     <!-- ContactTile Layouts -->
     <!--
@@ -193,7 +201,6 @@
     <!-- Call Log -->
     <dimen name="call_log_call_action_size">32dip</dimen>
     <dimen name="call_log_call_action_width">48dip</dimen>
-    <dimen name="call_log_call_action_height">64dip</dimen>
     <dimen name="call_log_icon_margin">4dip</dimen>
     <dimen name="call_log_inner_margin">8dip</dimen>
     <dimen name="call_log_outer_margin">16dip</dimen>
@@ -214,9 +221,6 @@
     <dimen name="contact_filter_icon_size">32dip</dimen>
     <dimen name="contact_filter_header_min_height">24dip</dimen>
 
-    <!-- Height for directory headers in contact lists -->
-    <dimen name="directory_header_height">24dip</dimen>
-
     <!--  Vertical and horizontal padding in between contact tiles -->
     <dimen name="contact_tile_divider_padding">1dip</dimen>
 
@@ -242,4 +246,7 @@
     <!-- Min height of the list of contacts when the contact picker is a dialog (on
         wide screen devices). -->
     <dimen name="contact_picker_contact_list_min_height">550dip</dimen>
+
+    <!-- Min with of fake menu buttons, which should be same as ActionBar's one -->
+    <dimen name="fake_menu_button_min_width">56dip</dimen>
 </resources>
diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml
index b36dbe1..dd94097 100644
--- a/res/values/donottranslate_config.xml
+++ b/res/values/donottranslate_config.xml
@@ -44,6 +44,9 @@
          resource. -->
     <bool name="config_enable_dialer_key_vibration">true</bool>
 
+    <!-- Flag indicating whether to show images in browse list -->
+    <bool name="config_browse_list_show_images">true</bool>
+
     <!-- The type of vcard for improt. If the vcard importer cannot guess the exact type
     of a vCard type, the improter uses this type. -->
     <string name="config_import_vcard_type" translatable="false">default</string>
@@ -104,6 +107,12 @@
          shown in their own screens. This flag must be in sync with the layout definitions. -->
     <bool name="config_use_two_panes">false</bool>
 
+    <!--  If true, Contacts uses two panes in the favorites view, one for starred and one for
+          frequently contacted.  If false, only one list is shown with starred on top and frequently
+          contacted listed below. Note: This should not be true if config_use_two_panes is
+          false. -->
+    <bool name="config_use_two_panes_in_favorites">false</bool>
+
     <!-- If true, the "home" icon on the action bar will be shown. -->
     <bool name="show_home_icon">false</bool>
 
@@ -130,4 +139,17 @@
          Setting this flag to false in a resource overlay allows you to
          entirely disable SIM import on a per-product basis. -->
     <bool name="config_allow_sim_import">true</bool>
+
+
+    <!-- Help URL pointing to main TOC for People. This is intentionally empty because
+         the overlay will fill this in during build time. -->
+    <string name="help_url_people_main"></string>
+
+    <!-- Help URL pointing to adding contacts in People. This is intentionally empty because
+         the overlay will fill this in during build time. -->
+    <string name="help_url_people_add"></string>
+
+    <!-- Help URL pointing to editing contacts in People. This is intentionally empty because
+         the overlay will fill this in during build time. -->
+    <string name="help_url_people_edit"></string>
 </resources>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index e742ba0..6d5f7c9 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -18,6 +18,9 @@
     <!-- Determines the number of columns in a ContactTileRow -->
     <integer name="contact_tile_column_count">2</integer>
 
+    <!--  Determines the number of columns in a ContactTileRow in the favorites tab -->
+    <integer name="contact_tile_column_count_in_favorites">2</integer>
+
     <!-- Max lines to display of a contact's snippet in the "updates" tab of the contact card tab carousel  -->
     <integer name="updates_tab_snippet_max_lines">3</integer>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7bb875c..8292a56 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -100,8 +100,8 @@
     <!-- Menu item used to view the details for a specific contact -->
     <string name="menu_viewContact">View contact</string>
 
-    <!-- Menu item used to call a contact, containing the name of the contact to call -->
-    <string name="menu_callNumber">Call <xliff:g id="name">%s</xliff:g></string>
+    <!-- Menu item used to call a contact, containing the number of the contact to call -->
+    <string name="menu_callNumber">Call <xliff:g id="number">%s</xliff:g></string>
 
     <!-- Menu item used to add a star to a contact, which makes that contact show up at the top of favorites -->
     <string name="menu_addStar">Add to favorites</string>
@@ -115,6 +115,12 @@
     <!-- Menu item used to delete a specific contact -->
     <string name="menu_deleteContact">Delete</string>
 
+    <!-- Menu item to copy something [CHAR_LIMIT=10] -->
+    <string name="menu_copy">Copy</string>
+
+    <!-- Menu item used to create a contact shortcut when viewing contact details. [CHAR LIMIT=30] -->
+    <string name="menu_create_contact_shortcut">Place on Home screen</string>
+
     <!-- Menu item used to call a specific contact when viewing the details of that contact. -->
     <string name="menu_call">Call contact</string>
 
@@ -163,9 +169,6 @@
     <!-- Toast shown after two contacts have been joined by a user action -->
     <string name="contactsJoinedMessage">Contacts joined</string>
 
-    <!-- Confirmation dialog title after users selects to delete a contact. [CHAR LIMIT=25]-->
-    <string name="deleteConfirmation_title">Delete contact?</string>
-
     <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=15] -->
     <string name="menu_set_ring_tone">Set ringtone</string>
 
@@ -209,6 +212,9 @@
          for some reason doesn't exist anymore. [CHAR LIMIT=NONE]-->
     <string name="invalidContactMessage">The contact doesn\'t exist.</string>
 
+    <!-- Message displayed in a toast after you create a contact shortcut in the launcher [CHAR LIMIT=NONE]-->
+    <string name="createContactShortcutSuccessful">Contact widget added to Home screen.</string>
+
     <!-- When picking a contact from a list of all contacts there is an entry at the top of the
          list that allows the user to create a new contact, which this string is used for -->
     <string name="pickerNewContactHeader">Create new contact</string>
@@ -343,7 +349,7 @@
     <string name="foundTooManyContacts">More than <xliff:g id="count">%d</xliff:g> found.</string>
 
     <!-- Displayed at the top of the contacts showing the zero total number of contacts found when "Only contacts with phones" not selected. [CHAR LIMIT=30] -->
-    <string name="listFoundAllContactsZero">None found.</string>
+    <string name="listFoundAllContactsZero">No contacts</string>
 
     <!-- Displayed at the top of the contacts showing the total number of contacts found when typing search query -->
     <plurals name="searchFoundContacts">
@@ -357,7 +363,7 @@
          This is especially valuable for views without textual representation like ImageView.
 
          [CHAR LIMIT=NONE] -->
-    <string name="contactsAllLabel">All</string>
+    <string name="contactsAllLabel">All contacts</string>
 
     <!-- The content description text for the groups tab.
 
@@ -427,6 +433,15 @@
     <!-- Title of the "Clearing call log" progress-dialog [CHAR LIMIT=35] -->
     <string name="clearCallLogProgress_title">Clearing call log\u2026</string>
 
+    <!-- Title of the confirmation dialog for clearing frequents. [CHAR LIMIT=37] -->
+    <string name="clearFrequentsConfirmation_title">Clear frequently contacted?</string>
+
+    <!-- Confirmation dialog for clearing frequents. [CHAR LIMIT=NONE] -->
+    <string name="clearFrequentsConfirmation">You\'ll clear the frequently contacted list in the People and Phone apps, and force email apps to learn your addressing preferences from scratch.</string>
+
+    <!-- Title of the "Clearing frequently contacted" progress-dialog [CHAR LIMIT=35] -->
+    <string name="clearFrequentsProgress_title">Clearing frequently contacted\u2026</string>
+
     <!-- The title of a dialog that displays the IMEI of the phone -->
     <string name="imei">IMEI</string>
 
@@ -452,7 +467,8 @@
     <!-- Hint text displayed in the "digits" field above the dialer's
          dialpad, if there's already a call in progress.  (This hint
          reminds the user that the dialer will add a new call, as opposed
-         to sending DTMF tones over the current call.) -->
+         to sending DTMF tones over the current call.)
+         [CHAR LIMIT=40] -->
     <string name="dialerDialpadHintText">Dial to add a call</string>
 
     <!-- Dialog text displayed when loading a phone number from the SIM card for speed dial -->
@@ -584,8 +600,6 @@
     <!-- The text displayed on the divider for the Favorites tab in Phone app indicating that items below it are frequently called as opposed to starred contacts [CHAR LIMIT = 39] -->
     <string name="favoritesFrequentCalled">Frequently called</string>
 
-    <!-- Dialog title when prompting before creating a contact -->
-    <string name="add_contact_dlg_title">Add contact</string>
     <!-- Dialog message when prompting before creating a contact. Includes
          the email address, e.g. "Add xyz@foo.com to contacts?" -->
     <string name="add_contact_dlg_message_fmt">Add \"<xliff:g id="email">%s</xliff:g>\" to contacts?</string>
@@ -731,19 +745,11 @@
       -->
     <string name="description_view_contact_detail" msgid="2795575601596468581">View contact</string>
 
-    <!-- Dialog title shown when (USB) storage does not exist [CHAR LIMIT=25] -->
-    <string name="no_sdcard_title" product="nosdcard">Storage unavailable</string>
-    <!-- Dialog title shown when SD Card does not exist -->
-    <string name="no_sdcard_title" product="default">No SD card</string>
-
     <!-- Dialog message shown when (USB) storage does not exist [CHAR LIMIT=30] -->
     <string name="no_sdcard_message" product="nosdcard">No storage was found.</string>
     <!-- Dialog message shown when SDcard does not exist. [CHAR LIMIT=30] -->
     <string name="no_sdcard_message" product="default">No SD card was found.</string>
 
-    <!-- Dialog title shown when searching vCard data from SD Card -->
-    <string name="searching_vcard_title">Searching for vCard</string>
-
     <!-- Action string for selecting SIM for importing contacts -->
     <string name="import_from_sim">Import from SIM card</string>
 
@@ -776,11 +782,6 @@
     <!-- Dialog message shown when searching VCard data from SD Card. [CHAR LIMIT=NONE] -->
     <string name="searching_vcard_message" product="default">Searching for vCard data on SD card\u2026</string>
 
-    <!-- Dialog title shown when scanning VCard data failed. [CHAR LIMIT=NONE] -->
-    <string name="scanning_sdcard_failed_title" product="nosdcard">Couldn\'t scan storage</string>
-    <!-- Dialog title shown when scanning VCard data failed. -->
-    <string name="scanning_sdcard_failed_title" product="default">Couldn\'t scan SD card</string>
-
     <!-- Dialog message shown when searching VCard data failed.
          An exact reason for the failure should [CHAR LIMIT=NONE] -->
     <string name="scanning_sdcard_failed_message" product="nosdcard">The storage couldn\'t be scanned. (Reason: \"<xliff:g id="fail_reason">%s</xliff:g>\")</string>
@@ -890,7 +891,7 @@
     <string name="vcard_unknown_filename">contact</string>
 
     <!-- The percentage, used for expressing the progress of vCard import/export. -->
-    <string name="percentage">%s%%</string>
+    <string name="percentage"><xliff:g id="percentage" example="50">%s</xliff:g><xliff:g id="percentsign" example="%">%%</xliff:g></string>
 
     <!-- Dialog title shown when a user confirms whether he/she export Contact data. [CHAR LIMIT=32] -->
     <string name="confirm_export_title">Export contacts?</string>
@@ -968,17 +969,11 @@
     <!-- Message in progress bar while exporting contact list to a file "(current number) of (total number) contacts" The order of "current number" and "total number" cannot be changed (like "total: (total number), current: (current number)")-->
     <string name="exporting_contact_list_progress"><xliff:g id="current_number">%s</xliff:g> of <xliff:g id="total_number">%s</xliff:g> contacts</string>
 
-    <!-- Title shown in a Dialog confirming a user's cancel request toward existing vCard import. [CHAR LIMIT=40] -->
-    <string name="cancel_import_confirmation_title">Canceling vCard import</string>
-
     <!-- Message shown in a Dialog confirming a user's cancel request toward existing vCard import.
          The argument is file name for the vCard import the user wants to cancel.
          [CHAR LIMIT=128] -->
     <string name="cancel_import_confirmation_message">Cancel import of <xliff:g id="filename" example="import.vcf">%s</xliff:g>?</string>
 
-    <!-- Title shown in a Dialog confirming a user's cancel request toward existing vCard export. [CHAR LIMIT=128] -->
-    <string name="cancel_export_confirmation_title">Canceling vCard export</string>
-
     <!-- Message shown in a Dialog confirming a user's cancel request toward existing vCard export.
          The argument is file name for the vCard export the user wants to cancel.
          [CHAR LIMIT=128] -->
@@ -995,13 +990,13 @@
     <string name="add_wait">Add wait</string>
 
     <!-- Title for the call disambiguation dialog -->
-    <string name="call_disambig_title">Call using</string>
+    <string name="call_disambig_title">Choose number</string>
 
     <!-- Menu item label for call settings [CHAR LIMIT=30] -->
     <string name="call_settings">Settings</string>
 
     <!-- Title for the sms disambiguation dialog -->
-    <string name="sms_disambig_title">Text using</string>
+    <string name="sms_disambig_title">Choose number</string>
 
     <!-- Message next to disamgiguation dialog check box -->
     <string name="make_primary">Remember this choice</string>
@@ -1016,6 +1011,9 @@
     <!-- The menu item to open the list of accounts -->
     <string name="menu_accounts">Accounts</string>
 
+    <!--  The menu item to clear frequents [CHAR LIMIT=30] -->
+    <string name="menu_clear_frequents">Clear frequents</string>
+
     <!-- The menu item to filter the list of contacts displayed -->
     <string name="menu_contacts_filter">Contacts to display</string>
 
@@ -1025,12 +1023,12 @@
     <!-- Dialog title when selecting the bulk operation to perform from a list. [CHAR LIMIT=36] -->
     <string name="dialog_import_export">Import/export contacts</string>
 
+    <!-- Dialog title when importing contacts from an external source. [CHAR LIMIT=36] -->
+    <string name="dialog_import">Import contacts</string>
+
     <!-- The menu item to share the currently viewed contact [CHAR LIMIT=30] -->
     <string name="menu_share">Share</string>
 
-    <!-- The menu item to show all contacts in Phone entrance [CHAR LIMIT=30] -->
-    <string name="menu_all_contacts">All contacts</string>
-
     <!-- Dialog title when picking the application to share a contact with. -->
     <string name="share_via">Share contact via</string>
 
@@ -1303,9 +1301,6 @@
     <!-- An allowable value for the "view names as" contact display option  -->
     <string name="display_options_view_family_name_first">Family name first</string>
 
-    <!-- Gray hint displayed in the search field in Contacts when empty -->
-    <string name="search_bar_hint">Search contacts</string>
-
     <!-- An option in the 'Contact photo' dialog, if there is no photo yet [CHAR LIMIT=50] -->
     <string name="take_photo">Take photo</string>
 
@@ -1393,19 +1388,11 @@
     <!-- The name of the invisible local contact directory -->
     <string name="local_invisible_directory">Other</string>
 
-    <!-- The title of a confirmation dialog shown when the user selects a
-        contact aggregation suggestion in Contact editor. [CHAR LIMIT=128]-->
-    <string name="aggregation_suggestion_join_dialog_title">Join contacts</string>
-
     <!-- The message in a confirmation dialog shown when the user selects a
         contact aggregation suggestion in Contact editor. [CHAR LIMIT=512]-->
     <string name="aggregation_suggestion_join_dialog_message">Join
         the current contact with the selected contact?</string>
 
-    <!-- The title of a confirmation dialog shown when the user selects a
-        contact aggregation suggestion in Contact editor. [CHAR LIMIT=128]-->
-    <string name="aggregation_suggestion_edit_dialog_title">Edit selected contacts</string>
-
     <!-- The message in a confirmation dialog shown when the user selects a
         contact aggregation suggestion in Contact editor. [CHAR LIMIT=512]-->
     <string name="aggregation_suggestion_edit_dialog_message">Switch to editing
@@ -1465,6 +1452,9 @@
     <!-- Menu item for the settings activity [CHAR LIMIT=64] -->
     <string name="menu_settings" msgid="377929915873428211">Settings</string>
 
+    <!-- Menu item for invoking contextual help [CHAR LIMIT=64] -->
+    <string name="menu_help">Help</string>
+
     <!-- The preference section title for contact display options [CHAR LIMIT=128] -->
     <string name="preference_displayOptions">Display options</string>
 
@@ -1509,16 +1499,13 @@
 
     <!-- Button shown on the main contacts screen when there are no contacts on the device.
     Initiates a contact import dialog [CHAR LIMIT=128] -->
-    <string name="contacts_unavailable_import_contacts">Import contacts from a file</string>
+    <string name="contacts_unavailable_import_contacts">Import contacts</string>
 
     <!-- Title of the dialog that allows creation of a contact group [CHAR LIMIT=128] -->
     <string name="create_group_dialog_title">Create new group</string>
 
     <!-- An item in the popup list of groups that triggers creation of a contact group [CHAR LIMIT=128] -->
-    <string name="create_group_item_label">[Create new group]</string>
-
-    <!-- Title of the dialog that allows deletion of a contact group [CHAR LIMIT=128] -->
-    <string name="delete_group_dialog_title">Delete group</string>
+    <string name="create_group_item_label">Create new group</string>
 
     <!-- Shows how many groups are from the specified account [CHAR LIMIT=15] -->
     <plurals name="num_groups_in_account">
@@ -1562,9 +1549,6 @@
     <!-- Toast shown when text is copied to the clipboard [CHAR LIMIT=64] -->
     <string name="toast_text_copied">Text copied</string>
 
-    <!-- Title of the alert dialog when the user hits the Cancel button in the editor [CHAR LIMIT=64] -->
-    <string name="cancel_confirmation_dialog_title">Discard changes</string>
-
     <!-- Contents of the alert dialog when the user hits the Cancel button in the editor [CHAR LIMIT=128] -->
     <string name="cancel_confirmation_dialog_message">Discard your changes?</string>
 
@@ -1589,6 +1573,9 @@
         <item quantity="other"><xliff:g id="count">%1$d</xliff:g> Voicemails</item>
     </plurals>
 
+    <!-- Used in the notification of a new voicemail for the action to play the voicemail. -->
+    <string name="notification_action_voicemail_play">Play</string>
+
     <!-- Used to build a list of names or phone numbers, to indicate the callers who left
          voicemails.
          The first argument may be one or more callers, the most recent ones.
@@ -1818,15 +1805,23 @@
     <!-- Button label to prompt the user to add another account (when there are already existing accounts on the device) [CHAR LIMIT=30] -->
     <string name="add_new_account">Add new account</string>
 
-    <!-- Dialog title which is shown when the user tries to make a phone call
-         to prohibited phone numbers [CHAR LIMIT=40] -->
-    <string name="dialog_phone_call_prohibited_title" msgid="4313552620858880999">Call not sent</string>
-
-    <!-- Dialog title which is shown when the user tries to check voicemail
-         while the system isn't ready for the access. [CHAR LIMIT=40] -->
-    <string name="dialog_voicemail_not_ready_title">Voicemail number unavailable</string>
+    <!-- Dialog message which is shown when the user tries to make a phone call
+         to prohibited phone numbers [CHAR LIMIT=NONE] -->
+    <string name="dialog_phone_call_prohibited_message" msgid="4313552620858880999">Call not sent</string>
 
     <!-- Dialog message which is shown when the user tries to check voicemail
          while the system isn't ready for the access. [CHAR LIMIT=NONE] -->
     <string name="dialog_voicemail_not_ready_message">To set up voicemail, go to Menu &gt; Settings.</string>
+
+    <!-- Dialog message which is shown when the user tries to check voicemail
+         while the system is in airplane mode. The user cannot access to
+         voicemail service in Airplane mode. [CHAR LIMI=NONE] -->
+    <string name="dialog_voicemail_airplane_mode_message">To call voicemail, first turn off Airplane mode.</string>
+
+    <!-- Content description for the fake action menu overflow button.
+         This should be same as the description for the real action menu
+         overflow button available in ActionBar.
+         [CHAR LIMIT=NONE] -->
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">More options</string>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f22ff1d..829b207 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,13 +32,12 @@
         <item name="list_item_padding_left">0dip</item>
         <item name="list_item_gap_between_image_and_text">8dip</item>
         <item name="list_item_gap_between_label_and_data">5dip</item>
-        <item name="list_item_call_button_padding">14dip</item>
         <item name="list_item_vertical_divider_margin">5dip</item>
         <item name="list_item_presence_icon_margin">4dip</item>
         <item name="list_item_presence_icon_size">16dip</item>
         <item name="list_item_photo_size">@dimen/contact_browser_list_item_photo_size</item>
         <item name="list_item_profile_photo_size">70dip</item>
-        <item name="list_item_prefix_highlight_color">#729a27</item>
+        <item name="list_item_prefix_highlight_color">@color/people_app_theme_color</item>
         <item name="list_item_header_text_indent">8dip</item>
         <item name="list_item_header_text_color">@color/people_app_theme_color</item>
         <item name="list_item_header_text_size">14sp</item>
@@ -121,7 +120,6 @@
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowAnimationStyle">@null</item>
         <item name="android:windowIsFloating">false</item>
-        <item name="android:backgroundDimEnabled">true</item>
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:listViewStyle">@style/ListViewStyle</item>
@@ -132,6 +130,7 @@
         <item name="android:actionBarItemBackground">@drawable/action_bar_item_background</item>
         <item name="android:actionBarWidgetTheme">@style/ContactsActionBarTheme</item>
         <item name="android:actionBarTabStyle">@style/ContactsActionBarTabView</item>
+        <item name="android:actionDropDownStyle">@style/ContactsActionBarDropDownStyle</item>
         <item name="android:textColorPrimary">@color/primary_text_color</item>
         <item name="android:textColorSecondary">@color/secondary_text_color</item>
         <item name="android:listViewStyle">@style/ListViewStyle</item>
@@ -146,16 +145,15 @@
         <item name="list_item_padding_left">0dip</item>
         <item name="list_item_gap_between_image_and_text">8dip</item>
         <item name="list_item_gap_between_label_and_data">5dip</item>
-        <item name="list_item_call_button_padding">14dip</item>
         <item name="list_item_vertical_divider_margin">5dip</item>
         <item name="list_item_presence_icon_margin">4dip</item>
         <item name="list_item_presence_icon_size">16dip</item>
         <item name="list_item_photo_size">@dimen/contact_browser_list_item_photo_size</item>
         <item name="list_item_profile_photo_size">70dip</item>
-        <item name="list_item_prefix_highlight_color">#99cc00</item>
+        <item name="list_item_prefix_highlight_color">@color/people_app_theme_color</item>
         <item name="list_item_header_text_color">@color/people_app_theme_color</item>
         <item name="list_item_header_text_size">14sp</item>
-        <item name="list_item_header_height">26dip</item>
+        <item name="list_item_header_height">32dip</item>
         <item name="list_item_header_underline_height">1dip</item>
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
         <item name="list_item_data_width_weight">5</item>
@@ -177,6 +175,10 @@
         <item name="android:displayOptions"></item>
     </style>
 
+    <style name="ContactsActionBarDropDownStyle" parent="@android:style/Widget.Holo.Light.Spinner">
+        <item name="android:background">@drawable/ab_dropdown_navigation_item_background</item>
+    </style>
+
     <style name="ContactsActionBarTheme" parent="@android:style/Theme.Holo">
         <item name="android:textColorHint">#CCCCCC</item>
         <item name="android:textColor">@android:color/black</item>
@@ -314,6 +316,15 @@
         <item name="android:background">@color/quickcontact_tab_indicator</item>
     </style>
 
+    <style name="Theme.PhotoSelector" parent="@android:style/Theme.Holo.Light">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowAnimationStyle">@null</item>
+        <item name="android:backgroundDimEnabled">false</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
 
     <style name="GroupMembershipSizeTextAppearance" parent="@android:style/TextAppearance.Small"/>
 
@@ -337,4 +348,14 @@
         <item name="android:singleLine">true</item>
         <item name="android:textAllCaps">true</item>
     </style>
+
+    <style name="PeopleNavigationDropDownTextAppearance">
+        <item name="android:textColor">#333333</item>
+        <item name="android:textSize">18sp</item>
+    </style>
+
+    <style name="PeopleNavigationDropDownHeaderTextAppearance">
+        <item name="android:textColor">#cdffffff</item>
+        <item name="android:textSize">18sp</item>
+    </style>
 </resources>
diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml
index 949ec36..a78d531 100644
--- a/res/xml/searchable.xml
+++ b/res/xml/searchable.xml
@@ -14,12 +14,7 @@
      limitations under the License.
 -->
 
-<!--
-    TODO: Use localizable string resources instead of hard-coded strings
-    once Search Manager is enhanced to allow them.
--->
 <searchable xmlns:android="http://schemas.android.com/apk/res/android"
-    android:icon="@drawable/ic_tab_contacts"
     android:label="@string/contactsList"
     android:hint="@string/searchHint"
     android:searchMode="queryRewriteFromText"
diff --git a/src/com/android/contacts/CallContactActivity.java b/src/com/android/contacts/CallContactActivity.java
index b7c472a..793770b 100644
--- a/src/com/android/contacts/CallContactActivity.java
+++ b/src/com/android/contacts/CallContactActivity.java
@@ -18,10 +18,8 @@
 
 import com.android.contacts.interactions.PhoneNumberInteraction;
 
-import android.app.Dialog;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnDismissListener;
-import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
@@ -50,7 +48,7 @@
         if (Contacts.CONTENT_ITEM_TYPE.equals(getContentResolver().getType(contactUri))) {
             PhoneNumberInteraction.startInteractionForPhoneCall(this, contactUri);
         } else {
-            startActivity(new Intent(Intent.ACTION_CALL_PRIVILEGED, contactUri));
+            startActivity(ContactsUtils.getCallIntent(contactUri));
             finish();
         }
     }
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index caa8bce..47441ce 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -22,8 +22,11 @@
 import com.android.contacts.calllog.ContactInfo;
 import com.android.contacts.calllog.ContactInfoHelper;
 import com.android.contacts.calllog.PhoneNumberHelper;
+import com.android.contacts.format.FormatUtils;
 import com.android.contacts.util.AsyncTaskExecutor;
 import com.android.contacts.util.AsyncTaskExecutors;
+import com.android.contacts.util.ClipboardUtils;
+import com.android.contacts.util.Constants;
 import com.android.contacts.voicemail.VoicemailPlaybackFragment;
 import com.android.contacts.voicemail.VoicemailStatusHelper;
 import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
@@ -38,6 +41,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.database.Cursor;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -51,6 +55,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -92,6 +97,8 @@
     public static final String EXTRA_VOICEMAIL_URI = "EXTRA_VOICEMAIL_URI";
     /** If we should immediately start playback of the voicemail, this extra will be set to true. */
     public static final String EXTRA_VOICEMAIL_START_PLAYBACK = "EXTRA_VOICEMAIL_START_PLAYBACK";
+    /** If the activity was triggered from a notification. */
+    public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
 
     private CallTypeHelper mCallTypeHelper;
     private PhoneNumberHelper mPhoneNumberHelper;
@@ -130,6 +137,15 @@
     private ProximitySensorManager mProximitySensorManager;
     private final ProximitySensorListener mProximitySensorListener = new ProximitySensorListener();
 
+    /**
+     * The action mode used when the phone number is selected.  This will be non-null only when the
+     * phone number is selected.
+     */
+    private ActionMode mPhoneNumberActionMode;
+
+    private CharSequence mPhoneNumberLabelToCopy;
+    private CharSequence mPhoneNumberToCopy;
+
     /** Listener to changes in the proximity sensor state. */
     private class ProximitySensorListener implements ProximitySensorManager.Listener {
         /** Used to show a blank view and hide the action bar. */
@@ -200,6 +216,9 @@
     private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() {
         @Override
         public void onClick(View view) {
+            if (finishPhoneNumerSelectedActionModeIfShown()) {
+                return;
+            }
             startActivity(((ViewEntry) view.getTag()).primaryIntent);
         }
     };
@@ -207,10 +226,25 @@
     private final View.OnClickListener mSecondaryActionListener = new View.OnClickListener() {
         @Override
         public void onClick(View view) {
+            if (finishPhoneNumerSelectedActionModeIfShown()) {
+                return;
+            }
             startActivity(((ViewEntry) view.getTag()).secondaryIntent);
         }
     };
 
+    private final View.OnLongClickListener mPrimaryLongClickListener =
+            new View.OnLongClickListener() {
+        @Override
+        public boolean onLongClick(View v) {
+            if (finishPhoneNumerSelectedActionModeIfShown()) {
+                return true;
+            }
+            startPhoneNumberSelectedActionMode(v);
+            return true;
+        }
+    };
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -241,6 +275,9 @@
         mContactInfoHelper = new ContactInfoHelper(this, ContactsUtils.getCurrentCountryIso(this));
         configureActionBar();
         optionallyHandleVoicemail();
+        if (getIntent().getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) {
+            closeSystemDialogs();
+        }
     }
 
     @Override
@@ -331,9 +368,8 @@
                 TelephonyManager tm = (TelephonyManager)
                         getSystemService(Context.TELEPHONY_SERVICE);
                 if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
-                    Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            Uri.fromParts("tel", mNumber, null));
-                    startActivity(callIntent);
+                    startActivity(ContactsUtils.getCallIntent(
+                            Uri.fromParts(Constants.SCHEME_TEL, mNumber, null)));
                     return true;
                 }
             }
@@ -388,7 +424,6 @@
                 mPhoneCallDetailsHelper.setCallDetailsHeader(mHeaderTextView, firstDetails);
 
                 // Cache the details about the phone number.
-                final Uri numberCallUri = mPhoneNumberHelper.getCallUri(mNumber);
                 final boolean canPlaceCallsTo = mPhoneNumberHelper.canPlaceCallsTo(mNumber);
                 final boolean isVoicemailNumber = mPhoneNumberHelper.isVoicemailNumber(mNumber);
                 final boolean isSipNumber = mPhoneNumberHelper.isSipNumber(mNumber);
@@ -408,6 +443,10 @@
 
                 if (contactUri != null) {
                     mainActionIntent = new Intent(Intent.ACTION_VIEW, contactUri);
+                    // This will launch People's detail contact screen, so we probably want to
+                    // treat it as a separate People task.
+                    mainActionIntent.setFlags(
+                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                     mainActionIcon = R.drawable.ic_contacts_holo_dark;
                     mainActionDescription =
                             getString(R.string.description_view_contact, nameOrNumber);
@@ -469,9 +508,10 @@
                                     firstDetails.number, firstDetails.formattedNumber);
 
                     ViewEntry entry = new ViewEntry(
-                            getString(R.string.menu_callNumber, displayNumber),
-                            new Intent(Intent.ACTION_CALL_PRIVILEGED, numberCallUri),
-                            getString(R.string.description_call, nameOrNumber));
+                            getString(R.string.menu_callNumber,
+                                    FormatUtils.forceLeftToRight(displayNumber)),
+                                    ContactsUtils.getCallIntent(mNumber),
+                                    getString(R.string.description_call, nameOrNumber));
 
                     // Only show a label if the number is shown and it is not a SIP address.
                     if (!TextUtils.isEmpty(firstDetails.name)
@@ -492,8 +532,12 @@
                     }
 
                     configureCallButton(entry);
+                    mPhoneNumberToCopy = displayNumber;
+                    mPhoneNumberLabelToCopy = entry.label;
                 } else {
                     disableCallButton();
+                    mPhoneNumberToCopy = null;
+                    mPhoneNumberLabelToCopy = null;
                 }
 
                 mHasEditNumberBeforeCallOption =
@@ -602,7 +646,8 @@
 
     /** Load the contact photos and places them in the corresponding views. */
     private void loadContactPhotos(Uri photoUri) {
-        mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri, true, true);
+        mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri,
+                mContactBackgroundView.getWidth(), true);
     }
 
     static final class ViewEntry {
@@ -650,6 +695,7 @@
         mainAction.setOnClickListener(mPrimaryActionListener);
         mainAction.setTag(entry);
         mainAction.setContentDescription(entry.primaryDescription);
+        mainAction.setOnLongClickListener(mPrimaryLongClickListener);
 
         if (entry.secondaryIntent != null) {
             icon.setOnClickListener(mSecondaryActionListener);
@@ -771,7 +817,7 @@
     }
 
     public void onMenuEditNumberBeforeCall(MenuItem menuItem) {
-        startActivity(new Intent(Intent.ACTION_DIAL, mPhoneNumberHelper.getCallUri(mNumber)));
+        startActivity(new Intent(Intent.ACTION_DIAL, ContactsUtils.getCallUri(mNumber)));
     }
 
     public void onMenuTrashVoicemail(MenuItem menuItem) {
@@ -823,4 +869,68 @@
     public void disableProximitySensor(boolean waitForFarState) {
         mProximitySensorManager.disable(waitForFarState);
     }
+
+    /**
+     * If the phone number is selected, unselect it and return {@code true}.
+     * Otherwise, just {@code false}.
+     */
+    private boolean finishPhoneNumerSelectedActionModeIfShown() {
+        if (mPhoneNumberActionMode == null) return false;
+        mPhoneNumberActionMode.finish();
+        return true;
+    }
+
+    private void startPhoneNumberSelectedActionMode(View targetView) {
+        mPhoneNumberActionMode = startActionMode(new PhoneNumberActionModeCallback(targetView));
+    }
+
+    private void closeSystemDialogs() {
+        sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+    }
+
+    private class PhoneNumberActionModeCallback implements ActionMode.Callback {
+        private final View mTargetView;
+        private final Drawable mOriginalViewBackground;
+
+        public PhoneNumberActionModeCallback(View targetView) {
+            mTargetView = targetView;
+
+            // Highlight the phone number view.  Remember the old background, and put a new one.
+            mOriginalViewBackground = mTargetView.getBackground();
+            mTargetView.setBackgroundColor(getResources().getColor(R.color.item_selected));
+        }
+
+        @Override
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            if (TextUtils.isEmpty(mPhoneNumberToCopy)) return false;
+
+            getMenuInflater().inflate(R.menu.call_details_cab, menu);
+            return true;
+        }
+
+        @Override
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return true;
+        }
+
+        @Override
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            switch (item.getItemId()) {
+                case R.id.copy_phone_number:
+                    ClipboardUtils.copyText(CallDetailActivity.this, mPhoneNumberLabelToCopy,
+                            mPhoneNumberToCopy, true);
+                    mode.finish(); // Close the CAB
+                    return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void onDestroyActionMode(ActionMode mode) {
+            mPhoneNumberActionMode = null;
+
+            // Restore the view background.
+            mTargetView.setBackground(mOriginalViewBackground);
+        }
+    }
 }
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index c711b6c..10579f3 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -19,15 +19,18 @@
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.AccountTypeWithDataSet;
+import com.android.contacts.model.EntityDeltaList;
 import com.android.contacts.util.ContactLoaderUtils;
 import com.android.contacts.util.DataStatus;
 import com.android.contacts.util.StreamItemEntry;
 import com.android.contacts.util.StreamItemPhotoEntry;
-import com.google.android.collect.Lists;
+import com.android.contacts.util.UriUtils;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
+import android.content.AsyncTaskLoader;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -35,14 +38,12 @@
 import android.content.Entity;
 import android.content.Entity.NamedContentValues;
 import android.content.Intent;
-import android.content.Loader;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
@@ -56,14 +57,13 @@
 import android.provider.ContactsContract.StreamItems;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.LongSparseArray;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -71,21 +71,38 @@
 /**
  * Loads a single Contact and all it constituent RawContacts.
  */
-public class ContactLoader extends Loader<ContactLoader.Result> {
-    private static final String TAG = "ContactLoader";
+public class ContactLoader extends AsyncTaskLoader<ContactLoader.Result> {
+    private static final String TAG = ContactLoader.class.getSimpleName();
+
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /** A short-lived cache that can be set by {@link #cacheResult()} */
+    private static Result sCachedResult = null;
 
     private final Uri mRequestedUri;
     private Uri mLookupUri;
     private boolean mLoadGroupMetaData;
     private boolean mLoadStreamItems;
-    private final boolean mLoadInvitableAccountTypes;
+    private boolean mLoadInvitableAccountTypes;
+    private boolean mPostViewNotification;
     private Result mContact;
     private ForceLoadContentObserver mObserver;
-    private boolean mDestroyed;
     private final Set<Long> mNotifiedRawContactIds = Sets.newHashSet();
 
-    public interface Listener {
-        public void onContactLoaded(Result contact);
+    public ContactLoader(Context context, Uri lookupUri, boolean postViewNotification) {
+        this(context, lookupUri, false, false, false, postViewNotification);
+    }
+
+    public ContactLoader(Context context, Uri lookupUri, boolean loadGroupMetaData,
+            boolean loadStreamItems, boolean loadInvitableAccountTypes,
+            boolean postViewNotification) {
+        super(context);
+        mLookupUri = lookupUri;
+        mRequestedUri = lookupUri;
+        mLoadGroupMetaData = loadGroupMetaData;
+        mLoadStreamItems = loadStreamItems;
+        mLoadInvitableAccountTypes = loadInvitableAccountTypes;
+        mPostViewNotification = postViewNotification;
     }
 
     /**
@@ -117,9 +134,9 @@
         private final boolean mStarred;
         private final Integer mPresence;
         private final ArrayList<Entity> mEntities;
-        private final ArrayList<StreamItemEntry> mStreamItems;
-        private final HashMap<Long, DataStatus> mStatuses;
-        private final ArrayList<AccountType> mInvitableAccountTypes;
+        private ArrayList<StreamItemEntry> mStreamItems;
+        private final LongSparseArray<DataStatus> mStatuses;
+        private ArrayList<AccountType> mInvitableAccountTypes;
 
         private String mDirectoryDisplayName;
         private String mDirectoryType;
@@ -129,7 +146,6 @@
 
         private ArrayList<GroupMetaData> mGroups;
 
-        private boolean mLoadingPhoto;
         private byte[] mPhotoBinaryData;
         private final boolean mSendToVoicemail;
         private final String mCustomRingtone;
@@ -154,7 +170,7 @@
             mLookupKey = null;
             mId = -1;
             mEntities = null;
-            mStreamItems = new ArrayList<StreamItemEntry>();
+            mStreamItems = null;
             mStatuses = null;
             mNameRawContactId = -1;
             mDisplayNameSource = DisplayNameSources.UNDEFINED;
@@ -196,8 +212,8 @@
             mLookupKey = lookupKey;
             mId = id;
             mEntities = new ArrayList<Entity>();
-            mStreamItems = new ArrayList<StreamItemEntry>();
-            mStatuses = new HashMap<Long, DataStatus>();
+            mStreamItems = null;
+            mStatuses = new LongSparseArray<DataStatus>();
             mNameRawContactId = nameRawContactId;
             mDisplayNameSource = displayNameSource;
             mPhotoId = photoId;
@@ -207,16 +223,17 @@
             mPhoneticName = phoneticName;
             mStarred = starred;
             mPresence = presence;
-            mInvitableAccountTypes = Lists.newArrayList();
+            mInvitableAccountTypes = null;
             mSendToVoicemail = sendToVoicemail;
             mCustomRingtone = customRingtone;
             mIsUserProfile = isUserProfile;
         }
 
-        private Result(Result from) {
+        private Result(Uri requestedUri, Result from) {
+            mRequestedUri = requestedUri;
+
             mStatus = from.mStatus;
             mException = from.mException;
-            mRequestedUri = from.mRequestedUri;
             mLookupUri = from.mLookupUri;
             mUri = from.mUri;
             mDirectoryId = from.mDirectoryId;
@@ -244,7 +261,6 @@
 
             mGroups = from.mGroups;
 
-            mLoadingPhoto = from.mLoadingPhoto;
             mPhotoBinaryData = from.mPhotoBinaryData;
             mSendToVoicemail = from.mSendToVoicemail;
             mCustomRingtone = from.mCustomRingtone;
@@ -263,10 +279,6 @@
             mDirectoryExportSupport = exportSupport;
         }
 
-        private void setLoadingPhoto(boolean flag) {
-            mLoadingPhoto = flag;
-        }
-
         private void setPhotoBinaryData(byte[] photoBinaryData) {
             mPhotoBinaryData = photoBinaryData;
         }
@@ -301,8 +313,18 @@
             return mRequestedUri;
         }
 
+        /**
+         * Instantiate a new EntityDeltaList for this contact.
+         */
+        public EntityDeltaList createEntityDeltaList() {
+            return EntityDeltaList.fromIterator(getEntities().iterator());
+        }
+
+        /**
+         * Returns the contact ID.
+         */
         @VisibleForTesting
-        /*package*/ long getId() {
+        /* package */ long getId() {
             return mId;
         }
 
@@ -387,7 +409,7 @@
             return mStreamItems;
         }
 
-        public HashMap<Long, DataStatus> getStatuses() {
+        public LongSparseArray<DataStatus> getStatuses() {
             return mStatuses;
         }
 
@@ -400,6 +422,38 @@
                     && mDirectoryId != Directory.LOCAL_INVISIBLE;
         }
 
+        /**
+         * @return true if this is a contact (not group, etc.) with at least one
+         *         writable raw-contact, and false otherwise.
+         */
+        public boolean isWritableContact(final Context context) {
+            return getFirstWritableRawContactId(context) != -1;
+        }
+
+        /**
+         * Return the ID of the first raw-contact in the contact data that belongs to a
+         * contact-writable account, or -1 if no such entity exists.
+         */
+        public long getFirstWritableRawContactId(final Context context) {
+            // Directory entries are non-writable
+            if (isDirectoryEntry()) return -1;
+
+            // Iterate through raw-contacts; if we find a writable on, return its ID.
+            final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
+            for (Entity entity : getEntities()) {
+                ContentValues values = entity.getEntityValues();
+                String type = values.getAsString(RawContacts.ACCOUNT_TYPE);
+                String dataSet = values.getAsString(RawContacts.DATA_SET);
+
+                AccountType accountType = accountTypes.getAccountType(type, dataSet);
+                if (accountType != null && accountType.areContactsWritable()) {
+                    return values.getAsLong(RawContacts._ID);
+                }
+            }
+            // No writable raw-contact was found.
+            return -1;
+        }
+
         public int getDirectoryExportSupport() {
             return mDirectoryExportSupport;
         }
@@ -420,10 +474,6 @@
             return mDirectoryAccountName;
         }
 
-        public boolean isLoadingPhoto() {
-            return mLoadingPhoto;
-        }
-
         public byte[] getPhotoBinaryData() {
             return mPhotoBinaryData;
         }
@@ -459,13 +509,6 @@
             return result;
         }
 
-        private void addGroupMetaData(GroupMetaData group) {
-            if (mGroups == null) {
-                mGroups = new ArrayList<GroupMetaData>();
-            }
-            mGroups.add(group);
-        }
-
         public List<GroupMetaData> getGroupMetaData() {
             return mGroups;
         }
@@ -481,6 +524,12 @@
         public boolean isUserProfile() {
             return mIsUserProfile;
         }
+
+        @Override
+        public String toString() {
+            return "{requested=" + mRequestedUri + ",lookupkey=" + mLookupKey +
+                    ",uri=" + mUri + ",status=" + mStatus + "}";
+        }
     }
 
     /**
@@ -676,491 +725,527 @@
         public final static int FAVORITES = 7;
     }
 
-    private final class LoadContactTask extends AsyncTask<Void, Void, Result> {
-
-        @Override
-        protected Result doInBackground(Void... args) {
-            try {
-                final ContentResolver resolver = getContext().getContentResolver();
-                final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(
-                        resolver, mLookupUri);
-                Result result = loadContactEntity(resolver, uriCurrentFormat);
-                if (!result.isNotFound()) {
-                    if (result.isDirectoryEntry()) {
+    @Override
+    public Result loadInBackground() {
+        try {
+            final ContentResolver resolver = getContext().getContentResolver();
+            final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(
+                    resolver, mLookupUri);
+            final Result cachedResult = sCachedResult;
+            sCachedResult = null;
+            // Is this the same Uri as what we had before already? In that case, reuse that result
+            final Result result;
+            final boolean resultIsCached;
+            if (cachedResult != null &&
+                    UriUtils.areEqual(cachedResult.getLookupUri(), mLookupUri)) {
+                // We are using a cached result from earlier. Below, we should make sure
+                // we are not doing any more network or disc accesses
+                result = new Result(mRequestedUri, cachedResult);
+                resultIsCached = true;
+            } else {
+                result = loadContactEntity(resolver, uriCurrentFormat);
+                resultIsCached = false;
+            }
+            if (result.isLoaded()) {
+                if (result.isDirectoryEntry()) {
+                    if (!resultIsCached) {
                         loadDirectoryMetaData(result);
-                    } else if (mLoadGroupMetaData) {
+                    }
+                } else if (mLoadGroupMetaData) {
+                    if (result.getGroupMetaData() == null) {
                         loadGroupMetaData(result);
                     }
-                    if (mLoadStreamItems) {
-                        loadStreamItems(result);
-                    }
-                    loadPhotoBinaryData(result);
-
-                    // Note ME profile should never have "Add connection"
-                    if (mLoadInvitableAccountTypes && !result.isUserProfile()) {
-                        loadInvitableAccountTypes(result);
-                    }
                 }
-                return result;
-            } catch (Exception e) {
-                Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
-                return Result.forError(mRequestedUri, e);
+                if (mLoadStreamItems && result.getStreamItems() == null) {
+                    loadStreamItems(result);
+                }
+                if (!resultIsCached) loadPhotoBinaryData(result);
+
+                // Note ME profile should never have "Add connection"
+                if (mLoadInvitableAccountTypes && result.getInvitableAccountTypes() == null) {
+                    loadInvitableAccountTypes(result);
+                }
             }
+            return result;
+        } catch (Exception e) {
+            Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
+            return Result.forError(mRequestedUri, e);
+        }
+    }
+
+    private Result loadContactEntity(ContentResolver resolver, Uri contactUri) {
+        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
+        Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null,
+                Contacts.Entity.RAW_CONTACT_ID);
+        if (cursor == null) {
+            Log.e(TAG, "No cursor returned in loadContactEntity");
+            return Result.forNotFound(mRequestedUri);
         }
 
-        private Result loadContactEntity(ContentResolver resolver, Uri contactUri) {
-            Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
-            Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null,
-                    Contacts.Entity.RAW_CONTACT_ID);
-            if (cursor == null) {
-                Log.e(TAG, "No cursor returned in loadContactEntity");
+        try {
+            if (!cursor.moveToFirst()) {
+                cursor.close();
                 return Result.forNotFound(mRequestedUri);
             }
 
+            // Create the loaded result starting with the Contact data.
+            Result result = loadContactHeaderData(cursor, contactUri);
+
+            // Fill in the raw contacts, which is wrapped in an Entity and any
+            // status data.  Initially, result has empty entities and statuses.
+            long currentRawContactId = -1;
+            Entity entity = null;
+            ArrayList<Entity> entities = result.getEntities();
+            LongSparseArray<DataStatus> statuses = result.getStatuses();
+            for (; !cursor.isAfterLast(); cursor.moveToNext()) {
+                long rawContactId = cursor.getLong(ContactQuery.RAW_CONTACT_ID);
+                if (rawContactId != currentRawContactId) {
+                    // First time to see this raw contact id, so create a new entity, and
+                    // add it to the result's entities.
+                    currentRawContactId = rawContactId;
+                    entity = new android.content.Entity(loadRawContact(cursor));
+                    entities.add(entity);
+                }
+                if (!cursor.isNull(ContactQuery.DATA_ID)) {
+                    ContentValues data = loadData(cursor);
+                    entity.addSubValue(ContactsContract.Data.CONTENT_URI, data);
+
+                    if (!cursor.isNull(ContactQuery.PRESENCE)
+                            || !cursor.isNull(ContactQuery.STATUS)) {
+                        final DataStatus status = new DataStatus(cursor);
+                        final long dataId = cursor.getLong(ContactQuery.DATA_ID);
+                        statuses.put(dataId, status);
+                    }
+                }
+            }
+
+            return result;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Looks for the photo data item in entities. If found, creates a new Bitmap instance. If
+     * not found, returns null
+     */
+    private void loadPhotoBinaryData(Result contactData) {
+
+        // If we have a photo URI, try loading that first.
+        String photoUri = contactData.getPhotoUri();
+        if (photoUri != null) {
             try {
-                if (!cursor.moveToFirst()) {
-                    cursor.close();
-                    return Result.forNotFound(mRequestedUri);
-                }
-
-                long currentRawContactId = -1;
-                Entity entity = null;
-                Result result = loadContactHeaderData(cursor, contactUri);
-                ArrayList<Entity> entities = result.getEntities();
-                HashMap<Long, DataStatus> statuses = result.getStatuses();
-                for (; !cursor.isAfterLast(); cursor.moveToNext()) {
-                    long rawContactId = cursor.getLong(ContactQuery.RAW_CONTACT_ID);
-                    if (rawContactId != currentRawContactId) {
-                        currentRawContactId = rawContactId;
-                        entity = new android.content.Entity(loadRawContact(cursor));
-                        entities.add(entity);
-                    }
-                    if (!cursor.isNull(ContactQuery.DATA_ID)) {
-                        ContentValues data = loadData(cursor);
-                        entity.addSubValue(ContactsContract.Data.CONTENT_URI, data);
-
-                        if (!cursor.isNull(ContactQuery.PRESENCE)
-                                || !cursor.isNull(ContactQuery.STATUS)) {
-                            final DataStatus status = new DataStatus(cursor);
-                            final long dataId = cursor.getLong(ContactQuery.DATA_ID);
-                            statuses.put(dataId, status);
-                        }
-                    }
-                }
-
-                return result;
-            } finally {
-                cursor.close();
-            }
-        }
-
-        /**
-         * Looks for the photo data item in entities. If found, creates a new Bitmap instance. If
-         * not found, returns null
-         */
-        private void loadPhotoBinaryData(Result contactData) {
-
-            // If we have a photo URI, try loading that first.
-            String photoUri = contactData.getPhotoUri();
-            if (photoUri != null) {
+                AssetFileDescriptor fd = getContext().getContentResolver()
+                       .openAssetFileDescriptor(Uri.parse(photoUri), "r");
+                byte[] buffer = new byte[16 * 1024];
+                FileInputStream fis = fd.createInputStream();
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 try {
-                    AssetFileDescriptor fd = getContext().getContentResolver()
-                           .openAssetFileDescriptor(Uri.parse(photoUri), "r");
-                    byte[] buffer = new byte[16 * 1024];
-                    FileInputStream fis = fd.createInputStream();
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    try {
-                        int size;
-                        while ((size = fis.read(buffer)) != -1) {
-                            baos.write(buffer, 0, size);
-                        }
-                        contactData.setPhotoBinaryData(baos.toByteArray());
-                    } finally {
-                        fis.close();
-                        fd.close();
+                    int size;
+                    while ((size = fis.read(buffer)) != -1) {
+                        baos.write(buffer, 0, size);
                     }
-                    return;
-                } catch (IOException ioe) {
-                    // Just fall back to the case below.
+                    contactData.setPhotoBinaryData(baos.toByteArray());
+                } finally {
+                    fis.close();
+                    fd.close();
                 }
-            }
-
-            // If we couldn't load from a file, fall back to the data blob.
-            final long photoId = contactData.getPhotoId();
-            if (photoId <= 0) {
-                // No photo ID
                 return;
-            }
-
-            for (Entity entity : contactData.getEntities()) {
-                for (NamedContentValues subValue : entity.getSubValues()) {
-                    final ContentValues entryValues = subValue.values;
-                    final long dataId = entryValues.getAsLong(Data._ID);
-                    if (dataId == photoId) {
-                        final String mimeType = entryValues.getAsString(Data.MIMETYPE);
-                        // Correct Data Id but incorrect MimeType? Don't load
-                        if (!Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                            return;
-                        }
-                        contactData.setPhotoBinaryData(entryValues.getAsByteArray(Photo.PHOTO));
-                        break;
-                    }
-                }
+            } catch (IOException ioe) {
+                // Just fall back to the case below.
             }
         }
 
-        /**
-         * Sets the "invitable" account types to {@link Result#mInvitableAccountTypes}.
-         */
-        private void loadInvitableAccountTypes(Result contactData) {
+        // If we couldn't load from a file, fall back to the data blob.
+        final long photoId = contactData.getPhotoId();
+        if (photoId <= 0) {
+            // No photo ID
+            return;
+        }
+
+        for (Entity entity : contactData.getEntities()) {
+            for (NamedContentValues subValue : entity.getSubValues()) {
+                final ContentValues entryValues = subValue.values;
+                final long dataId = entryValues.getAsLong(Data._ID);
+                if (dataId == photoId) {
+                    final String mimeType = entryValues.getAsString(Data.MIMETYPE);
+                    // Correct Data Id but incorrect MimeType? Don't load
+                    if (!Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                        return;
+                    }
+                    contactData.setPhotoBinaryData(entryValues.getAsByteArray(Photo.PHOTO));
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the "invitable" account types to {@link Result#mInvitableAccountTypes}.
+     */
+    private void loadInvitableAccountTypes(Result contactData) {
+        final ArrayList<AccountType> resultList = Lists.newArrayList();
+        if (!contactData.isUserProfile()) {
             Map<AccountTypeWithDataSet, AccountType> invitables =
                     AccountTypeManager.getInstance(getContext()).getUsableInvitableAccountTypes();
-            if (invitables.isEmpty()) {
-                return;
-            }
+            if (!invitables.isEmpty()) {
+                final Map<AccountTypeWithDataSet, AccountType> resultMap =
+                        Maps.newHashMap(invitables);
 
-            HashMap<AccountTypeWithDataSet, AccountType> result = Maps.newHashMap(invitables);
-
-            // Remove the ones that already have a raw contact in the current contact
-            for (Entity entity : contactData.getEntities()) {
-                final ContentValues values = entity.getEntityValues();
-                final AccountTypeWithDataSet type = AccountTypeWithDataSet.get(
-                        values.getAsString(RawContacts.ACCOUNT_TYPE),
-                        values.getAsString(RawContacts.DATA_SET));
-                result.remove(type);
-            }
-
-            // Set to mInvitableAccountTypes
-            contactData.mInvitableAccountTypes.addAll(result.values());
-        }
-
-        /**
-         * Extracts Contact level columns from the cursor.
-         */
-        private Result loadContactHeaderData(final Cursor cursor, Uri contactUri) {
-            final String directoryParameter =
-                    contactUri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
-            final long directoryId = directoryParameter == null
-                    ? Directory.DEFAULT
-                    : Long.parseLong(directoryParameter);
-            final long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
-            final String lookupKey = cursor.getString(ContactQuery.LOOKUP_KEY);
-            final long nameRawContactId = cursor.getLong(ContactQuery.NAME_RAW_CONTACT_ID);
-            final int displayNameSource = cursor.getInt(ContactQuery.DISPLAY_NAME_SOURCE);
-            final String displayName = cursor.getString(ContactQuery.DISPLAY_NAME);
-            final String altDisplayName = cursor.getString(ContactQuery.ALT_DISPLAY_NAME);
-            final String phoneticName = cursor.getString(ContactQuery.PHONETIC_NAME);
-            final long photoId = cursor.getLong(ContactQuery.PHOTO_ID);
-            final String photoUri = cursor.getString(ContactQuery.PHOTO_URI);
-            final boolean starred = cursor.getInt(ContactQuery.STARRED) != 0;
-            final Integer presence = cursor.isNull(ContactQuery.CONTACT_PRESENCE)
-                    ? null
-                    : cursor.getInt(ContactQuery.CONTACT_PRESENCE);
-            final boolean sendToVoicemail = cursor.getInt(ContactQuery.SEND_TO_VOICEMAIL) == 1;
-            final String customRingtone = cursor.getString(ContactQuery.CUSTOM_RINGTONE);
-            final boolean isUserProfile = cursor.getInt(ContactQuery.IS_USER_PROFILE) == 1;
-
-            Uri lookupUri;
-            if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
-                lookupUri = ContentUris.withAppendedId(
-                    Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), contactId);
-            } else {
-                lookupUri = contactUri;
-            }
-
-            return new Result(mRequestedUri, contactUri, lookupUri, directoryId, lookupKey,
-                    contactId, nameRawContactId, displayNameSource, photoId, photoUri, displayName,
-                    altDisplayName, phoneticName, starred, presence, sendToVoicemail,
-                    customRingtone, isUserProfile);
-        }
-
-        /**
-         * Extracts RawContact level columns from the cursor.
-         */
-        private ContentValues loadRawContact(Cursor cursor) {
-            ContentValues cv = new ContentValues();
-
-            cv.put(RawContacts._ID, cursor.getLong(ContactQuery.RAW_CONTACT_ID));
-
-            cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE_AND_DATA_SET);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC1);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC2);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC3);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC4);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DELETED);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.CONTACT_ID);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.STARRED);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.NAME_VERIFIED);
-
-            return cv;
-        }
-
-        /**
-         * Extracts Data level columns from the cursor.
-         */
-        private ContentValues loadData(Cursor cursor) {
-            ContentValues cv = new ContentValues();
-
-            cv.put(Data._ID, cursor.getLong(ContactQuery.DATA_ID));
-
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA1);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA2);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA3);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA4);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA5);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA6);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA7);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA8);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA9);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA10);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA11);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA12);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA13);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA14);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA15);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC1);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC2);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC3);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC4);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_VERSION);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.IS_PRIMARY);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.IS_SUPERPRIMARY);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.MIMETYPE);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.RES_PACKAGE);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.GROUP_SOURCE_ID);
-            cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY);
-
-            return cv;
-        }
-
-        private void cursorColumnToContentValues(
-                Cursor cursor, ContentValues values, int index) {
-            switch (cursor.getType(index)) {
-                case Cursor.FIELD_TYPE_NULL:
-                    // don't put anything in the content values
-                    break;
-                case Cursor.FIELD_TYPE_INTEGER:
-                    values.put(ContactQuery.COLUMNS[index], cursor.getLong(index));
-                    break;
-                case Cursor.FIELD_TYPE_STRING:
-                    values.put(ContactQuery.COLUMNS[index], cursor.getString(index));
-                    break;
-                case Cursor.FIELD_TYPE_BLOB:
-                    values.put(ContactQuery.COLUMNS[index], cursor.getBlob(index));
-                    break;
-                default:
-                    throw new IllegalStateException("Invalid or unhandled data type");
-            }
-        }
-
-        private void loadDirectoryMetaData(Result result) {
-            long directoryId = result.getDirectoryId();
-
-            Cursor cursor = getContext().getContentResolver().query(
-                    ContentUris.withAppendedId(Directory.CONTENT_URI, directoryId),
-                    DirectoryQuery.COLUMNS, null, null, null);
-            if (cursor == null) {
-                return;
-            }
-            try {
-                if (cursor.moveToFirst()) {
-                    final String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME);
-                    final String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
-                    final int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
-                    final String accountType = cursor.getString(DirectoryQuery.ACCOUNT_TYPE);
-                    final String accountName = cursor.getString(DirectoryQuery.ACCOUNT_NAME);
-                    final int exportSupport = cursor.getInt(DirectoryQuery.EXPORT_SUPPORT);
-                    String directoryType = null;
-                    if (!TextUtils.isEmpty(packageName)) {
-                        PackageManager pm = getContext().getPackageManager();
-                        try {
-                            Resources resources = pm.getResourcesForApplication(packageName);
-                            directoryType = resources.getString(typeResourceId);
-                        } catch (NameNotFoundException e) {
-                            Log.w(TAG, "Contact directory resource not found: "
-                                    + packageName + "." + typeResourceId);
-                        }
-                    }
-
-                    result.setDirectoryMetaData(
-                            displayName, directoryType, accountType, accountName, exportSupport);
+                // Remove the ones that already have a raw contact in the current contact
+                for (Entity entity : contactData.getEntities()) {
+                    final ContentValues values = entity.getEntityValues();
+                    final AccountTypeWithDataSet type = AccountTypeWithDataSet.get(
+                            values.getAsString(RawContacts.ACCOUNT_TYPE),
+                            values.getAsString(RawContacts.DATA_SET));
+                    resultMap.remove(type);
                 }
-            } finally {
-                cursor.close();
+
+                resultList.addAll(resultMap.values());
             }
         }
 
-        /**
-         * Loads groups meta-data for all groups associated with all constituent raw contacts'
-         * accounts.
-         */
-        private void loadGroupMetaData(Result result) {
-            StringBuilder selection = new StringBuilder();
-            ArrayList<String> selectionArgs = new ArrayList<String>();
-            for (Entity entity : result.mEntities) {
-                ContentValues values = entity.getEntityValues();
-                String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
-                String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
-                String dataSet = values.getAsString(RawContacts.DATA_SET);
-                if (accountName != null && accountType != null) {
-                    if (selection.length() != 0) {
-                        selection.append(" OR ");
-                    }
-                    selection.append(
-                            "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?");
-                    selectionArgs.add(accountName);
-                    selectionArgs.add(accountType);
+        // Set to mInvitableAccountTypes
+        contactData.mInvitableAccountTypes = resultList;
+    }
 
-                    if (dataSet != null) {
-                        selection.append(" AND " + Groups.DATA_SET + "=?");
-                        selectionArgs.add(dataSet);
-                    } else {
-                        selection.append(" AND " + Groups.DATA_SET + " IS NULL");
-                    }
-                    selection.append(")");
-                }
-            }
-            Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
-                    GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]),
-                    null);
-            try {
-                while (cursor.moveToNext()) {
-                    final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
-                    final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
-                    final String dataSet = cursor.getString(GroupQuery.DATA_SET);
-                    final long groupId = cursor.getLong(GroupQuery.ID);
-                    final String title = cursor.getString(GroupQuery.TITLE);
-                    final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
-                            ? false
-                            : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
-                    final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
-                            ? false
-                            : cursor.getInt(GroupQuery.FAVORITES) != 0;
+    /**
+     * Extracts Contact level columns from the cursor.
+     */
+    private Result loadContactHeaderData(final Cursor cursor, Uri contactUri) {
+        final String directoryParameter =
+                contactUri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
+        final long directoryId = directoryParameter == null
+                ? Directory.DEFAULT
+                : Long.parseLong(directoryParameter);
+        final long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
+        final String lookupKey = cursor.getString(ContactQuery.LOOKUP_KEY);
+        final long nameRawContactId = cursor.getLong(ContactQuery.NAME_RAW_CONTACT_ID);
+        final int displayNameSource = cursor.getInt(ContactQuery.DISPLAY_NAME_SOURCE);
+        final String displayName = cursor.getString(ContactQuery.DISPLAY_NAME);
+        final String altDisplayName = cursor.getString(ContactQuery.ALT_DISPLAY_NAME);
+        final String phoneticName = cursor.getString(ContactQuery.PHONETIC_NAME);
+        final long photoId = cursor.getLong(ContactQuery.PHOTO_ID);
+        final String photoUri = cursor.getString(ContactQuery.PHOTO_URI);
+        final boolean starred = cursor.getInt(ContactQuery.STARRED) != 0;
+        final Integer presence = cursor.isNull(ContactQuery.CONTACT_PRESENCE)
+                ? null
+                : cursor.getInt(ContactQuery.CONTACT_PRESENCE);
+        final boolean sendToVoicemail = cursor.getInt(ContactQuery.SEND_TO_VOICEMAIL) == 1;
+        final String customRingtone = cursor.getString(ContactQuery.CUSTOM_RINGTONE);
+        final boolean isUserProfile = cursor.getInt(ContactQuery.IS_USER_PROFILE) == 1;
 
-                    result.addGroupMetaData(new GroupMetaData(
-                            accountName, accountType, dataSet, groupId, title, defaultGroup,
-                            favorites));
-                }
-            } finally {
-                cursor.close();
-            }
+        Uri lookupUri;
+        if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
+            lookupUri = ContentUris.withAppendedId(
+                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), contactId);
+        } else {
+            lookupUri = contactUri;
         }
 
-        /**
-         * Loads all stream items and stream item photos belonging to this contact.
-         */
-        private void loadStreamItems(Result result) {
-            Cursor cursor = getContext().getContentResolver().query(
-                    Contacts.CONTENT_LOOKUP_URI.buildUpon()
-                            .appendPath(result.getLookupKey())
-                            .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
-                    null, null, null, null);
-            Map<Long, StreamItemEntry> streamItemsById = new HashMap<Long, StreamItemEntry>();
-            ArrayList<StreamItemEntry> streamItems = new ArrayList<StreamItemEntry>();
-            try {
-                while (cursor.moveToNext()) {
-                    StreamItemEntry streamItem = new StreamItemEntry(cursor);
-                    streamItemsById.put(streamItem.getId(), streamItem);
-                    streamItems.add(streamItem);
-                }
-            } finally {
-                cursor.close();
-            }
+        return new Result(mRequestedUri, contactUri, lookupUri, directoryId, lookupKey,
+                contactId, nameRawContactId, displayNameSource, photoId, photoUri, displayName,
+                altDisplayName, phoneticName, starred, presence, sendToVoicemail,
+                customRingtone, isUserProfile);
+    }
 
-            // Now retrieve any photo records associated with the stream items.
-            if (!streamItems.isEmpty()) {
-                if (result.isUserProfile()) {
-                    // If the stream items we're loading are for the profile, we can't bulk-load the
-                    // stream items with a custom selection.
-                    for (StreamItemEntry entry : streamItems) {
-                        Cursor siCursor = getContext().getContentResolver().query(
-                                Uri.withAppendedPath(
-                                        ContentUris.withAppendedId(
-                                                StreamItems.CONTENT_URI, entry.getId()),
-                                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
-                                null, null, null, null);
-                        try {
-                            while (siCursor.moveToNext()) {
-                                entry.addPhoto(new StreamItemPhotoEntry(siCursor));
-                            }
-                        } finally {
-                            siCursor.close();
-                        }
-                    }
-                } else {
-                    String[] streamItemIdArr = new String[streamItems.size()];
-                    StringBuilder streamItemPhotoSelection = new StringBuilder();
-                    streamItemPhotoSelection.append(StreamItemPhotos.STREAM_ITEM_ID + " IN (");
-                    for (int i = 0; i < streamItems.size(); i++) {
-                        if (i > 0) {
-                            streamItemPhotoSelection.append(",");
-                        }
-                        streamItemPhotoSelection.append("?");
-                        streamItemIdArr[i] = String.valueOf(streamItems.get(i).getId());
-                    }
-                    streamItemPhotoSelection.append(")");
-                    Cursor sipCursor = getContext().getContentResolver().query(
-                            StreamItems.CONTENT_PHOTO_URI,
-                            null, streamItemPhotoSelection.toString(), streamItemIdArr,
-                            StreamItemPhotos.STREAM_ITEM_ID);
+    /**
+     * Extracts RawContact level columns from the cursor.
+     */
+    private ContentValues loadRawContact(Cursor cursor) {
+        ContentValues cv = new ContentValues();
+
+        cv.put(RawContacts._ID, cursor.getLong(ContactQuery.RAW_CONTACT_ID));
+
+        cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE_AND_DATA_SET);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC1);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC2);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC3);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC4);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DELETED);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.CONTACT_ID);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.STARRED);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.NAME_VERIFIED);
+
+        return cv;
+    }
+
+    /**
+     * Extracts Data level columns from the cursor.
+     */
+    private ContentValues loadData(Cursor cursor) {
+        ContentValues cv = new ContentValues();
+
+        cv.put(Data._ID, cursor.getLong(ContactQuery.DATA_ID));
+
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA1);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA2);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA3);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA4);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA5);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA6);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA7);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA8);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA9);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA10);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA11);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA12);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA13);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA14);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA15);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC1);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC2);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC3);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC4);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_VERSION);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.IS_PRIMARY);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.IS_SUPERPRIMARY);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.MIMETYPE);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.RES_PACKAGE);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.GROUP_SOURCE_ID);
+        cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY);
+
+        return cv;
+    }
+
+    private void cursorColumnToContentValues(
+            Cursor cursor, ContentValues values, int index) {
+        switch (cursor.getType(index)) {
+            case Cursor.FIELD_TYPE_NULL:
+                // don't put anything in the content values
+                break;
+            case Cursor.FIELD_TYPE_INTEGER:
+                values.put(ContactQuery.COLUMNS[index], cursor.getLong(index));
+                break;
+            case Cursor.FIELD_TYPE_STRING:
+                values.put(ContactQuery.COLUMNS[index], cursor.getString(index));
+                break;
+            case Cursor.FIELD_TYPE_BLOB:
+                values.put(ContactQuery.COLUMNS[index], cursor.getBlob(index));
+                break;
+            default:
+                throw new IllegalStateException("Invalid or unhandled data type");
+        }
+    }
+
+    private void loadDirectoryMetaData(Result result) {
+        long directoryId = result.getDirectoryId();
+
+        Cursor cursor = getContext().getContentResolver().query(
+                ContentUris.withAppendedId(Directory.CONTENT_URI, directoryId),
+                DirectoryQuery.COLUMNS, null, null, null);
+        if (cursor == null) {
+            return;
+        }
+        try {
+            if (cursor.moveToFirst()) {
+                final String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME);
+                final String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
+                final int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
+                final String accountType = cursor.getString(DirectoryQuery.ACCOUNT_TYPE);
+                final String accountName = cursor.getString(DirectoryQuery.ACCOUNT_NAME);
+                final int exportSupport = cursor.getInt(DirectoryQuery.EXPORT_SUPPORT);
+                String directoryType = null;
+                if (!TextUtils.isEmpty(packageName)) {
+                    PackageManager pm = getContext().getPackageManager();
                     try {
-                        while (sipCursor.moveToNext()) {
-                            long streamItemId = sipCursor.getLong(
-                                    sipCursor.getColumnIndex(StreamItemPhotos.STREAM_ITEM_ID));
-                            StreamItemEntry streamItem = streamItemsById.get(streamItemId);
-                            streamItem.addPhoto(new StreamItemPhotoEntry(sipCursor));
+                        Resources resources = pm.getResourcesForApplication(packageName);
+                        directoryType = resources.getString(typeResourceId);
+                    } catch (NameNotFoundException e) {
+                        Log.w(TAG, "Contact directory resource not found: "
+                                + packageName + "." + typeResourceId);
+                    }
+                }
+
+                result.setDirectoryMetaData(
+                        displayName, directoryType, accountType, accountName, exportSupport);
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Loads groups meta-data for all groups associated with all constituent raw contacts'
+     * accounts.
+     */
+    private void loadGroupMetaData(Result result) {
+        StringBuilder selection = new StringBuilder();
+        ArrayList<String> selectionArgs = new ArrayList<String>();
+        for (Entity entity : result.mEntities) {
+            ContentValues values = entity.getEntityValues();
+            String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
+            String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+            String dataSet = values.getAsString(RawContacts.DATA_SET);
+            if (accountName != null && accountType != null) {
+                if (selection.length() != 0) {
+                    selection.append(" OR ");
+                }
+                selection.append(
+                        "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?");
+                selectionArgs.add(accountName);
+                selectionArgs.add(accountType);
+
+                if (dataSet != null) {
+                    selection.append(" AND " + Groups.DATA_SET + "=?");
+                    selectionArgs.add(dataSet);
+                } else {
+                    selection.append(" AND " + Groups.DATA_SET + " IS NULL");
+                }
+                selection.append(")");
+            }
+        }
+        final ArrayList<GroupMetaData> groupList = new ArrayList<GroupMetaData>();
+        final Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
+                GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]),
+                null);
+        try {
+            while (cursor.moveToNext()) {
+                final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
+                final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
+                final String dataSet = cursor.getString(GroupQuery.DATA_SET);
+                final long groupId = cursor.getLong(GroupQuery.ID);
+                final String title = cursor.getString(GroupQuery.TITLE);
+                final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
+                        ? false
+                        : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
+                final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
+                        ? false
+                        : cursor.getInt(GroupQuery.FAVORITES) != 0;
+
+                groupList.add(new GroupMetaData(
+                        accountName, accountType, dataSet, groupId, title, defaultGroup,
+                        favorites));
+            }
+        } finally {
+            cursor.close();
+        }
+        result.mGroups = groupList;
+    }
+
+    /**
+     * Loads all stream items and stream item photos belonging to this contact.
+     */
+    private void loadStreamItems(Result result) {
+        Cursor cursor = getContext().getContentResolver().query(
+                Contacts.CONTENT_LOOKUP_URI.buildUpon()
+                        .appendPath(result.getLookupKey())
+                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
+                null, null, null, null);
+        LongSparseArray<StreamItemEntry> streamItemsById =
+                new LongSparseArray<StreamItemEntry>();
+        ArrayList<StreamItemEntry> streamItems = new ArrayList<StreamItemEntry>();
+        try {
+            while (cursor.moveToNext()) {
+                StreamItemEntry streamItem = new StreamItemEntry(cursor);
+                streamItemsById.put(streamItem.getId(), streamItem);
+                streamItems.add(streamItem);
+            }
+        } finally {
+            cursor.close();
+        }
+
+        // Pre-decode all HTMLs
+        final long start = System.currentTimeMillis();
+        for (StreamItemEntry streamItem : streamItems) {
+            streamItem.decodeHtml(getContext());
+        }
+        final long end = System.currentTimeMillis();
+        if (DEBUG) {
+            Log.d(TAG, "Decoded HTML for " + streamItems.size() + " items, took "
+                    + (end - start) + " ms");
+        }
+
+        // Now retrieve any photo records associated with the stream items.
+        if (!streamItems.isEmpty()) {
+            if (result.isUserProfile()) {
+                // If the stream items we're loading are for the profile, we can't bulk-load the
+                // stream items with a custom selection.
+                for (StreamItemEntry entry : streamItems) {
+                    Cursor siCursor = getContext().getContentResolver().query(
+                            Uri.withAppendedPath(
+                                    ContentUris.withAppendedId(
+                                            StreamItems.CONTENT_URI, entry.getId()),
+                                    StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
+                            null, null, null, null);
+                    try {
+                        while (siCursor.moveToNext()) {
+                            entry.addPhoto(new StreamItemPhotoEntry(siCursor));
                         }
                     } finally {
-                        sipCursor.close();
+                        siCursor.close();
                     }
                 }
+            } else {
+                String[] streamItemIdArr = new String[streamItems.size()];
+                StringBuilder streamItemPhotoSelection = new StringBuilder();
+                streamItemPhotoSelection.append(StreamItemPhotos.STREAM_ITEM_ID + " IN (");
+                for (int i = 0; i < streamItems.size(); i++) {
+                    if (i > 0) {
+                        streamItemPhotoSelection.append(",");
+                    }
+                    streamItemPhotoSelection.append("?");
+                    streamItemIdArr[i] = String.valueOf(streamItems.get(i).getId());
+                }
+                streamItemPhotoSelection.append(")");
+                Cursor sipCursor = getContext().getContentResolver().query(
+                        StreamItems.CONTENT_PHOTO_URI,
+                        null, streamItemPhotoSelection.toString(), streamItemIdArr,
+                        StreamItemPhotos.STREAM_ITEM_ID);
+                try {
+                    while (sipCursor.moveToNext()) {
+                        long streamItemId = sipCursor.getLong(
+                                sipCursor.getColumnIndex(StreamItemPhotos.STREAM_ITEM_ID));
+                        StreamItemEntry streamItem = streamItemsById.get(streamItemId);
+                        streamItem.addPhoto(new StreamItemPhotoEntry(sipCursor));
+                    }
+                } finally {
+                    sipCursor.close();
+                }
             }
-
-            // Set the sorted stream items on the result.
-            Collections.sort(streamItems);
-            result.mStreamItems.addAll(streamItems);
         }
 
-        @Override
-        protected void onPostExecute(Result result) {
-            unregisterObserver();
+        // Set the sorted stream items on the result.
+        Collections.sort(streamItems);
+        result.mStreamItems = streamItems;
+    }
 
-            // The creator isn't interested in any further updates
-            if (mDestroyed || result == null) {
-                return;
+    @Override
+    public void deliverResult(Result result) {
+        unregisterObserver();
+
+        // The creator isn't interested in any further updates
+        if (isReset() || result == null) {
+            return;
+        }
+
+        mContact = result;
+
+        if (result.isLoaded()) {
+            mLookupUri = result.getLookupUri();
+
+            if (!result.isDirectoryEntry()) {
+                Log.i(TAG, "Registering content observer for " + mLookupUri);
+                if (mObserver == null) {
+                    mObserver = new ForceLoadContentObserver();
+                }
+                getContext().getContentResolver().registerContentObserver(
+                        mLookupUri, true, mObserver);
             }
 
-            mContact = result;
-
-            if (result.isLoaded()) {
-                mLookupUri = result.getLookupUri();
-
-                if (!result.isDirectoryEntry()) {
-                    Log.i(TAG, "Registering content observer for " + mLookupUri);
-                    if (mObserver == null) {
-                        mObserver = new ForceLoadContentObserver();
-                    }
-                    getContext().getContentResolver().registerContentObserver(
-                            mLookupUri, true, mObserver);
-                }
-
-                if (mContact.getPhotoBinaryData() == null && mContact.getPhotoUri() != null) {
-                    mContact.setLoadingPhoto(true);
-                    new AsyncPhotoLoader().execute(mContact.getPhotoUri());
-                }
-
+            if (mPostViewNotification) {
                 // inform the source of the data that this contact is being looked at
                 postViewNotificationToSyncAdapter();
             }
-
-            deliverResult(mContact);
         }
+
+        super.deliverResult(mContact);
     }
 
     /**
@@ -1181,11 +1266,11 @@
             final AccountType accountType = AccountTypeManager.getInstance(context).getAccountType(
                     type, dataSet);
             final String serviceName = accountType.getViewContactNotifyServiceClassName();
-            final String resPackageName = accountType.resPackageName;
-            if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(resPackageName)) {
+            final String servicePackageName = accountType.getViewContactNotifyServicePackageName();
+            if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(servicePackageName)) {
                 final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
                 final Intent intent = new Intent();
-                intent.setClassName(resPackageName, serviceName);
+                intent.setClassName(servicePackageName, serviceName);
                 intent.setAction(Intent.ACTION_VIEW);
                 intent.setDataAndType(uri, RawContacts.CONTENT_ITEM_TYPE);
                 try {
@@ -1197,50 +1282,6 @@
         }
     }
 
-    private class AsyncPhotoLoader extends AsyncTask<String, Void, byte[]> {
-
-        private static final int BUFFER_SIZE = 1024*16;
-
-        @Override
-        protected byte[] doInBackground(String... params) {
-            Uri uri = Uri.parse(params[0]);
-            byte[] data = null;
-            try {
-                InputStream is = getContext().getContentResolver().openInputStream(uri);
-                if (is != null) {
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    try {
-                        byte[] mBuffer = new byte[BUFFER_SIZE];
-
-                        int size;
-                        while ((size = is.read(mBuffer)) != -1) {
-                            baos.write(mBuffer, 0, size);
-                        }
-                        data = baos.toByteArray();
-                    } finally {
-                        is.close();
-                    }
-                } else {
-                    Log.v(TAG, "Cannot load photo " + uri);
-                }
-            } catch (IOException e) {
-                Log.e(TAG, "Cannot load photo " + uri, e);
-            }
-
-            return data;
-        }
-
-        @Override
-        protected void onPostExecute(byte[] data) {
-            if (mContact != null) {
-                mContact = new Result(mContact);
-                mContact.setPhotoBinaryData(data);
-                mContact.setLoadingPhoto(false);
-                deliverResult(mContact);
-            }
-        }
-    }
-
     private void unregisterObserver() {
         if (mObserver != null) {
             getContext().getContentResolver().unregisterContentObserver(mObserver);
@@ -1248,18 +1289,41 @@
         }
     }
 
-    public ContactLoader(Context context, Uri lookupUri) {
-        this(context, lookupUri, false, false, false);
+    /**
+     * Sets whether to load stream items. Will trigger a reload if the value has changed.
+     * At the moment, this is only used for debugging purposes
+     */
+    public void setLoadStreamItems(boolean value) {
+        if (mLoadStreamItems != value) {
+            mLoadStreamItems = value;
+            onContentChanged();
+        }
     }
 
-    public ContactLoader(Context context, Uri lookupUri, boolean loadGroupMetaData,
-            boolean loadStreamItems, boolean loadInvitableAccountTypes) {
-        super(context);
-        mLookupUri = lookupUri;
-        mRequestedUri = lookupUri;
-        mLoadGroupMetaData = loadGroupMetaData;
-        mLoadStreamItems = loadStreamItems;
-        mLoadInvitableAccountTypes = loadInvitableAccountTypes;
+    /**
+     * Fully upgrades this ContactLoader to one with all lists fully loaded. When done, the
+     * new result will be delivered
+     */
+    public void upgradeToFullContact() {
+        // Everything requested already? Nothing to do, so let's bail out
+        if (mLoadGroupMetaData && mLoadInvitableAccountTypes && mLoadStreamItems
+                && mPostViewNotification) return;
+
+        mLoadGroupMetaData = true;
+        mLoadInvitableAccountTypes = true;
+        mLoadStreamItems = true;
+        mPostViewNotification = true;
+
+        // Cache the current result, so that we only load the "missing" parts of the contact.
+        cacheResult();
+
+        // Our load parameters have changed, so let's pretend the data has changed. Its the same
+        // thing, essentially.
+        onContentChanged();
+    }
+
+    public boolean getLoadStreamItems() {
+        return mLoadStreamItems;
     }
 
     public Uri getLookupUri() {
@@ -1278,15 +1342,27 @@
     }
 
     @Override
-    protected void onForceLoad() {
-        final LoadContactTask task = new LoadContactTask();
-        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
+    protected void onStopLoading() {
+        cancelLoad();
     }
 
     @Override
     protected void onReset() {
+        super.onReset();
+        cancelLoad();
         unregisterObserver();
         mContact = null;
-        mDestroyed = true;
+    }
+
+    /**
+     * Caches the result, which is useful when we switch from activity to activity, using the same
+     * contact. If the next load is for a different contact, the cached result will be dropped
+     */
+    public void cacheResult() {
+        if (mContact == null || !mContact.isLoaded()) {
+            sCachedResult = null;
+        } else {
+            sCachedResult = mContact;
+        }
     }
 }
diff --git a/src/com/android/contacts/ContactPhotoManager.java b/src/com/android/contacts/ContactPhotoManager.java
index 7c54e80..5b6a1ca 100644
--- a/src/com/android/contacts/ContactPhotoManager.java
+++ b/src/com/android/contacts/ContactPhotoManager.java
@@ -17,6 +17,7 @@
 package com.android.contacts;
 
 import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.util.BitmapUtil;
 import com.android.contacts.util.MemoryUtils;
 import com.android.contacts.util.UriUtils;
 import com.google.android.collect.Lists;
@@ -27,11 +28,17 @@
 import android.content.ContentUris;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Handler.Callback;
@@ -45,6 +52,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.LruCache;
+import android.util.TypedValue;
 import android.widget.ImageView;
 
 import java.io.ByteArrayOutputStream;
@@ -63,9 +71,31 @@
 public abstract class ContactPhotoManager implements ComponentCallbacks2 {
     static final String TAG = "ContactPhotoManager";
     static final boolean DEBUG = false; // Don't submit with true
+    static final boolean DEBUG_SIZES = false; // Don't submit with true
+
+    /** Caches 180dip in pixel. This is used to detect whether to show the hires or lores version
+     * of the default avatar */
+    private static int s180DipInPixel = -1;
 
     public static final String CONTACT_PHOTO_SERVICE = "contactPhotos";
 
+    /**
+     * Returns the resource id of the default avatar. Tries to find a resource that is bigger
+     * than the given extent (width or height). If extent=-1, a thumbnail avatar is returned
+     */
+    public static int getDefaultAvatarResId(Context context, int extent, boolean darkTheme) {
+        // TODO: Is it worth finding a nicer way to do hires/lores here? In practice, the
+        // default avatar doesn't look too different when stretched
+        if (s180DipInPixel == -1) {
+            Resources r = context.getResources();
+            s180DipInPixel = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 180,
+                    r.getDisplayMetrics());
+        }
+
+        final boolean hires = (extent != -1) && (extent > s180DipInPixel);
+        return getDefaultAvatarResId(hires, darkTheme);
+    }
+
     public static int getDefaultAvatarResId(boolean hires, boolean darkTheme) {
         if (hires && darkTheme) return R.drawable.ic_contact_picture_180_holo_dark;
         if (hires) return R.drawable.ic_contact_picture_180_holo_light;
@@ -74,13 +104,17 @@
     }
 
     public static abstract class DefaultImageProvider {
-        public abstract void applyDefaultImage(ImageView view, boolean hires, boolean darkTheme);
+        /**
+         * Applies the default avatar to the ImageView. Extent is an indicator for the size (width
+         * or height). If darkTheme is set, the avatar is one that looks better on dark background
+         */
+        public abstract void applyDefaultImage(ImageView view, int extent, boolean darkTheme);
     }
 
     private static class AvatarDefaultImageProvider extends DefaultImageProvider {
         @Override
-        public void applyDefaultImage(ImageView view, boolean hires, boolean darkTheme) {
-            view.setImageResource(getDefaultAvatarResId(hires, darkTheme));
+        public void applyDefaultImage(ImageView view, int extent, boolean darkTheme) {
+            view.setImageResource(getDefaultAvatarResId(view.getContext(), extent, darkTheme));
         }
     }
 
@@ -88,7 +122,7 @@
         private static Drawable sDrawable;
 
         @Override
-        public void applyDefaultImage(ImageView view, boolean hires, boolean darkTheme) {
+        public void applyDefaultImage(ImageView view, int extent, boolean darkTheme) {
             if (sDrawable == null) {
                 Context context = view.getContext();
                 sDrawable = new ColorDrawable(context.getResources().getColor(
@@ -98,7 +132,7 @@
         }
     }
 
-    public static final DefaultImageProvider DEFAULT_AVATER = new AvatarDefaultImageProvider();
+    public static final DefaultImageProvider DEFAULT_AVATAR = new AvatarDefaultImageProvider();
 
     public static final DefaultImageProvider DEFAULT_BLANK = new BlankDefaultImageProvider();
 
@@ -122,35 +156,53 @@
     }
 
     /**
-     * Load photo into the supplied image view.  If the photo is already cached,
+     * Load thumbnail image into the supplied image view. If the photo is already cached,
      * it is displayed immediately.  Otherwise a request is sent to load the photo
      * from the database.
      */
-    public abstract void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme,
+    public abstract void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
             DefaultImageProvider defaultProvider);
 
     /**
-     * Calls {@link #loadPhoto(ImageView, long, boolean, boolean, DefaultImageProvider)} with
-     * {@link #DEFAULT_AVATER}.
+     * Calls {@link #loadThumbnail(ImageView, long, boolean, DefaultImageProvider)} with
+     * {@link #DEFAULT_AVATAR}.
      */
-    public final void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme) {
-        loadPhoto(view, photoId, hires, darkTheme, DEFAULT_AVATER);
+    public final void loadThumbnail(ImageView view, long photoId, boolean darkTheme) {
+        loadThumbnail(view, photoId, darkTheme, DEFAULT_AVATAR);
     }
 
     /**
-     * Load photo into the supplied image view.  If the photo is already cached,
-     * it is displayed immediately.  Otherwise a request is sent to load the photo
+     * Load photo into the supplied image view. If the photo is already cached,
+     * it is displayed immediately. Otherwise a request is sent to load the photo
      * from the location specified by the URI.
+     * @param view The target view
+     * @param photoUri The uri of the photo to load
+     * @param requestedExtent Specifies an approximate Max(width, height) of the targetView.
+     * This is useful if the source image can be a lot bigger that the target, so that the decoding
+     * is done using efficient sampling. If requestedExtent is specified, no sampling of the image
+     * is performed
+     * @param darkTheme Whether the background is dark. This is used for default avatars
+     * @param defaultProvider The provider of default avatars (this is used if photoUri doesn't
+     * refer to an existing image)
      */
-    public abstract void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme,
-            DefaultImageProvider defaultProvider);
+    public abstract void loadPhoto(ImageView view, Uri photoUri, int requestedExtent,
+            boolean darkTheme, DefaultImageProvider defaultProvider);
 
     /**
      * Calls {@link #loadPhoto(ImageView, Uri, boolean, boolean, DefaultImageProvider)} with
-     * {@link #DEFAULT_AVATER}.
+     * {@link #DEFAULT_AVATAR}.
      */
-    public final void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme) {
-        loadPhoto(view, photoUri, hires, darkTheme, DEFAULT_AVATER);
+    public final void loadPhoto(ImageView view, Uri photoUri, int requestedExtent,
+            boolean darkTheme) {
+        loadPhoto(view, photoUri, requestedExtent, darkTheme, DEFAULT_AVATAR);
+    }
+
+    /**
+     * Calls {@link #loadPhoto(ImageView, Uri, boolean, boolean, DefaultImageProvider)} with
+     * {@link #DEFAULT_AVATAR} and with the assumption, that the image is a thumbnail
+     */
+    public final void loadDirectoryPhoto(ImageView view, Uri photoUri, boolean darkTheme) {
+        loadPhoto(view, photoUri, -1, darkTheme, DEFAULT_AVATAR);
     }
 
     /**
@@ -177,6 +229,14 @@
     public abstract void refreshCache();
 
     /**
+     * Stores the given bitmap directly in the LRU bitmap cache.
+     * @param photoUri The URI of the photo (for future requests).
+     * @param bitmap The bitmap.
+     * @param photoBytes The bytes that were parsed to create the bitmap.
+     */
+    public abstract void cacheBitmap(Uri photoUri, Bitmap bitmap, byte[] photoBytes);
+
+    /**
      * Initiates a background process that over time will fill up cache with
      * preload photos.
      */
@@ -201,6 +261,8 @@
 class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback {
     private static final String LOADER_THREAD_NAME = "ContactPhotoLoader";
 
+    private static final int FADE_TRANSITION_DURATION = 200;
+
     /**
      * Type of message sent by the UI thread to itself to indicate that some photos
      * need to be loaded.
@@ -222,14 +284,17 @@
      */
     private static class BitmapHolder {
         final byte[] bytes;
+        final int originalSmallerExtent;
 
         volatile boolean fresh;
         Bitmap bitmap;
         Reference<Bitmap> bitmapRef;
+        int decodedSampleSize;
 
-        public BitmapHolder(byte[] bytes) {
+        public BitmapHolder(byte[] bytes, int originalSmallerExtent) {
             this.bytes = bytes;
             this.fresh = true;
+            this.originalSmallerExtent = originalSmallerExtent;
         }
     }
 
@@ -243,6 +308,11 @@
     private final LruCache<Object, BitmapHolder> mBitmapHolderCache;
 
     /**
+     * {@code true} if ALL entries in {@link #mBitmapHolderCache} are NOT fresh.
+     */
+    private volatile boolean mBitmapHolderCacheAllUnfresh = true;
+
+    /**
      * Cache size threshold at which bitmaps will not be preloaded.
      */
     private final int mBitmapHolderCacheRedZoneBytes;
@@ -400,35 +470,35 @@
     }
 
     @Override
-    public void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme,
+    public void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
             DefaultImageProvider defaultProvider) {
         if (photoId == 0) {
             // No photo is needed
-            defaultProvider.applyDefaultImage(view, hires, darkTheme);
+            defaultProvider.applyDefaultImage(view, -1, darkTheme);
             mPendingRequests.remove(view);
         } else {
             if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoId);
-            loadPhotoByIdOrUri(view, Request.createFromId(photoId, hires, darkTheme,
+            loadPhotoByIdOrUri(view, Request.createFromThumbnailId(photoId, darkTheme,
                     defaultProvider));
         }
     }
 
     @Override
-    public void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme,
+    public void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme,
             DefaultImageProvider defaultProvider) {
         if (photoUri == null) {
             // No photo is needed
-            defaultProvider.applyDefaultImage(view, hires, darkTheme);
+            defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme);
             mPendingRequests.remove(view);
         } else {
             if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoUri);
-            loadPhotoByIdOrUri(view, Request.createFromUri(photoUri, hires, darkTheme,
+            loadPhotoByIdOrUri(view, Request.createFromUri(photoUri, requestedExtent, darkTheme,
                     defaultProvider));
         }
     }
 
     private void loadPhotoByIdOrUri(ImageView view, Request request) {
-        boolean loaded = loadCachedPhoto(view, request);
+        boolean loaded = loadCachedPhoto(view, request, false);
         if (loaded) {
             mPendingRequests.remove(view);
         } else {
@@ -448,7 +518,12 @@
 
     @Override
     public void refreshCache() {
+        if (mBitmapHolderCacheAllUnfresh) {
+            if (DEBUG) Log.d(TAG, "refreshCache -- no fresh entries.");
+            return;
+        }
         if (DEBUG) Log.d(TAG, "refreshCache");
+        mBitmapHolderCacheAllUnfresh = true;
         for (BitmapHolder holder : mBitmapHolderCache.snapshot().values()) {
             holder.fresh = false;
         }
@@ -459,10 +534,10 @@
      *
      * @return false if the photo needs to be (re)loaded from the provider.
      */
-    private boolean loadCachedPhoto(ImageView view, Request request) {
+    private boolean loadCachedPhoto(ImageView view, Request request, boolean fadeIn) {
         BitmapHolder holder = mBitmapHolderCache.get(request.getKey());
         if (holder == null) {
-            // The bitmap has not been loaded - should display the placeholder image.
+            // The bitmap has not been loaded ==> show default avatar
             request.applyDefaultImage(view);
             return false;
         }
@@ -472,14 +547,45 @@
             return holder.fresh;
         }
 
-        // Optionally decode bytes into a bitmap
-        inflateBitmap(holder);
+        Bitmap cachedBitmap = holder.bitmapRef == null ? null : holder.bitmapRef.get();
+        if (cachedBitmap == null) {
+            if (holder.bytes.length < 8 * 1024) {
+                // Small thumbnails are usually quick to inflate. Let's do that on the UI thread
+                inflateBitmap(holder, request.getRequestedExtent());
+                cachedBitmap = holder.bitmap;
+                if (cachedBitmap == null) return false;
+            } else {
+                // This is bigger data. Let's send that back to the Loader so that we can
+                // inflate this in the background
+                request.applyDefaultImage(view);
+                return false;
+            }
+        }
 
-        view.setImageBitmap(holder.bitmap);
+        final Drawable previousDrawable = view.getDrawable();
+        if (fadeIn && previousDrawable != null) {
+            final Drawable[] layers = new Drawable[2];
+            // Prevent cascade of TransitionDrawables.
+            if (previousDrawable instanceof TransitionDrawable) {
+                final TransitionDrawable previousTransitionDrawable =
+                        (TransitionDrawable) previousDrawable;
+                layers[0] = previousTransitionDrawable.getDrawable(
+                        previousTransitionDrawable.getNumberOfLayers() - 1);
+            } else {
+                layers[0] = previousDrawable;
+            }
+            layers[1] = new BitmapDrawable(mContext.getResources(), cachedBitmap);
+            TransitionDrawable drawable = new TransitionDrawable(layers);
+            view.setImageDrawable(drawable);
+            drawable.startTransition(FADE_TRANSITION_DURATION);
+        } else {
+            view.setImageBitmap(cachedBitmap);
+        }
 
-        if (holder.bitmap != null) {
-            // Put the bitmap in the LRU cache
-            mBitmapCache.put(request, holder.bitmap);
+        // Put the bitmap in the LRU cache. But only do this for images that are small enough
+        // (we require that at least six of those can be cached at the same time)
+        if (cachedBitmap.getByteCount() < mBitmapCache.maxSize() / 6) {
+            mBitmapCache.put(request.getKey(), cachedBitmap);
         }
 
         // Soften the reference
@@ -493,23 +599,45 @@
      * bitmap is held either by {@link #mBitmapCache} or by a soft reference in
      * the holder, it will not be necessary to decode the bitmap.
      */
-    private static void inflateBitmap(BitmapHolder holder) {
+    private static void inflateBitmap(BitmapHolder holder, int requestedExtent) {
+        final int sampleSize =
+                BitmapUtil.findOptimalSampleSize(holder.originalSmallerExtent, requestedExtent);
         byte[] bytes = holder.bytes;
         if (bytes == null || bytes.length == 0) {
             return;
         }
 
-        // Check the soft reference.  If will be retained if the bitmap is also
-        // in the LRU cache, so we don't need to check the LRU cache explicitly.
-        if (holder.bitmapRef != null) {
-            holder.bitmap = holder.bitmapRef.get();
-            if (holder.bitmap != null) {
-                return;
+        if (sampleSize == holder.decodedSampleSize) {
+            // Check the soft reference.  If will be retained if the bitmap is also
+            // in the LRU cache, so we don't need to check the LRU cache explicitly.
+            if (holder.bitmapRef != null) {
+                holder.bitmap = holder.bitmapRef.get();
+                if (holder.bitmap != null) {
+                    return;
+                }
             }
         }
 
         try {
-            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null);
+            Bitmap bitmap = BitmapUtil.decodeBitmapFromBytes(bytes, sampleSize);
+
+            // make bitmap mutable and draw size onto it
+            if (DEBUG_SIZES) {
+                Bitmap original = bitmap;
+                bitmap = bitmap.copy(bitmap.getConfig(), true);
+                original.recycle();
+                Canvas canvas = new Canvas(bitmap);
+                Paint paint = new Paint();
+                paint.setTextSize(16);
+                paint.setColor(Color.BLUE);
+                paint.setStyle(Style.FILL);
+                canvas.drawRect(0.0f, 0.0f, 50.0f, 20.0f, paint);
+                paint.setColor(Color.WHITE);
+                paint.setAntiAlias(true);
+                canvas.drawText(bitmap.getWidth() + "/" + sampleSize, 0, 15, paint);
+            }
+
+            holder.decodedSampleSize = sampleSize;
             holder.bitmap = bitmap;
             holder.bitmapRef = new SoftReference<Bitmap>(bitmap);
             if (DEBUG) {
@@ -598,7 +726,7 @@
         while (iterator.hasNext()) {
             ImageView view = iterator.next();
             Request key = mPendingRequests.get(view);
-            boolean loaded = loadCachedPhoto(view, key);
+            boolean loaded = loadCachedPhoto(view, key, true);
             if (loaded) {
                 iterator.remove();
             }
@@ -624,7 +752,7 @@
     /**
      * Stores the supplied bitmap in cache.
      */
-    private void cacheBitmap(Object key, byte[] bytes, boolean preloading) {
+    private void cacheBitmap(Object key, byte[] bytes, boolean preloading, int requestedExtent) {
         if (DEBUG) {
             BitmapHolder prev = mBitmapHolderCache.get(key);
             if (prev != null && prev.bytes != null) {
@@ -635,29 +763,47 @@
                     mStaleCacheOverwrite.incrementAndGet();
                 }
             }
-            Log.d(TAG, "Caching data: key=" + key + ", " + btk(bytes.length));
+            Log.d(TAG, "Caching data: key=" + key + ", " +
+                    (bytes == null ? "<null>" : btk(bytes.length)));
         }
-        BitmapHolder holder = new BitmapHolder(bytes);
-        holder.fresh = true;
+        BitmapHolder holder = new BitmapHolder(bytes,
+                bytes == null ? -1 : BitmapUtil.getSmallerExtentFromBytes(bytes));
 
         // Unless this image is being preloaded, decode it right away while
         // we are still on the background thread.
         if (!preloading) {
-            inflateBitmap(holder);
+            inflateBitmap(holder, requestedExtent);
         }
 
         mBitmapHolderCache.put(key, holder);
+        mBitmapHolderCacheAllUnfresh = false;
+    }
+
+    @Override
+    public void cacheBitmap(Uri photoUri, Bitmap bitmap, byte[] photoBytes) {
+        final int smallerExtent = Math.min(bitmap.getWidth(), bitmap.getHeight());
+        // We can pretend here that the extent of the photo was the size that we originally
+        // requested
+        Request request = Request.createFromUri(photoUri, smallerExtent, false, DEFAULT_AVATAR);
+        BitmapHolder holder = new BitmapHolder(photoBytes, smallerExtent);
+        holder.bitmapRef = new SoftReference<Bitmap>(bitmap);
+        mBitmapHolderCache.put(request.getKey(), holder);
+        mBitmapHolderCacheAllUnfresh = false;
+        mBitmapCache.put(request.getKey(), bitmap);
     }
 
     /**
-     * Populates an array of photo IDs that need to be loaded.
+     * Populates an array of photo IDs that need to be loaded. Also decodes bitmaps that we have
+     * already loaded
      */
     private void obtainPhotoIdsAndUrisToLoad(Set<Long> photoIds,
-            Set<String> photoIdsAsStrings, Set<Uri> uris) {
+            Set<String> photoIdsAsStrings, Set<Request> uris) {
         photoIds.clear();
         photoIdsAsStrings.clear();
         uris.clear();
 
+        boolean jpegsDecoded = false;
+
         /*
          * Since the call is made from the loader thread, the map could be
          * changing during the iteration. That's not really a problem:
@@ -669,16 +815,25 @@
         Iterator<Request> iterator = mPendingRequests.values().iterator();
         while (iterator.hasNext()) {
             Request request = iterator.next();
-            BitmapHolder holder = mBitmapHolderCache.get(request);
-            if (holder == null || !holder.fresh) {
-                if (request.isUriRequest()) {
-                    uris.add(request.mUri);
-                } else {
-                    photoIds.add(request.mId);
-                    photoIdsAsStrings.add(String.valueOf(request.mId));
+            final BitmapHolder holder = mBitmapHolderCache.get(request.getKey());
+            if (holder != null && holder.bytes != null && holder.fresh &&
+                    (holder.bitmapRef == null || holder.bitmapRef.get() == null)) {
+                // This was previously loaded but we don't currently have the inflated Bitmap
+                inflateBitmap(holder, request.getRequestedExtent());
+                jpegsDecoded = true;
+            } else {
+                if (holder == null || !holder.fresh) {
+                    if (request.isUriRequest()) {
+                        uris.add(request);
+                    } else {
+                        photoIds.add(request.getId());
+                        photoIdsAsStrings.add(String.valueOf(request.mId));
+                    }
                 }
             }
         }
+
+        if (jpegsDecoded) mMainThreadHandler.sendEmptyMessage(MESSAGE_PHOTOS_LOADED);
     }
 
     /**
@@ -709,7 +864,7 @@
         private final StringBuilder mStringBuilder = new StringBuilder();
         private final Set<Long> mPhotoIds = Sets.newHashSet();
         private final Set<String> mPhotoIdsAsStrings = Sets.newHashSet();
-        private final Set<Uri> mPhotoUris = Sets.newHashSet();
+        private final Set<Request> mPhotoUris = Sets.newHashSet();
         private final List<Long> mPreloadPhotoIds = Lists.newArrayList();
 
         private Handler mLoaderThreadHandler;
@@ -822,7 +977,7 @@
                 mPreloadPhotoIds.remove(preloadSize);
             }
 
-            loadPhotosFromDatabase(true);
+            loadThumbnails(true);
 
             if (preloadSize == 0) {
                 mPreloadStatus = PRELOAD_STATUS_DONE;
@@ -863,12 +1018,13 @@
 
         private void loadPhotosInBackground() {
             obtainPhotoIdsAndUrisToLoad(mPhotoIds, mPhotoIdsAsStrings, mPhotoUris);
-            loadPhotosFromDatabase(false);
-            loadRemotePhotos();
+            loadThumbnails(false);
+            loadUriBasedPhotos();
             requestPreloading();
         }
 
-        private void loadPhotosFromDatabase(boolean preloading) {
+        /** Loads thumbnail photos with ids */
+        private void loadThumbnails(boolean preloading) {
             if (mPhotoIds.isEmpty()) {
                 return;
             }
@@ -907,7 +1063,7 @@
                     while (cursor.moveToNext()) {
                         Long id = cursor.getLong(0);
                         byte[] bytes = cursor.getBlob(1);
-                        cacheBitmap(id, bytes, preloading);
+                        cacheBitmap(id, bytes, preloading, -1);
                         mPhotoIds.remove(id);
                     }
                 }
@@ -927,10 +1083,10 @@
                                 COLUMNS, null, null, null);
                         if (profileCursor != null && profileCursor.moveToFirst()) {
                             cacheBitmap(profileCursor.getLong(0), profileCursor.getBlob(1),
-                                    preloading);
+                                    preloading, -1);
                         } else {
                             // Couldn't load a photo this way either.
-                            cacheBitmap(id, null, preloading);
+                            cacheBitmap(id, null, preloading, -1);
                         }
                     } finally {
                         if (profileCursor != null) {
@@ -939,15 +1095,20 @@
                     }
                 } else {
                     // Not a profile photo and not found - mark the cache accordingly
-                    cacheBitmap(id, null, preloading);
+                    cacheBitmap(id, null, preloading, -1);
                 }
             }
 
             mMainThreadHandler.sendEmptyMessage(MESSAGE_PHOTOS_LOADED);
         }
 
-        private void loadRemotePhotos() {
-            for (Uri uri : mPhotoUris) {
+        /**
+         * Loads photos referenced with Uris. Those can be remote thumbnails
+         * (from directory searches), display photos etc
+         */
+        private void loadUriBasedPhotos() {
+            for (Request uriRequest : mPhotoUris) {
+                Uri uri = uriRequest.getUri();
                 if (mBuffer == null) {
                     mBuffer = new byte[BUFFER_SIZE];
                 }
@@ -964,15 +1125,16 @@
                         } finally {
                             is.close();
                         }
-                        cacheBitmap(uri, baos.toByteArray(), false);
+                        cacheBitmap(uri, baos.toByteArray(), false,
+                                uriRequest.getRequestedExtent());
                         mMainThreadHandler.sendEmptyMessage(MESSAGE_PHOTOS_LOADED);
                     } else {
                         Log.v(TAG, "Cannot load photo " + uri);
-                        cacheBitmap(uri, null, false);
+                        cacheBitmap(uri, null, false, uriRequest.getRequestedExtent());
                     }
                 } catch (Exception ex) {
                     Log.v(TAG, "Cannot load photo " + uri, ex);
-                    cacheBitmap(uri, null, false);
+                    cacheBitmap(uri, null, false, uriRequest.getRequestedExtent());
                 }
             }
         }
@@ -986,57 +1148,68 @@
         private final long mId;
         private final Uri mUri;
         private final boolean mDarkTheme;
-        private final boolean mHires;
+        private final int mRequestedExtent;
         private final DefaultImageProvider mDefaultProvider;
 
-        private Request(long id, Uri uri, boolean hires, boolean darkTheme,
+        private Request(long id, Uri uri, int requestedExtent, boolean darkTheme,
                 DefaultImageProvider defaultProvider) {
             mId = id;
             mUri = uri;
             mDarkTheme = darkTheme;
-            mHires = hires;
+            mRequestedExtent = requestedExtent;
             mDefaultProvider = defaultProvider;
         }
 
-        public static Request createFromId(long id, boolean hires, boolean darkTheme,
+        public static Request createFromThumbnailId(long id, boolean darkTheme,
                 DefaultImageProvider defaultProvider) {
-            return new Request(id, null /* no URI */, hires, darkTheme, defaultProvider);
+            return new Request(id, null /* no URI */, -1, darkTheme, defaultProvider);
         }
 
-        public static Request createFromUri(Uri uri, boolean hires, boolean darkTheme,
+        public static Request createFromUri(Uri uri, int requestedExtent, boolean darkTheme,
                 DefaultImageProvider defaultProvider) {
-            return new Request(0 /* no ID */, uri, hires, darkTheme, defaultProvider);
-        }
-
-        public boolean isDarkTheme() {
-            return mDarkTheme;
-        }
-
-        public boolean isHires() {
-            return mHires;
+            return new Request(0 /* no ID */, uri, requestedExtent, darkTheme, defaultProvider);
         }
 
         public boolean isUriRequest() {
             return mUri != null;
         }
 
-        @Override
-        public int hashCode() {
-            if (mUri != null) return mUri.hashCode();
+        public Uri getUri() {
+            return mUri;
+        }
 
-            // copied over from Long.hashCode()
-            return (int) (mId ^ (mId >>> 32));
+        public long getId() {
+            return mId;
+        }
+
+        public int getRequestedExtent() {
+            return mRequestedExtent;
         }
 
         @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof Request)) return false;
-            final Request that = (Request) o;
-            // Don't compare equality of mHires and mDarkTheme fields because these are only used
-            // in the default contact photo case. When the contact does have a photo, the contact
-            // photo is the same regardless of mHires and mDarkTheme, so we shouldn't need to put
-            // the photo request on the queue twice.
-            return mId == that.mId && UriUtils.areEqual(mUri, that.mUri);
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + (int) (mId ^ (mId >>> 32));
+            result = prime * result + mRequestedExtent;
+            result = prime * result + ((mUri == null) ? 0 : mUri.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            if (obj == null) return false;
+            if (getClass() != obj.getClass()) return false;
+            final Request that = (Request) obj;
+            if (mId != that.mId) return false;
+            if (mRequestedExtent != that.mRequestedExtent) return false;
+            if (!UriUtils.areEqual(mUri, that.mUri)) return false;
+            // Don't compare equality of mDarkTheme because it is only used in the default contact
+            // photo case. When the contact does have a photo, the contact photo is the same
+            // regardless of mDarkTheme, so we shouldn't need to put the photo request on the queue
+            // twice.
+            return true;
         }
 
         public Object getKey() {
@@ -1044,7 +1217,7 @@
         }
 
         public void applyDefaultImage(ImageView view) {
-            mDefaultProvider.applyDefaultImage(view, mHires, mDarkTheme);
+            mDefaultProvider.applyDefaultImage(view, mRequestedExtent, mDarkTheme);
         }
     }
 }
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index be84cc4..b8bf45f 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -21,6 +21,7 @@
 import com.android.contacts.model.EntityDelta;
 import com.android.contacts.model.EntityDeltaList;
 import com.android.contacts.model.EntityModifier;
+import com.android.contacts.util.CallerInfoCacheUtils;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Sets;
 
@@ -37,6 +38,7 @@
 import android.content.OperationApplicationException;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcelable;
@@ -53,6 +55,10 @@
 import android.util.Log;
 import android.widget.Toast;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -80,6 +86,7 @@
     public static final String EXTRA_SAVE_MODE = "saveMode";
     public static final String EXTRA_SAVE_IS_PROFILE = "saveIsProfile";
     public static final String EXTRA_SAVE_SUCCEEDED = "saveSucceeded";
+    public static final String EXTRA_UPDATED_PHOTOS = "updatedPhotos";
 
     public static final String ACTION_CREATE_GROUP = "createGroup";
     public static final String ACTION_RENAME_GROUP = "renameGroup";
@@ -171,11 +178,15 @@
 
     @Override
     protected void onHandleIntent(Intent intent) {
+        // Call an appropriate method. If we're sure it affects how incoming phone calls are
+        // handled, then notify the fact to in-call screen.
         String action = intent.getAction();
         if (ACTION_NEW_RAW_CONTACT.equals(action)) {
             createRawContact(intent);
+            CallerInfoCacheUtils.sendUpdateCallerInfoCacheIntent(this);
         } else if (ACTION_SAVE_CONTACT.equals(action)) {
             saveContact(intent);
+            CallerInfoCacheUtils.sendUpdateCallerInfoCacheIntent(this);
         } else if (ACTION_CREATE_GROUP.equals(action)) {
             createGroup(intent);
         } else if (ACTION_RENAME_GROUP.equals(action)) {
@@ -192,12 +203,16 @@
             clearPrimary(intent);
         } else if (ACTION_DELETE_CONTACT.equals(action)) {
             deleteContact(intent);
+            CallerInfoCacheUtils.sendUpdateCallerInfoCacheIntent(this);
         } else if (ACTION_JOIN_CONTACTS.equals(action)) {
             joinContacts(intent);
+            CallerInfoCacheUtils.sendUpdateCallerInfoCacheIntent(this);
         } else if (ACTION_SET_SEND_TO_VOICEMAIL.equals(action)) {
             setSendToVoicemail(intent);
+            CallerInfoCacheUtils.sendUpdateCallerInfoCacheIntent(this);
         } else if (ACTION_SET_RINGTONE.equals(action)) {
             setRingtone(intent);
+            CallerInfoCacheUtils.sendUpdateCallerInfoCacheIntent(this);
         }
     }
 
@@ -207,7 +222,7 @@
      */
     public static Intent createNewRawContactIntent(Context context,
             ArrayList<ContentValues> values, AccountWithDataSet account,
-            Class<?> callbackActivity, String callbackAction) {
+            Class<? extends Activity> callbackActivity, String callbackAction) {
         Intent serviceIntent = new Intent(
                 context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_NEW_RAW_CONTACT);
@@ -269,30 +284,57 @@
     /**
      * Creates an intent that can be sent to this service to create a new raw contact
      * using data presented as a set of ContentValues.
+     * This variant is more convenient to use when there is only one photo that can
+     * possibly be updated, as in the Contact Details screen.
+     * @param rawContactId identifies a writable raw-contact whose photo is to be updated.
+     * @param updatedPhotoPath denotes a temporary file containing the contact's new photo.
      */
     public static Intent createSaveContactIntent(Context context, EntityDeltaList state,
-            String saveModeExtraKey, int saveMode, boolean isProfile, Class<?> callbackActivity,
-            String callbackAction) {
+            String saveModeExtraKey, int saveMode, boolean isProfile,
+            Class<? extends Activity> callbackActivity, String callbackAction, long rawContactId,
+            String updatedPhotoPath) {
+        Bundle bundle = new Bundle();
+        bundle.putString(String.valueOf(rawContactId), updatedPhotoPath);
+        return createSaveContactIntent(context, state, saveModeExtraKey, saveMode, isProfile,
+                callbackActivity, callbackAction, bundle);
+    }
+
+    /**
+     * Creates an intent that can be sent to this service to create a new raw contact
+     * using data presented as a set of ContentValues.
+     * This variant is used when multiple contacts' photos may be updated, as in the
+     * Contact Editor.
+     * @param updatedPhotos maps each raw-contact's ID to the file-path of the new photo.
+     */
+    public static Intent createSaveContactIntent(Context context, EntityDeltaList state,
+            String saveModeExtraKey, int saveMode, boolean isProfile,
+            Class<? extends Activity> callbackActivity, String callbackAction,
+            Bundle updatedPhotos) {
         Intent serviceIntent = new Intent(
                 context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_SAVE_CONTACT);
         serviceIntent.putExtra(EXTRA_CONTACT_STATE, (Parcelable) state);
         serviceIntent.putExtra(EXTRA_SAVE_IS_PROFILE, isProfile);
+        if (updatedPhotos != null) {
+            serviceIntent.putExtra(EXTRA_UPDATED_PHOTOS, (Parcelable) updatedPhotos);
+        }
 
-        // Callback intent will be invoked by the service once the contact is
-        // saved.  The service will put the URI of the new contact as "data" on
-        // the callback intent.
-        Intent callbackIntent = new Intent(context, callbackActivity);
-        callbackIntent.putExtra(saveModeExtraKey, saveMode);
-        callbackIntent.setAction(callbackAction);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent);
+        if (callbackActivity != null) {
+            // Callback intent will be invoked by the service once the contact is
+            // saved.  The service will put the URI of the new contact as "data" on
+            // the callback intent.
+            Intent callbackIntent = new Intent(context, callbackActivity);
+            callbackIntent.putExtra(saveModeExtraKey, saveMode);
+            callbackIntent.setAction(callbackAction);
+            serviceIntent.putExtra(ContactSaveService.EXTRA_CALLBACK_INTENT, callbackIntent);
+        }
         return serviceIntent;
     }
 
     private void saveContact(Intent intent) {
         EntityDeltaList state = intent.getParcelableExtra(EXTRA_CONTACT_STATE);
-        Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
         boolean isProfile = intent.getBooleanExtra(EXTRA_SAVE_IS_PROFILE, false);
+        Bundle updatedPhotos = intent.getParcelableExtra(EXTRA_UPDATED_PHOTOS);
 
         // Trim any empty fields, and RawContacts, before persisting
         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
@@ -301,6 +343,10 @@
         Uri lookupUri = null;
 
         final ContentResolver resolver = getContentResolver();
+        boolean succeeded = false;
+
+        // Keep track of the id of a newly raw-contact (if any... there can be at most one).
+        long insertedRawContactId = -1;
 
         // Attempt to persist changes
         int tries = 0;
@@ -324,6 +370,9 @@
                 if (rawContactId == -1) {
                     throw new IllegalStateException("Could not determine RawContact ID after save");
                 }
+                // We don't have to check to see if the value is still -1.  If we reach here,
+                // the previous loop iteration didn't succeed, so any ID that we obtained is bogus.
+                insertedRawContactId = getInsertedRawContactId(diff, results);
                 if (isProfile) {
                     // Since the profile supports local raw contacts, which may have been completely
                     // removed if all information was removed, we need to do a special query to
@@ -346,10 +395,9 @@
                     lookupUri = RawContacts.getContactLookupUri(resolver, rawContactUri);
                 }
                 Log.v(TAG, "Saved contact. New URI: " + lookupUri);
-                // Mark the intent to indicate that the save was successful (even if the lookup URI
-                // is now null).  For local contacts or the local profile, it's possible that the
-                // save triggered removal of the contact, so no lookup URI would exist..
-                callbackIntent.putExtra(EXTRA_SAVE_SUCCEEDED, true);
+
+                // We can change this back to false later, if we fail to save the contact photo.
+                succeeded = true;
                 break;
 
             } catch (RemoteException e) {
@@ -395,19 +443,98 @@
             }
         }
 
-        callbackIntent.setData(lookupUri);
+        // Now save any updated photos.  We do this at the end to ensure that
+        // the ContactProvider already knows about newly-created contacts.
+        if (updatedPhotos != null) {
+            for (String key : updatedPhotos.keySet()) {
+                String photoFilePath = updatedPhotos.getString(key);
+                long rawContactId = Long.parseLong(key);
 
-        deliverCallback(callbackIntent);
+                // If the raw-contact ID is negative, we are saving a new raw-contact;
+                // replace the bogus ID with the new one that we actually saved the contact at.
+                if (rawContactId < 0) {
+                    rawContactId = insertedRawContactId;
+                    if (rawContactId == -1) {
+                        throw new IllegalStateException(
+                                "Could not determine RawContact ID for image insertion");
+                    }
+                }
+
+                File photoFile = new File(photoFilePath);
+                if (!saveUpdatedPhoto(rawContactId, photoFile)) succeeded = false;
+            }
+        }
+
+        Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
+        if (callbackIntent != null) {
+            if (succeeded) {
+                // Mark the intent to indicate that the save was successful (even if the lookup URI
+                // is now null).  For local contacts or the local profile, it's possible that the
+                // save triggered removal of the contact, so no lookup URI would exist..
+                callbackIntent.putExtra(EXTRA_SAVE_SUCCEEDED, true);
+            }
+            callbackIntent.setData(lookupUri);
+            deliverCallback(callbackIntent);
+        }
     }
 
+    /**
+     * Save updated photo for the specified raw-contact.
+     * @return true for success, false for failure
+     */
+    private boolean saveUpdatedPhoto(long rawContactId, File photoFile) {
+        final Uri outputUri = Uri.withAppendedPath(
+                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
+                RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
+
+        try {
+            final FileOutputStream outputStream = getContentResolver()
+                    .openAssetFileDescriptor(outputUri, "rw").createOutputStream();
+            try {
+                final FileInputStream inputStream = new FileInputStream(photoFile);
+                try {
+                    final byte[] buffer = new byte[16 * 1024];
+                    int length;
+                    int totalLength = 0;
+                    while ((length = inputStream.read(buffer)) > 0) {
+                        outputStream.write(buffer, 0, length);
+                        totalLength += length;
+                    }
+                    Log.v(TAG, "Wrote " + totalLength + " bytes for photo " + photoFile.toString());
+                } finally {
+                    inputStream.close();
+                }
+            } finally {
+                outputStream.close();
+                photoFile.delete();
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to write photo: " + photoFile.toString() + " because: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Find the ID of an existing or newly-inserted raw-contact.  If none exists, return -1.
+     */
     private long getRawContactId(EntityDeltaList state,
             final ArrayList<ContentProviderOperation> diff,
             final ContentProviderResult[] results) {
-        long rawContactId = state.findRawContactId();
-        if (rawContactId != -1) {
-            return rawContactId;
+        long existingRawContactId = state.findRawContactId();
+        if (existingRawContactId != -1) {
+            return existingRawContactId;
         }
 
+        return getInsertedRawContactId(diff, results);
+    }
+
+    /**
+     * Find the ID of a newly-inserted raw-contact.  If none exists, return -1.
+     */
+    private long getInsertedRawContactId(
+            final ArrayList<ContentProviderOperation> diff,
+            final ContentProviderResult[] results) {
         final int diffSize = diff.size();
         for (int i = 0; i < diffSize; i++) {
             ContentProviderOperation operation = diff.get(i);
@@ -433,7 +560,7 @@
      * @param callbackAction is the intent action for the callback intent
      */
     public static Intent createNewGroupIntent(Context context, AccountWithDataSet account,
-            String label, long[] rawContactsToAdd, Class<?> callbackActivity,
+            String label, long[] rawContactsToAdd, Class<? extends Activity> callbackActivity,
             String callbackAction) {
         Intent serviceIntent = new Intent(context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_CREATE_GROUP);
@@ -497,7 +624,7 @@
      * Creates an intent that can be sent to this service to rename a group.
      */
     public static Intent createGroupRenameIntent(Context context, long groupId, String newLabel,
-            Class<?> callbackActivity, String callbackAction) {
+            Class<? extends Activity> callbackActivity, String callbackAction) {
         Intent serviceIntent = new Intent(context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_RENAME_GROUP);
         serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_ID, groupId);
@@ -568,7 +695,7 @@
      */
     public static Intent createGroupUpdateIntent(Context context, long groupId, String newLabel,
             long[] rawContactsToAdd, long[] rawContactsToRemove,
-            Class<?> callbackActivity, String callbackAction) {
+            Class<? extends Activity> callbackActivity, String callbackAction) {
         Intent serviceIntent = new Intent(context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_UPDATE_GROUP);
         serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_ID, groupId);
@@ -615,7 +742,7 @@
         deliverCallback(callbackIntent);
     }
 
-    private void addMembersToGroup(ContentResolver resolver, long[] rawContactsToAdd,
+    private static void addMembersToGroup(ContentResolver resolver, long[] rawContactsToAdd,
             long groupId) {
         if (rawContactsToAdd == null) {
             return;
@@ -650,9 +777,8 @@
                 }
 
                 // Apply batch
-                ContentProviderResult[] results = null;
                 if (!rawContactOperations.isEmpty()) {
-                    results = resolver.applyBatch(ContactsContract.AUTHORITY, rawContactOperations);
+                    resolver.applyBatch(ContactsContract.AUTHORITY, rawContactOperations);
                 }
             } catch (RemoteException e) {
                 // Something went wrong, bail without success
@@ -668,7 +794,7 @@
         }
     }
 
-    private void removeMembersFromGroup(ContentResolver resolver, long[] rawContactsToRemove,
+    private static void removeMembersFromGroup(ContentResolver resolver, long[] rawContactsToRemove,
             long groupId) {
         if (rawContactsToRemove == null) {
             return;
@@ -677,7 +803,7 @@
             // Apply the delete operation on the data row for the given raw contact's
             // membership in the given group. If no contact matches the provided selection, then
             // nothing will be done. Just continue to the next contact.
-            getContentResolver().delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=? AND " +
+            resolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=? AND " +
                     Data.MIMETYPE + "=? AND " + GroupMembership.GROUP_ROW_ID + "=?",
                     new String[] { String.valueOf(rawContactId),
                     GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(groupId)});
@@ -839,7 +965,7 @@
      */
     public static Intent createJoinContactsIntent(Context context, long contactId1,
             long contactId2, boolean contactWritable,
-            Class<?> callbackActivity, String callbackAction) {
+            Class<? extends Activity> callbackActivity, String callbackAction) {
         Intent serviceIntent = new Intent(context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_JOIN_CONTACTS);
         serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_ID1, contactId1);
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index b23dde1..956ce65 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -26,10 +26,13 @@
 import android.app.FragmentManager;
 import android.app.LoaderManager;
 import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.os.AsyncTask;
 import android.os.StrictMode;
 import android.preference.PreferenceManager;
+import android.provider.ContactsContract.Contacts;
 import android.util.Log;
 
 public final class ContactsApplication extends Application {
@@ -120,10 +123,6 @@
             Log.d(Constants.PERFORMANCE_TAG, "ContactsApplication.onCreate start");
         }
 
-        // Priming caches to placate the StrictMode police
-        Context context = getApplicationContext();
-        PreferenceManager.getDefaultSharedPreferences(context);
-        AccountTypeManager.getInstance(context);
         if (ENABLE_FRAGMENT_LOG) FragmentManager.enableDebugLogging(true);
         if (ENABLE_LOADER_LOG) LoaderManager.enableDebugLogging(true);
 
@@ -132,8 +131,30 @@
                     new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
         }
 
+        // Perform the initialization that doesn't have to finish immediately.
+        // We use an async task here just to avoid creating a new thread.
+        (new DelayedInitializer()).execute();
+
         if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
             Log.d(Constants.PERFORMANCE_TAG, "ContactsApplication.onCreate finish");
         }
     }
+
+    private class DelayedInitializer extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected Void doInBackground(Void... params) {
+            final Context context = ContactsApplication.this;
+
+            // Warm up the preferences, the account type manager and the contacts provider.
+            PreferenceManager.getDefaultSharedPreferences(context);
+            AccountTypeManager.getInstance(context);
+            getContentResolver().getType(ContentUris.withAppendedId(Contacts.CONTENT_URI, 1));
+            return null;
+        }
+
+        public void execute() {
+            executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
+                    (Void[]) null);
+        }
+    }
 }
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index cb19713..ca32ff8 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -16,20 +16,24 @@
 
 package com.android.contacts;
 
+import com.android.contacts.activities.DialtactsActivity;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.AccountWithDataSet;
 import com.android.contacts.test.NeededForTesting;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
+import com.android.contacts.util.Constants;
 
 import android.content.Context;
 import android.content.Intent;
+import android.database.Cursor;
 import android.graphics.Rect;
 import android.location.CountryDetector;
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.DisplayPhoto;
+import android.provider.ContactsContract.QuickContact;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 import android.view.View;
@@ -41,6 +45,7 @@
     private static final String TAG = "ContactsUtils";
     private static final String WAIT_SYMBOL_AS_STRING = String.valueOf(PhoneNumberUtils.WAIT);
 
+    private static int sThumbnailSize = -1;
 
     // TODO find a proper place for the canonical version of these
     public interface ProviderNames {
@@ -123,36 +128,41 @@
         // mimetypes could have more sophisticated matching is the future, e.g. addresses)
         if (!TextUtils.equals(Phone.CONTENT_ITEM_TYPE, mimetype1)) return false;
 
-        // Now do the full phone number thing. split into parts, seperated by waiting symbol
-        // and compare them individually
-        final String[] dataParts1 = data1.toString().split(WAIT_SYMBOL_AS_STRING);
-        final String[] dataParts2 = data2.toString().split(WAIT_SYMBOL_AS_STRING);
-        if (dataParts1.length != dataParts2.length) return false;
-        final PhoneNumberUtil util = PhoneNumberUtil.getInstance();
-        for (int i = 0; i < dataParts1.length; i++) {
-            final String dataPart1 = dataParts1[i];
-            final String dataPart2 = dataParts2[i];
+        return shouldCollapsePhoneNumbers(data1.toString(), data2.toString());
+    }
 
-            // substrings equal? shortcut, don't parse
-            if (TextUtils.equals(dataPart1, dataPart2)) continue;
+    private static final boolean shouldCollapsePhoneNumbers(
+            String number1WithLetters, String number2WithLetters) {
+        final String number1 = PhoneNumberUtils.convertKeypadLettersToDigits(number1WithLetters);
+        final String number2 = PhoneNumberUtils.convertKeypadLettersToDigits(number2WithLetters);
 
-            // do a full parse of the numbers
-            switch (util.isNumberMatch(dataPart1, dataPart2)) {
-                case NOT_A_NUMBER:
-                    // don't understand the numbers? let's play it safe
-                    return false;
-                case NO_MATCH:
-                    return false;
-                case EXACT_MATCH:
-                case SHORT_NSN_MATCH:
-                case NSN_MATCH:
-                    break;
-                default:
-                    throw new IllegalStateException("Unknown result value from phone number " +
-                            "library");
+        int index1 = 0;
+        int index2 = 0;
+        for (;;) {
+            // Skip formatting characters.
+            while (index1 < number1.length() &&
+                    !PhoneNumberUtils.isNonSeparator(number1.charAt(index1))) {
+                index1++;
             }
+            while (index2 < number2.length() &&
+                    !PhoneNumberUtils.isNonSeparator(number2.charAt(index2))) {
+                index2++;
+            }
+            // If both have finished, match.  If only one has finished, not match.
+            final boolean number1End = (index1 == number1.length());
+            final boolean number2End = (index2 == number2.length());
+            if (number1End) {
+                return number2End;
+            }
+            if (number2End) return false;
+
+            // If the non-formatting characters are different, not match.
+            if (number1.charAt(index1) != number2.charAt(index2)) return false;
+
+            // Go to the next characters.
+            index1++;
+            index2++;
         }
-        return true;
     }
 
     /**
@@ -194,16 +204,16 @@
      * Returns the intent to launch for the given invitable account type and contact lookup URI.
      * This will return null if the account type is not invitable (i.e. there is no
      * {@link AccountType#getInviteContactActivityClassName()} or
-     * {@link AccountType#resPackageName}).
+     * {@link AccountType#syncAdapterPackageName}).
      */
     public static Intent getInvitableIntent(AccountType accountType, Uri lookupUri) {
-        String resPackageName = accountType.resPackageName;
+        String syncAdapterPackageName = accountType.syncAdapterPackageName;
         String className = accountType.getInviteContactActivityClassName();
-        if (TextUtils.isEmpty(resPackageName) || TextUtils.isEmpty(className)) {
+        if (TextUtils.isEmpty(syncAdapterPackageName) || TextUtils.isEmpty(className)) {
             return null;
         }
         Intent intent = new Intent();
-        intent.setClassName(resPackageName, className);
+        intent.setClassName(syncAdapterPackageName, className);
 
         intent.setAction(ContactsContract.Intents.INVITE_CONTACT);
 
@@ -213,6 +223,67 @@
     }
 
     /**
+     * Return Uri with an appropriate scheme, accepting Voicemail, SIP, and usual phone call
+     * numbers.
+     */
+    public static Uri getCallUri(String number) {
+        if (PhoneNumberUtils.isVoiceMailNumber(number)) {
+            return Uri.parse("voicemail:");
+        }
+        if (PhoneNumberUtils.isUriNumber(number)) {
+             return Uri.fromParts(Constants.SCHEME_SIP, number, null);
+        }
+        return Uri.fromParts(Constants.SCHEME_TEL, number, null);
+     }
+
+    /**
+     * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined
+     * automatically.
+     */
+    public static Intent getCallIntent(String number) {
+        return getCallIntent(number, null);
+    }
+
+    /**
+     * Return an Intent for making a phone call. A given Uri will be used as is (without any
+     * sanity check).
+     */
+    public static Intent getCallIntent(Uri uri) {
+        return getCallIntent(uri, null);
+    }
+
+    /**
+     * A variant of {@link #getCallIntent(String)} but also accept a call origin. For more
+     * information about call origin, see comments in Phone package (PhoneApp).
+     */
+    public static Intent getCallIntent(String number, String callOrigin) {
+        return getCallIntent(getCallUri(number), callOrigin);
+    }
+
+    /**
+     * A variant of {@link #getCallIntent(Uri)} but also accept a call origin. For more
+     * information about call origin, see comments in Phone package (PhoneApp).
+     */
+    public static Intent getCallIntent(Uri uri, String callOrigin) {
+        final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (callOrigin != null) {
+            intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin);
+        }
+        return intent;
+    }
+
+    /**
+     * Return an Intent for launching voicemail screen.
+     */
+    public static Intent getVoicemailIntent() {
+        final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                Uri.fromParts("voicemail", "", null));
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
+
+    /**
      * Returns a header view based on the R.layout.list_separator, where the
      * containing {@link TextView} is set using the given textResourceId.
      */
@@ -240,4 +311,24 @@
         rect.bottom = (int) ((pos[1] + view.getHeight()) * appScale + 0.5f);
         return rect;
     }
+
+    /**
+     * Returns the size (width and height) of thumbnail pictures as configured in the provider. This
+     * can safely be called from the UI thread, as the provider can serve this without performing
+     * a database access
+     */
+    public static int getThumbnailSize(Context context) {
+        if (sThumbnailSize == -1) {
+            final Cursor c = context.getContentResolver().query(
+                    DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
+                    new String[] { DisplayPhoto.THUMBNAIL_MAX_DIM }, null, null, null);
+            try {
+                c.moveToFirst();
+                sThumbnailSize = c.getInt(0);
+            } finally {
+                c.close();
+            }
+        }
+        return sThumbnailSize;
+    }
 }
diff --git a/src/com/android/contacts/NfcHandler.java b/src/com/android/contacts/NfcHandler.java
index ee3e002..1ae72be 100644
--- a/src/com/android/contacts/NfcHandler.java
+++ b/src/com/android/contacts/NfcHandler.java
@@ -89,9 +89,8 @@
                     ndefBytes.write(buffer, 0, r);
                 }
 
-                NdefRecord vcardRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
-                        "text/x-vCard".getBytes(), new byte[]{}, ndefBytes.toByteArray());
-                return new NdefMessage(new NdefRecord[] {vcardRecord});
+                NdefRecord record = NdefRecord.createMime("text/x-vcard", ndefBytes.toByteArray());
+                return new NdefMessage(record);
             } catch (IOException e) {
                 Log.e(TAG, "IOException creating vcard.");
                 return null;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 2d75c26..fd950fe 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -18,7 +18,7 @@
 
 import com.android.contacts.calllog.CallTypeHelper;
 import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.format.FormatUtils;
+import com.android.contacts.test.NeededForTesting;
 
 import android.content.res.Resources;
 import android.graphics.Typeface;
@@ -103,6 +103,7 @@
 
         final CharSequence nameText;
         final CharSequence numberText;
+        final CharSequence labelText;
         final CharSequence displayNumber =
             mPhoneNumberHelper.getDisplayNumber(details.number, details.formattedNumber);
         if (TextUtils.isEmpty(details.name)) {
@@ -113,20 +114,17 @@
             } else {
                 numberText = details.geocode;
             }
+            labelText = null;
         } else {
             nameText = details.name;
-            if (numberFormattedLabel != null) {
-                numberText = FormatUtils.applyStyleToSpan(Typeface.BOLD,
-                        numberFormattedLabel + " " + displayNumber, 0,
-                        numberFormattedLabel.length(),
-                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            } else {
-                numberText = displayNumber;
-            }
+            numberText = displayNumber;
+            labelText = numberFormattedLabel;
         }
 
         views.nameView.setText(nameText);
         views.numberView.setText(numberText);
+        views.labelView.setText(labelText);
+        views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE);
     }
 
     /** Sets the text of the header view for the details page of a phone call. */
@@ -144,6 +142,7 @@
         nameView.setText(nameText);
     }
 
+    @NeededForTesting
     public void setCurrentTimeForTest(long currentTimeMillis) {
         mCurrentTimeMillisForTest = currentTimeMillis;
     }
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
index fa06879..ea5a461 100644
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ b/src/com/android/contacts/PhoneCallDetailsViews.java
@@ -31,14 +31,17 @@
     public final CallTypeIconsView callTypeIcons;
     public final TextView callTypeAndDate;
     public final TextView numberView;
+    public final TextView labelView;
 
     private PhoneCallDetailsViews(TextView nameView, View callTypeView,
-            CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView numberView) {
+            CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView numberView,
+            TextView labelView) {
         this.nameView = nameView;
         this.callTypeView = callTypeView;
         this.callTypeIcons = callTypeIcons;
         this.callTypeAndDate = callTypeAndDate;
         this.numberView = numberView;
+        this.labelView = labelView;
     }
 
     /**
@@ -53,7 +56,8 @@
                 view.findViewById(R.id.call_type),
                 (CallTypeIconsView) view.findViewById(R.id.call_type_icons),
                 (TextView) view.findViewById(R.id.call_count_and_date),
-                (TextView) view.findViewById(R.id.number));
+                (TextView) view.findViewById(R.id.number),
+                (TextView) view.findViewById(R.id.label));
     }
 
     public static PhoneCallDetailsViews createForTest(Context context) {
@@ -62,6 +66,7 @@
                 new View(context),
                 new CallTypeIconsView(context),
                 new TextView(context),
+                new TextView(context),
                 new TextView(context));
     }
 }
diff --git a/src/com/android/contacts/SpecialCharSequenceMgr.java b/src/com/android/contacts/SpecialCharSequenceMgr.java
index b5deab8..a889c6d 100644
--- a/src/com/android/contacts/SpecialCharSequenceMgr.java
+++ b/src/com/android/contacts/SpecialCharSequenceMgr.java
@@ -17,6 +17,7 @@
 package com.android.contacts;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.TelephonyCapabilities;
 
 import android.app.AlertDialog;
 import android.app.KeyguardManager;
@@ -28,6 +29,7 @@
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Telephony.Intents;
@@ -54,6 +56,23 @@
     private static final String TAG = "SpecialCharSequenceMgr";
     private static final String MMI_IMEI_DISPLAY = "*#06#";
 
+    /**
+     * Remembers the previous {@link QueryHandler} and cancel the operation when needed, to
+     * prevent possible crash.
+     *
+     * QueryHandler may call {@link ProgressDialog#dismiss()} when the screen is already gone,
+     * which will cause the app crash. This variable enables the class to prevent the crash
+     * on {@link #cleanup()}.
+     *
+     * TODO: Remove this and replace it (and {@link #cleanup()}) with better implementation.
+     * One complication is that we have SpecialCharSequencMgr in Phone package too, which has
+     * *slightly* different implementation. Note that Phone package doesn't have this problem,
+     * so the class on Phone side doesn't have this functionality.
+     * Fundamental fix would be to have one shared implementation and resolve this corner case more
+     * gracefully.
+     */
+    private static QueryHandler sPreviousAdnQueryHandler;
+
     /** This class is never instantiated. */
     private SpecialCharSequenceMgr() {
     }
@@ -83,6 +102,23 @@
     }
 
     /**
+     * Cleanup everything around this class. Must be run inside the main thread.
+     *
+     * This should be called when the screen becomes background.
+     */
+    public static void cleanup() {
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            Log.wtf(TAG, "cleanup() is called outside the main thread");
+            return;
+        }
+
+        if (sPreviousAdnQueryHandler != null) {
+            sPreviousAdnQueryHandler.cancel();
+            sPreviousAdnQueryHandler = null;
+        }
+    }
+
+    /**
      * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
      * If a secret code is encountered an Intent is started with the android_secret_code://<code>
      * URI.
@@ -114,6 +150,13 @@
     static boolean handleAdnEntry(Context context, String input, EditText textField) {
         /* ADN entries are of the form "N(N)(N)#" */
 
+        TelephonyManager telephonyManager =
+                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        if (telephonyManager == null
+                || !TelephonyCapabilities.supportsAdn(telephonyManager.getCurrentPhoneType())) {
+            return false;
+        }
+
         // if the phone is keyguard-restricted, then just ignore this
         // input.  We want to make sure that sim card contacts are NOT
         // exposed unless the phone is unlocked, and this code can be
@@ -164,6 +207,12 @@
                 // run the query.
                 handler.startQuery(ADN_QUERY_TOKEN, sc, Uri.parse("content://icc/adn"),
                         new String[]{ADN_PHONE_NUMBER_COLUMN_NAME}, null, null, null);
+
+                if (sPreviousAdnQueryHandler != null) {
+                    // It is harmless to call cancel() even after the handler's gone.
+                    sPreviousAdnQueryHandler.cancel();
+                }
+                sPreviousAdnQueryHandler = handler;
                 return true;
             } catch (NumberFormatException ex) {
                 // Ignore
@@ -186,15 +235,15 @@
     }
 
     static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) {
-        if (input.equals(MMI_IMEI_DISPLAY)) {
-            int phoneType = ((TelephonyManager)context.getSystemService(
-                    Context.TELEPHONY_SERVICE)).getCurrentPhoneType();
-
+        TelephonyManager telephonyManager =
+                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        if (telephonyManager != null && input.equals(MMI_IMEI_DISPLAY)) {
+            int phoneType = telephonyManager.getCurrentPhoneType();
             if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
-                showIMEIPanel(context, useSystemWindow);
+                showIMEIPanel(context, useSystemWindow, telephonyManager);
                 return true;
             } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
-                showMEIDPanel(context, useSystemWindow);
+                showMEIDPanel(context, useSystemWindow, telephonyManager);
                 return true;
             }
         }
@@ -208,9 +257,9 @@
     // the phone app's TelephonyCapabilities.getDeviceIdLabel() method
     // into the telephony framework, though.)
 
-    static void showIMEIPanel(Context context, boolean useSystemWindow) {
-        String imeiStr = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE))
-                .getDeviceId();
+    private static void showIMEIPanel(Context context, boolean useSystemWindow,
+            TelephonyManager telephonyManager) {
+        String imeiStr = telephonyManager.getDeviceId();
 
         AlertDialog alert = new AlertDialog.Builder(context)
                 .setTitle(R.string.imei)
@@ -220,9 +269,9 @@
                 .show();
     }
 
-    static void showMEIDPanel(Context context, boolean useSystemWindow) {
-        String meidStr = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE))
-                .getDeviceId();
+    private static void showMEIDPanel(Context context, boolean useSystemWindow,
+            TelephonyManager telephonyManager) {
+        String meidStr = telephonyManager.getDeviceId();
 
         AlertDialog alert = new AlertDialog.Builder(context)
                 .setTitle(R.string.meid)
@@ -304,6 +353,8 @@
      */
     private static class QueryHandler extends AsyncQueryHandler {
 
+        private boolean mCanceled;
+
         public QueryHandler(ContentResolver cr) {
             super(cr);
         }
@@ -314,6 +365,11 @@
          */
         @Override
         protected void onQueryComplete(int token, Object cookie, Cursor c) {
+            sPreviousAdnQueryHandler = null;
+            if (mCanceled) {
+                return;
+            }
+
             SimContactQueryCookie sc = (SimContactQueryCookie) cookie;
 
             // close the progress dialog.
@@ -339,5 +395,12 @@
                     .show();
             }
         }
+
+        public void cancel() {
+            mCanceled = true;
+            // Ask AsyncQueryHandler to cancel the whole request. This will fails when the
+            // query already started.
+            cancelOperation(ADN_QUERY_TOKEN);
+        }
     }
 }
diff --git a/src/com/android/contacts/TabStripView.java b/src/com/android/contacts/TabStripView.java
deleted file mode 100644
index 9b875d1..0000000
--- a/src/com/android/contacts/TabStripView.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2009 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.contacts;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewParent;
-import android.widget.HorizontalScrollView;
-import android.widget.LinearLayout;
-
-/** Extension of LinearLayout that takes care of drawing bottom strips over the tab children. */
-public class TabStripView extends LinearLayout {
-
-    private Drawable mBottomLeftStrip;
-    private Drawable mBottomRightStrip;
-    private int mSelectedTabIndex;
-
-    public TabStripView(Context context) {
-        this(context, null);
-    }
-
-    public TabStripView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    private void init() {
-        mGroupFlags |= FLAG_USE_CHILD_DRAWING_ORDER;
-        mBottomLeftStrip = mContext.getResources().getDrawable(
-                R.drawable.tab_bottom);
-        mBottomRightStrip = mContext.getResources().getDrawable(
-                R.drawable.tab_bottom);
-    }
-
-    public void setSelected(int index, boolean selected) {
-        mSelectedTabIndex = index;
-        getChildAt(index).setSelected(selected);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        ViewParent parent = getParent();
-        if (parent instanceof HorizontalScrollView) {
-            setMinimumWidth(((HorizontalScrollView) getParent()).getMeasuredWidth());
-        }
-
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    @Override
-    protected int getChildDrawingOrder(int childCount, int i) {
-        // Always draw the selected tab last, so that drop shadows are drawn
-        // in the correct z-order.
-        if (i == childCount - 1) {
-            return mSelectedTabIndex;
-        } else if (i >= mSelectedTabIndex) {
-            return i + 1;
-        } else {
-            return i;
-        }
-    }
-
-    @Override
-    public void childDrawableStateChanged(View child) {
-        if (child == getChildAt(mSelectedTabIndex)) {
-            // To make sure that the bottom strip is redrawn
-            invalidate();
-        }
-        super.childDrawableStateChanged(child);
-    }
-
-    @Override
-    public void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
-
-        View selectedChild = getChildAt(mSelectedTabIndex);
-
-        mBottomRightStrip.setState(selectedChild.getDrawableState());
-        mBottomLeftStrip.setState(selectedChild.getDrawableState());
-
-        Rect selBounds = new Rect(); // Bounds of the selected tab indicator
-        selBounds.left = selectedChild.getLeft() - getScrollX();
-        selBounds.right = selectedChild.getRight() - getScrollX();
-        final int myHeight = getHeight();
-        mBottomLeftStrip.setBounds(
-                Math.min(0, selBounds.left
-                             - mBottomLeftStrip.getIntrinsicWidth()),
-                myHeight - mBottomLeftStrip.getIntrinsicHeight(),
-                selBounds.left,
-                myHeight);
-        mBottomRightStrip.setBounds(
-                selBounds.right,
-                myHeight - mBottomRightStrip.getIntrinsicHeight(),
-                Math.max(getWidth(),
-                        selBounds.right + mBottomRightStrip.getIntrinsicWidth()),
-                myHeight);
-
-        mBottomLeftStrip.draw(canvas);
-        mBottomRightStrip.draw(canvas);
-    }
-
-}
diff --git a/src/com/android/contacts/ViewNotificationService.java b/src/com/android/contacts/ViewNotificationService.java
new file mode 100644
index 0000000..a85c780
--- /dev/null
+++ b/src/com/android/contacts/ViewNotificationService.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 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.contacts;
+
+import com.android.contacts.ContactLoader.Result;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.Loader.OnLoadCompleteListener;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Service that sends out a view notification for a contact. At the moment, this is only
+ * supposed to be used by the Phone app
+ */
+public class ViewNotificationService extends Service {
+    private static final String TAG = ViewNotificationService.class.getSimpleName();
+
+    private static final boolean DEBUG = false;
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, final int startId) {
+        if (DEBUG) { Log.d(TAG, "onHandleIntent(). Intent: " + intent); }
+
+        // We simply need to start a Loader here. When its done, it will send out the
+        // View-Notification automatically.
+        final ContactLoader contactLoader = new ContactLoader(this, intent.getData(), true);
+        contactLoader.registerListener(0, new OnLoadCompleteListener<ContactLoader.Result>() {
+            @Override
+            public void onLoadComplete(Loader<Result> loader, Result data) {
+                try {
+                    loader.reset();
+                } catch (RuntimeException e) {
+                    Log.e(TAG, "Error reseting loader", e);
+                }
+                try {
+                    // This is not 100% accurate actually. If we get several calls quickly,
+                    // we might be stopping out-of-order, in which case the call with the last
+                    // startId will stop this service. In practice, this shouldn't be a problem,
+                    // as this service is supposed to be called by the Phone app which only sends
+                    // out the notification once per phonecall. And even if there is a problem,
+                    // the worst that should happen is a missing view notification
+                    stopSelfResult(startId);
+                } catch (RuntimeException e) {
+                    Log.e(TAG, "Error stopping service", e);
+                }
+            }
+        });
+        contactLoader.startLoading();
+        return START_REDELIVER_INTENT;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index b90d4c6..4fc9866 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -26,15 +26,19 @@
 import android.app.FragmentTransaction;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.ArrayAdapter;
 import android.widget.SearchView;
 import android.widget.SearchView.OnCloseListener;
 import android.widget.SearchView.OnQueryTextListener;
+import android.widget.TextView;
 
 /**
  * Adapter for the action bar at the top of the Contacts activity.
@@ -42,11 +46,13 @@
 public class ActionBarAdapter implements OnQueryTextListener, OnCloseListener {
 
     public interface Listener {
-        public enum Action {
-            CHANGE_SEARCH_QUERY, START_SEARCH_MODE, STOP_SEARCH_MODE
+        public abstract class Action {
+            public static final int CHANGE_SEARCH_QUERY = 0;
+            public static final int START_SEARCH_MODE = 1;
+            public static final int STOP_SEARCH_MODE = 2;
         }
 
-        void onAction(Action action);
+        void onAction(int action);
 
         /**
          * Called when the user selects a tab.  The new tab can be obtained using
@@ -72,32 +78,51 @@
     private Listener mListener;
 
     private final ActionBar mActionBar;
-    private final MyTabListener mTabListener = new MyTabListener();
+    private final int mActionBarNavigationMode;
+    private final MyTabListener mTabListener;
+    private final MyNavigationListener mNavigationListener;
 
     private boolean mShowHomeIcon;
     private boolean mShowTabsAsText;
 
-    public enum TabState {
-        GROUPS,
-        ALL,
-        FAVORITES;
+    public interface TabState {
+        public static int GROUPS = 0;
+        public static int ALL = 1;
+        public static int FAVORITES = 2;
 
-        public static TabState fromInt(int value) {
-            if (GROUPS.ordinal() == value) {
-                return GROUPS;
-            }
-            if (ALL.ordinal() == value) {
-                return ALL;
-            }
-            if (FAVORITES.ordinal() == value) {
-                return FAVORITES;
-            }
-            throw new IllegalArgumentException("Invalid value: " + value);
-        }
+        public static int COUNT = 3;
+        public static int DEFAULT = ALL;
     }
 
-    private static final TabState DEFAULT_TAB = TabState.ALL;
-    private TabState mCurrentTab = DEFAULT_TAB;
+    private int mCurrentTab = TabState.DEFAULT;
+
+    /**
+     * Extension of ArrayAdapter to be used for the action bar navigation drop list.  It is not
+     * possible to change the text appearance of a text item that is in the spinner header or
+     * in the drop down list using a selector xml file.  The only way to differentiate the two
+     * is if the view is gotten via {@link #getView(int, View, ViewGroup)} or
+     * {@link #getDropDownView(int, View, ViewGroup)}.
+     */
+    private class CustomArrayAdapter extends ArrayAdapter<String> {
+
+        public CustomArrayAdapter(Context context, int textResId) {
+            super(context, textResId);
+        }
+
+        public View getView (int position, View convertView, ViewGroup parent) {
+            TextView textView = (TextView) super.getView(position, convertView, parent);
+            textView.setTextAppearance(mContext,
+                    R.style.PeopleNavigationDropDownHeaderTextAppearance);
+            return textView;
+        }
+
+        public View getDropDownView (int position, View convertView, ViewGroup parent) {
+            TextView textView = (TextView) super.getDropDownView(position, convertView, parent);
+            textView.setTextAppearance(mContext,
+                    R.style.PeopleNavigationDropDownTextAppearance);
+            return textView;
+        }
+    }
 
     public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar,
             boolean isUsingTwoPanes) {
@@ -110,6 +135,15 @@
 
         // On wide screens, show the tabs as text (instead of icons)
         mShowTabsAsText = isUsingTwoPanes;
+        if (isUsingTwoPanes) {
+            mActionBarNavigationMode = ActionBar.NAVIGATION_MODE_LIST;
+            mTabListener = null;
+            mNavigationListener = new MyNavigationListener();
+        } else {
+            mActionBarNavigationMode = ActionBar.NAVIGATION_MODE_TABS;
+            mTabListener = new MyTabListener();
+            mNavigationListener = null;
+        }
 
         // Set up search view.
         View customSearchView = LayoutInflater.from(mActionBar.getThemedContext()).inflate(
@@ -133,12 +167,67 @@
         mSearchView.setQuery(mQueryString, false);
         mActionBar.setCustomView(customSearchView, layoutParams);
 
-        // Set up tabs
+        // Set up tabs or navigation list
+        switch(mActionBarNavigationMode) {
+            case ActionBar.NAVIGATION_MODE_TABS:
+                setupTabs();
+                break;
+            case ActionBar.NAVIGATION_MODE_LIST:
+                setupNavigationList();
+                break;
+        }
+    }
+
+    private void setupTabs() {
         addTab(TabState.GROUPS, R.drawable.ic_tab_groups, R.string.contactsGroupsLabel);
         addTab(TabState.ALL, R.drawable.ic_tab_all, R.string.contactsAllLabel);
         addTab(TabState.FAVORITES, R.drawable.ic_tab_starred, R.string.contactsFavoritesLabel);
     }
 
+    private void setupNavigationList() {
+        ArrayAdapter<String> navAdapter = new CustomArrayAdapter(mContext,
+                R.layout.people_navigation_item);
+        navAdapter.add(mContext.getString(R.string.contactsAllLabel));
+        navAdapter.add(mContext.getString(R.string.contactsFavoritesLabel));
+        navAdapter.add(mContext.getString(R.string.contactsGroupsLabel));
+        mActionBar.setListNavigationCallbacks(navAdapter, mNavigationListener);
+    }
+
+    /**
+     * Because the navigation list items are in a different order than tab items, this returns
+     * the appropriate tab from the navigation item position.
+     */
+    private int getTabPositionFromNavigationItemPosition(int navItemPos) {
+        switch(navItemPos) {
+            case 0:
+                return TabState.ALL;
+            case 1:
+                return TabState.FAVORITES;
+            case 2:
+                return TabState.GROUPS;
+        }
+        throw new IllegalArgumentException(
+                "Parameter must be between 0 and " + Integer.toString(TabState.COUNT-1)
+                + " inclusive.");
+    }
+
+    /**
+     * This is the inverse of {@link getTabPositionFromNavigationItemPosition}.
+     */
+    private int getNavigationItemPositionFromTabPosition(int tabPos) {
+        switch(tabPos) {
+            case TabState.ALL:
+                return 0;
+            case TabState.FAVORITES:
+                return 1;
+            case TabState.GROUPS:
+                return 2;
+        }
+        throw new IllegalArgumentException(
+                "Parameter must be between 0 and " + Integer.toString(TabState.COUNT-1)
+                + " inclusive.");
+    }
+
     public void initialize(Bundle savedState, ContactsRequest request) {
         if (savedState == null) {
             mSearchMode = request.isSearchMode();
@@ -149,18 +238,24 @@
             mQueryString = savedState.getString(EXTRA_KEY_QUERY);
 
             // Just set to the field here.  The listener will be notified by update().
-            mCurrentTab = TabState.fromInt(savedState.getInt(EXTRA_KEY_SELECTED_TAB));
+            mCurrentTab = savedState.getInt(EXTRA_KEY_SELECTED_TAB);
         }
+        // Show tabs or the expanded {@link SearchView}, depending on whether or not we are in
+        // search mode.
         update();
+        // Expanding the {@link SearchView} clears the query, so set the query from the
+        // {@link ContactsRequest} after it has been expanded, if applicable.
+        if (mSearchMode && !TextUtils.isEmpty(mQueryString)) {
+            setQueryString(mQueryString);
+        }
     }
 
     public void setListener(Listener listener) {
         mListener = listener;
     }
 
-    private void addTab(TabState tabState, int icon, int description) {
+    private void addTab(int expectedTabIndex, int icon, int description) {
         final Tab tab = mActionBar.newTab();
-        tab.setTag(tabState);
         tab.setTabListener(mTabListener);
         if (mShowTabsAsText) {
             tab.setText(description);
@@ -169,6 +264,9 @@
             tab.setContentDescription(description);
         }
         mActionBar.addTab(tab);
+        if (expectedTabIndex != tab.getPosition()) {
+            throw new IllegalStateException("Tabs must be created in the right order");
+        }
     }
 
     private class MyTabListener implements ActionBar.TabListener {
@@ -184,39 +282,59 @@
 
         @Override public void onTabSelected(Tab tab, FragmentTransaction ft) {
             if (!mIgnoreTabSelected) {
-                setCurrentTab((TabState)tab.getTag());
+                setCurrentTab(tab.getPosition());
             }
         }
     }
 
+    private class MyNavigationListener implements ActionBar.OnNavigationListener {
+        public boolean mIgnoreNavigationItemSelected;
+
+        public boolean onNavigationItemSelected(int itemPosition, long itemId) {
+            if (!mIgnoreNavigationItemSelected) {
+                setCurrentTab(getTabPositionFromNavigationItemPosition(itemPosition));
+            }
+            return true;
+        }
+    }
+
     /**
      * Change the current tab, and notify the listener.
      */
-    public void setCurrentTab(TabState tab) {
+    public void setCurrentTab(int tab) {
         setCurrentTab(tab, true);
     }
 
     /**
      * Change the current tab
      */
-    public void setCurrentTab(TabState tab, boolean notifyListener) {
-        if (tab == null) throw new NullPointerException();
+    public void setCurrentTab(int tab, boolean notifyListener) {
         if (tab == mCurrentTab) {
             return;
         }
         mCurrentTab = tab;
 
-        int index = mCurrentTab.ordinal();
-        if ((mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS)
-                && (index != mActionBar.getSelectedNavigationIndex())) {
-            mActionBar.setSelectedNavigationItem(index);
+        final int actionBarSelectedNavIndex = mActionBar.getSelectedNavigationIndex();
+        switch(mActionBar.getNavigationMode()) {
+            case ActionBar.NAVIGATION_MODE_TABS:
+                if (mCurrentTab != actionBarSelectedNavIndex) {
+                    mActionBar.setSelectedNavigationItem(mCurrentTab);
+                }
+                break;
+            case ActionBar.NAVIGATION_MODE_LIST:
+                if (mCurrentTab != getTabPositionFromNavigationItemPosition(
+                        actionBarSelectedNavIndex)) {
+                    mActionBar.setSelectedNavigationItem(
+                            getNavigationItemPositionFromTabPosition(mCurrentTab));
+                }
+                break;
         }
 
         if (notifyListener && mListener != null) mListener.onSelectedTabChanged();
         saveLastTabPreference(mCurrentTab);
     }
 
-    public TabState getCurrentTab() {
+    public int getCurrentTab() {
         return mCurrentTab;
     }
 
@@ -242,6 +360,9 @@
             } else {
                 mSearchView.setQuery(null, false);
             }
+        } else if (flag) {
+            // Everything is already set up. Still make sure the keyboard is up
+            if (mSearchView != null) setFocusOnSearchView();
         }
     }
 
@@ -289,11 +410,15 @@
     }
 
     private void update() {
+        boolean isIconifiedChanging = mSearchView.isIconified() == mSearchMode;
         if (mSearchMode) {
             setFocusOnSearchView();
             // Since we have the {@link SearchView} in a custom action bar, we must manually handle
-            // expanding the {@link SearchView} when a search is initiated.
-            mSearchView.onActionViewExpanded();
+            // expanding the {@link SearchView} when a search is initiated. Note that a side effect
+            // of this method is that the {@link SearchView} query text is set to empty string.
+            if (isIconifiedChanging) {
+                mSearchView.onActionViewExpanded();
+            }
             if (mActionBar.getNavigationMode() != ActionBar.NAVIGATION_MODE_STANDARD) {
                 mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
             }
@@ -301,7 +426,9 @@
                 mListener.onAction(Action.START_SEARCH_MODE);
             }
         } else {
-            if (mActionBar.getNavigationMode() != ActionBar.NAVIGATION_MODE_TABS) {
+            final int currentNavigationMode = mActionBar.getNavigationMode();
+            if (mActionBarNavigationMode == ActionBar.NAVIGATION_MODE_TABS
+                    && currentNavigationMode != ActionBar.NAVIGATION_MODE_TABS) {
                 // setNavigationMode will trigger onTabSelected() with the tab which was previously
                 // selected.
                 // The issue is that when we're first switching to the tab navigation mode after
@@ -312,13 +439,22 @@
                 // after this anyway.
                 mTabListener.mIgnoreTabSelected = true;
                 mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-                mActionBar.setSelectedNavigationItem(mCurrentTab.ordinal());
+                mActionBar.setSelectedNavigationItem(mCurrentTab);
                 mTabListener.mIgnoreTabSelected = false;
+            } else if (mActionBarNavigationMode == ActionBar.NAVIGATION_MODE_LIST
+                    && currentNavigationMode != ActionBar.NAVIGATION_MODE_LIST) {
+                mNavigationListener.mIgnoreNavigationItemSelected = true;
+                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+                mActionBar.setSelectedNavigationItem(
+                        getNavigationItemPositionFromTabPosition(mCurrentTab));
+                mNavigationListener.mIgnoreNavigationItemSelected = false;
             }
             mActionBar.setTitle(null);
             // Since we have the {@link SearchView} in a custom action bar, we must manually handle
             // collapsing the {@link SearchView} when search mode is exited.
-            mSearchView.onActionViewCollapsed();
+            if (isIconifiedChanging) {
+                mSearchView.onActionViewCollapsed();
+            }
             if (mListener != null) {
                 mListener.onAction(Action.STOP_SEARCH_MODE);
                 mListener.onSelectedTabChanged();
@@ -371,7 +507,7 @@
     public void onSaveInstanceState(Bundle outState) {
         outState.putBoolean(EXTRA_KEY_SEARCH_MODE, mSearchMode);
         outState.putString(EXTRA_KEY_QUERY, mQueryString);
-        outState.putInt(EXTRA_KEY_SELECTED_TAB, mCurrentTab.ordinal());
+        outState.putInt(EXTRA_KEY_SELECTED_TAB, mCurrentTab);
     }
 
     /**
@@ -386,21 +522,21 @@
         }
     }
 
-    private void setFocusOnSearchView() {
+    public void setFocusOnSearchView() {
         mSearchView.requestFocus();
         mSearchView.setIconified(false); // Workaround for the "IME not popping up" issue.
     }
 
-    private void saveLastTabPreference(TabState tab) {
-        mPrefs.edit().putInt(PERSISTENT_LAST_TAB, tab.ordinal()).apply();
+    private void saveLastTabPreference(int tab) {
+        mPrefs.edit().putInt(PERSISTENT_LAST_TAB, tab).apply();
     }
 
-    private TabState loadLastTabPreference() {
+    private int loadLastTabPreference() {
         try {
-            return TabState.fromInt(mPrefs.getInt(PERSISTENT_LAST_TAB, DEFAULT_TAB.ordinal()));
+            return mPrefs.getInt(PERSISTENT_LAST_TAB, TabState.DEFAULT);
         } catch (IllegalArgumentException e) {
             // Preference is corrupt?
-            return DEFAULT_TAB;
+            return TabState.DEFAULT;
         }
     }
 }
diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index a697c29..7ae6e1e 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -16,31 +16,33 @@
 
 package com.android.contacts.activities;
 
+import com.android.contacts.ContactLoader;
+import com.android.contacts.ContactLoader.Result;
+import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.model.ExchangeAccountType;
-import com.android.contacts.model.GoogleAccountType;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityDeltaList;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.util.ContactPhotoUtils;
 
-import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
 import android.content.Intent;
-import android.content.OperationApplicationException;
+import android.content.Loader;
+import android.content.Loader.OnLoadCompleteListener;
 import android.database.Cursor;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.DisplayPhoto;
-import android.provider.ContactsContract.RawContacts;
-import android.widget.Toast;
+import android.provider.MediaStore;
+import android.util.Log;
 
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
+import java.io.File;
 
 /**
  * Provides an external interface for other applications to attach images
@@ -49,27 +51,40 @@
  * size and give the user a chance to use the face detector.
  */
 public class AttachPhotoActivity extends ContactsActivity {
+    private static final String TAG = AttachPhotoActivity.class.getSimpleName();
+
     private static final int REQUEST_PICK_CONTACT = 1;
     private static final int REQUEST_CROP_PHOTO = 2;
 
-    private static final String RAW_CONTACT_URIS_KEY = "raw_contact_uris";
+    private static final String KEY_CONTACT_URI = "contact_uri";
+    private static final String KEY_TEMP_PHOTO_URI = "temp_photo_uri";
 
-    private Long[] mRawContactIds;
+    private File mTempPhotoFile;
+    private Uri mTempPhotoUri;
 
     private ContentResolver mContentResolver;
 
-    // Height/width (in pixels) to request for the photo - queried from the provider.
+    // Height and width (in pixels) to request for the photo - queried from the provider.
     private static int mPhotoDim;
 
+    private Uri mContactUri;
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
         if (icicle != null) {
-            mRawContactIds = toClassArray(icicle.getLongArray(RAW_CONTACT_URIS_KEY));
+            final String uri = icicle.getString(KEY_CONTACT_URI);
+            mContactUri = (uri == null) ? null : Uri.parse(uri);
+
+            mTempPhotoUri = Uri.parse(icicle.getString(KEY_TEMP_PHOTO_URI));
+            mTempPhotoFile = new File(mTempPhotoUri.getPath());
         } else {
-            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
-            intent.setType(Contacts.CONTENT_ITEM_TYPE);
+            mTempPhotoFile = ContactPhotoUtils.generateTempPhotoFile(this);
+            mTempPhotoUri = Uri.fromFile(mTempPhotoFile);
+
+            Intent intent = new Intent(Intent.ACTION_PICK);
+            intent.setType(Contacts.CONTENT_TYPE);
             startActivityForResult(intent, REQUEST_PICK_CONTACT);
         }
 
@@ -89,32 +104,8 @@
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-
-        if (mRawContactIds != null && mRawContactIds.length != 0) {
-            outState.putLongArray(RAW_CONTACT_URIS_KEY, toPrimativeArray(mRawContactIds));
-        }
-    }
-
-    private static long[] toPrimativeArray(Long[] in) {
-        if (in == null) {
-            return null;
-        }
-        long[] out = new long[in.length];
-        for (int i = 0; i < in.length; i++) {
-            out[i] = in[i];
-        }
-        return out;
-    }
-
-    private static Long[] toClassArray(long[] in) {
-        if (in == null) {
-            return null;
-        }
-        Long[] out = new Long[in.length];
-        for (int i = 0; i < in.length; i++) {
-            out[i] = in[i];
-        }
-        return out;
+        if (mContactUri != null) outState.putString(KEY_CONTACT_URI, mContactUri.toString());
+        outState.putString(KEY_TEMP_PHOTO_URI, mTempPhotoUri.toString());
     }
 
     @Override
@@ -137,147 +128,98 @@
             intent.putExtra("aspectY", 1);
             intent.putExtra("outputX", mPhotoDim);
             intent.putExtra("outputY", mPhotoDim);
-            intent.putExtra("return-data", true);
+            intent.putExtra(MediaStore.EXTRA_OUTPUT, mTempPhotoUri);
+
             startActivityForResult(intent, REQUEST_CROP_PHOTO);
 
-            // while they're cropping, convert the contact into a raw_contact
-            final long contactId = ContentUris.parseId(result.getData());
-            final ArrayList<Long> rawContactIdsList = queryForAllRawContactIds(
-                    mContentResolver, contactId);
-            mRawContactIds = new Long[rawContactIdsList.size()];
-            mRawContactIds = rawContactIdsList.toArray(mRawContactIds);
+            mContactUri = result.getData();
 
-            if (mRawContactIds == null || rawContactIdsList.isEmpty()) {
-                Toast.makeText(this, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
-            }
         } else if (requestCode == REQUEST_CROP_PHOTO) {
-            final Bundle extras = result.getExtras();
-            if (extras != null && mRawContactIds != null) {
-                Bitmap photo = extras.getParcelable("data");
-                if (photo != null) {
-                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
-                    photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);
-
-                    final ContentValues imageValues = new ContentValues();
-                    imageValues.put(Photo.PHOTO, stream.toByteArray());
-                    imageValues.put(RawContacts.Data.IS_SUPER_PRIMARY, 1);
-
-                    // attach the photo to every raw contact
-                    for (Long rawContactId : mRawContactIds) {
-
-                        // exchange and google only allow one image, so do an update rather than insert
-                        boolean shouldUpdate = false;
-
-                        final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI,
-                                rawContactId);
-                        final Uri rawContactDataUri = Uri.withAppendedPath(rawContactUri,
-                                RawContacts.Data.CONTENT_DIRECTORY);
-                        insertPhoto(imageValues, rawContactDataUri, true);
-                    }
+            loadContact(mContactUri, new Listener() {
+                @Override
+                public void onContactLoaded(ContactLoader.Result contact) {
+                    saveContact(contact);
                 }
-            }
-            finish();
+            });
         }
     }
 
-    // TODO: move to background
-    public static ArrayList<Long> queryForAllRawContactIds(ContentResolver cr, long contactId) {
-        Cursor rawContactIdCursor = null;
-        ArrayList<Long> rawContactIds = new ArrayList<Long>();
-        try {
-            rawContactIdCursor = cr.query(RawContacts.CONTENT_URI,
-                    new String[] {RawContacts._ID},
-                    RawContacts.CONTACT_ID + "=" + contactId, null, null);
-            if (rawContactIdCursor != null) {
-                while (rawContactIdCursor.moveToNext()) {
-                    rawContactIds.add(rawContactIdCursor.getLong(0));
+    // TODO: consider moving this to ContactLoader, especially if we keep adding similar
+    // code elsewhere (ViewNotificationService is another case).  The only concern is that,
+    // although this is convenient, it isn't quite as robust as using LoaderManager... for
+    // instance, the loader doesn't persist across Activity restarts.
+    private void loadContact(Uri contactUri, final Listener listener) {
+        final ContactLoader loader = new ContactLoader(this, contactUri, true);
+        loader.registerListener(0, new OnLoadCompleteListener<ContactLoader.Result>() {
+            @Override
+            public void onLoadComplete(
+                    Loader<ContactLoader.Result> loader, ContactLoader.Result contact) {
+                try {
+                    loader.reset();
                 }
+                catch (RuntimeException e) {
+                    Log.e(TAG, "Error resetting loader", e);
+                }
+                listener.onContactLoaded(contact);
             }
-        } finally {
-            if (rawContactIdCursor != null) {
-                rawContactIdCursor.close();
-            }
-        }
-        return rawContactIds;
+        });
+        loader.startLoading();
+    }
+
+    private interface Listener {
+        public void onContactLoaded(Result contact);
     }
 
     /**
-     * Inserts a photo on the raw contact.
-     * @param values the photo values
-     * @param assertAccount if true, will check to verify that no photos exist for Google,
-     *     Exchange and unsynced phone account types. These account types only take one picture,
-     *     so if one exists, the account will be updated with the new photo.
+     * If prerequisites have been met, attach the photo to a raw-contact and save.
+     * The prerequisites are:
+     * - photo has been cropped
+     * - contact has been loaded
      */
-    private void insertPhoto(ContentValues values, Uri rawContactDataUri,
-            boolean assertAccount) {
+    private void saveContact(ContactLoader.Result contact) {
 
-        ArrayList<ContentProviderOperation> operations =
-            new ArrayList<ContentProviderOperation>();
-
-        if (assertAccount) {
-            // Make sure no pictures exist for Google, Exchange and unsynced phone accounts.
-            operations.add(ContentProviderOperation.newAssertQuery(rawContactDataUri)
-                    .withSelection(Photo.MIMETYPE + "=? AND "
-                            + RawContacts.DATA_SET + " IS NULL AND ("
-                            + RawContacts.ACCOUNT_TYPE + " IN (?,?) OR "
-                            + RawContacts.ACCOUNT_TYPE + " IS NULL)",
-                            new String[] {Photo.CONTENT_ITEM_TYPE, GoogleAccountType.ACCOUNT_TYPE,
-                            ExchangeAccountType.ACCOUNT_TYPE})
-                            .withExpectedCount(0).build());
+        // Obtain the raw-contact that we will save to.
+        EntityDeltaList deltaList = contact.createEntityDeltaList();
+        EntityDelta raw = deltaList.getFirstWritableRawContact(this);
+        if (raw == null) {
+            Log.w(TAG, "no writable raw-contact found");
+            return;
         }
 
-        // insert the photo
-        values.put(Photo.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
-        operations.add(ContentProviderOperation.newInsert(rawContactDataUri)
-                .withValues(values).build());
-
-        try {
-            mContentResolver.applyBatch(ContactsContract.AUTHORITY, operations);
-        } catch (RemoteException e) {
-            throw new IllegalStateException("Problem querying raw_contacts/data", e);
-        } catch (OperationApplicationException e) {
-            // the account doesn't allow multiple photos, so update
-            if (assertAccount) {
-                updatePhoto(values, rawContactDataUri, false);
-            } else {
-                throw new IllegalStateException("Problem inserting photo into raw_contacts/data", e);
-            }
+        // Create a scaled, compressed bitmap to add to the entity-delta list.
+        final int size = ContactsUtils.getThumbnailSize(this);
+        final Bitmap bitmap = BitmapFactory.decodeFile(mTempPhotoFile.getAbsolutePath());
+        final Bitmap scaled = Bitmap.createScaledBitmap(bitmap, size, size, false);
+        final byte[] compressed = ContactPhotoUtils.compressBitmap(scaled);
+        if (compressed == null) {
+            Log.w(TAG, "could not create scaled and compressed Bitmap");
+            return;
         }
-    }
 
-    /**
-     * Tries to update the photo on the raw_contact.  If no photo exists, and allowInsert == true,
-     * then will try to {@link #updatePhoto(ContentValues, boolean)}
-     */
-    private void updatePhoto(ContentValues values, Uri rawContactDataUri,
-            boolean allowInsert) {
-        ArrayList<ContentProviderOperation> operations =
-            new ArrayList<ContentProviderOperation>();
-
-        values.remove(Photo.MIMETYPE);
-
-        // check that a photo exists
-        operations.add(ContentProviderOperation.newAssertQuery(rawContactDataUri)
-                .withSelection(Photo.MIMETYPE + "=?", new String[] {
-                    Photo.CONTENT_ITEM_TYPE
-                }).withExpectedCount(1).build());
-
-        // update that photo
-        operations.add(ContentProviderOperation.newUpdate(rawContactDataUri)
-                .withSelection(Photo.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE})
-                .withValues(values).build());
-
-        try {
-            mContentResolver.applyBatch(ContactsContract.AUTHORITY, operations);
-        } catch (RemoteException e) {
-            throw new IllegalStateException("Problem querying raw_contacts/data", e);
-        } catch (OperationApplicationException e) {
-            if (allowInsert) {
-                // they deleted the photo between insert and update, so insert one
-                insertPhoto(values, rawContactDataUri, false);
-            } else {
-                throw new IllegalStateException("Problem inserting photo raw_contacts/data", e);
-            }
+        // Add compressed bitmap to entity-delta... this allows us to save to
+        // a new contact; otherwise the entity-delta-list would be empty, and
+        // the ContactSaveService would not create the new contact, and the
+        // full-res photo would fail to be saved to the non-existent contact.
+        AccountType account = raw.getRawContactAccountType(this);
+        EntityDelta.ValuesDelta values =
+                EntityModifier.ensureKindExists(raw, account, Photo.CONTENT_ITEM_TYPE);
+        if (values == null) {
+            Log.w(TAG, "cannot attach photo to this account type");
+            return;
         }
+        values.put(Photo.PHOTO, compressed);
+
+        // Finally, invoke the ContactSaveService.
+        Log.v(TAG, "all prerequisites met, about to save photo to contact");
+        Intent intent = ContactSaveService.createSaveContactIntent(
+                this,
+                deltaList,
+                "", 0,
+                contact.isUserProfile(),
+                null, null,
+                raw.getRawContactId(),
+                mTempPhotoFile.getAbsolutePath());
+        startService(intent);
+        finish();
     }
 }
diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
index 4b297d9..becbf5c 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -21,6 +21,7 @@
 import com.android.contacts.editor.ViewIdGenerator;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
 import com.android.contacts.model.DataKind;
 import com.android.contacts.model.EntityDelta;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
@@ -37,6 +38,7 @@
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.OperationApplicationException;
@@ -54,6 +56,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Nickname;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
@@ -73,22 +76,34 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 
 /**
  * This is a dialog-themed activity for confirming the addition of a detail to an existing contact
  * (once the user has selected this contact from a list of all contacts). The incoming intent
  * must have an extra with max 1 phone or email specified, using
- * {@link ContactsContract.Intents.Insert.PHONE} with type
- * {@link ContactsContract.Intents.Insert.PHONE_TYPE} or
- * {@link ContactsContract.Intents.Insert.EMAIL} with type
- * {@link ContactsContract.Intents.Insert.EMAIL_TYPE} intent keys.
+ * {@link android.provider.ContactsContract.Intents.Insert#PHONE} with type
+ * {@link android.provider.ContactsContract.Intents.Insert#PHONE_TYPE} or
+ * {@link android.provider.ContactsContract.Intents.Insert#EMAIL} with type
+ * {@link android.provider.ContactsContract.Intents.Insert#EMAIL_TYPE} intent keys.
+ *
+ * If the selected contact doesn't contain editable raw_contacts, it'll create a new raw_contact
+ * on the first editable account found, and the data will be added to this raw_contact.  The newly
+ * created raw_contact will be joined with the selected contact with aggregation-exceptions.
+ *
+ * TODO: Don't open this activity if there's no editable accounts.
+ * If there's no editable accounts on the system, we'll set {@link #mIsReadOnly} and the dialog
+ * just says "contact is not editable".  It's slightly misleading because this really means
+ * "there's no editable accounts", but in this case we shouldn't show the contact picker in the
+ * first place.
+ * Note when there's no accounts, it *is* okay to show the picker / dialog, because the local-only
+ * contacts are writable.
  */
 public class ConfirmAddDetailActivity extends Activity implements
         DialogManager.DialogShowingViewActivity {
 
-    private static final String TAG = ConfirmAddDetailActivity.class.getSimpleName();
-
-    private static final String LEGACY_CONTACTS_AUTHORITY = "contacts";
+    private static final String TAG = "ConfirmAdd"; // The class name is too long to be a tag.
+    private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);
 
     private LayoutInflater mInflater;
     private View mRootView;
@@ -102,15 +117,19 @@
     private ContentResolver mContentResolver;
 
     private AccountType mEditableAccountType;
-    private EntityDelta mState;
     private Uri mContactUri;
     private long mContactId;
     private String mDisplayName;
-    private boolean mIsReadyOnly;
+    private boolean mIsReadOnly;
 
     private QueryHandler mQueryHandler;
+
+    /** {@link EntityDeltaList} for the entire selected contact. */
     private EntityDeltaList mEntityDeltaList;
 
+    /** {@link EntityDeltaList} for the editable account */
+    private EntityDelta mEntityDelta;
+
     private String mMimetype = Phone.CONTENT_ITEM_TYPE;
 
     /**
@@ -168,9 +187,9 @@
      * a disambiguation case. For example, if the contact does not have a
      * nickname, use the email field, and etc.
      */
-    private static final String[] sMimeTypePriorityList = new String[] { Nickname.CONTENT_ITEM_TYPE,
-            Email.CONTENT_ITEM_TYPE, Im.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE,
-            Phone.CONTENT_ITEM_TYPE };
+    private static final String[] MIME_TYPE_PRIORITY_LIST = new String[] {
+            Nickname.CONTENT_ITEM_TYPE, Email.CONTENT_ITEM_TYPE, Im.CONTENT_ITEM_TYPE,
+            StructuredPostal.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE };
 
     private static final int TOKEN_CONTACT_INFO = 0;
     private static final int TOKEN_PHOTO_QUERY = 1;
@@ -180,7 +199,7 @@
     private final OnClickListener mDetailsButtonClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
-            if (mIsReadyOnly) {
+            if (mIsReadOnly) {
                 onSaveCompleted(true);
             } else {
                 doSaveAction();
@@ -250,7 +269,8 @@
         mPhotoView = (ImageView) findViewById(R.id.photo);
         mEditorContainerView = (ViewGroup) findViewById(R.id.editor_container);
 
-        startContactQuery(mContactUri, true);
+        resetAsyncQueryHandler();
+        startContactQuery(mContactUri);
 
         new QueryEntitiesTask(this).execute(intent);
     }
@@ -282,13 +302,8 @@
      * Internal method to query contact by Uri.
      *
      * @param contactUri the contact uri
-     * @param resetQueryHandler whether to use a new AsyncQueryHandler or not
      */
-    private void startContactQuery(Uri contactUri, boolean resetQueryHandler) {
-        if (resetQueryHandler) {
-            resetAsyncQueryHandler();
-        }
-
+    private void startContactQuery(Uri contactUri) {
         mQueryHandler.startQuery(TOKEN_CONTACT_INFO, contactUri, contactUri, ContactQuery.COLUMNS,
                 null, null, null);
     }
@@ -298,13 +313,8 @@
      *
      * @param photoId the photo id.
      * @param lookupKey the lookup uri.
-     * @param resetQueryHandler whether to use a new AsyncQueryHandler or not.
      */
-    private void startPhotoQuery(long photoId, Uri lookupKey, boolean resetQueryHandler) {
-        if (resetQueryHandler) {
-            resetAsyncQueryHandler();
-        }
-
+    private void startPhotoQuery(long photoId, Uri lookupKey) {
         mQueryHandler.startQuery(TOKEN_PHOTO_QUERY, lookupKey,
                 ContentUris.withAppendedId(Data.CONTENT_URI, photoId),
                 PhotoQuery.COLUMNS, null, null, null);
@@ -319,15 +329,23 @@
         // Apply a limit of 1 result to the query because we only need to
         // determine whether or not at least one other contact has the same
         // name. We don't need to find ALL other contacts with the same name.
-        Builder builder = Contacts.CONTENT_URI.buildUpon();
+        final Builder builder = Contacts.CONTENT_URI.buildUpon();
         builder.appendQueryParameter("limit", String.valueOf(1));
-        Uri uri = builder.build();
+        final Uri uri = builder.build();
 
+        final String displayNameSelection;
+        final String[] selectionArgs;
+        if (TextUtils.isEmpty(contactDisplayName)) {
+            displayNameSelection = Contacts.DISPLAY_NAME_PRIMARY + " IS NULL";
+            selectionArgs = new String[] { String.valueOf(mContactId) };
+        } else {
+            displayNameSelection = Contacts.DISPLAY_NAME_PRIMARY + " = ?";
+            selectionArgs = new String[] { contactDisplayName, String.valueOf(mContactId) };
+        }
         mQueryHandler.startQuery(TOKEN_DISAMBIGUATION_QUERY, null, uri,
                 new String[] { Contacts._ID } /* unused projection but a valid one was needed */,
-                Contacts.DISPLAY_NAME_PRIMARY + " = ? and " + Contacts.PHOTO_ID + " is null and "
-                + Contacts._ID + " <> ?",
-                new String[] { contactDisplayName, String.valueOf(mContactId) }, null);
+                displayNameSelection + " AND " + Contacts.PHOTO_ID + " IS NULL AND "
+                + Contacts._ID + " <> ?", selectionArgs, null);
     }
 
     /**
@@ -411,10 +429,13 @@
             if (activityTarget.isFinishing()) {
                 return;
             }
+            if ((entityList == null) || (entityList.size() == 0)) {
+                Log.e(TAG, "Contact not found.");
+                activityTarget.finish();
+                return;
+            }
+
             activityTarget.setEntityDeltaList(entityList);
-            activityTarget.findEditableRawContact();
-            activityTarget.parseExtras();
-            activityTarget.bindEditor();
         }
     }
 
@@ -469,12 +490,11 @@
                                 // Otherwise do the photo query.
                                 Uri lookupUri = Contacts.getLookupUri(mContactId,
                                         cursor.getString(ContactQuery.LOOKUP_KEY));
-                                startPhotoQuery(photoId, lookupUri,
-                                        false /* don't reset query handler */);
+                                startPhotoQuery(photoId, lookupUri);
                                 // Display the name because there is no
                                 // disambiguation query.
                                 setDisplayName();
-                                onLoadDataFinished();
+                                showDialogContent();
                             }
                         }
                         break;
@@ -492,7 +512,7 @@
                             // If there are no other contacts with this name,
                             // then display the name.
                             setDisplayName();
-                            onLoadDataFinished();
+                            showDialogContent();
                         }
                         break;
                     }
@@ -527,14 +547,14 @@
                             // Find the first non-empty field according to the
                             // mimetype priority list and display this under the
                             // contact's display name to disambiguate the contact.
-                            for (String mimeType : sMimeTypePriorityList) {
+                            for (String mimeType : MIME_TYPE_PRIORITY_LIST) {
                                 if (hashMapCursorData.containsKey(mimeType)) {
                                     setDisplayName();
                                     setExtraInfoField(hashMapCursorData.get(mimeType));
                                     break;
                                 }
                             }
-                            onLoadDataFinished();
+                            showDialogContent();
                         }
                         break;
                     }
@@ -547,37 +567,107 @@
         }
     }
 
-    public void setEntityDeltaList(EntityDeltaList entityList) {
-        mEntityDeltaList = entityList;
-    }
-
-    public void findEditableRawContact() {
-        if (mEntityDeltaList == null) {
-            return;
+    private void setEntityDeltaList(EntityDeltaList entityList) {
+        if (entityList == null) {
+            throw new IllegalStateException();
         }
-        for (EntityDelta state : mEntityDeltaList) {
-            final String accountType = state.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
-            final String dataSet = state.getValues().getAsString(RawContacts.DATA_SET);
-            final AccountType type = mAccountTypeManager.getAccountType(accountType, dataSet);
+        if (VERBOSE_LOGGING) {
+            Log.v(TAG, "setEntityDeltaList: " + entityList);
+        }
 
-            if (type.areContactsWritable()) {
-                mEditableAccountType = type;
-                mState = state;
-                return;
+        mEntityDeltaList = entityList;
+
+        // Find the editable raw_contact.
+        mEntityDelta = mEntityDeltaList.getFirstWritableRawContact(this);
+
+        // If no editable raw_contacts are found, create one.
+        if (mEntityDelta == null) {
+            mEntityDelta = addEditableRawContact(this, mEntityDeltaList);
+
+            if ((mEntityDelta != null) && VERBOSE_LOGGING) {
+                Log.v(TAG, "setEntityDeltaList: created editable raw_contact " + entityList);
             }
         }
+
+        if (mEntityDelta == null) {
+            // Selected contact is read-only, and there's no editable account.
+            mIsReadOnly = true;
+            mEditableAccountType = null;
+        } else {
+            mIsReadOnly = false;
+
+            mEditableAccountType = mEntityDelta.getRawContactAccountType(this);
+
+            // Handle any incoming values that should be inserted
+            final Bundle extras = getIntent().getExtras();
+            if (extras != null && extras.size() > 0) {
+                // If there are any intent extras, add them as additional fields in the EntityDelta.
+                EntityModifier.parseExtras(this, mEditableAccountType, mEntityDelta, extras);
+            }
+        }
+
+        bindEditor();
     }
 
-    public void parseExtras() {
-        if (mEditableAccountType == null || mState == null) {
-            return;
+    /**
+     * Create an {@link EntityDelta} for a raw_contact on the first editable account found, and add
+     * to the list.  Also copy the structured name from an existing (read-only) raw_contact to the
+     * new one, if any of the read-only contacts has a name.
+     */
+    private static EntityDelta addEditableRawContact(Context context,
+            EntityDeltaList entityDeltaList) {
+        // First, see if there's an editable account.
+        final AccountTypeManager accounts = AccountTypeManager.getInstance(context);
+        final List<AccountWithDataSet> editableAccounts = accounts.getAccounts(true);
+        if (editableAccounts.size() == 0) {
+            // No editable account type found.  The dialog will be read-only mode.
+            return null;
         }
-        // Handle any incoming values that should be inserted
-        final Bundle extras = getIntent().getExtras();
-        if (extras != null && extras.size() > 0) {
-            // If there are any intent extras, add them as additional fields in the EntityDelta.
-            EntityModifier.parseExtras(this, mEditableAccountType, mState, extras);
+        final AccountWithDataSet editableAccount = editableAccounts.get(0);
+        final AccountType accountType = accounts.getAccountType(
+                editableAccount.type, editableAccount.dataSet);
+
+        // Create a new EntityDelta for the new raw_contact.
+        final ContentValues values = new ContentValues();
+        values.put(RawContacts.ACCOUNT_NAME, editableAccount.name);
+        values.put(RawContacts.ACCOUNT_TYPE, editableAccount.type);
+        values.put(RawContacts.DATA_SET, editableAccount.dataSet);
+
+        final EntityDelta entityDelta = new EntityDelta(ValuesDelta.fromAfter(values));
+
+        // Then, copy the structure name from an existing (read-only) raw_contact.
+        for (EntityDelta entity : entityDeltaList) {
+            final ArrayList<ValuesDelta> readOnlyNames =
+                    entity.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
+            if ((readOnlyNames != null) && (readOnlyNames.size() > 0)) {
+                final ValuesDelta readOnlyName = readOnlyNames.get(0);
+
+                final ValuesDelta newName = EntityModifier.ensureKindExists(entityDelta,
+                        accountType, StructuredName.CONTENT_ITEM_TYPE);
+
+                // Copy all the data fields.
+                newName.copyStringFrom(readOnlyName, StructuredName.DISPLAY_NAME);
+
+                newName.copyStringFrom(readOnlyName, StructuredName.GIVEN_NAME);
+                newName.copyStringFrom(readOnlyName, StructuredName.FAMILY_NAME);
+                newName.copyStringFrom(readOnlyName, StructuredName.PREFIX);
+                newName.copyStringFrom(readOnlyName, StructuredName.MIDDLE_NAME);
+                newName.copyStringFrom(readOnlyName, StructuredName.SUFFIX);
+
+                newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_GIVEN_NAME);
+                newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_MIDDLE_NAME);
+                newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_FAMILY_NAME);
+
+                newName.copyStringFrom(readOnlyName, StructuredName.FULL_NAME_STYLE);
+                newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_NAME_STYLE);
+                break;
+            }
         }
+
+        // Add the new EntityDelta to the list.
+        entityDeltaList.add(entityDelta);
+
+        return entityDelta;
     }
 
     /**
@@ -585,19 +675,18 @@
      */
     private void bindEditor() {
         if (mEntityDeltaList == null) {
-            return;
+            throw new IllegalStateException();
         }
 
         // If no valid raw contact (to insert the data) was found, we won't have an editable
         // account type to use. In this case, display an error message and hide the "OK" button.
-        if (mEditableAccountType == null) {
-            mIsReadyOnly = true;
+        if (mIsReadOnly) {
             mReadOnlyWarningView.setText(getString(R.string.contact_read_only));
             mReadOnlyWarningView.setVisibility(View.VISIBLE);
             mEditorContainerView.setVisibility(View.GONE);
             findViewById(R.id.btn_done).setVisibility(View.GONE);
             // Nothing more to be done, just show the UI
-            onLoadDataFinished();
+            showDialogContent();
             return;
         }
 
@@ -606,11 +695,11 @@
             // Skip kind that are not editable
             if (!kind.editable) continue;
             if (mMimetype.equals(kind.mimeType)) {
-                for (ValuesDelta valuesDelta : mState.getMimeEntries(mMimetype)) {
+                for (ValuesDelta valuesDelta : mEntityDelta.getMimeEntries(mMimetype)) {
                     // Skip entries that aren't visible
                     if (!valuesDelta.isVisible()) continue;
                     if (valuesDelta.isInsert()) {
-                        inflateEditorView(kind, valuesDelta, mState);
+                        inflateEditorView(kind, valuesDelta, mEntityDelta);
                         return;
                     }
                 }
@@ -661,7 +750,7 @@
      * once all the queries have completed, otherwise the screen will flash as additional data
      * comes in.
      */
-    private void onLoadDataFinished() {
+    private void showDialogContent() {
         mRootView.setVisibility(View.VISIBLE);
     }
 
@@ -674,14 +763,13 @@
         task.execute(mEntityDeltaList);
     }
 
-
     /**
      * Background task for persisting edited contact data, using the changes
      * defined by a set of {@link EntityDelta}. This task starts
      * {@link EmptyService} to make sure the background thread can finish
      * persisting in cases where the system wants to reclaim our process.
      */
-    public static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> {
+    private static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> {
         // In the future, use ContactSaver instead of WeakAsyncTask because of
         // the danger of the activity being null during a save action
         private static final int PERSIST_TRIES = 3;
@@ -730,6 +818,9 @@
             while (tries++ < PERSIST_TRIES) {
                 try {
                     // Build operations and try applying
+                    // Note: In case we've created a new raw_contact because the selected contact
+                    // is read-only, buildDiff() will create aggregation exceptions to join
+                    // the new one to the existing contact.
                     final ArrayList<ContentProviderOperation> diff = state.buildDiff();
                     ContentProviderResult[] results = null;
                     if (!diff.isEmpty()) {
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index b949176..d656fdb 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -43,12 +43,10 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.CheckBox;
 import android.widget.Toast;
 
 import java.util.ArrayList;
@@ -56,17 +54,11 @@
 public class ContactDetailActivity extends ContactsActivity {
     private static final String TAG = "ContactDetailActivity";
 
-    /**
-     * Boolean intent key that specifies whether pressing the "up" affordance in this activity
-     * should cause it to finish itself or launch an intent to bring the user back to a specific
-     * parent activity - the {@link PeopleActivity}.
-     */
-    public static final String INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED =
-            "finishActivityOnUpSelected";
+    /** Shows a toogle button for hiding/showing updates. Don't submit with true */
+    private static final boolean DEBUG_TRANSITIONS = false;
 
     private ContactLoader.Result mContactData;
     private Uri mLookupUri;
-    private boolean mFinishActivityOnUpSelected;
 
     private ContactDetailLayoutController mContactDetailLayoutController;
     private ContactLoaderFragment mLoaderFragment;
@@ -74,7 +66,7 @@
     private Handler mHandler = new Handler();
 
     @Override
-    public void onCreate(Bundle savedState) {
+    protected void onCreate(Bundle savedState) {
         super.onCreate(savedState);
         if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
             // This activity must not be shown. We have to select the contact in the
@@ -83,9 +75,18 @@
             Intent intent = new Intent();
             intent.setAction(originalIntent.getAction());
             intent.setDataAndType(originalIntent.getData(), originalIntent.getType());
-            intent.setFlags(
-                    Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_FORWARD_RESULT
-                            | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+            // If we are launched from the outside, we should create a new task, because the user
+            // can freely navigate the app (this is different from phones, where only the UP button
+            // kicks the user into the full app)
+            if (shouldUpRecreateTask(intent)) {
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |
+                        Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+            } else {
+                intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
+                        Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_SINGLE_TOP |
+                        Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            }
 
             intent.setClass(this, PeopleActivity.class);
             startActivity(intent);
@@ -93,13 +94,10 @@
             return;
         }
 
-        mFinishActivityOnUpSelected = getIntent().getBooleanExtra(
-                INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, false);
-
         setContentView(R.layout.contact_detail_activity);
 
         mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
-                getFragmentManager(), findViewById(R.id.contact_detail_container),
+                getFragmentManager(), null, findViewById(R.id.contact_detail_container),
                 mContactDetailFragmentListener);
 
         // We want the UP affordance but no app icon.
@@ -129,32 +127,55 @@
         super.onCreateOptionsMenu(menu);
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.star, menu);
+        if (DEBUG_TRANSITIONS) {
+            final MenuItem toggleSocial =
+                    menu.add(mLoaderFragment.getLoadStreamItems() ? "less" : "more");
+            toggleSocial.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            toggleSocial.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(MenuItem item) {
+                    mLoaderFragment.toggleLoadStreamItems();
+                    invalidateOptionsMenu();
+                    return false;
+                }
+            });
+        }
         return true;
     }
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        MenuItem starredMenuItem = menu.findItem(R.id.menu_star);
-        ViewGroup starredContainer = (ViewGroup) getLayoutInflater().inflate(
-                R.layout.favorites_star, null, false);
-        final CheckBox starredView = (CheckBox) starredContainer.findViewById(R.id.star);
-        starredView.setOnClickListener(new OnClickListener() {
+        final MenuItem starredMenuItem = menu.findItem(R.id.menu_star);
+        starredMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
             @Override
-            public void onClick(View v) {
+            public boolean onMenuItemClick(MenuItem item) {
                 // Toggle "starred" state
                 // Make sure there is a contact
                 if (mLookupUri != null) {
+                    // Read the current starred value from the UI instead of using the last
+                    // loaded state. This allows rapid tapping without writing the same
+                    // value several times
+                    final boolean isStarred = starredMenuItem.isChecked();
+
+                    // To improve responsiveness, swap out the picture (and tag) in the UI already
+                    ContactDetailDisplayUtils.configureStarredMenuItem(starredMenuItem,
+                            mContactData.isDirectoryEntry(), mContactData.isUserProfile(),
+                            !isStarred);
+
+                    // Now perform the real save
                     Intent intent = ContactSaveService.createSetStarredIntent(
-                            ContactDetailActivity.this, mLookupUri, starredView.isChecked());
+                            ContactDetailActivity.this, mLookupUri, !isStarred);
                     ContactDetailActivity.this.startService(intent);
                 }
+                return true;
             }
         });
         // If there is contact data, update the starred state
         if (mContactData != null) {
-            ContactDetailDisplayUtils.setStarred(mContactData, starredView);
+            ContactDetailDisplayUtils.configureStarredMenuItem(starredMenuItem,
+                    mContactData.isDirectoryEntry(), mContactData.isUserProfile(),
+                    mContactData.getStarred());
         }
-        starredMenuItem.setActionView(starredContainer);
         return true;
     }
 
@@ -285,24 +306,4 @@
          */
         public boolean handleKeyDown(int keyCode);
     }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                if (mFinishActivityOnUpSelected) {
-                    finish();
-                    return true;
-                }
-                Intent intent = new Intent(this, PeopleActivity.class);
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                startActivity(intent);
-                finish();
-                return true;
-            default:
-                break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
 }
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index d591b42..9dde2dd 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -207,7 +207,7 @@
                     account.type, account.dataSet);
 
             Intent intent = new Intent();
-            intent.setClassName(accountType.resPackageName,
+            intent.setClassName(accountType.syncAdapterPackageName,
                     accountType.getCreateContactActivityClassName());
             intent.setAction(Intent.ACTION_INSERT);
             intent.setType(Contacts.CONTENT_ITEM_TYPE);
@@ -232,7 +232,7 @@
                     account.type, account.dataSet);
 
             Intent intent = new Intent();
-            intent.setClassName(accountType.resPackageName,
+            intent.setClassName(accountType.syncAdapterPackageName,
                     accountType.getEditContactActivityClassName());
             intent.setAction(Intent.ACTION_EDIT);
             intent.setData(rawContactUri);
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index b5b6c1d..0db3a0c 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -31,6 +31,7 @@
 import com.android.contacts.list.PhoneNumberPickerFragment;
 import com.android.contacts.list.PostalAddressPickerFragment;
 import com.android.contacts.widget.ContextMenuAdapter;
+import com.google.android.collect.Sets;
 
 import android.app.ActionBar;
 import android.app.ActionBar.LayoutParams;
@@ -415,8 +416,14 @@
                         ConfirmAddDetailActivity.class);
                 intent.setData(contactLookupUri);
                 if (extras != null) {
+                    // First remove name key if present because the dialog does not support name
+                    // editing. This is fine because the user wants to add information to an
+                    // existing contact, who should already have a name and we wouldn't want to
+                    // override the name.
+                    extras.remove(Insert.NAME);
                     intent.putExtras(extras);
                 }
+
                 // Wait for the activity result because we want to keep the picker open (in case the
                 // user cancels adding the info to a contact and wants to pick someone else).
                 startActivityForResult(intent, SUBACTIVITY_ADD_TO_EXISTING_CONTACT);
@@ -440,13 +447,24 @@
          * Returns true if is a single email or single phone number provided in the {@link Intent}
          * extras bundle so that a pop-up confirmation dialog can be used to add the data to
          * a contact. Otherwise return false if there are other intent extras that require launching
-         * the full contact editor.
+         * the full contact editor. Ignore extras with the key {@link Insert.NAME} because names
+         * are a special case and we typically don't want to replace the name of an existing
+         * contact.
          */
         private boolean launchAddToContactDialog(Bundle extras) {
             if (extras == null) {
                 return false;
             }
-            Set<String> intentExtraKeys = extras.keySet();
+
+            // Copy extras because the set may be modified in the next step
+            Set<String> intentExtraKeys = Sets.newHashSet();
+            intentExtraKeys.addAll(extras.keySet());
+
+            // Ignore name key because this is an existing contact.
+            if (intentExtraKeys.contains(Insert.NAME)) {
+                intentExtraKeys.remove(Insert.NAME);
+            }
+
             int numIntentExtraKeys = intentExtraKeys.size();
             if (numIntentExtraKeys == 2) {
                 boolean hasPhone = intentExtraKeys.contains(Insert.PHONE) &&
@@ -573,6 +591,7 @@
 
     private void startCreateNewContactActivity() {
         Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
+        intent.putExtra(ContactEditorActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
         startActivityAndForwardResult(intent);
     }
 
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 9abcdf4..b5b0a63 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.activities;
 
+import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.calllog.CallLogFragment;
 import com.android.contacts.dialpad.DialpadFragment;
@@ -26,8 +27,8 @@
 import com.android.contacts.list.OnPhoneNumberPickerActionListener;
 import com.android.contacts.list.PhoneFavoriteFragment;
 import com.android.contacts.list.PhoneNumberPickerFragment;
-import com.android.contacts.activities.TransactionSafeActivity;
 import com.android.contacts.util.AccountFilterUtil;
+import com.android.contacts.util.Constants;
 import com.android.internal.telephony.ITelephony;
 
 import android.app.ActionBar;
@@ -53,6 +54,7 @@
 import android.support.v4.view.ViewPager;
 import android.support.v4.view.ViewPager.OnPageChangeListener;
 import android.text.TextUtils;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -62,6 +64,7 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
 import android.view.ViewConfiguration;
+import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.PopupMenu;
 import android.widget.SearchView;
@@ -75,10 +78,11 @@
  * embedded using intents.
  * The dialer tab's title is 'phone', a more common name (see strings.xml).
  */
-public class DialtactsActivity extends TransactionSafeActivity {
+public class DialtactsActivity extends TransactionSafeActivity
+        implements View.OnClickListener {
     private static final String TAG = "DialtactsActivity";
 
-    private static final boolean DEBUG = false;
+    public static final boolean DEBUG = false;
 
     /** Used to open Call Setting */
     private static final String PHONE_PACKAGE = "com.android.phone";
@@ -89,7 +93,8 @@
      * Copied from PhoneApp. See comments in Phone app for more detail.
      */
     public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
-    public static final String CALL_ORIGIN_DIALTACTS =
+    /** @see #getCallOrigin() */
+    private static final String CALL_ORIGIN_DIALTACTS =
             "com.android.contacts.activities.DialtactsActivity";
 
     /**
@@ -113,14 +118,6 @@
 
     private static final int SUBACTIVITY_ACCOUNT_FILTER = 1;
 
-    /**
-     * Listener interface for Fragments accommodated in {@link ViewPager} enabling them to know
-     * when it becomes visible or invisible inside the ViewPager.
-     */
-    public interface ViewPagerVisibilityListener {
-        public void onVisibilityChanged(boolean visible);
-    }
-
     public class ViewPagerAdapter extends FragmentPagerAdapter {
         public ViewPagerAdapter(FragmentManager fm) {
             super(fm);
@@ -140,6 +137,16 @@
         }
 
         @Override
+        public void setPrimaryItem(ViewGroup container, int position, Object object) {
+            // The parent's setPrimaryItem() also calls setMenuVisibility(), so we want to know
+            // when it happens.
+            if (DEBUG) {
+                Log.d(TAG, "FragmentPagerAdapter#setPrimaryItem(), position: " + position);
+            }
+            super.setPrimaryItem(container, position, object);
+        }
+
+        @Override
         public int getCount() {
             return TAB_INDEX_COUNT;
         }
@@ -177,15 +184,16 @@
 
         @Override
         public void onPageSelected(int position) {
-            if (DEBUG) Log.d(TAG, "onPageSelected: " + position);
+            if (DEBUG) Log.d(TAG, "onPageSelected: position: " + position);
             final ActionBar actionBar = getActionBar();
-            if (mDialpadFragment != null && !mDuringSwipe) {
-                if (DEBUG) {
-                    Log.d(TAG, "Immediately show/hide fake menu buttons. position: "
-                            + position + ", dragging: " + mDuringSwipe);
+            if (mDialpadFragment != null) {
+                if (mDuringSwipe && position == TAB_INDEX_DIALER) {
+                    // TODO: Figure out if we want this or not. Right now
+                    // - with this call, both fake buttons and real action bar overlap
+                    // - without this call, there's tiny flicker happening to search/menu buttons.
+                    // If we can reduce the flicker without this call, it would be much better.
+                    // updateFakeMenuButtonsVisibility(true);
                 }
-                mDialpadFragment.updateFakeMenuButtonsVisibility(
-                        position == TAB_INDEX_DIALER && !mDuringSwipe);
             }
 
             if (mCurrentPosition == position) {
@@ -200,21 +208,39 @@
             mCurrentPosition = position;
         }
 
+        public int getCurrentPosition() {
+            return mCurrentPosition;
+        }
+
         @Override
         public void onPageScrollStateChanged(int state) {
             switch (state) {
                 case ViewPager.SCROLL_STATE_IDLE: {
-                    if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_IDLE");
+                    if (mNextPosition == -1) {
+                        // This happens when the user drags the screen just after launching the
+                        // application, and settle down the same screen without actually swiping it.
+                        // At that moment mNextPosition is apparently -1 yet, and we expect it
+                        // being updated by onPageSelected(), which is *not* called if the user
+                        // settle down the exact same tab after the dragging.
+                        if (DEBUG) {
+                            Log.d(TAG, "Next position is not specified correctly. Use current tab ("
+                                    + mViewPager.getCurrentItem() + ")");
+                        }
+                        mNextPosition = mViewPager.getCurrentItem();
+                    }
+                    if (DEBUG) {
+                        Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_IDLE. "
+                                + "mCurrentPosition: " + mCurrentPosition
+                                + ", mNextPosition: " + mNextPosition);
+                    }
                     // Interpret IDLE as the end of migration (both swipe and tab click)
                     mDuringSwipe = false;
                     mUserTabClick = false;
 
-                    if (mCurrentPosition >= 0) {
-                        sendFragmentVisibilityChange(mCurrentPosition, false);
-                    }
-                    if (mNextPosition >= 0) {
-                        sendFragmentVisibilityChange(mNextPosition, true);
-                    }
+                    updateFakeMenuButtonsVisibility(mNextPosition == TAB_INDEX_DIALER);
+                    sendFragmentVisibilityChange(mCurrentPosition, false);
+                    sendFragmentVisibilityChange(mNextPosition, true);
+
                     invalidateOptionsMenu();
 
                     mCurrentPosition = mNextPosition;
@@ -224,12 +250,6 @@
                     if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_DRAGGING");
                     mDuringSwipe = true;
                     mUserTabClick = false;
-
-                    if (mCurrentPosition == TAB_INDEX_DIALER) {
-                        sendFragmentVisibilityChange(TAB_INDEX_DIALER, false);
-                        sendFragmentVisibilityChange(TAB_INDEX_CALL_LOG, true);
-                        invalidateOptionsMenu();
-                    }
                     break;
                 }
                 case ViewPager.SCROLL_STATE_SETTLING: {
@@ -253,6 +273,9 @@
     private CallLogFragment mCallLogFragment;
     private PhoneFavoriteFragment mPhoneFavoriteFragment;
 
+    private View mSearchButton;
+    private View mMenuButton;
+
     private final ContactListFilterListener mContactListFilterListener =
             new ContactListFilterListener() {
         @Override
@@ -293,9 +316,12 @@
             // when the user clicks a tab at the ActionBar at the top, this will be called before
             // them. This logic interprets the order difference as a difference of the user action.
             if (!mDuringSwipe) {
+                if (DEBUG) {
+                    Log.d(TAG, "Tab select. from: " + mPageChangeListener.getCurrentPosition()
+                            + ", to: " + tab.getPosition());
+                }
                 if (mDialpadFragment != null) {
-                    if (DEBUG) Log.d(TAG, "Immediately hide fake buttons for tab selection case");
-                    mDialpadFragment.updateFakeMenuButtonsVisibility(false);
+                    updateFakeMenuButtonsVisibility(tab.getPosition() == TAB_INDEX_DIALER);
                 }
                 mUserTabClick = true;
             }
@@ -358,7 +384,8 @@
         @Override
         public boolean onMenuItemClick(MenuItem item) {
             AccountFilterUtil.startAccountFilterActivityForResult(
-                    DialtactsActivity.this, SUBACTIVITY_ACCOUNT_FILTER);
+                    DialtactsActivity.this, SUBACTIVITY_ACCOUNT_FILTER,
+                    mContactListFilterController.getFilter());
             return true;
         }
     };
@@ -383,8 +410,7 @@
                     // Specify call-origin so that users will see the previous tab instead of
                     // CallLog screen (search UI will be automatically exited).
                     PhoneNumberInteraction.startInteractionForPhoneCall(
-                            DialtactsActivity.this, dataUri,
-                            CALL_ORIGIN_DIALTACTS);
+                            DialtactsActivity.this, dataUri, getCallOrigin());
                 }
 
                 @Override
@@ -468,6 +494,31 @@
         mViewPager = (ViewPager) findViewById(R.id.pager);
         mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
         mViewPager.setOnPageChangeListener(mPageChangeListener);
+        mViewPager.setOffscreenPageLimit(2);
+
+        // Do same width calculation as ActionBar does
+        DisplayMetrics dm = getResources().getDisplayMetrics();
+        int minCellSize = getResources().getDimensionPixelSize(R.dimen.fake_menu_button_min_width);
+        int cellCount = dm.widthPixels / minCellSize;
+        int fakeMenuItemWidth = dm.widthPixels / cellCount;
+        if (DEBUG) Log.d(TAG, "The size of fake menu buttons (in pixel): " + fakeMenuItemWidth);
+
+        // Soft menu button should appear only when there's no hardware menu button.
+        mMenuButton = findViewById(R.id.overflow_menu);
+        if (mMenuButton != null) {
+            mMenuButton.setMinimumWidth(fakeMenuItemWidth);
+            if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
+                // This is required for dialpad button's layout, so must not use GONE here.
+                mMenuButton.setVisibility(View.INVISIBLE);
+            } else {
+                mMenuButton.setOnClickListener(this);
+            }
+        }
+        mSearchButton = findViewById(R.id.searchButton);
+        if (mSearchButton != null) {
+            mSearchButton.setMinimumWidth(fakeMenuItemWidth);
+            mSearchButton.setOnClickListener(this);
+        }
 
         // Setup the ActionBar tabs (the order matches the tab-index contants TAB_INDEX_*)
         setupDialer();
@@ -509,6 +560,16 @@
             mDuringSwipe = false;
             mUserTabClick = false;
         }
+
+        final int currentPosition = mPageChangeListener.getCurrentPosition();
+        if (DEBUG) {
+            Log.d(TAG, "onStart(). current position: " + mPageChangeListener.getCurrentPosition()
+                    + ". Reset all menu visibility state.");
+        }
+        updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER && !mInSearchUi);
+        for (int i = 0; i < TAB_INDEX_COUNT; i++) {
+            sendFragmentVisibilityChange(i, i == currentPosition);
+        }
     }
 
     @Override
@@ -517,6 +578,31 @@
         mContactListFilterController.removeListener(mContactListFilterListener);
     }
 
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.searchButton: {
+                enterSearchUi();
+                break;
+            }
+            case R.id.overflow_menu: {
+                if (mDialpadFragment != null) {
+                    PopupMenu popup = mDialpadFragment.constructPopupMenu(view);
+                    if (popup != null) {
+                        popup.show();
+                    }
+                } else {
+                    Log.w(TAG, "DialpadFragment is null during onClick() event for " + view);
+                }
+                break;
+            }
+            default: {
+                Log.wtf(TAG, "Unexpected onClick event from " + view);
+                break;
+            }
+        }
+    }
+
     /**
      * Add search fragment.  Note this is called during onLayout, so there's some restrictions,
      * such as executePendingTransaction can't be used in it.
@@ -583,15 +669,8 @@
 
         if (fragment instanceof DialpadFragment) {
             mDialpadFragment = (DialpadFragment) fragment;
-            mDialpadFragment.setListener(mDialpadListener);
-            if (currentPosition == TAB_INDEX_DIALER) {
-                mDialpadFragment.onVisibilityChanged(true);
-            }
         } else if (fragment instanceof CallLogFragment) {
             mCallLogFragment = (CallLogFragment) fragment;
-            if (currentPosition == TAB_INDEX_CALL_LOG) {
-                mCallLogFragment.onVisibilityChanged(true);
-            }
         } else if (fragment instanceof PhoneFavoriteFragment) {
             mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment;
             mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener);
@@ -605,6 +684,7 @@
             mSearchFragment.setQuickContactEnabled(true);
             mSearchFragment.setDarkTheme(true);
             mSearchFragment.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
+            mSearchFragment.setUseCallableUri(true);
             if (mContactListFilterController != null
                     && mContactListFilterController.getFilter() != null) {
                 mSearchFragment.setFilter(mContactListFilterController.getFilter());
@@ -725,10 +805,10 @@
         final int previousItemIndex = mViewPager.getCurrentItem();
         mViewPager.setCurrentItem(tabIndex, false /* smoothScroll */);
         if (previousItemIndex != tabIndex) {
-            sendFragmentVisibilityChange(previousItemIndex, false);
+            sendFragmentVisibilityChange(previousItemIndex, false /* not visible */ );
         }
         mPageChangeListener.setCurrentPosition(tabIndex);
-        sendFragmentVisibilityChange(tabIndex, true);
+        sendFragmentVisibilityChange(tabIndex, true /* visible */ );
 
         // Restore to the previous manual selection
         mLastManuallySelectedFragment = savedTabIndex;
@@ -755,6 +835,12 @@
             } else {
                 Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected.");
             }
+        } else if (mViewPager.getCurrentItem() == TAB_INDEX_CALL_LOG) {
+            if (mCallLogFragment != null) {
+                mCallLogFragment.configureScreenFromIntent(newIntent);
+            } else {
+                Log.e(TAG, "CallLogFragment isn't ready yet when the tab is already selected.");
+            }
         }
         invalidateOptionsMenu();
     }
@@ -767,7 +853,7 @@
         }
         if (Intent.ACTION_VIEW.equals(action)) {
             final Uri data = intent.getData();
-            if (data != null && "tel".equals(data.getScheme())) {
+            if (data != null && Constants.SCHEME_TEL.equals(data.getScheme())) {
                 return true;
             }
         }
@@ -775,6 +861,16 @@
     }
 
     /**
+     * Returns an appropriate call origin for this Activity. May return null when no call origin
+     * should be used (e.g. when some 3rd party application launched the screen. Call origin is
+     * for remembering the tab in which the user made a phone call, so the external app's DIAL
+     * request should not be counted.)
+     */
+    public String getCallOrigin() {
+        return !isDialIntent(getIntent()) ? CALL_ORIGIN_DIALTACTS : null;
+    }
+
+    /**
      * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
      * This text originally came from a FILTER_CONTACTS_ACTION intent received
      * by this activity. The stored text will then be cleared after after this
@@ -821,20 +917,18 @@
         }
     }
 
-    private DialpadFragment.Listener mDialpadListener = new DialpadFragment.Listener() {
-        @Override
-        public void onSearchButtonPressed() {
-            enterSearchUi();
-        }
-    };
-
-    private PhoneFavoriteFragment.Listener mPhoneFavoriteListener =
+    private final PhoneFavoriteFragment.Listener mPhoneFavoriteListener =
             new PhoneFavoriteFragment.Listener() {
         @Override
         public void onContactSelected(Uri contactUri) {
             PhoneNumberInteraction.startInteractionForPhoneCall(
-                    DialtactsActivity.this, contactUri,
-                    CALL_ORIGIN_DIALTACTS);
+                    DialtactsActivity.this, contactUri, getCallOrigin());
+        }
+
+        @Override
+        public void onCallNumberDirectly(String phoneNumber) {
+            Intent intent = ContactsUtils.getCallIntent(phoneNumber, getCallOrigin());
+            startActivity(intent);
         }
     };
 
@@ -842,81 +936,127 @@
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.dialtacts_options, menu);
+
+        // set up intents and onClick listeners
+        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
+        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
+        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
+        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
+
+        callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
+        searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
+        filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
+        addContactOptionMenuItem.setIntent(
+                new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
+
         return true;
     }
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
+        if (mInSearchUi) {
+            prepareOptionsMenuInSearchMode(menu);
+        } else {
+            // get reference to the currently selected tab
+            final Tab tab = getActionBar().getSelectedTab();
+            if (tab != null) {
+                switch(tab.getPosition()) {
+                    case TAB_INDEX_DIALER:
+                        prepareOptionsMenuForDialerTab(menu);
+                        break;
+                    case TAB_INDEX_CALL_LOG:
+                        prepareOptionsMenuForCallLogTab(menu);
+                        break;
+                    case TAB_INDEX_FAVORITES:
+                        prepareOptionsMenuForFavoritesTab(menu);
+                        break;
+                }
+            }
+        }
+        return true;
+    }
+
+    private void prepareOptionsMenuInSearchMode(Menu menu) {
+        // get references to menu items
         final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
         final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
         final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
         final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        final MenuItem fakeMenuItem = menu.findItem(R.id.fake_menu_item);
-        Tab tab = getActionBar().getSelectedTab();
-        if (mInSearchUi) {
-            searchMenuItem.setVisible(false);
-            if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
-                filterOptionMenuItem.setVisible(true);
-                filterOptionMenuItem.setOnMenuItemClickListener(
-                        mFilterOptionsMenuItemClickListener);
-                addContactOptionMenuItem.setVisible(true);
-                addContactOptionMenuItem.setIntent(
-                        new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-            } else {
-                // Filter option menu should be not be shown as a overflow menu.
-                filterOptionMenuItem.setVisible(false);
-                addContactOptionMenuItem.setVisible(false);
-            }
-            callSettingsMenuItem.setVisible(false);
-            fakeMenuItem.setVisible(false);
-        } else {
-            final boolean showCallSettingsMenu;
-            if (tab != null && tab.getPosition() == TAB_INDEX_DIALER) {
-                if (DEBUG) {
-                    Log.d(TAG, "onPrepareOptionsMenu(dialer). swipe: " + mDuringSwipe
-                            + ", user tab click: " + mUserTabClick);
-                }
-                if (mDuringSwipe || mUserTabClick) {
-                    // During horizontal movement, we just show real ActionBar menu items.
-                    searchMenuItem.setVisible(true);
-                    searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
-                    showCallSettingsMenu = true;
+        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
 
-                    fakeMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
-                } else {
-                    searchMenuItem.setVisible(false);
-                    // When permanent menu key is _not_ available, the call settings menu should be
-                    // available via DialpadFragment.
-                    showCallSettingsMenu = ViewConfiguration.get(this).hasPermanentMenuKey();
-                    fakeMenuItem.setVisible(false);
-                }
-            } else {
-                searchMenuItem.setVisible(true);
-                searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
-                showCallSettingsMenu = true;
-                fakeMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
-            }
-            if (tab != null && tab.getPosition() == TAB_INDEX_FAVORITES) {
-                filterOptionMenuItem.setVisible(true);
-                filterOptionMenuItem.setOnMenuItemClickListener(
-                        mFilterOptionsMenuItemClickListener);
-                addContactOptionMenuItem.setVisible(true);
-                addContactOptionMenuItem.setIntent(
-                        new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-            } else {
-                filterOptionMenuItem.setVisible(false);
-                addContactOptionMenuItem.setVisible(false);
-            }
+        // prepare the menu items
+        searchMenuItem.setVisible(false);
+        filterOptionMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
+        addContactOptionMenuItem.setVisible(false);
+        callSettingsMenuItem.setVisible(false);
+        emptyRightMenuItem.setVisible(false);
+    }
 
-            if (showCallSettingsMenu) {
-                callSettingsMenuItem.setVisible(true);
-                callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
-            } else {
-                callSettingsMenuItem.setVisible(false);
-            }
+    private void prepareOptionsMenuForDialerTab(Menu menu) {
+        if (DEBUG) {
+            Log.d(TAG, "onPrepareOptionsMenu(dialer). swipe: " + mDuringSwipe
+                    + ", user tab click: " + mUserTabClick);
         }
 
-        return true;
+        // get references to menu items
+        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
+        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
+        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
+        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
+        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
+
+        // prepare the menu items
+        filterOptionMenuItem.setVisible(false);
+        addContactOptionMenuItem.setVisible(false);
+        if (mDuringSwipe || mUserTabClick) {
+            // During horizontal movement, the real ActionBar menu items are shown
+            searchMenuItem.setVisible(true);
+            callSettingsMenuItem.setVisible(true);
+            // When there is a permanent menu key, there is no overflow icon on the right of
+            // the action bar which would force the search menu item (if it is visible) to the
+            // left.  This is the purpose of showing the emptyRightMenuItem.
+            emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
+        } else {
+            // This is when the user is looking at the dialer pad.  In this case, the real
+            // ActionBar is hidden and fake menu items are shown.
+            searchMenuItem.setVisible(false);
+            // If a permanent menu key is available, then we need to show the call settings item
+            // so that the call settings item can be invoked by the permanent menu key.
+            callSettingsMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
+            emptyRightMenuItem.setVisible(false);
+        }
+    }
+
+    private void prepareOptionsMenuForCallLogTab(Menu menu) {
+        // get references to menu items
+        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
+        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
+        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
+        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
+        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
+
+        // prepare the menu items
+        searchMenuItem.setVisible(true);
+        filterOptionMenuItem.setVisible(false);
+        addContactOptionMenuItem.setVisible(false);
+        callSettingsMenuItem.setVisible(true);
+        emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
+    }
+
+    private void prepareOptionsMenuForFavoritesTab(Menu menu) {
+        // get references to menu items
+        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
+        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
+        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
+        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
+        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
+
+        // prepare the menu items
+        searchMenuItem.setVisible(true);
+        filterOptionMenuItem.setVisible(true);
+        addContactOptionMenuItem.setVisible(true);
+        callSettingsMenuItem.setVisible(true);
+        emptyRightMenuItem.setVisible(false);
     }
 
     @Override
@@ -970,7 +1110,11 @@
         actionBar.setDisplayShowHomeEnabled(true);
         actionBar.setDisplayHomeAsUpEnabled(true);
 
-        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), false);
+        updateFakeMenuButtonsVisibility(false);
+
+        for (int i = 0; i < TAB_INDEX_COUNT; i++) {
+            sendFragmentVisibilityChange(i, false /* not visible */ );
+        }
 
         // Show the search fragment and hide everything else.
         mSearchFragment.setUserVisibleHint(true);
@@ -1022,7 +1166,9 @@
         actionBar.setDisplayShowHomeEnabled(false);
         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 
-        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), true);
+        for (int i = 0; i < TAB_INDEX_COUNT; i++) {
+            sendFragmentVisibilityChange(i, i == mViewPager.getCurrentItem());
+        }
 
         // Before exiting the search screen, reset swipe state.
         mDuringSwipe = false;
@@ -1054,9 +1200,45 @@
     }
 
     private void sendFragmentVisibilityChange(int position, boolean visibility) {
-        final Fragment fragment = getFragmentAt(position);
-        if (fragment instanceof ViewPagerVisibilityListener) {
-            ((ViewPagerVisibilityListener) fragment).onVisibilityChanged(visibility);
+        if (DEBUG) {
+            Log.d(TAG, "sendFragmentVisibiltyChange(). position: " + position
+                    + ", visibility: " + visibility);
+        }
+        // Position can be -1 initially. See PageChangeListener.
+        if (position >= 0) {
+            final Fragment fragment = getFragmentAt(position);
+            if (fragment != null) {
+                fragment.setMenuVisibility(visibility);
+                fragment.setUserVisibleHint(visibility);
+            }
+        }
+    }
+
+    /**
+     * Update visibility of the search button and menu button at the bottom.
+     * They should be invisible when bottom ActionBar's real items are available, and be visible
+     * otherwise.
+     *
+     * @param visible True when visible.
+     */
+    private void updateFakeMenuButtonsVisibility(boolean visible) {
+        if (DEBUG) {
+            Log.d(TAG, "updateFakeMenuButtonVisibility(" + visible + ")");
+        }
+
+        if (mSearchButton != null) {
+            if (visible) {
+                mSearchButton.setVisibility(View.VISIBLE);
+            } else {
+                mSearchButton.setVisibility(View.INVISIBLE);
+            }
+        }
+        if (mMenuButton != null) {
+            if (visible && !ViewConfiguration.get(this).hasPermanentMenuKey()) {
+                mMenuButton.setVisibility(View.VISIBLE);
+            } else {
+                mMenuButton.setVisibility(View.INVISIBLE);
+            }
         }
     }
 
diff --git a/src/com/android/contacts/activities/DialtactsViewPager.java b/src/com/android/contacts/activities/DialtactsViewPager.java
deleted file mode 100644
index 6bf41f7..0000000
--- a/src/com/android/contacts/activities/DialtactsViewPager.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.activities;
-
-import android.content.Context;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-
-public class DialtactsViewPager extends ViewPager {
-    public DialtactsViewPager(Context context) {
-        super(context);
-    }
-
-    public DialtactsViewPager(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    /**
-     * ViewPager inherits ViewGroup's default behavior of delayed clicks
-     * on its children, but in order to make the dialpad more responsive we
-     * disable that here. The Call Log and Favorites tabs are both
-     * ListViews which delay their children anyway, as desired to prevent
-     * seeing pressed states flashing while scrolling lists
-     */
-    /*
-    public boolean shouldDelayChildPressedState() {
-        return false;
-    }*/
-}
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index 6c36b5d..e49789e 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -106,7 +106,6 @@
         @Override
         public void onContactSelected(Uri contactUri) {
             Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
-            intent.putExtra(ContactDetailActivity.INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, true);
             startActivity(intent);
         }
 
@@ -148,7 +147,8 @@
                 final Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI,
                         mFragment.getGroupId());
                 final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-                intent.setClassName(accountType.resPackageName, accountType.getViewGroupActivity());
+                intent.setClassName(accountType.syncAdapterPackageName,
+                        accountType.getViewGroupActivity());
                 startActivity(intent);
             }
         });
diff --git a/src/com/android/contacts/activities/GroupEditorActivity.java b/src/com/android/contacts/activities/GroupEditorActivity.java
index 7fed0f8..f3255bf 100644
--- a/src/com/android/contacts/activities/GroupEditorActivity.java
+++ b/src/com/android/contacts/activities/GroupEditorActivity.java
@@ -18,7 +18,6 @@
 
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
-import com.android.contacts.editor.ContactEditorFragment.SaveMode;
 import com.android.contacts.group.GroupEditorFragment;
 import com.android.contacts.util.DialogManager;
 import com.android.contacts.util.PhoneCapabilityTester;
@@ -108,7 +107,7 @@
     @Override
     public void onBackPressed() {
         // If the change could not be saved, then revert to the default "back" button behavior.
-        if (!mFragment.save(SaveMode.CLOSE)) {
+        if (!mFragment.save()) {
             super.onBackPressed();
         }
     }
@@ -123,9 +122,7 @@
 
         String action = intent.getAction();
         if (ACTION_SAVE_COMPLETED.equals(action)) {
-            mFragment.onSaveCompleted(true,
-                    intent.getIntExtra(GroupEditorFragment.SAVE_MODE_EXTRA_KEY, SaveMode.CLOSE),
-                    intent.getData());
+            mFragment.onSaveCompleted(true, intent.getData());
         }
     }
 
diff --git a/src/com/android/contacts/activities/JoinContactActivity.java b/src/com/android/contacts/activities/JoinContactActivity.java
index 75a13d0..4a277cb 100644
--- a/src/com/android/contacts/activities/JoinContactActivity.java
+++ b/src/com/android/contacts/activities/JoinContactActivity.java
@@ -24,18 +24,29 @@
 import com.android.contacts.list.OnContactPickerActionListener;
 
 import android.app.ActionBar;
+import android.app.ActionBar.LayoutParams;
 import android.app.Fragment;
+import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract;
+import android.text.TextUtils;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.SearchView;
+import android.widget.SearchView.OnCloseListener;
+import android.widget.SearchView.OnQueryTextListener;
 
 /**
  * An activity that shows a list of contacts that can be joined with the target contact.
  */
-public class JoinContactActivity extends ContactsActivity {
+public class JoinContactActivity extends ContactsActivity
+        implements OnQueryTextListener, OnCloseListener, OnFocusChangeListener {
 
     private static final String TAG = "JoinContactActivity";
 
@@ -59,6 +70,7 @@
     private long mTargetContactId;
 
     private JoinContactListFragment mListFragment;
+    private SearchView mSearchView;
 
     @Override
     public void onAttachFragment(Fragment fragment) {
@@ -93,12 +105,7 @@
                     .commitAllowingStateLoss();
         }
 
-        final ActionBar actionBar = getActionBar();
-        if (actionBar != null) {
-            actionBar.setDisplayShowHomeEnabled(true);
-            actionBar.setDisplayHomeAsUpEnabled(true);
-            actionBar.setDisplayShowTitleEnabled(true);
-        }
+        prepareSearchViewAndActionBar();
     }
 
     private void setupActionListener() {
@@ -125,6 +132,74 @@
         });
     }
 
+    private void prepareSearchViewAndActionBar() {
+        final ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            final View searchViewOnLayout = findViewById(R.id.search_view);
+            if (searchViewOnLayout != null) {
+                searchViewOnLayout.setVisibility(View.GONE);
+            }
+
+            final View searchViewLayout = LayoutInflater.from(actionBar.getThemedContext())
+                    .inflate(R.layout.custom_action_bar, null);
+            mSearchView = (SearchView) searchViewLayout.findViewById(R.id.search_view);
+
+            // In order to make the SearchView look like "shown via search menu", we need to
+            // manually setup its state. See also DialtactsActivity.java and ActionBarAdapter.java.
+            mSearchView.setIconifiedByDefault(true);
+            mSearchView.setQueryHint(getString(R.string.hint_findContacts));
+            mSearchView.setIconified(false);
+
+            mSearchView.setOnQueryTextListener(this);
+            mSearchView.setOnCloseListener(this);
+            mSearchView.setOnQueryTextFocusChangeListener(this);
+
+            actionBar.setCustomView(searchViewLayout,
+                    new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+            actionBar.setDisplayShowCustomEnabled(true);
+            actionBar.setDisplayShowHomeEnabled(true);
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        } else {
+            mSearchView = (SearchView) findViewById(R.id.search_view);
+            mSearchView.setQueryHint(getString(R.string.hint_findContacts));
+            mSearchView.setOnQueryTextListener(this);
+            mSearchView.setOnQueryTextFocusChangeListener(this);
+        }
+
+        // Clear focus and suppress keyboard show-up.
+        mSearchView.clearFocus();
+    }
+
+    @Override
+    public boolean onQueryTextChange(String newText) {
+        mListFragment.setQueryString(newText, true);
+        return false;
+    }
+
+    @Override
+    public boolean onQueryTextSubmit(String query) {
+        return false;
+    }
+
+    @Override
+    public boolean onClose() {
+        if (!TextUtils.isEmpty(mSearchView.getQuery())) {
+            mSearchView.setQuery(null, true);
+        }
+        return true;
+    }
+
+    @Override
+    public void onFocusChange(View view, boolean hasFocus) {
+        switch (view.getId()) {
+            case R.id.search_view: {
+                if (hasFocus) {
+                    showInputMethod(mSearchView.findFocus());
+                }
+            }
+        }
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
@@ -156,4 +231,14 @@
             mListFragment.onPickerResult(data);
         }
     }
+
+    private void showInputMethod(View view) {
+        final InputMethodManager imm = (InputMethodManager)
+                getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (imm != null) {
+            if (!imm.showSoftInput(view, 0)) {
+                Log.w(TAG, "Failed to show soft input method.");
+            }
+        }
+    }
 }
diff --git a/src/com/android/contacts/activities/NonPhoneActivity.java b/src/com/android/contacts/activities/NonPhoneActivity.java
index 3a54292..47ae020 100644
--- a/src/com/android/contacts/activities/NonPhoneActivity.java
+++ b/src/com/android/contacts/activities/NonPhoneActivity.java
@@ -18,6 +18,7 @@
 
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
+import com.android.contacts.util.Constants;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -56,7 +57,7 @@
         final Uri data = getIntent().getData();
         if (data == null) return null;
         final String scheme = data.getScheme();
-        if (!"tel".equals(scheme)) return null;
+        if (!Constants.SCHEME_TEL.equals(scheme)) return null;
         return getIntent().getData().getSchemeSpecificPart();
     }
 
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 8d1b9aa..d1b493f 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -27,6 +27,7 @@
 import com.android.contacts.detail.ContactDetailUpdatesFragment;
 import com.android.contacts.detail.ContactLoaderFragment;
 import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
+import com.android.contacts.dialog.ClearFrequentsDialog;
 import com.android.contacts.group.GroupBrowseListFragment;
 import com.android.contacts.group.GroupBrowseListFragment.OnGroupBrowserActionListener;
 import com.android.contacts.group.GroupDetailFragment;
@@ -47,20 +48,19 @@
 import com.android.contacts.list.DirectoryListLoader;
 import com.android.contacts.list.OnContactBrowserActionListener;
 import com.android.contacts.list.OnContactsUnavailableActionListener;
-import com.android.contacts.list.ProviderStatusLoader;
-import com.android.contacts.list.ProviderStatusLoader.ProviderStatusListener;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.list.ProviderStatusWatcher;
+import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener;
 import com.android.contacts.model.AccountWithDataSet;
 import com.android.contacts.preference.ContactsPreferenceActivity;
 import com.android.contacts.preference.DisplayOptionsPreferenceFragment;
 import com.android.contacts.util.AccountFilterUtil;
 import com.android.contacts.util.AccountPromptUtils;
-import com.android.contacts.util.AccountSelectionUtil;
-import com.android.contacts.util.AccountsListAdapter;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.DialogManager;
+import com.android.contacts.util.HelpUtils;
 import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.util.UriUtils;
+import com.android.contacts.widget.TransitionAnimationView;
 
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -76,7 +76,6 @@
 import android.preference.PreferenceActivity;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.ProviderStatus;
 import android.provider.ContactsContract.QuickContact;
 import android.provider.Settings;
@@ -84,19 +83,17 @@
 import android.support.v4.view.PagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.util.Log;
+import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListPopupWindow;
+import android.view.ViewGroup;
 import android.widget.Toast;
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -110,6 +107,9 @@
 
     private static final String TAG = "PeopleActivity";
 
+    /** Shows a toogle button for hiding/showing updates. Don't submit with true */
+    private static final boolean DEBUG_TRANSITIONS = false;
+
     // These values needs to start at 2. See {@link ContactEntryListFragment}.
     private static final int SUBACTIVITY_NEW_CONTACT = 2;
     private static final int SUBACTIVITY_EDIT_CONTACT = 3;
@@ -125,7 +125,6 @@
     private ActionBarAdapter mActionBarAdapter;
 
     private ContactDetailFragment mContactDetailFragment;
-    private ContactDetailUpdatesFragment mContactDetailUpdatesFragment;
 
     private ContactLoaderFragment mContactDetailLoaderFragment;
     private final ContactDetailLoaderFragmentListener mContactDetailLoaderFragmentListener =
@@ -141,8 +140,8 @@
     private ContactListFilterController mContactListFilterController;
 
     private ContactsUnavailableFragment mContactsUnavailableFragment;
-    private ProviderStatusLoader mProviderStatusLoader;
-    private int mProviderStatus = -1;
+    private ProviderStatusWatcher mProviderStatusWatcher;
+    private ProviderStatusWatcher.Status mProviderStatus;
 
     private boolean mOptionsMenuContactsAvailable;
 
@@ -156,9 +155,8 @@
 
     private View mFavoritesView;
     private View mBrowserView;
-    private View mDetailsView;
-
-    private View mAddGroupImageView;
+    private TransitionAnimationView mContactDetailsView;
+    private TransitionAnimationView mGroupDetailsView;
 
     /** ViewPager for swipe, used only on the phone (i.e. one-pane mode) */
     private ViewPager mTabPager;
@@ -198,7 +196,7 @@
     public PeopleActivity() {
         mInstanceId = sNextInstanceId.getAndIncrement();
         mIntentResolver = new ContactsIntentResolver(this);
-        mProviderStatusLoader = new ProviderStatusLoader(this);
+        mProviderStatusWatcher = ProviderStatusWatcher.getInstance(this);
     }
 
     @Override
@@ -208,7 +206,8 @@
     }
 
     public boolean areContactsAvailable() {
-        return mProviderStatus == ProviderStatus.STATUS_NORMAL;
+        return (mProviderStatus != null)
+                && mProviderStatus.status == ProviderStatus.STATUS_NORMAL;
     }
 
     private boolean areContactWritableAccountsAvailable() {
@@ -236,11 +235,8 @@
     public void onAttachFragment(Fragment fragment) {
         if (fragment instanceof ContactDetailFragment) {
             mContactDetailFragment = (ContactDetailFragment) fragment;
-        } else if (fragment instanceof ContactDetailUpdatesFragment) {
-            mContactDetailUpdatesFragment = (ContactDetailUpdatesFragment) fragment;
         } else if (fragment instanceof ContactsUnavailableFragment) {
             mContactsUnavailableFragment = (ContactsUnavailableFragment)fragment;
-            mContactsUnavailableFragment.setProviderStatusLoader(mProviderStatusLoader);
             mContactsUnavailableFragment.setOnContactsUnavailableActionListener(
                     new ContactsUnavailableFragmentListener());
         }
@@ -262,6 +258,8 @@
         mContactListFilterController.checkFilterValidity(false);
         mContactListFilterController.addListener(this);
 
+        mProviderStatusWatcher.addListener(this);
+
         mIsRecreatedInstance = (savedState != null);
         createViewsAndFragments(savedState);
         if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
@@ -335,7 +333,7 @@
         final FragmentTransaction transaction = fragmentManager.beginTransaction();
 
         // Prepare the fragments which are used both on 1-pane and on 2-pane.
-        boolean isUsingTwoPanes = PhoneCapabilityTester.isUsingTwoPanes(this);
+        final boolean isUsingTwoPanes = PhoneCapabilityTester.isUsingTwoPanes(this);
         if (isUsingTwoPanes) {
             mFavoritesFragment = getFragment(R.id.favorites_fragment);
             mAllFragment = getFragment(R.id.all_fragment);
@@ -391,14 +389,17 @@
 
             // Container views for fragments
             mFavoritesView = getView(R.id.favorites_view);
-            mDetailsView = getView(R.id.details_view);
+            mContactDetailsView = getView(R.id.contact_details_view);
+            mGroupDetailsView = getView(R.id.group_details_view);
             mBrowserView = getView(R.id.browse_view);
 
-            // 2-pane only fragments
-            mFrequentFragment = getFragment(R.id.frequent_fragment);
-            mFrequentFragment.setListener(mFavoritesFragmentListener);
-            mFrequentFragment.setDisplayType(DisplayType.FREQUENT_ONLY);
-            mFrequentFragment.enableQuickContact(true);
+            // Only favorites tab with two panes has a separate frequent fragment
+            if (PhoneCapabilityTester.isUsingTwoPanesInFavorites(this)) {
+                mFrequentFragment = getFragment(R.id.frequent_fragment);
+                mFrequentFragment.setListener(mFavoritesFragmentListener);
+                mFrequentFragment.setDisplayType(DisplayType.FREQUENT_ONLY);
+                mFrequentFragment.enableQuickContact(true);
+            }
 
             mContactDetailLoaderFragment = getFragment(R.id.contact_detail_loader_fragment);
             mContactDetailLoaderFragment.setListener(mContactDetailLoaderFragmentListener);
@@ -414,17 +415,21 @@
 
             // Configure contact details
             mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
-                    getFragmentManager(), findViewById(R.id.contact_detail_container),
+                    getFragmentManager(), mContactDetailsView,
+                    findViewById(R.id.contact_detail_container),
                     new ContactDetailFragmentListener());
         }
         transaction.commitAllowingStateLoss();
         fragmentManager.executePendingTransactions();
 
         // Setting Properties after fragment is created
-        if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
+        if (PhoneCapabilityTester.isUsingTwoPanesInFavorites(this)) {
             mFavoritesFragment.enableQuickContact(true);
             mFavoritesFragment.setDisplayType(DisplayType.STARRED_ONLY);
         } else {
+            // For 2-pane in All and Groups but not in Favorites fragment, show the chevron
+            // for quick contact popup
+            mFavoritesFragment.enableQuickContact(isUsingTwoPanes);
             mFavoritesFragment.setDisplayType(DisplayType.STREQUENT);
         }
 
@@ -475,17 +480,16 @@
     @Override
     protected void onPause() {
         mOptionsMenuContactsAvailable = false;
-
-        mProviderStatus = -1;
-        mProviderStatusLoader.setProviderStatusListener(null);
+        mProviderStatusWatcher.stop();
         super.onPause();
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        mProviderStatusLoader.setProviderStatusListener(this);
-        showContactsUnavailableFragmentIfNecessary();
+
+        mProviderStatusWatcher.start();
+        updateViewConfiguration(true);
 
         // Re-register the listener, which may have been cleared when onSaveInstanceState was
         // called.  See also: onSaveInstanceState
@@ -506,6 +510,8 @@
 
     @Override
     protected void onDestroy() {
+        mProviderStatusWatcher.removeListener(this);
+
         // Some of variables will be null if this Activity redirects Intent.
         // See also onCreate() or other methods called during the Activity's initialization.
         if (mActionBarAdapter != null) {
@@ -523,7 +529,7 @@
             ContactListFilter filter = null;
             int actionCode = mRequest.getActionCode();
             boolean searchMode = mRequest.isSearchMode();
-            TabState tabToOpen = null;
+            final int tabToOpen;
             switch (actionCode) {
                 case ContactsRequest.ACTION_ALL_CONTACTS:
                     filter = ContactListFilter.createFilterWithType(
@@ -544,13 +550,21 @@
                 case ContactsRequest.ACTION_VIEW_CONTACT:
                     // We redirect this intent to the detail activity on 1-pane, so we don't get
                     // here.  It's only for 2-pane.
+                    Uri currentlyLoadedContactUri = mContactDetailFragment.getUri();
+                    if (currentlyLoadedContactUri != null
+                            && !mRequest.getContactUri().equals(currentlyLoadedContactUri)) {
+                        mContactDetailsView.setMaskVisibility(true);
+                    }
                     tabToOpen = TabState.ALL;
                     break;
                 case ContactsRequest.ACTION_GROUP:
                     tabToOpen = TabState.GROUPS;
                     break;
+                default:
+                    tabToOpen = -1;
+                    break;
             }
-            if (tabToOpen != null) {
+            if (tabToOpen != -1) {
                 mActionBarAdapter.setCurrentTab(tabToOpen);
             }
 
@@ -590,6 +604,11 @@
     }
 
     private void setupGroupDetailFragment(Uri groupUri) {
+        // If we are switching from one group to another, do a cross-fade
+        if (mGroupDetailFragment != null && mGroupDetailFragment.getGroupUri() != null &&
+                !UriUtils.areEqual(mGroupDetailFragment.getGroupUri(), groupUri)) {
+            mGroupDetailsView.startMaskTransition(false);
+        }
         mGroupDetailFragment.loadGroup(groupUri);
         invalidateOptionsMenuIfNeeded();
     }
@@ -598,20 +617,20 @@
      * Handler for action bar actions.
      */
     @Override
-    public void onAction(Action action) {
+    public void onAction(int action) {
         switch (action) {
-            case START_SEARCH_MODE:
+            case ActionBarAdapter.Listener.Action.START_SEARCH_MODE:
                 // Tell the fragments that we're in the search mode
                 configureFragments(false /* from request */);
                 updateFragmentsVisibility();
                 invalidateOptionsMenu();
                 break;
-            case STOP_SEARCH_MODE:
+            case ActionBarAdapter.Listener.Action.STOP_SEARCH_MODE:
                 setQueryTextToFragment("");
                 updateFragmentsVisibility();
                 invalidateOptionsMenu();
                 break;
-            case CHANGE_SEARCH_QUERY:
+            case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY:
                 setQueryTextToFragment(mActionBarAdapter.getQueryString());
                 break;
             default:
@@ -629,7 +648,7 @@
      * {@link ActionBarAdapter#isSearchMode()} and {@link ActionBarAdapter#getCurrentTab()}.
      */
     private void updateFragmentsVisibility() {
-        TabState tab = mActionBarAdapter.getCurrentTab();
+        int tab = mActionBarAdapter.getCurrentTab();
 
         // We use ViewPager on 1-pane.
         if (!PhoneCapabilityTester.isUsingTwoPanes(this)) {
@@ -639,9 +658,8 @@
                 // No smooth scrolling if quitting from the search mode.
                 final boolean wasSearchMode = mTabPagerAdapter.isSearchMode();
                 mTabPagerAdapter.setSearchMode(false);
-                int tabIndex = tab.ordinal();
-                if (mTabPager.getCurrentItem() != tabIndex) {
-                    mTabPager.setCurrentItem(tabIndex, !wasSearchMode);
+                if (mTabPager.getCurrentItem() != tab) {
+                    mTabPager.setCurrentItem(tab, !wasSearchMode);
                 }
             }
             invalidateOptionsMenu();
@@ -659,21 +677,24 @@
             tab = TabState.ALL;
         }
         switch (tab) {
-            case FAVORITES:
+            case TabState.FAVORITES:
                 mFavoritesView.setVisibility(View.VISIBLE);
                 mBrowserView.setVisibility(View.GONE);
-                mDetailsView.setVisibility(View.GONE);
+                mGroupDetailsView.setVisibility(View.GONE);
+                mContactDetailsView.setVisibility(View.GONE);
                 break;
-            case GROUPS:
+            case TabState.GROUPS:
                 mFavoritesView.setVisibility(View.GONE);
                 mBrowserView.setVisibility(View.VISIBLE);
-                mDetailsView.setVisibility(View.VISIBLE);
+                mGroupDetailsView.setVisibility(View.VISIBLE);
+                mContactDetailsView.setVisibility(View.GONE);
                 mGroupsFragment.setAddAccountsVisibility(!areGroupWritableAccountsAvailable());
                 break;
-            case ALL:
+            case TabState.ALL:
                 mFavoritesView.setVisibility(View.GONE);
                 mBrowserView.setVisibility(View.VISIBLE);
-                mDetailsView.setVisibility(View.VISIBLE);
+                mContactDetailsView.setVisibility(View.VISIBLE);
+                mGroupDetailsView.setVisibility(View.GONE);
                 break;
         }
         FragmentManager fragmentManager = getFragmentManager();
@@ -682,7 +703,7 @@
         // Note mContactDetailLoaderFragment is an invisible fragment, but we still have to show/
         // hide it so its options menu will be shown/hidden.
         switch (tab) {
-            case FAVORITES:
+            case TabState.FAVORITES:
                 showFragment(ft, mFavoritesFragment);
                 showFragment(ft, mFrequentFragment);
                 hideFragment(ft, mAllFragment);
@@ -691,7 +712,7 @@
                 hideFragment(ft, mGroupsFragment);
                 hideFragment(ft, mGroupDetailFragment);
                 break;
-            case ALL:
+            case TabState.ALL:
                 hideFragment(ft, mFavoritesFragment);
                 hideFragment(ft, mFrequentFragment);
                 showFragment(ft, mAllFragment);
@@ -700,7 +721,7 @@
                 hideFragment(ft, mGroupsFragment);
                 hideFragment(ft, mGroupDetailFragment);
                 break;
-            case GROUPS:
+            case TabState.GROUPS:
                 hideFragment(ft, mFavoritesFragment);
                 hideFragment(ft, mFrequentFragment);
                 hideFragment(ft, mAllFragment);
@@ -720,18 +741,18 @@
         showEmptyStateForTab(tab);
     }
 
-    private void showEmptyStateForTab(TabState tab) {
+    private void showEmptyStateForTab(int tab) {
         if (mContactsUnavailableFragment != null) {
             switch (tab) {
-                case FAVORITES:
+                case TabState.FAVORITES:
                     mContactsUnavailableFragment.setMessageText(
                             R.string.listTotalAllContactsZeroStarred, -1);
                     break;
-                case GROUPS:
+                case TabState.GROUPS:
                     mContactsUnavailableFragment.setMessageText(R.string.noGroups,
                             areGroupWritableAccountsAvailable() ? -1 : R.string.noAccounts);
                     break;
-                case ALL:
+                case TabState.ALL:
                     mContactsUnavailableFragment.setMessageText(R.string.noContacts, -1);
                     break;
             }
@@ -739,6 +760,21 @@
     }
 
     private class TabPagerListener implements ViewPager.OnPageChangeListener {
+
+        // This package-protected constructor is here because of a possible compiler bug.
+        // PeopleActivity$1.class should be generated due to the private outer/inner class access
+        // needed here.  But for some reason, PeopleActivity$1.class is missing.
+        // Since $1 class is needed as a jvm work around to get access to the inner class,
+        // changing the constructor to package-protected or public will solve the problem.
+        // To verify whether $1 class is needed, javap PeopleActivity$TabPagerListener and look for
+        // references to PeopleActivity$1.
+        //
+        // When the constructor is private and PeopleActivity$1.class is missing, proguard will
+        // correctly catch this and throw warnings and error out the build on user/userdebug builds.
+        //
+        // All private inner classes below also need this fix.
+        TabPagerListener() {}
+
         @Override
         public void onPageScrollStateChanged(int state) {
         }
@@ -751,10 +787,9 @@
         public void onPageSelected(int position) {
             // Make sure not in the search mode, in which case position != TabState.ordinal().
             if (!mTabPagerAdapter.isSearchMode()) {
-                TabState selectedTab = TabState.fromInt(position);
-                mActionBarAdapter.setCurrentTab(selectedTab, false);
-                showEmptyStateForTab(selectedTab);
-                if (selectedTab == TabState.GROUPS) {
+                mActionBarAdapter.setCurrentTab(position, false);
+                showEmptyStateForTab(position);
+                if (position == TabState.GROUPS) {
                     mGroupsFragment.setAddAccountsVisibility(!areGroupWritableAccountsAvailable());
                 }
                 invalidateOptionsMenu();
@@ -798,7 +833,7 @@
 
         @Override
         public int getCount() {
-            return mTabPagerAdapterSearchMode ? 1 : TabState.values().length;
+            return mTabPagerAdapterSearchMode ? 1 : TabState.COUNT;
         }
 
         /** Gets called when the number of items changes. */
@@ -810,33 +845,37 @@
                 }
             } else {
                 if (object == mFavoritesFragment) {
-                    return TabState.FAVORITES.ordinal();
+                    return TabState.FAVORITES;
                 }
                 if (object == mAllFragment) {
-                    return TabState.ALL.ordinal();
+                    return TabState.ALL;
                 }
                 if (object == mGroupsFragment) {
-                    return TabState.GROUPS.ordinal();
+                    return TabState.GROUPS;
                 }
             }
             return POSITION_NONE;
         }
 
         @Override
-        public void startUpdate(View container) {
+        public void startUpdate(ViewGroup container) {
         }
 
         private Fragment getFragment(int position) {
             if (mTabPagerAdapterSearchMode) {
-                if (position == 0) {
-                    return mAllFragment;
+                if (position != 0) {
+                    // This has only been observed in monkey tests.
+                    // Let's log this issue, but not crash
+                    Log.w(TAG, "Request fragment at position=" + position + ", eventhough we " +
+                            "are in search mode");
                 }
+                return mAllFragment;
             } else {
-                if (position == TabState.FAVORITES.ordinal()) {
+                if (position == TabState.FAVORITES) {
                     return mFavoritesFragment;
-                } else if (position == TabState.ALL.ordinal()) {
+                } else if (position == TabState.ALL) {
                     return mAllFragment;
-                } else if (position == TabState.GROUPS.ordinal()) {
+                } else if (position == TabState.GROUPS) {
                     return mGroupsFragment;
                 }
             }
@@ -844,7 +883,7 @@
         }
 
         @Override
-        public Object instantiateItem(View container, int position) {
+        public Object instantiateItem(ViewGroup container, int position) {
             if (mCurTransaction == null) {
                 mCurTransaction = mFragmentManager.beginTransaction();
             }
@@ -857,7 +896,7 @@
         }
 
         @Override
-        public void destroyItem(View container, int position, Object object) {
+        public void destroyItem(ViewGroup container, int position, Object object) {
             if (mCurTransaction == null) {
                 mCurTransaction = mFragmentManager.beginTransaction();
             }
@@ -865,7 +904,7 @@
         }
 
         @Override
-        public void finishUpdate(View container) {
+        public void finishUpdate(ViewGroup container) {
             if (mCurTransaction != null) {
                 mCurTransaction.commitAllowingStateLoss();
                 mCurTransaction = null;
@@ -879,7 +918,7 @@
         }
 
         @Override
-        public void setPrimaryItem(View container, int position, Object object) {
+        public void setPrimaryItem(ViewGroup container, int position, Object object) {
             Fragment fragment = (Fragment) object;
             if (mCurrentPrimaryItem != fragment) {
                 if (mCurrentPrimaryItem != null) {
@@ -953,22 +992,25 @@
 
     @Override
     public void onProviderStatusChange() {
-        showContactsUnavailableFragmentIfNecessary();
+        updateViewConfiguration(false);
     }
 
-    private void showContactsUnavailableFragmentIfNecessary() {
-        int providerStatus = mProviderStatusLoader.getProviderStatus();
-        if (providerStatus == mProviderStatus) {
-            return;
-        }
-
+    private void updateViewConfiguration(boolean forceUpdate) {
+        ProviderStatusWatcher.Status providerStatus = mProviderStatusWatcher.getProviderStatus();
+        if (!forceUpdate && (mProviderStatus != null)
+                && (providerStatus.status == mProviderStatus.status)) return;
         mProviderStatus = providerStatus;
 
         View contactsUnavailableView = findViewById(R.id.contacts_unavailable_view);
         View mainView = findViewById(R.id.main_view);
 
-        if (mProviderStatus == ProviderStatus.STATUS_NORMAL) {
+        if (mProviderStatus.status == ProviderStatus.STATUS_NORMAL) {
+            // Ensure that the mTabPager is visible; we may have made it invisible below.
             contactsUnavailableView.setVisibility(View.GONE);
+            if (mTabPager != null) {
+                mTabPager.setVisibility(View.VISIBLE);
+            }
+
             if (mainView != null) {
                 mainView.setVisibility(View.VISIBLE);
             }
@@ -992,28 +1034,33 @@
             }
             if (mContactsUnavailableFragment == null) {
                 mContactsUnavailableFragment = new ContactsUnavailableFragment();
-                mContactsUnavailableFragment.setProviderStatusLoader(mProviderStatusLoader);
                 mContactsUnavailableFragment.setOnContactsUnavailableActionListener(
                         new ContactsUnavailableFragmentListener());
                 getFragmentManager().beginTransaction()
                         .replace(R.id.contacts_unavailable_container, mContactsUnavailableFragment)
                         .commitAllowingStateLoss();
-            } else {
-                mContactsUnavailableFragment.update();
             }
+            mContactsUnavailableFragment.updateStatus(mProviderStatus);
+
+            // Show the contactsUnavailableView, and hide the mTabPager so that we don't
+            // see it sliding in underneath the contactsUnavailableView at the edges.
             contactsUnavailableView.setVisibility(View.VISIBLE);
+            if (mTabPager != null) {
+                mTabPager.setVisibility(View.GONE);
+            }
+
             if (mainView != null) {
                 mainView.setVisibility(View.INVISIBLE);
             }
 
-            TabState tab = mActionBarAdapter.getCurrentTab();
-            showEmptyStateForTab(tab);
+            showEmptyStateForTab(mActionBarAdapter.getCurrentTab());
         }
 
         invalidateOptionsMenuIfNeeded();
     }
 
     private final class ContactBrowserActionListener implements OnContactBrowserActionListener {
+        ContactBrowserActionListener() {}
 
         @Override
         public void onSelectionChange() {
@@ -1028,12 +1075,6 @@
                 setupContactDetailFragment(contactLookupUri);
             } else {
                 Intent intent = new Intent(Intent.ACTION_VIEW, contactLookupUri);
-                // In search mode, the "up" affordance in the contact detail page should return the
-                // user to the search results, so finish the activity when that button is selected.
-                if (mActionBarAdapter.isSearchMode()) {
-                    intent.putExtra(
-                            ContactDetailActivity.INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, true);
-                }
                 startActivity(intent);
             }
         }
@@ -1113,6 +1154,8 @@
     }
 
     private class ContactDetailLoaderFragmentListener implements ContactLoaderFragmentListener {
+        ContactDetailLoaderFragmentListener() {}
+
         @Override
         public void onContactNotFound() {
             // Nothing needs to be done here
@@ -1181,6 +1224,7 @@
 
     private class ContactsUnavailableFragmentListener
             implements OnContactsUnavailableActionListener {
+        ContactsUnavailableFragmentListener() {}
 
         @Override
         public void onCreateNewContactAction() {
@@ -1198,7 +1242,7 @@
 
         @Override
         public void onImportContactsFromFileAction() {
-            ImportExportDialogFragment.show(getFragmentManager());
+            ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable());
         }
 
         @Override
@@ -1209,6 +1253,8 @@
 
     private final class StrequentContactListFragmentListener
             implements ContactTileListFragment.Listener {
+        StrequentContactListFragmentListener() {}
+
         @Override
         public void onContactSelected(Uri contactUri, Rect targetRect) {
             if (PhoneCapabilityTester.isUsingTwoPanes(PeopleActivity.this)) {
@@ -1217,10 +1263,18 @@
                 startActivity(new Intent(Intent.ACTION_VIEW, contactUri));
             }
         }
+
+        @Override
+        public void onCallNumberDirectly(String phoneNumber) {
+            // No need to call phone number directly from People app.
+            Log.w(TAG, "unexpected invocation of onCallNumberDirectly()");
+        }
     }
 
     private final class GroupBrowserActionListener implements OnGroupBrowserActionListener {
 
+        GroupBrowserActionListener() {}
+
         @Override
         public void onViewGroupAction(Uri groupUri) {
             if (PhoneCapabilityTester.isUsingTwoPanes(PeopleActivity.this)) {
@@ -1234,6 +1288,9 @@
     }
 
     private class GroupDetailFragmentListener implements GroupDetailFragment.Listener {
+
+        GroupDetailFragmentListener() {}
+
         @Override
         public void onGroupSizeUpdated(String size) {
             // Nothing needs to be done here because the size will be displayed in the detail
@@ -1288,23 +1345,22 @@
         super.onCreateOptionsMenu(menu);
 
         MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.actions, menu);
+        inflater.inflate(R.menu.people_options, menu);
 
-        // On narrow screens we specify a NEW group button in the {@link ActionBar}, so that
-        // it can be in the overflow menu. On wide screens, we use a custom view because we need
-        // its location for anchoring the account-selector popup.
-        final MenuItem addGroup = menu.findItem(R.id.menu_custom_add_group);
-        if (addGroup != null) {
-            mAddGroupImageView = getLayoutInflater().inflate(
-                    R.layout.add_group_menu_item, null, false);
-            mAddGroupImageView.setOnClickListener(new OnClickListener() {
+        if (DEBUG_TRANSITIONS && mContactDetailLoaderFragment != null) {
+            final MenuItem toggleSocial =
+                    menu.add(mContactDetailLoaderFragment.getLoadStreamItems() ? "less" : "more");
+            toggleSocial.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            toggleSocial.setOnMenuItemClickListener(new OnMenuItemClickListener() {
                 @Override
-                public void onClick(View v) {
-                    createNewGroupWithAccountDisambiguation();
+                public boolean onMenuItemClick(MenuItem item) {
+                    mContactDetailLoaderFragment.toggleLoadStreamItems();
+                    invalidateOptionsMenu();
+                    return false;
                 }
             });
-            addGroup.setActionView(mAddGroupImageView);
         }
+
         return true;
     }
 
@@ -1342,32 +1398,37 @@
             return false;
         }
 
+        // Get references to individual menu items in the menu
         final MenuItem addContactMenu = menu.findItem(R.id.menu_add_contact);
         final MenuItem contactsFilterMenu = menu.findItem(R.id.menu_contacts_filter);
 
         MenuItem addGroupMenu = menu.findItem(R.id.menu_add_group);
-        if (addGroupMenu == null) {
-            addGroupMenu = menu.findItem(R.id.menu_custom_add_group);
-        }
+
+        final MenuItem clearFrequentsMenu = menu.findItem(R.id.menu_clear_frequents);
+        final MenuItem helpMenu = menu.findItem(R.id.menu_help);
 
         final boolean isSearchMode = mActionBarAdapter.isSearchMode();
         if (isSearchMode) {
             addContactMenu.setVisible(false);
             addGroupMenu.setVisible(false);
             contactsFilterMenu.setVisible(false);
+            clearFrequentsMenu.setVisible(false);
+            helpMenu.setVisible(false);
         } else {
             switch (mActionBarAdapter.getCurrentTab()) {
-                case FAVORITES:
+                case TabState.FAVORITES:
                     addContactMenu.setVisible(false);
                     addGroupMenu.setVisible(false);
                     contactsFilterMenu.setVisible(false);
+                    clearFrequentsMenu.setVisible(hasFrequents());
                     break;
-                case ALL:
+                case TabState.ALL:
                     addContactMenu.setVisible(true);
                     addGroupMenu.setVisible(false);
                     contactsFilterMenu.setVisible(true);
+                    clearFrequentsMenu.setVisible(false);
                     break;
-                case GROUPS:
+                case TabState.GROUPS:
                     // Do not display the "new group" button if no accounts are available
                     if (areGroupWritableAccountsAvailable()) {
                         addGroupMenu.setVisible(true);
@@ -1376,8 +1437,10 @@
                     }
                     addContactMenu.setVisible(false);
                     contactsFilterMenu.setVisible(false);
+                    clearFrequentsMenu.setVisible(false);
                     break;
             }
+            HelpUtils.prepareHelpMenuItem(this, helpMenu, R.string.help_url_people_main);
         }
         final boolean showMiscOptions = !isSearchMode;
         makeMenuItemVisible(menu, R.id.menu_search, showMiscOptions);
@@ -1389,6 +1452,18 @@
         return true;
     }
 
+    /**
+     * Returns whether there are any frequently contacted people being displayed
+     * @return
+     */
+    private boolean hasFrequents() {
+        if (PhoneCapabilityTester.isUsingTwoPanesInFavorites(this)) {
+            return mFrequentFragment.hasFrequents();
+        } else {
+            return mFavoritesFragment.hasFrequents();
+        }
+    }
+
     private void makeMenuItemVisible(Menu menu, int itemId, boolean visible) {
         MenuItem item =menu.findItem(itemId);
         if (item != null) {
@@ -1424,8 +1499,9 @@
                 return true;
             }
             case R.id.menu_contacts_filter: {
-                AccountFilterUtil.startAccountFilterActivityForResult(this,
-                        SUBACTIVITY_ACCOUNT_FILTER);
+                AccountFilterUtil.startAccountFilterActivityForResult(
+                        this, SUBACTIVITY_ACCOUNT_FILTER,
+                        mContactListFilterController.getFilter());
                 return true;
             }
             case R.id.menu_search: {
@@ -1438,7 +1514,8 @@
                 // to this activity to display the new contact.
                 if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
                     intent.putExtra(
-                        ContactEditorActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
+                            ContactEditorActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED,
+                            true);
                     startActivityForResult(intent, SUBACTIVITY_NEW_CONTACT);
                 } else {
                     // Otherwise, on 1-pane UI, we need the editor to launch the view contact
@@ -1448,11 +1525,15 @@
                 return true;
             }
             case R.id.menu_add_group: {
-                createNewGroupWithAccountDisambiguation();
+                createNewGroup();
                 return true;
             }
             case R.id.menu_import_export: {
-                ImportExportDialogFragment.show(getFragmentManager());
+                ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable());
+                return true;
+            }
+            case R.id.menu_clear_frequents: {
+                ClearFrequentsDialog.show(getFragmentManager());
                 return true;
             }
             case R.id.menu_accounts: {
@@ -1468,40 +1549,10 @@
         return false;
     }
 
-    private void createNewGroupWithAccountDisambiguation() {
-        final List<AccountWithDataSet> accounts =
-                AccountTypeManager.getInstance(this).getAccounts(true);
-        if (accounts.size() <= 1 || mAddGroupImageView == null) {
-            // No account to choose or no control to anchor the popup-menu to
-            // ==> just go straight to the editor which will disambig if necessary
-            final Intent intent = new Intent(this, GroupEditorActivity.class);
-            intent.setAction(Intent.ACTION_INSERT);
-            startActivityForResult(intent, SUBACTIVITY_NEW_GROUP);
-            return;
-        }
-
-        final ListPopupWindow popup = new ListPopupWindow(this, null);
-        popup.setWidth(getResources().getDimensionPixelSize(R.dimen.account_selector_popup_width));
-        popup.setAnchorView(mAddGroupImageView);
-        // Create a list adapter with all writeable accounts (assume that the writeable accounts all
-        // allow group creation).
-        final AccountsListAdapter adapter = new AccountsListAdapter(this,
-                AccountListFilter.ACCOUNTS_GROUP_WRITABLE);
-        popup.setAdapter(adapter);
-        popup.setOnItemClickListener(new OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                popup.dismiss();
-                AccountWithDataSet account = adapter.getItem(position);
-                final Intent intent = new Intent(PeopleActivity.this, GroupEditorActivity.class);
-                intent.setAction(Intent.ACTION_INSERT);
-                intent.putExtra(Intents.Insert.ACCOUNT, account);
-                intent.putExtra(Intents.Insert.DATA_SET, account.dataSet);
-                startActivityForResult(intent, SUBACTIVITY_NEW_GROUP);
-            }
-        });
-        popup.setModal(true);
-        popup.show();
+    private void createNewGroup() {
+        final Intent intent = new Intent(this, GroupEditorActivity.class);
+        intent.setAction(Intent.ACTION_INSERT);
+        startActivityForResult(intent, SUBACTIVITY_NEW_GROUP);
     }
 
     @Override
@@ -1524,7 +1575,7 @@
                 if (resultCode == RESULT_OK && PhoneCapabilityTester.isUsingTwoPanes(this)) {
                     mRequest.setActionCode(ContactsRequest.ACTION_VIEW_CONTACT);
                     mAllFragment.setSelectionRequired(true);
-                    mAllFragment.reloadDataAndSetSelectedUri(data.getData());
+                    mAllFragment.setSelectedContactUri(data.getData());
                     // Suppress IME if in search mode
                     if (mActionBarAdapter != null) {
                         mActionBarAdapter.clearFocusOnSearchView();
@@ -1581,7 +1632,10 @@
             default: {
                 // Bring up the search UI if the user starts typing
                 final int unicodeChar = event.getUnicodeChar();
-                if (unicodeChar != 0 && !Character.isWhitespace(unicodeChar)) {
+                if ((unicodeChar != 0)
+                        // If COMBINING_ACCENT is set, it's not a unicode character.
+                        && ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) == 0)
+                        && !Character.isWhitespace(unicodeChar)) {
                     String query = new String(new int[]{ unicodeChar }, 0, 1);
                     if (!mActionBarAdapter.isSearchMode()) {
                         mActionBarAdapter.setQueryString(query);
@@ -1637,6 +1691,17 @@
     }
 
     @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        // In our own lifecycle, the focus is saved and restore but later taken away by the
+        // ViewPager. As a hack, we force focus on the SearchView if we know that we are searching.
+        // This fixes the keyboard going away on screen rotation
+        if (mActionBarAdapter.isSearchMode()) {
+            mActionBarAdapter.setFocusOnSearchView();
+        }
+    }
+
+    @Override
     public DialogManager getDialogManager() {
         return mDialogManager;
     }
diff --git a/src/com/android/contacts/activities/PhotoSelectionActivity.java b/src/com/android/contacts/activities/PhotoSelectionActivity.java
new file mode 100644
index 0000000..21cf192
--- /dev/null
+++ b/src/com/android/contacts/activities/PhotoSelectionActivity.java
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2011 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.contacts.activities;
+
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+import com.android.contacts.detail.PhotoSelectionHandler;
+import com.android.contacts.editor.PhotoActionPopup;
+import com.android.contacts.model.EntityDeltaList;
+import com.android.contacts.util.ContactPhotoUtils;
+import com.android.contacts.util.SchedulingUtils;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.view.View;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.FrameLayout.LayoutParams;
+import android.widget.ImageView;
+
+
+/**
+ * Popup activity for choosing a contact photo within the Contacts app.
+ */
+public class PhotoSelectionActivity extends Activity {
+
+    private static final String TAG = "PhotoSelectionActivity";
+
+    /** Number of ms for the animation to expand the photo. */
+    private static final int PHOTO_EXPAND_DURATION = 100;
+
+    /** Number of ms for the animation to contract the photo on activity exit. */
+    private static final int PHOTO_CONTRACT_DURATION = 50;
+
+    /** Number of ms for the animation to hide the backdrop on finish. */
+    private static final int BACKDROP_FADEOUT_DURATION = 100;
+
+    /** Key used to persist photo-filename (NOT full file-path). */
+    private static final String KEY_CURRENT_PHOTO_FILE = "currentphotofile";
+
+    /** Key used to persist whether a sub-activity is currently in progress. */
+    private static final String KEY_SUB_ACTIVITY_IN_PROGRESS = "subinprogress";
+
+    /** Intent extra to get the photo URI. */
+    public static final String PHOTO_URI = "photo_uri";
+
+    /** Intent extra to get the entity delta list. */
+    public static final String ENTITY_DELTA_LIST = "entity_delta_list";
+
+    /** Intent extra to indicate whether the contact is the user's profile. */
+    public static final String IS_PROFILE = "is_profile";
+
+    /** Intent extra to indicate whether the contact is from a directory (non-editable). */
+    public static final String IS_DIRECTORY_CONTACT = "is_directory_contact";
+
+    /**
+     * Intent extra to indicate whether the photo should be animated to show the full contents of
+     * the photo (on a larger portion of the screen) when clicked.  If unspecified or false, the
+     * photo will not move from its original location.
+     */
+    public static final String EXPAND_PHOTO = "expand_photo";
+
+    /** Source bounds of the image that was clicked on. */
+    private Rect mSourceBounds;
+
+    /**
+     * The photo URI. May be null, in which case the default avatar will be used.
+     */
+    private Uri mPhotoUri;
+
+    /** Entity delta list of the contact. */
+    private EntityDeltaList mState;
+
+    /** Whether the contact is the user's profile. */
+    private boolean mIsProfile;
+
+    /** Whether the contact is from a directory. */
+    private boolean mIsDirectoryContact;
+
+    /** Whether to animate the photo to an expanded view covering more of the screen. */
+    private boolean mExpandPhoto;
+
+    /**
+     * Side length (in pixels) of the expanded photo if to be expanded. Photos are expected to
+     * be square.
+     */
+    private int mExpandedPhotoSize;
+
+    /** Height (in pixels) to leave underneath the expanded photo to show the list popup */
+    private int mHeightOffset;
+
+    /** The semi-transparent backdrop. */
+    private View mBackdrop;
+
+    /** The photo view. */
+    private ImageView mPhotoView;
+
+    /** The photo handler attached to this activity, if any. */
+    private PhotoHandler mPhotoHandler;
+
+    /** Animator to expand the photo out to full size. */
+    private ObjectAnimator mPhotoAnimator;
+
+    /** Listener for the animation. */
+    private AnimatorListenerAdapter mAnimationListener;
+
+    /** Whether a change in layout of the photo has occurred that has no animation yet. */
+    private boolean mAnimationPending;
+
+    /** Prior position of the image (for animating). */
+    Rect mOriginalPos = new Rect();
+
+    /** Layout params for the photo view before we started animating. */
+    private LayoutParams mPhotoStartParams;
+
+    /** Layout params for the photo view after we finished animating. */
+    private LayoutParams mPhotoEndParams;
+
+    /** Whether a sub-activity is currently in progress. */
+    private boolean mSubActivityInProgress;
+
+    private boolean mCloseActivityWhenCameBackFromSubActivity;
+
+    /**
+     * A photo result received by the activity, persisted across activity lifecycle.
+     */
+    private PendingPhotoResult mPendingPhotoResult;
+
+    /**
+     * The photo file being interacted with, if any.  Saved/restored between activity instances.
+     */
+    private String mCurrentPhotoFile;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.photoselection_activity);
+        if (savedInstanceState != null) {
+            mCurrentPhotoFile = savedInstanceState.getString(KEY_CURRENT_PHOTO_FILE);
+            mSubActivityInProgress = savedInstanceState.getBoolean(KEY_SUB_ACTIVITY_IN_PROGRESS);
+        }
+
+        // Pull data out of the intent.
+        final Intent intent = getIntent();
+        mPhotoUri = intent.getParcelableExtra(PHOTO_URI);
+        mState = (EntityDeltaList) intent.getParcelableExtra(ENTITY_DELTA_LIST);
+        mIsProfile = intent.getBooleanExtra(IS_PROFILE, false);
+        mIsDirectoryContact = intent.getBooleanExtra(IS_DIRECTORY_CONTACT, false);
+        mExpandPhoto = intent.getBooleanExtra(EXPAND_PHOTO, false);
+
+        // Pull out photo expansion properties from resources
+        mExpandedPhotoSize = getResources().getDimensionPixelSize(
+                R.dimen.detail_contact_photo_expanded_size);
+        mHeightOffset = getResources().getDimensionPixelOffset(
+                R.dimen.expanded_photo_height_offset);
+
+        mBackdrop = findViewById(R.id.backdrop);
+        mPhotoView = (ImageView) findViewById(R.id.photo);
+        mSourceBounds = intent.getSourceBounds();
+
+        // Fade in the background.
+        animateInBackground();
+
+        // Dismiss the dialog on clicking the backdrop.
+        mBackdrop.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finish();
+            }
+        });
+
+        // Wait until the layout pass to show the photo, so that the source bounds will match up.
+        SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
+            @Override
+            public void run() {
+                displayPhoto();
+            }
+        });
+    }
+
+    /**
+     * Compute the adjusted expanded photo size to fit within the enclosing view with the same
+     * aspect ratio.
+     * @param enclosingView This is the view that the photo must fit within.
+     * @param heightOffset This is the amount of height to leave open for the photo action popup.
+     */
+    private int getAdjustedExpandedPhotoSize(View enclosingView, int heightOffset) {
+        // pull out the bounds of the backdrop
+        final Rect bounds = new Rect();
+        enclosingView.getDrawingRect(bounds);
+        final int boundsWidth = bounds.width();
+        final int boundsHeight = bounds.height() - heightOffset;
+
+        // ensure that the new expanded photo size can fit within the backdrop
+        final float alpha = Math.min((float) boundsHeight / (float) mExpandedPhotoSize,
+                (float) boundsWidth / (float) mExpandedPhotoSize);
+        if (alpha < 1.0f) {
+            // need to shrink width and height while maintaining aspect ratio
+            return (int) (alpha * mExpandedPhotoSize);
+        } else {
+            return mExpandedPhotoSize;
+        }
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        // The current look may not seem right on the new configuration, so let's just close self.
+
+        if (!mSubActivityInProgress) {
+            finishImmediatelyWithNoAnimation();
+        } else {
+            // A sub-activity is in progress, so don't close it yet, but close it when we come back
+            // to this activity.
+            mCloseActivityWhenCameBackFromSubActivity = true;
+        }
+    }
+
+    @Override
+    public void finish() {
+        if (!mSubActivityInProgress) {
+            closePhotoAndFinish();
+        } else {
+            finishImmediatelyWithNoAnimation();
+        }
+    }
+
+    /**
+     * Builds a well-formed intent for invoking this activity.
+     * @param context The context.
+     * @param photoUri The URI of the current photo (may be null, in which case the default
+     *     avatar image will be displayed).
+     * @param photoBitmap The bitmap of the current photo (may be null, in which case the default
+     *     avatar image will be displayed).
+     * @param photoBytes The bytes for the current photo (may be null, in which case the default
+     *     avatar image will be displayed).
+     * @param photoBounds The pixel bounds of the current photo.
+     * @param delta The entity delta list for the contact.
+     * @param isProfile Whether the contact is the user's profile.
+     * @param isDirectoryContact Whether the contact comes from a directory (non-editable).
+     * @param expandPhotoOnClick Whether the photo should be expanded on click or not (generally,
+     *     this should be true for phones, and false for tablets).
+     * @return An intent that can be used to invoke the photo selection activity.
+     */
+    public static Intent buildIntent(Context context, Uri photoUri, Bitmap photoBitmap,
+            byte[] photoBytes, Rect photoBounds, EntityDeltaList delta, boolean isProfile,
+            boolean isDirectoryContact, boolean expandPhotoOnClick) {
+        Intent intent = new Intent(context, PhotoSelectionActivity.class);
+        if (photoUri != null && photoBitmap != null && photoBytes != null) {
+            intent.putExtra(PHOTO_URI, photoUri);
+        }
+        intent.setSourceBounds(photoBounds);
+        intent.putExtra(ENTITY_DELTA_LIST, (Parcelable) delta);
+        intent.putExtra(IS_PROFILE, isProfile);
+        intent.putExtra(IS_DIRECTORY_CONTACT, isDirectoryContact);
+        intent.putExtra(EXPAND_PHOTO, expandPhotoOnClick);
+        return intent;
+    }
+
+    private void finishImmediatelyWithNoAnimation() {
+        super.finish();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mPhotoAnimator != null) {
+            mPhotoAnimator.cancel();
+            mPhotoAnimator = null;
+        }
+        if (mPhotoHandler != null) {
+            mPhotoHandler.destroy();
+            mPhotoHandler = null;
+        }
+    }
+
+    private void displayPhoto() {
+        // Animate the photo view into its end location.
+        final int[] pos = new int[2];
+        mBackdrop.getLocationOnScreen(pos);
+        LayoutParams layoutParams = new LayoutParams(mSourceBounds.width(),
+                mSourceBounds.height());
+        mOriginalPos.left = mSourceBounds.left - pos[0];
+        mOriginalPos.top = mSourceBounds.top - pos[1];
+        mOriginalPos.right = mOriginalPos.left + mSourceBounds.width();
+        mOriginalPos.bottom = mOriginalPos.top + mSourceBounds.height();
+        layoutParams.setMargins(mOriginalPos.left, mOriginalPos.top, mOriginalPos.right,
+                mOriginalPos.bottom);
+        mPhotoStartParams = layoutParams;
+        mPhotoView.setLayoutParams(layoutParams);
+        mPhotoView.requestLayout();
+
+        // Load the photo.
+        int photoWidth = getPhotoEndParams().width;
+        if (mPhotoUri != null) {
+            // If we have a URI, the bitmap should be cached directly.
+            ContactPhotoManager.getInstance(this).loadPhoto(mPhotoView, mPhotoUri, photoWidth,
+                    false);
+        } else {
+            // Fall back to avatar image.
+            mPhotoView.setImageResource(ContactPhotoManager.getDefaultAvatarResId(this, photoWidth,
+                    false));
+        }
+
+        mPhotoView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                if (mAnimationPending) {
+                    mAnimationPending = false;
+                    PropertyValuesHolder pvhLeft =
+                            PropertyValuesHolder.ofInt("left", mOriginalPos.left, left);
+                    PropertyValuesHolder pvhTop =
+                            PropertyValuesHolder.ofInt("top", mOriginalPos.top, top);
+                    PropertyValuesHolder pvhRight =
+                            PropertyValuesHolder.ofInt("right", mOriginalPos.right, right);
+                    PropertyValuesHolder pvhBottom =
+                            PropertyValuesHolder.ofInt("bottom", mOriginalPos.bottom, bottom);
+                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(mPhotoView,
+                            pvhLeft, pvhTop, pvhRight, pvhBottom).setDuration(
+                            PHOTO_EXPAND_DURATION);
+                    if (mAnimationListener != null) {
+                        anim.addListener(mAnimationListener);
+                    }
+                    anim.start();
+                }
+            }
+        });
+        attachPhotoHandler();
+    }
+
+    /**
+     * This sets the photo's layout params at the end of the animation.
+     * <p>
+     * The scheme is to enlarge the photo to the desired size with the enlarged photo shifted
+     * to the top left of the screen as much as possible while keeping the underlying smaller
+     * photo occluded.
+     */
+    private LayoutParams getPhotoEndParams() {
+        if (mPhotoEndParams == null) {
+            mPhotoEndParams = new LayoutParams(mPhotoStartParams);
+            if (mExpandPhoto) {
+                final int adjustedPhotoSize = getAdjustedExpandedPhotoSize(mBackdrop,
+                        mHeightOffset);
+                int widthDelta = adjustedPhotoSize - mPhotoStartParams.width;
+                int heightDelta = adjustedPhotoSize - mPhotoStartParams.height;
+                if (widthDelta >= 1 || heightDelta >= 1) {
+                    // This is an actual expansion.
+                    mPhotoEndParams.width = adjustedPhotoSize;
+                    mPhotoEndParams.height = adjustedPhotoSize;
+                    mPhotoEndParams.topMargin =
+                            Math.max(mPhotoStartParams.topMargin - heightDelta, 0);
+                    mPhotoEndParams.leftMargin =
+                            Math.max(mPhotoStartParams.leftMargin - widthDelta, 0);
+                    mPhotoEndParams.bottomMargin = 0;
+                    mPhotoEndParams.rightMargin = 0;
+                }
+            }
+        }
+        return mPhotoEndParams;
+    }
+
+    private void animatePhotoOpen() {
+        mAnimationListener = new AnimatorListenerAdapter() {
+            private void capturePhotoPos() {
+                mPhotoView.requestLayout();
+                mOriginalPos.left = mPhotoView.getLeft();
+                mOriginalPos.top = mPhotoView.getTop();
+                mOriginalPos.right = mPhotoView.getRight();
+                mOriginalPos.bottom = mPhotoView.getBottom();
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                capturePhotoPos();
+                if (mPhotoHandler != null) {
+                    mPhotoHandler.onClick(mPhotoView);
+                }
+            }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                capturePhotoPos();
+            }
+        };
+        animatePhoto(getPhotoEndParams());
+    }
+
+    private void closePhotoAndFinish() {
+        mAnimationListener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                // After the photo animates down, fade it away and finish.
+                ObjectAnimator anim = ObjectAnimator.ofFloat(
+                        mPhotoView, "alpha", 0f).setDuration(PHOTO_CONTRACT_DURATION);
+                anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        finishImmediatelyWithNoAnimation();
+                    }
+                });
+                anim.start();
+            }
+        };
+
+        animatePhoto(mPhotoStartParams);
+        animateAwayBackground();
+    }
+
+    private void animatePhoto(MarginLayoutParams to) {
+        // Cancel any existing animation.
+        if (mPhotoAnimator != null) {
+            mPhotoAnimator.cancel();
+        }
+
+        mPhotoView.setLayoutParams(to);
+        mAnimationPending = true;
+        mPhotoView.requestLayout();
+    }
+
+    private void animateInBackground() {
+        ObjectAnimator.ofFloat(mBackdrop, "alpha", 0, 0.5f).setDuration(
+                PHOTO_EXPAND_DURATION).start();
+    }
+
+    private void animateAwayBackground() {
+        ObjectAnimator.ofFloat(mBackdrop, "alpha", 0f).setDuration(
+                BACKDROP_FADEOUT_DURATION).start();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile);
+        outState.putBoolean(KEY_SUB_ACTIVITY_IN_PROGRESS, mSubActivityInProgress);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (mPhotoHandler != null) {
+            mSubActivityInProgress = false;
+            if (mPhotoHandler.handlePhotoActivityResult(requestCode, resultCode, data)) {
+                // Clear out any pending photo result.
+                mPendingPhotoResult = null;
+            } else {
+                // User cancelled the sub-activity and returning to the photo selection activity.
+                if (mCloseActivityWhenCameBackFromSubActivity) {
+                    finishImmediatelyWithNoAnimation();
+                } else {
+                    // Re-display options.
+                    mPhotoHandler.onClick(mPhotoView);
+                }
+            }
+        } else {
+            // Create a pending photo result to be handled when the photo handler is created.
+            mPendingPhotoResult = new PendingPhotoResult(requestCode, resultCode, data);
+        }
+    }
+
+    private void attachPhotoHandler() {
+        // Always provide the same two choices (take a photo with the camera, select a photo
+        // from the gallery), but with slightly different wording.
+        // Note: don't worry about this being a read-only contact; this code will not be invoked.
+        int mode = (mPhotoUri == null) ? PhotoActionPopup.Modes.NO_PHOTO
+                : PhotoActionPopup.Modes.PHOTO_DISALLOW_PRIMARY;
+        // We don't want to provide a choice to remove the photo for two reasons:
+        //   1) the UX designs don't call for it
+        //   2) even if we wanted to, the implementation would be moderately hairy
+        mode &= ~PhotoActionPopup.Flags.REMOVE_PHOTO;
+
+        mPhotoHandler = new PhotoHandler(this, mPhotoView, mode, mState);
+
+        if (mPendingPhotoResult != null) {
+            mPhotoHandler.handlePhotoActivityResult(mPendingPhotoResult.mRequestCode,
+                    mPendingPhotoResult.mResultCode, mPendingPhotoResult.mData);
+            mPendingPhotoResult = null;
+        } else {
+            // Setting the photo in displayPhoto() resulted in a relayout
+            // request... to avoid jank, wait until this layout has happened.
+            SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
+                @Override
+                public void run() {
+                    animatePhotoOpen();
+                }
+            });
+        }
+    }
+
+    private final class PhotoHandler extends PhotoSelectionHandler {
+        private final PhotoActionListener mListener;
+
+        private PhotoHandler(
+                Context context, View photoView, int photoMode, EntityDeltaList state) {
+            super(context, photoView, photoMode, PhotoSelectionActivity.this.mIsDirectoryContact,
+                    state);
+            mListener = new PhotoListener();
+        }
+
+        @Override
+        public PhotoActionListener getListener() {
+            return mListener;
+        }
+
+        @Override
+        public void startPhotoActivity(Intent intent, int requestCode, String photoFile) {
+            mSubActivityInProgress = true;
+            mCurrentPhotoFile = photoFile;
+            PhotoSelectionActivity.this.startActivityForResult(intent, requestCode);
+        }
+
+        private final class PhotoListener extends PhotoActionListener {
+            @Override
+            public void onPhotoSelected(Bitmap bitmap) {
+                EntityDeltaList delta = getDeltaForAttachingPhotoToContact();
+                long rawContactId = getWritableEntityId();
+                final String croppedPath = ContactPhotoUtils.pathForCroppedPhoto(
+                        PhotoSelectionActivity.this, mCurrentPhotoFile);
+                Intent intent = ContactSaveService.createSaveContactIntent(
+                        mContext, delta, "", 0, mIsProfile, null, null, rawContactId, croppedPath);
+                startService(intent);
+                finish();
+            }
+
+            @Override
+            public String getCurrentPhotoFile() {
+                return mCurrentPhotoFile;
+            }
+
+            @Override
+            public void onPhotoSelectionDismissed() {
+                if (!mSubActivityInProgress) {
+                    finish();
+                }
+            }
+        }
+    }
+
+    private static class PendingPhotoResult {
+        final private int mRequestCode;
+        final private int mResultCode;
+        final private Intent mData;
+        private PendingPhotoResult(int requestCode, int resultCode, Intent data) {
+            mRequestCode = requestCode;
+            mResultCode = resultCode;
+            mData = data;
+        }
+    }
+}
diff --git a/src/com/android/contacts/activities/ShowOrCreateActivity.java b/src/com/android/contacts/activities/ShowOrCreateActivity.java
index c60d0fb..2efd6ba 100755
--- a/src/com/android/contacts/activities/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/activities/ShowOrCreateActivity.java
@@ -24,7 +24,6 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.SearchManager;
 import android.content.ComponentName;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -122,14 +121,12 @@
         // Handle specific query request
         if (Constants.SCHEME_MAILTO.equals(scheme)) {
             mCreateExtras.putString(Intents.Insert.EMAIL, ssp);
-            mCreateExtras.putString(SearchManager.QUERY, ssp);
 
             Uri uri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(ssp));
             mQueryHandler.startQuery(QUERY_TOKEN, null, uri, CONTACTS_PROJECTION, null, null, null);
 
         } else if (Constants.SCHEME_TEL.equals(scheme)) {
             mCreateExtras.putString(Intents.Insert.PHONE, ssp);
-            mCreateExtras.putString(SearchManager.QUERY, ssp);
 
             Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, ssp);
             mQueryHandler.startQuery(QUERY_TOKEN, null, uri, PHONES_PROJECTION, null, null, null);
@@ -216,7 +213,6 @@
                         R.string.add_contact_dlg_message_fmt, mCreateDescrip);
 
                 return new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT)
-                        .setTitle(R.string.add_contact_dlg_title)
                         .setMessage(message)
                         .setPositiveButton(android.R.string.ok,
                                 new IntentClickListener(this, createIntent))
diff --git a/src/com/android/contacts/activities/TransactionSafeActivity.java b/src/com/android/contacts/activities/TransactionSafeActivity.java
index ab80b42..b177665 100644
--- a/src/com/android/contacts/activities/TransactionSafeActivity.java
+++ b/src/com/android/contacts/activities/TransactionSafeActivity.java
@@ -23,7 +23,7 @@
  * A common superclass that keeps track of whether an {@link Activity} has saved its state yet or
  * not.
  */
-public class TransactionSafeActivity extends Activity {
+public abstract class TransactionSafeActivity extends Activity {
 
     private boolean mIsSafeToCommitTransactions;
 
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
index 22b85d7..7b6ae63 100644
--- a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
+++ b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
@@ -72,6 +72,12 @@
     }
 
     @Override
+    public boolean isEnabled(int position) {
+        // None of history will be clickable.
+        return false;
+    }
+
+    @Override
     public int getCount() {
         return mPhoneCallDetails.length + 1;
     }
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
index 99ba8e8..2275a3d 100644
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ b/src/com/android/contacts/calllog/CallLogAdapter.java
@@ -48,7 +48,7 @@
  * Adapter class to fill in data for the Call Log.
  */
 /*package*/ class CallLogAdapter extends GroupingListAdapter
-        implements Runnable, ViewTreeObserver.OnPreDrawListener, CallLogGroupBuilder.GroupCreator {
+        implements ViewTreeObserver.OnPreDrawListener, CallLogGroupBuilder.GroupCreator {
     /** Interface used to initiate a refresh of the content. */
     public interface CallFetcher {
         public void fetchCalls();
@@ -94,6 +94,7 @@
     private final Context mContext;
     private final ContactInfoHelper mContactInfoHelper;
     private final CallFetcher mCallFetcher;
+    private ViewTreeObserver mViewTreeObserver = null;
 
     /**
      * A cache of the contact details for the phone numbers in the call log.
@@ -159,14 +160,11 @@
      */
     private final LinkedList<ContactInfoRequest> mRequests;
 
-    private volatile boolean mDone;
     private boolean mLoading = true;
-    private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
     private static final int REDRAW = 1;
     private static final int START_THREAD = 2;
 
-    private boolean mFirst;
-    private Thread mCallerIdThread;
+    private QueryThread mCallerIdThread;
 
     /** Instance of helper class for managing views. */
     private final CallLogListItemHelper mCallLogViewsHelper;
@@ -204,11 +202,15 @@
 
     @Override
     public boolean onPreDraw() {
-        if (mFirst) {
-            mHandler.sendEmptyMessageDelayed(START_THREAD,
-                    START_PROCESSING_REQUESTS_DELAY_MILLIS);
-            mFirst = false;
+        // We only wanted to listen for the first draw (and this is it).
+        unregisterPreDrawListener();
+
+        // Only schedule a thread-creation message if the thread hasn't been
+        // created yet. This is purely an optimization, to queue fewer messages.
+        if (mCallerIdThread == null) {
+            mHandler.sendEmptyMessageDelayed(START_THREAD, START_PROCESSING_REQUESTS_DELAY_MILLIS);
         }
+
         return true;
     }
 
@@ -236,7 +238,6 @@
 
         mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
         mRequests = new LinkedList<ContactInfoRequest>();
-        mPreDrawListener = null;
 
         Resources resources = mContext.getResources();
         CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
@@ -273,35 +274,53 @@
         }
     }
 
-    private void startRequestProcessing() {
-        if (mRequestProcessingDisabled) {
-            return;
-        }
+    /**
+     * Starts a background thread to process contact-lookup requests, unless one
+     * has already been started.
+     */
+    private synchronized void startRequestProcessing() {
+        // For unit-testing.
+        if (mRequestProcessingDisabled) return;
 
-        mDone = false;
-        mCallerIdThread = new Thread(this, "CallLogContactLookup");
+        // Idempotence... if a thread is already started, don't start another.
+        if (mCallerIdThread != null) return;
+
+        mCallerIdThread = new QueryThread();
         mCallerIdThread.setPriority(Thread.MIN_PRIORITY);
         mCallerIdThread.start();
     }
 
     /**
-     * Stops the background thread that processes updates and cancels any pending requests to
-     * start it.
-     * <p>
-     * Should be called from the main thread to prevent a race condition between the request to
-     * start the thread being processed and stopping the thread.
+     * Stops the background thread that processes updates and cancels any
+     * pending requests to start it.
      */
-    public void stopRequestProcessing() {
+    public synchronized void stopRequestProcessing() {
         // Remove any pending requests to start the processing thread.
         mHandler.removeMessages(START_THREAD);
-        mDone = true;
-        if (mCallerIdThread != null) mCallerIdThread.interrupt();
+        if (mCallerIdThread != null) {
+            // Stop the thread; we are finished with it.
+            mCallerIdThread.stopProcessing();
+            mCallerIdThread.interrupt();
+            mCallerIdThread = null;
+        }
+    }
+
+    /**
+     * Stop receiving onPreDraw() notifications.
+     */
+    private void unregisterPreDrawListener() {
+        if (mViewTreeObserver != null && mViewTreeObserver.isAlive()) {
+            mViewTreeObserver.removeOnPreDrawListener(this);
+        }
+        mViewTreeObserver = null;
     }
 
     public void invalidateCache() {
         mContactInfoCache.expireAll();
-        // Let it restart the thread after next draw
-        mPreDrawListener = null;
+
+        // Restart the request-processing thread after the next draw.
+        stopRequestProcessing();
+        unregisterPreDrawListener();
     }
 
     /**
@@ -323,10 +342,7 @@
                 mRequests.notifyAll();
             }
         }
-        if (mFirst && immediate) {
-            startRequestProcessing();
-            mFirst = false;
-        }
+        if (immediate) startRequestProcessing();
     }
 
     /**
@@ -352,7 +368,8 @@
         // view.
         NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
         ContactInfo existingInfo = mContactInfoCache.getPossiblyExpired(numberCountryIso);
-        boolean updated = !info.equals(existingInfo);
+        boolean updated = (existingInfo != ContactInfo.EMPTY) && !info.equals(existingInfo);
+
         // Store the data in the cache so that the UI thread can use to display it. Store it
         // even if it has not changed so that it is marked as not expired.
         mContactInfoCache.put(numberCountryIso, info);
@@ -361,34 +378,60 @@
         updateCallLogContactInfoCache(number, countryIso, info, callLogInfo);
         return updated;
     }
+
     /*
-     * Handles requests for contact name and number type
-     * @see java.lang.Runnable#run()
+     * Handles requests for contact name and number type.
      */
-    @Override
-    public void run() {
-        boolean needNotify = false;
-        while (!mDone) {
-            ContactInfoRequest request = null;
-            synchronized (mRequests) {
-                if (!mRequests.isEmpty()) {
-                    request = mRequests.removeFirst();
-                } else {
-                    if (needNotify) {
-                        needNotify = false;
-                        mHandler.sendEmptyMessage(REDRAW);
-                    }
-                    try {
-                        mRequests.wait(1000);
-                    } catch (InterruptedException ie) {
-                        // Ignore and continue processing requests
-                        Thread.currentThread().interrupt();
+    private class QueryThread extends Thread {
+        private volatile boolean mDone = false;
+
+        public QueryThread() {
+            super("CallLogAdapter.QueryThread");
+        }
+
+        public void stopProcessing() {
+            mDone = true;
+        }
+
+        @Override
+        public void run() {
+            boolean needRedraw = false;
+            while (true) {
+                // Check if thread is finished, and if so return immediately.
+                if (mDone) return;
+
+                // Obtain next request, if any is available.
+                // Keep synchronized section small.
+                ContactInfoRequest req = null;
+                synchronized (mRequests) {
+                    if (!mRequests.isEmpty()) {
+                        req = mRequests.removeFirst();
                     }
                 }
-            }
-            if (!mDone && request != null
-                    && queryContactInfo(request.number, request.countryIso, request.callLogInfo)) {
-                needNotify = true;
+
+                if (req != null) {
+                    // Process the request. If the lookup succeeds, schedule a
+                    // redraw.
+                    needRedraw |= queryContactInfo(req.number, req.countryIso, req.callLogInfo);
+                } else {
+                    // Throttle redraw rate by only sending them when there are
+                    // more requests.
+                    if (needRedraw) {
+                        needRedraw = false;
+                        mHandler.sendEmptyMessage(REDRAW);
+                    }
+
+                    // Wait until another request is available, or until this
+                    // thread is no longer needed (as indicated by being
+                    // interrupted).
+                    try {
+                        synchronized (mRequests) {
+                            mRequests.wait(1000);
+                        }
+                    } catch (InterruptedException ie) {
+                        // Ignore, and attempt to continue processing requests.
+                    }
+                }
             }
         }
     }
@@ -566,10 +609,9 @@
         setPhoto(views, photoId, lookupUri);
 
         // Listen for the first draw
-        if (mPreDrawListener == null) {
-            mFirst = true;
-            mPreDrawListener = this;
-            view.getViewTreeObserver().addOnPreDrawListener(this);
+        if (mViewTreeObserver == null) {
+            mViewTreeObserver = view.getViewTreeObserver();
+            mViewTreeObserver.addOnPreDrawListener(this);
         }
     }
 
@@ -646,9 +688,7 @@
             needsUpdate = true;
         }
 
-        if (!needsUpdate) {
-            return;
-        }
+        if (!needsUpdate) return;
 
         if (countryIso == null) {
             mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
@@ -697,7 +737,7 @@
 
     private void setPhoto(CallLogListItemViews views, long photoId, Uri contactUri) {
         views.quickContactView.assignContactUri(contactUri);
-        mContactPhotoManager.loadPhoto(views.quickContactView, photoId, false, true);
+        mContactPhotoManager.loadThumbnail(views.quickContactView, photoId, true);
     }
 
     /**
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index d9606cb..fcd1780 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -19,7 +19,7 @@
 import com.android.common.io.MoreCloseables;
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
-import com.android.contacts.activities.DialtactsActivity.ViewPagerVisibilityListener;
+import com.android.contacts.util.Constants;
 import com.android.contacts.util.EmptyLoader;
 import com.android.contacts.voicemail.VoicemailStatusHelper;
 import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
@@ -33,11 +33,15 @@
 import android.app.ListFragment;
 import android.content.Context;
 import android.content.Intent;
+import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.provider.CallLog;
+import android.provider.ContactsContract;
 import android.provider.CallLog.Calls;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
@@ -56,8 +60,8 @@
 /**
  * Displays a list of call log entries.
  */
-public class CallLogFragment extends ListFragment implements ViewPagerVisibilityListener,
-        CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher {
+public class CallLogFragment extends ListFragment
+        implements CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher {
     private static final String TAG = "CallLogFragment";
 
     /**
@@ -69,7 +73,6 @@
     private CallLogQueryHandler mCallLogQueryHandler;
     private boolean mScrollToTop;
 
-    private boolean mShowOptionsMenu;
     /** Whether there is at least one voicemail source installed. */
     private boolean mVoicemailSourcesAvailable = false;
     /** Whether we are currently filtering over voicemail. */
@@ -85,6 +88,26 @@
     private boolean mCallLogFetched;
     private boolean mVoicemailStatusFetched;
 
+    private final Handler mHandler = new Handler();
+
+    private class CustomContentObserver extends ContentObserver {
+        public CustomContentObserver() {
+            super(mHandler);
+        }
+        @Override
+        public void onChange(boolean selfChange) {
+            mRefreshDataRequired = true;
+        }
+    }
+
+    // See issue 6363009
+    private final ContentObserver mCallLogObserver = new CustomContentObserver();
+    private final ContentObserver mContactsObserver = new CustomContentObserver();
+    private boolean mRefreshDataRequired = true;
+
+    // Exactly same variable is in Fragment as a package private.
+    private boolean mMenuVisible = true;
+
     @Override
     public void onCreate(Bundle state) {
         super.onCreate(state);
@@ -92,6 +115,10 @@
         mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), this);
         mKeyguardManager =
                 (KeyguardManager) getActivity().getSystemService(Context.KEYGUARD_SERVICE);
+        getActivity().getContentResolver().registerContentObserver(
+                CallLog.CONTENT_URI, true, mCallLogObserver);
+        getActivity().getContentResolver().registerContentObserver(
+                ContactsContract.Contacts.CONTENT_URI, true, mContactsObserver);
         setHasOptionsMenu(true);
     }
 
@@ -107,10 +134,25 @@
         getActivity().invalidateOptionsMenu();
         if (mScrollToTop) {
             final ListView listView = getListView();
+            // The smooth-scroll animation happens over a fixed time period.
+            // As a result, if it scrolls through a large portion of the list,
+            // each frame will jump so far from the previous one that the user
+            // will not experience the illusion of downward motion.  Instead,
+            // if we're not already near the top of the list, we instantly jump
+            // near the top, and animate from there.
             if (listView.getFirstVisiblePosition() > 5) {
                 listView.setSelection(5);
             }
-            listView.smoothScrollToPosition(0);
+            // Workaround for framework issue: the smooth-scroll doesn't
+            // occur if setSelection() is called immediately before.
+            mHandler.post(new Runnable() {
+               @Override
+               public void run() {
+                   if (getActivity() == null || getActivity().isFinishing()) return;
+                   listView.smoothScrollToPosition(0);
+               }
+            });
+
             mScrollToTop = false;
         }
         mCallLogFetched = true;
@@ -173,10 +215,22 @@
         getListView().setItemsCanFocus(true);
     }
 
+    /**
+     * Based on the new intent, decide whether the list should be configured
+     * to scroll up to display the first item.
+     */
+    public void configureScreenFromIntent(Intent newIntent) {
+        // Typically, when switching to the call-log we want to show the user
+        // the same section of the list that they were most recently looking
+        // at.  However, under some circumstances, we want to automatically
+        // scroll to the top of the list to present the newest call items.
+        // For example, immediately after a call is finished, we want to
+        // display information about that call.
+        mScrollToTop = Calls.CONTENT_TYPE.equals(newIntent.getType());
+    }
+
     @Override
     public void onStart() {
-        mScrollToTop = true;
-
         // Start the empty loader now to defer other fragments.  We destroy it when both calllog
         // and the voicemail status are fetched.
         getLoaderManager().initLoader(EMPTY_LOADER_ID, null,
@@ -238,6 +292,8 @@
         super.onDestroy();
         mAdapter.stopRequestProcessing();
         mAdapter.changeCursor(null);
+        getActivity().getContentResolver().unregisterContentObserver(mCallLogObserver);
+        getActivity().getContentResolver().unregisterContentObserver(mContactsObserver);
     }
 
     @Override
@@ -265,24 +321,20 @@
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
-        if (mShowOptionsMenu) {
-            inflater.inflate(R.menu.call_log_options, menu);
-        }
+        inflater.inflate(R.menu.call_log_options, menu);
     }
 
     @Override
     public void onPrepareOptionsMenu(Menu menu) {
-        if (mShowOptionsMenu) {
-            final MenuItem itemDeleteAll = menu.findItem(R.id.delete_all);
-            // Check if all the menu items are inflated correctly. As a shortcut, we assume all
-            // menu items are ready if the first item is non-null.
-            if (itemDeleteAll != null) {
-                itemDeleteAll.setEnabled(mAdapter != null && !mAdapter.isEmpty());
-                menu.findItem(R.id.show_voicemails_only).setVisible(
-                        mVoicemailSourcesAvailable && !mShowingVoicemailOnly);
-                menu.findItem(R.id.show_all_calls).setVisible(
-                        mVoicemailSourcesAvailable && mShowingVoicemailOnly);
-            }
+        final MenuItem itemDeleteAll = menu.findItem(R.id.delete_all);
+        // Check if all the menu items are inflated correctly. As a shortcut, we assume all
+        // menu items are ready if the first item is non-null.
+        if (itemDeleteAll != null) {
+            itemDeleteAll.setEnabled(mAdapter != null && !mAdapter.isEmpty());
+            menu.findItem(R.id.show_voicemails_only).setVisible(
+                    mVoicemailSourcesAvailable && !mShowingVoicemailOnly);
+            menu.findItem(R.id.show_all_calls).setVisible(
+                    mVoicemailSourcesAvailable && mShowingVoicemailOnly);
         }
     }
 
@@ -329,8 +381,8 @@
             Intent intent;
             // If "number" is really a SIP address, construct a sip: URI.
             if (PhoneNumberUtils.isUriNumber(number)) {
-                intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                                    Uri.fromParts("sip", number, null));
+                intent = ContactsUtils.getCallIntent(
+                        Uri.fromParts(Constants.SCHEME_SIP, number, null));
             } else {
                 // We're calling a regular PSTN phone number.
                 // Construct a tel: URI, but do some other possible cleanup first.
@@ -342,8 +394,8 @@
                     String countryIso = cursor.getString(CallLogQuery.COUNTRY_ISO);
                     number = mAdapter.getBetterNumberFromContacts(number, countryIso);
                 }
-                intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                                    Uri.fromParts("tel", number, null));
+                intent = ContactsUtils.getCallIntent(
+                        Uri.fromParts(Constants.SCHEME_TEL, number, null));
             }
             intent.setFlags(
                     Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
@@ -357,33 +409,30 @@
     }
 
     @Override
-    public void onVisibilityChanged(boolean visible) {
-        if (mShowOptionsMenu != visible) {
-            mShowOptionsMenu = visible;
-            // Invalidate the options menu since we are changing the list of options shown in it.
-            Activity activity = getActivity();
-            if (activity != null) {
-                activity.invalidateOptionsMenu();
+    public void setMenuVisibility(boolean menuVisible) {
+        super.setMenuVisibility(menuVisible);
+        if (mMenuVisible != menuVisible) {
+            mMenuVisible = menuVisible;
+            if (!menuVisible) {
+                updateOnExit();
+            } else if (isResumed()) {
+                refreshData();
             }
         }
-
-        if (visible && isResumed()) {
-            refreshData();
-        }
-
-        if (!visible) {
-            updateOnExit();
-        }
     }
 
     /** Requests updates to the data to be shown. */
     private void refreshData() {
-        // Mark all entries in the contact info cache as out of date, so they will be looked up
-        // again once being shown.
-        mAdapter.invalidateCache();
-        startCallsQuery();
-        startVoicemailStatusQuery();
-        updateOnEntry();
+        // Prevent unnecessary refresh.
+        if (mRefreshDataRequired) {
+            // Mark all entries in the contact info cache as out of date, so they will be looked up
+            // again once being shown.
+            mAdapter.invalidateCache();
+            startCallsQuery();
+            startVoicemailStatusQuery();
+            updateOnEntry();
+            mRefreshDataRequired = false;
+        }
     }
 
     /** Removes the missed call notifications. */
@@ -415,7 +464,8 @@
     private void updateOnTransition(boolean onEntry) {
         // We don't want to update any call data when keyguard is on because the user has likely not
         // seen the new calls yet.
-        if (!mKeyguardManager.inKeyguardRestrictedInputMode()) {
+        // This might be called before onCreate() and thus we need to check null explicitly.
+        if (mKeyguardManager != null && !mKeyguardManager.inKeyguardRestrictedInputMode()) {
             // On either of the transitions we reset the new flag and update the notifications.
             // While exiting we additionally consume all missed calls (by marking them as read).
             // This will ensure that they no more appear in the "new" section when we return back.
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index bfedba5..9485b54 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -45,7 +45,7 @@
     public CallLogListItemHelper(PhoneCallDetailsHelper phoneCallDetailsHelper,
             PhoneNumberHelper phoneNumberHelper, Resources resources) {
         mPhoneCallDetailsHelper = phoneCallDetailsHelper;
-        mPhoneNumberHelper= phoneNumberHelper;
+        mPhoneNumberHelper = phoneNumberHelper;
         mResources = resources;
     }
 
diff --git a/src/com/android/contacts/calllog/CallLogListItemViews.java b/src/com/android/contacts/calllog/CallLogListItemViews.java
index 741d218..503de43 100644
--- a/src/com/android/contacts/calllog/CallLogListItemViews.java
+++ b/src/com/android/contacts/calllog/CallLogListItemViews.java
@@ -18,6 +18,7 @@
 
 import com.android.contacts.PhoneCallDetailsViews;
 import com.android.contacts.R;
+import com.android.contacts.test.NeededForTesting;
 
 import android.content.Context;
 import android.view.View;
@@ -68,6 +69,7 @@
                 view.findViewById(R.id.call_log_divider));
     }
 
+    @NeededForTesting
     public static CallLogListItemViews createForTest(Context context) {
         return new CallLogListItemViews(
                 new QuickContactBadge(context),
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
index affdd1d..edc631f 100644
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ b/src/com/android/contacts/calllog/CallLogQueryHandler.java
@@ -59,7 +59,6 @@
     private static final int UPDATE_MARK_VOICEMAILS_AS_OLD_TOKEN = 56;
     /** The token for the query to mark all missed calls as read after seeing the call log. */
     private static final int UPDATE_MARK_MISSED_CALL_AS_READ_TOKEN = 57;
-
     /** The token for the query to fetch voicemail status messages. */
     private static final int QUERY_VOICEMAIL_STATUS_TOKEN = 58;
 
@@ -75,6 +74,24 @@
     @GuardedBy("this") private Cursor mNewCallsCursor;
     /** The cursor containing the old calls, or null if they have not yet been fetched. */
     @GuardedBy("this") private Cursor mOldCallsCursor;
+    /**
+     * The identifier of the latest calls request.
+     * <p>
+     * A request for the list of calls requires two queries and hence the two cursor
+     * {@link #mNewCallsCursor} and {@link #mOldCallsCursor} above, corresponding to
+     * {@link #QUERY_NEW_CALLS_TOKEN} and {@link #QUERY_OLD_CALLS_TOKEN}.
+     * <p>
+     * When a new request is about to be started, existing cursors are closed. However, it is
+     * possible that one of the queries completes after the new request has started. This means that
+     * we might merge two cursors that do not correspond to the same request. Moreover, this may
+     * lead to a resource leak if the same query completes and we override the cursor without
+     * closing it first.
+     * <p>
+     * To make sure we only join two cursors from the same request, we use this variable to store
+     * the request id of the latest request and make sure we only process cursors corresponding to
+     * the this request.
+     */
+    @GuardedBy("this") private int mCallsRequestId;
 
     /**
      * Simple handler that wraps background calls to catch
@@ -141,9 +158,9 @@
      */
     public void fetchAllCalls() {
         cancelFetch();
-        invalidate();
-        fetchCalls(QUERY_NEW_CALLS_TOKEN, true /*isNew*/, false /*voicemailOnly*/);
-        fetchCalls(QUERY_OLD_CALLS_TOKEN, false /*isNew*/, false /*voicemailOnly*/);
+        int requestId = newCallsRequest();
+        fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, false /*voicemailOnly*/);
+        fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, false /*voicemailOnly*/);
     }
 
     /**
@@ -153,9 +170,9 @@
      */
     public void fetchVoicemailOnly() {
         cancelFetch();
-        invalidate();
-        fetchCalls(QUERY_NEW_CALLS_TOKEN, true /*isNew*/, true /*voicemailOnly*/);
-        fetchCalls(QUERY_OLD_CALLS_TOKEN, false /*isNew*/, true /*voicemailOnly*/);
+        int requestId = newCallsRequest();
+        fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, true /*voicemailOnly*/);
+        fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, true /*voicemailOnly*/);
     }
 
 
@@ -165,7 +182,7 @@
     }
 
     /** Fetches the list of calls in the call log, either the new one or the old ones. */
-    private void fetchCalls(int token, boolean isNew, boolean voicemailOnly) {
+    private void fetchCalls(int token, int requestId, boolean isNew, boolean voicemailOnly) {
         // We need to check for NULL explicitly otherwise entries with where READ is NULL
         // may not match either the query or its negation.
         // We consider the calls that are not yet consumed (i.e. IS_READ = 0) as "new".
@@ -182,7 +199,7 @@
             selection = String.format("(%s) AND (%s = ?)", selection, Calls.TYPE);
             selectionArgs.add(Integer.toString(Calls.VOICEMAIL_TYPE));
         }
-        startQuery(token, null, Calls.CONTENT_URI_WITH_VOICEMAIL,
+        startQuery(token, requestId, Calls.CONTENT_URI_WITH_VOICEMAIL,
                 CallLogQuery._PROJECTION, selection, selectionArgs.toArray(EMPTY_STRING_ARRAY),
                 Calls.DEFAULT_SORT_ORDER);
     }
@@ -239,25 +256,41 @@
     }
 
     /**
-     * Invalidate the current list of calls.
+     * Start a new request and return its id. The request id will be used as the cookie for the
+     * background request.
      * <p>
-     * This method is synchronized because it must close the cursors and reset them atomically.
+     * Closes any open cursor that has not yet been sent to the requester.
      */
-    private synchronized void invalidate() {
+    private synchronized int newCallsRequest() {
         MoreCloseables.closeQuietly(mNewCallsCursor);
         MoreCloseables.closeQuietly(mOldCallsCursor);
         mNewCallsCursor = null;
         mOldCallsCursor = null;
+        return ++mCallsRequestId;
     }
 
     @Override
     protected synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
         if (token == QUERY_NEW_CALLS_TOKEN) {
+            int requestId = ((Integer) cookie).intValue();
+            if (requestId != mCallsRequestId) {
+                // Ignore this query since it does not correspond to the latest request.
+                return;
+            }
+
             // Store the returned cursor.
+            MoreCloseables.closeQuietly(mNewCallsCursor);
             mNewCallsCursor = new ExtendedCursor(
                     cursor, CallLogQuery.SECTION_NAME, CallLogQuery.SECTION_NEW_ITEM);
         } else if (token == QUERY_OLD_CALLS_TOKEN) {
+            int requestId = ((Integer) cookie).intValue();
+            if (requestId != mCallsRequestId) {
+                // Ignore this query since it does not correspond to the latest request.
+                return;
+            }
+
             // Store the returned cursor.
+            MoreCloseables.closeQuietly(mOldCallsCursor);
             mOldCallsCursor = new ExtendedCursor(
                     cursor, CallLogQuery.SECTION_NAME, CallLogQuery.SECTION_OLD_ITEM);
         } else if (token == QUERY_VOICEMAIL_STATUS_TOKEN) {
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
index c5e8f91..1c2a595 100644
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
@@ -90,8 +90,13 @@
         // TODO: Move this into a service, to avoid holding the receiver up.
         final NewCall[] newCalls = mNewCallsQuery.query();
 
+        if (newCalls == null) {
+            // Query failed, just return.
+            return;
+        }
+
         if (newCalls.length == 0) {
-            Log.e(TAG, "No voicemails to notify about: clear the notification.");
+            // No voicemails to notify about: clear the notification.
             clearNotification();
             return;
         }
@@ -147,14 +152,13 @@
         // TODO: Use the photo of contact if all calls are from the same person.
         final int icon = android.R.drawable.stat_notify_voicemail;
 
-        Notification notification = new Notification.Builder(mContext)
+        Notification.Builder notificationBuilder = new Notification.Builder(mContext)
                 .setSmallIcon(icon)
                 .setContentTitle(title)
                 .setContentText(callers)
                 .setDefaults(callToNotify != null ? Notification.DEFAULT_ALL : 0)
                 .setDeleteIntent(createMarkNewVoicemailsAsOldIntent())
-                .setAutoCancel(true)
-                .getNotification();
+                .setAutoCancel(true);
 
         // Determine the intent to fire when the notification is clicked on.
         final Intent contentIntent;
@@ -164,19 +168,29 @@
             contentIntent.setData(newCalls[0].callsUri);
             contentIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
                     newCalls[0].voicemailUri);
+            Intent playIntent = new Intent(mContext, CallDetailActivity.class);
+            playIntent.setData(newCalls[0].callsUri);
+            playIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
+                    newCalls[0].voicemailUri);
+            playIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, true);
+            playIntent.putExtra(CallDetailActivity.EXTRA_FROM_NOTIFICATION, true);
+            notificationBuilder.addAction(R.drawable.ic_play_holo_dark,
+                    resources.getString(R.string.notification_action_voicemail_play),
+                    PendingIntent.getActivity(mContext, 0, playIntent, 0));
         } else {
             // Open the call log.
             contentIntent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
         }
-        notification.contentIntent = PendingIntent.getActivity(mContext, 0, contentIntent, 0);
+        notificationBuilder.setContentIntent(
+                PendingIntent.getActivity(mContext, 0, contentIntent, 0));
 
         // The text to show in the ticker, describing the new event.
         if (callToNotify != null) {
-            notification.tickerText = resources.getString(
-                    R.string.notification_new_voicemail_ticker, names.get(callToNotify.number));
+            notificationBuilder.setTicker(resources.getString(
+                    R.string.notification_new_voicemail_ticker, names.get(callToNotify.number)));
         }
 
-        mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notification);
+        mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notificationBuilder.build());
     }
 
     /** Creates a pending intent that marks all new voicemails as old. */
@@ -243,6 +257,9 @@
             try {
                 cursor = mContentResolver.query(Calls.CONTENT_URI_WITH_VOICEMAIL, PROJECTION,
                         selection, selectionArgs, Calls.DEFAULT_SORT_ORDER);
+                if (cursor == null) {
+                    return null;
+                }
                 NewCall[] newCalls = new NewCall[cursor.getCount()];
                 while (cursor.moveToNext()) {
                     newCalls[cursor.getPosition()] = createNewCallsFromCursor(cursor);
@@ -301,7 +318,7 @@
                 cursor = mContentResolver.query(
                         Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
                         PROJECTION, null, null, null);
-                if (!cursor.moveToFirst()) return null;
+                if (cursor == null || !cursor.moveToFirst()) return null;
                 return cursor.getString(DISPLAY_NAME_COLUMN_INDEX);
             } finally {
                 if (cursor != null) {
diff --git a/src/com/android/contacts/calllog/IntentProvider.java b/src/com/android/contacts/calllog/IntentProvider.java
index bfee5ec..7ddfecc 100644
--- a/src/com/android/contacts/calllog/IntentProvider.java
+++ b/src/com/android/contacts/calllog/IntentProvider.java
@@ -17,6 +17,7 @@
 package com.android.contacts.calllog;
 
 import com.android.contacts.CallDetailActivity;
+import com.android.contacts.ContactsUtils;
 
 import android.content.ContentUris;
 import android.content.Context;
@@ -38,16 +39,7 @@
         return new IntentProvider() {
             @Override
             public Intent getIntent(Context context) {
-                // Here, "number" can either be a PSTN phone number or a
-                // SIP address.  So turn it into either a tel: URI or a
-                // sip: URI, as appropriate.
-                Uri uri;
-                if (PhoneNumberUtils.isUriNumber(number)) {
-                    uri = Uri.fromParts("sip", number, null);
-                } else {
-                    uri = Uri.fromParts("tel", number, null);
-                }
-                return new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
+                return ContactsUtils.getCallIntent(number);
             }
         };
     }
diff --git a/src/com/android/contacts/calllog/PhoneNumberHelper.java b/src/com/android/contacts/calllog/PhoneNumberHelper.java
index 20031b2..af7c2f6 100644
--- a/src/com/android/contacts/calllog/PhoneNumberHelper.java
+++ b/src/com/android/contacts/calllog/PhoneNumberHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.calllog;
 
+import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.internal.telephony.CallerInfo;
 
@@ -76,23 +77,18 @@
         }
     }
 
-    /** Returns a URI that can be used to place a call to this number. */
-    public Uri getCallUri(String number) {
-        if (isVoicemailNumber(number)) {
-            return Uri.parse("voicemail:x");
-        }
-        if (isSipNumber(number)) {
-             return Uri.fromParts("sip", number, null);
-        }
-         return Uri.fromParts("tel", number, null);
-     }
-
-    /** Returns true if the given number is the number of the configured voicemail. */
+    /**
+     * Returns true if the given number is the number of the configured voicemail.
+     * To be able to mock-out this, it is not a static method.
+     */
     public boolean isVoicemailNumber(CharSequence number) {
         return PhoneNumberUtils.isVoiceMailNumber(number.toString());
     }
 
-    /** Returns true if the given number is a SIP address. */
+    /**
+     * Returns true if the given number is a SIP address.
+     * To be able to mock-out this, it is not a static method.
+     */
     public boolean isSipNumber(CharSequence number) {
         return PhoneNumberUtils.isUriNumber(number.toString());
     }
diff --git a/src/com/android/contacts/datepicker/DatePicker.java b/src/com/android/contacts/datepicker/DatePicker.java
index 7ea9641..629fd9c 100644
--- a/src/com/android/contacts/datepicker/DatePicker.java
+++ b/src/com/android/contacts/datepicker/DatePicker.java
@@ -21,6 +21,7 @@
 
 import com.android.contacts.R;
 
+import android.animation.LayoutTransition;
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -58,6 +59,7 @@
     private static final int DEFAULT_END_YEAR = 2100;
 
     /* UI Components */
+    private final LinearLayout mPickerContainer;
     private final CheckBox mYearToggle;
     private final NumberPicker mDayPicker;
     private final NumberPicker mMonthPicker;
@@ -104,10 +106,12 @@
                 Context.LAYOUT_INFLATER_SERVICE);
         inflater.inflate(R.layout.date_picker, this, true);
 
+        mPickerContainer = (LinearLayout) findViewById(R.id.parent);
         mDayPicker = (NumberPicker) findViewById(R.id.day);
         mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
         mDayPicker.setOnLongPressUpdateInterval(100);
         mDayPicker.setOnValueChangedListener(new OnValueChangeListener() {
+            @Override
             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                 mDay = newVal;
                 notifyDateChanged();
@@ -137,6 +141,7 @@
 
         mMonthPicker.setOnLongPressUpdateInterval(200);
         mMonthPicker.setOnValueChangedListener(new OnValueChangeListener() {
+            @Override
             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
 
                 /* We display the month 1-12 but store it 0-11 so always
@@ -152,6 +157,7 @@
         mYearPicker = (NumberPicker) findViewById(R.id.year);
         mYearPicker.setOnLongPressUpdateInterval(100);
         mYearPicker.setOnValueChangedListener(new OnValueChangeListener() {
+            @Override
             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                 mYear = newVal;
                 // Adjust max day for leap years if needed
@@ -192,6 +198,7 @@
         // re-order the number pickers to match the current date format
         reorderPickers(months);
 
+        mPickerContainer.setLayoutTransition(new LayoutTransition());
         if (!isEnabled()) {
             setEnabled(false);
         }
@@ -232,8 +239,7 @@
         /* Remove the 3 pickers from their parent and then add them back in the
          * required order.
          */
-        LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
-        parent.removeAllViews();
+        mPickerContainer.removeAllViews();
 
         boolean quoted = false;
         boolean didDay = false, didMonth = false, didYear = false;
@@ -247,13 +253,13 @@
 
             if (!quoted) {
                 if (c == DateFormat.DATE && !didDay) {
-                    parent.addView(mDayPicker);
+                    mPickerContainer.addView(mDayPicker);
                     didDay = true;
                 } else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) {
-                    parent.addView(mMonthPicker);
+                    mPickerContainer.addView(mMonthPicker);
                     didMonth = true;
                 } else if (c == DateFormat.YEAR && !didYear) {
-                    parent.addView (mYearPicker);
+                    mPickerContainer.addView (mYearPicker);
                     didYear = true;
                 }
             }
@@ -261,13 +267,13 @@
 
         // Shouldn't happen, but just in case.
         if (!didMonth) {
-            parent.addView(mMonthPicker);
+            mPickerContainer.addView(mMonthPicker);
         }
         if (!didDay) {
-            parent.addView(mDayPicker);
+            mPickerContainer.addView(mDayPicker);
         }
         if (!didYear) {
-            parent.addView(mYearPicker);
+            mPickerContainer.addView(mYearPicker);
         }
     }
 
@@ -353,10 +359,12 @@
         public static final Parcelable.Creator<SavedState> CREATOR =
                 new Creator<SavedState>() {
 
+                    @Override
                     public SavedState createFromParcel(Parcel in) {
                         return new SavedState(in);
                     }
 
+                    @Override
                     public SavedState[] newArray(int size) {
                         return new SavedState[size];
                     }
diff --git a/src/com/android/contacts/datepicker/DatePickerDialog.java b/src/com/android/contacts/datepicker/DatePickerDialog.java
index 112b96e..b0c4ed6 100644
--- a/src/com/android/contacts/datepicker/DatePickerDialog.java
+++ b/src/com/android/contacts/datepicker/DatePickerDialog.java
@@ -19,6 +19,10 @@
 // This is a fork of the standard Android DatePicker that additionally allows toggling the year
 // on/off. It uses some private API so that not everything has to be copied.
 
+import com.android.contacts.R;
+import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
+import com.android.contacts.util.DateUtils;
+
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -30,10 +34,8 @@
 import android.view.View;
 import android.widget.TextView;
 
-import com.android.contacts.R;
-import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
-
-import java.text.DateFormatSymbols;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.Calendar;
 
 /**
@@ -53,8 +55,8 @@
     private final DatePicker mDatePicker;
     private final OnDateSetListener mCallBack;
     private final Calendar mCalendar;
-    private final java.text.DateFormat mTitleDateFormat;
-    private final String[] mWeekDays;
+    private final DateFormat mTitleDateFormat;
+    private final DateFormat mTitleNoYearDateFormat;
 
     private int mInitialYear;
     private int mInitialMonth;
@@ -148,11 +150,10 @@
         mInitialYear = year;
         mInitialMonth = monthOfYear;
         mInitialDay = dayOfMonth;
-        DateFormatSymbols symbols = new DateFormatSymbols();
-        mWeekDays = symbols.getShortWeekdays();
 
-        mTitleDateFormat = java.text.DateFormat.
-                                getDateInstance(java.text.DateFormat.FULL);
+        mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL);
+        mTitleNoYearDateFormat = new SimpleDateFormat(
+                DateUtils.isMonthBeforeDay(getContext()) ? "MMMM dd" : "dd MMMM");
         mCalendar = Calendar.getInstance();
         updateTitle(mInitialYear, mInitialMonth, mInitialDay);
 
@@ -182,6 +183,7 @@
         title.setEllipsize(TruncateAt.END);
     }
 
+    @Override
     public void onClick(DialogInterface dialog, int which) {
         if (mCallBack != null) {
             mDatePicker.clearFocus();
@@ -190,8 +192,8 @@
         }
     }
 
-    public void onDateChanged(DatePicker view, int year,
-            int month, int day) {
+    @Override
+    public void onDateChanged(DatePicker view, int year, int month, int day) {
         updateTitle(year, month, day);
     }
 
@@ -206,7 +208,9 @@
         mCalendar.set(Calendar.YEAR, year);
         mCalendar.set(Calendar.MONTH, month);
         mCalendar.set(Calendar.DAY_OF_MONTH, day);
-        setTitle(mTitleDateFormat.format(mCalendar.getTime()));
+        final DateFormat dateFormat =
+                year == 0 ? mTitleNoYearDateFormat : mTitleDateFormat;
+        setTitle(dateFormat.format(mCalendar.getTime()));
     }
 
     @Override
diff --git a/src/com/android/contacts/detail/CarouselTab.java b/src/com/android/contacts/detail/CarouselTab.java
index 677f0ad..0b430b6 100644
--- a/src/com/android/contacts/detail/CarouselTab.java
+++ b/src/com/android/contacts/detail/CarouselTab.java
@@ -17,33 +17,31 @@
 package com.android.contacts.detail;
 
 import com.android.contacts.R;
+import com.android.contacts.widget.FrameLayoutWithOverlay;
 
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.RelativeLayout;
+import android.view.ViewPropertyAnimator;
 import android.widget.TextView;
 
 /**
  * This is a tab in the {@link ContactDetailTabCarousel}.
  */
-public class CarouselTab extends RelativeLayout implements ViewOverlay {
+public class CarouselTab extends FrameLayoutWithOverlay {
 
     private static final String TAG = CarouselTab.class.getSimpleName();
 
+    private static final long FADE_TRANSITION_TIME = 150;
+
     private TextView mLabelView;
+    private View mLabelBackgroundView;
 
     /**
-     * This view adds an alpha layer over the entire tab.
+     * This view adds an alpha layer over the entire tab (except for the label).
      */
     private View mAlphaLayer;
 
-    /**
-     * This view adds a layer over the entire tab so that when visible, it intercepts all touch
-     * events on the tab.
-     */
-    private View mTouchInterceptLayer;
-
     public CarouselTab(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -53,10 +51,9 @@
         super.onFinishInflate();
 
         mLabelView = (TextView) findViewById(R.id.label);
-        mLabelView.setClickable(true);
-
+        mLabelBackgroundView = findViewById(R.id.label_background);
         mAlphaLayer = findViewById(R.id.alpha_overlay);
-        mTouchInterceptLayer = findViewById(R.id.touch_intercept_overlay);
+        setAlphaLayer(mAlphaLayer);
     }
 
     public void setLabel(String label) {
@@ -71,22 +68,19 @@
         mLabelView.setSelected(false);
     }
 
-    @Override
-    public void disableTouchInterceptor() {
-        // This shouldn't be called because there is no need to disable the touch interceptor if
-        // there is no content within the tab that needs to be clicked.
-    }
+    public void fadeInLabelViewAnimator(int startDelay, boolean fadeBackground) {
+        final ViewPropertyAnimator labelAnimator = mLabelView.animate();
+        mLabelView.setAlpha(0.0f);
+        labelAnimator.alpha(1.0f);
+        labelAnimator.setStartDelay(startDelay);
+        labelAnimator.setDuration(FADE_TRANSITION_TIME);
 
-    @Override
-    public void enableTouchInterceptor(OnClickListener clickListener) {
-        if (mTouchInterceptLayer != null) {
-            mTouchInterceptLayer.setVisibility(View.VISIBLE);
-            mTouchInterceptLayer.setOnClickListener(clickListener);
+        if (fadeBackground) {
+            final ViewPropertyAnimator backgroundAnimator = mLabelBackgroundView.animate();
+            mLabelBackgroundView.setAlpha(0.0f);
+            backgroundAnimator.alpha(1.0f);
+            backgroundAnimator.setStartDelay(startDelay);
+            backgroundAnimator.setDuration(FADE_TRANSITION_TIME);
         }
     }
-
-    @Override
-    public void setAlphaLayerValue(float alpha) {
-        ContactDetailDisplayUtils.setAlphaOnViewBackground(mAlphaLayer, alpha);
-    }
 }
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index b81cebf..404148d 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -23,6 +23,7 @@
 import com.android.contacts.preference.ContactsPreferences;
 import com.android.contacts.util.ContactBadgeUtil;
 import com.android.contacts.util.HtmlUtils;
+import com.android.contacts.util.MoreMath;
 import com.android.contacts.util.StreamItemEntry;
 import com.android.contacts.util.StreamItemPhotoEntry;
 import com.google.common.annotations.VisibleForTesting;
@@ -36,8 +37,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.ContactsContract;
@@ -50,13 +49,10 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AlphaAnimation;
-import android.widget.CheckBox;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.TextView;
 
@@ -70,8 +66,6 @@
 public class ContactDetailDisplayUtils {
     private static final String TAG = "ContactDetailDisplayUtils";
 
-    private static final int PHOTO_FADE_IN_ANIMATION_DURATION_MILLIS = 100;
-
     /**
      * Tag object used for stream item photos.
      */
@@ -190,37 +184,41 @@
     }
 
     /**
-     * Sets the contact photo to display in the given {@link ImageView}. If bitmap is null, the
-     * default placeholder image is shown.
+     * Sets the starred state of this contact.
      */
-    public static void setPhoto(Context context, Result contactData, ImageView photoView) {
-        if (contactData.isLoadingPhoto()) {
-            photoView.setImageBitmap(null);
-            return;
+    public static void configureStarredImageView(ImageView starredView, boolean isDirectoryEntry,
+            boolean isUserProfile, boolean isStarred) {
+        // Check if the starred state should be visible
+        if (!isDirectoryEntry && !isUserProfile) {
+            starredView.setVisibility(View.VISIBLE);
+            final int resId = isStarred
+                    ? R.drawable.btn_star_on_normal_holo_light
+                    : R.drawable.btn_star_off_normal_holo_light;
+            starredView.setImageResource(resId);
+            starredView.setTag(isStarred);
+            starredView.setContentDescription(starredView.getResources().getString(
+                    isStarred ? R.string.menu_removeStar : R.string.menu_addStar));
+        } else {
+            starredView.setVisibility(View.GONE);
         }
-        byte[] photo = contactData.getPhotoBinaryData();
-        Bitmap bitmap = photo != null ? BitmapFactory.decodeByteArray(photo, 0, photo.length)
-                : ContactBadgeUtil.loadDefaultAvatarPhoto(context, true, false);
-        boolean fadeIn = contactData.isDirectoryEntry();
-        if (photoView.getDrawable() == null && fadeIn) {
-            AlphaAnimation animation = new AlphaAnimation(0, 1);
-            animation.setDuration(PHOTO_FADE_IN_ANIMATION_DURATION_MILLIS);
-            animation.setInterpolator(new AccelerateInterpolator());
-            photoView.startAnimation(animation);
-        }
-        photoView.setImageBitmap(bitmap);
     }
 
     /**
      * Sets the starred state of this contact.
      */
-    public static void setStarred(Result contactData, CheckBox starredView) {
+    public static void configureStarredMenuItem(MenuItem starredMenuItem, boolean isDirectoryEntry,
+            boolean isUserProfile, boolean isStarred) {
         // Check if the starred state should be visible
-        if (!contactData.isDirectoryEntry() && !contactData.isUserProfile()) {
-            starredView.setVisibility(View.VISIBLE);
-            starredView.setChecked(contactData.getStarred());
+        if (!isDirectoryEntry && !isUserProfile) {
+            starredMenuItem.setVisible(true);
+            final int resId = isStarred
+                    ? R.drawable.btn_star_on_normal_holo_dark
+                    : R.drawable.btn_star_off_normal_holo_dark;
+            starredMenuItem.setIcon(resId);
+            starredMenuItem.setChecked(isStarred);
+            starredMenuItem.setTitle(isStarred ? R.string.menu_removeStar : R.string.menu_addStar);
         } else {
-            starredView.setVisibility(View.GONE);
+            starredMenuItem.setVisible(false);
         }
     }
 
@@ -249,7 +247,7 @@
         setDataOrHideIfNone(snippet, statusView);
         if (photoUri != null) {
             ContactPhotoManager.getInstance(context).loadPhoto(
-                    statusPhotoView, Uri.parse(photoUri), true, false,
+                    statusPhotoView, Uri.parse(photoUri), -1, false,
                     ContactPhotoManager.DEFAULT_BLANK);
             statusPhotoView.setVisibility(View.VISIBLE);
         } else {
@@ -259,61 +257,76 @@
 
     /** Creates the view that represents a stream item. */
     public static View createStreamItemView(LayoutInflater inflater, Context context,
-            StreamItemEntry streamItem, LinearLayout parent,
-            View.OnClickListener photoClickListener) {
-        View container = inflater.inflate(R.layout.stream_item_container, parent, false);
-        ViewGroup contentTable = (ViewGroup) container.findViewById(R.id.stream_item_content);
+            View convertView, StreamItemEntry streamItem, View.OnClickListener photoClickListener) {
 
-        ContactPhotoManager contactPhotoManager = ContactPhotoManager.getInstance(context);
-        List<StreamItemPhotoEntry> photos = streamItem.getPhotos();
+        // Try to recycle existing views.
+        final View container;
+        if (convertView != null) {
+            container = convertView;
+        } else {
+            container = inflater.inflate(R.layout.stream_item_container, null, false);
+        }
+
+        final ContactPhotoManager contactPhotoManager = ContactPhotoManager.getInstance(context);
+        final List<StreamItemPhotoEntry> photos = streamItem.getPhotos();
         final int photoCount = photos.size();
 
-        // This stream item only has text.
+        // Add the text part.
+        addStreamItemText(context, streamItem, container);
+
+        // Add images.
+        final ViewGroup imageRows = (ViewGroup) container.findViewById(R.id.stream_item_image_rows);
+
         if (photoCount == 0) {
-            View textOnlyContainer = inflater.inflate(R.layout.stream_item_row_text, contentTable,
-                    false);
-            addStreamItemText(context, streamItem, textOnlyContainer);
-            contentTable.addView(textOnlyContainer);
+            // This stream item only has text.
+            imageRows.setVisibility(View.GONE);
         } else {
-            // This stream item has text and photos. Process the photos, two at a time.
-            for (int index = 0; index < photoCount; index += 2) {
-                final StreamItemPhotoEntry firstPhoto = photos.get(index);
-                if (index + 1 < photoCount) {
-                    // Put in two photos, side by side.
-                    final StreamItemPhotoEntry secondPhoto = photos.get(index + 1);
-                    View photoContainer = inflater.inflate(R.layout.stream_item_row_two_images,
-                            contentTable, false);
-                    loadPhoto(contactPhotoManager, streamItem, firstPhoto, photoContainer,
-                            R.id.stream_item_first_image, photoClickListener);
-                    loadPhoto(contactPhotoManager, streamItem, secondPhoto, photoContainer,
-                            R.id.stream_item_second_image, photoClickListener);
-                    contentTable.addView(photoContainer);
-                } else {
-                    // Put in a single photo
-                    View photoContainer = inflater.inflate(
-                            R.layout.stream_item_row_one_image, contentTable, false);
-                    loadPhoto(contactPhotoManager, streamItem, firstPhoto, photoContainer,
-                            R.id.stream_item_first_image, photoClickListener);
-                    contentTable.addView(photoContainer);
+            // This stream item has text and photos.
+            imageRows.setVisibility(View.VISIBLE);
+
+            // Number of image rows needed, which is cailing(photoCount / 2)
+            final int numImageRows = (photoCount + 1) / 2;
+
+            // Actual image rows.
+            final int numOldImageRows = imageRows.getChildCount();
+
+            // Make sure we have enough stream_item_row_images.
+            if (numOldImageRows == numImageRows) {
+                // Great, we have the just enough number of rows...
+
+            } else if (numOldImageRows < numImageRows) {
+                // Need to add more image rows.
+                for (int i = numOldImageRows; i < numImageRows; i++) {
+                    View imageRow = inflater.inflate(R.layout.stream_item_row_images, imageRows,
+                            true);
+                }
+            } else {
+                // We have exceeding image rows.  Hide them.
+                for (int i = numImageRows; i < numOldImageRows; i++) {
+                    imageRows.getChildAt(i).setVisibility(View.GONE);
                 }
             }
 
-            // Add text, comments, and attribution if applicable
-            View textContainer = inflater.inflate(R.layout.stream_item_row_text, contentTable,
-                    false);
-            // Add extra padding between the text and the images
-            int extraVerticalPadding = context.getResources().getDimensionPixelSize(
-                    R.dimen.detail_update_section_between_items_vertical_padding);
-            textContainer.setPadding(textContainer.getPaddingLeft(),
-                    textContainer.getPaddingTop() + extraVerticalPadding,
-                    textContainer.getPaddingRight(),
-                    textContainer.getPaddingBottom());
-            addStreamItemText(context, streamItem, textContainer);
-            contentTable.addView(textContainer);
-        }
+            // Put images, two by two.
+            for (int i = 0; i < photoCount; i += 2) {
+                final View imageRow = imageRows.getChildAt(i / 2);
+                // Reused image rows may not visible, so make sure they're shown.
+                imageRow.setVisibility(View.VISIBLE);
 
-        if (parent != null) {
-            parent.addView(container);
+                // Show first image.
+                loadPhoto(contactPhotoManager, streamItem, photos.get(i), imageRow,
+                        R.id.stream_item_first_image, photoClickListener);
+                final View secondContainer = imageRow.findViewById(R.id.second_image_container);
+                if (i + 1 < photoCount) {
+                    // Show the second image too.
+                    loadPhoto(contactPhotoManager, streamItem, photos.get(i + 1), imageRow,
+                            R.id.stream_item_second_image, photoClickListener);
+                    secondContainer.setVisibility(View.VISIBLE);
+                } else {
+                    // Hide the second image, but it still has to occupy the space.
+                    secondContainer.setVisibility(View.INVISIBLE);
+                }
+            }
         }
 
         return container;
@@ -339,7 +352,7 @@
             pushLayerView.setClickable(false);
             pushLayerView.setEnabled(false);
         }
-        contactPhotoManager.loadPhoto(imageView, Uri.parse(streamItemPhoto.getPhotoUri()), true,
+        contactPhotoManager.loadPhoto(imageView, Uri.parse(streamItemPhoto.getPhotoUri()), -1,
                 false, ContactPhotoManager.DEFAULT_BLANK);
     }
 
@@ -352,14 +365,12 @@
         ImageGetter imageGetter = new DefaultImageGetter(context.getPackageManager());
 
         // Stream item text
-        setDataOrHideIfNone(HtmlUtils.fromHtml(context, streamItem.getText(), imageGetter, null),
-                htmlView);
+        setDataOrHideIfNone(streamItem.getDecodedText(), htmlView);
         // Attribution
         setDataOrHideIfNone(ContactBadgeUtil.getSocialDate(streamItem, context),
                 attributionView);
         // Comments
-        setDataOrHideIfNone(HtmlUtils.fromHtml(context, streamItem.getComments(), imageGetter,
-                null), commentsView);
+        setDataOrHideIfNone(streamItem.getDecodedComments(), commentsView);
         return rootView;
     }
 
@@ -421,6 +432,15 @@
         }
     }
 
+    private static Html.ImageGetter sImageGetter;
+
+    public static Html.ImageGetter getImageGetter(Context context) {
+        if (sImageGetter == null) {
+            sImageGetter = new DefaultImageGetter(context.getPackageManager());
+        }
+        return sImageGetter;
+    }
+
     /** Fetcher for images from resources to be included in HTML text. */
     private static class DefaultImageGetter implements Html.ImageGetter {
         /** The scheme used to load resources. */
@@ -504,7 +524,7 @@
         if (view != null) {
             // Convert alpha layer to a black background HEX color with an alpha value for better
             // performance (i.e. use setBackgroundColor() instead of setAlpha())
-            view.setBackgroundColor((int) (alpha * 255) << 24);
+            view.setBackgroundColor((int) (MoreMath.clamp(alpha, 0.0f, 1.0f) * 255) << 24);
         }
     }
 
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 26d240f..5c68dcb 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -26,6 +26,7 @@
 import com.android.contacts.R;
 import com.android.contacts.TypePrecedence;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.detail.ContactDetailPhotoSetter;
 import com.android.contacts.editor.SelectAccountDialogFragment;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountType.EditType;
@@ -37,20 +38,18 @@
 import com.android.contacts.model.EntityDeltaList;
 import com.android.contacts.model.EntityModifier;
 import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.util.ClipboardUtils;
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.DataStatus;
 import com.android.contacts.util.DateUtils;
-import com.android.contacts.util.StructuredPostalUtils;
 import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.contacts.widget.TransitionAnimationView;
+import com.android.contacts.util.StructuredPostalUtils;
 import com.android.internal.telephony.ITelephony;
 import com.google.common.annotations.VisibleForTesting;
 
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.SearchManager;
-import android.content.ClipData;
-import android.content.ClipboardManager;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
@@ -84,8 +83,6 @@
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.Intents.UI;
-import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.StatusUpdates;
 import android.telephony.PhoneNumberUtils;
@@ -93,11 +90,15 @@
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
+import android.view.DragEvent;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.View.OnDragListener;
+import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
 import android.widget.AbsListView.OnScrollListener;
 import android.widget.AdapterView;
@@ -105,13 +106,11 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
 import android.widget.Button;
-import android.widget.CheckBox;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -119,7 +118,7 @@
 import java.util.List;
 import java.util.Map;
 
-public class ContactDetailFragment extends Fragment implements FragmentKeyListener, ViewOverlay,
+public class ContactDetailFragment extends Fragment implements FragmentKeyListener,
         SelectAccountDialogFragment.Listener, OnItemClickListener {
 
     private static final String TAG = "ContactDetailFragment";
@@ -133,13 +132,6 @@
     private static final String KEY_CONTACT_URI = "contactUri";
     private static final String KEY_LIST_STATE = "liststate";
 
-    // TODO: Make maxLines a field in {@link DataKind}
-    private static final int WEBSITE_MAX_LINES = 1;
-    private static final int SIP_ADDRESS_MAX_LINES= 1;
-    private static final int POSTAL_ADDRESS_MAX_LINES = 10;
-    private static final int GROUP_MAX_LINES = 10;
-    private static final int NOTE_MAX_LINES = 100;
-
     private Context mContext;
     private View mView;
     private OnScrollListener mVerticalScrollListener;
@@ -147,22 +139,25 @@
     private Listener mListener;
 
     private ContactLoader.Result mContactData;
-    private ImageView mStaticPhotoView;
+    private ViewGroup mStaticPhotoContainer;
+    private View mPhotoTouchOverlay;
     private ListView mListView;
     private ViewAdapter mAdapter;
     private Uri mPrimaryPhoneUri = null;
     private ViewEntryDimensions mViewEntryDimensions;
 
+    private final ContactDetailPhotoSetter mPhotoSetter = new ContactDetailPhotoSetter();
+
     private Button mQuickFixButton;
     private QuickFix mQuickFix;
-    private int mNumPhoneNumbers = 0;
     private String mDefaultCountryIso;
     private boolean mContactHasSocialUpdates;
     private boolean mShowStaticPhoto = true;
 
     private final QuickFix[] mPotentialQuickFixes = new QuickFix[] {
             new MakeLocalCopyQuickFix(),
-            new AddToMyContactsQuickFix() };
+            new AddToMyContactsQuickFix()
+    };
 
     /**
      * Device capability: Set during buildEntries and used in the long-press context menu
@@ -187,22 +182,6 @@
     private View mEmptyView;
 
     /**
-     * Initial alpha value to set on the alpha layer.
-     */
-    private float mInitialAlphaValue;
-
-    /**
-     * This optional view adds an alpha layer over the entire fragment.
-     */
-    private View mAlphaLayer;
-
-    /**
-     * This optional view adds a layer over the entire fragment so that when visible, it intercepts
-     * all touch events on the fragment.
-     */
-    private View mTouchInterceptLayer;
-
-    /**
      * Saved state of the {@link ListView}. This must be saved and applied to the {@ListView} only
      * when the adapter has been populated again.
      */
@@ -229,11 +208,41 @@
     private ArrayList<ViewEntry> mAllEntries = new ArrayList<ViewEntry>();
     private LayoutInflater mInflater;
 
-    private boolean mTransitionAnimationRequested;
-
     private boolean mIsUniqueNumber;
     private boolean mIsUniqueEmail;
 
+    private ListPopupWindow mPopup;
+
+    /**
+     * This is to forward touch events to the list view to enable users to scroll the list view
+     * from the blank area underneath the static photo when the layout with static photo is used.
+     */
+    private OnTouchListener mForwardTouchToListView = new OnTouchListener() {
+        @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            if (mListView != null) {
+                mListView.dispatchTouchEvent(event);
+                return true;
+            }
+            return false;
+        }
+    };
+
+    /**
+     * This is to forward drag events to the list view to enable users to scroll the list view
+     * from the blank area underneath the static photo when the layout with static photo is used.
+     */
+    private OnDragListener mForwardDragToListView = new OnDragListener() {
+        @Override
+        public boolean onDrag(View v, DragEvent event) {
+            if (mListView != null) {
+                mListView.dispatchDragEvent(event);
+                return true;
+            }
+            return false;
+        }
+    };
+
     public ContactDetailFragment() {
         // Explicit constructor for inflation
     }
@@ -258,6 +267,7 @@
 
     @Override
     public void onPause() {
+        dismissPopupIfShown();
         super.onPause();
     }
 
@@ -277,13 +287,17 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
         mView = inflater.inflate(R.layout.contact_detail_fragment, container, false);
+        // Set the touch and drag listener to forward the event to the mListView so that
+        // vertical scrolling can happen from outside of the list view.
+        mView.setOnTouchListener(mForwardTouchToListView);
+        mView.setOnDragListener(mForwardDragToListView);
 
         mInflater = inflater;
 
-        mStaticPhotoView = (ImageView) mView.findViewById(R.id.photo);
+        mStaticPhotoContainer = (ViewGroup) mView.findViewById(R.id.static_photo_container);
+        mPhotoTouchOverlay = mView.findViewById(R.id.photo_touch_intercept_overlay);
 
         mListView = (ListView) mView.findViewById(android.R.id.list);
-        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
         mListView.setOnItemClickListener(this);
         mListView.setItemsCanFocus(true);
         mListView.setOnScrollListener(mVerticalScrollListener);
@@ -291,10 +305,6 @@
         // Don't set it to mListView yet.  We do so later when we bind the adapter.
         mEmptyView = mView.findViewById(android.R.id.empty);
 
-        mTouchInterceptLayer = mView.findViewById(R.id.touch_intercept_overlay);
-        mAlphaLayer = mView.findViewById(R.id.alpha_overlay);
-        ContactDetailDisplayUtils.setAlphaOnViewBackground(mAlphaLayer, mInitialAlphaValue);
-
         mQuickFixButton = (Button) mView.findViewById(R.id.contact_quick_fix);
         mQuickFixButton.setOnClickListener(new OnClickListener() {
             @Override
@@ -314,40 +324,10 @@
         return mView;
     }
 
-    protected View inflate(int resource, ViewGroup root, boolean attachToRoot) {
-        return mInflater.inflate(resource, root, attachToRoot);
-    }
-
     public void setListener(Listener value) {
         mListener = value;
     }
 
-    @Override
-    public void setAlphaLayerValue(float alpha) {
-        // If the alpha layer is not ready yet, store it for later when the view is initialized
-        if (mAlphaLayer == null) {
-            mInitialAlphaValue = alpha;
-        } else {
-            // Otherwise set the value immediately
-            ContactDetailDisplayUtils.setAlphaOnViewBackground(mAlphaLayer, alpha);
-        }
-    }
-
-    @Override
-    public void enableTouchInterceptor(OnClickListener clickListener) {
-        if (mTouchInterceptLayer != null) {
-            mTouchInterceptLayer.setVisibility(View.VISIBLE);
-            mTouchInterceptLayer.setOnClickListener(clickListener);
-        }
-    }
-
-    @Override
-    public void disableTouchInterceptor() {
-        if (mTouchInterceptLayer != null) {
-            mTouchInterceptLayer.setVisibility(View.GONE);
-        }
-    }
-
     protected Context getContext() {
         return mContext;
     }
@@ -376,6 +356,9 @@
         mShowStaticPhoto = showPhoto;
     }
 
+    /**
+     * Shows the contact detail with a message indicating there are no contact details.
+     */
     public void showEmptyState() {
         setData(null, null);
     }
@@ -424,13 +407,11 @@
             getActivity().invalidateOptionsMenu();
         }
 
-        if (mTransitionAnimationRequested) {
-            TransitionAnimationView.startAnimation(mView, mContactData == null);
-            mTransitionAnimationRequested = false;
-        }
-
         if (mContactData == null) {
             mView.setVisibility(View.INVISIBLE);
+            if (mStaticPhotoContainer != null) {
+                mStaticPhotoContainer.setVisibility(View.GONE);
+            }
             mAllEntries.clear();
             if (mAdapter != null) {
                 mAdapter.notifyDataSetChanged();
@@ -442,16 +423,28 @@
         mContactHasSocialUpdates = !mContactData.getStreamItems().isEmpty();
 
         // Setup the photo if applicable
-        if (mStaticPhotoView != null) {
-            // The presence of a static photo view is not sufficient to determine whether or not
-            // we should show the photo. Check the mShowStaticPhoto flag which can be set by an
+        if (mStaticPhotoContainer != null) {
+            // The presence of a static photo container is not sufficient to determine whether or
+            // not we should show the photo. Check the mShowStaticPhoto flag which can be set by an
             // outside class depending on screen size, layout, and whether the contact has social
             // updates or not.
             if (mShowStaticPhoto) {
-                mStaticPhotoView.setVisibility(View.VISIBLE);
-                ContactDetailDisplayUtils.setPhoto(mContext, mContactData, mStaticPhotoView);
+                mStaticPhotoContainer.setVisibility(View.VISIBLE);
+                final ImageView photoView = (ImageView) mStaticPhotoContainer.findViewById(
+                        R.id.photo);
+                final boolean expandPhotoOnClick = mContactData.getPhotoUri() != null;
+                final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
+                        mContext, mContactData, photoView, expandPhotoOnClick);
+                if (mPhotoTouchOverlay != null) {
+                    mPhotoTouchOverlay.setVisibility(View.VISIBLE);
+                    if (expandPhotoOnClick || mContactData.isWritableContact(mContext)) {
+                        mPhotoTouchOverlay.setOnClickListener(listener);
+                    } else {
+                        mPhotoTouchOverlay.setClickable(false);
+                    }
+                }
             } else {
-                mStaticPhotoView.setVisibility(View.GONE);
+                mStaticPhotoContainer.setVisibility(View.GONE);
             }
         }
 
@@ -541,7 +534,6 @@
         mRawContactIds.clear();
 
         mPrimaryPhoneUri = null;
-        mNumPhoneNumbers = 0;
 
         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
 
@@ -586,6 +578,7 @@
                 final DetailViewEntry entry = DetailViewEntry.fromValues(mContext, mimeType, kind,
                         dataId, entryValues, mContactData.isDirectoryEntry(),
                         mContactData.getDirectoryId());
+                entry.maxLines = kind.maxLinesForDisplay;
 
                 final boolean hasData = !TextUtils.isEmpty(entry.data);
                 Integer superPrimary = entryValues.getAsInteger(Data.IS_SUPER_PRIMARY);
@@ -595,13 +588,12 @@
                     // Always ignore the name. It is shown in the header if set
                 } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build phone entries
-                    mNumPhoneNumbers++;
                     String phoneNumberE164 =
-                            entryValues.getAsString(PhoneLookup.NORMALIZED_NUMBER);
+                            entryValues.getAsString(Phone.NORMALIZED_NUMBER);
                     entry.data = PhoneNumberUtils.formatNumber(
                             entry.data, phoneNumberE164, mDefaultCountryIso);
-                    final Intent phoneIntent = mHasPhone ? new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            Uri.fromParts(Constants.SCHEME_TEL, entry.data, null)) : null;
+                    final Intent phoneIntent = mHasPhone ?
+                            ContactsUtils.getCallIntent(entry.data) : null;
                     final Intent smsIntent = mHasSms ? new Intent(Intent.ACTION_SENDTO,
                             Uri.fromParts(Constants.SCHEME_SMSTO, entry.data, null)) : null;
 
@@ -623,13 +615,26 @@
                     if (isSuperPrimary) mPrimaryPhoneUri = entry.uri;
 
                     entry.isPrimary = isSuperPrimary;
-                    mPhoneEntries.add(entry);
+
+                    // If the entry is a primary entry, then render it first in the view.
+                    if (entry.isPrimary) {
+                        // add to beginning of list so that this phone number shows up first
+                        mPhoneEntries.add(0, entry);
+                    } else {
+                        // add to end of list
+                        mPhoneEntries.add(entry);
+                    }
                 } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build email entries
                     entry.intent = new Intent(Intent.ACTION_SENDTO,
                             Uri.fromParts(Constants.SCHEME_MAILTO, entry.data, null));
                     entry.isPrimary = isSuperPrimary;
-                    mEmailEntries.add(entry);
+                    // If entry is a primary entry, then render it first in the view.
+                    if (entry.isPrimary) {
+                        mEmailEntries.add(0, entry);
+                    } else {
+                        mEmailEntries.add(entry);
+                    }
 
                     // When Email rows have status, create additional Im row
                     final DataStatus status = mContactData.getStatuses().get(entry.id);
@@ -641,22 +646,22 @@
                                 imKind, dataId, entryValues, mContactData.isDirectoryEntry(),
                                 mContactData.getDirectoryId());
                         buildImActions(mContext, imEntry, entryValues);
-                        imEntry.applyStatus(status, false);
+                        imEntry.setPresence(status.getPresence());
+                        imEntry.maxLines = imKind.maxLinesForDisplay;
                         mImEntries.add(imEntry);
                     }
                 } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build postal entries
-                    entry.maxLines = POSTAL_ADDRESS_MAX_LINES;
                     entry.intent = StructuredPostalUtils.getViewPostalAddressIntent(entry.data);
                     mPostalEntries.add(entry);
                 } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build IM entries
                     buildImActions(mContext, entry, entryValues);
 
-                    // Apply presence and status details when available
+                    // Apply presence when available
                     final DataStatus status = mContactData.getStatuses().get(entry.id);
                     if (status != null) {
-                        entry.applyStatus(status, false);
+                        entry.setPresence(status.getPresence());
                     }
                     mImEntries.add(entry);
                 } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
@@ -678,12 +683,10 @@
                 } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build note entries
                     entry.uri = null;
-                    entry.maxLines = NOTE_MAX_LINES;
                     mNoteEntries.add(entry);
                 } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build Website entries
                     entry.uri = null;
-                    entry.maxLines = WEBSITE_MAX_LINES;
                     try {
                         WebAddress webAddress = new WebAddress(entry.data);
                         entry.intent = new Intent(Intent.ACTION_VIEW,
@@ -695,9 +698,8 @@
                 } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build SipAddress entries
                     entry.uri = null;
-                    entry.maxLines = SIP_ADDRESS_MAX_LINES;
                     if (mHasSip) {
-                        entry.intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                        entry.intent = ContactsUtils.getCallIntent(
                                 Uri.fromParts(Constants.SCHEME_SIP, entry.data, null));
                     } else {
                         entry.intent = null;
@@ -759,7 +761,6 @@
             entry.mimetype = GroupMembership.MIMETYPE;
             entry.kind = mContext.getString(R.string.groupsLabel);
             entry.data = sb.toString();
-            entry.maxLines = GROUP_MAX_LINES;
             mGroupEntries.add(entry);
         }
     }
@@ -851,7 +852,7 @@
         for (AccountType accountType : mOtherEntriesMap.keySet()) {
 
             // Add a title for each third party app
-            mAllEntries.add(NetworkTitleViewEntry.fromAccountType(mContext, accountType));
+            mAllEntries.add(new NetworkTitleViewEntry(mContext, accountType));
 
             for (DetailViewEntry detailEntry : mOtherEntriesMap.get(accountType)) {
                 // Add indented separator
@@ -907,7 +908,7 @@
         };
 
         // Finally create the entry.
-        mAllEntries.add(NetworkTitleViewEntry.forMoreNetworks(mContext, onClickListener));
+        mAllEntries.add(new AddConnectionViewEntry(mContext, onClickListener));
     }
 
     /**
@@ -1045,23 +1046,31 @@
      */
     private void showListPopup(View anchorView, ListAdapter adapter,
             final AdapterView.OnItemClickListener onItemClickListener) {
-        final ListPopupWindow popup = new ListPopupWindow(mContext, null);
-        popup.setAnchorView(anchorView);
-        popup.setWidth(anchorView.getWidth());
-        popup.setAdapter(adapter);
-        popup.setModal(true);
+        dismissPopupIfShown();
+        mPopup = new ListPopupWindow(mContext, null);
+        mPopup.setAnchorView(anchorView);
+        mPopup.setWidth(anchorView.getWidth());
+        mPopup.setAdapter(adapter);
+        mPopup.setModal(true);
 
         // We need to wrap the passed onItemClickListener here, so that we can dismiss() the
         // popup afterwards.  Otherwise we could directly use the passed listener.
-        popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+        mPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position,
                     long id) {
                 onItemClickListener.onItemClick(parent, view, position, id);
-                popup.dismiss();
+                dismissPopupIfShown();
             }
         });
-        popup.show();
+        mPopup.show();
+    }
+
+    private void dismissPopupIfShown() {
+        if (mPopup != null && mPopup.isShowing()) {
+            mPopup.dismiss();
+        }
+        mPopup = null;
     }
 
     /**
@@ -1156,35 +1165,43 @@
     }
 
     /**
-     * A title for a section of contact details from a single 3rd party network.  It's also
-     * used for the "More networks" entry, which has the same layout.
+     * A title for a section of contact details from a single 3rd party network.
      */
     private static class NetworkTitleViewEntry extends ViewEntry {
         private final Drawable mIcon;
         private final CharSequence mLabel;
-        private final View.OnClickListener mOnClickListener;
 
-        private NetworkTitleViewEntry(Drawable icon, CharSequence label, View.OnClickListener
-                onClickListener) {
+        public NetworkTitleViewEntry(Context context, AccountType type) {
             super(ViewAdapter.VIEW_TYPE_NETWORK_TITLE_ENTRY);
-            this.mIcon = icon;
-            this.mLabel = label;
-            this.mOnClickListener = onClickListener;
+            this.mIcon = type.getDisplayIcon(context);
+            this.mLabel = type.getDisplayLabel(context);
             this.isEnabled = false;
         }
 
-        public static NetworkTitleViewEntry fromAccountType(Context context, AccountType type) {
-            return new NetworkTitleViewEntry(
-                    type.getDisplayIcon(context), type.getDisplayLabel(context), null);
+        public Drawable getIcon() {
+            return mIcon;
         }
 
-        public static NetworkTitleViewEntry forMoreNetworks(Context context, View.OnClickListener
-                onClickListener) {
-            // TODO Icon is temporary.  Need proper one.
-            return new NetworkTitleViewEntry(
-                    context.getResources().getDrawable(R.drawable.ic_menu_add_field_holo_light),
-                    context.getString(R.string.add_connection_button),
-                    onClickListener);
+        public CharSequence getLabel() {
+            return mLabel;
+        }
+    }
+
+    /**
+     * This is used for the "Add Connections" entry.
+     */
+    private static class AddConnectionViewEntry extends ViewEntry {
+        private final Drawable mIcon;
+        private final CharSequence mLabel;
+        private final View.OnClickListener mOnClickListener;
+
+        private AddConnectionViewEntry(Context context, View.OnClickListener onClickListener) {
+            super(ViewAdapter.VIEW_TYPE_ADD_CONNECTION_ENTRY);
+            this.mIcon = context.getResources().getDrawable(
+                    R.drawable.ic_menu_add_field_holo_light);
+            this.mLabel = context.getString(R.string.add_connection_button);
+            this.mOnClickListener = onClickListener;
+            this.isEnabled = true;
         }
 
         @Override
@@ -1217,7 +1234,6 @@
         public String mimetype;
 
         public Context context = null;
-        public String resPackageName = null;
         public boolean isPrimary = false;
         public int secondaryActionIcon = -1;
         public int secondaryActionDescription = -1;
@@ -1229,8 +1245,6 @@
         public int presence = -1;
         public int chatCapability = 0;
 
-        public CharSequence footerLine = null;
-
         private boolean mIsInSubSection = false;
 
         DetailViewEntry() {
@@ -1255,7 +1269,6 @@
             entry.kind = (kind.titleRes == -1 || kind.titleRes == 0) ? ""
                     : context.getString(kind.titleRes);
             entry.data = buildDataString(kind, values, context);
-            entry.resPackageName = kind.resPackageName;
 
             if (kind.typeColumn != null && values.containsKey(kind.typeColumn)) {
                 entry.type = values.getAsInteger(kind.typeColumn);
@@ -1281,21 +1294,8 @@
             return entry;
         }
 
-        /**
-         * Apply given {@link DataStatus} values over this {@link DetailViewEntry}
-         *
-         * @param fillData When true, the given status replaces {@link #data}
-         *            and {@link #footerLine}. Otherwise only {@link #presence}
-         *            is updated.
-         */
-        public DetailViewEntry applyStatus(DataStatus status, boolean fillData) {
-            presence = status.getPresence();
-            if (fillData && status.isValid()) {
-                this.data = status.getStatus().toString();
-                this.footerLine = status.getTimestampLabel(context);
-            }
-
-            return this;
+        public void setPresence(int presence) {
+            this.presence = presence;
         }
 
         public void setIsInSubSection(boolean isInSubSection) {
@@ -1375,16 +1375,33 @@
         public final TextView displayNameView;
         public final TextView companyView;
         public final ImageView photoView;
-        public final CheckBox starredView;
+        public final View photoOverlayView;
+        public final ImageView starredView;
         public final int layoutResourceId;
 
         public HeaderViewCache(View view, int layoutResourceInflated) {
             displayNameView = (TextView) view.findViewById(R.id.name);
             companyView = (TextView) view.findViewById(R.id.company);
             photoView = (ImageView) view.findViewById(R.id.photo);
-            starredView = (CheckBox) view.findViewById(R.id.star);
+            photoOverlayView = view.findViewById(R.id.photo_touch_intercept_overlay);
+            starredView = (ImageView) view.findViewById(R.id.star);
             layoutResourceId = layoutResourceInflated;
         }
+
+        public void enablePhotoOverlay(OnClickListener listener) {
+            if (photoOverlayView != null) {
+                photoOverlayView.setOnClickListener(listener);
+                photoOverlayView.setVisibility(View.VISIBLE);
+            }
+        }
+    }
+
+    private static class KindTitleViewCache {
+        public final TextView titleView;
+
+        public KindTitleViewCache(View view) {
+            titleView = (TextView)view.findViewById(R.id.title);
+        }
     }
 
     /**
@@ -1401,13 +1418,27 @@
     }
 
     /**
+     * Cache of the children views for a view that displays a {@link AddConnectionViewEntry}
+     */
+    private static class AddConnectionViewCache {
+        public final TextView name;
+        public final ImageView icon;
+        public final View primaryActionView;
+
+        public AddConnectionViewCache(View view) {
+            name = (TextView) view.findViewById(R.id.add_connection_label);
+            icon = (ImageView) view.findViewById(R.id.add_connection_icon);
+            primaryActionView = view.findViewById(R.id.primary_action_view);
+        }
+    }
+
+    /**
      * Cache of the children views of a contact detail entry represented by a
      * {@link DetailViewEntry}
      */
     private static class DetailViewCache {
         public final TextView type;
         public final TextView data;
-        public final TextView footer;
         public final ImageView presenceIcon;
         public final ImageView secondaryActionButton;
         public final View actionsViewContainer;
@@ -1421,7 +1452,6 @@
                 OnClickListener secondaryActionClickListener) {
             type = (TextView) view.findViewById(R.id.type);
             data = (TextView) view.findViewById(R.id.data);
-            footer = (TextView) view.findViewById(R.id.footer);
             primaryIndicator = view.findViewById(R.id.primary_indicator);
             presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
 
@@ -1446,8 +1476,9 @@
         public static final int VIEW_TYPE_HEADER_ENTRY = 1;
         public static final int VIEW_TYPE_KIND_TITLE_ENTRY = 2;
         public static final int VIEW_TYPE_NETWORK_TITLE_ENTRY = 3;
-        public static final int VIEW_TYPE_SEPARATOR_ENTRY = 4;
-        private static final int VIEW_TYPE_COUNT = 5;
+        public static final int VIEW_TYPE_ADD_CONNECTION_ENTRY = 4;
+        public static final int VIEW_TYPE_SEPARATOR_ENTRY = 5;
+        private static final int VIEW_TYPE_COUNT = 6;
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
@@ -1462,6 +1493,8 @@
                     return getDetailEntryView(position, convertView, parent);
                 case VIEW_TYPE_NETWORK_TITLE_ENTRY:
                     return getNetworkTitleEntryView(position, convertView, parent);
+                case VIEW_TYPE_ADD_CONNECTION_ENTRY:
+                    return getAddConnectionEntryView(position, convertView, parent);
                 default:
                     throw new IllegalStateException("Invalid view type ID " +
                             getItemViewType(position));
@@ -1498,13 +1531,21 @@
 
             // Set the photo if it should be displayed
             if (viewCache.photoView != null) {
-                ContactDetailDisplayUtils.setPhoto(mContext, mContactData, viewCache.photoView);
+                final boolean expandOnClick = mContactData.getPhotoUri() != null;
+                final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
+                        mContext, mContactData, viewCache.photoView, expandOnClick);
+
+                if (expandOnClick || mContactData.isWritableContact(mContext)) {
+                    viewCache.enablePhotoOverlay(listener);
+                }
             }
 
             // Set the starred state if it should be displayed
-            final CheckBox favoritesStar = viewCache.starredView;
+            final ImageView favoritesStar = viewCache.starredView;
             if (favoritesStar != null) {
-                ContactDetailDisplayUtils.setStarred(mContactData, favoritesStar);
+                ContactDetailDisplayUtils.configureStarredImageView(favoritesStar,
+                        mContactData.isDirectoryEntry(), mContactData.isUserProfile(),
+                        mContactData.getStarred());
                 final Uri lookupUri = mContactData.getLookupUri();
                 favoritesStar.setOnClickListener(new OnClickListener() {
                     @Override
@@ -1512,8 +1553,22 @@
                         // Toggle "starred" state
                         // Make sure there is a contact
                         if (lookupUri != null) {
+                            // Read the current starred value from the UI instead of using the last
+                            // loaded state. This allows rapid tapping without writing the same
+                            // value several times
+                            final Object tag = favoritesStar.getTag();
+                            final boolean isStarred = tag == null
+                                    ? false : (Boolean) favoritesStar.getTag();
+
+                            // To improve responsiveness, swap out the picture (and tag) in the UI
+                            // already
+                            ContactDetailDisplayUtils.configureStarredImageView(favoritesStar,
+                                    mContactData.isDirectoryEntry(), mContactData.isUserProfile(),
+                                    !isStarred);
+
+                            // Now perform the real save
                             Intent intent = ContactSaveService.createSetStarredIntent(
-                                    getContext(), lookupUri, favoritesStar.isChecked());
+                                    getContext(), lookupUri, !isStarred);
                             getContext().startService(intent);
                         }
                     }
@@ -1537,11 +1592,19 @@
 
         private View getKindTitleEntryView(int position, View convertView, ViewGroup parent) {
             final KindTitleViewEntry entry = (KindTitleViewEntry) getItem(position);
+            final View result;
+            final KindTitleViewCache viewCache;
 
-            final View result = (convertView != null) ? convertView :
-                    mInflater.inflate(R.layout.list_separator, parent, false);
-            final TextView titleTextView = (TextView) result.findViewById(R.id.title);
-            titleTextView.setText(entry.getTitle());
+            if (convertView != null) {
+                result = convertView;
+                viewCache = (KindTitleViewCache)result.getTag();
+            } else {
+                result = mInflater.inflate(R.layout.list_separator, parent, false);
+                viewCache = new KindTitleViewCache(result);
+                result.setTag(viewCache);
+            }
+
+            viewCache.titleView.setText(entry.getTitle());
 
             return result;
         }
@@ -1559,8 +1622,6 @@
                         parent, false);
                 viewCache = new NetworkTitleViewCache(result);
                 result.setTag(viewCache);
-                result.findViewById(R.id.primary_action_view).setOnClickListener(
-                        entry.mOnClickListener);
             }
 
             viewCache.name.setText(entry.getLabel());
@@ -1569,6 +1630,27 @@
             return result;
         }
 
+        private View getAddConnectionEntryView(int position, View convertView, ViewGroup parent) {
+            final AddConnectionViewEntry entry = (AddConnectionViewEntry) getItem(position);
+            final View result;
+            final AddConnectionViewCache viewCache;
+
+            if (convertView != null) {
+                result = convertView;
+                viewCache = (AddConnectionViewCache) result.getTag();
+            } else {
+                result = mInflater.inflate(R.layout.contact_detail_add_connection_entry_view,
+                        parent, false);
+                viewCache = new AddConnectionViewCache(result);
+                result.setTag(viewCache);
+            }
+            viewCache.name.setText(entry.getLabel());
+            viewCache.icon.setImageDrawable(entry.getIcon());
+            viewCache.primaryActionView.setOnClickListener(entry.mOnClickListener);
+
+            return result;
+        }
+
         private View getDetailEntryView(int position, View convertView, ViewGroup parent) {
             final DetailViewEntry entry = (DetailViewEntry) getItem(position);
             final View v;
@@ -1606,14 +1688,6 @@
             views.data.setText(entry.data);
             setMaxLines(views.data, entry.maxLines);
 
-            // Set the footer
-            if (!TextUtils.isEmpty(entry.footerLine)) {
-                views.footer.setText(entry.footerLine);
-                views.footer.setVisibility(View.VISIBLE);
-            } else {
-                views.footer.setVisibility(View.GONE);
-            }
-
             // Set the default contact method
             views.primaryIndicator.setVisibility(entry.isPrimary ? View.VISIBLE : View.GONE);
 
@@ -1865,17 +1939,7 @@
         // Checking for empty string
         if (TextUtils.isEmpty(textToCopy)) return;
 
-        // Adding item to clipboard
-        ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(
-                Context.CLIPBOARD_SERVICE);
-        String[] mimeTypes = new String[]{detailViewEntry.mimetype};
-        ClipData.Item clipDataItem = new ClipData.Item(textToCopy);
-        ClipData cd = new ClipData(detailViewEntry.typeString, mimeTypes, clipDataItem);
-        clipboardManager.setPrimaryClip(cd);
-
-        // Display Confirmation Toast
-        String toastText = getString(R.string.toast_text_copied);
-        Toast.makeText(getActivity(), toastText, Toast.LENGTH_SHORT).show();
+        ClipboardUtils.copyText(getActivity(), detailViewEntry.typeString, textToCopy, true);
     }
 
     @Override
@@ -1903,9 +1967,7 @@
                     }
                 } else if (mPrimaryPhoneUri != null) {
                     // There isn't anything selected, call the default number
-                    final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            mPrimaryPhoneUri);
-                    mContext.startActivity(intent);
+                    mContext.startActivity(ContactsUtils.getCallIntent(mPrimaryPhoneUri));
                     return true;
                 }
                 return false;
@@ -1988,8 +2050,7 @@
             if (defaultGroupId == -1) return;
 
             // add the group membership to the current state
-            final EntityDeltaList contactDeltaList = EntityDeltaList.fromIterator(
-                    mContactData.getEntities().iterator());
+            final EntityDeltaList contactDeltaList = mContactData.createEntityDeltaList();
             final EntityDelta rawContactEntityDelta = contactDeltaList.get(0);
 
             final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
@@ -2007,7 +2068,7 @@
             // should update the ui
             final Intent intent = ContactSaveService.createSaveContactIntent(getActivity(),
                     contactDeltaList, "", 0, false, getActivity().getClass(),
-                    Intent.ACTION_VIEW);
+                    Intent.ACTION_VIEW, null);
             getActivity().startService(intent);
         }
     }
@@ -2136,17 +2197,14 @@
     private final static class InvitableAccountTypesAdapter extends BaseAdapter {
         private final Context mContext;
         private final LayoutInflater mInflater;
-        private final ContactLoader.Result mContactData;
         private final ArrayList<AccountType> mAccountTypes;
 
         public InvitableAccountTypesAdapter(Context context, ContactLoader.Result contactData) {
             mContext = context;
             mInflater = LayoutInflater.from(context);
-            mContactData = contactData;
             final List<AccountType> types = contactData.getInvitableAccountTypes();
             mAccountTypes = new ArrayList<AccountType>(types.size());
 
-            AccountTypeManager manager = AccountTypeManager.getInstance(context);
             for (int i = 0; i < types.size(); i++) {
                 mAccountTypes.add(types.get(i));
             }
diff --git a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
index 756b1c7..08ed87b 100644
--- a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
@@ -17,20 +17,21 @@
 package com.android.contacts.detail;
 
 import com.android.contacts.R;
+import com.android.contacts.widget.FrameLayoutWithOverlay;
 
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 import android.view.View.OnTouchListener;
 import android.widget.HorizontalScrollView;
 
 /**
  * This is a horizontally scrolling carousel with 2 fragments: one to see info about the contact and
  * one to see updates from the contact. Depending on the scroll position and user selection of which
- * fragment to currently view, the alpha values and touch interceptors over each fragment are
- * configured accordingly.
+ * fragment to currently view, the touch interceptors over each fragment are configured accordingly.
  */
 public class ContactDetailFragmentCarousel extends HorizontalScrollView implements OnTouchListener {
 
@@ -60,12 +61,6 @@
     private int mMinFragmentWidth = Integer.MIN_VALUE;
 
     /**
-     * Maximum alpha value of the overlay on the fragment that is not currently selected
-     * (if there are 1+ fragments in the carousel).
-     */
-    private static final float MAX_ALPHA = 0.5f;
-
-    /**
      * Fragment width (if there are 1+ fragments in the carousel) as defined as a fraction of the
      * screen width.
      */
@@ -81,11 +76,8 @@
     private int mCurrentPage = ABOUT_PAGE;
     private int mLastScrollPosition;
 
-    private ViewOverlay mAboutFragment;
-    private ViewOverlay mUpdatesFragment;
-
-    private View mDetailFragmentView;
-    private View mUpdatesFragmentView;
+    private FrameLayoutWithOverlay mAboutFragment;
+    private FrameLayoutWithOverlay mUpdatesFragment;
 
     public ContactDetailFragmentCarousel(Context context) {
         this(context, null);
@@ -148,26 +140,18 @@
     public void setCurrentPage(int pageIndex) {
         mCurrentPage = pageIndex;
 
-        if (mAboutFragment != null && mUpdatesFragment != null) {
-            mAboutFragment.setAlphaLayerValue(mCurrentPage == ABOUT_PAGE ? 0 : MAX_ALPHA);
-            mUpdatesFragment.setAlphaLayerValue(mCurrentPage == UPDATES_PAGE ? 0 : MAX_ALPHA);
-        }
+        updateTouchInterceptors();
     }
 
     /**
      * Set the view containers for the detail and updates fragment.
      */
-    public void setFragmentViews(View detailFragmentView, View updatesFragmentView) {
-        mDetailFragmentView = detailFragmentView;
-        mUpdatesFragmentView = updatesFragmentView;
-    }
+    public void setFragmentViews(FrameLayoutWithOverlay about, FrameLayoutWithOverlay updates) {
+        mAboutFragment = about;
+        mUpdatesFragment = updates;
 
-    /**
-     * Set the detail and updates fragment.
-     */
-    public void setFragments(ViewOverlay aboutFragment, ViewOverlay updatesFragment) {
-        mAboutFragment = aboutFragment;
-        mUpdatesFragment = updatesFragment;
+        mAboutFragment.setOverlayOnClickListener(mAboutFragTouchInterceptListener);
+        mUpdatesFragment.setOverlayOnClickListener(mUpdatesFragTouchInterceptListener);
     }
 
     /**
@@ -177,18 +161,28 @@
     public void enableSwipe(boolean enable) {
         if (mEnableSwipe != enable) {
             mEnableSwipe = enable;
-            if (mUpdatesFragmentView != null) {
-                mUpdatesFragmentView.setVisibility(enable ? View.VISIBLE : View.GONE);
+            if (mUpdatesFragment != null) {
+                mUpdatesFragment.setVisibility(enable ? View.VISIBLE : View.GONE);
                 if (mCurrentPage == ABOUT_PAGE) {
-                    mDetailFragmentView.requestFocus();
+                    mAboutFragment.requestFocus();
                 } else {
-                    mUpdatesFragmentView.requestFocus();
+                    mUpdatesFragment.requestFocus();
                 }
                 updateTouchInterceptors();
             }
         }
     }
 
+    /**
+     * Reset the fragment carousel to show the about page.
+     */
+    public void reset() {
+        if (mCurrentPage != ABOUT_PAGE) {
+            mCurrentPage = ABOUT_PAGE;
+            snapToEdge();
+        }
+    }
+
     public int getCurrentPage() {
         return mCurrentPage;
     }
@@ -210,25 +204,13 @@
     };
 
     private void updateTouchInterceptors() {
-        switch (mCurrentPage) {
-            case ABOUT_PAGE:
-                // The "about this contact" page has been selected, so disable the touch interceptor
-                // on this page and enable it for the "updates" page.
-                mAboutFragment.disableTouchInterceptor();
-                mUpdatesFragment.enableTouchInterceptor(mUpdatesFragTouchInterceptListener);
-                break;
-            case UPDATES_PAGE:
-                mUpdatesFragment.disableTouchInterceptor();
-                mAboutFragment.enableTouchInterceptor(mAboutFragTouchInterceptListener);
-                break;
+        // Disable the touch-interceptor on the selected page, and enable it on the other.
+        if (mAboutFragment != null) {
+            mAboutFragment.setOverlayClickable(mCurrentPage != ABOUT_PAGE);
         }
-    }
-
-    private void updateAlphaLayers() {
-        mAboutFragment.setAlphaLayerValue(mLastScrollPosition * MAX_ALPHA /
-                mAllowedHorizontalScrollLength);
-        mUpdatesFragment.setAlphaLayerValue(MAX_ALPHA - mLastScrollPosition * MAX_ALPHA /
-                mAllowedHorizontalScrollLength);
+        if (mUpdatesFragment != null) {
+            mUpdatesFragment.setOverlayClickable(mCurrentPage != UPDATES_PAGE);
+        }
     }
 
     @Override
@@ -237,19 +219,12 @@
         if (!mEnableSwipe) {
             return;
         }
-        mLastScrollPosition= l;
-        updateAlphaLayers();
+        mLastScrollPosition = l;
     }
 
     private void snapToEdge() {
-        switch (mCurrentPage) {
-            case ABOUT_PAGE:
-                smoothScrollTo(0, 0);
-                break;
-            case UPDATES_PAGE:
-                smoothScrollTo(mAllowedHorizontalScrollLength, 0);
-                break;
-        }
+        final int x = mCurrentPage == ABOUT_PAGE ? 0 : mAllowedHorizontalScrollLength;
+        smoothScrollTo(x,0);
         updateTouchInterceptors();
     }
 
@@ -283,4 +258,14 @@
         }
         return false;
     }
+
+    /**
+     * Starts an "appear" animation by moving in the "Updates" from the right.
+     */
+    public void animateAppear() {
+        final int x = Math.round((1.0f - FRAGMENT_WIDTH_SCREEN_WIDTH_FRACTION) * getWidth());
+        mUpdatesFragment.setTranslationX(x);
+        final ViewPropertyAnimator animator = mUpdatesFragment.animate();
+        animator.translationX(0.0f);
+    }
 }
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 74811e4..2c18d4f 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -17,10 +17,14 @@
 package com.android.contacts.detail;
 
 import com.android.contacts.ContactLoader;
+
 import com.android.contacts.NfcHandler;
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.util.UriUtils;
+import com.android.contacts.widget.FrameLayoutWithOverlay;
+import com.android.contacts.widget.TransitionAnimationView;
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
@@ -35,6 +39,7 @@
 import android.support.v4.view.ViewPager.OnPageChangeListener;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 import android.view.animation.AnimationUtils;
 import android.widget.AbsListView;
 import android.widget.AbsListView.OnScrollListener;
@@ -51,20 +56,38 @@
     private static final int TAB_INDEX_DETAIL = 0;
     private static final int TAB_INDEX_UPDATES = 1;
 
+    private final int SINGLE_PANE_FADE_IN_DURATION = 275;
+
     /**
-     * There are 3 possible layouts for the contact detail screen:
-     * 1. TWO_COLUMN - Tall and wide screen so the 2 pages can be shown side-by-side
-     * 2. VIEW_PAGER_AND_TAB_CAROUSEL - Tall and narrow screen to allow swipe between the 2 pages
-     * 3. FRAGMENT_CAROUSEL- Short and wide screen to allow half of the other page to show at a time
+     * There are 4 possible layouts for the contact detail screen: TWO_COLUMN,
+     * VIEW_PAGER_AND_TAB_CAROUSEL, FRAGMENT_CAROUSEL, and TWO_COLUMN_FRAGMENT_CAROUSEL.
      */
-    private enum LayoutMode {
-        TWO_COLUMN, VIEW_PAGER_AND_TAB_CAROUSEL, FRAGMENT_CAROUSEL,
+    private interface LayoutMode {
+        /**
+         * Tall and wide screen with details and updates shown side-by-side.
+         */
+        static final int TWO_COLUMN = 0;
+        /**
+         * Tall and narrow screen to allow swipe between the details and updates.
+         */
+        static final int VIEW_PAGER_AND_TAB_CAROUSEL = 1;
+        /**
+         * Short and wide screen to allow part of the other page to show.
+         */
+        static final int FRAGMENT_CAROUSEL = 2;
+        /**
+         * Same as FRAGMENT_CAROUSEL (allowing part of the other page to show) except the details
+         * layout is similar to the details layout in TWO_COLUMN mode.
+         */
+        static final int TWO_COLUMN_FRAGMENT_CAROUSEL = 3;
     }
 
     private final Activity mActivity;
     private final LayoutInflater mLayoutInflater;
     private final FragmentManager mFragmentManager;
 
+    private final View mViewContainer;
+    private final TransitionAnimationView mTransitionAnimationView;
     private ContactDetailFragment mDetailFragment;
     private ContactDetailUpdatesFragment mUpdatesFragment;
 
@@ -78,19 +101,20 @@
     private final ContactDetailTabCarousel mTabCarousel;
     private final ContactDetailFragmentCarousel mFragmentCarousel;
 
-    private ContactDetailFragment.Listener mContactDetailFragmentListener;
+    private final ContactDetailFragment.Listener mContactDetailFragmentListener;
 
     private ContactLoader.Result mContactData;
     private Uri mContactUri;
 
     private boolean mTabCarouselIsAnimating;
+
     private boolean mContactHasUpdates;
 
-    private LayoutMode mLayoutMode;
+    private int mLayoutMode;
 
     public ContactDetailLayoutController(Activity activity, Bundle savedState,
-            FragmentManager fragmentManager, View viewContainer, ContactDetailFragment.Listener
-            contactDetailFragmentListener) {
+            FragmentManager fragmentManager, TransitionAnimationView animationView,
+            View viewContainer, ContactDetailFragment.Listener contactDetailFragmentListener) {
 
         if (fragmentManager == null) {
             throw new IllegalStateException("Cannot initialize a ContactDetailLayoutController "
@@ -103,7 +127,11 @@
         mFragmentManager = fragmentManager;
         mContactDetailFragmentListener = contactDetailFragmentListener;
 
+        mTransitionAnimationView = animationView;
+
         // Retrieve views in case this is view pager and carousel mode
+        mViewContainer = viewContainer;
+
         mViewPager = (ViewPager) viewContainer.findViewById(R.id.pager);
         mTabCarousel = (ContactDetailTabCarousel) viewContainer.findViewById(R.id.tab_carousel);
 
@@ -118,9 +146,14 @@
         // Determine the layout mode based on the presence of certain views in the layout XML.
         if (mViewPager != null) {
             mLayoutMode = LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL;
+        } else if (mFragmentCarousel != null) {
+            if (PhoneCapabilityTester.isUsingTwoPanes(mActivity)) {
+                mLayoutMode = LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL;
+            } else {
+                mLayoutMode = LayoutMode.FRAGMENT_CAROUSEL;
+            }
         } else {
-            mLayoutMode = (mFragmentCarousel != null) ? LayoutMode.FRAGMENT_CAROUSEL :
-                    LayoutMode.TWO_COLUMN;
+            mLayoutMode = LayoutMode.TWO_COLUMN;
         }
 
         initialize(savedState);
@@ -131,7 +164,7 @@
         mDetailFragment = (ContactDetailFragment) mFragmentManager.findFragmentByTag(
                 ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
         mUpdatesFragment = (ContactDetailUpdatesFragment) mFragmentManager.findFragmentByTag(
-                ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
+                ContactDetailViewPagerAdapter.UPDATES_FRAGMENT_TAG);
 
         // If the detail fragment was found in the {@link FragmentManager} then we don't need to add
         // it again. Otherwise, create the fragments dynamically and remember to add them to the
@@ -154,7 +187,7 @@
         }
 
         switch (mLayoutMode) {
-            case VIEW_PAGER_AND_TAB_CAROUSEL: {
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL: {
                 // Inflate 2 view containers to pass in as children to the {@link ViewPager},
                 // which will in turn be the parents to the mDetailFragment and mUpdatesFragment
                 // since the fragments must have the same parent view IDs in both landscape and
@@ -178,7 +211,7 @@
                     transaction.add(R.id.about_fragment_container, mDetailFragment,
                             ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
                     transaction.add(R.id.updates_fragment_container, mUpdatesFragment,
-                            ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
+                            ContactDetailViewPagerAdapter.UPDATES_FRAGMENT_TAG);
                     transaction.commitAllowingStateLoss();
                     mFragmentManager.executePendingTransactions();
                 }
@@ -192,19 +225,20 @@
                 mViewPager.setCurrentItem(currentPageIndex);
                 break;
             }
-            case TWO_COLUMN: {
+            case LayoutMode.TWO_COLUMN: {
                 if (!fragmentsAddedToFragmentManager) {
                     FragmentTransaction transaction = mFragmentManager.beginTransaction();
                     transaction.add(R.id.about_fragment_container, mDetailFragment,
                             ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
                     transaction.add(R.id.updates_fragment_container, mUpdatesFragment,
-                            ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
+                            ContactDetailViewPagerAdapter.UPDATES_FRAGMENT_TAG);
                     transaction.commitAllowingStateLoss();
                     mFragmentManager.executePendingTransactions();
                 }
                 break;
             }
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL:
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL: {
                 // Add the fragments to the fragment containers in the carousel using a
                 // {@link FragmentTransaction} if they haven't already been added to the
                 // {@link FragmentManager}.
@@ -213,14 +247,16 @@
                     transaction.add(R.id.about_fragment_container, mDetailFragment,
                             ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
                     transaction.add(R.id.updates_fragment_container, mUpdatesFragment,
-                            ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
+                            ContactDetailViewPagerAdapter.UPDATES_FRAGMENT_TAG);
                     transaction.commitAllowingStateLoss();
                     mFragmentManager.executePendingTransactions();
                 }
 
-                mFragmentCarousel.setFragmentViews(mDetailFragmentView, mUpdatesFragmentView);
-                mFragmentCarousel.setFragments(mDetailFragment, mUpdatesFragment);
+                mFragmentCarousel.setFragmentViews(
+                        (FrameLayoutWithOverlay) mDetailFragmentView,
+                        (FrameLayoutWithOverlay) mUpdatesFragmentView);
                 mFragmentCarousel.setCurrentPage(currentPageIndex);
+
                 break;
             }
         }
@@ -228,7 +264,7 @@
         // Setup the layout if we already have a saved state
         if (savedState != null) {
             if (mContactHasUpdates) {
-                showContactWithUpdates();
+                showContactWithUpdates(false);
             } else {
                 showContactWithoutUpdates();
             }
@@ -236,10 +272,40 @@
     }
 
     public void setContactData(ContactLoader.Result data) {
+        final boolean contactWasLoaded;
+        final boolean contactHadUpdates;
+        final boolean isDifferentContact;
+        if (mContactData == null) {
+            contactHadUpdates = false;
+            contactWasLoaded = false;
+            isDifferentContact = true;
+        } else {
+            contactHadUpdates = mContactHasUpdates;
+            contactWasLoaded = true;
+            isDifferentContact =
+                    !UriUtils.areEqual(mContactData.getLookupUri(), data.getLookupUri());
+        }
         mContactData = data;
         mContactHasUpdates = !data.getStreamItems().isEmpty();
+
+        if (PhoneCapabilityTester.isUsingTwoPanes(mActivity)) {
+            // Tablet: If we already showed data before, we want to cross-fade from screen to screen
+            if (contactWasLoaded && mTransitionAnimationView != null && isDifferentContact) {
+                mTransitionAnimationView.startMaskTransition(mContactData == null);
+            }
+        } else {
+            // Small screen: We are on our own screen. Fade the data in, but only the first time
+            if (!contactWasLoaded) {
+                mViewContainer.setAlpha(0.0f);
+                final ViewPropertyAnimator animator = mViewContainer.animate();
+                animator.alpha(1.0f);
+                animator.setDuration(SINGLE_PANE_FADE_IN_DURATION);
+            }
+        }
+
         if (mContactHasUpdates) {
-            showContactWithUpdates();
+            showContactWithUpdates(
+                    contactWasLoaded && contactHadUpdates == false);
         } else {
             showContactWithoutUpdates();
         }
@@ -247,19 +313,27 @@
 
     public void showEmptyState() {
         switch (mLayoutMode) {
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL: {
                 mFragmentCarousel.setCurrentPage(0);
                 mFragmentCarousel.enableSwipe(false);
                 mDetailFragment.showEmptyState();
                 break;
             }
-            case TWO_COLUMN: {
+            case LayoutMode.TWO_COLUMN: {
                 mDetailFragment.setShowStaticPhoto(false);
                 mUpdatesFragmentView.setVisibility(View.GONE);
                 mDetailFragment.showEmptyState();
                 break;
             }
-            case VIEW_PAGER_AND_TAB_CAROUSEL: {
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL: {
+                mFragmentCarousel.setCurrentPage(0);
+                mFragmentCarousel.enableSwipe(false);
+                mDetailFragment.setShowStaticPhoto(false);
+                mUpdatesFragmentView.setVisibility(View.GONE);
+                mDetailFragment.showEmptyState();
+                break;
+            }
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL: {
                 mDetailFragment.setShowStaticPhoto(false);
                 mDetailFragment.showEmptyState();
                 mTabCarousel.loadData(null);
@@ -277,7 +351,7 @@
      * Setup the layout for the contact with updates.
      * TODO: Clean up this method so it's easier to understand.
      */
-    private void showContactWithUpdates() {
+    private void showContactWithUpdates(boolean animateStateChange) {
         if (mContactData == null) {
             return;
         }
@@ -287,7 +361,14 @@
         boolean isDifferentContact = !UriUtils.areEqual(previousContactUri, mContactUri);
 
         switch (mLayoutMode) {
-            case TWO_COLUMN: {
+            case LayoutMode.TWO_COLUMN: {
+                if (!isDifferentContact && animateStateChange) {
+                    // This is screen is very hard to animate properly, because there is such a hard
+                    // cut from the regular version. A proper animation would have to reflow text
+                    // and move things around. Doing a simple cross-fade instead.
+                    mTransitionAnimationView.startMaskTransition(false);
+                }
+
                 // Set the contact data (hide the static photo because the photo will already be in
                 // the header that scrolls with contact details).
                 mDetailFragment.setShowStaticPhoto(false);
@@ -295,7 +376,7 @@
                 mUpdatesFragmentView.setVisibility(View.VISIBLE);
                 break;
             }
-            case VIEW_PAGER_AND_TAB_CAROUSEL: {
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL: {
                 // Update and show the tab carousel (also restore its last saved position)
                 mTabCarousel.loadData(mContactData);
                 mTabCarousel.restoreYCoordinate();
@@ -307,11 +388,30 @@
                     resetViewPager();
                     resetTabCarousel();
                 }
+                if (!isDifferentContact && animateStateChange) {
+                    mTabCarousel.animateAppear(mViewContainer.getWidth(),
+                            mDetailFragment.getFirstListItemOffset());
+                }
                 break;
             }
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL: {
                 // Allow swiping between all fragments
                 mFragmentCarousel.enableSwipe(true);
+                if (!isDifferentContact && animateStateChange) {
+                    mFragmentCarousel.animateAppear();
+                }
+                break;
+            }
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL: {
+                // Allow swiping between all fragments
+                mFragmentCarousel.enableSwipe(true);
+                if (isDifferentContact) {
+                    mFragmentCarousel.reset();
+                }
+                if (!isDifferentContact && animateStateChange) {
+                    mFragmentCarousel.animateAppear();
+                }
+                mDetailFragment.setShowStaticPhoto(false);
                 break;
             }
             default:
@@ -340,13 +440,13 @@
         boolean isDifferentContact = !UriUtils.areEqual(previousContactUri, mContactUri);
 
         switch (mLayoutMode) {
-            case TWO_COLUMN:
+            case LayoutMode.TWO_COLUMN:
                 // Show the static photo which is next to the list of scrolling contact details
                 mDetailFragment.setShowStaticPhoto(true);
                 // Hide the updates fragment
                 mUpdatesFragmentView.setVisibility(View.GONE);
                 break;
-            case VIEW_PAGER_AND_TAB_CAROUSEL:
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL:
                 // Hide the tab carousel
                 mTabCarousel.setVisibility(View.GONE);
                 // Update ViewPager to disable swipe so that it only shows the detail fragment
@@ -354,12 +454,16 @@
                 mViewPagerAdapter.enableSwipe(false);
                 mViewPager.setCurrentItem(0, false /* smooth transition */);
                 break;
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL:
                 // Disable swipe so only the detail fragment shows
                 mFragmentCarousel.setCurrentPage(0);
                 mFragmentCarousel.enableSwipe(false);
                 break;
-            }
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL:
+                mFragmentCarousel.setCurrentPage(0);
+                mFragmentCarousel.enableSwipe(false);
+                mDetailFragment.setShowStaticPhoto(true);
+                break;
             default:
                 throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
         }
@@ -425,9 +529,8 @@
             // these scroll changes to the tab carousel. Ignore these events though if the carousel
             // is actually controlling the {@link ViewPager} scrolls because it will already be
             // in the correct position.
-            if (mViewPager.isFakeDragging()) {
-                return;
-            }
+            if (mViewPager.isFakeDragging()) return;
+
             int x = (int) ((position + positionOffset) *
                     mTabCarousel.getAllowedHorizontalScrollLength());
             mTabCarousel.scrollTo(x, 0);
@@ -560,34 +663,31 @@
         }
     };
 
-    private final ContactDetailTabCarousel.Listener mTabCarouselListener =
-            new ContactDetailTabCarousel.Listener() {
+    private final ContactDetailTabCarousel.Listener mTabCarouselListener
+            = new ContactDetailTabCarousel.Listener() {
 
         @Override
         public void onTouchDown() {
-            // The user just started scrolling the carousel, so begin "fake dragging" the
-            // {@link ViewPager} if it's not already doing so.
-            if (mViewPager.isFakeDragging()) {
-                return;
-            }
-            mViewPager.beginFakeDrag();
+            // The user just started scrolling the carousel, so begin
+            // "fake dragging" the {@link ViewPager} if it's not already
+            // doing so.
+            if (!mViewPager.isFakeDragging()) mViewPager.beginFakeDrag();
         }
 
         @Override
         public void onTouchUp() {
-            // The user just stopped scrolling the carousel, so stop "fake dragging" the
-            // {@link ViewPager} if was doing so before.
-            if (mViewPager.isFakeDragging()) {
-                mViewPager.endFakeDrag();
-            }
+            // The user just stopped scrolling the carousel, so stop
+            // "fake dragging" the {@link ViewPager} if it was doing so
+            // before.
+            if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
         }
 
         @Override
         public void onScrollChanged(int l, int t, int oldl, int oldt) {
-            // The user is scrolling the carousel, so send the scroll deltas to the
-            // {@link ViewPager} so it can move in sync.
+            // The user is scrolling the carousel, so send the scroll
+            // deltas to the {@link ViewPager} so it can move in sync.
             if (mViewPager.isFakeDragging()) {
-                mViewPager.fakeDragBy(oldl-l);
+                mViewPager.fakeDragBy(oldl - l);
             }
         }
 
diff --git a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
new file mode 100644
index 0000000..dffb37b
--- /dev/null
+++ b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 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.contacts.detail;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactLoader.Result;
+import com.android.contacts.activities.PhotoSelectionActivity;
+import com.android.contacts.model.EntityDeltaList;
+import com.android.contacts.util.ImageViewDrawableSetter;
+
+/**
+ * Extends superclass with methods specifically for setting the contact-detail
+ * photo.
+ */
+public class ContactDetailPhotoSetter extends ImageViewDrawableSetter {
+    public OnClickListener setupContactPhotoForClick(Context context, Result contactData,
+            ImageView photoView, boolean expandPhotoOnClick) {
+        setTarget(photoView);
+        Bitmap bitmap = setCompressedImage(contactData.getPhotoBinaryData());
+        return setupClickListener(context, contactData, bitmap, expandPhotoOnClick);
+    }
+
+    private static final class PhotoClickListener implements OnClickListener {
+
+        private final Context mContext;
+        private final Result mContactData;
+        private final Bitmap mPhotoBitmap;
+        private final byte[] mPhotoBytes;
+        private final boolean mExpandPhotoOnClick;
+
+        public PhotoClickListener(Context context, Result contactData, Bitmap photoBitmap,
+                byte[] photoBytes, boolean expandPhotoOnClick) {
+            mContext = context;
+            mContactData = contactData;
+            mPhotoBitmap = photoBitmap;
+            mPhotoBytes = photoBytes;
+            mExpandPhotoOnClick = expandPhotoOnClick;
+        }
+
+        @Override
+        public void onClick(View v) {
+            // Assemble the intent.
+            EntityDeltaList delta = mContactData.createEntityDeltaList();
+
+            // Find location and bounds of target view, adjusting based on the
+            // assumed local density.
+            final float appScale =
+                    mContext.getResources().getCompatibilityInfo().applicationScale;
+            final int[] pos = new int[2];
+            v.getLocationOnScreen(pos);
+
+            // rect is the bounds (in pixels) of the photo view in screen coordinates
+            final Rect rect = new Rect();
+            rect.left = (int) (pos[0] * appScale + 0.5f);
+            rect.top = (int) (pos[1] * appScale + 0.5f);
+            rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
+            rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
+
+            Uri photoUri = null;
+            if (mContactData.getPhotoUri() != null) {
+                photoUri = Uri.parse(mContactData.getPhotoUri());
+            }
+            Intent photoSelectionIntent = PhotoSelectionActivity.buildIntent(mContext,
+                    photoUri, mPhotoBitmap, mPhotoBytes, rect, delta, mContactData.isUserProfile(),
+                    mContactData.isDirectoryEntry(), mExpandPhotoOnClick);
+            // Cache the bitmap directly, so the activity can pull it from the
+            // photo manager.
+            if (mPhotoBitmap != null) {
+                ContactPhotoManager.getInstance(mContext).cacheBitmap(
+                        photoUri, mPhotoBitmap, mPhotoBytes);
+            }
+            mContext.startActivity(photoSelectionIntent);
+        }
+    }
+
+    private OnClickListener setupClickListener(Context context, Result contactData, Bitmap bitmap,
+            boolean expandPhotoOnClick) {
+        final ImageView target = getTarget();
+        if (target == null) return null;
+
+        return new PhotoClickListener(
+                context, contactData, bitmap, getCompressedImage(), expandPhotoOnClick);
+    }
+}
diff --git a/src/com/android/contacts/detail/ContactDetailTabCarousel.java b/src/com/android/contacts/detail/ContactDetailTabCarousel.java
index 045e900..3929281 100644
--- a/src/com/android/contacts/detail/ContactDetailTabCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailTabCarousel.java
@@ -16,19 +16,27 @@
 
 package com.android.contacts.detail;
 
-import com.android.contacts.ContactLoader;
 import com.android.contacts.R;
+import com.android.contacts.ContactLoader;
+import com.android.contacts.detail.ContactDetailPhotoSetter;
+import com.android.contacts.util.MoreMath;
+import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.util.SchedulingUtils;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnTouchListener;
+import android.view.ViewPropertyAnimator;
 import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import android.util.Log;
+
 /**
  * This is a horizontally scrolling carousel with 2 tabs: one to see info about the contact and
  * one to see updates from the contact.
@@ -37,6 +45,9 @@
 
     private static final String TAG = ContactDetailTabCarousel.class.getSimpleName();
 
+    private static final int TRANSITION_TIME = 200;
+    private static final int TRANSITION_MOVE_IN_TIME = 150;
+
     private static final int TAB_INDEX_ABOUT = 0;
     private static final int TAB_INDEX_UPDATES = 1;
     private static final int TAB_COUNT = 2;
@@ -47,15 +58,23 @@
     /** Tab height as defined as a fraction of the screen width */
     private float mTabHeightScreenWidthFraction;
 
+    /** Height in pixels of the shadow under the tab carousel */
+    private int mTabShadowHeight;
+
     private ImageView mPhotoView;
+    private View mPhotoViewOverlay;
     private TextView mStatusView;
     private ImageView mStatusPhotoView;
+    private final ContactDetailPhotoSetter mPhotoSetter = new ContactDetailPhotoSetter();
 
     private Listener mListener;
 
     private int mCurrentTab = TAB_INDEX_ABOUT;
 
+    private View mTabAndShadowContainer;
+    private View mShadow;
     private CarouselTab mAboutTab;
+    private View mTabDivider;
     private CarouselTab mUpdatesTab;
 
     /** Last Y coordinate of the carousel when the tab at the given index was selected */
@@ -64,11 +83,13 @@
     private int mTabDisplayLabelHeight;
 
     private boolean mScrollToCurrentTab = false;
-    private int mLastScrollPosition;
-
+    private int mLastScrollPosition = Integer.MIN_VALUE;
     private int mAllowedHorizontalScrollLength = Integer.MIN_VALUE;
     private int mAllowedVerticalScrollLength = Integer.MIN_VALUE;
 
+    /** Factor to scale scroll-amount sent to listeners. */
+    private float mScrollScaleFactor = 1.0f;
+
     private static final float MAX_ALPHA = 0.5f;
 
     /**
@@ -77,6 +98,7 @@
     public interface Listener {
         public void onTouchDown();
         public void onTouchUp();
+
         public void onScrollChanged(int l, int t, int oldl, int oldt);
         public void onTabSelected(int position);
     }
@@ -89,6 +111,8 @@
         Resources resources = mContext.getResources();
         mTabDisplayLabelHeight = resources.getDimensionPixelSize(
                 R.dimen.detail_tab_carousel_tab_label_height);
+        mTabShadowHeight = resources.getDimensionPixelSize(
+                R.dimen.detail_contact_photo_shadow_height);
         mTabWidthScreenWidthFraction = resources.getFraction(
                 R.fraction.tab_width_screen_width_percentage, 1, 1);
         mTabHeightScreenWidthFraction = resources.getFraction(
@@ -98,43 +122,80 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        mTabAndShadowContainer = findViewById(R.id.tab_and_shadow_container);
         mAboutTab = (CarouselTab) findViewById(R.id.tab_about);
         mAboutTab.setLabel(mContext.getString(R.string.contactDetailAbout));
+        mAboutTab.setOverlayOnClickListener(mAboutTabTouchInterceptListener);
+
+        mTabDivider = findViewById(R.id.tab_divider);
 
         mUpdatesTab = (CarouselTab) findViewById(R.id.tab_update);
         mUpdatesTab.setLabel(mContext.getString(R.string.contactDetailUpdates));
+        mUpdatesTab.setOverlayOnClickListener(mUpdatesTabTouchInterceptListener);
 
-        mAboutTab.enableTouchInterceptor(mAboutTabTouchInterceptListener);
-        mUpdatesTab.enableTouchInterceptor(mUpdatesTabTouchInterceptListener);
+        mShadow = findViewById(R.id.shadow);
 
         // Retrieve the photo view for the "about" tab
+        // TODO: This should be moved down to mAboutTab, so that it hosts its own controls
         mPhotoView = (ImageView) mAboutTab.findViewById(R.id.photo);
+        mPhotoViewOverlay = mAboutTab.findViewById(R.id.photo_overlay);
 
         // Retrieve the social update views for the "updates" tab
+        // TODO: This should be moved down to mUpdatesTab, so that it hosts its own controls
         mStatusView = (TextView) mUpdatesTab.findViewById(R.id.status);
         mStatusPhotoView = (ImageView) mUpdatesTab.findViewById(R.id.status_photo);
+
+        // Workaround for framework issue... it shouldn't be necessary to have a
+        // clickable object in the hierarchy, but if not the horizontal scroll
+        // behavior doesn't work. Note: the "About" tab doesn't need this
+        // because we set a real click-handler elsewhere.
+        mStatusView.setClickable(true);
+        mStatusPhotoView.setClickable(true);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int screenWidth = MeasureSpec.getSize(widthMeasureSpec);
         // Compute the width of a tab as a fraction of the screen width
-        int tabWidth = (int) (mTabWidthScreenWidthFraction * screenWidth);
+        int tabWidth = Math.round(mTabWidthScreenWidthFraction * screenWidth);
 
         // Find the allowed scrolling length by subtracting the current visible screen width
         // from the total length of the tabs.
         mAllowedHorizontalScrollLength = tabWidth * TAB_COUNT - screenWidth;
 
-        int tabHeight = (int) (screenWidth * mTabHeightScreenWidthFraction);
+        // Scrolling by mAllowedHorizontalScrollLength causes listeners to
+        // scroll by the entire screen amount; compute the scale-factor
+        // necessary to make this so.
+        if (mAllowedHorizontalScrollLength == 0) {
+            // Guard against divide-by-zero.
+            // Note: this hard-coded value prevents a crash, but won't result in the
+            // desired scrolling behavior.  We rely on the framework calling onMeasure()
+            // again with a non-zero screen width.
+            mScrollScaleFactor = 1.0f;
+            Log.w(TAG, "set scale-factor to 1.0 to avoid divide-by-zero");
+        } else {
+            mScrollScaleFactor = screenWidth / mAllowedHorizontalScrollLength;
+        }
+
+        int tabHeight = Math.round(screenWidth * mTabHeightScreenWidthFraction) + mTabShadowHeight;
         // Set the child {@link LinearLayout} to be TAB_COUNT * the computed tab width so that the
         // {@link LinearLayout}'s children (which are the tabs) will evenly split that width.
         if (getChildCount() > 0) {
             View child = getChildAt(0);
-            child.measure(MeasureSpec.makeMeasureSpec(TAB_COUNT * tabWidth, MeasureSpec.EXACTLY),
+
+            // add 1 dip of separation between the tabs
+            final int seperatorPixels =
+                    (int)(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
+                    getResources().getDisplayMetrics()) + 0.5f);
+
+            child.measure(
+                    MeasureSpec.makeMeasureSpec(
+                            TAB_COUNT * tabWidth +
+                            (TAB_COUNT - 1) * seperatorPixels, MeasureSpec.EXACTLY),
                     MeasureSpec.makeMeasureSpec(tabHeight, MeasureSpec.EXACTLY));
         }
 
-        mAllowedVerticalScrollLength = tabHeight - mTabDisplayLabelHeight;
+        mAllowedVerticalScrollLength = tabHeight - mTabDisplayLabelHeight - mTabShadowHeight;
         setMeasuredDimension(
                 resolveSize(screenWidth, widthMeasureSpec),
                 resolveSize(tabHeight, heightMeasureSpec));
@@ -143,39 +204,168 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
-        if (mScrollToCurrentTab) {
-            mScrollToCurrentTab = false;
-            scrollTo(mCurrentTab == TAB_INDEX_ABOUT ? 0 : mAllowedHorizontalScrollLength, 0);
-            updateAlphaLayers();
+
+        // Defer this stuff until after the layout has finished.  This is because
+        // updateAlphaLayers() ultimately results in another layout request, and
+        // the framework currently can't handle this safely.
+        if (!mScrollToCurrentTab) return;
+        mScrollToCurrentTab = false;
+        SchedulingUtils.doAfterLayout(this, new Runnable() {
+            @Override
+            public void run() {
+                scrollTo(mCurrentTab == TAB_INDEX_ABOUT ? 0 : mAllowedHorizontalScrollLength, 0);
+                updateAlphaLayers();
+            }
+        });
+    }
+
+    /** When clicked, selects the corresponding tab. */
+    private class TabClickListener implements OnClickListener {
+        private final int mTab;
+
+        public TabClickListener(int tab) {
+            super();
+            mTab = tab;
+        }
+
+        @Override
+        public void onClick(View v) {
+            mListener.onTabSelected(mTab);
         }
     }
 
-    private final OnClickListener mAboutTabTouchInterceptListener = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mListener.onTabSelected(TAB_INDEX_ABOUT);
-        }
-    };
+    private final TabClickListener mAboutTabTouchInterceptListener =
+            new TabClickListener(TAB_INDEX_ABOUT);
 
-    private final OnClickListener mUpdatesTabTouchInterceptListener = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mListener.onTabSelected(TAB_INDEX_UPDATES);
+    private final TabClickListener mUpdatesTabTouchInterceptListener =
+            new TabClickListener(TAB_INDEX_UPDATES);
+
+    /**
+     * Does in "appear" animation to allow a seamless transition from
+     * the "No updates" mode.
+     * @param width Width of the container. As we haven't been layed out yet, we can't know
+     * @param scrollOffset The offset by how far we scrolled, where 0=not scrolled, -x=scrolled by
+     * x pixels, Integer.MIN_VALUE=scrolled so far that the image is not visible in "no updates"
+     * mode of this screen
+     */
+    public void animateAppear(int width, int scrollOffset) {
+        final float photoHeight = mTabHeightScreenWidthFraction * width;
+        final boolean animateZoomAndFade;
+        int pixelsToScrollVertically = 0;
+
+        // Depending on how far we are scrolled down, there is one of three animations:
+        //   - Zoom and fade the picture (if it is still visible)
+        //   - Scroll, zoom and fade (if the picture is mostly invisible and we now have a
+        //     bigger visible region due to the pinning)
+        //   - Just scroll if the picture is completely invisible. This time, no zoom is needed
+        if (scrollOffset == Integer.MIN_VALUE) {
+            // animate in completely by scrolling. no need for zooming here
+            pixelsToScrollVertically = mTabDisplayLabelHeight;
+            animateZoomAndFade = false;
+        } else {
+            final int pixelsOfPhotoLeft = Math.round(photoHeight) + scrollOffset;
+            if (pixelsOfPhotoLeft > mTabDisplayLabelHeight) {
+                // nothing to scroll
+                pixelsToScrollVertically = 0;
+            } else {
+                pixelsToScrollVertically = mTabDisplayLabelHeight - pixelsOfPhotoLeft;
+            }
+            animateZoomAndFade = true;
         }
-    };
+
+        if (pixelsToScrollVertically != 0) {
+            // We can't animate ourselves here, because our own translation is needed for the user's
+            // scrolling. Instead, we use our only child. As we are transparent, that is just as
+            // good
+            mTabAndShadowContainer.setTranslationY(-pixelsToScrollVertically);
+            final ViewPropertyAnimator animator = mTabAndShadowContainer.animate();
+            animator.translationY(0.0f);
+            animator.setDuration(TRANSITION_MOVE_IN_TIME);
+        }
+
+        if (animateZoomAndFade) {
+            // Hack: We have two types of possible layouts:
+            //   If the picture is square, it is square in both "with updates" and "without updates"
+            //     --> no need for scale animation here
+            //     example: 10inch tablet portrait
+            //   If the picture is non-square, it is full-width in "without updates" and something
+            //     arbitrary in "with updates"
+            //     --> do animation with container
+            //     example: 4.6inch phone portrait
+            final boolean squarePicture =
+                    mTabWidthScreenWidthFraction == mTabHeightScreenWidthFraction;
+            final int firstTransitionTime;
+            if (squarePicture) {
+                firstTransitionTime = 0;
+            } else {
+                // For x, we need to scale our container so we'll animate the whole tab
+                // (unfortunately, we need to have the text invisible during this transition as it
+                // would also be stretched)
+                float revScale = 1.0f/mTabWidthScreenWidthFraction;
+                mAboutTab.setScaleX(revScale);
+                mAboutTab.setPivotX(0.0f);
+                final ViewPropertyAnimator aboutAnimator = mAboutTab.animate();
+                aboutAnimator.setDuration(TRANSITION_TIME);
+                aboutAnimator.scaleX(1.0f);
+
+                // For y, we need to scale only the picture itself because we want it to be cropped
+                mPhotoView.setScaleY(revScale);
+                mPhotoView.setPivotY(photoHeight * 0.5f);
+                final ViewPropertyAnimator photoAnimator = mPhotoView.animate();
+                photoAnimator.setDuration(TRANSITION_TIME);
+                photoAnimator.scaleY(1.0f);
+                firstTransitionTime = TRANSITION_TIME;
+            }
+
+            // Animate in the labels after the above transition is finished
+            mAboutTab.fadeInLabelViewAnimator(firstTransitionTime, true);
+            mUpdatesTab.fadeInLabelViewAnimator(firstTransitionTime, false);
+
+            final float pixelsToTranslate = (1.0f - mTabWidthScreenWidthFraction) * width;
+            // Views to translate
+            for (View view : new View[] { mUpdatesTab, mTabDivider }) {
+                view.setTranslationX(pixelsToTranslate);
+                final ViewPropertyAnimator translateAnimator = view.animate();
+                translateAnimator.translationX(0.0f);
+                translateAnimator.setDuration(TRANSITION_TIME);
+            }
+
+            // Another hack: If the picture is square, there is no shadow in "Without updates"
+            //    --> fade it in after the translations are done
+            if (squarePicture) {
+                mShadow.setAlpha(0.0f);
+                mShadow.animate().setStartDelay(TRANSITION_TIME).alpha(1.0f);
+            }
+        }
+    }
 
     private void updateAlphaLayers() {
-        mAboutTab.setAlphaLayerValue(mLastScrollPosition * MAX_ALPHA /
-                mAllowedHorizontalScrollLength);
-        mUpdatesTab.setAlphaLayerValue(MAX_ALPHA - mLastScrollPosition * MAX_ALPHA /
-                mAllowedHorizontalScrollLength);
+        float alpha = mLastScrollPosition * MAX_ALPHA / mAllowedHorizontalScrollLength;
+        alpha = MoreMath.clamp(alpha, 0.0f, 1.0f);
+        mAboutTab.setAlphaLayerValue(alpha);
+        mUpdatesTab.setAlphaLayerValue(MAX_ALPHA - alpha);
     }
 
     @Override
-    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
-        super.onScrollChanged(l, t, oldl, oldt);
-        mListener.onScrollChanged(l, t, oldl, oldt);
-        mLastScrollPosition = l;
+    protected void onScrollChanged(int x, int y, int oldX, int oldY) {
+        super.onScrollChanged(x, y, oldX, oldY);
+
+        // Guard against framework issue where onScrollChanged() is called twice
+        // for each touch-move event.  This wreaked havoc on the tab-carousel: the
+        // view-pager moved twice as fast as it should because we called fakeDragBy()
+        // twice with the same value.
+        if (mLastScrollPosition == x) return;
+
+        // Since we never completely scroll the about/updates tabs off-screen,
+        // the draggable range is less than the width of the carousel. Our
+        // listeners don't care about this... if we scroll 75% percent of our
+        // draggable range, they want to scroll 75% of the entire carousel
+        // width, not the same number of pixels that we scrolled.
+        int scaledL = (int) (x * mScrollScaleFactor);
+        int oldScaledL = (int) (oldX * mScrollScaleFactor);
+        mListener.onScrollChanged(scaledL, y, oldScaledL, oldY);
+
+        mLastScrollPosition = x;
         updateAlphaLayers();
     }
 
@@ -252,18 +442,24 @@
      * Updates the tab selection.
      */
     public void setCurrentTab(int position) {
+        final CarouselTab selected, deselected;
+
         switch (position) {
             case TAB_INDEX_ABOUT:
-                mAboutTab.showSelectedState();
-                mUpdatesTab.showDeselectedState();
+                selected = mAboutTab;
+                deselected = mUpdatesTab;
                 break;
             case TAB_INDEX_UPDATES:
-                mUpdatesTab.showSelectedState();
-                mAboutTab.showDeselectedState();
+                selected = mUpdatesTab;
+                deselected = mAboutTab;
                 break;
             default:
                 throw new IllegalStateException("Invalid tab position " + position);
         }
+        selected.showSelectedState();
+        selected.setOverlayClickable(false);
+        deselected.showDeselectedState();
+        deselected.setOverlayClickable(true);
         mCurrentTab = position;
     }
 
@@ -272,15 +468,24 @@
      * from the outside to fully setup the View
      */
     public void loadData(ContactLoader.Result contactData) {
-        if (contactData == null) {
-            return;
+        if (contactData == null) return;
+
+        // TODO: Move this into the {@link CarouselTab} class when the updates
+        // fragment code is more finalized.
+        final boolean expandOnClick = contactData.getPhotoUri() != null;
+        final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
+                mContext, contactData, mPhotoView, expandOnClick);
+
+        if (expandOnClick || contactData.isWritableContact(mContext)) {
+            mPhotoViewOverlay.setOnClickListener(listener);
+        } else {
+            // Work around framework issue... if we instead use
+            // setClickable(false), then we can't swipe horizontally.
+            mPhotoViewOverlay.setOnClickListener(null);
         }
 
-        // TODO: Move this into the {@link CarouselTab} class when the updates fragment code is more
-        // finalized
-        ContactDetailDisplayUtils.setPhoto(mContext, contactData, mPhotoView);
-        ContactDetailDisplayUtils.setSocialSnippet(mContext, contactData, mStatusView,
-                mStatusPhotoView);
+        ContactDetailDisplayUtils.setSocialSnippet(
+                mContext, contactData, mStatusView, mStatusPhotoView);
     }
 
     /**
diff --git a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
index fd59674..e8ce622 100644
--- a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
@@ -37,8 +37,7 @@
 import android.widget.AbsListView.OnScrollListener;
 import android.widget.ListView;
 
-public class ContactDetailUpdatesFragment extends ListFragment
-        implements FragmentKeyListener, ViewOverlay {
+public class ContactDetailUpdatesFragment extends ListFragment implements FragmentKeyListener {
 
     private static final String TAG = "ContactDetailUpdatesFragment";
 
@@ -48,19 +47,6 @@
     private LayoutInflater mInflater;
     private StreamItemAdapter mStreamItemAdapter;
 
-    private float mInitialAlphaValue;
-
-    /**
-     * This optional view adds an alpha layer over the entire fragment.
-     */
-    private View mAlphaLayer;
-
-    /**
-     * This optional view adds a layer over the entire fragment so that when visible, it intercepts
-     * all touch events on the fragment.
-     */
-    private View mTouchInterceptLayer;
-
     private OnScrollListener mVerticalScrollListener;
 
     /**
@@ -81,7 +67,7 @@
             final Uri uri = ContentUris.withAppendedId(StreamItems.CONTENT_URI,
                     streamItemEntry.getId());
             final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-            intent.setClassName(accountType.resPackageName,
+            intent.setClassName(accountType.syncAdapterPackageName,
                     accountType.getViewStreamItemActivity());
             startActivity(intent);
         }
@@ -98,7 +84,7 @@
             final AccountType accountType = getAccountTypeForStreamItemEntry(tag.streamItem);
 
             final Intent intent = new Intent(Intent.ACTION_VIEW, tag.getStreamItemPhotoUri());
-            intent.setClassName(accountType.resPackageName,
+            intent.setClassName(accountType.syncAdapterPackageName,
                     accountType.getViewStreamItemPhotoActivity());
             startActivity(intent);
         }
@@ -116,14 +102,7 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
         mInflater = inflater;
-        View rootView = mInflater.inflate(R.layout.contact_detail_updates_fragment, container,
-                false);
-
-        mTouchInterceptLayer = rootView.findViewById(R.id.touch_intercept_overlay);
-        mAlphaLayer = rootView.findViewById(R.id.alpha_overlay);
-        ContactDetailDisplayUtils.setAlphaOnViewBackground(mAlphaLayer, mInitialAlphaValue);
-
-        return rootView;
+        return mInflater.inflate(R.layout.contact_detail_updates_fragment, container, false);
     }
 
     @Override
@@ -167,32 +146,6 @@
     }
 
     @Override
-    public void setAlphaLayerValue(float alpha) {
-        // If the alpha layer is not ready yet, store it for later when the view is initialized
-        if (mAlphaLayer == null) {
-            mInitialAlphaValue = alpha;
-        } else {
-            // Otherwise set the value immediately
-            ContactDetailDisplayUtils.setAlphaOnViewBackground(mAlphaLayer, alpha);
-        }
-    }
-
-    @Override
-    public void enableTouchInterceptor(OnClickListener clickListener) {
-        if (mTouchInterceptLayer != null) {
-            mTouchInterceptLayer.setVisibility(View.VISIBLE);
-            mTouchInterceptLayer.setOnClickListener(clickListener);
-        }
-    }
-
-    @Override
-    public void disableTouchInterceptor() {
-        if (mTouchInterceptLayer != null) {
-            mTouchInterceptLayer.setVisibility(View.GONE);
-        }
-    }
-
-    @Override
     public boolean handleKeyDown(int keyCode) {
         return false;
     }
diff --git a/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java b/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java
index edcfc39..4213490 100644
--- a/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java
+++ b/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java
@@ -19,6 +19,7 @@
 import android.support.v4.view.PagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.view.View;
+import android.view.ViewGroup;
 
 /**
  * Adapter for the {@link ViewPager} for the contact detail page for a contact in 2 cases:
@@ -28,7 +29,7 @@
 public class ContactDetailViewPagerAdapter extends PagerAdapter {
 
     public static final String ABOUT_FRAGMENT_TAG = "view-pager-about-fragment";
-    public static final String UPDTES_FRAGMENT_TAG = "view-pager-updates-fragment";
+    public static final String UPDATES_FRAGMENT_TAG = "view-pager-updates-fragment";
 
     private static final int INDEX_ABOUT_FRAGMENT = 0;
     private static final int INDEX_UPDATES_FRAGMENT = 1;
@@ -88,11 +89,11 @@
     }
 
     @Override
-    public void startUpdate(View container) {
+    public void startUpdate(ViewGroup container) {
     }
 
     @Override
-    public Object instantiateItem(View container, int position) {
+    public Object instantiateItem(ViewGroup container, int position) {
         switch (position) {
             case INDEX_ABOUT_FRAGMENT:
                 mAboutFragmentView.setVisibility(View.VISIBLE);
@@ -105,12 +106,12 @@
     }
 
     @Override
-    public void destroyItem(View container, int position, Object object) {
+    public void destroyItem(ViewGroup container, int position, Object object) {
         ((View) object).setVisibility(View.GONE);
     }
 
     @Override
-    public void finishUpdate(View container) {
+    public void finishUpdate(ViewGroup container) {
     }
 
     @Override
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index 008aff8..c56f659 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -20,6 +20,8 @@
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.list.ShortcutIntentBuilder;
+import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.internal.util.Objects;
 
@@ -33,7 +35,6 @@
 import android.content.Loader;
 import android.media.RingtoneManager;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
@@ -58,10 +59,14 @@
     /** The launch code when picking a ringtone */
     private static final int REQUEST_CODE_PICK_RINGTONE = 1;
 
+    /** This is the Intent action to install a shortcut in the launcher. */
+    private static final String ACTION_INSTALL_SHORTCUT =
+            "com.android.launcher.action.INSTALL_SHORTCUT";
 
     private boolean mOptionsMenuOptions;
     private boolean mOptionsMenuEditable;
     private boolean mOptionsMenuShareable;
+    private boolean mOptionsMenuCanCreateShortcut;
     private boolean mSendToVoicemailState;
     private String mCustomRingtone;
 
@@ -180,12 +185,14 @@
         public Loader<ContactLoader.Result> onCreateLoader(int id, Bundle args) {
             Uri lookupUri = args.getParcelable(LOADER_ARG_CONTACT_URI);
             return new ContactLoader(mContext, lookupUri, true /* loadGroupMetaData */,
-                    true /* loadStreamItems */, true /* load invitable account types */);
+                    true /* loadStreamItems */, true /* load invitable account types */,
+                    true /* postViewNotification */);
         }
 
         @Override
         public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
             if (!mLookupUri.equals(data.getRequestedUri())) {
+                Log.e(TAG, "Different URI: requested=" + mLookupUri + "  actual=" + data);
                 return;
             }
 
@@ -223,7 +230,8 @@
     public boolean isOptionsMenuChanged() {
         return mOptionsMenuOptions != isContactOptionsChangeEnabled()
                 || mOptionsMenuEditable != isContactEditable()
-                || mOptionsMenuShareable != isContactShareable();
+                || mOptionsMenuShareable != isContactShareable()
+                || mOptionsMenuCanCreateShortcut != isContactCanCreateShortcut();
     }
 
     @Override
@@ -231,6 +239,7 @@
         mOptionsMenuOptions = isContactOptionsChangeEnabled();
         mOptionsMenuEditable = isContactEditable();
         mOptionsMenuShareable = isContactShareable();
+        mOptionsMenuCanCreateShortcut = isContactCanCreateShortcut();
         if (mContactData != null) {
             mSendToVoicemailState = mContactData.isSendToVoicemail();
             mCustomRingtone = mContactData.getCustomRingtone();
@@ -256,6 +265,9 @@
 
         final MenuItem shareMenu = menu.findItem(R.id.menu_share);
         shareMenu.setVisible(mOptionsMenuShareable);
+
+        final MenuItem createContactShortcutMenu = menu.findItem(R.id.menu_create_contact_shortcut);
+        createContactShortcutMenu.setVisible(mOptionsMenuCanCreateShortcut);
     }
 
     public boolean isContactOptionsChangeEnabled() {
@@ -271,6 +283,11 @@
         return mContactData != null && !mContactData.isDirectoryEntry();
     }
 
+    public boolean isContactCanCreateShortcut() {
+        return mContactData != null && !mContactData.isUserProfile()
+                && !mContactData.isDirectoryEntry();
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
@@ -323,11 +340,45 @@
                 mContext.startService(intent);
                 return true;
             }
+            case R.id.menu_create_contact_shortcut: {
+                // Create a launcher shortcut with this contact
+                createLauncherShortcutWithContact();
+                return true;
+            }
         }
         return false;
     }
 
     /**
+     * Creates a launcher shortcut with the current contact.
+     */
+    private void createLauncherShortcutWithContact() {
+        // Hold the parent activity of this fragment in case this fragment is destroyed
+        // before the callback to onShortcutIntentCreated(...)
+        final Activity parentActivity = getActivity();
+
+        ShortcutIntentBuilder builder = new ShortcutIntentBuilder(parentActivity,
+                new OnShortcutIntentCreatedListener() {
+
+            @Override
+            public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
+                // Broadcast the shortcutIntent to the launcher to create a
+                // shortcut to this contact
+                shortcutIntent.setAction(ACTION_INSTALL_SHORTCUT);
+                parentActivity.sendBroadcast(shortcutIntent);
+
+                // Send a toast to give feedback to the user that a shortcut to this
+                // contact was added to the launcher.
+                Toast.makeText(parentActivity,
+                        R.string.createContactShortcutSuccessful,
+                        Toast.LENGTH_SHORT).show();
+            }
+
+        });
+        builder.createContactShortcutIntent(mLookupUri);
+    }
+
+    /**
      * Calls into the contacts provider to get a pre-authorized version of the given URI.
      */
     private Uri getPreAuthorizedUri(Uri uri) {
@@ -407,4 +458,18 @@
                 mContext, mLookupUri, mCustomRingtone);
         mContext.startService(intent);
     }
+
+    /** Toggles whether to load stream items. Just for debugging */
+    public void toggleLoadStreamItems() {
+        Loader<ContactLoader.Result> loaderObj = getLoaderManager().getLoader(LOADER_DETAILS);
+        ContactLoader loader = (ContactLoader) loaderObj;
+        loader.setLoadStreamItems(!loader.getLoadStreamItems());
+    }
+
+    /** Returns whether to load stream items. Just for debugging */
+    public boolean getLoadStreamItems() {
+        Loader<ContactLoader.Result> loaderObj = getLoaderManager().getLoader(LOADER_DETAILS);
+        ContactLoader loader = (ContactLoader) loaderObj;
+        return loader != null && loader.getLoadStreamItems();
+    }
 }
diff --git a/src/com/android/contacts/detail/PhotoSelectionHandler.java b/src/com/android/contacts/detail/PhotoSelectionHandler.java
new file mode 100644
index 0000000..73296a6
--- /dev/null
+++ b/src/com/android/contacts/detail/PhotoSelectionHandler.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2011 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.contacts.detail;
+
+import com.android.contacts.R;
+import com.android.contacts.editor.PhotoActionPopup;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.model.EntityDeltaList;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.util.ContactPhotoUtils;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaScannerConnection;
+import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.DisplayPhoto;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ListPopupWindow;
+import android.widget.PopupWindow.OnDismissListener;
+import android.widget.Toast;
+import java.io.File;
+
+/**
+ * Handles displaying a photo selection popup for a given photo view and dealing with the results
+ * that come back.
+ */
+public abstract class PhotoSelectionHandler implements OnClickListener {
+
+    private static final String TAG = PhotoSelectionHandler.class.getSimpleName();
+
+    private static final int REQUEST_CODE_CAMERA_WITH_DATA = 1001;
+    private static final int REQUEST_CODE_PHOTO_PICKED_WITH_DATA = 1002;
+
+    protected final Context mContext;
+    private final View mPhotoView;
+    private final int mPhotoMode;
+    private final int mPhotoPickSize;
+    private final EntityDeltaList mState;
+    private final boolean mIsDirectoryContact;
+    private ListPopupWindow mPopup;
+
+    public PhotoSelectionHandler(Context context, View photoView, int photoMode,
+            boolean isDirectoryContact, EntityDeltaList state) {
+        mContext = context;
+        mPhotoView = photoView;
+        mPhotoMode = photoMode;
+        mIsDirectoryContact = isDirectoryContact;
+        mState = state;
+        mPhotoPickSize = getPhotoPickSize();
+    }
+
+    public void destroy() {
+        if (mPopup != null) {
+            mPopup.dismiss();
+        }
+    }
+
+    public abstract PhotoActionListener getListener();
+
+    @Override
+    public void onClick(View v) {
+        final PhotoActionListener listener = getListener();
+        if (listener != null) {
+            if (getWritableEntityIndex() != -1) {
+                mPopup = PhotoActionPopup.createPopupMenu(
+                        mContext, mPhotoView, listener, mPhotoMode);
+                mPopup.setOnDismissListener(new OnDismissListener() {
+                    @Override
+                    public void onDismiss() {
+                        listener.onPhotoSelectionDismissed();
+                    }
+                });
+                mPopup.show();
+            }
+        }
+    }
+
+    /**
+     * Attempts to handle the given activity result.  Returns whether this handler was able to
+     * process the result successfully.
+     * @param requestCode The request code.
+     * @param resultCode The result code.
+     * @param data The intent that was returned.
+     * @return Whether the handler was able to process the result.
+     */
+    public boolean handlePhotoActivityResult(int requestCode, int resultCode, Intent data) {
+        final PhotoActionListener listener = getListener();
+        if (resultCode == Activity.RESULT_OK) {
+            switch (requestCode) {
+                // Photo was chosen (either new or existing from gallery), and cropped.
+                case REQUEST_CODE_PHOTO_PICKED_WITH_DATA: {
+                    final String path = ContactPhotoUtils.pathForCroppedPhoto(
+                            mContext, listener.getCurrentPhotoFile());
+                    Bitmap bitmap = BitmapFactory.decodeFile(path);
+                    listener.onPhotoSelected(bitmap);
+                    return true;
+                }
+                // Photo was successfully taken, now crop it.
+                case REQUEST_CODE_CAMERA_WITH_DATA: {
+                    doCropPhoto(listener.getCurrentPhotoFile());
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return the index of the first entity in the contact data that belongs to a contact-writable
+     * account, or -1 if no such entity exists.
+     */
+    private int getWritableEntityIndex() {
+        // Directory entries are non-writable.
+        if (mIsDirectoryContact) return -1;
+        return mState.indexOfFirstWritableRawContact(mContext);
+    }
+
+    /**
+     * Return the raw-contact id of the first entity in the contact data that belongs to a
+     * contact-writable account, or -1 if no such entity exists.
+     */
+    protected long getWritableEntityId() {
+        int index = getWritableEntityIndex();
+        if (index == -1) return -1;
+        return mState.get(index).getValues().getId();
+    }
+
+    /**
+     * Utility method to retrieve the entity delta for attaching the given bitmap to the contact.
+     * This will attach the photo to the first contact-writable account that provided data to the
+     * contact.  It is the caller's responsibility to apply the delta.
+     * @return An entity delta list that can be applied to associate the bitmap with the contact,
+     *     or null if the photo could not be parsed or none of the accounts associated with the
+     *     contact are writable.
+     */
+    public EntityDeltaList getDeltaForAttachingPhotoToContact() {
+        // Find the first writable entity.
+        int writableEntityIndex = getWritableEntityIndex();
+        if (writableEntityIndex != -1) {
+            // We are guaranteed to have contact data if we have a writable entity index.
+            final EntityDelta delta = mState.get(writableEntityIndex);
+
+            // Need to find the right account so that EntityModifier knows which fields to add
+            final ContentValues entityValues = delta.getValues().getCompleteValues();
+            final String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
+            final String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
+            final AccountType accountType = AccountTypeManager.getInstance(mContext).getAccountType(
+                        type, dataSet);
+
+            final ValuesDelta child = EntityModifier.ensureKindExists(
+                    delta, accountType, Photo.CONTENT_ITEM_TYPE);
+            child.setFromTemplate(false);
+            child.put(Photo.IS_SUPER_PRIMARY, 1);
+
+            return mState;
+        }
+        return null;
+    }
+
+    /** Used by subclasses to delegate to their enclosing Activity or Fragment. */
+    protected abstract void startPhotoActivity(Intent intent, int requestCode, String photoFile);
+
+    /**
+     * Sends a newly acquired photo to Gallery for cropping
+     */
+    private void doCropPhoto(String fileName) {
+        try {
+            // Obtain the absolute paths for the newly-taken photo, and the destination
+            // for the soon-to-be-cropped photo.
+            final String newPath = ContactPhotoUtils.pathForNewCameraPhoto(fileName);
+            final String croppedPath = ContactPhotoUtils.pathForCroppedPhoto(mContext, fileName);
+
+            // Add the image to the media store
+            MediaScannerConnection.scanFile(
+                    mContext,
+                    new String[] { newPath },
+                    new String[] { null },
+                    null);
+
+            // Launch gallery to crop the photo
+            final Intent intent = getCropImageIntent(newPath, croppedPath);
+            startPhotoActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, fileName);
+        } catch (Exception e) {
+            Log.e(TAG, "Cannot crop image", e);
+            Toast.makeText(mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
+        }
+    }
+
+    /**
+     * Should initiate an activity to take a photo using the camera.
+     * @param photoFile The file path that will be used to store the photo.  This is generally
+     *     what should be returned by
+     *     {@link PhotoSelectionHandler.PhotoActionListener#getCurrentPhotoFile()}.
+     */
+    private void startTakePhotoActivity(String photoFile) {
+        final Intent intent = getTakePhotoIntent(photoFile);
+        startPhotoActivity(intent, REQUEST_CODE_CAMERA_WITH_DATA, photoFile);
+    }
+
+    /**
+     * Should initiate an activity pick a photo from the gallery.
+     * @param photoFile The temporary file that the cropped image is written to before being
+     *     stored by the content-provider.
+     *     {@link PhotoSelectionHandler#handlePhotoActivityResult(int, int, Intent)}.
+     */
+    private void startPickFromGalleryActivity(String photoFile) {
+        final Intent intent = getPhotoPickIntent(photoFile);
+        startPhotoActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, photoFile);
+    }
+
+    private int getPhotoPickSize() {
+        // Note that this URI is safe to call on the UI thread.
+        Cursor c = mContext.getContentResolver().query(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
+                new String[]{DisplayPhoto.DISPLAY_MAX_DIM}, null, null, null);
+        try {
+            c.moveToFirst();
+            return c.getInt(0);
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Constructs an intent for picking a photo from Gallery, cropping it and returning the bitmap.
+     */
+    private Intent getPhotoPickIntent(String photoFile) {
+        final String croppedPhotoPath = ContactPhotoUtils.pathForCroppedPhoto(mContext, photoFile);
+        final Uri croppedPhotoUri = Uri.fromFile(new File(croppedPhotoPath));
+        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
+        intent.setType("image/*");
+        intent.putExtra("crop", "true");
+        intent.putExtra("aspectX", 1);
+        intent.putExtra("aspectY", 1);
+        intent.putExtra("outputX", mPhotoPickSize);
+        intent.putExtra("outputY", mPhotoPickSize);
+        intent.putExtra(MediaStore.EXTRA_OUTPUT, croppedPhotoUri);
+        return intent;
+    }
+
+    /**
+     * Constructs an intent for image cropping.
+     */
+    private Intent getCropImageIntent(String inputPhotoPath, String croppedPhotoPath) {
+        final Uri inputPhotoUri = Uri.fromFile(new File(inputPhotoPath));
+        final Uri croppedPhotoUri = Uri.fromFile(new File(croppedPhotoPath));
+        Intent intent = new Intent("com.android.camera.action.CROP");
+        intent.setDataAndType(inputPhotoUri, "image/*");
+        intent.putExtra("crop", "true");
+        intent.putExtra("aspectX", 1);
+        intent.putExtra("aspectY", 1);
+        intent.putExtra("outputX", mPhotoPickSize);
+        intent.putExtra("outputY", mPhotoPickSize);
+        intent.putExtra(MediaStore.EXTRA_OUTPUT, croppedPhotoUri);
+        return intent;
+    }
+
+    /**
+     * Constructs an intent for capturing a photo and storing it in a temporary file.
+     */
+    private static Intent getTakePhotoIntent(String fileName) {
+        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
+        final String newPhotoPath = ContactPhotoUtils.pathForNewCameraPhoto(fileName);
+        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(newPhotoPath)));
+        return intent;
+    }
+
+    public abstract class PhotoActionListener implements PhotoActionPopup.Listener {
+        @Override
+        public void onUseAsPrimaryChosen() {
+            // No default implementation.
+        }
+
+        @Override
+        public void onRemovePictureChosen() {
+            // No default implementation.
+        }
+
+        @Override
+        public void onTakePhotoChosen() {
+            try {
+                // Launch camera to take photo for selected contact
+                startTakePhotoActivity(ContactPhotoUtils.generateTempPhotoFileName());
+            } catch (ActivityNotFoundException e) {
+                Toast.makeText(
+                        mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
+            }
+        }
+
+        @Override
+        public void onPickFromGalleryChosen() {
+            try {
+                // Launch picker to choose photo for selected contact
+                startPickFromGalleryActivity(ContactPhotoUtils.generateTempPhotoFileName());
+            } catch (ActivityNotFoundException e) {
+                Toast.makeText(
+                        mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
+            }
+        }
+
+        /**
+         * Called when the user has completed selection of a photo.
+         * @param bitmap The selected and cropped photo.
+         */
+        public abstract void onPhotoSelected(Bitmap bitmap);
+
+        /**
+         * Gets the current photo file that is being interacted with.  It is the activity or
+         * fragment's responsibility to maintain this in saved state, since this handler instance
+         * will not survive rotation.
+         */
+        public abstract String getCurrentPhotoFile();
+
+        /**
+         * Called when the photo selection dialog is dismissed.
+         */
+        public abstract void onPhotoSelectionDismissed();
+    }
+}
diff --git a/src/com/android/contacts/detail/StreamItemAdapter.java b/src/com/android/contacts/detail/StreamItemAdapter.java
index 2d870b4..089cb07 100644
--- a/src/com/android/contacts/detail/StreamItemAdapter.java
+++ b/src/com/android/contacts/detail/StreamItemAdapter.java
@@ -104,7 +104,7 @@
                 manager.getAccountType(streamItem.getAccountType(), streamItem.getDataSet());
 
         final View view = ContactDetailDisplayUtils.createStreamItemView(
-                mInflater, mContext, streamItem, null,
+                mInflater, mContext, convertView, streamItem,
                 // Only pass the photo click listener if the account type has the photo
                 // view activity.
                 (accountType.getViewStreamItemPhotoActivity() == null) ? null : mPhotoClickListener
@@ -130,6 +130,12 @@
     }
 
     @Override
+    public int getViewTypeCount() {
+        // ITEM_VIEW_TYPE_HEADER and ITEM_VIEW_TYPE_STREAM_ITEM
+        return 2;
+    }
+
+    @Override
     public int getItemViewType(int position) {
         if (position == 0) {
             return ITEM_VIEW_TYPE_HEADER;
diff --git a/src/com/android/contacts/detail/TransformableImageView.java b/src/com/android/contacts/detail/TransformableImageView.java
new file mode 100644
index 0000000..241df41
--- /dev/null
+++ b/src/com/android/contacts/detail/TransformableImageView.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 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.contacts.detail;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * Extension to ImageView that handles cropping during resize animations.
+ */
+public class TransformableImageView extends ImageView {
+
+    public TransformableImageView(Context context) {
+        super(context);
+    }
+
+    public TransformableImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public TransformableImageView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        int saveCount = canvas.getSaveCount();
+        canvas.save();
+        canvas.translate(mPaddingLeft, mPaddingTop);
+        Matrix drawMatrix = new Matrix();
+        int dwidth = getDrawable().getIntrinsicWidth();
+        int dheight = getDrawable().getIntrinsicHeight();
+
+        int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
+        int vheight = getHeight() - mPaddingTop - mPaddingBottom;
+        float scale;
+        float dx = 0, dy = 0;
+
+        if (dwidth * vheight > vwidth * dheight) {
+            scale = (float) vheight / (float) dheight;
+            dx = (vwidth - dwidth * scale) * 0.5f;
+        } else {
+            scale = (float) vwidth / (float) dwidth;
+            dy = (vheight - dheight * scale) * 0.5f;
+        }
+
+        drawMatrix.setScale(scale, scale);
+        drawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
+        canvas.concat(drawMatrix);
+        getDrawable().draw(canvas);
+        canvas.restoreToCount(saveCount);
+    }
+}
diff --git a/src/com/android/contacts/detail/ViewOverlay.java b/src/com/android/contacts/detail/ViewOverlay.java
deleted file mode 100644
index 58428b8..0000000
--- a/src/com/android/contacts/detail/ViewOverlay.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.detail;
-
-import android.view.View.OnClickListener;
-
-/**
- * This is implemented by {@link View}s that contain an alpha layer and touch interceptor layer.
- * The alpha layer covers the entire fragment and has an alpha value which makes the fragment
- * contents appear "dimmed" out. The touch interceptor layer covers the entire fragment so that
- * when visible, it intercepts all touch events on the {@link View}.
- */
-public interface ViewOverlay {
-
-    /**
-     * Sets the alpha value on the alpha layer (if there is one).
-     */
-    public void setAlphaLayerValue(float alpha);
-
-    /**
-     * Makes the touch intercept layer on this fragment visible (if there is one). Also adds a click
-     * listener which is called when there is a touch event on the layer.
-     */
-    public void enableTouchInterceptor(OnClickListener clickListener);
-
-    /**
-     * Makes the touch intercept layer on this fragment gone (if there is one).
-     */
-    public void disableTouchInterceptor();
-}
diff --git a/src/com/android/contacts/dialog/ClearFrequentsDialog.java b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
new file mode 100644
index 0000000..4aeaf1c
--- /dev/null
+++ b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.contacts.dialog;
+
+import com.android.contacts.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ContentResolver;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+
+/**
+ * Dialog that clears the frequently contacted list after confirming with the user.
+ */
+public class ClearFrequentsDialog extends DialogFragment {
+    /** Preferred way to show this dialog */
+    public static void show(FragmentManager fragmentManager) {
+        ClearFrequentsDialog dialog = new ClearFrequentsDialog();
+        dialog.show(fragmentManager, "clearFrequents");
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final ContentResolver resolver = getActivity().getContentResolver();
+        final OnClickListener okListener = new OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                final IndeterminateProgressDialog progressDialog = IndeterminateProgressDialog.show(
+                        getFragmentManager(), getString(R.string.clearFrequentsProgress_title),
+                        null, 500);
+                final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+                    @Override
+                    protected Void doInBackground(Void... params) {
+                        resolver.delete(ContactsContract.DataUsageFeedback.DELETE_USAGE_URI,
+                                null, null);
+                        return null;
+                    }
+
+                    @Override
+                    protected void onPostExecute(Void result) {
+                        progressDialog.dismiss();
+                    }
+                };
+                task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+            }
+        };
+        return new AlertDialog.Builder(getActivity())
+            .setTitle(R.string.clearFrequentsConfirmation_title)
+            .setMessage(R.string.clearFrequentsConfirmation)
+            .setNegativeButton(android.R.string.cancel, null)
+            .setPositiveButton(android.R.string.ok, okListener)
+            .setCancelable(true)
+            .create();
+    }
+}
diff --git a/src/com/android/contacts/dialog/IndeterminateProgressDialog.java b/src/com/android/contacts/dialog/IndeterminateProgressDialog.java
new file mode 100644
index 0000000..21cd4bb
--- /dev/null
+++ b/src/com/android/contacts/dialog/IndeterminateProgressDialog.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2012 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.contacts.dialog;
+
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Handler;
+
+/**
+ * Indeterminate progress dialog wrapped up in a DialogFragment to work even when the device
+ * orientation is changed. Currently, only supports adding a title and/or message to the progress
+ * dialog.  There is an additional parameter of the minimum amount of time to display the progress
+ * dialog even after a call to dismiss the dialog {@link #dismiss()} or
+ * {@link #dismissAllowingStateLoss()}.
+ * <p>
+ * To create and show the progress dialog, use
+ * {@link #show(FragmentManager, CharSequence, CharSequence, long)} and retain the reference to the
+ * IndeterminateProgressDialog instance.
+ * <p>
+ * To dismiss the dialog, use {@link #dismiss()} or {@link #dismissAllowingStateLoss()} on the
+ * instance.  The instance returned by
+ * {@link #show(FragmentManager, CharSequence, CharSequence, long)} is guaranteed to be valid
+ * after a device orientation change because the {@link #setRetainInstance(boolean)} is called
+ * internally with true.
+ */
+public class IndeterminateProgressDialog extends DialogFragment {
+    private static final String TAG = IndeterminateProgressDialog.class.getSimpleName();
+
+    private CharSequence mTitle;
+    private CharSequence mMessage;
+    private long mMinDisplayTime;
+    private long mShowTime = 0;
+    private boolean mActivityReady = false;
+    private Dialog mOldDialog;
+    private final Handler mHandler = new Handler();
+    private boolean mCalledSuperDismiss = false;
+    private boolean mAllowStateLoss;
+    private final Runnable mDismisser = new Runnable() {
+        @Override
+        public void run() {
+            superDismiss();
+        }
+    };
+
+    /**
+     * Creates and shows an indeterminate progress dialog.  Once the progress dialog is shown, it
+     * will be shown for at least the minDisplayTime (in milliseconds), so that the progress dialog
+     * does not flash in and out to quickly.
+     */
+    public static IndeterminateProgressDialog show(FragmentManager fragmentManager,
+            CharSequence title, CharSequence message, long minDisplayTime) {
+        IndeterminateProgressDialog dialogFragment = new IndeterminateProgressDialog();
+        dialogFragment.mTitle = title;
+        dialogFragment.mMessage = message;
+        dialogFragment.mMinDisplayTime = minDisplayTime;
+        dialogFragment.show(fragmentManager, TAG);
+        dialogFragment.mShowTime = System.currentTimeMillis();
+        dialogFragment.setCancelable(false);
+
+        return dialogFragment;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setRetainInstance(true);
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Create the progress dialog and set its properties
+        final ProgressDialog dialog = new ProgressDialog(getActivity());
+        dialog.setIndeterminate(true);
+        dialog.setIndeterminateDrawable(null);
+        dialog.setTitle(mTitle);
+        dialog.setMessage(mMessage);
+
+        return dialog;
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        mActivityReady = true;
+
+        // Check if superDismiss() had been called before.  This can happen if in a long
+        // running operation, the user hits the home button and closes this fragment's activity.
+        // Upon returning, we want to dismiss this progress dialog fragment.
+        if (mCalledSuperDismiss) {
+            superDismiss();
+        }
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        mActivityReady = false;
+    }
+
+    /**
+     * There is a race condition that is not handled properly by the DialogFragment class.
+     * If we don't check that this onDismiss callback isn't for the old progress dialog from before
+     * the device orientation change, then this will cause the newly created dialog after the
+     * orientation change to be dismissed immediately.
+     */
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        if (mOldDialog != null && mOldDialog == dialog) {
+            // This is the callback from the old progress dialog that was already dismissed before
+            // the device orientation change, so just ignore it.
+            return;
+        }
+        super.onDismiss(dialog);
+    }
+
+    /**
+     * Save the old dialog that is about to get destroyed in case this is due to a change
+     * in device orientation.  This will allow us to intercept the callback to
+     * {@link #onDismiss(DialogInterface)} in case the callback happens after a new progress dialog
+     * instance was created.
+     */
+    @Override
+    public void onDestroyView() {
+        mOldDialog = getDialog();
+        super.onDestroyView();
+    }
+
+    /**
+     * This tells the progress dialog to dismiss itself after guaranteeing to be shown for the
+     * specified time in {@link #show(FragmentManager, CharSequence, CharSequence, long)}.
+     */
+    @Override
+    public void dismiss() {
+        mAllowStateLoss = false;
+        dismissWhenReady();
+    }
+
+    /**
+     * This tells the progress dialog to dismiss itself (with state loss) after guaranteeing to be
+     * shown for the specified time in
+     * {@link #show(FragmentManager, CharSequence, CharSequence, long)}.
+     */
+    @Override
+    public void dismissAllowingStateLoss() {
+        mAllowStateLoss = true;
+        dismissWhenReady();
+    }
+
+    /**
+     * Tells the progress dialog to dismiss itself after guaranteeing that the dialog had been
+     * showing for at least the minimum display time as set in
+     * {@link #show(FragmentManager, CharSequence, CharSequence, long)}.
+     */
+    private void dismissWhenReady() {
+        // Compute how long the dialog has been showing
+        final long shownTime = System.currentTimeMillis() - mShowTime;
+        if (shownTime >= mMinDisplayTime) {
+            // dismiss immediately
+            mHandler.post(mDismisser);
+        } else {
+            // Need to wait some more, so compute the amount of time to sleep.
+            final long sleepTime = mMinDisplayTime - shownTime;
+            mHandler.postDelayed(mDismisser, sleepTime);
+        }
+    }
+
+    /**
+     * Actually dismiss the dialog fragment.
+     */
+    private void superDismiss() {
+        mCalledSuperDismiss = true;
+        if (mActivityReady) {
+            // The fragment is either in onStart or past it, but has not gotten to onStop yet.
+            // It is safe to dismiss this dialog fragment.
+            if (mAllowStateLoss) {
+                super.dismissAllowingStateLoss();
+            } else {
+                super.dismiss();
+            }
+        }
+        // If mActivityReady is false, then this dialog fragment has already passed the onStop
+        // state. This can happen if the user hit the 'home' button before this dialog fragment was
+        // dismissed or if there is a configuration change.
+        // In the event that this dialog fragment is re-attached and reaches onStart (e.g.,
+        // because the user returns to this fragment's activity or the device configuration change
+        // has re-attached this dialog fragment), because the mCalledSuperDismiss flag was set to
+        // true, this dialog fragment will be dismissed within onStart.  So, there's nothing else
+        // that needs to be done.
+    }
+}
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index cdba30b..745c044 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -44,9 +44,11 @@
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.Editable;
+import android.text.SpannableString;
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.text.method.DialerKeyListener;
+import android.text.style.RelativeSizeSpan;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -69,8 +71,9 @@
 import com.android.contacts.R;
 import com.android.contacts.SpecialCharSequenceMgr;
 import com.android.contacts.activities.DialtactsActivity;
-import com.android.contacts.activities.DialtactsActivity.ViewPagerVisibilityListener;
+import com.android.contacts.util.Constants;
 import com.android.contacts.util.PhoneNumberFormatter;
+import com.android.contacts.util.StopWatch;
 import com.android.internal.telephony.ITelephony;
 import com.android.phone.CallLogAsync;
 import com.android.phone.HapticFeedback;
@@ -83,25 +86,22 @@
         View.OnLongClickListener, View.OnKeyListener,
         AdapterView.OnItemClickListener, TextWatcher,
         PopupMenu.OnMenuItemClickListener,
-        ViewPagerVisibilityListener {
+        DialpadImageButton.OnPressedListener {
     private static final String TAG = DialpadFragment.class.getSimpleName();
 
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = DialtactsActivity.DEBUG;
 
     private static final String EMPTY_NUMBER = "";
 
     /** The length of DTMF tones in milliseconds */
     private static final int TONE_LENGTH_MS = 150;
+    private static final int TONE_LENGTH_INFINITE = -1;
 
     /** The DTMF tone volume relative to other sounds in the stream */
     private static final int TONE_RELATIVE_VOLUME = 80;
 
     /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */
-    private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_MUSIC;
-
-    public interface Listener {
-        public void onSearchButtonPressed();
-    }
+    private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF;
 
     /**
      * View (usually FrameLayout) containing mDigits field. This can be null, in which mDigits
@@ -110,14 +110,20 @@
     private View mDigitsContainer;
     private EditText mDigits;
 
+    /** Remembers if we need to clear digits field when the screen is completely gone. */
+    private boolean mClearDigitsOnStop;
+
     private View mDelete;
     private ToneGenerator mToneGenerator;
-    private Object mToneGeneratorLock = new Object();
+    private final Object mToneGeneratorLock = new Object();
     private View mDialpad;
-
-    private View mSearchButton;
-    private View mMenuButton;
-    private Listener mListener;
+    /**
+     * Remembers the number of dialpad buttons which are pressed at this moment.
+     * If it becomes 0, meaning no buttons are pressed, we'll call
+     * {@link ToneGenerator#stopTone()}; the method shouldn't be called unless the last key is
+     * released.
+     */
+    private int mDialpadPressCount;
 
     private View mDialButtonContainer;
     private View mDialButton;
@@ -129,23 +135,21 @@
      */
     private String mProhibitedPhoneNumberRegexp;
 
-    private boolean mShowOptionsMenu;
-
 
     // Last number dialed, retrieved asynchronously from the call DB
     // in onCreate. This number is displayed when the user hits the
     // send key and cleared in onPause.
-    CallLogAsync mCallLog = new CallLogAsync();
+    private final CallLogAsync mCallLog = new CallLogAsync();
     private String mLastNumberDialed = EMPTY_NUMBER;
 
     // determines if we want to playback local DTMF tones.
     private boolean mDTMFToneEnabled;
 
     // Vibration (haptic feedback) for dialer key presses.
-    private HapticFeedback mHaptic = new HapticFeedback();
+    private final HapticFeedback mHaptic = new HapticFeedback();
 
     /** Identifier for the "Add Call" intent extra. */
-    static final String ADD_CALL_MODE_KEY = "add_call_mode";
+    private static final String ADD_CALL_MODE_KEY = "add_call_mode";
 
     /**
      * Identifier for intent extra for sending an empty Flash message for
@@ -157,7 +161,7 @@
      * TODO: Keep in sync with the string defined in OutgoingCallBroadcaster.java
      * in Phone app until this is replaced with the ITelephony API.
      */
-    static final String EXTRA_SEND_EMPTY_FLASH
+    private static final String EXTRA_SEND_EMPTY_FLASH
             = "com.android.phone.extra.SEND_EMPTY_FLASH";
 
     private String mCurrentCountryIso;
@@ -187,10 +191,12 @@
 
     private boolean mWasEmptyBeforeTextChange;
 
+    @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
         mWasEmptyBeforeTextChange = TextUtils.isEmpty(s);
     }
 
+    @Override
     public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
         if (mWasEmptyBeforeTextChange != TextUtils.isEmpty(input)) {
             final Activity activity = getActivity();
@@ -203,7 +209,11 @@
         // the DTMF dialer handles that functionality now.
     }
 
+    @Override
     public void afterTextChanged(Editable input) {
+        // When DTMF dialpad buttons are being pressed, we delay SpecialCharSequencMgr sequence,
+        // since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down"
+        // behavior.
         if (SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), mDigits)) {
             // A special sequence was entered, clear the digits
             mDigits.getText().clear();
@@ -252,39 +262,26 @@
 
         PhoneNumberFormatter.setPhoneNumberFormattingTextWatcher(getActivity(), mDigits);
 
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int minCellSize = (int) (56 * dm.density); // 56dip == minimum size of menu buttons
-        int cellCount = dm.widthPixels / minCellSize;
-        int fakeMenuItemWidth = dm.widthPixels / cellCount;
-        if (DEBUG) Log.d(TAG, "The size of fake menu buttons (in pixel): " + fakeMenuItemWidth);
-
-        // Soft menu button should appear only when there's no hardware menu button.
-        mMenuButton = fragmentView.findViewById(R.id.overflow_menu);
-        if (mMenuButton != null) {
-            mMenuButton.setMinimumWidth(fakeMenuItemWidth);
-            if (ViewConfiguration.get(getActivity()).hasPermanentMenuKey()) {
-                // This is required for dialpad button's layout, so must not use GONE here.
-                mMenuButton.setVisibility(View.INVISIBLE);
-            } else {
-                mMenuButton.setOnClickListener(this);
-            }
-        }
-        mSearchButton = fragmentView.findViewById(R.id.searchButton);
-        if (mSearchButton != null) {
-            mSearchButton.setMinimumWidth(fakeMenuItemWidth);
-            mSearchButton.setOnClickListener(this);
-        }
-
         // Check for the presence of the keypad
         View oneButton = fragmentView.findViewById(R.id.one);
         if (oneButton != null) {
             setupKeypad(fragmentView);
         }
 
+        DisplayMetrics dm = getResources().getDisplayMetrics();
+        int minCellSize = (int) (56 * dm.density); // 56dip == minimum size of menu buttons
+        int cellCount = dm.widthPixels / minCellSize;
+        int fakeMenuItemWidth = dm.widthPixels / cellCount;
         mDialButtonContainer = fragmentView.findViewById(R.id.dialButtonContainer);
+        if (mDialButtonContainer != null) {
+            mDialButtonContainer.setPadding(
+                    fakeMenuItemWidth, mDialButtonContainer.getPaddingTop(),
+                    fakeMenuItemWidth, mDialButtonContainer.getPaddingBottom());
+        }
         mDialButton = fragmentView.findViewById(R.id.dialButton);
         if (r.getBoolean(R.bool.config_show_onscreen_dial_button)) {
             mDialButton.setOnClickListener(this);
+            mDialButton.setOnLongClickListener(this);
         } else {
             mDialButton.setVisibility(View.GONE); // It's VISIBLE by default
             mDialButton = null;
@@ -311,8 +308,6 @@
 
         configureScreenFromIntent(getActivity().getIntent());
 
-        updateFakeMenuButtonsVisibility(mShowOptionsMenu);
-
         return fragmentView;
     }
 
@@ -332,7 +327,7 @@
         if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
             Uri uri = intent.getData();
             if (uri != null) {
-                if ("tel".equals(uri.getScheme())) {
+                if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
                     // Put the requested number into the input area
                     String data = uri.getSchemeSpecificPart();
                     setFormattedDigits(data, null);
@@ -456,59 +451,58 @@
     }
 
     private void setupKeypad(View fragmentView) {
-        // Setup the listeners for the buttons
-        View view = fragmentView.findViewById(R.id.one);
-        view.setOnClickListener(this);
-        view.setOnLongClickListener(this);
+        int[] buttonIds = new int[] { R.id.one, R.id.two, R.id.three, R.id.four, R.id.five,
+                R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.zero, R.id.star, R.id.pound};
+        for (int id : buttonIds) {
+            ((DialpadImageButton) fragmentView.findViewById(id)).setOnPressedListener(this);
+        }
 
-        fragmentView.findViewById(R.id.two).setOnClickListener(this);
-        fragmentView.findViewById(R.id.three).setOnClickListener(this);
-        fragmentView.findViewById(R.id.four).setOnClickListener(this);
-        fragmentView.findViewById(R.id.five).setOnClickListener(this);
-        fragmentView.findViewById(R.id.six).setOnClickListener(this);
-        fragmentView.findViewById(R.id.seven).setOnClickListener(this);
-        fragmentView.findViewById(R.id.eight).setOnClickListener(this);
-        fragmentView.findViewById(R.id.nine).setOnClickListener(this);
-        fragmentView.findViewById(R.id.star).setOnClickListener(this);
+        // Long-pressing one button will initiate Voicemail.
+        fragmentView.findViewById(R.id.one).setOnLongClickListener(this);
 
-        view = fragmentView.findViewById(R.id.zero);
-        view.setOnClickListener(this);
-        view.setOnLongClickListener(this);
+        // Long-pressing zero button will enter '+' instead.
+        fragmentView.findViewById(R.id.zero).setOnLongClickListener(this);
 
-        fragmentView.findViewById(R.id.pound).setOnClickListener(this);
     }
 
     @Override
     public void onResume() {
         super.onResume();
 
+        final StopWatch stopWatch = StopWatch.start("Dialpad.onResume");
+
         // Query the last dialed number. Do it first because hitting
         // the DB is 'slow'. This call is asynchronous.
         queryLastOutgoingCall();
 
+        stopWatch.lap("qloc");
+
         // retrieve the DTMF tone play back setting.
         mDTMFToneEnabled = Settings.System.getInt(getActivity().getContentResolver(),
                 Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
 
+        stopWatch.lap("dtwd");
+
         // Retrieve the haptic feedback setting.
         mHaptic.checkSystemSetting();
 
+        stopWatch.lap("hptc");
+
         // if the mToneGenerator creation fails, just continue without it.  It is
         // a local audio signal, and is not as important as the dtmf tone itself.
         synchronized (mToneGeneratorLock) {
             if (mToneGenerator == null) {
                 try {
-                    // we want the user to be able to control the volume of the dial tones
-                    // outside of a call, so we use the stream type that is also mapped to the
-                    // volume control keys for this activity
                     mToneGenerator = new ToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);
-                    getActivity().setVolumeControlStream(DIAL_TONE_STREAM_TYPE);
                 } catch (RuntimeException e) {
                     Log.w(TAG, "Exception caught while creating local tone generator: " + e);
                     mToneGenerator = null;
                 }
             }
         }
+        stopWatch.lap("tg");
+        // Prevent unnecessary confusion. Reset the press count anyway.
+        mDialpadPressCount = 0;
 
         Activity parent = getActivity();
         if (parent instanceof DialtactsActivity) {
@@ -517,6 +511,8 @@
             fillDigitsIfNecessary(parent.getIntent());
         }
 
+        stopWatch.lap("fdin");
+
         // While we're in the foreground, listen for phone state changes,
         // purely so that we can take down the "dialpad chooser" if the
         // phone becomes idle while the chooser UI is visible.
@@ -524,6 +520,8 @@
                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
         telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
 
+        stopWatch.lap("tm");
+
         // Potentially show hint text in the mDigits field when the user
         // hasn't typed any digits yet.  (If there's already an active call,
         // this hint text will remind the user that he's about to add a new
@@ -534,7 +532,10 @@
         // another call, but that call is guaranteed to fail.  Perhaps the
         // entire dialer UI should be disabled instead.)
         if (phoneIsInUse()) {
-            mDigits.setHint(R.string.dialerDialpadHintText);
+            final SpannableString hint = new SpannableString(
+                    getActivity().getString(R.string.dialerDialpadHintText));
+            hint.setSpan(new RelativeSizeSpan(0.8f), 0, hint.length(), 0);
+            mDigits.setHint(hint);
         } else {
             // Common case; no hint necessary.
             mDigits.setHint(null);
@@ -544,7 +545,13 @@
             showDialpadChooser(false);
         }
 
+        stopWatch.lap("hnt");
+
         updateDialAndDeleteButtonEnabledState();
+
+        stopWatch.lap("bes");
+
+        stopWatch.stopAndLog(TAG, 50);
     }
 
     @Override
@@ -556,6 +563,11 @@
                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
         telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
 
+        // Make sure we don't leave this activity with a tone still playing.
+        stopTone();
+        // Just in case reset the counter too.
+        mDialpadPressCount = 0;
+
         synchronized (mToneGeneratorLock) {
             if (mToneGenerator != null) {
                 mToneGenerator.release();
@@ -565,12 +577,23 @@
         // TODO: I wonder if we should not check if the AsyncTask that
         // lookup the last dialed number has completed.
         mLastNumberDialed = EMPTY_NUMBER;  // Since we are going to query again, free stale number.
+
+        SpecialCharSequenceMgr.cleanup();
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        if (mClearDigitsOnStop) {
+            mClearDigitsOnStop = false;
+            mDigits.getText().clear();
+        }
     }
 
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
-        if (mShowOptionsMenu && ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
+        if (ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
                 isLayoutReady() && mDialpadChooser != null) {
             inflater.inflate(R.menu.dialpad_options, menu);
         }
@@ -579,7 +602,7 @@
     @Override
     public void onPrepareOptionsMenu(Menu menu) {
         // Hardware menu key should be available and Views should already be ready.
-        if (mShowOptionsMenu && ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
+        if (ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
                 isLayoutReady() && mDialpadChooser != null) {
              setupMenuItems(menu);
         }
@@ -665,6 +688,47 @@
     }
 
     private void keyPressed(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_1:
+                playTone(ToneGenerator.TONE_DTMF_1, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_2:
+                playTone(ToneGenerator.TONE_DTMF_2, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_3:
+                playTone(ToneGenerator.TONE_DTMF_3, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_4:
+                playTone(ToneGenerator.TONE_DTMF_4, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_5:
+                playTone(ToneGenerator.TONE_DTMF_5, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_6:
+                playTone(ToneGenerator.TONE_DTMF_6, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_7:
+                playTone(ToneGenerator.TONE_DTMF_7, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_8:
+                playTone(ToneGenerator.TONE_DTMF_8, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_9:
+                playTone(ToneGenerator.TONE_DTMF_9, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_0:
+                playTone(ToneGenerator.TONE_DTMF_0, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_POUND:
+                playTone(ToneGenerator.TONE_DTMF_P, TONE_LENGTH_INFINITE);
+                break;
+            case KeyEvent.KEYCODE_STAR:
+                playTone(ToneGenerator.TONE_DTMF_S, TONE_LENGTH_INFINITE);
+                break;
+            default:
+                break;
+        }
+
         mHaptic.vibrate();
         KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
         mDigits.onKeyDown(keyCode, event);
@@ -676,6 +740,7 @@
         }
     }
 
+    @Override
     public boolean onKey(View view, int keyCode, KeyEvent event) {
         switch (view.getId()) {
             case R.id.digits:
@@ -688,69 +753,92 @@
         return false;
     }
 
+    /**
+     * When a key is pressed, we start playing DTMF tone, do vibration, and enter the digit
+     * immediately. When a key is released, we stop the tone. Note that the "key press" event will
+     * be delivered by the system with certain amount of delay, it won't be synced with user's
+     * actual "touch-down" behavior.
+     */
+    @Override
+    public void onPressed(View view, boolean pressed) {
+        if (DEBUG) Log.d(TAG, "onPressed(). view: " + view + ", pressed: " + pressed);
+        if (pressed) {
+            switch (view.getId()) {
+                case R.id.one: {
+                    keyPressed(KeyEvent.KEYCODE_1);
+                    break;
+                }
+                case R.id.two: {
+                    keyPressed(KeyEvent.KEYCODE_2);
+                    break;
+                }
+                case R.id.three: {
+                    keyPressed(KeyEvent.KEYCODE_3);
+                    break;
+                }
+                case R.id.four: {
+                    keyPressed(KeyEvent.KEYCODE_4);
+                    break;
+                }
+                case R.id.five: {
+                    keyPressed(KeyEvent.KEYCODE_5);
+                    break;
+                }
+                case R.id.six: {
+                    keyPressed(KeyEvent.KEYCODE_6);
+                    break;
+                }
+                case R.id.seven: {
+                    keyPressed(KeyEvent.KEYCODE_7);
+                    break;
+                }
+                case R.id.eight: {
+                    keyPressed(KeyEvent.KEYCODE_8);
+                    break;
+                }
+                case R.id.nine: {
+                    keyPressed(KeyEvent.KEYCODE_9);
+                    break;
+                }
+                case R.id.zero: {
+                    keyPressed(KeyEvent.KEYCODE_0);
+                    break;
+                }
+                case R.id.pound: {
+                    keyPressed(KeyEvent.KEYCODE_POUND);
+                    break;
+                }
+                case R.id.star: {
+                    keyPressed(KeyEvent.KEYCODE_STAR);
+                    break;
+                }
+                default: {
+                    Log.wtf(TAG, "Unexpected onTouch(ACTION_DOWN) event from: " + view);
+                    break;
+                }
+            }
+            mDialpadPressCount++;
+        } else {
+            view.jumpDrawablesToCurrentState();
+            mDialpadPressCount--;
+            if (mDialpadPressCount < 0) {
+                // e.g.
+                // - when the user action is detected as horizontal swipe, at which only
+                //   "up" event is thrown.
+                // - when the user long-press '0' button, at which dialpad will decrease this count
+                //   while it still gets press-up event here.
+                if (DEBUG) Log.d(TAG, "mKeyPressCount become negative.");
+                stopTone();
+                mDialpadPressCount = 0;
+            } else if (mDialpadPressCount == 0) {
+                stopTone();
+            }
+        }
+    }
+
     @Override
     public void onClick(View view) {
         switch (view.getId()) {
-            case R.id.one: {
-                playTone(ToneGenerator.TONE_DTMF_1);
-                keyPressed(KeyEvent.KEYCODE_1);
-                return;
-            }
-            case R.id.two: {
-                playTone(ToneGenerator.TONE_DTMF_2);
-                keyPressed(KeyEvent.KEYCODE_2);
-                return;
-            }
-            case R.id.three: {
-                playTone(ToneGenerator.TONE_DTMF_3);
-                keyPressed(KeyEvent.KEYCODE_3);
-                return;
-            }
-            case R.id.four: {
-                playTone(ToneGenerator.TONE_DTMF_4);
-                keyPressed(KeyEvent.KEYCODE_4);
-                return;
-            }
-            case R.id.five: {
-                playTone(ToneGenerator.TONE_DTMF_5);
-                keyPressed(KeyEvent.KEYCODE_5);
-                return;
-            }
-            case R.id.six: {
-                playTone(ToneGenerator.TONE_DTMF_6);
-                keyPressed(KeyEvent.KEYCODE_6);
-                return;
-            }
-            case R.id.seven: {
-                playTone(ToneGenerator.TONE_DTMF_7);
-                keyPressed(KeyEvent.KEYCODE_7);
-                return;
-            }
-            case R.id.eight: {
-                playTone(ToneGenerator.TONE_DTMF_8);
-                keyPressed(KeyEvent.KEYCODE_8);
-                return;
-            }
-            case R.id.nine: {
-                playTone(ToneGenerator.TONE_DTMF_9);
-                keyPressed(KeyEvent.KEYCODE_9);
-                return;
-            }
-            case R.id.zero: {
-                playTone(ToneGenerator.TONE_DTMF_0);
-                keyPressed(KeyEvent.KEYCODE_0);
-                return;
-            }
-            case R.id.pound: {
-                playTone(ToneGenerator.TONE_DTMF_P);
-                keyPressed(KeyEvent.KEYCODE_POUND);
-                return;
-            }
-            case R.id.star: {
-                playTone(ToneGenerator.TONE_DTMF_S);
-                keyPressed(KeyEvent.KEYCODE_STAR);
-                return;
-            }
             case R.id.deleteButton: {
                 keyPressed(KeyEvent.KEYCODE_DEL);
                 return;
@@ -760,29 +848,20 @@
                 dialButtonPressed();
                 return;
             }
-            case R.id.searchButton: {
-                mHaptic.vibrate();
-                if (mListener != null) {
-                    mListener.onSearchButtonPressed();
-                }
-                return;
-            }
             case R.id.digits: {
                 if (!isDigitsEmpty()) {
                     mDigits.setCursorVisible(true);
                 }
                 return;
             }
-            case R.id.overflow_menu: {
-                PopupMenu popup = constructPopupMenu(view);
-                if (popup != null) {
-                    popup.show();
-                }
+            default: {
+                Log.wtf(TAG, "Unexpected onClick() event from: " + view);
+                return;
             }
         }
     }
 
-    private PopupMenu constructPopupMenu(View anchorView) {
+    public PopupMenu constructPopupMenu(View anchorView) {
         final Context context = getActivity();
         if (context == null) {
             return null;
@@ -795,9 +874,10 @@
         return popupMenu;
     }
 
+    @Override
     public boolean onLongClick(View view) {
         final Editable digits = mDigits.getText();
-        int id = view.getId();
+        final int id = view.getId();
         switch (id) {
             case R.id.deleteButton: {
                 digits.clear();
@@ -808,21 +888,47 @@
                 return true;
             }
             case R.id.one: {
-                if (isDigitsEmpty()) {
+                // '1' may be already entered since we rely on onTouch() event for numeric buttons.
+                // Just for safety we also check if the digits field is empty or not.
+                if (isDigitsEmpty() || TextUtils.equals(mDigits.getText(), "1")) {
+                    // We'll try to initiate voicemail and thus we want to remove irrelevant string.
+                    removePreviousDigitIfPossible();
+
                     if (isVoicemailAvailable()) {
                         callVoicemail();
                     } else if (getActivity() != null) {
-                        DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
-                                R.string.dialog_voicemail_not_ready_title,
-                                R.string.dialog_voicemail_not_ready_message);
-                        dialogFragment.show(getFragmentManager(), "voicemail_not_ready");
+                        // Voicemail is unavailable maybe because Airplane mode is turned on.
+                        // Check the current status and show the most appropriate error message.
+                        final boolean isAirplaneModeOn =
+                                Settings.System.getInt(getActivity().getContentResolver(),
+                                Settings.System.AIRPLANE_MODE_ON, 0) != 0;
+                        if (isAirplaneModeOn) {
+                            DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
+                                    R.string.dialog_voicemail_airplane_mode_message);
+                            dialogFragment.show(getFragmentManager(),
+                                    "voicemail_request_during_airplane_mode");
+                        } else {
+                            DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
+                                    R.string.dialog_voicemail_not_ready_message);
+                            dialogFragment.show(getFragmentManager(), "voicemail_not_ready");
+                        }
                     }
                     return true;
                 }
                 return false;
             }
             case R.id.zero: {
+                // Remove tentative input ('0') done by onTouch().
+                removePreviousDigitIfPossible();
                 keyPressed(KeyEvent.KEYCODE_PLUS);
+
+                // Stop tone immediately and decrease the press count, so that possible subsequent
+                // dial button presses won't honor the 0 click any more.
+                // Note: this *will* make mDialpadPressCount negative when the 0 key is released,
+                // which should be handled appropriately.
+                stopTone();
+                if (mDialpadPressCount > 0) mDialpadPressCount--;
+
                 return true;
             }
             case R.id.digits: {
@@ -832,39 +938,55 @@
                 mDigits.setCursorVisible(true);
                 return false;
             }
+            case R.id.dialButton: {
+                if (isDigitsEmpty()) {
+                    handleDialButtonClickWithEmptyDigits();
+                    // This event should be consumed so that onClick() won't do the exactly same
+                    // thing.
+                    return true;
+                } else {
+                    return false;
+                }
+            }
         }
         return false;
     }
 
+    /**
+     * Remove the digit just before the current position. This can be used if we want to replace
+     * the previous digit or cancel previously entered character.
+     */
+    private void removePreviousDigitIfPossible() {
+        final Editable editable = mDigits.getText();
+        final int currentPosition = mDigits.getSelectionStart();
+        if (currentPosition > 0) {
+            mDigits.setSelection(currentPosition);
+            mDigits.getText().delete(currentPosition - 1, currentPosition);
+        }
+    }
+
     public void callVoicemail() {
-        startActivity(newVoicemailIntent());
-        mDigits.getText().clear(); // TODO: Fix bug 1745781
+        startActivity(ContactsUtils.getVoicemailIntent());
+        mClearDigitsOnStop = true;
         getActivity().finish();
     }
 
     public static class ErrorDialogFragment extends DialogFragment {
         private int mTitleResId;
-        private Integer mMessageResId;  // can be null
+        private int mMessageResId;
 
         private static final String ARG_TITLE_RES_ID = "argTitleResId";
         private static final String ARG_MESSAGE_RES_ID = "argMessageResId";
 
-        public static ErrorDialogFragment newInstance(int titleResId) {
-            return newInstanceInter(titleResId, null);
+        public static ErrorDialogFragment newInstance(int messageResId) {
+            return newInstance(0, messageResId);
         }
 
         public static ErrorDialogFragment newInstance(int titleResId, int messageResId) {
-            return newInstanceInter(titleResId, messageResId);
-        }
-
-        private static ErrorDialogFragment newInstanceInter(
-                int titleResId, Integer messageResId) {
             final ErrorDialogFragment fragment = new ErrorDialogFragment();
             final Bundle args = new Bundle();
             args.putInt(ARG_TITLE_RES_ID, titleResId);
-            if (messageResId != null) {
-                args.putInt(ARG_MESSAGE_RES_ID, messageResId);
-            }
+            args.putInt(ARG_MESSAGE_RES_ID, messageResId);
             fragment.setArguments(args);
             return fragment;
         }
@@ -873,25 +995,25 @@
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID);
-            if (getArguments().containsKey(ARG_MESSAGE_RES_ID)) {
-                mMessageResId = getArguments().getInt(ARG_MESSAGE_RES_ID);
-            }
+            mMessageResId = getArguments().getInt(ARG_MESSAGE_RES_ID);
         }
 
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-            builder.setTitle(mTitleResId)
-                    .setPositiveButton(android.R.string.ok,
-                            new DialogInterface.OnClickListener() {
-                                @Override
-                                public void onClick(DialogInterface dialog, int which) {
-                                    dismiss();
-                                }
-                            });
-            if (mMessageResId != null) {
+            if (mTitleResId != 0) {
+                builder.setTitle(mTitleResId);
+            }
+            if (mMessageResId != 0) {
                 builder.setMessage(mMessageResId);
             }
+            builder.setPositiveButton(android.R.string.ok,
+                    new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                dismiss();
+                            }
+                    });
             return builder.create();
         }
     }
@@ -917,35 +1039,7 @@
      */
     public void dialButtonPressed() {
         if (isDigitsEmpty()) { // No number entered.
-            if (phoneIsCdma() && phoneIsOffhook()) {
-                // This is really CDMA specific. On GSM is it possible
-                // to be off hook and wanted to add a 3rd party using
-                // the redial feature.
-                startActivity(newFlashIntent());
-            } else {
-                if (!TextUtils.isEmpty(mLastNumberDialed)) {
-                    // Recall the last number dialed.
-                    mDigits.setText(mLastNumberDialed);
-
-                    // ...and move the cursor to the end of the digits string,
-                    // so you'll be able to delete digits using the Delete
-                    // button (just as if you had typed the number manually.)
-                    //
-                    // Note we use mDigits.getText().length() here, not
-                    // mLastNumberDialed.length(), since the EditText widget now
-                    // contains a *formatted* version of mLastNumberDialed (due to
-                    // mTextWatcher) and its length may have changed.
-                    mDigits.setSelection(mDigits.getText().length());
-                } else {
-                    // There's no "last number dialed" or the
-                    // background query is still running. There's
-                    // nothing useful for the Dial button to do in
-                    // this case.  Note: with a soft dial button, this
-                    // can never happens since the dial button is
-                    // disabled under these conditons.
-                    playTone(ToneGenerator.TONE_PROP_NACK);
-                }
-            }
+            handleDialButtonClickWithEmptyDigits();
         } else {
             final String number = mDigits.getText().toString();
 
@@ -959,35 +1053,76 @@
                 Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
                 if (getActivity() != null) {
                     DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
-                                    R.string.dialog_phone_call_prohibited_title);
+                            R.string.dialog_phone_call_prohibited_message);
                     dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
                 }
 
                 // Clear the digits just in case.
                 mDigits.getText().clear();
             } else {
-                final Intent intent = newDialNumberIntent(number);
-                if (getActivity() instanceof DialtactsActivity) {
-                    intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN,
-                            DialtactsActivity.CALL_ORIGIN_DIALTACTS);
-                }
+                final Intent intent = ContactsUtils.getCallIntent(number,
+                        (getActivity() instanceof DialtactsActivity ?
+                                ((DialtactsActivity)getActivity()).getCallOrigin() : null));
                 startActivity(intent);
-                mDigits.getText().clear();  // TODO: Fix bug 1745781
+                mClearDigitsOnStop = true;
                 getActivity().finish();
             }
         }
     }
 
+    private void handleDialButtonClickWithEmptyDigits() {
+        if (phoneIsCdma() && phoneIsOffhook()) {
+            // This is really CDMA specific. On GSM is it possible
+            // to be off hook and wanted to add a 3rd party using
+            // the redial feature.
+            startActivity(newFlashIntent());
+        } else {
+            if (!TextUtils.isEmpty(mLastNumberDialed)) {
+                // Recall the last number dialed.
+                mDigits.setText(mLastNumberDialed);
+
+                // ...and move the cursor to the end of the digits string,
+                // so you'll be able to delete digits using the Delete
+                // button (just as if you had typed the number manually.)
+                //
+                // Note we use mDigits.getText().length() here, not
+                // mLastNumberDialed.length(), since the EditText widget now
+                // contains a *formatted* version of mLastNumberDialed (due to
+                // mTextWatcher) and its length may have changed.
+                mDigits.setSelection(mDigits.getText().length());
+            } else {
+                // There's no "last number dialed" or the
+                // background query is still running. There's
+                // nothing useful for the Dial button to do in
+                // this case.  Note: with a soft dial button, this
+                // can never happens since the dial button is
+                // disabled under these conditons.
+                playTone(ToneGenerator.TONE_PROP_NACK);
+            }
+        }
+    }
+
     /**
      * Plays the specified tone for TONE_LENGTH_MS milliseconds.
+     */
+    private void playTone(int tone) {
+        playTone(tone, TONE_LENGTH_MS);
+    }
+
+    /**
+     * Play the specified tone for the specified milliseconds
      *
      * The tone is played locally, using the audio stream for phone calls.
      * Tones are played only if the "Audible touch tones" user preference
      * is checked, and are NOT played if the device is in silent mode.
      *
+     * The tone length can be -1, meaning "keep playing the tone." If the caller does so, it should
+     * call stopTone() afterward.
+     *
      * @param tone a tone code from {@link ToneGenerator}
+     * @param durationMs tone length.
      */
-    void playTone(int tone) {
+    private void playTone(int tone, int durationMs) {
         // if local tone playback is disabled, just return.
         if (!mDTMFToneEnabled) {
             return;
@@ -1013,7 +1148,24 @@
             }
 
             // Start the new tone (will stop any playing tone)
-            mToneGenerator.startTone(tone, TONE_LENGTH_MS);
+            mToneGenerator.startTone(tone, durationMs);
+        }
+    }
+
+    /**
+     * Stop the tone if it is played.
+     */
+    private void stopTone() {
+        // if local tone playback is disabled, just return.
+        if (!mDTMFToneEnabled) {
+            return;
+        }
+        synchronized (mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                Log.w(TAG, "stopTone: mToneGenerator == null");
+                return;
+            }
+            mToneGenerator.stopTone();
         }
     }
 
@@ -1135,6 +1287,7 @@
                     DIALPAD_CHOICE_ADD_NEW_CALL);
         }
 
+        @Override
         public int getCount() {
             return NUM_ITEMS;
         }
@@ -1142,6 +1295,7 @@
         /**
          * Return the ChoiceItem for a given position.
          */
+        @Override
         public Object getItem(int position) {
             return mChoiceItems[position];
         }
@@ -1149,6 +1303,7 @@
         /**
          * Return a unique ID for each possible choice.
          */
+        @Override
         public long getItemId(int position) {
             return position;
         }
@@ -1156,6 +1311,7 @@
         /**
          * Make a view for each row.
          */
+        @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             // When convertView is non-null, we can reuse it (there's no need
             // to reinflate it.)
@@ -1176,7 +1332,8 @@
     /**
      * Handle clicks from the dialpad chooser.
      */
-    public void onItemClick(AdapterView parent, View v, int position, long id) {
+    @Override
+    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
         DialpadChooserAdapter.ChoiceItem item =
                 (DialpadChooserAdapter.ChoiceItem) parent.getItemAtPosition(position);
         int itemId = item.id;
@@ -1418,6 +1575,7 @@
                 new CallLogAsync.GetLastOutgoingCallArgs(
                     getActivity(),
                     new CallLogAsync.OnLastOutgoingCallComplete() {
+                        @Override
                         public void lastOutgoingCall(String number) {
                             // TODO: Filter out emergency numbers if
                             // the carrier does not want redial for
@@ -1429,60 +1587,9 @@
         mCallLog.getLastOutgoingCall(lastCallArgs);
     }
 
-    // Helpers for the call intents.
-    private Intent newVoicemailIntent() {
-        final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                                         Uri.fromParts("voicemail", EMPTY_NUMBER, null));
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
     private Intent newFlashIntent() {
-        final Intent intent = newDialNumberIntent(EMPTY_NUMBER);
+        final Intent intent = ContactsUtils.getCallIntent(EMPTY_NUMBER);
         intent.putExtra(EXTRA_SEND_EMPTY_FLASH, true);
         return intent;
     }
-
-    private Intent newDialNumberIntent(String number) {
-        final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                                         Uri.fromParts("tel", number, null));
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    public void setListener(Listener listener) {
-        mListener = listener;
-    }
-
-    @Override
-    public void onVisibilityChanged(boolean fragmentVisible) {
-        mShowOptionsMenu = fragmentVisible;
-        updateFakeMenuButtonsVisibility(fragmentVisible);
-    }
-
-    /**
-     * Update visibility of the search button and menu button at the bottom of dialer screen, which
-     * should be invisible when bottom ActionBar's real items are available and be visible
-     * otherwise.
-     *
-     * @param visible True when visible.
-     */
-    public void updateFakeMenuButtonsVisibility(boolean visible) {
-        if (DEBUG) Log.d(TAG, "updateFakeMenuButtonVisibility(" + visible + ")");
-
-        if (mSearchButton != null) {
-            if (visible) {
-                mSearchButton.setVisibility(View.VISIBLE);
-            } else {
-                mSearchButton.setVisibility(View.INVISIBLE);
-            }
-        }
-        if (mMenuButton != null) {
-            if (visible && !ViewConfiguration.get(getActivity()).hasPermanentMenuKey()) {
-                mMenuButton.setVisibility(View.VISIBLE);
-            } else {
-                mMenuButton.setVisibility(View.INVISIBLE);
-            }
-        }
-    }
 }
diff --git a/src/com/android/contacts/dialpad/DialpadImageButton.java b/src/com/android/contacts/dialpad/DialpadImageButton.java
new file mode 100644
index 0000000..a18cbb8
--- /dev/null
+++ b/src/com/android/contacts/dialpad/DialpadImageButton.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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.contacts.dialpad;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageButton;
+
+/**
+ * Custom {@link ImageButton} for dialpad buttons.
+ *
+ * During horizontal swipe, we want to exit "fading out" animation offered by its background
+ * just after starting the swipe.This class overrides {@link #onTouchEvent(MotionEvent)} to achieve
+ * the behavior.
+ */
+public class DialpadImageButton extends ImageButton {
+    public interface OnPressedListener {
+        public void onPressed(View view, boolean pressed);
+    }
+
+    private OnPressedListener mOnPressedListener;
+
+    public void setOnPressedListener(OnPressedListener onPressedListener) {
+        mOnPressedListener = onPressedListener;
+    }
+
+    public DialpadImageButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public DialpadImageButton(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    public void setPressed(boolean pressed) {
+        super.setPressed(pressed);
+        if (mOnPressedListener != null) {
+            mOnPressedListener.onPressed(this, pressed);
+        }
+    }
+}
diff --git a/src/com/android/contacts/dialpad/DigitsEditText.java b/src/com/android/contacts/dialpad/DigitsEditText.java
index 68335da..7b3e8b2 100644
--- a/src/com/android/contacts/dialpad/DigitsEditText.java
+++ b/src/com/android/contacts/dialpad/DigitsEditText.java
@@ -32,6 +32,7 @@
     public DigitsEditText(Context context, AttributeSet attrs) {
         super(context, attrs);
         setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
+        setShowSoftInputOnFocus(false);
     }
 
     @Override
diff --git a/src/com/android/contacts/editor/AggregationSuggestionEngine.java b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
index 0861d92..c340f96 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionEngine.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
@@ -119,7 +119,7 @@
 
     public AggregationSuggestionEngine(Context context) {
         super("AggregationSuggestions", Process.THREAD_PRIORITY_BACKGROUND);
-        mContext = context;
+        mContext = context.getApplicationContext();
         mMainHandler = new Handler() {
             @Override
             public void handleMessage(Message msg) {
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 844f892..a4e4db4 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -23,6 +23,7 @@
 import com.android.contacts.activities.ContactEditorAccountsChangedActivity;
 import com.android.contacts.activities.ContactEditorActivity;
 import com.android.contacts.activities.JoinContactActivity;
+import com.android.contacts.detail.PhotoSelectionHandler;
 import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
 import com.android.contacts.editor.Editor.EditorListener;
 import com.android.contacts.model.AccountType;
@@ -34,7 +35,9 @@
 import com.android.contacts.model.EntityModifier;
 import com.android.contacts.model.GoogleAccountType;
 import com.android.contacts.util.AccountsListAdapter;
+import com.android.contacts.util.ContactPhotoUtils;
 import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.util.HelpUtils;
 
 import android.accounts.Account;
 import android.app.Activity;
@@ -44,7 +47,6 @@
 import android.app.Fragment;
 import android.app.LoaderManager;
 import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ActivityNotFoundException;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
@@ -55,23 +57,20 @@
 import android.content.Loader;
 import android.database.Cursor;
 import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.MediaScannerConnection;
+import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.SystemClock;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Event;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.DisplayPhoto;
 import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.RawContacts;
-import android.provider.MediaStore;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -87,11 +86,9 @@
 import android.widget.Toast;
 
 import java.io.File;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.List;
 
 public class ContactEditorFragment extends Fragment implements
@@ -117,6 +114,7 @@
     private static final String KEY_STATUS = "status";
     private static final String KEY_NEW_LOCAL_PROFILE = "newLocalProfile";
     private static final String KEY_IS_USER_PROFILE = "isUserProfile";
+    private static final String KEY_UPDATED_PHOTOS = "updatedPhotos";
 
     public static final String SAVE_MODE_EXTRA_KEY = "saveMode";
 
@@ -131,8 +129,6 @@
     /**
      * Modes that specify what the AsyncTask has to perform after saving
      */
-    // TODO: Move this into a common utils class or the save service because the contact and
-    // group editors need to use this interface definition
     public interface SaveMode {
         /**
          * Close the editor after saving
@@ -192,25 +188,29 @@
     }
 
     private static final int REQUEST_CODE_JOIN = 0;
-    private static final int REQUEST_CODE_CAMERA_WITH_DATA = 1;
-    private static final int REQUEST_CODE_PHOTO_PICKED_WITH_DATA = 2;
-    private static final int REQUEST_CODE_ACCOUNTS_CHANGED = 3;
+    private static final int REQUEST_CODE_ACCOUNTS_CHANGED = 1;
 
-    private Bitmap mPhoto = null;
-    private long mRawContactIdRequestingPhoto = -1;
-    private long mRawContactIdRequestingPhotoAfterLoad = -1;
+    /**
+     * The raw contact for which we started "take photo" or "choose photo from gallery" most
+     * recently.  Used to restore {@link #mCurrentPhotoHandler} after orientation change.
+     */
+    private long mRawContactIdRequestingPhoto;
+    /**
+     * The {@link PhotoHandler} for the photo editor for the {@link #mRawContactIdRequestingPhoto}
+     * raw contact.
+     *
+     * A {@link PhotoHandler} is created for each photo editor in {@link #bindPhotoHandler}, but
+     * the only "active" one should get the activity result.  This member represents the active
+     * one.
+     */
+    private PhotoHandler mCurrentPhotoHandler;
 
     private final EntityDeltaComparator mComparator = new EntityDeltaComparator();
 
-    private static final File PHOTO_DIR = new File(
-            Environment.getExternalStorageDirectory() + "/DCIM/Camera");
-
     private Cursor mGroupMetaData;
 
-    private File mCurrentPhotoFile;
-
-    // Height/width (in pixels) to request for the photo - queried from the provider.
-    private int mPhotoPickSize;
+    private String mCurrentPhotoFile;
+    private Bundle mUpdatedPhotos = new Bundle();
 
     private Context mContext;
     private String mAction;
@@ -322,7 +322,6 @@
         super.onAttach(activity);
         mContext = activity;
         mEditorUtils = ContactEditorUtils.getInstance(mContext);
-        loadPhotoPickSize();
     }
 
     @Override
@@ -425,10 +424,7 @@
             mRawContactIdRequestingPhoto = savedState.getLong(
                     KEY_RAW_CONTACT_ID_REQUESTING_PHOTO);
             mViewIdGenerator = savedState.getParcelable(KEY_VIEW_ID_GENERATOR);
-            String fileName = savedState.getString(KEY_CURRENT_PHOTO_FILE);
-            if (fileName != null) {
-                mCurrentPhotoFile = new File(fileName);
-            }
+            mCurrentPhotoFile = savedState.getString(KEY_CURRENT_PHOTO_FILE);
             mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN);
             mContactWritableForJoin = savedState.getBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN);
             mAggregationSuggestionsRawContactId = savedState.getLong(KEY_SHOW_JOIN_SUGGESTIONS);
@@ -436,6 +432,7 @@
             mStatus = savedState.getInt(KEY_STATUS);
             mNewLocalProfile = savedState.getBoolean(KEY_NEW_LOCAL_PROFILE);
             mIsUserProfile = savedState.getBoolean(KEY_IS_USER_PROFILE);
+            mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS);
         }
     }
 
@@ -477,15 +474,15 @@
         mListener.onCustomEditContactActivityRequested(account, uri, null, false);
     }
 
-    private void bindEditorsForExistingContact(ContactLoader.Result data) {
+    private void bindEditorsForExistingContact(ContactLoader.Result contact) {
         setEnabled(true);
 
-        mState = EntityDeltaList.fromIterator(data.getEntities().iterator());
+        mState = contact.createEntityDeltaList();
         setIntentExtras(mIntentExtras);
         mIntentExtras = null;
 
         // For user profile, change the contacts query URI
-        mIsUserProfile = data.isUserProfile();
+        mIsUserProfile = contact.isUserProfile();
         boolean localProfileExists = false;
 
         if (mIsUserProfile) {
@@ -729,16 +726,26 @@
 
             editor.setState(entity, type, mViewIdGenerator, isEditingUserProfile());
 
-            editor.getPhotoEditor().setEditorListener(
-                    new PhotoEditorListener(editor, type.areContactsWritable()));
+            // Set up the photo handler.
+            bindPhotoHandler(editor, type, mState);
+
+            // If a new photo was chosen but not yet saved, we need to
+            // update the thumbnail to reflect this.
+            Bitmap bitmap = updatedBitmapForRawContact(rawContactId);
+            if (bitmap != null) editor.setPhotoBitmap(bitmap);
+
             if (editor instanceof RawContactEditorView) {
+                final Activity activity = getActivity();
                 final RawContactEditorView rawContactEditor = (RawContactEditorView) editor;
                 EditorListener listener = new EditorListener() {
 
                     @Override
                     public void onRequest(int request) {
+                        if (activity.isFinishing()) { // Make sure activity is still running.
+                            return;
+                        }
                         if (request == EditorListener.FIELD_CHANGED && !isEditingUserProfile()) {
-                            acquireAggregationSuggestions(rawContactEditor);
+                            acquireAggregationSuggestions(activity, rawContactEditor);
                         }
                     }
 
@@ -760,7 +767,7 @@
                 rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);
 
                 if (rawContactId == mAggregationSuggestionsRawContactId) {
-                    acquireAggregationSuggestions(rawContactEditor);
+                    acquireAggregationSuggestions(activity, rawContactEditor);
                 }
             }
         }
@@ -776,7 +783,50 @@
         // Activity can be null if we have been detached from the Activity
         final Activity activity = getActivity();
         if (activity != null) activity.invalidateOptionsMenu();
+    }
 
+    /**
+     * If we've stashed a temporary file containing a contact's new photo,
+     * decode it and return the bitmap.
+     * @param rawContactId identifies the raw-contact whose Bitmap we'll try to return.
+     * @return Bitmap of photo for specified raw-contact, or null
+    */
+    private Bitmap updatedBitmapForRawContact(long rawContactId) {
+        String path = mUpdatedPhotos.getString(String.valueOf(rawContactId));
+        return BitmapFactory.decodeFile(path);
+    }
+
+    private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
+            EntityDeltaList state) {
+        final int mode;
+        if (type.areContactsWritable()) {
+            if (editor.hasSetPhoto()) {
+                if (hasMoreThanOnePhoto()) {
+                    mode = PhotoActionPopup.Modes.PHOTO_ALLOW_PRIMARY;
+                } else {
+                    mode = PhotoActionPopup.Modes.PHOTO_DISALLOW_PRIMARY;
+                }
+            } else {
+                mode = PhotoActionPopup.Modes.NO_PHOTO;
+            }
+        } else {
+            if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) {
+                mode = PhotoActionPopup.Modes.READ_ONLY_ALLOW_PRIMARY;
+            } else {
+                // Read-only and either no photo or the only photo ==> no options
+                editor.getPhotoEditor().setEditorListener(null);
+                return;
+            }
+        }
+        final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state);
+        editor.getPhotoEditor().setEditorListener(
+                (PhotoHandler.PhotoEditorListener) photoHandler.getListener());
+
+        // Note a newly created raw contact gets some random negative ID, so any value is valid
+        // here. (i.e. don't check against -1 or anything.)
+        if (mRawContactIdRequestingPhoto == editor.getRawContactId()) {
+            mCurrentPhotoHandler = photoHandler;
+        }
     }
 
     private void bindGroupMetaData() {
@@ -854,7 +904,7 @@
         // Remove the pressed state from the account header because the user cannot switch accounts
         // on an existing contact
         final View accountView = editor.findViewById(R.id.account);
-        accountView.setBackgroundDrawable(null);
+        accountView.setBackground(null);
         accountView.setEnabled(false);
     }
 
@@ -868,14 +918,31 @@
         // This supports the keyboard shortcut to save changes to a contact but shouldn't be visible
         // because the custom action bar contains the "save" button now (not the overflow menu).
         // TODO: Find a better way to handle shortcuts, i.e. onKeyDown()?
-        menu.findItem(R.id.menu_done).setVisible(false);
+        final MenuItem doneMenu = menu.findItem(R.id.menu_done);
+        final MenuItem splitMenu = menu.findItem(R.id.menu_split);
+        final MenuItem joinMenu = menu.findItem(R.id.menu_join);
+        final MenuItem helpMenu = menu.findItem(R.id.menu_help);
+
+        // Set visibility of menus
+        doneMenu.setVisible(false);
 
         // Split only if more than one raw profile and not a user profile
-        menu.findItem(R.id.menu_split).setVisible(mState != null && mState.size() > 1 &&
-                !isEditingUserProfile());
-        // Cannot join a user profile
-        menu.findItem(R.id.menu_join).setVisible(!isEditingUserProfile());
+        splitMenu.setVisible(mState != null && mState.size() > 1 && !isEditingUserProfile());
 
+        // Cannot join a user profile
+        joinMenu.setVisible(!isEditingUserProfile());
+
+        // help menu depending on whether this is inserting or editing
+        if (Intent.ACTION_INSERT.equals(mAction)) {
+            // inserting
+            HelpUtils.prepareHelpMenuItem(mContext, helpMenu, R.string.help_url_people_add);
+        } else if (Intent.ACTION_EDIT.equals(mAction)) {
+            // editing
+            HelpUtils.prepareHelpMenuItem(mContext, helpMenu, R.string.help_url_people_edit);
+        } else {
+            // something else, so don't show the help menu
+            helpMenu.setVisible(false);
+        }
 
         int size = menu.size();
         for (int i = 0; i < size; i++) {
@@ -915,10 +982,8 @@
 
         // If we just started creating a new contact and haven't added any data, it's too
         // early to do a join
-        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
-        if (mState.size() == 1 && mState.get(0).isContactInsert()
-                && !EntityModifier.hasChanges(mState, accountTypes)) {
-            Toast.makeText(getActivity(), R.string.toast_join_with_empty_contact,
+        if (mState.size() == 1 && mState.get(0).isContactInsert() && !hasPendingChanges()) {
+            Toast.makeText(mContext, R.string.toast_join_with_empty_contact,
                             Toast.LENGTH_LONG).show();
             return true;
         }
@@ -926,32 +991,6 @@
         return save(SaveMode.JOIN);
     }
 
-    private void loadPhotoPickSize() {
-        Cursor c = mContext.getContentResolver().query(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
-                new String[]{DisplayPhoto.DISPLAY_MAX_DIM}, null, null, null);
-        try {
-            c.moveToFirst();
-            mPhotoPickSize = c.getInt(0);
-        } finally {
-            c.close();
-        }
-    }
-
-    /**
-     * Constructs an intent for picking a photo from Gallery, cropping it and returning the bitmap.
-     */
-    public Intent getPhotoPickIntent() {
-        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
-        intent.setType("image/*");
-        intent.putExtra("crop", "true");
-        intent.putExtra("aspectX", 1);
-        intent.putExtra("aspectY", 1);
-        intent.putExtra("outputX", mPhotoPickSize);
-        intent.putExtra("outputY", mPhotoPickSize);
-        intent.putExtra("return-data", true);
-        return intent;
-    }
-
     /**
      * Check if our internal {@link #mState} is valid, usually checked before
      * performing user actions.
@@ -961,58 +1000,12 @@
     }
 
     /**
-     * Create a file name for the icon photo using current time.
+     * Return true if there are any edits to the current contact which need to
+     * be saved.
      */
-    private String getPhotoFileName() {
-        Date date = new Date(System.currentTimeMillis());
-        SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss");
-        return dateFormat.format(date) + ".jpg";
-    }
-
-    /**
-     * Constructs an intent for capturing a photo and storing it in a temporary file.
-     */
-    public static Intent getTakePickIntent(File f) {
-        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
-        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
-        return intent;
-    }
-
-    /**
-     * Sends a newly acquired photo to Gallery for cropping
-     */
-    protected void doCropPhoto(File f) {
-        try {
-            // Add the image to the media store
-            MediaScannerConnection.scanFile(
-                    mContext,
-                    new String[] { f.getAbsolutePath() },
-                    new String[] { null },
-                    null);
-
-            // Launch gallery to crop the photo
-            final Intent intent = getCropImageIntent(Uri.fromFile(f));
-            mStatus = Status.SUB_ACTIVITY;
-            startActivityForResult(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA);
-        } catch (Exception e) {
-            Log.e(TAG, "Cannot crop image", e);
-            Toast.makeText(mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
-        }
-    }
-
-    /**
-     * Constructs an intent for image cropping.
-     */
-    public Intent getCropImageIntent(Uri photoUri) {
-        Intent intent = new Intent("com.android.camera.action.CROP");
-        intent.setDataAndType(photoUri, "image/*");
-        intent.putExtra("crop", "true");
-        intent.putExtra("aspectX", 1);
-        intent.putExtra("aspectY", 1);
-        intent.putExtra("outputX", mPhotoPickSize);
-        intent.putExtra("outputY", mPhotoPickSize);
-        intent.putExtra("return-data", true);
-        return intent;
+    private boolean hasPendingChanges() {
+        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
+        return EntityModifier.hasChanges(mState, accountTypes);
     }
 
     /**
@@ -1031,8 +1024,13 @@
 
         mStatus = Status.SAVING;
 
-        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
-        if (!EntityModifier.hasChanges(mState, accountTypes)) {
+        if (!hasPendingChanges()) {
+            if (mLookupUri == null && saveMode == SaveMode.RELOAD) {
+                // We don't have anything to save and there isn't even an existing contact yet.
+                // Nothing to do, simply go back to editing mode
+                mStatus = Status.EDITING;
+                return true;
+            }
             onSaveCompleted(false, saveMode, mLookupUri != null, mLookupUri);
             return true;
         }
@@ -1043,10 +1041,15 @@
         saveDefaultAccountIfNecessary();
 
         // Save contact
-        Intent intent = ContactSaveService.createSaveContactIntent(getActivity(), mState,
+        Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
                 SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
-                getActivity().getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED);
-        getActivity().startService(intent);
+                ((Activity)mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED,
+                mUpdatedPhotos);
+        mContext.startService(intent);
+
+        // Don't try to save the same photos twice.
+        mUpdatedPhotos = new Bundle();
+
         return true;
     }
 
@@ -1062,12 +1065,11 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             AlertDialog dialog = new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.cancel_confirmation_dialog_title)
                     .setMessage(R.string.cancel_confirmation_dialog_message)
                     .setPositiveButton(android.R.string.ok,
                         new DialogInterface.OnClickListener() {
                             @Override
-                            public void onClick(DialogInterface dialog, int whichButton) {
+                            public void onClick(DialogInterface dialogInterface, int whichButton) {
                                 ((ContactEditorFragment)getTargetFragment()).doRevertAction();
                             }
                         }
@@ -1079,8 +1081,7 @@
     }
 
     private boolean revert() {
-        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
-        if (mState == null || !EntityModifier.hasChanges(mState, accountTypes)) {
+        if (mState == null || !hasPendingChanges()) {
             doRevertAction();
         } else {
             CancelEditDialogFragment.show(this);
@@ -1104,7 +1105,6 @@
 
     public void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded,
             Uri contactLookupUri) {
-        Log.d(TAG, "onSaveCompleted(" + saveMode + ", " + contactLookupUri);
         if (hadChanges) {
             if (saveSucceeded) {
                 if (saveMode != SaveMode.JOIN) {
@@ -1375,7 +1375,8 @@
     /**
      * Triggers an asynchronous search for aggregation suggestions.
      */
-    public void acquireAggregationSuggestions(RawContactEditorView rawContactEditor) {
+    private void acquireAggregationSuggestions(Context context,
+            RawContactEditorView rawContactEditor) {
         long rawContactId = rawContactEditor.getRawContactId();
         if (mAggregationSuggestionsRawContactId != rawContactId
                 && mAggregationSuggestionView != null) {
@@ -1387,7 +1388,7 @@
         mAggregationSuggestionsRawContactId = rawContactId;
 
         if (mAggregationSuggestionEngine == null) {
-            mAggregationSuggestionEngine = new AggregationSuggestionEngine(getActivity());
+            mAggregationSuggestionEngine = new AggregationSuggestionEngine(context);
             mAggregationSuggestionEngine.setListener(this);
             mAggregationSuggestionEngine.start();
         }
@@ -1422,7 +1423,6 @@
         mAggregationSuggestionPopup.setAnchorView(anchorView);
         mAggregationSuggestionPopup.setWidth(anchorView.getWidth());
         mAggregationSuggestionPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
-        mAggregationSuggestionPopup.setModal(true);
         mAggregationSuggestionPopup.setAdapter(
                 new AggregationSuggestionAdapter(getActivity(),
                         mState.size() == 1 && mState.get(0).isContactInsert(),
@@ -1456,10 +1456,10 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.aggregation_suggestion_join_dialog_title)
                     .setMessage(R.string.aggregation_suggestion_join_dialog_message)
                     .setPositiveButton(android.R.string.yes,
                         new DialogInterface.OnClickListener() {
+                            @Override
                             public void onClick(DialogInterface dialog, int whichButton) {
                                 ContactEditorFragment targetFragment =
                                         (ContactEditorFragment) getTargetFragment();
@@ -1504,10 +1504,10 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.aggregation_suggestion_edit_dialog_title)
                     .setMessage(R.string.aggregation_suggestion_edit_dialog_message)
                     .setPositiveButton(android.R.string.yes,
                         new DialogInterface.OnClickListener() {
+                            @Override
                             public void onClick(DialogInterface dialog, int whichButton) {
                                 ContactEditorFragment targetFragment =
                                         (ContactEditorFragment) getTargetFragment();
@@ -1548,21 +1548,6 @@
         }
     }
 
-    /**
-     * Computes bounds of the supplied view relative to its ascendant.
-     */
-    private Rect getRelativeBounds(View ascendant, View view) {
-        Rect rect = new Rect();
-        rect.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
-
-        View parent = (View) view.getParent();
-        while (parent != ascendant) {
-            rect.offset(parent.getLeft(), parent.getTop());
-            parent = (View) parent.getParent();
-        }
-        return rect;
-    }
-
     @Override
     public void onSaveInstanceState(Bundle outState) {
         outState.putParcelable(KEY_URI, mLookupUri);
@@ -1572,12 +1557,9 @@
             // Store entities with modifications
             outState.putParcelable(KEY_EDIT_STATE, mState);
         }
-
         outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto);
         outState.putParcelable(KEY_VIEW_ID_GENERATOR, mViewIdGenerator);
-        if (mCurrentPhotoFile != null) {
-            outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile.toString());
-        }
+        outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile);
         outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin);
         outState.putBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN, mContactWritableForJoin);
         outState.putLong(KEY_SHOW_JOIN_SUGGESTIONS, mAggregationSuggestionsRawContactId);
@@ -1585,6 +1567,8 @@
         outState.putBoolean(KEY_NEW_LOCAL_PROFILE, mNewLocalProfile);
         outState.putBoolean(KEY_IS_USER_PROFILE, mIsUserProfile);
         outState.putInt(KEY_STATUS, mStatus);
+        outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos);
+
         super.onSaveInstanceState(outState);
     }
 
@@ -1594,27 +1578,13 @@
             mStatus = Status.EDITING;
         }
 
-        switch (requestCode) {
-            case REQUEST_CODE_PHOTO_PICKED_WITH_DATA: {
-                // Ignore failed requests
-                if (resultCode != Activity.RESULT_OK) return;
-                // As we are coming back to this view, the editor will be reloaded automatically,
-                // which will cause the photo that is set here to disappear. To prevent this,
-                // we remember to set a flag which is interpreted after loading.
-                // This photo is set here already to reduce flickering.
-                mPhoto = data.getParcelableExtra("data");
-                setPhoto(mRawContactIdRequestingPhoto, mPhoto);
-                mRawContactIdRequestingPhotoAfterLoad = mRawContactIdRequestingPhoto;
-                mRawContactIdRequestingPhoto = -1;
+        // See if the photo selection handler handles this result.
+        if (mCurrentPhotoHandler != null && mCurrentPhotoHandler.handlePhotoActivityResult(
+                requestCode, resultCode, data)) {
+            return;
+        }
 
-                break;
-            }
-            case REQUEST_CODE_CAMERA_WITH_DATA: {
-                // Ignore failed requests
-                if (resultCode != Activity.RESULT_OK) return;
-                doCropPhoto(mCurrentPhotoFile);
-                break;
-            }
+        switch (requestCode) {
             case REQUEST_CODE_JOIN: {
                 // Ignore failed requests
                 if (resultCode != Activity.RESULT_OK) return;
@@ -1650,13 +1620,23 @@
     /**
      * Sets the photo stored in mPhoto and writes it to the RawContact with the given id
      */
-    private void setPhoto(long rawContact, Bitmap photo) {
+    private void setPhoto(long rawContact, Bitmap photo, String photoFile) {
         BaseRawContactEditorView requestingEditor = getRawContactEditorView(rawContact);
+
+        if (photo == null || photo.getHeight() < 0 || photo.getWidth() < 0) {
+            // This is unexpected.
+            Log.w(TAG, "Invalid bitmap passed to setPhoto()");
+        }
+
         if (requestingEditor != null) {
             requestingEditor.setPhotoBitmap(photo);
         } else {
             Log.w(TAG, "The contact that requested the photo is no longer present.");
         }
+
+        final String croppedPhotoPath =
+                ContactPhotoUtils.pathForCroppedPhoto(mContext, mCurrentPhotoFile);
+        mUpdatedPhotos.putString(String.valueOf(rawContact), croppedPhotoPath);
     }
 
     /**
@@ -1679,19 +1659,31 @@
      * Returns true if there is currently more than one photo on screen.
      */
     private boolean hasMoreThanOnePhoto() {
-        int count = mContent.getChildCount();
         int countWithPicture = 0;
-        for (int i = 0; i < count; i++) {
-            final View childView = mContent.getChildAt(i);
-            if (childView instanceof BaseRawContactEditorView) {
-                final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
-                if (editor.hasSetPhoto()) {
+        final int numEntities = mState.size();
+        for (int i = 0; i < numEntities; i++) {
+            final EntityDelta entity = mState.get(i);
+            final ValuesDelta values = entity.getValues();
+            if (values.isVisible()) {
+                final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
+                if (primary != null && primary.getAsByteArray(Photo.PHOTO) != null) {
                     countWithPicture++;
-                    if (countWithPicture > 1) return true;
+                } else {
+                    final long rawContactId = values.getAsLong(RawContacts._ID);
+                    final String path = mUpdatedPhotos.getString(String.valueOf(rawContactId));
+                    if (path != null) {
+                        final File file = new File(path);
+                        if (file.exists()) {
+                            countWithPicture++;
+                        }
+                    }
+                }
+
+                if (countWithPicture > 1) {
+                    return true;
                 }
             }
         }
-
         return false;
     }
 
@@ -1703,7 +1695,7 @@
         @Override
         public Loader<ContactLoader.Result> onCreateLoader(int id, Bundle args) {
             mLoaderStartTime = SystemClock.elapsedRealtime();
-            return new ContactLoader(mContext, mLookupUri);
+            return new ContactLoader(mContext, mLookupUri, true);
         }
 
         @Override
@@ -1723,12 +1715,6 @@
             setData(data);
             final long setDataEndTime = SystemClock.elapsedRealtime();
 
-            // If we are coming back from the photo trimmer, this will be set.
-            if (mRawContactIdRequestingPhotoAfterLoad != -1) {
-                setPhoto(mRawContactIdRequestingPhotoAfterLoad, mPhoto);
-                mRawContactIdRequestingPhotoAfterLoad = -1;
-                mPhoto = null;
-            }
             Log.v(TAG, "Time needed for setting UI: " + (setDataEndTime-setDataStartTime));
         }
 
@@ -1754,6 +1740,7 @@
             bindGroupMetaData();
         }
 
+        @Override
         public void onLoaderReset(Loader<Cursor> loader) {
         }
     };
@@ -1773,111 +1760,104 @@
         save(SaveMode.SPLIT);
     }
 
-    private final class PhotoEditorListener
-            implements EditorListener, PhotoActionPopup.Listener {
+    /**
+     * Custom photo handler for the editor.  The inner listener that this creates also has a
+     * reference to the editor and acts as an {@link EditorListener}, and uses that editor to hold
+     * state information in several of the listener methods.
+     */
+    private final class PhotoHandler extends PhotoSelectionHandler {
+
+        final long mRawContactId;
         private final BaseRawContactEditorView mEditor;
-        private final boolean mAccountWritable;
+        private final PhotoActionListener mPhotoEditorListener;
 
-        private PhotoEditorListener(BaseRawContactEditorView editor, boolean accountWritable) {
+        public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
+                EntityDeltaList state) {
+            super(context, editor.getPhotoEditor(), photoMode, false, state);
             mEditor = editor;
-            mAccountWritable = accountWritable;
+            mRawContactId = editor.getRawContactId();
+            mPhotoEditorListener = new PhotoEditorListener();
         }
 
         @Override
-        public void onRequest(int request) {
-            if (!hasValidState()) return;
-
-            if (request == EditorListener.REQUEST_PICK_PHOTO) {
-                // Determine mode
-                final int mode;
-                if (mAccountWritable) {
-                    if (mEditor.hasSetPhoto()) {
-                        if (hasMoreThanOnePhoto()) {
-                            mode = PhotoActionPopup.MODE_PHOTO_ALLOW_PRIMARY;
-                        } else {
-                            mode = PhotoActionPopup.MODE_PHOTO_DISALLOW_PRIMARY;
-                        }
-                    } else {
-                        mode = PhotoActionPopup.MODE_NO_PHOTO;
-                    }
-                } else {
-                    if (mEditor.hasSetPhoto() && hasMoreThanOnePhoto()) {
-                        mode = PhotoActionPopup.MODE_READ_ONLY_ALLOW_PRIMARY;
-                    } else {
-                        // Read-only and either no photo or the only photo ==> no options
-                        return;
-                    }
-                }
-                PhotoActionPopup.createPopupMenu(mContext, mEditor.getPhotoEditor(), this, mode)
-                        .show();
-            }
+        public PhotoActionListener getListener() {
+            return mPhotoEditorListener;
         }
 
         @Override
-        public void onDeleteRequested(Editor removedEditor) {
-            // The picture cannot be deleted, it can only be removed, which is handled by
-            // onRemovePictureChosen()
+        public void startPhotoActivity(Intent intent, int requestCode, String photoFile) {
+            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
+            mCurrentPhotoHandler = this;
+            mStatus = Status.SUB_ACTIVITY;
+            mCurrentPhotoFile = photoFile;
+            ContactEditorFragment.this.startActivityForResult(intent, requestCode);
         }
 
-        /**
-         * User has chosen to set the selected photo as the (super) primary photo
-         */
-        @Override
-        public void onUseAsPrimaryChosen() {
-            // Set the IsSuperPrimary for each editor
-            int count = mContent.getChildCount();
-            for (int i = 0; i < count; i++) {
-                final View childView = mContent.getChildAt(i);
-                if (childView instanceof BaseRawContactEditorView) {
-                    final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
-                    final PhotoEditorView photoEditor = editor.getPhotoEditor();
-                    photoEditor.setSuperPrimary(editor == mEditor);
+        private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
+                implements EditorListener {
+
+            @Override
+            public void onRequest(int request) {
+                if (!hasValidState()) return;
+
+                if (request == EditorListener.REQUEST_PICK_PHOTO) {
+                    onClick(mEditor.getPhotoEditor());
                 }
             }
-        }
 
-        /**
-         * User has chosen to remove a picture
-         */
-        @Override
-        public void onRemovePictureChosen() {
-            mEditor.setPhotoBitmap(null);
-        }
-
-        /**
-         * Launches Camera to take a picture and store it in a file.
-         */
-        @Override
-        public void onTakePhotoChosen() {
-            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
-            try {
-                // Launch camera to take photo for selected contact
-                PHOTO_DIR.mkdirs();
-                mCurrentPhotoFile = new File(PHOTO_DIR, getPhotoFileName());
-                final Intent intent = getTakePickIntent(mCurrentPhotoFile);
-
-                mStatus = Status.SUB_ACTIVITY;
-                startActivityForResult(intent, REQUEST_CODE_CAMERA_WITH_DATA);
-            } catch (ActivityNotFoundException e) {
-                Toast.makeText(mContext, R.string.photoPickerNotFoundText,
-                        Toast.LENGTH_LONG).show();
+            @Override
+            public void onDeleteRequested(Editor removedEditor) {
+                // The picture cannot be deleted, it can only be removed, which is handled by
+                // onRemovePictureChosen()
             }
-        }
 
-        /**
-         * Launches Gallery to pick a photo.
-         */
-        @Override
-        public void onPickFromGalleryChosen() {
-            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
-            try {
-                // Launch picker to choose photo for selected contact
-                final Intent intent = getPhotoPickIntent();
-                mStatus = Status.SUB_ACTIVITY;
-                startActivityForResult(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA);
-            } catch (ActivityNotFoundException e) {
-                Toast.makeText(mContext, R.string.photoPickerNotFoundText,
-                        Toast.LENGTH_LONG).show();
+            /**
+             * User has chosen to set the selected photo as the (super) primary photo
+             */
+            @Override
+            public void onUseAsPrimaryChosen() {
+                // Set the IsSuperPrimary for each editor
+                int count = mContent.getChildCount();
+                for (int i = 0; i < count; i++) {
+                    final View childView = mContent.getChildAt(i);
+                    if (childView instanceof BaseRawContactEditorView) {
+                        final BaseRawContactEditorView editor =
+                                (BaseRawContactEditorView) childView;
+                        final PhotoEditorView photoEditor = editor.getPhotoEditor();
+                        photoEditor.setSuperPrimary(editor == mEditor);
+                    }
+                }
+                bindEditors();
+            }
+
+            /**
+             * User has chosen to remove a picture
+             */
+            @Override
+            public void onRemovePictureChosen() {
+                mEditor.setPhotoBitmap(null);
+
+                // Prevent bitmap from being restored if rotate the device.
+                // (only if we first chose a new photo before removing it)
+                mUpdatedPhotos.remove(String.valueOf(mRawContactId));
+                bindEditors();
+            }
+
+            @Override
+            public void onPhotoSelected(Bitmap bitmap) {
+                setPhoto(mRawContactId, bitmap, mCurrentPhotoFile);
+                mCurrentPhotoHandler = null;
+                bindEditors();
+            }
+
+            @Override
+            public String getCurrentPhotoFile() {
+                return mCurrentPhotoFile;
+            }
+
+            @Override
+            public void onPhotoSelectionDismissed() {
+                // Nothing to do.
             }
         }
     }
diff --git a/src/com/android/contacts/editor/ContactEditorUtils.java b/src/com/android/contacts/editor/ContactEditorUtils.java
index 05a041d..46006a0 100644
--- a/src/com/android/contacts/editor/ContactEditorUtils.java
+++ b/src/com/android/contacts/editor/ContactEditorUtils.java
@@ -19,6 +19,7 @@
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.AccountWithDataSet;
+import com.android.contacts.test.NeededForTesting;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
@@ -74,11 +75,13 @@
         return sInstance;
     }
 
+    @NeededForTesting
     void cleanupForTest() {
         mPrefs.edit().remove(KEY_DEFAULT_ACCOUNT).remove(KEY_KNOWN_ACCOUNTS)
                 .remove(KEY_ANYTHING_SAVED).apply();
     }
 
+    @NeededForTesting
     void removeDefaultAccountForTest() {
         mPrefs.edit().remove(KEY_DEFAULT_ACCOUNT).apply();
     }
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index 423ca94..1151afd 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -85,4 +85,13 @@
      * Clears all fields in this {@link Editor}.
      */
     public void clearAllFields();
+
+    /**
+     * Called internally when the user has added a new field.  This
+     * allows the appropriate editor UI to be presented immediately.
+     * For example, if a new "event" is added, a date-picker will
+     * immediately pop up.
+     */
+    public void editNewlyAddedField();
+
 }
diff --git a/src/com/android/contacts/editor/EditorAnimator.java b/src/com/android/contacts/editor/EditorAnimator.java
new file mode 100644
index 0000000..a16b425
--- /dev/null
+++ b/src/com/android/contacts/editor/EditorAnimator.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2012 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.contacts.editor;
+
+import com.android.contacts.util.SchedulingUtils;
+
+import com.google.common.collect.Lists;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.LinearLayout;
+
+import java.util.List;
+
+/**
+ * Configures animations for typical use-cases
+ */
+public class EditorAnimator {
+    private static EditorAnimator sInstance = new EditorAnimator();
+
+    public static  EditorAnimator getInstance() {
+        return sInstance;
+    }
+
+    /** Private constructor for singleton */
+    private EditorAnimator() { }
+
+    private AnimatorRunner mRunner = new AnimatorRunner();
+
+    public void removeEditorView(final View victim) {
+        mRunner.endOldAnimation();
+        final int offset = victim.getHeight();
+
+        final List<View> viewsToMove = getViewsBelowOf(victim);
+        final List<Animator> animators = Lists.newArrayList();
+
+        // Fade out
+        final ObjectAnimator fadeOutAnimator =
+                ObjectAnimator.ofFloat(victim, View.ALPHA, 1.0f, 0.0f);
+        fadeOutAnimator.setDuration(200);
+        animators.add(fadeOutAnimator);
+
+        // Translations
+        translateViews(animators, viewsToMove, 0.0f, -offset, 100, 200);
+
+        mRunner.run(animators, new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                // Clean up: Remove all the translations
+                for (int i = 0; i < viewsToMove.size(); i++) {
+                    final View view = viewsToMove.get(i);
+                    view.setTranslationY(0.0f);
+                }
+                // Remove our target view (if parent is null, we were run several times by quick
+                // fingers. Just ignore)
+                final ViewGroup victimParent = (ViewGroup) victim.getParent();
+                if (victimParent != null) {
+                    victimParent.removeView(victim);
+                }
+            }
+        });
+    }
+
+    public void expandOrganization(final View addOrganizationButton,
+            final ViewGroup organizationSectionViewContainer) {
+        mRunner.endOldAnimation();
+        // Make the new controls visible and do one layout pass (so that we can measure)
+        organizationSectionViewContainer.setVisibility(View.VISIBLE);
+        organizationSectionViewContainer.setAlpha(0.0f);
+        organizationSectionViewContainer.requestFocus();
+        SchedulingUtils.doAfterLayout(addOrganizationButton, new Runnable() {
+            @Override
+            public void run() {
+                // How many pixels extra do we need?
+                final int offset = organizationSectionViewContainer.getHeight() -
+                        addOrganizationButton.getHeight();
+
+                final List<Animator> animators = Lists.newArrayList();
+
+                // Fade out
+                final ObjectAnimator fadeOutAnimator = ObjectAnimator.ofFloat(
+                        addOrganizationButton, View.ALPHA, 1.0f, 0.0f);
+                fadeOutAnimator.setDuration(200);
+                animators.add(fadeOutAnimator);
+
+                // Translations
+                final List<View> viewsToMove = getViewsBelowOf(organizationSectionViewContainer);
+                translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200);
+
+                // Fade in
+                final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(
+                        organizationSectionViewContainer, View.ALPHA, 0.0f, 1.0f);
+                fadeInAnimator.setDuration(200);
+                fadeInAnimator.setStartDelay(200);
+                animators.add(fadeInAnimator);
+
+                mRunner.run(animators);
+            }
+        });
+    }
+
+    public void showAddFieldFooter(final View view) {
+        mRunner.endOldAnimation();
+        if (view.getVisibility() == View.VISIBLE) return;
+        // Make the new controls visible and do one layout pass (so that we can measure)
+        view.setVisibility(View.VISIBLE);
+        view.setAlpha(0.0f);
+        SchedulingUtils.doAfterLayout(view, new Runnable() {
+            @Override
+            public void run() {
+                // How many pixels extra do we need?
+                final int offset = view.getHeight();
+
+                final List<Animator> animators = Lists.newArrayList();
+
+                // Translations
+                final List<View> viewsToMove = getViewsBelowOf(view);
+                translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200);
+
+                // Fade in
+                final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(
+                        view, View.ALPHA, 0.0f, 1.0f);
+                fadeInAnimator.setDuration(200);
+                fadeInAnimator.setStartDelay(200);
+                animators.add(fadeInAnimator);
+
+                mRunner.run(animators);
+            }
+        });
+    }
+
+    public void hideAddFieldFooter(final View victim) {
+        mRunner.endOldAnimation();
+        if (victim.getVisibility() == View.GONE) return;
+        final int offset = victim.getHeight();
+
+        final List<View> viewsToMove = getViewsBelowOf(victim);
+        final List<Animator> animators = Lists.newArrayList();
+
+        // Fade out
+        final ObjectAnimator fadeOutAnimator =
+                ObjectAnimator.ofFloat(victim, View.ALPHA, 1.0f, 0.0f);
+        fadeOutAnimator.setDuration(200);
+        animators.add(fadeOutAnimator);
+
+        // Translations
+        translateViews(animators, viewsToMove, 0.0f, -offset, 100, 200);
+
+        // Combine
+        mRunner.run(animators, new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                // Clean up: Remove all the translations
+                for (int i = 0; i < viewsToMove.size(); i++) {
+                    final View view = viewsToMove.get(i);
+                    view.setTranslationY(0.0f);
+                }
+
+                // Restore alpha (for next time), but hide the view for good now
+                victim.setAlpha(1.0f);
+                victim.setVisibility(View.GONE);
+            }
+        });
+    }
+
+    /**
+     * Creates a translation-animation for the given views
+     */
+    private static void translateViews(List<Animator> animators, List<View> views, float fromY,
+            float toY, int startDelay, int duration) {
+        for (int i = 0; i < views.size(); i++) {
+            final View child = views.get(i);
+            final ObjectAnimator translateAnimator =
+                    ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, fromY, toY);
+            translateAnimator.setStartDelay(startDelay);
+            translateAnimator.setDuration(duration);
+            animators.add(translateAnimator);
+        }
+    }
+
+    /**
+     * Traverses up the view hierarchy and returns all views below this item. Stops
+     * once a parent is not a vertical LinearLayout
+     *
+     * @return List of views that are below the given view. Empty list if parent of view is null.
+     */
+    private static List<View> getViewsBelowOf(View view) {
+        final ViewGroup victimParent = (ViewGroup) view.getParent();
+        final List<View> result = Lists.newArrayList();
+        if (victimParent != null) {
+            final int index = victimParent.indexOfChild(view);
+            getViewsBelowOfRecursive(result, victimParent, index + 1);
+        }
+        return result;
+    }
+
+    private static void getViewsBelowOfRecursive(List<View> result, ViewGroup container,
+            int index) {
+        for (int i = index; i < container.getChildCount(); i++) {
+            result.add(container.getChildAt(i));
+        }
+
+        final ViewParent parent = container.getParent();
+        if (parent instanceof LinearLayout) {
+            final LinearLayout parentLayout = (LinearLayout) parent;
+            if (parentLayout.getOrientation() == LinearLayout.VERTICAL) {
+                int containerIndex = parentLayout.indexOfChild(container);
+                getViewsBelowOfRecursive(result, parentLayout, containerIndex+1);
+            }
+        }
+    }
+
+    /**
+     * Keeps a reference to the last animator, so that we can end that early if the user
+     * quickly pushes buttons. Removes the reference once the animation has finished
+     */
+    /* package */ static class AnimatorRunner extends AnimatorListenerAdapter {
+        private Animator mLastAnimator;
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mLastAnimator = null;
+        }
+
+        public void run(List<Animator> animators) {
+            run(animators, null);
+        }
+
+        public void run(List<Animator> animators, AnimatorListener listener) {
+            final AnimatorSet set = new AnimatorSet();
+            set.playTogether(animators);
+            if (listener != null) set.addListener(listener);
+            set.addListener(this);
+            mLastAnimator = set;
+            set.start();
+        }
+
+        public void endOldAnimation() {
+            if (mLastAnimator != null) {
+                mLastAnimator.end();
+            }
+        }
+    }
+}
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 4a5a502..538d4dc 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -29,7 +29,6 @@
 
 import android.app.Dialog;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.text.TextUtils;
@@ -92,6 +91,11 @@
     }
 
     @Override
+    public void editNewlyAddedField() {
+        showDialog(R.id.dialog_event_date_picker);
+    }
+
+    @Override
     protected void requestFocusForFirstEditField() {
         mDateView.requestFocus();
     }
@@ -131,7 +135,9 @@
 
     @Override
     public boolean isEmpty() {
-        return TextUtils.isEmpty(mDateView.getText());
+        final EditField editField = getKind().fieldList.get(0);
+        final String column = editField.column;
+        return TextUtils.isEmpty(getEntry().getAsString(column));
     }
 
     @Override
@@ -231,10 +237,11 @@
                 final Calendar outCalendar =
                         Calendar.getInstance(DateUtils.UTC_TIMEZONE, Locale.US);
 
-                // If no year specified, set it to 1900. The format string will ignore that year
+                // If no year specified, set it to 2000 (we could pick any leap year here).
+                // The format string will ignore that year.
                 // For formats other than Exchange, the time of the day is ignored
                 outCalendar.clear();
-                outCalendar.set(year == 0 ? 1900 : year, monthOfYear, dayOfMonth,
+                outCalendar.set(year == 0 ? 2000 : year, monthOfYear, dayOfMonth,
                         DEFAULT_HOUR, 0, 0);
 
                 final String resultString;
@@ -243,6 +250,7 @@
                 } else {
                     resultString = kind.dateFormatWithYear.format(outCalendar.getTime());
                 }
+
                 onFieldChanged(column, resultString);
                 rebuildDateView();
             }
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index ab52e0b..a8e8d03 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -19,6 +19,7 @@
 import com.android.contacts.GroupMetaDataLoader;
 import com.android.contacts.R;
 import com.android.contacts.interactions.GroupCreationDialogFragment;
+import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCreatedListener;
 import com.android.contacts.model.DataKind;
 import com.android.contacts.model.EntityDelta;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
@@ -27,7 +28,6 @@
 
 import android.app.Activity;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -36,9 +36,11 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
+import android.widget.CheckedTextView;
 import android.widget.LinearLayout;
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
@@ -84,19 +86,61 @@
         }
     }
 
+    /**
+     * Extends the array adapter to show checkmarks on all but the last list item for
+     * the group membership popup.  Note that this is highly specific to the fact that the
+     * group_membership_list_item.xml is a CheckedTextView object.
+     */
+    private class GroupMembershipAdapter<T> extends ArrayAdapter<T> {
+
+        public GroupMembershipAdapter(Context context, int textViewResourceId) {
+            super(context, textViewResourceId);
+        }
+
+        public boolean getItemIsCheckable(int position) {
+            // Item is checkable if it is NOT the last one in the list
+            return position != getCount()-1;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return getItemIsCheckable(position) ? 0 : 1;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 2;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final View itemView = super.getView(position, convertView, parent);
+
+            // Hide the checkable drawable.  This assumes that the item views
+            // are CheckedTextView objects
+            final CheckedTextView checkedTextView = (CheckedTextView)itemView;
+            if (!getItemIsCheckable(position)) {
+                checkedTextView.setCheckMarkDrawable(null);
+            }
+
+            return checkedTextView;
+        }
+    }
+
     private EntityDelta mState;
     private Cursor mGroupMetaData;
     private String mAccountName;
     private String mAccountType;
     private String mDataSet;
     private TextView mGroupList;
-    private ArrayAdapter<GroupSelectionItem> mAdapter;
+    private GroupMembershipAdapter<GroupSelectionItem> mAdapter;
     private long mDefaultGroupId;
     private long mFavoritesGroupId;
     private ListPopupWindow mPopup;
     private DataKind mKind;
     private boolean mDefaultGroupVisibilityKnown;
     private boolean mDefaultGroupVisible;
+    private boolean mCreatedNewGroup;
 
     private String mNoGroupString;
     private int mPrimaryTextColor;
@@ -136,6 +180,21 @@
     public void setGroupMetaData(Cursor groupMetaData) {
         this.mGroupMetaData = groupMetaData;
         updateView();
+        // Open up the list of groups if a new group was just created.
+        if (mCreatedNewGroup) {
+            mCreatedNewGroup = false;
+            onClick(this); // This causes the popup to open.
+            if (mPopup != null) {
+                // Ensure that the newly created group is checked.
+                int position = mAdapter.getCount() - 2;
+                ListView listView = mPopup.getListView();
+                if (!listView.isItemChecked(position)) {
+                    // Newly created group is not checked, so check it.
+                    listView.setItemChecked(position, true);
+                    onItemClick(listView, null, position, listView.getItemIdAtPosition(position));
+                }
+            }
+        }
     }
 
     public void setState(EntityDelta state) {
@@ -145,6 +204,7 @@
         mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
         mDataSet = values.getAsString(RawContacts.DATA_SET);
         mDefaultGroupVisibilityKnown = false;
+        mCreatedNewGroup = false;
         updateView();
     }
 
@@ -227,7 +287,7 @@
             return;
         }
 
-        mAdapter = new ArrayAdapter<GroupSelectionItem>(
+        mAdapter = new GroupMembershipAdapter<GroupSelectionItem>(
                 getContext(), R.layout.group_membership_list_item);
 
         mGroupMetaData.moveToPosition(-1);
@@ -254,6 +314,7 @@
         mPopup.setAnchorView(mGroupList);
         mPopup.setAdapter(mAdapter);
         mPopup.setModal(true);
+        mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
         mPopup.show();
 
         ListView listView = mPopup.getListView();
@@ -356,7 +417,16 @@
         }
 
         GroupCreationDialogFragment.show(
-                ((Activity) getContext()).getFragmentManager(), mAccountType, mAccountName,
-                mDataSet);
+                ((Activity) getContext()).getFragmentManager(),
+                mAccountType,
+                mAccountName,
+                mDataSet,
+                new OnGroupCreatedListener() {
+                    @Override
+                    public void onGroupCreated() {
+                        mCreatedNewGroup = true;
+                    }
+                });
     }
+
 }
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index eb8a0a7..b474956 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -24,6 +24,7 @@
 import com.android.contacts.model.EntityModifier;
 
 import android.content.Context;
+import android.provider.ContactsContract.Data;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
@@ -56,6 +57,8 @@
 
     private LayoutInflater mInflater;
 
+    private final ArrayList<Runnable> mRunWhenWindowFocused = new ArrayList<Runnable>(1);
+
     public KindSectionView(Context context) {
         this(context, null);
     }
@@ -110,13 +113,18 @@
     public void onDeleteRequested(Editor editor) {
         // If there is only 1 editor in the section, then don't allow the user to delete it.
         // Just clear the fields in the editor.
+        final boolean animate;
         if (getEditorCount() == 1) {
             editor.clearAllFields();
+            animate = true;
         } else {
             // Otherwise it's okay to delete this {@link Editor}
             editor.deleteEditor();
+
+            // This is already animated, don't do anything further here
+            animate = false;
         }
-        updateAddFooterVisible();
+        updateAddFooterVisible(animate);
     }
 
     @Override
@@ -124,7 +132,7 @@
         // If a field has become empty or non-empty, then check if another row
         // can be added dynamically.
         if (request == FIELD_TURNED_EMPTY || request == FIELD_TURNED_NON_EMPTY) {
-            updateAddFooterVisible();
+            updateAddFooterVisible(true);
         }
     }
 
@@ -143,7 +151,7 @@
         mTitle.setText(mTitleString);
 
         rebuildFromState();
-        updateAddFooterVisible();
+        updateAddFooterVisible(false);
         updateSectionVisible();
     }
 
@@ -223,18 +231,26 @@
         setVisibility(getEditorCount() != 0 ? VISIBLE : GONE);
     }
 
-    protected void updateAddFooterVisible() {
+    protected void updateAddFooterVisible(boolean animate) {
         if (!mReadOnly && (mKind.typeOverallMax != 1)) {
             // First determine whether there are any existing empty editors.
             updateEmptyEditors();
             // If there are no existing empty editors and it's possible to add
             // another field, then make the "add footer" field visible.
             if (!hasEmptyEditor() && EntityModifier.canInsert(mState, mKind)) {
-                mAddFieldFooter.setVisibility(View.VISIBLE);
+                if (animate) {
+                    EditorAnimator.getInstance().showAddFieldFooter(mAddFieldFooter);
+                } else {
+                    mAddFieldFooter.setVisibility(View.VISIBLE);
+                }
                 return;
             }
         }
-        mAddFieldFooter.setVisibility(View.GONE);
+        if (animate) {
+            EditorAnimator.getInstance().hideAddFieldFooter(mAddFieldFooter);
+        } else {
+            mAddFieldFooter.setVisibility(View.GONE);
+        }
     }
 
     /**
@@ -291,6 +307,46 @@
         return true;
     }
 
+    /**
+     * Extends superclass implementation to also run tasks
+     * enqueued by {@link #runWhenWindowFocused}.
+     */
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+        if (hasWindowFocus) {
+            for (Runnable r: mRunWhenWindowFocused) {
+                r.run();
+            }
+            mRunWhenWindowFocused.clear();
+        }
+    }
+
+    /**
+     * Depending on whether we are in the currently-focused window, either run
+     * the argument immediately, or stash it until our window becomes focused.
+     */
+    private void runWhenWindowFocused(Runnable r) {
+        if (hasWindowFocus()) {
+            r.run();
+        } else {
+            mRunWhenWindowFocused.add(r);
+        }
+    }
+
+    /**
+     * Simple wrapper around {@link #runWhenWindowFocused}
+     * to ensure that it runs in the UI thread.
+     */
+    private void postWhenWindowFocused(final Runnable r) {
+        post(new Runnable() {
+            @Override
+            public void run() {
+                runWhenWindowFocused(r);
+            }
+        });
+    }
+
     public void addItem() {
         ValuesDelta values = null;
         // If this is a list, we can freely add. If not, only allow adding the first.
@@ -312,13 +368,15 @@
         }
 
         final View newField = createEditorView(values);
-        post(new Runnable() {
-
-            @Override
-            public void run() {
-                newField.requestFocus();
-            }
-        });
+        if (newField instanceof Editor) {
+            postWhenWindowFocused(new Runnable() {
+                @Override
+                public void run() {
+                    newField.requestFocus();
+                    ((Editor)newField).editNewlyAddedField();
+                }
+            });
+        }
 
         // Hide the "add field" footer because there is now a blank field.
         mAddFieldFooter.setVisibility(View.GONE);
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 2a97f4c..6f10fa2 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -31,20 +31,24 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Entity;
-import android.graphics.Color;
+import android.content.DialogInterface.OnShowListener;
 import android.os.Bundle;
 import android.os.Handler;
+import android.text.Editable;
 import android.text.TextUtils;
+import android.text.TextWatcher;
 import android.text.TextUtils.TruncateAt;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
+import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -128,6 +132,8 @@
     protected void onFinishInflate() {
 
         mLabel = (Spinner) findViewById(R.id.spinner);
+        // Turn off the Spinner's own state management. We do this ourselves on rotation
+        mLabel.setId(View.NO_ID);
         mLabel.setOnItemSelectedListener(mSpinnerListener);
 
         mDelete = (ImageView) findViewById(R.id.delete_button);
@@ -177,10 +183,7 @@
         mEntry.markDeleted();
 
         // Remove the view
-        final ViewGroup parent = (ViewGroup)getParent();
-        if (parent != null) {
-            parent.removeView(LabeledEditorView.this);
-        }
+        EditorAnimator.getInstance().removeEditorView(this);
     }
 
     public boolean isReadOnly() {
@@ -289,7 +292,17 @@
         }
 
         // Field changes are saved directly
+        saveValue(column, value);
+
+        // Notify listener if applicable
+        notifyEditorListener();
+    }
+
+    protected void saveValue(String column, String value) {
         mEntry.put(column, value);
+    }
+
+    protected void notifyEditorListener() {
         if (mListener != null) {
             mListener.onRequest(EditorListener.FIELD_CHANGED);
         }
@@ -368,20 +381,21 @@
      */
     private Dialog createCustomDialog() {
         final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+        final LayoutInflater layoutInflater = LayoutInflater.from(builder.getContext());
         builder.setTitle(R.string.customLabelPickerTitle);
 
-        final EditText customType = new EditText(builder.getContext());
-        customType.setId(R.id.custom_dialog_content);
-        customType.setInputType(INPUT_TYPE_CUSTOM);
-        customType.setSaveEnabled(true);
-        customType.requestFocus();
+        final View view = layoutInflater.inflate(R.layout.contact_editor_label_name_dialog, null);
+        final EditText editText = (EditText) view.findViewById(R.id.custom_dialog_content);
+        editText.setInputType(INPUT_TYPE_CUSTOM);
+        editText.setSaveEnabled(true);
 
-        builder.setView(customType);
+        builder.setView(view);
+        editText.requestFocus();
 
         builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
             @Override
             public void onClick(DialogInterface dialog, int which) {
-                final String customText = customType.getText().toString().trim();
+                final String customText = editText.getText().toString().trim();
                 if (ContactsUtils.isGraphic(customText)) {
                     final List<EditType> allTypes =
                             EntityModifier.getValidTypes(mState, mKind, null);
@@ -405,7 +419,36 @@
 
         builder.setNegativeButton(android.R.string.cancel, null);
 
-        return builder.create();
+        final AlertDialog dialog = builder.create();
+        dialog.setOnShowListener(new OnShowListener() {
+            @Override
+            public void onShow(DialogInterface dialogInterface) {
+                updateCustomDialogOkButtonState(dialog, editText);
+            }
+        });
+        editText.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                updateCustomDialogOkButtonState(dialog, editText);
+            }
+        });
+        dialog.getWindow().setSoftInputMode(
+                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+
+        return dialog;
+    }
+
+    /* package */ void updateCustomDialogOkButtonState(AlertDialog dialog, EditText editText) {
+        final Button okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
+        okButton.setEnabled(!TextUtils.isEmpty(editText.getText().toString().trim()));
     }
 
     /**
diff --git a/src/com/android/contacts/editor/PhotoActionPopup.java b/src/com/android/contacts/editor/PhotoActionPopup.java
index cca6f9d..a27dd8a 100644
--- a/src/com/android/contacts/editor/PhotoActionPopup.java
+++ b/src/com/android/contacts/editor/PhotoActionPopup.java
@@ -29,15 +29,46 @@
 import java.util.ArrayList;
 
 /**
- * Shows a popup asking the user what to do for a photo. The result is pased back to the Listener
+ * Shows a popup asking the user what to do for a photo. The result is passed back to the Listener
  */
 public class PhotoActionPopup {
     public static final String TAG = "PhotoActionPopup";
 
-    public static final int MODE_NO_PHOTO = 0;
-    public static final int MODE_READ_ONLY_ALLOW_PRIMARY = 1;
-    public static final int MODE_PHOTO_DISALLOW_PRIMARY = 2;
-    public static final int MODE_PHOTO_ALLOW_PRIMARY = 3;
+    /**
+     * Bitmask flags to specify which actions should be presented to the user.
+     */
+    public static final class Flags {
+        /** If set, show choice to use as primary photo. */
+        public static final int ALLOW_PRIMARY = 1;
+        /** If set, show choice to remove photo. */
+        public static final int REMOVE_PHOTO = 2;
+        /** If set, show choices to take a picture with the camera, or pick one from the gallery. */
+        public static final int TAKE_OR_PICK_PHOTO = 4;
+        /**
+         *  If set, modifies the wording in the choices for TAKE_OR_PICK_PHOTO
+         *  to emphasize that the existing photo will be replaced.
+         */
+        public static final int TAKE_OR_PICK_PHOTO_REPLACE_WORDING = 8;
+    }
+
+    /**
+     * Convenient combinations of commonly-used flags (see {@link Flags}).
+     */
+    public static final class Modes {
+        public static final int NO_PHOTO =
+                Flags.TAKE_OR_PICK_PHOTO;
+        public static final int READ_ONLY_ALLOW_PRIMARY =
+                Flags.ALLOW_PRIMARY;
+        public static final int PHOTO_DISALLOW_PRIMARY =
+                Flags.REMOVE_PHOTO |
+                Flags.TAKE_OR_PICK_PHOTO |
+                Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING;
+        public static final int PHOTO_ALLOW_PRIMARY =
+                Flags.ALLOW_PRIMARY |
+                Flags.REMOVE_PHOTO |
+                Flags.TAKE_OR_PICK_PHOTO |
+                Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING;
+    }
 
     public static ListPopupWindow createPopupMenu(Context context, View anchorView,
             final Listener listener, int mode) {
@@ -45,29 +76,26 @@
         // if there are NO choices (e.g. a read-only picture is already super-primary)
         final ArrayList<ChoiceListItem> choices = new ArrayList<ChoiceListItem>(4);
         // Use as Primary
-        if (mode == MODE_PHOTO_ALLOW_PRIMARY || mode == MODE_READ_ONLY_ALLOW_PRIMARY) {
+        if ((mode & Flags.ALLOW_PRIMARY) > 0) {
             choices.add(new ChoiceListItem(ChoiceListItem.ID_USE_AS_PRIMARY,
                     context.getString(R.string.use_photo_as_primary)));
         }
         // Remove
-        if (mode == MODE_PHOTO_DISALLOW_PRIMARY || mode == MODE_PHOTO_ALLOW_PRIMARY) {
+        if ((mode & Flags.REMOVE_PHOTO) > 0) {
             choices.add(new ChoiceListItem(ChoiceListItem.ID_REMOVE,
                     context.getString(R.string.removePhoto)));
         }
-        // Take photo (if there is already a photo, it says "Take new photo")
-        if (mode == MODE_NO_PHOTO || mode == MODE_PHOTO_ALLOW_PRIMARY
-                || mode == MODE_PHOTO_DISALLOW_PRIMARY) {
-            final int resId = mode == MODE_NO_PHOTO ? R.string.take_photo :R.string.take_new_photo;
-            choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO,
-                    context.getString(resId)));
+        // Take photo or pick one from the gallery.  Wording differs if there is already a photo.
+        if ((mode & Flags.TAKE_OR_PICK_PHOTO) > 0) {
+            boolean replace = (mode & Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING) > 0;
+            final int takePhotoResId = replace ? R.string.take_new_photo : R.string.take_photo;
+            final String takePhotoString = context.getString(takePhotoResId);
+            final int pickPhotoResId = replace ? R.string.pick_new_photo : R.string.pick_photo;
+            final String pickPhotoString = context.getString(pickPhotoResId);
+            choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO, takePhotoString));
+            choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO, pickPhotoString));
         }
-        // Select from Gallery (or "Select new from Gallery")
-        if (mode == MODE_NO_PHOTO || mode == MODE_PHOTO_ALLOW_PRIMARY
-                || mode == MODE_PHOTO_DISALLOW_PRIMARY) {
-            final int resId = mode == MODE_NO_PHOTO ? R.string.pick_photo :R.string.pick_new_photo;
-            choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO,
-                    context.getString(resId)));
-        }
+
         final ListAdapter adapter = new ArrayAdapter<ChoiceListItem>(context,
                 R.layout.select_dialog_item, choices);
 
@@ -76,8 +104,6 @@
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 final ChoiceListItem choice = choices.get(position);
-                listPopupWindow.dismiss();
-
                 switch (choice.getId()) {
                     case ChoiceListItem.ID_USE_AS_PRIMARY:
                         listener.onUseAsPrimaryChosen();
@@ -92,16 +118,21 @@
                         listener.onPickFromGalleryChosen();
                         break;
                 }
+
+                listPopupWindow.dismiss();
             }
         };
 
         listPopupWindow.setAnchorView(anchorView);
         listPopupWindow.setAdapter(adapter);
         listPopupWindow.setOnItemClickListener(clickListener);
-        listPopupWindow.setWidth(context.getResources().getDimensionPixelSize(
-                R.dimen.photo_action_popup_width));
         listPopupWindow.setModal(true);
         listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
+        final int minWidth = context.getResources().getDimensionPixelSize(
+                R.dimen.photo_action_popup_min_width);
+        if (anchorView.getWidth() < minWidth) {
+            listPopupWindow.setWidth(minWidth);
+        }
         return listPopupWindow;
     }
 
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 086b07f..955554c 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -16,35 +16,33 @@
 
 package com.android.contacts.editor;
 
+import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.model.DataKind;
 import com.android.contacts.model.EntityDelta;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.util.ContactPhotoUtils;
 
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import android.widget.LinearLayout;
 
 /**
  * Simple editor for {@link Photo}.
  */
-public class PhotoEditorView extends FrameLayout implements Editor {
-    private static final String TAG = "PhotoEditorView";
+public class PhotoEditorView extends LinearLayout implements Editor {
 
     private ImageView mPhotoImageView;
     private View mFrameView;
 
     private ValuesDelta mEntry;
     private EditorListener mListener;
+    private View mTriangleAffordance;
 
     private boolean mHasSetPhoto = false;
     private boolean mReadOnly;
@@ -63,10 +61,17 @@
         mFrameView.setEnabled(enabled);
     }
 
+    @Override
+    public void editNewlyAddedField() {
+        // Never called, since the user never adds a new photo-editor;
+        // you can only change the picture in an existing editor.
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        mTriangleAffordance = findViewById(R.id.photo_triangle_affordance);
         mPhotoImageView = (ImageView) findViewById(R.id.photo);
         mFrameView = findViewById(R.id.frame);
         mFrameView.setOnClickListener(new OnClickListener() {
@@ -132,25 +137,24 @@
             return;
         }
 
-        final int size = photo.getWidth() * photo.getHeight() * 4;
-        final ByteArrayOutputStream out = new ByteArrayOutputStream(size);
+        mPhotoImageView.setImageBitmap(photo);
+        mFrameView.setEnabled(isEnabled());
+        mHasSetPhoto = true;
+        mEntry.setFromTemplate(false);
 
-        try {
-            photo.compress(Bitmap.CompressFormat.PNG, 100, out);
-            out.flush();
-            out.close();
+        // When the user chooses a new photo mark it as super primary
+        mEntry.put(Photo.IS_SUPER_PRIMARY, 1);
 
-            mEntry.put(Photo.PHOTO, out.toByteArray());
-            mPhotoImageView.setImageBitmap(photo);
-            mFrameView.setEnabled(isEnabled());
-            mHasSetPhoto = true;
-            mEntry.setFromTemplate(false);
-
-            // When the user chooses a new photo mark it as super primary
-            mEntry.put(Photo.IS_SUPER_PRIMARY, 1);
-        } catch (IOException e) {
-            Log.w(TAG, "Unable to serialize photo: " + e.toString());
-        }
+        // Even though high-res photos cannot be saved by passing them via
+        // an EntityDeltaList (since they cause the Bundle size limit to be
+        // exceeded), we still pass a low-res thumbnail. This simplifies
+        // code all over the place, because we don't have to test whether
+        // there is a change in EITHER the delta-list OR a changed photo...
+        // this way, there is always a change in the delta-list.
+        final int size = ContactsUtils.getThumbnailSize(getContext());
+        final Bitmap scaled = Bitmap.createScaledBitmap(photo, size, size, false);
+        final byte[] compressed = ContactPhotoUtils.compressBitmap(scaled);
+        if (compressed != null) mEntry.put(Photo.PHOTO, compressed);
     }
 
     /**
@@ -172,6 +176,10 @@
     @Override
     public void setEditorListener(EditorListener listener) {
         mListener = listener;
+
+        final boolean isPushable = listener != null;
+        mTriangleAffordance.setVisibility(isPushable ? View.VISIBLE : View.INVISIBLE);
+        mFrameView.setVisibility(isPushable ? View.VISIBLE : View.INVISIBLE);
     }
 
     @Override
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index c9c6699..cb5e838 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -280,9 +280,8 @@
                         public void onClick(View v) {
                             // Once the user expands the organization field, the user cannot
                             // collapse them again.
-                            addOrganizationButton.setVisibility(View.GONE);
-                            organizationSectionViewContainer.setVisibility(View.VISIBLE);
-                            organizationSectionViewContainer.requestFocus();
+                            EditorAnimator.getInstance().expandOrganization(addOrganizationButton,
+                                    organizationSectionViewContainer);
                         }
                     });
 
@@ -307,6 +306,9 @@
 
         addToDefaultGroupIfNeeded();
 
+
+        final int sectionCount = getSectionViewsWithoutFields().size();
+        mAddFieldButton.setVisibility(sectionCount > 0 ? View.VISIBLE : View.GONE);
         mAddFieldButton.setEnabled(isEnabled());
     }
 
@@ -405,12 +407,14 @@
         return mRawContactId;
     }
 
-    private void showAddInformationPopupWindow() {
+    /**
+     * Return a list of KindSectionViews that have no fields yet...
+     * these are candidates to have fields added in
+     * {@link #showAddInformationPopupWindow()}
+     */
+    private ArrayList<KindSectionView> getSectionViewsWithoutFields() {
         final ArrayList<KindSectionView> fields =
                 new ArrayList<KindSectionView>(mFields.getChildCount());
-
-        final PopupMenu popupMenu = new PopupMenu(getContext(), mAddFieldButton);
-        final Menu menu = popupMenu.getMenu();
         for (int i = 0; i < mFields.getChildCount(); i++) {
             View child = mFields.getChildAt(i);
             if (child instanceof KindSectionView) {
@@ -434,10 +438,19 @@
                     continue;
                 }
 
-                menu.add(Menu.NONE, fields.size(), Menu.NONE, sectionView.getTitle());
                 fields.add(sectionView);
             }
         }
+        return fields;
+    }
+
+    private void showAddInformationPopupWindow() {
+        final ArrayList<KindSectionView> fields = getSectionViewsWithoutFields();
+        final PopupMenu popupMenu = new PopupMenu(getContext(), mAddFieldButton);
+        final Menu menu = popupMenu.getMenu();
+        for (int i = 0; i < fields.size(); i++) {
+            menu.add(Menu.NONE, i, Menu.NONE, fields.get(i).getTitle());
+        }
 
         popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
             @Override
@@ -449,6 +462,13 @@
                 } else {
                     view.addItem();
                 }
+
+                // If this was the last section without an entry, we just added one, and therefore
+                // there's no reason to show the button.
+                if (fields.size() == 1) {
+                    mAddFieldButton.setVisibility(View.GONE);
+                }
+
                 return true;
             }
         });
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index 2cc5d98..58474ef 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -55,7 +55,6 @@
         implements OnClickListener {
     private LayoutInflater mInflater;
 
-    private View mPhotoStub;
     private TextView mName;
     private Button mEditExternallyButton;
     private ViewGroup mGeneral;
@@ -96,8 +95,6 @@
         mInflater = (LayoutInflater)getContext().getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
 
-        mPhotoStub = findViewById(R.id.stub_photo);
-
         mName = (TextView) findViewById(R.id.read_only_name);
         mEditExternallyButton = (Button) findViewById(R.id.button_edit_externally);
         mEditExternallyButton.setOnClickListener(this);
@@ -177,13 +174,6 @@
             setHasPhotoEditor(hasPhotoEditor);
             primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
             getPhotoEditor().setValues(kind, primary, state, !type.areContactsWritable(), vig);
-            if (!hasPhotoEditor || !getPhotoEditor().hasSetPhoto()) {
-                mPhotoStub.setVisibility(View.GONE);
-            } else {
-                mPhotoStub.setVisibility(View.VISIBLE);
-            }
-        } else {
-            mPhotoStub.setVisibility(View.VISIBLE);
         }
 
         // Name
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 6911628..af1b3cf 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -77,11 +77,12 @@
         if (!isFieldChanged(column, value)) {
             return;
         }
-        super.onFieldChanged(column, value);
 
+        // First save the new value for the column.
+        saveValue(column, value);
         mChanged = true;
 
-        // Make sure the display name and the structured name are synced
+        // Next make sure the display name and the structured name are synced
         if (hasShortAndLongForms()) {
             if (areOptionalFieldsVisible()) {
                 rebuildFullName(getValues());
@@ -89,6 +90,10 @@
                 rebuildStructuredName(getValues());
             }
         }
+
+        // Then notify the listener, which will rely on the display and structured names to be
+        // synced (in order to provide aggregate suggestions).
+        notifyEditorListener();
     }
 
     @Override
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 0919006..a1f67a8 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -22,40 +22,36 @@
 import com.android.contacts.model.DataKind;
 import com.android.contacts.model.EntityDelta;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.util.NameConverter;
 import com.android.contacts.util.PhoneNumberFormatter;
 
 import android.content.Context;
 import android.content.Entity;
 import android.graphics.Rect;
-import android.graphics.Typeface;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.telephony.PhoneNumberFormattingTextWatcher;
 import android.text.Editable;
 import android.text.InputType;
-import android.text.Spannable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
-import android.text.style.StyleSpan;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import java.util.Map;
-
 /**
  * Simple editor that handles labels and any {@link EditField} defined for the
  * entry. Uses {@link ValuesDelta} to read any existing {@link Entity} values,
  * and to correctly write any changes values.
  */
 public class TextFieldsEditorView extends LabeledEditorView {
+    private static final String TAG = TextFieldsEditorView.class.getSimpleName();
+
     private EditText[] mFieldEditTexts = null;
     private ViewGroup mFields = null;
     private View mExpansionViewContainer;
@@ -113,6 +109,22 @@
     }
 
     @Override
+    public void editNewlyAddedField() {
+        // Some editors may have multiple fields (eg: first-name/last-name), but since the user
+        // has not selected a particular one, it is reasonable to simply pick the first.
+        final View editor = mFields.getChildAt(0);
+
+        // Show the soft-keyboard.
+        InputMethodManager imm =
+                (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (imm != null) {
+            if (!imm.showSoftInput(editor, InputMethodManager.SHOW_IMPLICIT)) {
+                Log.w(TAG, "Failed to show soft input method.");
+            }
+        }
+    }
+
+    @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
 
diff --git a/src/com/android/contacts/format/FormatUtils.java b/src/com/android/contacts/format/FormatUtils.java
index 4b076cf..82bf78d 100644
--- a/src/com/android/contacts/format/FormatUtils.java
+++ b/src/com/android/contacts/format/FormatUtils.java
@@ -28,6 +28,8 @@
  * Assorted utility methods related to text formatting in Contacts.
  */
 public class FormatUtils {
+    private static final char LEFT_TO_RIGHT_EMBEDDING = '\u202A';
+    private static final char POP_DIRECTIONAL_FORMATTING = '\u202C';
 
     /**
      * Finds the earliest point in buffer1 at which the first part of buffer2 matches.  For example,
@@ -180,4 +182,13 @@
 
         return -1;
     }
+
+    /** Returns the given text, forced to be left-to-right. */
+    public static CharSequence forceLeftToRight(CharSequence text) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(LEFT_TO_RIGHT_EMBEDDING);
+        sb.append(text);
+        sb.append(POP_DIRECTIONAL_FORMATTING);
+        return sb.toString();
+    }
 }
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index f0e4175..9e19735 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -23,6 +23,7 @@
 import com.android.contacts.interactions.GroupDeletionDialogFragment;
 import com.android.contacts.list.ContactTileAdapter;
 import com.android.contacts.list.ContactTileAdapter.DisplayType;
+import com.android.contacts.list.ContactTileView;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
 
@@ -42,6 +43,7 @@
 import android.os.Bundle;
 import android.provider.ContactsContract.Groups;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -189,6 +191,10 @@
         mShowGroupActionInActionBar = show;
     }
 
+    public Uri getGroupUri() {
+        return mGroupUri;
+    }
+
     /**
      * Start the loader to retrieve the metadata for this group.
      */
@@ -203,13 +209,24 @@
         getLoaderManager().restartLoader(LOADER_MEMBERS, null, mGroupMemberListLoaderListener);
     }
 
-    private final ContactTileAdapter.Listener mContactTileListener =
-            new ContactTileAdapter.Listener() {
+    private final ContactTileView.Listener mContactTileListener =
+            new ContactTileView.Listener() {
 
         @Override
         public void onContactSelected(Uri contactUri, Rect targetRect) {
             mListener.onContactSelected(contactUri);
         }
+
+        @Override
+        public void onCallNumberDirectly(String phoneNumber) {
+            // No need to call phone number directly from People app.
+            Log.w(TAG, "unexpected invocation of onCallNumberDirectly()");
+        }
+
+        @Override
+        public int getApproximateTileWidth() {
+            return getView().getWidth() / mAdapter.getColumnCount();
+        }
     };
 
     /**
@@ -358,7 +375,7 @@
                 public void onClick(View v) {
                     final Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI, mGroupId);
                     final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-                    intent.setClassName(accountType.resPackageName,
+                    intent.setClassName(accountType.syncAdapterPackageName,
                             accountType.getViewGroupActivity());
                     startActivity(intent);
                 }
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index a3ebeb0..6940efb 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -23,13 +23,13 @@
 import com.android.contacts.GroupMetaDataLoader;
 import com.android.contacts.R;
 import com.android.contacts.activities.GroupEditorActivity;
-import com.android.contacts.editor.ContactEditorFragment.SaveMode;
 import com.android.contacts.editor.SelectAccountDialogFragment;
 import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.AccountWithDataSet;
 import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.util.ViewUtil;
 import com.android.internal.util.Objects;
 
 import android.accounts.Account;
@@ -122,8 +122,6 @@
     private static final int LOADER_EXISTING_MEMBERS = 2;
     private static final int LOADER_NEW_GROUP_MEMBER = 3;
 
-    public static final String SAVE_MODE_EXTRA_KEY = "saveMode";
-
     private static final String MEMBER_RAW_CONTACT_ID_KEY = "rawContactId";
     private static final String MEMBER_LOOKUP_URI_KEY = "memberLookupUri";
 
@@ -502,7 +500,7 @@
 
     public void onDoneClicked() {
         if (isGroupMembershipEditable()) {
-            save(SaveMode.CLOSE);
+            save();
         } else {
             // Just revert it.
             doRevertAction();
@@ -550,12 +548,11 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             AlertDialog dialog = new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.cancel_confirmation_dialog_title)
                     .setMessage(R.string.cancel_confirmation_dialog_message)
                     .setPositiveButton(android.R.string.ok,
                         new DialogInterface.OnClickListener() {
                             @Override
-                            public void onClick(DialogInterface dialog, int whichButton) {
+                            public void onClick(DialogInterface dialogInterface, int whichButton) {
                                 ((GroupEditorFragment) getTargetFragment()).doRevertAction();
                             }
                         }
@@ -571,19 +568,17 @@
      * finishes the activity. This actually only handles saving the group name.
      * @return true when successful
      */
-    public boolean save(int saveMode) {
+    public boolean save() {
         if (!hasValidGroupName() || mStatus != Status.EDITING) {
             return false;
         }
 
         // If we are about to close the editor - there is no need to refresh the data
-        if (saveMode == SaveMode.CLOSE) {
-            getLoaderManager().destroyLoader(LOADER_EXISTING_MEMBERS);
-        }
+        getLoaderManager().destroyLoader(LOADER_EXISTING_MEMBERS);
 
         // If there are no changes, then go straight to onSaveCompleted()
         if (!hasNameChange() && !hasMembershipChange()) {
-            onSaveCompleted(false, SaveMode.CLOSE, mGroupUri);
+            onSaveCompleted(false, mGroupUri);
             return true;
         }
 
@@ -623,50 +618,40 @@
         return true;
     }
 
-    public void onSaveCompleted(boolean hadChanges, int saveMode, Uri groupUri) {
+    public void onSaveCompleted(boolean hadChanges, Uri groupUri) {
         boolean success = groupUri != null;
-        Log.d(TAG, "onSaveCompleted(" + saveMode + ", " + groupUri + ")");
+        Log.d(TAG, "onSaveCompleted(" + groupUri + ")");
         if (hadChanges) {
             Toast.makeText(mContext, success ? R.string.groupSavedToast :
                     R.string.groupSavedErrorToast, Toast.LENGTH_SHORT).show();
         }
-        switch (saveMode) {
-            case SaveMode.CLOSE:
-            case SaveMode.HOME:
-                final Intent resultIntent;
-                final int resultCode;
-                if (success && groupUri != null) {
-                    final String requestAuthority =
-                            groupUri == null ? null : groupUri.getAuthority();
+        final Intent resultIntent;
+        final int resultCode;
+        if (success && groupUri != null) {
+            final String requestAuthority = groupUri.getAuthority();
 
-                    resultIntent = new Intent();
-                    if (LEGACY_CONTACTS_AUTHORITY.equals(requestAuthority)) {
-                        // Build legacy Uri when requested by caller
-                        final long groupId = ContentUris.parseId(groupUri);
-                        final Uri legacyContentUri = Uri.parse("content://contacts/groups");
-                        final Uri legacyUri = ContentUris.withAppendedId(
-                                legacyContentUri, groupId);
-                        resultIntent.setData(legacyUri);
-                    } else {
-                        // Otherwise pass back the given Uri
-                        resultIntent.setData(groupUri);
-                    }
+            resultIntent = new Intent();
+            if (LEGACY_CONTACTS_AUTHORITY.equals(requestAuthority)) {
+                // Build legacy Uri when requested by caller
+                final long groupId = ContentUris.parseId(groupUri);
+                final Uri legacyContentUri = Uri.parse("content://contacts/groups");
+                final Uri legacyUri = ContentUris.withAppendedId(
+                        legacyContentUri, groupId);
+                resultIntent.setData(legacyUri);
+            } else {
+                // Otherwise pass back the given Uri
+                resultIntent.setData(groupUri);
+            }
 
-                    resultCode = Activity.RESULT_OK;
-                } else {
-                    resultCode = Activity.RESULT_CANCELED;
-                    resultIntent = null;
-                }
-                // It is already saved, so prevent that it is saved again
-                mStatus = Status.CLOSING;
-                if (mListener != null) {
-                    mListener.onSaveFinished(resultCode, resultIntent);
-                }
-                break;
-            case SaveMode.RELOAD:
-                // TODO: Handle reloading the group list
-            default:
-                throw new IllegalStateException("Unsupported save mode " + saveMode);
+            resultCode = Activity.RESULT_OK;
+        } else {
+            resultCode = Activity.RESULT_CANCELED;
+            resultIntent = null;
+        }
+        // It is already saved, so prevent that it is saved again
+        mStatus = Status.CLOSING;
+        if (mListener != null) {
+            mListener.onSaveFinished(resultCode, resultIntent);
         }
     }
 
@@ -853,7 +838,6 @@
      * This represents a single member of the current group.
      */
     public static class Member implements Parcelable {
-        private static final Member[] EMPTY_ARRAY = new Member[0];
 
         // TODO: Switch to just dealing with raw contact IDs everywhere if possible
         private final long mRawContactId;
@@ -895,11 +879,16 @@
         public boolean equals(Object object) {
             if (object instanceof Member) {
                 Member otherMember = (Member) object;
-                return otherMember != null && Objects.equal(mLookupUri, otherMember.getLookupUri());
+                return Objects.equal(mLookupUri, otherMember.getLookupUri());
             }
             return false;
         }
 
+        @Override
+        public int hashCode() {
+            return mLookupUri == null ? 0 : mLookupUri.hashCode();
+        }
+
         // Parcelable
         @Override
         public int describeContents() {
@@ -924,10 +913,12 @@
         }
 
         public static final Parcelable.Creator<Member> CREATOR = new Parcelable.Creator<Member>() {
+            @Override
             public Member createFromParcel(Parcel in) {
                 return new Member(in);
             }
 
+            @Override
             public Member[] newArray(int size) {
                 return new Member[size];
             }
@@ -969,7 +960,8 @@
                 });
             }
 
-            mPhotoManager.loadPhoto(badge, member.getPhotoUri(), false, false);
+            mPhotoManager.loadPhoto(badge, member.getPhotoUri(),
+                    ViewUtil.getConstantPreLayoutWidth(badge), false);
             return result;
         }
 
diff --git a/src/com/android/contacts/group/SuggestedMemberListAdapter.java b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
index 08401bf..30718de 100644
--- a/src/com/android/contacts/group/SuggestedMemberListAdapter.java
+++ b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
@@ -295,6 +295,7 @@
 
         @Override
         protected void publishResults(CharSequence constraint, FilterResults results) {
+            @SuppressWarnings("unchecked")
             List<SuggestedMember> suggestionsList = (List<SuggestedMember>) results.values;
             if (suggestionsList == null) {
                 return;
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 7e880a4..4aa4030 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -274,7 +274,6 @@
 
     private void showDialog(int messageId, final Uri contactUri) {
         mDialog = new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.deleteConfirmation_title)
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setMessage(messageId)
                 .setNegativeButton(android.R.string.cancel, null)
diff --git a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
index 224b4a0..051dc13 100644
--- a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
@@ -33,16 +33,38 @@
     private static final String ARG_ACCOUNT_NAME = "accountName";
     private static final String ARG_DATA_SET = "dataSet";
 
+    public static final String FRAGMENT_TAG = "createGroupDialog";
+
+    private final OnGroupCreatedListener mListener;
+
+    public interface OnGroupCreatedListener {
+        public void onGroupCreated();
+    }
+
     public static void show(
             FragmentManager fragmentManager, String accountType, String accountName,
-            String dataSet) {
-        GroupCreationDialogFragment dialog = new GroupCreationDialogFragment();
+            String dataSet, OnGroupCreatedListener listener) {
+        GroupCreationDialogFragment dialog = new GroupCreationDialogFragment(listener);
         Bundle args = new Bundle();
         args.putString(ARG_ACCOUNT_TYPE, accountType);
         args.putString(ARG_ACCOUNT_NAME, accountName);
         args.putString(ARG_DATA_SET, dataSet);
         dialog.setArguments(args);
-        dialog.show(fragmentManager, "createGroup");
+        dialog.show(fragmentManager, FRAGMENT_TAG);
+    }
+
+    public GroupCreationDialogFragment() {
+        super();
+        mListener = null;
+    }
+
+    private GroupCreationDialogFragment(OnGroupCreatedListener listener) {
+        super();
+        mListener = listener;
+    }
+
+    public OnGroupCreatedListener getOnGroupCreatedListener() {
+        return mListener;
     }
 
     @Override
@@ -61,6 +83,13 @@
         String accountName = arguments.getString(ARG_ACCOUNT_NAME);
         String dataSet = arguments.getString(ARG_DATA_SET);
 
+        // Indicate to the listener that a new group will be created.
+        // If the device is rotated, mListener will become null, so that the
+        // popup from GroupMembershipView will not be shown.
+        if (mListener != null) {
+            mListener.onGroupCreated();
+        }
+
         Activity activity = getActivity();
         activity.startService(ContactSaveService.createNewGroupIntent(activity,
                 new AccountWithDataSet(accountName, accountType, dataSet), groupLabel,
diff --git a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
index c1f3bd7..09306f2 100644
--- a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
@@ -52,7 +52,6 @@
 
         return new AlertDialog.Builder(getActivity())
                 .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setTitle(R.string.delete_group_dialog_title)
                 .setMessage(message)
                 .setPositiveButton(android.R.string.ok,
                     new DialogInterface.OnClickListener() {
diff --git a/src/com/android/contacts/interactions/GroupNameDialogFragment.java b/src/com/android/contacts/interactions/GroupNameDialogFragment.java
index 3c65562..8798c59 100644
--- a/src/com/android/contacts/interactions/GroupNameDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupNameDialogFragment.java
@@ -28,70 +28,68 @@
 import android.text.TextWatcher;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.EditText;
 
 /**
  * A common superclass for creating and renaming groups.
  */
-public abstract class GroupNameDialogFragment extends DialogFragment
-        implements TextWatcher, OnShowListener {
-    private EditText mEdit;
-
+public abstract class GroupNameDialogFragment extends DialogFragment {
     protected abstract int getTitleResourceId();
     protected abstract void initializeGroupLabelEditText(EditText editText);
     protected abstract void onCompleted(String groupLabel);
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        View view = LayoutInflater.from(getActivity()).inflate(R.layout.group_name_dialog, null);
-        mEdit = (EditText) view.findViewById(R.id.group_label);
-        initializeGroupLabelEditText(mEdit);
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        final LayoutInflater layoutInflater = LayoutInflater.from(builder.getContext());
+        final View view = layoutInflater.inflate(R.layout.group_name_dialog, null);
+        final EditText editText = (EditText) view.findViewById(R.id.group_label);
+        initializeGroupLabelEditText(editText);
 
-        mEdit.addTextChangedListener(this);
-
-        AlertDialog dialog = new AlertDialog.Builder(getActivity())
-                .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setTitle(getTitleResourceId())
-                .setView(view)
-                .setPositiveButton(android.R.string.ok,
-                    new DialogInterface.OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int whichButton) {
-                            onCompleted(mEdit.getText().toString().trim());
-                        }
+        builder.setTitle(getTitleResourceId());
+        builder.setView(view);
+        editText.requestFocus();
+        builder.setPositiveButton(android.R.string.ok,
+                new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int whichButton) {
+                        onCompleted(editText.getText().toString().trim());
                     }
-                )
-                .setNegativeButton(android.R.string.cancel, null)
-                .create();
+                }
+            );
 
-        dialog.setOnShowListener(this);
+        builder.setNegativeButton(android.R.string.cancel, null);
+        final AlertDialog dialog = builder.create();
+
+        dialog.setOnShowListener(new OnShowListener() {
+            @Override
+            public void onShow(DialogInterface dialogInterface) {
+                updateOkButtonState(dialog, editText);
+            }
+        });
+        editText.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                updateOkButtonState(dialog, editText);
+            }
+        });
+        dialog.getWindow().setSoftInputMode(
+                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
         return dialog;
     }
 
-    public void onShow(DialogInterface dialog) {
-        updateOkButtonState((AlertDialog) dialog);
-    }
-
-    @Override
-    public void afterTextChanged(Editable s) {
-        AlertDialog dialog = (AlertDialog) getDialog();
-        // Make sure the dialog has not already been dismissed or destroyed.
-        if (dialog != null) {
-            updateOkButtonState(dialog);
-        }
-    }
-
-    private void updateOkButtonState(AlertDialog dialog) {
-        Button okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
-        okButton.setEnabled(!TextUtils.isEmpty(mEdit.getText().toString().trim()));
-    }
-
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    /* package */ void updateOkButtonState(AlertDialog dialog, EditText editText) {
+        final Button okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
+        okButton.setEnabled(!TextUtils.isEmpty(editText.getText().toString().trim()));
     }
 }
diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
index 7fdc47e..521d2f0 100644
--- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
@@ -55,14 +55,18 @@
     public static final String TAG = "ImportExportDialogFragment";
 
     private static final String KEY_RES_ID = "resourceId";
+    private static final String ARG_CONTACTS_ARE_AVAILABLE = "CONTACTS_ARE_AVAILABLE";
 
     private final String[] LOOKUP_PROJECTION = new String[] {
             Contacts.LOOKUP_KEY
     };
 
     /** Preferred way to show this dialog */
-    public static void show(FragmentManager fragmentManager) {
+    public static void show(FragmentManager fragmentManager, boolean contactsAreAvailable) {
         final ImportExportDialogFragment fragment = new ImportExportDialogFragment();
+        Bundle args = new Bundle();
+        args.putBoolean(ARG_CONTACTS_ARE_AVAILABLE, contactsAreAvailable);
+        fragment.setArguments(args);
         fragment.show(fragmentManager, ImportExportDialogFragment.TAG);
     }
 
@@ -72,6 +76,7 @@
         final Resources res = getActivity().getResources();
         final LayoutInflater dialogInflater = (LayoutInflater)getActivity()
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        final boolean contactsAreAvailable = getArguments().getBoolean(ARG_CONTACTS_ARE_AVAILABLE);
 
         // Adapter that shows a list of string resources
         final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(getActivity(),
@@ -95,10 +100,14 @@
             adapter.add(R.string.import_from_sdcard);
         }
         if (res.getBoolean(R.bool.config_allow_export_to_sdcard)) {
-            adapter.add(R.string.export_to_sdcard);
+            if (contactsAreAvailable) {
+                adapter.add(R.string.export_to_sdcard);
+            }
         }
         if (res.getBoolean(R.bool.config_allow_share_visible_contacts)) {
-            adapter.add(R.string.share_visible_contacts);
+            if (contactsAreAvailable) {
+                adapter.add(R.string.share_visible_contacts);
+            }
         }
 
         final DialogInterface.OnClickListener clickListener =
@@ -136,7 +145,9 @@
             }
         };
         return new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.dialog_import_export)
+                .setTitle(contactsAreAvailable
+                        ? R.string.dialog_import_export
+                        : R.string.dialog_import)
                 .setSingleChoiceItems(adapter, -1, clickListener)
                 .create();
     }
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 4c75896..3c3c347 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -47,6 +47,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
@@ -65,6 +66,11 @@
  * Initiates phone calls or a text message. If there are multiple candidates, this class shows a
  * dialog to pick one. Creating one of these interactions should be done through the static
  * factory methods.
+ *
+ * Note that this class initiates not only usual *phone* calls but also *SIP* calls.
+ *
+ * TODO: clean up code and documents since it is quite confusing to use "phone numbers" or
+ *        "phone calls" here while they can be SIP addresses or SIP calls (See also issue 5039627).
  */
 public class PhoneNumberInteraction implements OnLoadCompleteListener<Cursor> {
     private static final String TAG = PhoneNumberInteraction.class.getSimpleName();
@@ -86,6 +92,8 @@
         String dataSet;
         long type;
         String label;
+        /** {@link Phone#CONTENT_ITEM_TYPE} or {@link SipAddress#CONTENT_ITEM_TYPE}. */
+        String mimeType;
 
         public PhoneItem() {
         }
@@ -97,8 +105,10 @@
             this.dataSet     = in.readString();
             this.type        = in.readLong();
             this.label       = in.readString();
+            this.mimeType    = in.readString();
         }
 
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeLong(id);
             dest.writeString(phoneNumber);
@@ -106,12 +116,15 @@
             dest.writeString(dataSet);
             dest.writeLong(type);
             dest.writeString(label);
+            dest.writeString(mimeType);
         }
 
+        @Override
         public int describeContents() {
             return 0;
         }
 
+        @Override
         public boolean collapseWith(PhoneItem phoneItem) {
             if (!shouldCollapseWith(phoneItem)) {
                 return false;
@@ -120,6 +133,7 @@
             return true;
         }
 
+        @Override
         public boolean shouldCollapseWith(PhoneItem phoneItem) {
             return ContactsUtils.shouldCollapse(Phone.CONTENT_ITEM_TYPE, phoneNumber,
                     Phone.CONTENT_ITEM_TYPE, phoneItem.phoneNumber);
@@ -132,10 +146,12 @@
 
         public static final Parcelable.Creator<PhoneItem> CREATOR
                 = new Parcelable.Creator<PhoneItem>() {
+            @Override
             public PhoneItem createFromParcel(Parcel in) {
                 return new PhoneItem(in);
             }
 
+            @Override
             public PhoneItem[] newArray(int size) {
                 return new PhoneItem[size];
             }
@@ -233,7 +249,10 @@
                     .create();
         }
 
+        @Override
         public void onClick(DialogInterface dialog, int which) {
+            final Activity activity = getActivity();
+            if (activity == null) return;
             final AlertDialog alertDialog = (AlertDialog)dialog;
             if (mPhoneList.size() > which && which >= 0) {
                 final PhoneItem phoneItem = mPhoneList.get(which);
@@ -241,11 +260,11 @@
                 if (checkBox.isChecked()) {
                     // Request to mark the data as primary in the background.
                     final Intent serviceIntent = ContactSaveService.createSetSuperPrimaryIntent(
-                            getActivity(), phoneItem.id);
-                    getActivity().startService(serviceIntent);
+                            activity, phoneItem.id);
+                    activity.startService(serviceIntent);
                 }
 
-                PhoneNumberInteraction.performAction(getActivity(), phoneItem.phoneNumber,
+                PhoneNumberInteraction.performAction(activity, phoneItem.phoneNumber,
                         mInteractionType, mCallOrigin);
             } else {
                 dialog.dismiss();
@@ -260,11 +279,15 @@
             RawContacts.ACCOUNT_TYPE,
             RawContacts.DATA_SET,
             Phone.TYPE,
-            Phone.LABEL
+            Phone.LABEL,
+            Phone.MIMETYPE
     };
 
-    private static final String PHONE_NUMBER_SELECTION = Data.MIMETYPE + "='"
-            + Phone.CONTENT_ITEM_TYPE + "' AND " + Phone.NUMBER + " NOT NULL";
+    private static final String PHONE_NUMBER_SELECTION =
+            Data.MIMETYPE + " IN ('"
+                + Phone.CONTENT_ITEM_TYPE + "', "
+                + "'" + SipAddress.CONTENT_ITEM_TYPE + "') AND "
+                + Data.DATA1 + " NOT NULL";
 
     private final Context mContext;
     private final OnDismissListener mDismissListener;
@@ -308,11 +331,7 @@
                         Intent.ACTION_SENDTO, Uri.fromParts("sms", phoneNumber, null));
                 break;
             default:
-                intent = new Intent(
-                        Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", phoneNumber, null));
-                if (callOrigin != null) {
-                    intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin);
-                }
+                intent = ContactsUtils.getCallIntent(phoneNumber, callOrigin);
                 break;
         }
         context.startActivity(intent);
@@ -378,6 +397,7 @@
                 item.dataSet = cursor.getString(cursor.getColumnIndex(RawContacts.DATA_SET));
                 item.type = cursor.getInt(cursor.getColumnIndex(Phone.TYPE));
                 item.label = cursor.getString(cursor.getColumnIndex(Phone.LABEL));
+                item.mimeType = cursor.getString(cursor.getColumnIndex(Phone.MIMETYPE));
 
                 phoneList.add(item);
             }
@@ -396,8 +416,9 @@
         if (phoneList.size() == 0) {
             onDismiss();
         } else if (phoneList.size() == 1) {
+            PhoneItem item = phoneList.get(0);
             onDismiss();
-            performAction(phoneList.get(0).phoneNumber);
+            performAction(item.phoneNumber);
         } else {
             // There are multiple candidates. Let the user choose one.
             showDisambiguationDialog(phoneList);
diff --git a/src/com/android/contacts/list/AccountFilterActivity.java b/src/com/android/contacts/list/AccountFilterActivity.java
index 14db634..2624e5d 100644
--- a/src/com/android/contacts/list/AccountFilterActivity.java
+++ b/src/com/android/contacts/list/AccountFilterActivity.java
@@ -56,11 +56,14 @@
     private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 0;
 
     public static final String KEY_EXTRA_CONTACT_LIST_FILTER = "contactListFilter";
+    public static final String KEY_EXTRA_CURRENT_FILTER = "currentFilter";
 
     private static final int FILTER_LOADER_ID = 0;
 
     private ListView mListView;
 
+    private ContactListFilter mCurrentFilter;
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -74,6 +77,8 @@
             actionBar.setDisplayHomeAsUpEnabled(true);
         }
 
+        mCurrentFilter = getIntent().getParcelableExtra(KEY_EXTRA_CURRENT_FILTER);
+
         getLoaderManager().initLoader(FILTER_LOADER_ID, null, new MyLoaderCallbacks());
     }
 
@@ -151,7 +156,8 @@
                 Log.e(TAG, "Failed to load filters");
                 return;
             }
-            mListView.setAdapter(new FilterListAdapter(AccountFilterActivity.this, data));
+            mListView.setAdapter(
+                    new FilterListAdapter(AccountFilterActivity.this, data, mCurrentFilter));
         }
 
         @Override
@@ -197,11 +203,16 @@
     private static class FilterListAdapter extends BaseAdapter {
         private final List<ContactListFilter> mFilters;
         private final LayoutInflater mLayoutInflater;
+        private final AccountTypeManager mAccountTypes;
+        private final ContactListFilter mCurrentFilter;
 
-        public FilterListAdapter(Context context, List<ContactListFilter> filters) {
+        public FilterListAdapter(
+                Context context, List<ContactListFilter> filters, ContactListFilter current) {
             mLayoutInflater = (LayoutInflater) context.getSystemService
                     (Context.LAYOUT_INFLATER_SERVICE);
             mFilters = filters;
+            mCurrentFilter = current;
+            mAccountTypes = AccountTypeManager.getInstance(context);
         }
 
         @Override
@@ -230,8 +241,9 @@
             view.setSingleAccount(mFilters.size() == 1);
             final ContactListFilter filter = mFilters.get(position);
             view.setContactListFilter(filter);
-            view.bindView(true);
+            view.bindView(mAccountTypes);
             view.setTag(filter);
+            view.setActivated(filter.equals(mCurrentFilter));
             return view;
         }
     }
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 4c38efb..a2b61c7 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -300,7 +300,7 @@
      * Sets the new selection for the list.
      */
     public void setSelectedContactUri(Uri uri) {
-        setSelectedContactUri(uri, true, true, true, false);
+        setSelectedContactUri(uri, true, false /* no smooth scroll */, true, false);
     }
 
     @Override
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index 9c36f05..78bf628 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -18,7 +18,6 @@
 import com.android.contacts.ContactPhotoManager;
 import com.android.contacts.R;
 import com.android.contacts.widget.IndexerListAdapter;
-import com.android.contacts.widget.TextWithHighlightingFactory;
 
 import android.content.Context;
 import android.content.CursorLoader;
@@ -54,13 +53,8 @@
      */
     private static final boolean LOCAL_INVISIBLE_DIRECTORY_ENABLED = false;
 
-    /**
-     * The animation is used here to allocate animated name text views.
-     */
-    private TextWithHighlightingFactory mTextWithHighlightingFactory;
     private int mDisplayOrder;
     private int mSortOrder;
-    private boolean mNameHighlightingEnabled;
 
     private boolean mDisplayPhotos;
     private boolean mQuickContactEnabled;
@@ -92,9 +86,17 @@
     private String mContactsCount = "";
     private boolean mDarkTheme = false;
 
+    /** Resource used to provide header-text for default filter. */
+    private CharSequence mDefaultFilterHeaderText;
+
     public ContactEntryListAdapter(Context context) {
         super(context);
         addPartitions();
+        setDefaultFilterHeaderText(R.string.local_search_label);
+    }
+
+    protected void setDefaultFilterHeaderText(int resourceId) {
+        mDefaultFilterHeaderText = getContext().getResources().getText(resourceId);
     }
 
     @Override
@@ -136,6 +138,28 @@
         return partition;
     }
 
+    /**
+     * Remove all directories after the default directory. This is typically used when contacts
+     * list screens are asked to exit the search mode and thus need to remove all remote directory
+     * results for the search.
+     *
+     * This code assumes that the default directory and directories before that should not be
+     * deleted (e.g. Join screen has "suggested contacts" directory before the default director,
+     * and we should not remove the directory).
+     */
+    /* package */ void removeDirectoriesAfterDefault() {
+        final int partitionCount = getPartitionCount();
+        for (int i = partitionCount - 1; i >= 0; i--) {
+            final Partition partition = getPartition(i);
+            if ((partition instanceof DirectoryPartition)
+                    && ((DirectoryPartition) partition).getDirectoryId() == Directory.DEFAULT) {
+                break;
+            } else {
+                removePartition(i);
+            }
+        }
+    }
+
     private int getPartitionByDirectoryId(long id) {
         int count = getPartitionCount();
         for (int i = 0; i < count; i++) {
@@ -516,7 +540,7 @@
         TextView labelTextView = (TextView)view.findViewById(R.id.label);
         TextView displayNameTextView = (TextView)view.findViewById(R.id.display_name);
         if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
-            labelTextView.setText(R.string.local_search_label);
+            labelTextView.setText(mDefaultFilterHeaderText);
             displayNameTextView.setText(null);
         } else {
             labelTextView.setText(R.string.directory_search_label);
@@ -602,8 +626,16 @@
 
     // TODO: move sharable logic (bindXX() methods) to here with extra arguments
 
+    /**
+     * Loads the photo for the quick contact view and assigns the contact uri.
+     * @param photoIdColumn Index of the photo id column
+     * @param photoUriColumn Index of the photo uri column. Optional: Can be -1
+     * @param contactIdColumn Index of the contact id column
+     * @param lookUpKeyColumn Index of the lookup key column
+     */
     protected void bindQuickContact(final ContactListItemView view, int partitionIndex,
-            Cursor cursor, int photoIdColumn, int contactIdColumn, int lookUpKeyColumn) {
+            Cursor cursor, int photoIdColumn, int photoUriColumn, int contactIdColumn,
+            int lookUpKeyColumn) {
         long photoId = 0;
         if (!cursor.isNull(photoIdColumn)) {
             photoId = cursor.getLong(photoIdColumn);
@@ -612,7 +644,15 @@
         QuickContactBadge quickContact = view.getQuickContact();
         quickContact.assignContactUri(
                 getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn));
-        getPhotoLoader().loadPhoto(quickContact, photoId, false, mDarkTheme);
+
+        if (photoId != 0 || photoUriColumn == -1) {
+            getPhotoLoader().loadThumbnail(quickContact, photoId, mDarkTheme);
+        } else {
+            final String photoUriString = cursor.getString(photoUriColumn);
+            final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
+            getPhotoLoader().loadPhoto(quickContact, photoUri, -1, mDarkTheme);
+        }
+
     }
 
     protected Uri getContactUri(int partitionIndex, Cursor cursor,
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 8db477e..27fdada 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -128,7 +128,6 @@
     private ContextMenuAdapter mContextMenuAdapter;
     private ContactPhotoManager mPhotoManager;
     private ContactListEmptyView mEmptyView;
-    private ProviderStatusLoader mProviderStatusLoader;
     private ContactsPreferences mContactsPrefs;
 
     private boolean mForceLoad;
@@ -291,10 +290,6 @@
 
         mContactsPrefs.registerChangeListener(mPreferencesChangeListener);
 
-        if (mProviderStatusLoader == null) {
-            mProviderStatusLoader = new ProviderStatusLoader(mContext);
-        }
-
         mForceLoad = loadPreferences();
 
         mDirectoryListStatus = STATUS_NOT_LOADED;
@@ -613,12 +608,10 @@
 
                 mAdapter.clearPartitions();
                 if (!flag) {
-                    // If we are switching from search to regular display,
-                    // remove all directory partitions (except the default one).
-                    int count = mAdapter.getPartitionCount();
-                    for (int i = count; --i >= 1;) {
-                        mAdapter.removePartition(i);
-                    }
+                    // If we are switching from search to regular display, remove all directory
+                    // partitions after default one, assuming they are remote directories which
+                    // should be cleaned up on exiting the search mode.
+                    mAdapter.removeDirectoriesAfterDefault();
                 }
                 mAdapter.configureDefaultPartition(false, flag);
             }
diff --git a/src/com/android/contacts/list/ContactListAdapter.java b/src/com/android/contacts/list/ContactListAdapter.java
index a8caf3b..18f7e04 100644
--- a/src/com/android/contacts/list/ContactListAdapter.java
+++ b/src/com/android/contacts/list/ContactListAdapter.java
@@ -23,7 +23,6 @@
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.ContactCounts;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.SearchSnippetColumns;
 import android.text.TextUtils;
@@ -226,11 +225,11 @@
         }
 
         if (photoId != 0) {
-            getPhotoLoader().loadPhoto(view.getPhotoView(), photoId, false, false);
+            getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false);
         } else {
             final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI);
             final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
-            getPhotoLoader().loadPhoto(view.getPhotoView(), photoUri, false, false);
+            getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, false);
         }
     }
 
diff --git a/src/com/android/contacts/list/ContactListFilter.java b/src/com/android/contacts/list/ContactListFilter.java
index 07319f9..172cbe2 100644
--- a/src/com/android/contacts/list/ContactListFilter.java
+++ b/src/com/android/contacts/list/ContactListFilter.java
@@ -18,8 +18,10 @@
 
 import android.content.SharedPreferences;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
 
 /**
@@ -252,6 +254,23 @@
         return mId;
     }
 
+    /**
+     * Adds the account query parameters to the given {@code uriBuilder}.
+     *
+     * @throws IllegalStateException if the filter type is not {@link #FILTER_TYPE_ACCOUNT}.
+     */
+    public Uri.Builder addAccountQueryParameterToUrl(Uri.Builder uriBuilder) {
+        if (filterType != FILTER_TYPE_ACCOUNT) {
+            throw new IllegalStateException("filterType must be FILTER_TYPE_ACCOUNT");
+        }
+        uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName);
+        uriBuilder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType);
+        if (!TextUtils.isEmpty(dataSet)) {
+            uriBuilder.appendQueryParameter(RawContacts.DATA_SET, dataSet);
+        }
+        return uriBuilder;
+    }
+
     public String toDebugString() {
         final StringBuilder builder = new StringBuilder();
         builder.append("[filter type: " + filterType + " (" + filterTypeToString(filterType) + ")");
diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java
index 8126c62..9f483f1 100644
--- a/src/com/android/contacts/list/ContactListFilterController.java
+++ b/src/com/android/contacts/list/ContactListFilterController.java
@@ -50,6 +50,9 @@
 
     public abstract void removeListener(ContactListFilterListener listener);
 
+    /**
+     * Return the currently-active filter.
+     */
     public abstract ContactListFilter getFilter();
 
     /**
diff --git a/src/com/android/contacts/list/ContactListFilterView.java b/src/com/android/contacts/list/ContactListFilterView.java
index 398a864..020952d 100644
--- a/src/com/android/contacts/list/ContactListFilterView.java
+++ b/src/com/android/contacts/list/ContactListFilterView.java
@@ -17,13 +17,18 @@
 package com.android.contacts.list;
 
 import com.android.contacts.R;
+import com.android.contacts.editor.ContactEditorFragment;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.util.ThemeUtils;
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.RadioButton;
 import android.widget.TextView;
 
 /**
@@ -31,12 +36,14 @@
  */
 public class ContactListFilterView extends LinearLayout {
 
+    private static final String TAG = ContactListFilterView.class.getSimpleName();
+
     private ImageView mIcon;
-    private TextView mLabel;
-    private View mIndent;
+    private TextView mAccountType;
+    private TextView mAccountUserName;
+    private RadioButton mRadioButton;
     private ContactListFilter mFilter;
     private boolean mSingleAccount;
-    private int mActivatedBackground;
 
     public ContactListFilterView(Context context) {
         super(context);
@@ -58,78 +65,80 @@
         this.mSingleAccount = flag;
     }
 
-    public void bindView(boolean dropdown) {
-        if (dropdown) {
-            if (mActivatedBackground == 0) {
-                mActivatedBackground = ThemeUtils.getActivatedBackground(getContext().getTheme());
-            }
-            setBackgroundResource(mActivatedBackground);
+    @Override
+    public void setActivated(boolean activated) {
+        super.setActivated(activated);
+        if (mRadioButton != null) {
+            mRadioButton.setChecked(activated);
+        } else {
+            // We're guarding against null-pointer exceptions,
+            // but otherwise this code is not expected to work
+            // properly if the button hasn't been initialized.
+            Log.wtf(TAG, "radio-button cannot be activated because it is null");
         }
+    }
 
-        if (mLabel == null) {
+    public void bindView(AccountTypeManager accountTypes) {
+        if (mAccountType == null) {
             mIcon = (ImageView) findViewById(R.id.icon);
-            mLabel = (TextView) findViewById(R.id.label);
-            mIndent = findViewById(R.id.indent);
+            mAccountType = (TextView) findViewById(R.id.accountType);
+            mAccountUserName = (TextView) findViewById(R.id.accountUserName);
+            mRadioButton = (RadioButton) findViewById(R.id.radioButton);
+            mRadioButton.setChecked(isActivated());
         }
 
         if (mFilter == null) {
-            mLabel.setText(R.string.contactsList);
+            mAccountType.setText(R.string.contactsList);
             return;
         }
 
+        mAccountUserName.setVisibility(View.GONE);
         switch (mFilter.filterType) {
             case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS: {
-                bindView(R.drawable.ic_menu_contacts_holo_light, R.string.list_filter_all_accounts,
-                        dropdown);
+                bindView(0, R.string.list_filter_all_accounts);
                 break;
             }
             case ContactListFilter.FILTER_TYPE_STARRED: {
-                bindView(R.drawable.ic_menu_star_holo_light, R.string.list_filter_all_starred,
-                        dropdown);
+                bindView(R.drawable.ic_menu_star_holo_light, R.string.list_filter_all_starred);
                 break;
             }
             case ContactListFilter.FILTER_TYPE_CUSTOM: {
-                bindView(R.drawable.ic_menu_settings_holo_light,
-                        dropdown ? R.string.list_filter_customize : R.string.list_filter_custom,
-                        dropdown);
+                bindView(R.drawable.ic_menu_settings_holo_light, R.string.list_filter_customize);
                 break;
             }
             case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY: {
-                bindView(0, R.string.list_filter_phones, dropdown);
+                bindView(0, R.string.list_filter_phones);
                 break;
             }
             case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT: {
-                bindView(0, R.string.list_filter_single, dropdown);
+                bindView(0, R.string.list_filter_single);
                 break;
             }
             case ContactListFilter.FILTER_TYPE_ACCOUNT: {
+                mAccountUserName.setVisibility(View.VISIBLE);
                 mIcon.setVisibility(View.VISIBLE);
                 if (mFilter.icon != null) {
                     mIcon.setImageDrawable(mFilter.icon);
                 } else {
                     mIcon.setImageResource(R.drawable.unknown_source);
                 }
-                mLabel.setText(mFilter.accountName);
-                if (dropdown) {
-                    mIndent.setVisibility(View.GONE);
-                }
+                final AccountType accountType =
+                        accountTypes.getAccountType(mFilter.accountType, mFilter.dataSet);
+                mAccountUserName.setText(mFilter.accountName);
+                mAccountType.setText(accountType.getDisplayLabel(getContext()));
                 break;
             }
         }
     }
 
-    private void bindView(int iconResource, int textResource, boolean dropdown) {
+    private void bindView(int iconResource, int textResource) {
         if (iconResource != 0) {
             mIcon.setVisibility(View.VISIBLE);
             mIcon.setImageResource(iconResource);
         } else {
-            mIcon.setVisibility(dropdown ? View.INVISIBLE : View.GONE);
+            mIcon.setVisibility(View.GONE);
         }
 
-        mLabel.setText(textResource);
-
-        if (mIndent != null) {
-            mIndent.setVisibility(View.GONE);
-        }
+        mAccountType.setText(textResource);
     }
 }
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index 4390d78..191212b 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -70,14 +70,11 @@
     private static final int QUICK_CONTACT_BADGE_STYLE =
             com.android.internal.R.attr.quickContactBadgeStyleWindowMedium;
 
-    protected final Context mContext;
-
     // Style values for layout and appearance
     private final int mPreferredHeight;
     private final int mVerticalDividerMargin;
     private final int mGapBetweenImageAndText;
     private final int mGapBetweenLabelAndData;
-    private final int mCallButtonPadding;
     private final int mPresenceIconMargin;
     private final int mPresenceIconSize;
     private final int mHeaderTextColor;
@@ -186,7 +183,6 @@
     // same row.
     private int mLabelAndDataViewMaxHeight;
 
-    private OnClickListener mCallButtonClickListener;
     // TODO: some TextView fields are using CharArrayBuffer while some are not. Determine which is
     // more efficient for each case or in general, and simplify the whole implementation.
     // Note: if we're sure MARQUEE will be used every time, there's no reason to use
@@ -201,7 +197,7 @@
     private Rect mBoundsWithoutHeader = new Rect();
 
     /** A helper used to highlight a prefix in a text field. */
-    private PrefixHighlighter mPrefixHighligher;
+    private PrefixHighlighter mPrefixHighlighter;
     private CharSequence mUnknownNameText;
 
     /**
@@ -244,8 +240,6 @@
                 R.styleable.ContactListItemView_list_item_gap_between_image_and_text, 0);
         mGapBetweenLabelAndData = a.getDimensionPixelOffset(
                 R.styleable.ContactListItemView_list_item_gap_between_label_and_data, 0);
-        mCallButtonPadding = a.getDimensionPixelOffset(
-                R.styleable.ContactListItemView_list_item_call_button_padding, 0);
         mPresenceIconMargin = a.getDimensionPixelOffset(
                 R.styleable.ContactListItemView_list_item_presence_icon_margin, 4);
         mPresenceIconSize = a.getDimensionPixelOffset(
@@ -285,9 +279,9 @@
                 a.getDimensionPixelOffset(
                         R.styleable.ContactListItemView_list_item_padding_bottom, 0));
 
-        mPrefixHighligher = new PrefixHighlighter(
-                a.getColor(R.styleable.ContactListItemView_list_item_prefix_highlight_color,
-                        Color.GREEN));
+        final int prefixHighlightColor = a.getColor(
+                R.styleable.ContactListItemView_list_item_prefix_highlight_color, Color.GREEN);
+        mPrefixHighlighter = new PrefixHighlighter(prefixHighlightColor);
         a.recycle();
 
         a = getContext().obtainStyledAttributes(android.R.styleable.Theme);
@@ -301,13 +295,6 @@
         }
     }
 
-    /**
-     * Installs a call button listener.
-     */
-    public void setOnCallButtonClickListener(OnClickListener callButtonClickListener) {
-        mCallButtonClickListener = callButtonClickListener;
-    }
-
     public void setUnknownNameText(CharSequence unknownNameText) {
         mUnknownNameText = unknownNameText;
     }
@@ -415,7 +402,9 @@
 
         // Status view height is the biggest of the text view and the presence icon
         if (isVisible(mPresenceIcon)) {
-            mPresenceIcon.measure(mPresenceIconSize, mPresenceIconSize);
+            mPresenceIcon.measure(
+                    MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY));
             mStatusTextViewHeight = mPresenceIcon.getMeasuredHeight();
         }
 
@@ -839,7 +828,7 @@
                 mPhotoView = new ImageView(mContext);
             }
             // Quick contact style used above will set a background - remove it
-            mPhotoView.setBackgroundDrawable(null);
+            mPhotoView.setBackground(null);
             addView(mPhotoView);
             mPhotoViewWidthAndHeightAreReady = false;
         }
@@ -904,31 +893,6 @@
     }
 
     /**
-     * Adds a call button using the supplied arguments as an id and tag.
-     */
-    public void showCallButton(int id, int tag) {
-        if (mCallButton == null) {
-            mCallButton = new DontPressWithParentImageView(mContext, null);
-            mCallButton.setId(id);
-            mCallButton.setOnClickListener(mCallButtonClickListener);
-            mCallButton.setBackgroundResource(R.drawable.call_background);
-            mCallButton.setImageResource(android.R.drawable.sym_action_call);
-            mCallButton.setPadding(mCallButtonPadding, 0, mCallButtonPadding, 0);
-            mCallButton.setScaleType(ScaleType.CENTER);
-            addView(mCallButton);
-        }
-
-        mCallButton.setTag(tag);
-        mCallButton.setVisibility(View.VISIBLE);
-    }
-
-    public void hideCallButton() {
-        if (mCallButton != null) {
-            mCallButton.setVisibility(View.GONE);
-        }
-    }
-
-    /**
      * Adds or updates a text view for the phonetic name.
      */
     public void setPhoneticName(char[] text, int size) {
@@ -1056,7 +1020,7 @@
                 mSnippetView.setVisibility(View.GONE);
             }
         } else {
-            mPrefixHighligher.setText(getSnippetView(), text, mHighlightedPrefix);
+            mPrefixHighlighter.setText(getSnippetView(), text, mHighlightedPrefix);
             mSnippetView.setVisibility(VISIBLE);
         }
     }
@@ -1167,7 +1131,7 @@
     public void showDisplayName(Cursor cursor, int nameColumnIndex, int displayOrder) {
         CharSequence name = cursor.getString(nameColumnIndex);
         if (!TextUtils.isEmpty(name)) {
-            name = mPrefixHighligher.apply(name, mHighlightedPrefix);
+            name = mPrefixHighlighter.apply(name, mHighlightedPrefix);
         } else {
             name = mUnknownNameText;
         }
diff --git a/src/com/android/contacts/list/ContactPickerFragment.java b/src/com/android/contacts/list/ContactPickerFragment.java
index 43081e5..ef51732 100644
--- a/src/com/android/contacts/list/ContactPickerFragment.java
+++ b/src/com/android/contacts/list/ContactPickerFragment.java
@@ -205,6 +205,7 @@
         }
     }
 
+    @Override
     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
         mListener.onShortcutIntentCreated(shortcutIntent);
     }
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index 490cd92..ddf88b0 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -23,13 +23,11 @@
 import com.android.contacts.GroupMemberLoader;
 import com.android.contacts.GroupMemberLoader.GroupDetailQuery;
 import com.android.contacts.R;
-import com.android.contacts.list.ContactTileAdapter.DisplayType;
 
 import android.content.ContentUris;
 import android.content.Context;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -50,11 +48,12 @@
     private static final String TAG = ContactTileAdapter.class.getSimpleName();
 
     private DisplayType mDisplayType;
-    private Listener mListener;
+    private ContactTileView.Listener mListener;
     private Context mContext;
     private Resources mResources;
     private Cursor mContactCursor = null;
     private ContactPhotoManager mPhotoManager;
+    private int mNumFrequents;
 
     /**
      * Index of the first NON starred contact in the {@link Cursor}
@@ -114,13 +113,14 @@
         GROUP_MEMBERS
     }
 
-    public ContactTileAdapter(Context context, Listener listener, int numCols,
+    public ContactTileAdapter(Context context, ContactTileView.Listener listener, int numCols,
             DisplayType displayType) {
         mListener = listener;
         mContext = context;
         mResources = context.getResources();
         mColumnCount = (displayType == DisplayType.FREQUENT_ONLY ? 1 : numCols);
         mDisplayType = displayType;
+        mNumFrequents = 0;
 
         // Converting padding in dips to padding in pixels
         mPaddingInPixels = mContext.getResources()
@@ -186,6 +186,25 @@
     public void setContactCursor(Cursor cursor) {
         mContactCursor = cursor;
         mDividerPosition = getDividerPosition(cursor);
+
+        // count the number of frequents
+        switch (mDisplayType) {
+            case STARRED_ONLY:
+            case GROUP_MEMBERS:
+                mNumFrequents = 0;
+                break;
+            case STREQUENT:
+            case STREQUENT_PHONE_ONLY:
+                mNumFrequents = mContactCursor.getCount() - mDividerPosition;
+                break;
+            case FREQUENT_ONLY:
+                mNumFrequents = mContactCursor.getCount();
+                break;
+            default:
+                throw new IllegalArgumentException("Unrecognized DisplayType " + mDisplayType);
+        }
+
+        // cause a refresh of any views that rely on this data
         notifyDataSetChanged();
     }
 
@@ -276,6 +295,13 @@
         return contact;
     }
 
+    /**
+     * Returns the number of frequents that will be displayed in the list.
+     */
+    public int getNumFrequents() {
+        return mNumFrequents;
+    }
+
     @Override
     public int getCount() {
         if (mContactCursor == null || mContactCursor.isClosed()) {
@@ -291,11 +317,9 @@
                 // Takes numbers of rows the Starred Contacts Occupy
                 int starredRowCount = getRowCount(mDividerPosition);
 
-                // Calculates the number of frequent contacts
-                int frequentRowCount = mContactCursor.getCount() - mDividerPosition ;
-
-                // If there are any frequent contacts add one for the divider
-                frequentRowCount += frequentRowCount == 0 ? 0 : 1;
+                // Compute the frequent row count which is 1 plus the number of frequents
+                // (to account for the divider) or 0 if there are no frequents.
+                int frequentRowCount = mNumFrequents == 0 ? 0 : mNumFrequents + 1;
 
                 // Return the number of starred plus frequent rows
                 return starredRowCount + frequentRowCount;
@@ -315,6 +339,10 @@
         return entryCount == 0 ? 0 : ((entryCount - 1) / mColumnCount) + 1;
     }
 
+    public int getColumnCount() {
+        return mColumnCount;
+    }
+
     /**
      * Returns an ArrayList of the {@link ContactEntry}s that are to appear
      * on the row for the given position.
@@ -418,8 +446,8 @@
             case ViewTypes.FREQUENT:
                 return mDisplayType == DisplayType.STREQUENT_PHONE_ONLY ?
                         R.layout.contact_tile_frequent_phone : R.layout.contact_tile_frequent;
-            case ViewTypes.STARRED_WITH_SECONDARY_ACTION:
-                return R.layout.contact_tile_starred_secondary_target;
+            case ViewTypes.STARRED_PHONE:
+                return R.layout.contact_tile_phone_starred;
             default:
                 throw new IllegalArgumentException("Unrecognized viewType " + viewType);
         }
@@ -450,7 +478,7 @@
                 }
             case STREQUENT_PHONE_ONLY:
                 if (position < getRowCount(mDividerPosition)) {
-                    return ViewTypes.STARRED_WITH_SECONDARY_ACTION;
+                    return ViewTypes.STARRED_PHONE;
                  } else if (position == getRowCount(mDividerPosition)) {
                     return ViewTypes.DIVIDER;
                 } else {
@@ -474,16 +502,6 @@
         return getRowCount(mDividerPosition);
     }
 
-    private ContactTileView.Listener mContactTileListener = new ContactTileView.Listener() {
-        @Override
-        public void onClick(ContactTileView contactTileView) {
-            if (mListener != null) {
-                mListener.onContactSelected(contactTileView.getLookupUri(),
-                        ContactsUtils.getTargetRectFromView(mContext, contactTileView));
-            }
-        }
-    };
-
     /**
      * Acts as a row item composed of {@link ContactTileView}
      *
@@ -531,7 +549,7 @@
                         0);
                 contactTile.setLayoutParams(params);
                 contactTile.setPhotoManager(mPhotoManager);
-                contactTile.setListener(mContactTileListener);
+                contactTile.setListener(mListener);
                 addView(contactTile);
             } else {
                 contactTile = (ContactTileView) getChildAt(childIndex);
@@ -539,7 +557,7 @@
             contactTile.loadFromContact(entry);
 
             switch (mItemViewType) {
-                case ViewTypes.STARRED_WITH_SECONDARY_ACTION:
+                case ViewTypes.STARRED_PHONE:
                 case ViewTypes.STARRED:
                     // Setting divider visibilities
                     contactTile.setPadding(0, 0,
@@ -558,9 +576,9 @@
         @Override
         protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
             switch (mItemViewType) {
-                case ViewTypes.STARRED_WITH_SECONDARY_ACTION:
+                case ViewTypes.STARRED_PHONE:
                 case ViewTypes.STARRED:
-                    onLayoutForTiles(left, top, right, bottom);
+                    onLayoutForTiles();
                     return;
                 default:
                     super.onLayout(changed, left, top, right, bottom);
@@ -568,9 +586,8 @@
             }
         }
 
-        private void onLayoutForTiles(int left, int top, int right, int bottom) {
+        private void onLayoutForTiles() {
             final int count = getChildCount();
-            final int width = right - left;
 
             // Just line up children horizontally.
             int childLeft = 0;
@@ -587,9 +604,9 @@
         @Override
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             switch (mItemViewType) {
-                case ViewTypes.STARRED_WITH_SECONDARY_ACTION:
+                case ViewTypes.STARRED_PHONE:
                 case ViewTypes.STARRED:
-                    onMeasureForTiles(widthMeasureSpec, heightMeasureSpec);
+                    onMeasureForTiles(widthMeasureSpec);
                     return;
                 default:
                     super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -597,7 +614,7 @@
             }
         }
 
-        private void onMeasureForTiles(int widthMeasureSpec, int heightMeasureSpec) {
+        private void onMeasureForTiles(int widthMeasureSpec) {
             final int width = MeasureSpec.getSize(widthMeasureSpec);
 
             final int childCount = getChildCount();
@@ -665,10 +682,6 @@
         public static final int STARRED = 0;
         public static final int DIVIDER = 1;
         public static final int FREQUENT = 2;
-        public static final int STARRED_WITH_SECONDARY_ACTION = 3;
-    }
-
-    public interface Listener {
-        public void onContactSelected(Uri contactUri, Rect targetRect);
+        public static final int STARRED_PHONE = 3;
     }
 }
diff --git a/src/com/android/contacts/list/ContactTileFrequentFragment.java b/src/com/android/contacts/list/ContactTileFrequentFragment.java
index d958c95..73ff6cc 100644
--- a/src/com/android/contacts/list/ContactTileFrequentFragment.java
+++ b/src/com/android/contacts/list/ContactTileFrequentFragment.java
@@ -15,27 +15,13 @@
  */
 package com.android.contacts.list;
 
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactTileLoaderFactory;
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
-import com.android.contacts.list.ContactTileAdapter.DisplayType;
 
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.CursorLoader;
-import android.content.Loader;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ListView;
-import android.widget.TextView;
 
 /**
  * Fragment containing a list of frequently contacted people.
diff --git a/src/com/android/contacts/list/ContactTileDarkFrequentView.java b/src/com/android/contacts/list/ContactTileFrequentView.java
similarity index 61%
rename from src/com/android/contacts/list/ContactTileDarkFrequentView.java
rename to src/com/android/contacts/list/ContactTileFrequentView.java
index 78f45bd..0bd6729 100644
--- a/src/com/android/contacts/list/ContactTileDarkFrequentView.java
+++ b/src/com/android/contacts/list/ContactTileFrequentView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 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.
@@ -15,19 +15,26 @@
  */
 package com.android.contacts.list;
 
+import com.android.contacts.util.ViewUtil;
+
 import android.content.Context;
 import android.util.AttributeSet;
 
 /**
- * A dark version of the {@link ContactTileView} (This class is needed to load the proper avatar)
+ * A {@link ContactTileView} that is used for most frequently contacted in the People app
  */
-public class ContactTileDarkFrequentView extends ContactTileView {
-    public ContactTileDarkFrequentView(Context context, AttributeSet attrs) {
+public class ContactTileFrequentView extends ContactTileView {
+    public ContactTileFrequentView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
     protected boolean isDarkTheme() {
-        return true;
+        return false;
+    }
+
+    @Override
+    protected int getApproximateImageSize() {
+        return ViewUtil.getConstantPreLayoutWidth(getQuickContact());
     }
 }
diff --git a/src/com/android/contacts/list/ContactTileImageContainer.java b/src/com/android/contacts/list/ContactTileImageContainer.java
deleted file mode 100644
index e1a791b..0000000
--- a/src/com/android/contacts/list/ContactTileImageContainer.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.list;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-/**
- * Custom container for ImageView or ContactBadge inside {@link ContactTileView}.
- *
- * This improves the performance of favorite tabs by not passing the layout request to the parent
- * views, assuming that once measured this will not need to resize itself.
- */
-public class ContactTileImageContainer extends FrameLayout {
-
-    public ContactTileImageContainer(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public void requestLayout() {
-        forceLayout();
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/ContactTileListFragment.java b/src/com/android/contacts/list/ContactTileListFragment.java
index d4d961b..4ee20f5 100644
--- a/src/com/android/contacts/list/ContactTileListFragment.java
+++ b/src/com/android/contacts/list/ContactTileListFragment.java
@@ -19,6 +19,7 @@
 import com.android.contacts.ContactTileLoaderFactory;
 import com.android.contacts.R;
 import com.android.contacts.list.ContactTileAdapter.DisplayType;
+import com.android.contacts.util.PhoneCapabilityTester;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -31,6 +32,7 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -49,23 +51,24 @@
     private static final String TAG = ContactTileListFragment.class.getSimpleName();
 
     public interface Listener {
-        public void onContactSelected(Uri contactUri, Rect targetRect);
+        void onContactSelected(Uri contactUri, Rect targetRect);
+        void onCallNumberDirectly(String phoneNumber);
     }
 
-    private static int LOADER_CONTACTS = 1;
-
     private Listener mListener;
     private ContactTileAdapter mAdapter;
     private DisplayType mDisplayType;
     private TextView mEmptyView;
     private ListView mListView;
 
+    private boolean mOptionsMenuHasFrequents;
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
 
         Resources res = getResources();
-        int columnCount = res.getInteger(R.integer.contact_tile_column_count);
+        int columnCount = res.getInteger(R.integer.contact_tile_column_count_in_favorites);
 
         mAdapter = new ContactTileAdapter(activity, mAdapterListener,
                 columnCount, mDisplayType);
@@ -94,8 +97,35 @@
     @Override
     public void onStart() {
         super.onStart();
-        // TODO: Use initLoader?
-        getLoaderManager().restartLoader(LOADER_CONTACTS, null, mContactTileLoaderListener);
+
+        // initialize the loader for this display type and destroy all others
+        final DisplayType[] loaderTypes = mDisplayType.values();
+        for (int i = 0; i < loaderTypes.length; i++) {
+            if (loaderTypes[i] == mDisplayType) {
+                getLoaderManager().initLoader(mDisplayType.ordinal(), null,
+                        mContactTileLoaderListener);
+            } else {
+                getLoaderManager().destroyLoader(loaderTypes[i].ordinal());
+            }
+        }
+    }
+
+    /**
+     * Returns whether there are any frequents with the side effect of setting the
+     * internal flag mOptionsMenuHasFrequents to the value.  This should be called externally
+     * by the activity that is about to prepare the options menu with the clear frequents
+     * menu item.
+     */
+    public boolean hasFrequents() {
+        mOptionsMenuHasFrequents = internalHasFrequents();
+        return mOptionsMenuHasFrequents;
+    }
+
+    /**
+     * Returns whether there are any frequents.
+     */
+    private boolean internalHasFrequents() {
+        return mAdapter.getNumFrequents() > 0;
     }
 
     public void setColumnCount(int columnCount) {
@@ -136,12 +166,25 @@
             mAdapter.setContactCursor(data);
             mEmptyView.setText(getEmptyStateText());
             mListView.setEmptyView(mEmptyView);
+
+            // invalidate the menu options if needed
+            invalidateOptionsMenuIfNeeded();
         }
 
         @Override
         public void onLoaderReset(Loader<Cursor> loader) {}
     };
 
+    private boolean isOptionsMenuChanged() {
+        return mOptionsMenuHasFrequents != internalHasFrequents();
+    }
+
+    private void invalidateOptionsMenuIfNeeded() {
+        if (isOptionsMenuChanged()) {
+            getActivity().invalidateOptionsMenu();
+        }
+    }
+
     private String getEmptyStateText() {
         String emptyText;
         switch (mDisplayType) {
@@ -164,13 +207,25 @@
         mListener = listener;
     }
 
-    private ContactTileAdapter.Listener mAdapterListener =
-            new ContactTileAdapter.Listener() {
+    private ContactTileView.Listener mAdapterListener =
+            new ContactTileView.Listener() {
         @Override
         public void onContactSelected(Uri contactUri, Rect targetRect) {
             if (mListener != null) {
                 mListener.onContactSelected(contactUri, targetRect);
             }
         }
+
+        @Override
+        public void onCallNumberDirectly(String phoneNumber) {
+            if (mListener != null) {
+                mListener.onCallNumberDirectly(phoneNumber);
+            }
+        }
+
+        @Override
+        public int getApproximateTileWidth() {
+            return getView().getWidth() / mAdapter.getColumnCount();
+        }
     };
 }
diff --git a/src/com/android/contacts/list/ContactTilePhoneFrequentView.java b/src/com/android/contacts/list/ContactTilePhoneFrequentView.java
new file mode 100644
index 0000000..88796ba
--- /dev/null
+++ b/src/com/android/contacts/list/ContactTilePhoneFrequentView.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 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.contacts.list;
+
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.list.ContactTileAdapter.ContactEntry;
+import com.android.contacts.util.ViewUtil;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * A dark version of the {@link ContactTileView} that is used in Dialtacts
+ * for frequently called contacts. Slightly different behavior from superclass...
+ * when you tap it, you want to call the frequently-called number for the
+ * contact, even if that is not the default number for that contact.
+ */
+public class ContactTilePhoneFrequentView extends ContactTileView {
+    private String mPhoneNumberString;
+
+    public ContactTilePhoneFrequentView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected boolean isDarkTheme() {
+        return true;
+    }
+
+    @Override
+    protected int getApproximateImageSize() {
+        return ViewUtil.getConstantPreLayoutWidth(getQuickContact());
+    }
+
+    @Override
+    public void loadFromContact(ContactEntry entry) {
+        super.loadFromContact(entry);
+        mPhoneNumberString = null; // ... in case we're reusing the view
+        if (entry != null) {
+            // Grab the phone-number to call directly... see {@link onClick()}
+            mPhoneNumberString = entry.phoneNumber;
+        }
+    }
+
+    @Override
+    protected OnClickListener createClickListener() {
+        return new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mListener == null) return;
+                if (TextUtils.isEmpty(mPhoneNumberString)) {
+                    // Copy "superclass" implementation
+                    mListener.onContactSelected(getLookupUri(), ContactsUtils.getTargetRectFromView(
+                            mContext, ContactTilePhoneFrequentView.this));
+                } else {
+                    // When you tap a frequently-called contact, you want to
+                    // call them at the number that you usually talk to them
+                    // at (i.e. the one displayed in the UI), regardless of
+                    // whether that's their default number.
+                    mListener.onCallNumberDirectly(mPhoneNumberString);
+                }
+            }
+        };
+    }
+}
diff --git a/src/com/android/contacts/list/ContactTileSecondaryTargetView.java b/src/com/android/contacts/list/ContactTilePhoneStarredView.java
similarity index 60%
rename from src/com/android/contacts/list/ContactTileSecondaryTargetView.java
rename to src/com/android/contacts/list/ContactTilePhoneStarredView.java
index c4ea212..fc53782 100644
--- a/src/com/android/contacts/list/ContactTileSecondaryTargetView.java
+++ b/src/com/android/contacts/list/ContactTilePhoneStarredView.java
@@ -24,17 +24,13 @@
 import android.widget.ImageButton;
 
 /**
- * A {@link ContactTileSecondaryTargetView} displays the contact's picture overlayed with their name
- * in a perfect square like the {@link ContactTileStarredView}. However it adds in an additional
- * touch target for a secondary action.
+ * Displays the contact's picture overlayed with their name
+ * in a perfect square. It also has an additional touch target for a secondary action.
  */
-public class ContactTileSecondaryTargetView extends ContactTileStarredView {
-
-    private final static String TAG = ContactTileSecondaryTargetView.class.getSimpleName();
-
+public class ContactTilePhoneStarredView extends ContactTileView {
     private ImageButton mSecondaryButton;
 
-    public ContactTileSecondaryTargetView(Context context, AttributeSet attrs) {
+    public ContactTilePhoneStarredView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
@@ -46,7 +42,11 @@
         mSecondaryButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                getContext().startActivity(new Intent(Intent.ACTION_VIEW, getLookupUri()));
+                Intent intent = new Intent(Intent.ACTION_VIEW, getLookupUri());
+                // Secondary target will be visible only from phone's favorite screen, then
+                // we want to launch it as a separate People task.
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                getContext().startActivity(intent);
             }
         });
     }
@@ -55,4 +55,10 @@
     protected boolean isDarkTheme() {
         return true;
     }
+
+    @Override
+    protected int getApproximateImageSize() {
+        // The picture is the full size of the tile (minus some padding, but we can be generous)
+        return mListener.getApproximateTileWidth();
+    }
 }
diff --git a/src/com/android/contacts/list/ContactTileStarredView.java b/src/com/android/contacts/list/ContactTileStarredView.java
index 3be6bf2..ee76d4d 100644
--- a/src/com/android/contacts/list/ContactTileStarredView.java
+++ b/src/com/android/contacts/list/ContactTileStarredView.java
@@ -20,18 +20,22 @@
 
 /**
  * A {@link ContactTileStarredView} displays the contact's picture overlayed with their name
- * in a square.  The actual dimensions are set by
+ * in a square. The actual dimensions are set by
  * {@link com.android.contacts.list.ContactTileAdapter.ContactTileRow}.
  */
 public class ContactTileStarredView extends ContactTileView {
-    private final static String TAG = ContactTileStarredView.class.getSimpleName();
-
     public ContactTileStarredView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
-    protected boolean isDefaultIconHires() {
-        return true;
+    protected boolean isDarkTheme() {
+        return false;
+    }
+
+    @Override
+    protected int getApproximateImageSize() {
+        // The picture is the full size of the tile (minus some padding, but we can be generous)
+        return mListener.getApproximateTileWidth();
     }
 }
diff --git a/src/com/android/contacts/list/ContactTileView.java b/src/com/android/contacts/list/ContactTileView.java
index 0b90c44..528e7a3 100644
--- a/src/com/android/contacts/list/ContactTileView.java
+++ b/src/com/android/contacts/list/ContactTileView.java
@@ -16,10 +16,12 @@
 package com.android.contacts.list;
 
 import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.list.ContactTileAdapter.ContactEntry;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -30,9 +32,9 @@
 import android.widget.TextView;
 
 /**
- * A ContactTile displays the contact's picture overlayed with their name
+ * A ContactTile displays a contact's picture and name
  */
-public class ContactTileView extends FrameLayout {
+public abstract class ContactTileView extends FrameLayout {
     private final static String TAG = ContactTileView.class.getSimpleName();
 
     private Uri mLookupUri;
@@ -45,7 +47,7 @@
     private ContactPhotoManager mPhotoManager = null;
     private View mPushState;
     private View mHorizontalDivider;
-    private Listener mListener;
+    protected Listener mListener;
 
     public ContactTileView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -64,14 +66,7 @@
         mPushState = findViewById(R.id.contact_tile_push_state);
         mHorizontalDivider = findViewById(R.id.contact_tile_horizontal_divider);
 
-        OnClickListener listener = new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mListener != null) {
-                    mListener.onClick(ContactTileView.this);
-                }
-            }
-        };
+        OnClickListener listener = createClickListener();
 
         if(mPushState != null) {
             mPushState.setOnClickListener(listener);
@@ -80,6 +75,18 @@
         }
     }
 
+    protected OnClickListener createClickListener() {
+        return new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mListener == null) return;
+                mListener.onContactSelected(
+                        getLookupUri(),
+                        ContactsUtils.getTargetRectFromView(mContext, ContactTileView.this));
+            }
+        };
+    }
+
     public void setPhotoManager(ContactPhotoManager photoManager) {
         mPhotoManager = photoManager;
     }
@@ -118,7 +125,7 @@
 
             if (mPhotoManager != null) {
                 if (mPhoto != null) {
-                    mPhotoManager.loadPhoto(mPhoto, entry.photoUri, isDefaultIconHires(),
+                    mPhotoManager.loadPhoto(mPhoto, entry.photoUri, getApproximateImageSize(),
                             isDarkTheme());
 
                     if (mQuickContact != null) {
@@ -126,10 +133,9 @@
                     }
                 } else if (mQuickContact != null) {
                     mQuickContact.assignContactUri(mLookupUri);
-                    mPhotoManager.loadPhoto(mQuickContact, entry.photoUri, isDefaultIconHires(),
-                            isDarkTheme());
+                    mPhotoManager.loadPhoto(mQuickContact, entry.photoUri,
+                            getApproximateImageSize(), isDarkTheme());
                 }
-
             } else {
                 Log.w(TAG, "contactPhotoManager not set");
             }
@@ -156,15 +162,31 @@
         return mLookupUri;
     }
 
-    protected boolean isDefaultIconHires() {
-        return false;
+    protected QuickContactBadge getQuickContact() {
+        return mQuickContact;
     }
 
-    protected boolean isDarkTheme() {
-        return false;
-    }
+    /**
+     * Implemented by subclasses to estimate the size of the picture. This can return -1 if only
+     * a thumbnail is shown anyway
+     */
+    protected abstract int getApproximateImageSize();
+
+    protected abstract boolean isDarkTheme();
 
     public interface Listener {
-        void onClick(ContactTileView contactTileView);
+        /**
+         * Notification that the contact was selected; no specific action is dictated.
+         */
+        void onContactSelected(Uri contactLookupUri, Rect viewRect);
+        /**
+         * Notification that the specified number is to be called.
+         */
+        void onCallNumberDirectly(String phoneNumber);
+        /**
+         * @return The width of each tile. This doesn't have to be a precise number (e.g. paddings
+         *         can be ignored), but is used to load the correct picture size from the database
+         */
+        int getApproximateTileWidth();
     }
 }
diff --git a/src/com/android/contacts/list/ContactsIntentResolver.java b/src/com/android/contacts/list/ContactsIntentResolver.java
index 8d14591..9199766 100644
--- a/src/com/android/contacts/list/ContactsIntentResolver.java
+++ b/src/com/android/contacts/list/ContactsIntentResolver.java
@@ -18,6 +18,7 @@
 
 import com.android.contacts.CallContactActivity;
 import com.android.contacts.ContactsSearchManager;
+import com.android.contacts.ContactsUtils;
 
 import android.app.Activity;
 import android.app.SearchManager;
@@ -33,6 +34,7 @@
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Intents;
+import android.provider.ContactsContract.Intents.Insert;
 import android.provider.ContactsContract.Intents.UI;
 import android.text.TextUtils;
 import android.util.Log;
@@ -124,16 +126,22 @@
         } else if (Intent.ACTION_INSERT_OR_EDIT.equals(action)) {
             request.setActionCode(ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT);
         } else if (Intent.ACTION_SEARCH.equals(action)) {
+            String query = intent.getStringExtra(SearchManager.QUERY);
             // See if the suggestion was clicked with a search action key (call button)
             if ("call".equals(intent.getStringExtra(SearchManager.ACTION_MSG))) {
-                String query = intent.getStringExtra(SearchManager.QUERY);
                 if (!TextUtils.isEmpty(query)) {
-                    Intent newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            Uri.fromParts("tel", query, null));
-                    request.setRedirectIntent(newIntent);
+                    request.setRedirectIntent(ContactsUtils.getCallIntent(query));
                 }
             } else {
-                request.setQueryString(intent.getStringExtra(SearchManager.QUERY));
+                // If the {@link SearchManager.QUERY} is empty, then check if a phone number
+                // or email is specified, in that priority.
+                if (TextUtils.isEmpty(query)) {
+                    query = intent.getStringExtra(Insert.PHONE);
+                }
+                if (TextUtils.isEmpty(query)) {
+                    query = intent.getStringExtra(Insert.EMAIL);
+                }
+                request.setQueryString(query);
                 request.setSearchMode(true);
             }
         } else if (Intent.ACTION_VIEW.equals(action)) {
@@ -182,7 +190,7 @@
                 intent.setData(null);
             }
         } else if (Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED.equals(action)) {
-            request.setRedirectIntent(new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData()));
+            request.setRedirectIntent(ContactsUtils.getCallIntent(intent.getData()));
         } else if (Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED.equals(action)) {
             // TODO actually support this in EditContactActivity.
             String number = intent.getData().getSchemeSpecificPart();
diff --git a/src/com/android/contacts/list/ContactsUnavailableFragment.java b/src/com/android/contacts/list/ContactsUnavailableFragment.java
index 74a578f..b645425 100644
--- a/src/com/android/contacts/list/ContactsUnavailableFragment.java
+++ b/src/com/android/contacts/list/ContactsUnavailableFragment.java
@@ -18,6 +18,7 @@
 import com.android.contacts.R;
 
 import android.app.Fragment;
+import android.content.Context;
 import android.os.Bundle;
 import android.provider.ContactsContract.ProviderStatus;
 import android.view.Gravity;
@@ -35,8 +36,6 @@
  */
 public class ContactsUnavailableFragment extends Fragment implements OnClickListener {
 
-    private ProviderStatusLoader mProviderStatusLoader;
-
     private View mView;
     private TextView mMessageView;
     private TextView mSecondaryMessageView;
@@ -51,6 +50,13 @@
 
     private OnContactsUnavailableActionListener mListener;
 
+    private ProviderStatusWatcher.Status mProviderStatus;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
     @Override
     public View onCreateView(
             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -68,7 +74,11 @@
         mRetryUpgradeButton = (Button) mView.findViewById(R.id.import_failure_retry_button);
         mRetryUpgradeButton.setOnClickListener(this);
         mProgress = (ProgressBar) mView.findViewById(R.id.progress);
-        update();
+
+        if (mProviderStatus != null) {
+            updateStatus(mProviderStatus);
+        }
+
         return mView;
     }
 
@@ -77,13 +87,13 @@
         mListener = listener;
     }
 
-    public void setProviderStatusLoader(ProviderStatusLoader loader) {
-        mProviderStatusLoader = loader;
-    }
-
-    public void update() {
-        int providerStatus = mProviderStatusLoader.getProviderStatus();
-        switch (providerStatus) {
+    public void updateStatus(ProviderStatusWatcher.Status providerStatus) {
+        mProviderStatus = providerStatus;
+        if (mView == null) {
+            // The view hasn't been inflated yet.
+            return;
+        }
+        switch (providerStatus.status) {
             case ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS:
                 setMessageText(mNoContactsMsgResId, mNSecNoContactsMsgResId);
                 mCreateContactButton.setVisibility(View.VISIBLE);
@@ -120,7 +130,7 @@
 
             case ProviderStatus.STATUS_UPGRADE_OUT_OF_MEMORY:
                 String message = getResources().getString(R.string.upgrade_out_of_memory,
-                        new Object[] { mProviderStatusLoader.getProviderStatusData() });
+                        new Object[] { providerStatus.data});
                 mMessageView.setText(message);
                 mMessageView.setGravity(Gravity.LEFT);
                 mMessageView.setVisibility(View.VISIBLE);
@@ -153,7 +163,10 @@
                 mListener.onFreeInternalStorageAction();
                 break;
             case R.id.import_failure_retry_button:
-                mProviderStatusLoader.retryUpgrade();
+                final Context context = getActivity();
+                if (context != null) { // Just in case.
+                    ProviderStatusWatcher.retryUpgrade(context);
+                }
                 break;
         }
     }
@@ -165,9 +178,8 @@
     public void setMessageText(int resId, int secResId) {
         mNoContactsMsgResId = resId;
         mNSecNoContactsMsgResId = secResId;
-        if (mMessageView != null &&
-                mProviderStatusLoader.getProviderStatus() ==
-                    ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS) {
+        if ((mMessageView != null) && (mProviderStatus != null) &&
+                (mProviderStatus.status == ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS)) {
             if (resId != -1) {
                 mMessageView.setText(mNoContactsMsgResId);
                 mMessageView.setGravity(Gravity.CENTER_HORIZONTAL);
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index 4bf1a04..e358f6f 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -28,12 +28,12 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.Button;
 import android.widget.FrameLayout;
 import android.widget.ListView;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 
 /**
@@ -53,14 +53,16 @@
     private Button mProfileMessage;
     private FrameLayout mMessageContainer;
     private TextView mProfileTitle;
-
-    private View mPaddingView;
+    private View mSearchProgress;
+    private TextView mSearchProgressText;
 
     private class FilterHeaderClickListener implements OnClickListener {
         @Override
         public void onClick(View view) {
             AccountFilterUtil.startAccountFilterActivityForResult(
-                        DefaultContactBrowseListFragment.this, REQUEST_CODE_ACCOUNT_FILTER);
+                        DefaultContactBrowseListFragment.this,
+                        REQUEST_CODE_ACCOUNT_FILTER,
+                        getFilter());
         }
     }
     private OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener();
@@ -85,7 +87,7 @@
     protected ContactListAdapter createListAdapter() {
         DefaultContactListAdapter adapter = new DefaultContactListAdapter(getContext());
         adapter.setSectionHeaderDisplayEnabled(isSectionHeaderDisplayEnabled());
-        adapter.setDisplayPhotos(true);
+        adapter.setDisplayPhotos(getResources().getBoolean(R.bool.config_browse_list_show_images));
         return adapter;
     }
 
@@ -114,12 +116,21 @@
         headerContainer.addView(mSearchHeaderView);
         getListView().addHeaderView(headerContainer, null, false);
         checkHeaderViewVisibility();
+
+        mSearchProgress = getView().findViewById(R.id.search_progress);
+        mSearchProgressText = (TextView) mSearchHeaderView.findViewById(R.id.totalContactsText);
     }
 
     @Override
     protected void setSearchMode(boolean flag) {
         super.setSearchMode(flag);
         checkHeaderViewVisibility();
+        if (!flag) showSearchProgress(false);
+    }
+
+    /** Show or hide the directory-search progress spinner. */
+    private void showSearchProgress(boolean show) {
+        mSearchProgress.setVisibility(show ? View.VISIBLE : View.GONE);
     }
 
     private void checkHeaderViewVisibility() {
@@ -147,7 +158,7 @@
         final ContactListFilter filter = getFilter();
         if (filter != null && !isSearchMode()) {
             final boolean shouldShowHeader = AccountFilterUtil.updateAccountFilterTitleForPeople(
-                    mAccountFilterHeader, filter, false, false);
+                    mAccountFilterHeader, filter, false);
             mAccountFilterHeader.setVisibility(shouldShowHeader ? View.VISIBLE : View.GONE);
         } else {
             mAccountFilterHeader.setVisibility(View.GONE);
@@ -200,19 +211,17 @@
             // In search mode we only display the header if there is nothing found
             if (TextUtils.isEmpty(getQueryString()) || !adapter.areAllPartitionsEmpty()) {
                 mSearchHeaderView.setVisibility(View.GONE);
+                showSearchProgress(false);
             } else {
-                TextView textView = (TextView) mSearchHeaderView.findViewById(
-                        R.id.totalContactsText);
-                ProgressBar progress = (ProgressBar) mSearchHeaderView.findViewById(
-                        R.id.progress);
                 mSearchHeaderView.setVisibility(View.VISIBLE);
                 if (adapter.isLoading()) {
-                    textView.setText(R.string.search_results_searching);
-                    progress.setVisibility(View.VISIBLE);
+                    mSearchProgressText.setText(R.string.search_results_searching);
+                    showSearchProgress(true);
                 } else {
-                    textView.setText(R.string.listFoundAllContactsZero);
-                    textView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-                    progress.setVisibility(View.GONE);
+                    mSearchProgressText.setText(R.string.listFoundAllContactsZero);
+                    mSearchProgressText.sendAccessibilityEvent(
+                            AccessibilityEvent.TYPE_VIEW_SELECTED);
+                    showSearchProgress(false);
                 }
             }
             showEmptyUserProfile(false);
@@ -247,8 +256,6 @@
         mProfileTitle.setVisibility(show ? View.VISIBLE : View.GONE);
         mMessageContainer.setVisibility(show ? View.VISIBLE : View.GONE);
         mProfileMessage.setVisibility(show ? View.VISIBLE : View.GONE);
-
-        mPaddingView.setVisibility(show ? View.GONE : View.VISIBLE);
     }
 
     /**
@@ -284,11 +291,5 @@
                 startActivity(intent);
             }
         });
-
-        View paddingViewContainer =
-                inflater.inflate(R.layout.contact_detail_list_padding, null, false);
-        mPaddingView = paddingViewContainer.findViewById(R.id.contact_detail_list_padding);
-        mPaddingView.setVisibility(View.GONE);
-        getListView().addHeaderView(paddingViewContainer);
     }
 }
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index 348abb9..a53914d 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -26,9 +26,7 @@
 import android.net.Uri.Builder;
 import android.preference.PreferenceManager;
 import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.SearchSnippetColumns;
@@ -124,9 +122,13 @@
         if (filter != null
                 && filter.filterType != ContactListFilter.FILTER_TYPE_CUSTOM
                 && filter.filterType != ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
-            uri = uri.buildUpon().appendQueryParameter(
-                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
-                    .build();
+            final Uri.Builder builder = uri.buildUpon();
+            builder.appendQueryParameter(
+                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT));
+            if (filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
+                filter.addAccountQueryParameterToUrl(builder);
+            }
+            uri = builder.build();
         }
 
         loader.setUri(uri);
@@ -172,22 +174,7 @@
                 break;
             }
             case ContactListFilter.FILTER_TYPE_ACCOUNT: {
-                // TODO: avoid the use of private API
-                selection.append(
-                        Contacts._ID + " IN ("
-                                + "SELECT DISTINCT " + RawContacts.CONTACT_ID
-                                + " FROM raw_contacts"
-                                + " WHERE " + RawContacts.ACCOUNT_TYPE + "=?"
-                                + " AND " + RawContacts.ACCOUNT_NAME + "=?");
-                selectionArgs.add(filter.accountType);
-                selectionArgs.add(filter.accountName);
-                if (filter.dataSet != null) {
-                    selection.append(" AND " + RawContacts.DATA_SET + "=?");
-                    selectionArgs.add(filter.dataSet);
-                } else {
-                    selection.append(" AND " + RawContacts.DATA_SET + " IS NULL");
-                }
-                selection.append(")");
+                // We use query parameters for account filter, so no selection to add here.
                 break;
             }
         }
@@ -209,9 +196,12 @@
 
         if (isQuickContactEnabled()) {
             bindQuickContact(view, partition, cursor, ContactQuery.CONTACT_PHOTO_ID,
-                    ContactQuery.CONTACT_ID, ContactQuery.CONTACT_LOOKUP_KEY);
+                    ContactQuery.CONTACT_PHOTO_URI, ContactQuery.CONTACT_ID,
+                    ContactQuery.CONTACT_LOOKUP_KEY);
         } else {
-            bindPhoto(view, partition, cursor);
+            if (getDisplayPhotos()) {
+                bindPhoto(view, partition, cursor);
+            }
         }
 
         bindName(view, cursor);
diff --git a/src/com/android/contacts/list/EmailAddressListAdapter.java b/src/com/android/contacts/list/EmailAddressListAdapter.java
index 93f435e..c85abdd 100644
--- a/src/com/android/contacts/list/EmailAddressListAdapter.java
+++ b/src/com/android/contacts/list/EmailAddressListAdapter.java
@@ -78,6 +78,9 @@
             builder.appendPath(TextUtils.isEmpty(query) ? "" : query);
         } else {
             builder = Email.CONTENT_URI.buildUpon();
+            if (isSectionHeaderDisplayEnabled()) {
+                builder.appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true");
+            }
         }
         builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
                 String.valueOf(directoryId));
@@ -97,11 +100,6 @@
         }
     }
 
-    protected static Builder buildSectionIndexerUri(Uri uri) {
-        return uri.buildUpon()
-                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true");
-    }
-
     @Override
     public String getContactDisplayName(int position) {
         return ((Cursor) getItem(position)).getString(EmailQuery.EMAIL_DISPLAY_NAME);
@@ -112,7 +110,7 @@
      * position.
      */
     public Uri getDataUri(int position) {
-        long id = ((Cursor)getItem(position)).getLong(EmailQuery.EMAIL_ID);
+        long id = ((Cursor) getItem(position)).getLong(EmailQuery.EMAIL_ID);
         return ContentUris.withAppendedId(Data.CONTENT_URI, id);
     }
 
@@ -175,7 +173,7 @@
             photoId = cursor.getLong(EmailQuery.EMAIL_PHOTO_ID);
         }
 
-        getPhotoLoader().loadPhoto(view.getPhotoView(), photoId, false, false);
+        getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false);
     }
 //
 //    protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
diff --git a/src/com/android/contacts/list/EmailAddressPickerFragment.java b/src/com/android/contacts/list/EmailAddressPickerFragment.java
index 14b6c23..13fe541 100644
--- a/src/com/android/contacts/list/EmailAddressPickerFragment.java
+++ b/src/com/android/contacts/list/EmailAddressPickerFragment.java
@@ -58,6 +58,13 @@
         return inflater.inflate(R.layout.contact_list_content, null);
     }
 
+    @Override
+    protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
+        super.onCreateView(inflater, container);
+
+        setVisibleScrollbarEnabled(!isLegacyCompatibilityMode());
+    }
+
     private void pickEmailAddress(Uri uri) {
         mListener.onPickEmailAddressAction(uri);
     }
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index bfe8c53..80ddc83 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.CursorLoader;
 import android.database.Cursor;
-import android.database.MatrixCursor;
 import android.net.Uri;
 import android.net.Uri.Builder;
 import android.provider.ContactsContract;
@@ -53,7 +52,6 @@
 
     @Override
     protected void addPartitions() {
-
         // Partition 0: suggestions
         addPartition(false, true);
 
@@ -69,11 +67,11 @@
     public void configureLoader(CursorLoader cursorLoader, long directoryId) {
         JoinContactLoader loader = (JoinContactLoader) cursorLoader;
 
-        Builder builder = Contacts.CONTENT_URI.buildUpon();
+        final Builder builder = Contacts.CONTENT_URI.buildUpon();
         builder.appendEncodedPath(String.valueOf(mTargetContactId));
         builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY);
 
-        String filter = getQueryString();
+        final String filter = getQueryString();
         if (!TextUtils.isEmpty(filter)) {
             builder.appendEncodedPath(Uri.encode(filter));
         }
@@ -84,13 +82,22 @@
 
         // TODO simplify projection
         loader.setProjection(getProjection(false));
-        Uri allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_URI).buildUpon()
+        final Uri allContactsUri;
+        if (!TextUtils.isEmpty(filter)) {
+            allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_FILTER_URI).buildUpon()
+                .appendEncodedPath(Uri.encode(filter))
                 .appendQueryParameter(
                         ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
                 .build();
+        } else {
+            allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_URI).buildUpon()
+                .appendQueryParameter(
+                        ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
+                .build();
+        }
         loader.setUri(allContactsUri);
         loader.setSelection(Contacts._ID + "!=?");
-        loader.setSelectionArgs(new String[]{String.valueOf(mTargetContactId)});
+        loader.setSelectionArgs(new String[]{ String.valueOf(mTargetContactId) });
         if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
             loader.setSortOrder(Contacts.SORT_KEY_PRIMARY);
         } else {
@@ -120,7 +127,7 @@
 
     @Override
     public int getViewTypeCount() {
-        return super.getViewTypeCount() + 1;
+        return super.getViewTypeCount();
     }
 
     @Override
@@ -173,14 +180,14 @@
     protected void bindView(View itemView, int partition, Cursor cursor, int position) {
         switch (partition) {
             case PARTITION_SUGGESTIONS: {
-                final ContactListItemView view = (ContactListItemView)itemView;
+                final ContactListItemView view = (ContactListItemView) itemView;
                 view.setSectionHeader(null);
                 bindPhoto(view, partition, cursor);
                 bindName(view, cursor);
                 break;
             }
             case PARTITION_ALL_CONTACTS: {
-                final ContactListItemView view = (ContactListItemView)itemView;
+                final ContactListItemView view = (ContactListItemView) itemView;
                 bindSectionHeaderAndDivider(view, position, cursor);
                 bindPhoto(view, partition, cursor);
                 bindName(view, cursor);
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index 5b27bdf..1c526a5 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -16,6 +16,7 @@
 package com.android.contacts.list;
 
 import com.android.contacts.R;
+import com.android.contacts.list.JoinContactLoader.JoinContactLoaderResult;
 
 import android.app.Activity;
 import android.app.LoaderManager.LoaderCallbacks;
@@ -24,8 +25,10 @@
 import android.content.Intent;
 import android.content.Loader;
 import android.database.Cursor;
+import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -76,13 +79,14 @@
                     break;
                 }
                 case JoinContactListAdapter.PARTITION_ALL_CONTACTS: {
-                    Cursor suggestionsCursor = ((JoinContactLoader) loader).getSuggestionsCursor();
+                    Cursor suggestionsCursor = ((JoinContactLoaderResult) data).suggestionCursor;
                     onContactListLoaded(suggestionsCursor, data);
                     break;
                 }
             }
         }
 
+        @Override
         public void onLoaderReset(Loader<Cursor> loader) {
         }
     };
@@ -103,7 +107,10 @@
         configureAdapter();
 
         getLoaderManager().initLoader(DISPLAY_NAME_LOADER, null, mLoaderCallbacks);
-        getLoaderManager().initLoader(JoinContactListAdapter.PARTITION_ALL_CONTACTS,
+
+        // When this method is called, Uri to be used may be changed. We should use restartLoader()
+        // to load the parameter again.
+        getLoaderManager().restartLoader(JoinContactListAdapter.PARTITION_ALL_CONTACTS,
                 null, mLoaderCallbacks);
     }
 
@@ -144,14 +151,14 @@
 
     @Override
     protected void onItemClick(int position, long id) {
-        JoinContactListAdapter adapter = getAdapter();
-        int partition = adapter.getPartitionForPosition(position);
-        mListener.onPickContactAction(adapter.getContactUri(position));
+        final Uri contactUri = getAdapter().getContactUri(position);
+        if (contactUri != null) mListener.onPickContactAction(contactUri);
     }
 
     @Override
     public void onPickerResult(Intent data) {
-        mListener.onPickContactAction(data.getData());
+        final Uri contactUri = data.getData();
+        if (contactUri != null) mListener.onPickContactAction(contactUri);
     }
 
     @Override
@@ -167,4 +174,11 @@
             mTargetContactId = savedState.getLong(KEY_TARGET_CONTACT_ID);
         }
     }
+
+    @Override
+    public void setQueryString(String queryString, boolean delaySelection) {
+        super.setQueryString(queryString, delaySelection);
+
+        setSearchMode(!TextUtils.isEmpty(queryString));
+    }
 }
diff --git a/src/com/android/contacts/list/JoinContactLoader.java b/src/com/android/contacts/list/JoinContactLoader.java
index 2f1f9b0..beb5208 100644
--- a/src/com/android/contacts/list/JoinContactLoader.java
+++ b/src/com/android/contacts/list/JoinContactLoader.java
@@ -18,18 +18,46 @@
 import android.content.Context;
 import android.content.CursorLoader;
 import android.database.Cursor;
-import android.database.MatrixCursor;
+import android.database.CursorWrapper;
 import android.net.Uri;
 
 /**
  * A specialized loader for the Join Contacts UI.  It executes two queries:
  * join suggestions and (optionally) the full contact list.
+ *
+ * This loader also loads the "suggestion" cursor, which can be accessed with:
+ * {@code ((JoinContactLoaderResult) result).suggestionCursor }
  */
 public class JoinContactLoader extends CursorLoader {
 
     private String[] mProjection;
     private Uri mSuggestionUri;
-    private MatrixCursor mSuggestionsCursor;
+
+    /**
+     * Actual returned class.  It's guaranteed that this loader always returns an instance of this
+     * class.  This class is needed to tie the lifecycle of the second cursor to that of the
+     * primary one.
+     *
+     * Note we can't change the result type of this loader itself, because CursorLoader
+     * extends AsyncTaskLoader<Cursor>, not AsyncTaskLoader<? extends Cursor>
+     */
+    public static class JoinContactLoaderResult extends CursorWrapper {
+        public final Cursor suggestionCursor;
+
+        public JoinContactLoaderResult(Cursor baseCursor, Cursor suggestionCursor) {
+            super(baseCursor);
+            this.suggestionCursor = suggestionCursor;
+        }
+
+        @Override
+        public void close() {
+            try {
+                suggestionCursor.close();
+            } finally {
+                super.close();
+            }
+        }
+    }
 
     public JoinContactLoader(Context context) {
         super(context, null, null, null, null, null);
@@ -45,36 +73,12 @@
         this.mProjection = projection;
     }
 
-    public Cursor getSuggestionsCursor() {
-        return mSuggestionsCursor;
-    }
-
     @Override
     public Cursor loadInBackground() {
         // First execute the suggestions query, then call super.loadInBackground
         // to load the entire list
-        mSuggestionsCursor = loadSuggestions();
-        return super.loadInBackground();
-    }
-
-    /**
-     * Loads join suggestions into a MatrixCursor.
-     */
-    private MatrixCursor loadSuggestions() {
-        Cursor cursor = getContext().getContentResolver().query(mSuggestionUri, mProjection,
-                null, null, null);
-        try {
-            MatrixCursor matrix = new MatrixCursor(mProjection);
-            Object[] row = new Object[mProjection.length];
-            while (cursor.moveToNext()) {
-                for (int i = 0; i < row.length; i++) {
-                    row[i] = cursor.getString(i);
-                }
-                matrix.addRow(row);
-            }
-            return matrix;
-        } finally {
-            cursor.close();
-        }
+        final Cursor suggestionsCursor = getContext().getContentResolver()
+                .query(mSuggestionUri, mProjection, null, null, null);
+        return new JoinContactLoaderResult(super.loadInBackground(), suggestionsCursor);
     }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index 7073a57..170790f 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -18,13 +18,14 @@
 import com.android.contacts.ContactPhotoManager;
 import com.android.contacts.ContactTileLoaderFactory;
 import com.android.contacts.R;
+import com.android.contacts.dialog.ClearFrequentsDialog;
+import com.android.contacts.interactions.ImportExportDialogFragment;
 import com.android.contacts.preference.ContactsPreferences;
 import com.android.contacts.util.AccountFilterUtil;
 
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.LoaderManager;
-import android.content.Context;
 import android.content.CursorLoader;
 import android.content.Intent;
 import android.content.Loader;
@@ -32,9 +33,16 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Directory;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
@@ -69,6 +77,7 @@
 
     public interface Listener {
         public void onContactSelected(Uri contactUri);
+        public void onCallNumberDirectly(String phoneNumber);
     }
 
     private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
@@ -99,6 +108,9 @@
             // Show the filter header with "loading" state.
             updateFilterHeaderView();
             mAccountFilterHeader.setVisibility(View.VISIBLE);
+
+            // invalidate the options menu if needed
+            invalidateOptionsMenuIfNeeded();
         }
 
         @Override
@@ -121,7 +133,8 @@
             if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoadFinished");
             mAllContactsAdapter.changeCursor(0, data);
             updateFilterHeaderView();
-            mAccountFilterHeaderContainer.setVisibility(View.VISIBLE);
+            mHandler.removeMessages(MESSAGE_SHOW_LOADING_EFFECT);
+            mLoadingView.setVisibility(View.VISIBLE);
         }
 
         @Override
@@ -130,20 +143,34 @@
         }
     }
 
-    private class ContactTileAdapterListener implements ContactTileAdapter.Listener {
+    private class ContactTileAdapterListener implements ContactTileView.Listener {
         @Override
         public void onContactSelected(Uri contactUri, Rect targetRect) {
             if (mListener != null) {
                 mListener.onContactSelected(contactUri);
             }
         }
+
+        @Override
+        public void onCallNumberDirectly(String phoneNumber) {
+            if (mListener != null) {
+                mListener.onCallNumberDirectly(phoneNumber);
+            }
+        }
+
+        @Override
+        public int getApproximateTileWidth() {
+            return getView().getWidth() / mContactTileAdapter.getColumnCount();
+        }
     }
 
     private class FilterHeaderClickListener implements OnClickListener {
         @Override
         public void onClick(View view) {
             AccountFilterUtil.startAccountFilterActivityForResult(
-                    PhoneFavoriteFragment.this, REQUEST_CODE_ACCOUNT_FILTER);
+                    PhoneFavoriteFragment.this,
+                    REQUEST_CODE_ACCOUNT_FILTER,
+                    mFilter);
         }
     }
 
@@ -177,6 +204,19 @@
         }
     }
 
+    private static final int MESSAGE_SHOW_LOADING_EFFECT = 1;
+    private static final int LOADING_EFFECT_DELAY = 500;  // ms
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_SHOW_LOADING_EFFECT:
+                    mLoadingView.setVisibility(View.VISIBLE);
+                    break;
+            }
+        }
+    };
+
     private Listener mListener;
     private PhoneFavoriteMergedAdapter mAdapter;
     private ContactTileAdapter mContactTileAdapter;
@@ -204,7 +244,13 @@
     private FrameLayout mAccountFilterHeaderContainer;
     private View mAccountFilterHeader;
 
-    private final ContactTileAdapter.Listener mContactTileAdapterListener =
+    /**
+     * Layout used when contacts load is slower than expected and thus "loading" view should be
+     * shown.
+     */
+    private View mLoadingView;
+
+    private final ContactTileView.Listener mContactTileAdapterListener =
             new ContactTileAdapterListener();
     private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener =
             new ContactTileLoaderListener();
@@ -215,12 +261,62 @@
             new ContactsPreferenceChangeListener();
     private final ScrollListener mScrollListener = new ScrollListener();
 
+    private boolean mOptionsMenuHasFrequents;
+
+    @Override
+    public void onAttach(Activity activity) {
+        if (DEBUG) Log.d(TAG, "onAttach()");
+        super.onAttach(activity);
+
+        mContactsPrefs = new ContactsPreferences(activity);
+
+        // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter.
+        // We don't construct the resultant adapter at this moment since it requires LayoutInflater
+        // that will be available on onCreateView().
+
+        mContactTileAdapter = new ContactTileAdapter(activity, mContactTileAdapterListener,
+                getResources().getInteger(R.integer.contact_tile_column_count_in_favorites),
+                ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
+        mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
+
+        // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment.
+        mAllContactsAdapter = new PhoneNumberListAdapter(activity);
+        mAllContactsAdapter.setDisplayPhotos(true);
+        mAllContactsAdapter.setQuickContactEnabled(true);
+        mAllContactsAdapter.setSearchMode(false);
+        mAllContactsAdapter.setIncludeProfile(false);
+        mAllContactsAdapter.setSelectionVisible(false);
+        mAllContactsAdapter.setDarkTheme(true);
+        mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
+        // Disable directory header.
+        mAllContactsAdapter.setHasHeader(0, false);
+        // Show A-Z section index.
+        mAllContactsAdapter.setSectionHeaderDisplayEnabled(true);
+        // Disable pinned header. It doesn't work with this fragment.
+        mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false);
+        // Put photos on left for consistency with "frequent" contacts section.
+        mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
+
+        // Use Callable.CONTENT_URI which will include not only phone numbers but also SIP
+        // addresses.
+        mAllContactsAdapter.setUseCallableUri(true);
+
+        mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
+        mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder());
+    }
+
     @Override
     public void onCreate(Bundle savedState) {
+        if (DEBUG) Log.d(TAG, "onCreate()");
         super.onCreate(savedState);
         if (savedState != null) {
             mFilter = savedState.getParcelable(KEY_FILTER);
+
+            if (mFilter != null) {
+                mAllContactsAdapter.setFilter(mFilter);
+            }
         }
+        setHasOptionsMenu(true);
     }
 
     @Override
@@ -230,13 +326,6 @@
     }
 
     @Override
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-
-        mContactsPrefs = new ContactsPreferences(activity);
-    }
-
-    @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         final View listLayout = inflater.inflate(
@@ -249,7 +338,18 @@
         mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
         mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
 
-        initAdapters(getActivity(), inflater);
+        // Create the account filter header but keep it hidden until "all" contacts are loaded.
+        mAccountFilterHeaderContainer = new FrameLayout(getActivity(), null);
+        mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite,
+                mListView, false);
+        mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
+        mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
+
+        mLoadingView = inflater.inflate(R.layout.phone_loading_contacts, mListView, false);
+
+        mAdapter = new PhoneFavoriteMergedAdapter(getActivity(),
+                mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter,
+                mLoadingView);
 
         mListView.setAdapter(mAdapter);
 
@@ -266,55 +366,56 @@
         return listLayout;
     }
 
-    /**
-     * Constructs and initializes {@link #mContactTileAdapter}, {@link #mAllContactsAdapter}, and
-     * {@link #mAllContactsAdapter}.
-     *
-     * TODO: Move all the code here to {@link PhoneFavoriteMergedAdapter} if possible.
-     * There are two problems: account header (whose content changes depending on filter settings)
-     * and OnClickListener (which initiates {@link Activity#startActivityForResult(Intent, int)}).
-     * See also issue 5429203, 5269692, and 5432286. If we are able to have a singleton for filter,
-     * this work will become easier.
-     */
-    private void initAdapters(Context context, LayoutInflater inflater) {
-        mContactTileAdapter = new ContactTileAdapter(context, mContactTileAdapterListener,
-                getResources().getInteger(R.integer.contact_tile_column_count),
-                ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
-        mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context));
+    private boolean isOptionsMenuChanged() {
+        return mOptionsMenuHasFrequents != hasFrequents();
+    }
 
-        // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment.
-        mAllContactsAdapter = new PhoneNumberListAdapter(context);
-        mAllContactsAdapter.setDisplayPhotos(true);
-        mAllContactsAdapter.setQuickContactEnabled(true);
-        mAllContactsAdapter.setSearchMode(false);
-        mAllContactsAdapter.setIncludeProfile(false);
-        mAllContactsAdapter.setSelectionVisible(false);
-        mAllContactsAdapter.setDarkTheme(true);
-        mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(context));
-        // Disable directory header.
-        mAllContactsAdapter.setHasHeader(0, false);
-        // Show A-Z section index.
-        mAllContactsAdapter.setSectionHeaderDisplayEnabled(true);
-        // Disable pinned header. It doesn't work with this fragment.
-        mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false);
-        // Put photos on left for consistency with "frequent" contacts section.
-        mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
-
-        if (mFilter != null) {
-            mAllContactsAdapter.setFilter(mFilter);
+    private void invalidateOptionsMenuIfNeeded() {
+        if (isOptionsMenuChanged()) {
+            getActivity().invalidateOptionsMenu();
         }
+    }
 
-        // Create the account filter header but keep it hidden until "all" contacts are loaded.
-        mAccountFilterHeaderContainer = new FrameLayout(context, null);
-        mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite,
-                mListView, false);
-        mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
-        mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
-        mAccountFilterHeaderContainer.setVisibility(View.GONE);
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.phone_favorite_options, menu);
+    }
 
-        mAdapter = new PhoneFavoriteMergedAdapter(context,
-                mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter);
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
+        mOptionsMenuHasFrequents = hasFrequents();
+        clearFrequents.setVisible(mOptionsMenuHasFrequents);
+    }
 
+    private boolean hasFrequents() {
+        return mContactTileAdapter.getNumFrequents() > 0;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_import_export:
+                // We hard-code the "contactsAreAvailable" argument because doing it properly would
+                // involve querying a {@link ProviderStatusLoader}, which we don't want to do right
+                // now in Dialtacts for (potential) performance reasons.  Compare with how it is
+                // done in {@link PeopleActivity}.
+                ImportExportDialogFragment.show(getFragmentManager(), true);
+                return true;
+            case R.id.menu_accounts:
+                final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
+                intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
+                    ContactsContract.AUTHORITY
+                });
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                startActivity(intent);
+                return true;
+            case R.id.menu_clear_frequents:
+                ClearFrequentsDialog.show(getFragmentManager());
+                return true;
+        }
+        return false;
     }
 
     @Override
@@ -329,10 +430,16 @@
             mAllContactsForceReload = true;
         }
 
-        // Use initLoader() instead of reloadLoader() to refraing unnecessary reload.
+        // Use initLoader() instead of restartLoader() to refraining unnecessary reload.
         // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will
         // be called, on which we'll check if "all" contacts should be reloaded again or not.
         getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener);
+
+        // Delay showing "loading" view until certain amount of time so that users won't see
+        // instant flash of the view when the contacts load is fast enough.
+        // This will be kept shown until both tile and all sections are loaded.
+        mLoadingView.setVisibility(View.INVISIBLE);
+        mHandler.sendEmptyMessageDelayed(MESSAGE_SHOW_LOADING_EFFECT, LOADING_EFFECT_DELAY);
     }
 
     @Override
@@ -379,13 +486,15 @@
         }
 
         boolean changed = false;
-        if (mAllContactsAdapter.getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) {
-            mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
+        final int currentDisplayOrder = mContactsPrefs.getDisplayOrder();
+        if (mAllContactsAdapter.getContactNameDisplayOrder() != currentDisplayOrder) {
+            mAllContactsAdapter.setContactNameDisplayOrder(currentDisplayOrder);
             changed = true;
         }
 
-        if (mAllContactsAdapter.getSortOrder() != mContactsPrefs.getSortOrder()) {
-            mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder());
+        final int currentSortOrder = mContactsPrefs.getSortOrder();
+        if (mAllContactsAdapter.getSortOrder() != currentSortOrder) {
+            mAllContactsAdapter.setSortOrder(currentSortOrder);
             changed = true;
         }
 
@@ -422,8 +531,7 @@
         if (mAccountFilterHeader == null || mAllContactsAdapter == null || filter == null) {
             return;
         }
-        AccountFilterUtil.updateAccountFilterTitleForPhone(
-                mAccountFilterHeader, filter, mAllContactsAdapter.isLoading(), true);
+        AccountFilterUtil.updateAccountFilterTitleForPhone(mAccountFilterHeader, filter, true);
     }
 
     public ContactListFilter getFilter() {
@@ -452,4 +560,4 @@
     public void setListener(Listener listener) {
         mListener = listener;
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
index 205e156..d5b62e5 100644
--- a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
@@ -44,6 +44,7 @@
     private final ContactTileAdapter mContactTileAdapter;
     private final ContactEntryListAdapter mContactEntryListAdapter;
     private final View mAccountFilterHeaderContainer;
+    private final View mLoadingView;
 
     private final int mItemPaddingLeft;
     private final int mItemPaddingRight;
@@ -56,7 +57,8 @@
     public PhoneFavoriteMergedAdapter(Context context,
             ContactTileAdapter contactTileAdapter,
             View accountFilterHeaderContainer,
-            ContactEntryListAdapter contactEntryListAdapter) {
+            ContactEntryListAdapter contactEntryListAdapter,
+            View loadingView) {
         Resources resources = context.getResources();
         mItemPaddingLeft = resources.getDimensionPixelSize(R.dimen.detail_item_side_margin);
         mItemPaddingRight = resources.getDimensionPixelSize(R.dimen.list_visible_scrollbar_padding);
@@ -70,6 +72,15 @@
         mObserver = new CustomDataSetObserver();
         mContactTileAdapter.registerDataSetObserver(mObserver);
         mContactEntryListAdapter.registerDataSetObserver(mObserver);
+
+        mLoadingView = loadingView;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        // Cannot use the super's method here because we add extra rows in getCount() to account
+        // for headers
+        return mContactTileAdapter.getCount() + mContactEntryListAdapter.getCount() == 0;
     }
 
     @Override
@@ -77,9 +88,12 @@
         final int contactTileAdapterCount = mContactTileAdapter.getCount();
         final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
         if (mContactEntryListAdapter.isLoading()) {
-            // Hide "all" contacts during its being loaded.
-            return contactTileAdapterCount + 1;
+            // Hide "all" contacts during its being loaded. Instead show "loading" view.
+            //
+            // "+2" for mAccountFilterHeaderContainer and mLoadingView
+            return contactTileAdapterCount + 2;
         } else {
+            // "+1" for mAccountFilterHeaderContainer
             return contactTileAdapterCount + contactEntryListAdapterCount + 1;
         }
     }
@@ -88,13 +102,18 @@
     public Object getItem(int position) {
         final int contactTileAdapterCount = mContactTileAdapter.getCount();
         final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
-        if (position < contactTileAdapterCount) {
+        if (position < contactTileAdapterCount) {  // For "tile" and "frequent" sections
             return mContactTileAdapter.getItem(position);
-        } else if (position == contactTileAdapterCount) {
+        } else if (position == contactTileAdapterCount) {  // For "all" section's account header
             return mAccountFilterHeaderContainer;
-        } else {
-            final int localPosition = position - contactTileAdapterCount - 1;
-            return mContactTileAdapter.getItem(localPosition);
+        } else {  // For "all" section
+            if (mContactEntryListAdapter.isLoading()) {  // "All" section is being loaded.
+                return mLoadingView;
+            } else {
+                // "-1" for mAccountFilterHeaderContainer
+                final int localPosition = position - contactTileAdapterCount - 1;
+                return mContactTileAdapter.getItem(localPosition);
+            }
         }
     }
 
@@ -105,25 +124,63 @@
 
     @Override
     public int getViewTypeCount() {
+        // "+2" for mAccountFilterHeaderContainer and mLoadingView
         return (mContactTileAdapter.getViewTypeCount()
                 + mContactEntryListAdapter.getViewTypeCount()
-                + 1);
+                + 2);
     }
 
     @Override
     public int getItemViewType(int position) {
         final int contactTileAdapterCount = mContactTileAdapter.getCount();
         final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
-        if (position < contactTileAdapterCount) {
+        // There should be four kinds of types that are usually used, and one more exceptional
+        // type (IGNORE_ITEM_VIEW_TYPE), which sometimes comes from mContactTileAdapter.
+        //
+        // The four ordinary view types have the index equal to or more than 0, and less than
+        // mContactTileAdapter.getViewTypeCount()+ mContactEntryListAdapter.getViewTypeCount() + 2.
+        // (See also this class's getViewTypeCount())
+        //
+        // We have those values for:
+        // - The view types mContactTileAdapter originally has
+        // - The view types mContactEntryListAdapter originally has
+        // - mAccountFilterHeaderContainer ("all" section's account header), and
+        // - mLoadingView
+        //
+        // Those types should not be mixed, so we have a different range for each kinds of types:
+        // - Types for mContactTileAdapter ("tile" and "frequent" sections)
+        //   They should have the index, >=0 and <mContactTileAdapter.getViewTypeCount()
+        //
+        // - Types for mContactEntryListAdapter ("all" sections)
+        //   They should have the index, >=mContactTileAdapter.getViewTypeCount() and
+        //   <(mContactTileAdapter.getViewTypeCount() + mContactEntryListAdapter.getViewTypeCount())
+        //
+        // - Type for "all" section's account header
+        //   It should have the exact index
+        //   mContactTileAdapter.getViewTypeCount()+ mContactEntryListAdapter.getViewTypeCount()
+        //
+        // - Type for "loading" view used during "all" section is being loaded.
+        //   It should have the exact index
+        //   mContactTileAdapter.getViewTypeCount()+ mContactEntryListAdapter.getViewTypeCount() + 1
+        //
+        // As an exception, IGNORE_ITEM_VIEW_TYPE (-1) will be remained as is, which will be used
+        // by framework's Adapter implementation and thus should be left as is.
+        if (position < contactTileAdapterCount) {  // For "tile" and "frequent" sections
             return mContactTileAdapter.getItemViewType(position);
-        } else if (position == contactTileAdapterCount) {
+        } else if (position == contactTileAdapterCount) {  // For "all" section's account header
             return mContactTileAdapter.getViewTypeCount()
                     + mContactEntryListAdapter.getViewTypeCount();
-        } else {
-            final int localPosition = position - contactTileAdapterCount - 1;
-            final int type = mContactEntryListAdapter.getItemViewType(localPosition);
-            // IGNORE_ITEM_VIEW_TYPE must be handled differently.
-            return (type < 0) ? type : type + mContactTileAdapter.getViewTypeCount();
+        } else {  // For "all" section
+            if (mContactEntryListAdapter.isLoading()) {  // "All" section is being loaded.
+                return mContactTileAdapter.getViewTypeCount()
+                        + mContactEntryListAdapter.getViewTypeCount() + 1;
+            } else {
+                // "-1" for mAccountFilterHeaderContainer
+                final int localPosition = position - contactTileAdapterCount - 1;
+                final int type = mContactEntryListAdapter.getItemViewType(localPosition);
+                // IGNORE_ITEM_VIEW_TYPE must be handled differently.
+                return (type < 0) ? type : type + mContactTileAdapter.getViewTypeCount();
+            }
         }
     }
 
@@ -134,7 +191,7 @@
 
         // Obtain a View relevant for that position, and adjust its horizontal padding. Each
         // View has different implementation, so we use different way to control those padding.
-        if (position < contactTileAdapterCount) {
+        if (position < contactTileAdapterCount) {  // For "tile" and "frequent" sections
             final View view = mContactTileAdapter.getView(position, convertView, parent);
             final int frequentHeaderPosition = mContactTileAdapter.getFrequentHeaderPosition();
             if (position < frequentHeaderPosition) {  // "starred" contacts
@@ -153,26 +210,39 @@
                 child.setLayoutParams(params);
             }
             return view;
-        } else if (position == contactTileAdapterCount) {
+        } else if (position == contactTileAdapterCount) {  // For "all" section's account header
             mAccountFilterHeaderContainer.setPadding(mItemPaddingLeft,
                     mAccountFilterHeaderContainer.getPaddingTop(),
                     mItemPaddingRight,
                     mAccountFilterHeaderContainer.getPaddingBottom());
             return mAccountFilterHeaderContainer;
-        } else {
-            final int localPosition = position - contactTileAdapterCount - 1;
-            final ContactListItemView itemView = (ContactListItemView)
-                    mContactEntryListAdapter.getView(localPosition, convertView, null);
-            itemView.setPadding(mItemPaddingLeft, itemView.getPaddingTop(),
-                    mItemPaddingRight, itemView.getPaddingBottom());
-            itemView.setSelectionBoundsHorizontalMargin(mItemPaddingLeft, mItemPaddingRight);
-            return itemView;
+        } else {  // For "all" section
+            if (mContactEntryListAdapter.isLoading()) {  // "All" section is being loaded.
+                mLoadingView.setPadding(mItemPaddingLeft,
+                        mLoadingView.getPaddingTop(),
+                        mItemPaddingRight,
+                        mLoadingView.getPaddingBottom());
+                return mLoadingView;
+            } else {
+                // "-1" for mAccountFilterHeaderContainer
+                final int localPosition = position - contactTileAdapterCount - 1;
+                final ContactListItemView itemView = (ContactListItemView)
+                        mContactEntryListAdapter.getView(localPosition, convertView, null);
+                itemView.setPadding(mItemPaddingLeft, itemView.getPaddingTop(),
+                        mItemPaddingRight, itemView.getPaddingBottom());
+                itemView.setSelectionBoundsHorizontalMargin(mItemPaddingLeft, mItemPaddingRight);
+                return itemView;
+            }
         }
     }
 
     @Override
     public boolean areAllItemsEnabled() {
-        return (mContactTileAdapter.areAllItemsEnabled()
+        // If "all" section is being loaded we'll show mLoadingView, which is not enabled.
+        // Otherwise check the all the other components in the ListView and return appropriate
+        // result.
+        return !mContactEntryListAdapter.isLoading()
+                && (mContactTileAdapter.areAllItemsEnabled()
                 && mAccountFilterHeaderContainer.isEnabled()
                 && mContactEntryListAdapter.areAllItemsEnabled());
     }
@@ -181,14 +251,19 @@
     public boolean isEnabled(int position) {
         final int contactTileAdapterCount = mContactTileAdapter.getCount();
         final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
-        if (position < contactTileAdapterCount) {
+        if (position < contactTileAdapterCount) {  // For "tile" and "frequent" sections
             return mContactTileAdapter.isEnabled(position);
-        } else if (position == contactTileAdapterCount) {
+        } else if (position == contactTileAdapterCount) {  // For "all" section's account header
             // This will be handled by View's onClick event instead of ListView's onItemClick event.
             return false;
-        } else {
-            final int localPosition = position - contactTileAdapterCount - 1;
-            return mContactEntryListAdapter.isEnabled(localPosition);
+        } else {  // For "all" section
+            if (mContactEntryListAdapter.isLoading()) {  // "All" section is being loaded.
+                return false;
+            } else {
+                // "-1" for mAccountFilterHeaderContainer
+                final int localPosition = position - contactTileAdapterCount - 1;
+                return mContactEntryListAdapter.isEnabled(localPosition);
+            }
         }
     }
 
@@ -205,6 +280,7 @@
         if (position <= contactTileAdapterCount) {
             return 0;
         } else {
+            // "-1" for mAccountFilterHeaderContainer
             final int localPosition = position - contactTileAdapterCount - 1;
             return mContactEntryListAdapter.getSectionForPosition(localPosition);
         }
diff --git a/src/com/android/contacts/list/PhoneNumberListAdapter.java b/src/com/android/contacts/list/PhoneNumberListAdapter.java
index 1d077b7..6323cc1 100644
--- a/src/com/android/contacts/list/PhoneNumberListAdapter.java
+++ b/src/com/android/contacts/list/PhoneNumberListAdapter.java
@@ -22,22 +22,30 @@
 import android.net.Uri;
 import android.net.Uri.Builder;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Callable;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.ContactCounts;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.contacts.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * A cursor adapter for the {@link Phone#CONTENT_TYPE} content type.
+ * A cursor adapter for the {@link Phone#CONTENT_ITEM_TYPE} and
+ * {@link SipAddress#CONTENT_ITEM_TYPE}.
+ *
+ * By default this adapter just handles phone numbers. When {@link #setUseCallableUri(boolean)} is
+ * called with "true", this adapter starts handling SIP addresses too, by using {@link Callable}
+ * API instead of {@link Phone}.
  */
 public class PhoneNumberListAdapter extends ContactEntryListAdapter {
     private static final String TAG = PhoneNumberListAdapter.class.getSimpleName();
@@ -79,9 +87,11 @@
 
     private ContactListItemView.PhotoPosition mPhotoPosition;
 
+    private boolean mUseCallableUri;
+
     public PhoneNumberListAdapter(Context context) {
         super(context);
-
+        setDefaultFilterHeaderText(R.string.list_filter_phones);
         mUnknownNameText = context.getText(android.R.string.unknownName);
     }
 
@@ -91,40 +101,37 @@
 
     @Override
     public void configureLoader(CursorLoader loader, long directoryId) {
-        Uri uri;
-
         if (directoryId != Directory.DEFAULT) {
             Log.w(TAG, "PhoneNumberListAdapter is not ready for non-default directory ID ("
                     + "directoryId: " + directoryId + ")");
         }
 
+        final Builder builder;
         if (isSearchMode()) {
-            String query = getQueryString();
-            Builder builder = Phone.CONTENT_FILTER_URI.buildUpon();
+            final Uri baseUri =
+                    mUseCallableUri ? Callable.CONTENT_FILTER_URI : Phone.CONTENT_FILTER_URI;
+            builder = baseUri.buildUpon();
+            final String query = getQueryString();
             if (TextUtils.isEmpty(query)) {
                 builder.appendPath("");
             } else {
                 builder.appendPath(query);      // Builder will encode the query
             }
-
             builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
                     String.valueOf(directoryId));
-            uri = builder.build();
         } else {
-            uri = Phone.CONTENT_URI.buildUpon().appendQueryParameter(
-                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
-                    .build();
+            final Uri baseUri = mUseCallableUri ? Callable.CONTENT_URI : Phone.CONTENT_URI;
+            builder = baseUri.buildUpon().appendQueryParameter(
+                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT));
             if (isSectionHeaderDisplayEnabled()) {
-                uri = buildSectionIndexerUri(uri);
+                builder.appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true");
             }
-            configureSelection(loader, directoryId, getFilter());
+            applyFilter(loader, builder, directoryId, getFilter());
         }
 
         // Remove duplicates when it is possible.
-        uri = uri.buildUpon()
-                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
-                .build();
-        loader.setUri(uri);
+        builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true");
+        loader.setUri(builder.build());
 
         // TODO a projection that includes the search snippet
         if (getContactNameDisplayOrder() == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
@@ -140,8 +147,12 @@
         }
     }
 
-    private void configureSelection(
-            CursorLoader loader, long directoryId, ContactListFilter filter) {
+    /**
+     * Configure {@code loader} and {@code uriBuilder} according to {@code directoryId} and {@code
+     * filter}.
+     */
+    private void applyFilter(CursorLoader loader, Uri.Builder uriBuilder, long directoryId,
+            ContactListFilter filter) {
         if (filter == null || directoryId != Directory.DEFAULT) {
             return;
         }
@@ -156,19 +167,7 @@
                 break;
             }
             case ContactListFilter.FILTER_TYPE_ACCOUNT: {
-                selection.append("(");
-
-                selection.append(RawContacts.ACCOUNT_TYPE + "=?"
-                        + " AND " + RawContacts.ACCOUNT_NAME + "=?");
-                selectionArgs.add(filter.accountType);
-                selectionArgs.add(filter.accountName);
-                if (filter.dataSet != null) {
-                    selection.append(" AND " + RawContacts.DATA_SET + "=?");
-                    selectionArgs.add(filter.dataSet);
-                } else {
-                    selection.append(" AND " + RawContacts.DATA_SET + " IS NULL");
-                }
-                selection.append(")");
+                filter.addAccountQueryParameterToUrl(uriBuilder);
                 break;
             }
             case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS:
@@ -187,11 +186,6 @@
         loader.setSelectionArgs(selectionArgs.toArray(new String[0]));
     }
 
-    protected static Uri buildSectionIndexerUri(Uri uri) {
-        return uri.buildUpon()
-                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
-    }
-
     @Override
     public String getContactDisplayName(int position) {
         return ((Cursor) getItem(position)).getString(PhoneQuery.PHONE_DISPLAY_NAME);
@@ -227,6 +221,8 @@
     protected void bindView(View itemView, int partition, Cursor cursor, int position) {
         ContactListItemView view = (ContactListItemView)itemView;
 
+        view.setHighlightedPrefix(isSearchMode() ? getUpperCaseQueryString() : null);
+
         // Look at elements before and after this position, checking if contact IDs are same.
         // If they have one same contact ID, it means they can be grouped.
         //
@@ -259,7 +255,9 @@
         if (isFirstEntry) {
             bindName(view, cursor);
             if (isQuickContactEnabled()) {
-                bindQuickContact(view, partition, cursor, PhoneQuery.PHONE_PHOTO_ID,
+                // No need for photo uri here, because we can not have directory results. If we
+                // ever do, we need to add photo uri to the query
+                bindQuickContact(view, partition, cursor, PhoneQuery.PHONE_PHOTO_ID, -1,
                         PhoneQuery.PHONE_CONTACT_ID, PhoneQuery.PHONE_LOOKUP_KEY);
             } else {
                 bindPhoto(view, cursor);
@@ -312,7 +310,7 @@
             photoId = cursor.getLong(PhoneQuery.PHONE_PHOTO_ID);
         }
 
-        getPhotoLoader().loadPhoto(view.getPhotoView(), photoId, false, false);
+        getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false);
     }
 
     public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
@@ -322,4 +320,12 @@
     public ContactListItemView.PhotoPosition getPhotoPosition() {
         return mPhotoPosition;
     }
+
+    public void setUseCallableUri(boolean useCallableUri) {
+        mUseCallableUri = useCallableUri;
+    }
+
+    public boolean usesCallableUri() {
+        return mUseCallableUri;
+    }
 }
diff --git a/src/com/android/contacts/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index c96956b..3785fa6 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -20,6 +20,8 @@
 import com.android.contacts.util.AccountFilterUtil;
 
 import android.content.Intent;
+import android.content.Loader;
+import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
@@ -28,6 +30,7 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.widget.TextView;
 
 /**
  * Fragment containing a phone number list for picking.
@@ -38,6 +41,8 @@
 
     private static final int REQUEST_CODE_ACCOUNT_FILTER = 1;
 
+    private static final String KEY_SHORTCUT_ACTION = "shortcutAction";
+
     private OnPhoneNumberPickerActionListener mListener;
     private String mShortcutAction;
 
@@ -55,6 +60,8 @@
     /** true if the loader has started at least once. */
     private boolean mLoaderStarted;
 
+    private boolean mUseCallableUri;
+
     private ContactListItemView.PhotoPosition mPhotoPosition =
             ContactListItemView.DEFAULT_PHOTO_POSITION;
 
@@ -62,7 +69,9 @@
         @Override
         public void onClick(View view) {
             AccountFilterUtil.startAccountFilterActivityForResult(
-                    PhoneNumberPickerFragment.this, REQUEST_CODE_ACCOUNT_FILTER);
+                    PhoneNumberPickerFragment.this,
+                    REQUEST_CODE_ACCOUNT_FILTER,
+                    mFilter);
         }
     }
     private OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener();
@@ -107,8 +116,10 @@
         if (mAccountFilterHeader == null || filter == null) {
             return;
         }
-        final boolean shouldShowHeader = AccountFilterUtil.updateAccountFilterTitleForPhone(
-                mAccountFilterHeader, filter, false, false);
+        final boolean shouldShowHeader =
+                !isSearchMode() &&
+                AccountFilterUtil.updateAccountFilterTitleForPhone(
+                        mAccountFilterHeader, filter, false);
         if (shouldShowHeader) {
             mPaddingView.setVisibility(View.GONE);
             mAccountFilterHeader.setVisibility(View.VISIBLE);
@@ -127,12 +138,14 @@
         }
 
         mFilter = savedState.getParcelable(KEY_FILTER);
+        mShortcutAction = savedState.getString(KEY_SHORTCUT_ACTION);
     }
 
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putParcelable(KEY_FILTER, mFilter);
+        outState.putString(KEY_SHORTCUT_ACTION, mShortcutAction);
     }
 
     @Override
@@ -181,10 +194,27 @@
     }
 
     @Override
+    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+        super.onLoadFinished(loader, data);
+
+        // disable scroll bar if there is no data
+        setVisibleScrollbarEnabled(data.getCount() > 0);
+    }
+
+    public void setUseCallableUri(boolean useCallableUri) {
+        mUseCallableUri = useCallableUri;
+    }
+
+    public boolean usesCallableUri() {
+        return mUseCallableUri;
+    }
+
+    @Override
     protected ContactEntryListAdapter createListAdapter() {
         if (!isLegacyCompatibilityMode()) {
             PhoneNumberListAdapter adapter = new PhoneNumberListAdapter(getActivity());
             adapter.setDisplayPhotos(true);
+            adapter.setUseCallableUri(mUseCallableUri);
             return adapter;
         } else {
             LegacyPhoneNumberListAdapter adapter = new LegacyPhoneNumberListAdapter(getActivity());
diff --git a/src/com/android/contacts/list/PostalAddressListAdapter.java b/src/com/android/contacts/list/PostalAddressListAdapter.java
index 41591de..5e3be30 100644
--- a/src/com/android/contacts/list/PostalAddressListAdapter.java
+++ b/src/com/android/contacts/list/PostalAddressListAdapter.java
@@ -20,10 +20,11 @@
 import android.content.CursorLoader;
 import android.database.Cursor;
 import android.net.Uri;
+import android.net.Uri.Builder;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.ContactCounts;
 import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -69,11 +70,12 @@
 
     @Override
     public void configureLoader(CursorLoader loader, long directoryId) {
-        Uri uri = buildSectionIndexerUri(StructuredPostal.CONTENT_URI)
-                .buildUpon()
-                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
-                .build();
-        loader.setUri(uri);
+        final Builder builder = StructuredPostal.CONTENT_URI.buildUpon()
+                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true");
+        if (isSectionHeaderDisplayEnabled()) {
+            builder.appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true");
+        }
+        loader.setUri(builder.build());
 
         if (getContactNameDisplayOrder() == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
             loader.setProjection(PostalQuery.PROJECTION_PRIMARY);
@@ -88,11 +90,6 @@
         }
     }
 
-    protected static Uri buildSectionIndexerUri(Uri uri) {
-        return uri.buildUpon()
-                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
-    }
-
     @Override
     public String getContactDisplayName(int position) {
         return ((Cursor) getItem(position)).getString(PostalQuery.POSTAL_DISPLAY_NAME);
@@ -166,7 +163,7 @@
             photoId = cursor.getLong(PostalQuery.POSTAL_PHOTO_ID);
         }
 
-        getPhotoLoader().loadPhoto(view.getPhotoView(), photoId, false, false);
+        getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false);
     }
 //
 //    protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
diff --git a/src/com/android/contacts/list/PostalAddressPickerFragment.java b/src/com/android/contacts/list/PostalAddressPickerFragment.java
index 85fc155..ddb8e9a 100644
--- a/src/com/android/contacts/list/PostalAddressPickerFragment.java
+++ b/src/com/android/contacts/list/PostalAddressPickerFragment.java
@@ -73,6 +73,13 @@
         return inflater.inflate(R.layout.contact_list_content, null);
     }
 
+    @Override
+    protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
+        super.onCreateView(inflater, container);
+
+        setVisibleScrollbarEnabled(!isLegacyCompatibilityMode());
+    }
+
     private void pickPostalAddress(Uri uri) {
         mListener.onPickPostalAddressAction(uri);
     }
diff --git a/src/com/android/contacts/list/ProviderStatusLoader.java b/src/com/android/contacts/list/ProviderStatusLoader.java
deleted file mode 100644
index a6afa9f..0000000
--- a/src/com/android/contacts/list/ProviderStatusLoader.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.list;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.os.Handler;
-import android.provider.ContactsContract.ProviderStatus;
-
-/**
- * Checks provider status and configures a list adapter accordingly.
- */
-public class ProviderStatusLoader extends ContentObserver {
-
-    /**
-     * Callback interface invoked when the provider status changes.
-     */
-    public interface ProviderStatusListener {
-        public void onProviderStatusChange();
-    }
-
-    private static final String[] PROJECTION = new String[] {
-        ProviderStatus.STATUS,
-        ProviderStatus.DATA1
-    };
-
-    private static final int UNKNOWN = -1;
-
-    private final Context mContext;
-    private int mProviderStatus = UNKNOWN;
-    private String mProviderData;
-    private ProviderStatusListener mListener;
-    private Handler mHandler = new Handler();
-
-    public ProviderStatusLoader(Context context) {
-        super(null);
-        this.mContext = context;
-    }
-
-    public int getProviderStatus() {
-        if (mProviderStatus == UNKNOWN) {
-            loadProviderStatus();
-        }
-
-        return mProviderStatus;
-    }
-
-    public String getProviderStatusData() {
-        if (mProviderStatus == UNKNOWN) {
-            loadProviderStatus();
-        }
-
-        return mProviderData;
-    }
-
-    protected void loadProviderStatus() {
-
-        // Default to normal status
-        mProviderStatus = ProviderStatus.STATUS_NORMAL;
-
-        // This query can be performed on the UI thread because
-        // the API explicitly allows such use.
-        Cursor cursor = mContext.getContentResolver().query(ProviderStatus.CONTENT_URI,
-                PROJECTION, null, null, null);
-        if (cursor != null) {
-            try {
-                if (cursor.moveToFirst()) {
-                    mProviderStatus = cursor.getInt(0);
-                    mProviderData = cursor.getString(1);
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
-    public void setProviderStatusListener(ProviderStatusListener listener) {
-        mListener = listener;
-
-        ContentResolver resolver = mContext.getContentResolver();
-        if (listener != null) {
-            mProviderStatus = UNKNOWN;
-            resolver.registerContentObserver(ProviderStatus.CONTENT_URI, false, this);
-        } else {
-            resolver.unregisterContentObserver(this);
-        }
-    }
-
-    @Override
-    public void onChange(boolean selfChange) {
-        // Deliver a notification on the UI thread
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mListener != null) {
-                    mProviderStatus = UNKNOWN;
-                    mListener.onProviderStatusChange();
-                }
-            }
-        });
-    }
-
-    /**
-     * Sends a provider status update, which will trigger a retry of database upgrade
-     */
-    public void retryUpgrade() {
-        ContentValues values = new ContentValues();
-        values.put(ProviderStatus.STATUS, ProviderStatus.STATUS_UPGRADING);
-        mContext.getContentResolver().update(ProviderStatus.CONTENT_URI, values, null, null);
-    }
-}
diff --git a/src/com/android/contacts/list/ProviderStatusWatcher.java b/src/com/android/contacts/list/ProviderStatusWatcher.java
new file mode 100644
index 0000000..ae0b779
--- /dev/null
+++ b/src/com/android/contacts/list/ProviderStatusWatcher.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2012 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.contacts.list;
+
+import com.google.common.collect.Lists;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.provider.ContactsContract.ProviderStatus;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * A singleton that keeps track of the last known provider status.
+ *
+ * All methods must be called on the UI thread unless noted otherwise.
+ *
+ * All members must be set on the UI thread unless noted otherwise.
+ */
+public class ProviderStatusWatcher extends ContentObserver {
+    private static final String TAG = "ProviderStatusWatcher";
+    private static final boolean DEBUG = false;
+
+    /**
+     * Callback interface invoked when the provider status changes.
+     */
+    public interface ProviderStatusListener {
+        public void onProviderStatusChange();
+    }
+
+    public static class Status {
+        /** See {@link ProviderStatus#STATUS} */
+        public final int status;
+
+        /** See {@link ProviderStatus#DATA1} */
+        public final String data;
+
+        public Status(int status, String data) {
+            this.status = status;
+            this.data = data;
+        }
+    }
+
+    private static final String[] PROJECTION = new String[] {
+        ProviderStatus.STATUS,
+        ProviderStatus.DATA1
+    };
+
+    /**
+     * We'll wait for this amount of time on the UI thread if the load hasn't finished.
+     */
+    private static final int LOAD_WAIT_TIMEOUT_MS = 1000;
+
+    private static ProviderStatusWatcher sInstance;
+
+    private final Context mContext;
+    private final Handler mHandler = new Handler();
+
+    private final Object mSignal = new Object();
+
+    private int mStartRequestedCount;
+
+    private LoaderTask mLoaderTask;
+
+    /** Last known provider status.  This can be changed on a worker thread. */
+    private Status mProviderStatus;
+
+    private final ArrayList<ProviderStatusListener> mListeners = Lists.newArrayList();
+
+    private final Runnable mStartLoadingRunnable = new Runnable() {
+        @Override
+        public void run() {
+            startLoading();
+        }
+    };
+
+    /**
+     * Returns the singleton instance.
+     */
+    public synchronized static ProviderStatusWatcher getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new ProviderStatusWatcher(context);
+        }
+        return sInstance;
+    }
+
+    private ProviderStatusWatcher(Context context) {
+        super(null);
+        mContext = context;
+    }
+
+    /** Add a listener. */
+    public void addListener(ProviderStatusListener listener) {
+        mListeners.add(listener);
+    }
+
+    /** Remove a listener */
+    public void removeListener(ProviderStatusListener listener) {
+        mListeners.remove(listener);
+    }
+
+    private void notifyListeners() {
+        if (DEBUG) {
+            Log.d(TAG, "notifyListeners: " + mListeners.size());
+        }
+        if (isStarted()) {
+            for (ProviderStatusListener listener : mListeners) {
+                listener.onProviderStatusChange();
+            }
+        }
+    }
+
+    private boolean isStarted() {
+        return mStartRequestedCount > 0;
+    }
+
+    /**
+     * Starts watching the provider status.  {@link #start()} and {@link #stop()} calls can be
+     * nested.
+     */
+    public void start() {
+        if (++mStartRequestedCount == 1) {
+            mContext.getContentResolver()
+                .registerContentObserver(ProviderStatus.CONTENT_URI, false, this);
+            startLoading();
+
+            if (DEBUG) {
+                Log.d(TAG, "Start observing");
+            }
+        }
+    }
+
+    /**
+     * Stops watching the provider status.
+     */
+    public void stop() {
+        if (!isStarted()) {
+            Log.e(TAG, "Already stopped");
+            return;
+        }
+        if (--mStartRequestedCount == 0) {
+
+            mHandler.removeCallbacks(mStartLoadingRunnable);
+
+            mContext.getContentResolver().unregisterContentObserver(this);
+            if (DEBUG) {
+                Log.d(TAG, "Stop observing");
+            }
+        }
+    }
+
+    /**
+     * @return last known provider status.
+     *
+     * If this method is called when we haven't started the status query or the query is still in
+     * progress, it will start a query in a worker thread if necessary, and *wait for the result*.
+     *
+     * This means this method is essentially a blocking {@link ProviderStatus#CONTENT_URI} query.
+     * This URI is not backed by the file system, so is usually fast enough to perform on the main
+     * thread, but in extreme cases (when the system takes a while to bring up the contacts
+     * provider?) this may still cause ANRs.
+     *
+     * In order to avoid that, if we can't load the status within {@link #LOAD_WAIT_TIMEOUT_MS},
+     * we'll give up and just returns {@link ProviderStatus#STATUS_UPGRADING} in order to unblock
+     * the UI thread.  The actual result will be delivered later via {@link ProviderStatusListener}.
+     * (If {@link ProviderStatus#STATUS_UPGRADING} is returned, the app (should) shows an according
+     * message, like "contacts are being updated".)
+     */
+    public Status getProviderStatus() {
+        waitForLoaded();
+
+        if (mProviderStatus == null) {
+            return new Status(ProviderStatus.STATUS_UPGRADING, null);
+        }
+
+        return mProviderStatus;
+    }
+
+    private void waitForLoaded() {
+        if (mProviderStatus == null) {
+            if (mLoaderTask == null) {
+                // For some reason the loader couldn't load the status.  Let's start it again.
+                startLoading();
+            }
+            synchronized (mSignal) {
+                try {
+                    mSignal.wait(LOAD_WAIT_TIMEOUT_MS);
+                } catch (InterruptedException ignore) {
+                }
+            }
+        }
+    }
+
+    private void startLoading() {
+        if (mLoaderTask != null) {
+            return; // Task already running.
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Start loading");
+        }
+
+        mLoaderTask = new LoaderTask();
+        mLoaderTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+
+    private class LoaderTask extends AsyncTask<Void, Void, Boolean> {
+        @Override
+        protected Boolean doInBackground(Void... params) {
+            try {
+                Cursor cursor = mContext.getContentResolver().query(ProviderStatus.CONTENT_URI,
+                        PROJECTION, null, null, null);
+                if (cursor != null) {
+                    try {
+                        if (cursor.moveToFirst()) {
+                            // Note here we can't just say "Status", as AsyncTask has the "Status"
+                            // enum too.
+                            mProviderStatus = new ProviderStatusWatcher.Status(
+                                    cursor.getInt(0), cursor.getString(1));
+                            return true;
+                        }
+                    } finally {
+                        cursor.close();
+                    }
+                }
+                return false;
+            } finally {
+                synchronized (mSignal) {
+                    mSignal.notifyAll();
+                }
+            }
+        }
+
+        @Override
+        protected void onCancelled(Boolean result) {
+            cleanUp();
+        }
+
+        @Override
+        protected void onPostExecute(Boolean loaded) {
+            cleanUp();
+            if (loaded != null && loaded) {
+                notifyListeners();
+            }
+        }
+
+        private void cleanUp() {
+            mLoaderTask = null;
+        }
+    }
+
+    /**
+     * Called when provider status may has changed.
+     *
+     * This method will be called on a worker thread by the framework.
+     */
+    @Override
+    public void onChange(boolean selfChange, Uri uri) {
+        if (!ProviderStatus.CONTENT_URI.equals(uri)) return;
+
+        // Provider status change is rare, so okay to log.
+        Log.i(TAG, "Provider status changed.");
+
+        mHandler.removeCallbacks(mStartLoadingRunnable); // Remove one in the queue, if any.
+        mHandler.post(mStartLoadingRunnable);
+    }
+
+    /**
+     * Sends a provider status update, which will trigger a retry of database upgrade
+     */
+    public static void retryUpgrade(final Context context) {
+        Log.i(TAG, "retryUpgrade");
+        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                ContentValues values = new ContentValues();
+                values.put(ProviderStatus.STATUS, ProviderStatus.STATUS_UPGRADING);
+                context.getContentResolver().update(ProviderStatus.CONTENT_URI, values,
+                        null, null);
+                return null;
+            }
+        };
+        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+}
diff --git a/src/com/android/contacts/list/ShortcutIntentBuilder.java b/src/com/android/contacts/list/ShortcutIntentBuilder.java
index 1be0b74..d71a0f5 100644
--- a/src/com/android/contacts/list/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/list/ShortcutIntentBuilder.java
@@ -86,6 +86,13 @@
     private final int mBorderColor;
 
     /**
+     * This is a hidden API of the launcher in JellyBean that allows us to disable the animation
+     * that it would usually do, because it interferes with our own animation for QuickContact
+     */
+    public static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
+            "com.android.launcher.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";
+
+    /**
      * Listener interface.
      */
     public interface OnShortcutIntentCreatedListener {
@@ -130,6 +137,7 @@
      */
     private abstract class LoadingAsyncTask extends AsyncTask<Void, Void, Void> {
         protected Uri mUri;
+        protected String mContentType;
         protected String mDisplayName;
         protected byte[] mBitmapData;
         protected long mPhotoId;
@@ -140,6 +148,7 @@
 
         @Override
         protected Void doInBackground(Void... params) {
+            mContentType = mContext.getContentResolver().getType(mUri);
             loadData();
             loadPhoto();
             return null;
@@ -189,7 +198,7 @@
         }
         @Override
         protected void onPostExecute(Void result) {
-            createContactShortcutIntent(mUri, mDisplayName, mBitmapData);
+            createContactShortcutIntent(mUri, mContentType, mDisplayName, mBitmapData);
         }
     }
 
@@ -241,29 +250,38 @@
         return bitmap;
     }
 
-    private void createContactShortcutIntent(Uri contactUri, String displayName,
+    private void createContactShortcutIntent(Uri contactUri, String contentType, String displayName,
             byte[] bitmapData) {
         Bitmap bitmap = getPhotoBitmap(bitmapData);
 
-        Intent shortcutIntent;
-        // This is a simple shortcut to view a contact.
-        shortcutIntent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT);
-        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        Intent shortcutIntent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT);
 
-        shortcutIntent.setData(contactUri);
+        // When starting from the launcher, start in a new, cleared task.
+        // CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we
+        // clear the whole thing preemptively here since QuickContactActivity will
+        // finish itself when launching other detail activities.
+        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+        // Tell the launcher to not do its animation, because we are doing our own
+        shortcutIntent.putExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION, true);
+
+        shortcutIntent.setDataAndType(contactUri, contentType);
         shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_MODE,
                 ContactsContract.QuickContact.MODE_LARGE);
         shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_EXCLUDE_MIMES,
                 (String[]) null);
-        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
 
         final Bitmap icon = generateQuickContactIcon(bitmap);
 
         Intent intent = new Intent();
         intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
         intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
-        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName);
+        if (TextUtils.isEmpty(displayName)) {
+            intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mContext.getResources().getString(
+                    R.string.missing_name));
+        } else {
+            intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName);
+        }
 
         mListener.onShortcutIntentCreated(contactUri, intent);
     }
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/AccountType.java
index 22ea884..7e48d83 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/AccountType.java
@@ -21,16 +21,13 @@
 import com.google.android.collect.Maps;
 import com.google.common.annotations.VisibleForTesting;
 
-import android.accounts.Account;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.database.Cursor;
 import android.graphics.drawable.Drawable;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.view.inputmethod.EditorInfo;
 import android.widget.EditText;
@@ -63,11 +60,25 @@
     public String dataSet = null;
 
     /**
-     * Package that resources should be loaded from, either defined through an
-     * {@link Account} or for matching against {@link Data#RES_PACKAGE}.
+     * Package that resources should be loaded from.  Will be null for embedded types, in which
+     * case resources are stored in this package itself.
+     *
+     * TODO Clean up {@link #resourcePackageName}, {@link #syncAdapterPackageName} and
+     * {@link #getViewContactNotifyServicePackageName()}.
+     *
+     * There's the following invariants:
+     * - {@link #syncAdapterPackageName} is always set to the actual sync adapter package name.
+     * - {@link #resourcePackageName} too is set to the same value, unless {@link #isEmbedded()},
+     *   in which case it'll be null.
+     * There's an unfortunate exception of {@link FallbackAccountType}.  Even though it
+     * {@link #isEmbedded()}, but we set non-null to {@link #resourcePackageName} for unit tests.
      */
-    public String resPackageName;
-    public String summaryResPackageName;
+    public String resourcePackageName;
+    /**
+     * The package name for the authenticator (for the embedded types, i.e. Google and Exchange)
+     * or the sync adapter (for external type, including extensions).
+     */
+    public String syncAdapterPackageName;
 
     public int titleRes;
     public int iconRes;
@@ -126,24 +137,33 @@
     public abstract boolean areContactsWritable();
 
     /**
-     * Returns an optional custom edit activity.  The activity class should reside
-     * in the sync adapter package as determined by {@link #resPackageName}.
+     * Returns an optional custom edit activity.
+     *
+     * Only makes sense for non-embedded account types.
+     * The activity class should reside in the sync adapter package as determined by
+     * {@link #syncAdapterPackageName}.
      */
     public String getEditContactActivityClassName() {
         return null;
     }
 
     /**
-     * Returns an optional custom new contact activity. The activity class should reside
-     * in the sync adapter package as determined by {@link #resPackageName}.
+     * Returns an optional custom new contact activity.
+     *
+     * Only makes sense for non-embedded account types.
+     * The activity class should reside in the sync adapter package as determined by
+     * {@link #syncAdapterPackageName}.
      */
     public String getCreateContactActivityClassName() {
         return null;
     }
 
     /**
-     * Returns an optional custom invite contact activity. The activity class should reside
-     * in the sync adapter package as determined by {@link #resPackageName}.
+     * Returns an optional custom invite contact activity.
+     *
+     * Only makes sense for non-embedded account types.
+     * The activity class should reside in the sync adapter package as determined by
+     * {@link #syncAdapterPackageName}.
      */
     public String getInviteContactActivityClassName() {
         return null;
@@ -152,13 +172,25 @@
     /**
      * Returns an optional service that can be launched whenever a contact is being looked at.
      * This allows the sync adapter to provide more up-to-date information.
+     *
      * The service class should reside in the sync adapter package as determined by
-     * {@link #resPackageName}.
+     * {@link #getViewContactNotifyServicePackageName()}.
      */
     public String getViewContactNotifyServiceClassName() {
         return null;
     }
 
+    /**
+     * TODO This is way too hacky should be removed.
+     *
+     * This is introduced for {@link GoogleAccountType} where {@link #syncAdapterPackageName}
+     * is the authenticator package name but the notification service is in the sync adapter
+     * package.  See {@link #resourcePackageName} -- we should clean up those.
+     */
+    public String getViewContactNotifyServicePackageName() {
+        return syncAdapterPackageName;
+    }
+
     /** Returns an optional Activity string that can be used to view the group. */
     public String getViewGroupActivity() {
         return null;
@@ -175,7 +207,8 @@
     }
 
     public CharSequence getDisplayLabel(Context context) {
-        return getResourceText(context, summaryResPackageName, titleRes, accountType);
+        // Note this resource is defined in the sync adapter package, not resourcePackageName.
+        return getResourceText(context, syncAdapterPackageName, titleRes, accountType);
     }
 
     /**
@@ -214,7 +247,8 @@
      * the contact card.  (If not defined, returns null.)
      */
     public CharSequence getInviteContactActionLabel(Context context) {
-        return getResourceText(context, summaryResPackageName, getInviteContactActionResId(), "");
+        // Note this resource is defined in the sync adapter package, not resourcePackageName.
+        return getResourceText(context, syncAdapterPackageName, getInviteContactActionResId(), "");
     }
 
     /**
@@ -222,8 +256,9 @@
      * own "View Updates" string
      */
     public CharSequence getViewGroupLabel(Context context) {
+        // Note this resource is defined in the sync adapter package, not resourcePackageName.
         final CharSequence customTitle =
-                getResourceText(context, summaryResPackageName, getViewGroupLabelResId(), null);
+                getResourceText(context, syncAdapterPackageName, getViewGroupLabelResId(), null);
 
         return customTitle == null
                 ? context.getText(R.string.view_updates_from_group)
@@ -251,9 +286,9 @@
     }
 
     public Drawable getDisplayIcon(Context context) {
-        if (this.titleRes != -1 && this.summaryResPackageName != null) {
+        if (this.titleRes != -1 && this.syncAdapterPackageName != null) {
             final PackageManager pm = context.getPackageManager();
-            return pm.getDrawable(this.summaryResPackageName, this.iconRes, null);
+            return pm.getDrawable(this.syncAdapterPackageName, this.iconRes, null);
         } else if (this.titleRes != -1) {
             return context.getResources().getDrawable(this.iconRes);
         } else {
@@ -270,6 +305,7 @@
      * {@link Comparator} to sort by {@link DataKind#weight}.
      */
     private static Comparator<DataKind> sWeightComparator = new Comparator<DataKind>() {
+        @Override
         public int compare(DataKind object1, DataKind object2) {
             return object1.weight - object2.weight;
         }
@@ -306,7 +342,7 @@
                     "mime type '" + kind.mimeType + "' is already registered");
         }
 
-        kind.resPackageName = this.resPackageName;
+        kind.resourcePackageName = this.resourcePackageName;
         this.mKinds.add(kind);
         this.mMimeKinds.put(kind.mimeType, kind);
         return kind;
@@ -460,13 +496,12 @@
     }
 
     /**
-     * Generic method of inflating a given {@link Cursor} into a user-readable
+     * Generic method of inflating a given {@link ContentValues} into a user-readable
      * {@link CharSequence}. For example, an inflater could combine the multiple
      * columns of {@link StructuredPostal} together using a string resource
      * before presenting to the user.
      */
     public interface StringInflater {
-        public CharSequence inflateUsing(Context context, Cursor cursor);
         public CharSequence inflateUsing(Context context, ContentValues values);
     }
 
diff --git a/src/com/android/contacts/model/BaseAccountType.java b/src/com/android/contacts/model/BaseAccountType.java
index cd113eb..1e830e2 100644
--- a/src/com/android/contacts/model/BaseAccountType.java
+++ b/src/com/android/contacts/model/BaseAccountType.java
@@ -17,18 +17,14 @@
 package com.android.contacts.model;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DefinitionException;
+import com.android.contacts.test.NeededForTesting;
 import com.android.contacts.util.DateUtils;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.res.Resources;
-import android.database.Cursor;
 import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Event;
@@ -48,6 +44,9 @@
 import android.util.Log;
 import android.view.inputmethod.EditorInfo;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.util.List;
 import java.util.Locale;
@@ -79,6 +78,12 @@
     protected static final int FLAGS_RELATION = EditorInfo.TYPE_CLASS_TEXT
             | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME;
 
+    // Specify the maximum number of lines that can be used to display various field types.  If no
+    // value is specified for a particular type, we use the default value from {@link DataKind}.
+    protected static final int MAX_LINES_FOR_POSTAL_ADDRESS = 10;
+    protected static final int MAX_LINES_FOR_GROUP = 10;
+    protected static final int MAX_LINES_FOR_NOTE = 100;
+
     private interface Tag {
         static final String DATA_KIND = "DataKind";
         static final String TYPE = "Type";
@@ -323,6 +328,8 @@
                 new EditField(StructuredPostal.FORMATTED_ADDRESS, R.string.postal_address,
                         FLAGS_POSTAL));
 
+        kind.maxLinesForDisplay = MAX_LINES_FOR_POSTAL_ADDRESS;
+
         return kind;
     }
 
@@ -391,6 +398,8 @@
         kind.fieldList = Lists.newArrayList();
         kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE));
 
+        kind.maxLinesForDisplay = MAX_LINES_FOR_NOTE;
+
         return kind;
     }
 
@@ -430,6 +439,8 @@
         kind.fieldList = Lists.newArrayList();
         kind.fieldList.add(new EditField(GroupMembership.GROUP_ROW_ID, -1, -1));
 
+        kind.maxLinesForDisplay = MAX_LINES_FOR_GROUP;
+
         return kind;
     }
 
@@ -454,25 +465,7 @@
             mColumnName = columnName;
         }
 
-        public CharSequence inflateUsing(Context context, Cursor cursor) {
-            final int index = mColumnName != null ? cursor.getColumnIndex(mColumnName) : -1;
-            final boolean validString = mStringRes > 0;
-            final boolean validColumn = index != -1;
-
-            final CharSequence stringValue = validString ? context.getText(mStringRes) : null;
-            final CharSequence columnValue = validColumn ? cursor.getString(index) : null;
-
-            if (validString && validColumn) {
-                return String.format(stringValue.toString(), columnValue);
-            } else if (validString) {
-                return stringValue;
-            } else if (validColumn) {
-                return columnValue;
-            } else {
-                return null;
-            }
-        }
-
+        @Override
         public CharSequence inflateUsing(Context context, ContentValues values) {
             final boolean validColumn = values.containsKey(mColumnName);
             final boolean validString = mStringRes > 0;
@@ -498,6 +491,7 @@
                     + " mColumnName" + mColumnName;
         }
 
+        @NeededForTesting
         public String getColumnNameForTest() {
             return mColumnName;
         }
@@ -529,12 +523,7 @@
             }
         }
 
-        public CharSequence inflateUsing(Context context, Cursor cursor) {
-            final Integer type = cursor.getInt(cursor.getColumnIndex(getTypeColumn()));
-            final String label = cursor.getString(cursor.getColumnIndex(getLabelColumn()));
-            return getTypeLabel(context.getResources(), type, label);
-        }
-
+        @Override
         public CharSequence inflateUsing(Context context, ContentValues values) {
             final Integer type = values.getAsInteger(getTypeColumn());
             final String label = values.getAsString(getLabelColumn());
@@ -1210,6 +1199,7 @@
                             R.string.postal_country, FLAGS_POSTAL).setOptional(true));
                 }
             } else {
+                kind.maxLinesForDisplay= MAX_LINES_FOR_POSTAL_ADDRESS;
                 kind.fieldList.add(
                         new EditField(StructuredPostal.FORMATTED_ADDRESS, R.string.postal_address,
                                 FLAGS_POSTAL));
@@ -1344,6 +1334,7 @@
                     new SimpleInflater(R.string.label_notes), new SimpleInflater(Note.NOTE));
 
             kind.fieldList.add(new EditField(Note.NOTE, R.string.label_notes, FLAGS_NOTE));
+            kind.maxLinesForDisplay = MAX_LINES_FOR_NOTE;
 
             throwIfList(kind);
 
@@ -1417,6 +1408,7 @@
                     R.string.groupsLabel, Weight.GROUP_MEMBERSHIP, -1, null, null);
 
             kind.fieldList.add(new EditField(GroupMembership.GROUP_ROW_ID, -1, -1));
+            kind.maxLinesForDisplay = MAX_LINES_FOR_GROUP;
 
             throwIfList(kind);
 
diff --git a/src/com/android/contacts/model/DataKind.java b/src/com/android/contacts/model/DataKind.java
index 857f3e4..0d60317 100644
--- a/src/com/android/contacts/model/DataKind.java
+++ b/src/com/android/contacts/model/DataKind.java
@@ -40,7 +40,7 @@
     public static final String PSEUDO_MIME_TYPE_PHONETIC_NAME = "#phoneticName";
     public static final String PSEUDO_COLUMN_PHONETIC_NAME = "#phoneticName";
 
-    public String resPackageName;
+    public String resourcePackageName;
     public String mimeType;
     public int titleRes;
     public int iconAltRes;
@@ -83,8 +83,16 @@
      */
     public SimpleDateFormat dateFormatWithYear;
 
+    /**
+     * The number of lines available for displaying this kind of data in a
+     * {@link ContactDetailFragment} (and possibly elsewhere)
+     * Defaults to 1.
+     */
+    public int maxLinesForDisplay;
+
     public DataKind() {
         editorLayoutResourceId = R.layout.text_fields_editor_view;
+        maxLinesForDisplay = 1;
     }
 
     public DataKind(String mimeType, int titleRes, int weight, boolean editable,
@@ -95,13 +103,14 @@
         this.editable = editable;
         this.typeOverallMax = -1;
         this.editorLayoutResourceId = editorLayoutResourceId;
+        maxLinesForDisplay = 1;
     }
 
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
         sb.append("DataKind:");
-        sb.append(" resPackageName=").append(resPackageName);
+        sb.append(" resPackageName=").append(resourcePackageName);
         sb.append(" mimeType=").append(mimeType);
         sb.append(" titleRes=").append(titleRes);
         sb.append(" iconAltRes=").append(iconAltRes);
diff --git a/src/com/android/contacts/model/EntityDelta.java b/src/com/android/contacts/model/EntityDelta.java
index 8244e9c..0f45a4b 100644
--- a/src/com/android/contacts/model/EntityDelta.java
+++ b/src/com/android/contacts/model/EntityDelta.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.model;
 
+import com.android.contacts.test.NeededForTesting;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
@@ -23,6 +24,7 @@
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderOperation.Builder;
 import android.content.ContentValues;
+import android.content.Context;
 import android.content.Entity;
 import android.content.Entity.NamedContentValues;
 import android.net.Uri;
@@ -76,7 +78,7 @@
      * Internal map of children values from {@link Entity#getSubValues()}, which
      * we store here sorted into {@link Data#MIMETYPE} bins.
      */
-    private HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap();
+    private final HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap();
 
     public EntityDelta() {
     }
@@ -183,6 +185,7 @@
      *     doesn't exist (may be a primary, or just a random item
      * @return
      */
+    @NeededForTesting
     public ValuesDelta getSuperPrimaryEntry(String mimeType, boolean forceSelection) {
         final ArrayList<ValuesDelta> mimeEntries = getMimeEntries(mimeType, false);
         if (mimeEntries == null) return null;
@@ -208,6 +211,20 @@
     }
 
     /**
+     * Return the AccountType that this raw-contact belongs to.
+     */
+    public AccountType getRawContactAccountType(Context context) {
+        ContentValues entityValues = getValues().getCompleteValues();
+        String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
+        String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
+        return AccountTypeManager.getInstance(context).getAccountType(type, dataSet);
+    }
+
+    public Long getRawContactId() {
+        return getValues().getAsLong(RawContacts._ID);
+    }
+
+    /**
      * Return the list of child {@link ValuesDelta} from our optimized map,
      * creating the list if requested.
      */
@@ -337,15 +354,18 @@
     public String toString() {
         final StringBuilder builder = new StringBuilder();
         builder.append("\n(");
+        builder.append("Uri=");
+        builder.append(mContactsQueryUri);
+        builder.append(", Values=");
         builder.append(mValues != null ? mValues.toString() : "null");
-        builder.append(") = {");
+        builder.append(", Entries={");
         for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
             for (ValuesDelta child : mimeEntries) {
                 builder.append("\n\t");
                 child.toString(builder);
             }
         }
-        builder.append("\n}\n");
+        builder.append("\n})\n");
         return builder.toString();
     }
 
@@ -564,6 +584,7 @@
             return entry;
         }
 
+        @NeededForTesting
         public ContentValues getAfter() {
             return mAfter;
         }
@@ -760,6 +781,11 @@
             mAfter.putNull(key);
         }
 
+        public void copyStringFrom(ValuesDelta from, String key) {
+            ensureUpdate();
+            put(key, from.getAsString(key));
+        }
+
         /**
          * Return set of all keys defined through this object.
          */
@@ -847,6 +873,11 @@
          */
         public void toString(StringBuilder builder) {
             builder.append("{ ");
+            builder.append("IdColumn=");
+            builder.append(mIdColumn);
+            builder.append(", FromTemplate=");
+            builder.append(mFromTemplate);
+            builder.append(", ");
             for (String key : this.keySet()) {
                 builder.append(key);
                 builder.append("=");
diff --git a/src/com/android/contacts/model/EntityDeltaList.java b/src/com/android/contacts/model/EntityDeltaList.java
index 5a9355b..47fd9c6 100644
--- a/src/com/android/contacts/model/EntityDeltaList.java
+++ b/src/com/android/contacts/model/EntityDeltaList.java
@@ -16,26 +16,26 @@
 
 package com.android.contacts.model;
 
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.google.android.collect.Lists;
+
 import android.content.ContentProviderOperation;
+import android.content.ContentProviderOperation.Builder;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.Entity;
 import android.content.EntityIterator;
-import android.content.ContentProviderOperation.Builder;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.ContactsContract.AggregationExceptions;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.RawContactsEntity;
-
-import com.google.android.collect.Lists;
-
-import com.android.contacts.model.EntityDelta.ValuesDelta;
+import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
-import java.util.List;
 
 /**
  * Container for multiple {@link EntityDelta} objects, usually when editing
@@ -43,6 +43,9 @@
  * and applying another {@link EntityDeltaList} over it.
  */
 public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelable {
+    private static final String TAG = "EntityDeltaList";
+    private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);
+
     private boolean mSplitRawContacts;
     private long[] mJoinWithRawContactIds;
 
@@ -124,6 +127,9 @@
      * any {@link AggregationExceptions} rules needed to groups edits together.
      */
     public ArrayList<ContentProviderOperation> buildDiff() {
+        if (VERBOSE_LOGGING) {
+            Log.v(TAG, "buildDiff: list=" + toString());
+        }
         final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
 
         final long rawContactId = this.findRawContactId();
@@ -198,10 +204,23 @@
         if (diff.size() == assertMark) {
             diff.clear();
         }
-
+        if (VERBOSE_LOGGING) {
+            Log.v(TAG, "buildDiff: ops=" + diffToString(diff));
+        }
         return diff;
     }
 
+    private static String diffToString(ArrayList<ContentProviderOperation> ops) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[\n");
+        for (ContentProviderOperation op : ops) {
+            sb.append(op.toString());
+            sb.append(",\n");
+        }
+        sb.append("]\n");
+        return sb.toString();
+    }
+
     /**
      * Start building a {@link ContentProviderOperation} that will keep two
      * {@link RawContacts} together.
@@ -290,6 +309,9 @@
         return null;
     }
 
+    /**
+     * Find the raw-contact (an {@link EntityDelta}) with the specified ID.
+     */
     public EntityDelta getByRawContactId(Long rawContactId) {
         final int index = this.indexOfRawContactId(rawContactId);
         return (index == -1) ? null : this.get(index);
@@ -310,6 +332,23 @@
         return -1;
     }
 
+    /** Return the index of the first EntityDelta corresponding to a writable raw-contact, or -1. */
+    public int indexOfFirstWritableRawContact(Context context) {
+        // Find the first writable entity.
+        int entityIndex = 0;
+        for (EntityDelta delta : this) {
+            if (delta.getRawContactAccountType(context).areContactsWritable()) return entityIndex;
+            entityIndex++;
+        }
+        return -1;
+    }
+
+    /**  Return the first EntityDelta corresponding to a writable raw-contact, or null. */
+    public EntityDelta getFirstWritableRawContact(Context context) {
+        final int index = indexOfFirstWritableRawContact(context);
+        return (index == -1) ? null : get(index);
+    }
+
     public ValuesDelta getSuperPrimaryEntry(final String mimeType) {
         ValuesDelta primary = null;
         ValuesDelta randomEntry = null;
@@ -354,12 +393,14 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public int describeContents() {
         // Nothing special about this parcel
         return 0;
     }
 
     /** {@inheritDoc} */
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
         final int size = this.size();
         dest.writeInt(size);
@@ -383,14 +424,30 @@
 
     public static final Parcelable.Creator<EntityDeltaList> CREATOR =
             new Parcelable.Creator<EntityDeltaList>() {
+        @Override
         public EntityDeltaList createFromParcel(Parcel in) {
             final EntityDeltaList state = new EntityDeltaList();
             state.readFromParcel(in);
             return state;
         }
 
+        @Override
         public EntityDeltaList[] newArray(int size) {
             return new EntityDeltaList[size];
         }
     };
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("(");
+        sb.append("Split=");
+        sb.append(mSplitRawContacts);
+        sb.append(", Join=[");
+        sb.append(Arrays.toString(mJoinWithRawContactIds));
+        sb.append("], Values=");
+        sb.append(super.toString());
+        sb.append(")");
+        return sb.toString();
+    }
 }
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/EntityModifier.java
index 289ca54..2d87ff0 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/EntityModifier.java
@@ -53,6 +53,7 @@
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import java.text.ParsePosition;
@@ -60,12 +61,10 @@
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -103,19 +102,28 @@
     /**
      * Ensure that at least one of the given {@link DataKind} exists in the
      * given {@link EntityDelta} state, and try creating one if none exist.
+     * @return The child (either newly created or the first existing one), or null if the
+     *     account doesn't support this {@link DataKind}.
      */
-    public static void ensureKindExists(
+    public static ValuesDelta ensureKindExists(
             EntityDelta state, AccountType accountType, String mimeType) {
         final DataKind kind = accountType.getKindForMimetype(mimeType);
         final boolean hasChild = state.getMimeEntriesCount(mimeType, true) > 0;
 
-        if (!hasChild && kind != null) {
-            // Create child when none exists and valid kind
-            final ValuesDelta child = insertChild(state, kind);
-            if (kind.mimeType.equals(Photo.CONTENT_ITEM_TYPE)) {
-                child.setFromTemplate(true);
+        if (kind != null) {
+            if (hasChild) {
+                // Return the first entry.
+                return state.getMimeEntries(mimeType).get(0);
+            } else {
+                // Create child when none exists and valid kind
+                final ValuesDelta child = insertChild(state, kind);
+                if (kind.mimeType.equals(Photo.CONTENT_ITEM_TYPE)) {
+                    child.setFromTemplate(true);
+                }
+                return child;
             }
         }
+        return null;
     }
 
     /**
@@ -1228,7 +1236,7 @@
             return;
         }
 
-        final Map<Integer, EventEditType> allowedTypes = new HashMap<Integer, EventEditType>();
+        final SparseArray<EventEditType> allowedTypes = new SparseArray<EventEditType>();
         for (EditType editType : newDataKind.typeList) {
             allowedTypes.put(editType.rawValue, (EventEditType) editType);
         }
@@ -1239,7 +1247,8 @@
             }
             final String dateString = values.getAsString(Event.START_DATE);
             final Integer type = values.getAsInteger(Event.TYPE);
-            if (type != null && allowedTypes.containsKey(type) && !TextUtils.isEmpty(dateString)) {
+            if (type != null && (allowedTypes.indexOfKey(type) >= 0)
+                    && !TextUtils.isEmpty(dateString)) {
                 EventEditType suitableType = allowedTypes.get(type);
 
                 final ParsePosition position = new ParsePosition(0);
@@ -1323,7 +1332,7 @@
         }
         final Set<Integer> allowedTypes = new HashSet<Integer>();
         // key: type, value: the number of entries allowed for the type (specificMax)
-        final Map<Integer, Integer> typeSpecificMaxMap = new HashMap<Integer, Integer>();
+        final SparseIntArray typeSpecificMaxMap = new SparseIntArray();
         if (defaultType != null) {
             allowedTypes.add(defaultType);
             typeSpecificMaxMap.put(defaultType, -1);
@@ -1350,7 +1359,7 @@
         final int typeOverallMax = newDataKind.typeOverallMax;
 
         // key: type, value: the number of current entries.
-        final Map<Integer, Integer> currentEntryCount = new HashMap<Integer, Integer>();
+        final SparseIntArray currentEntryCount = new SparseIntArray();
         int totalCount = 0;
 
         for (ValuesDelta entry : mimeEntries) {
@@ -1381,11 +1390,9 @@
                 typeForNewAccount = oldType;
             }
             if (typeForNewAccount != null) {
-                final int specificMax = (typeSpecificMaxMap.containsKey(typeForNewAccount) ?
-                        typeSpecificMaxMap.get(typeForNewAccount) : 0);
+                final int specificMax = typeSpecificMaxMap.get(typeForNewAccount, 0);
                 if (specificMax >= 0) {
-                    final int currentCount = (currentEntryCount.get(typeForNewAccount) != null ?
-                            currentEntryCount.get(typeForNewAccount) : 0);
+                    final int currentCount = currentEntryCount.get(typeForNewAccount, 0);
                     if (currentCount >= specificMax) {
                         continue;
                     }
diff --git a/src/com/android/contacts/model/ExchangeAccountType.java b/src/com/android/contacts/model/ExchangeAccountType.java
index e5491d2..1e3f6ee 100644
--- a/src/com/android/contacts/model/ExchangeAccountType.java
+++ b/src/com/android/contacts/model/ExchangeAccountType.java
@@ -43,10 +43,10 @@
 
     public static final String ACCOUNT_TYPE = "com.android.exchange";
 
-    public ExchangeAccountType(Context context, String resPackageName) {
+    public ExchangeAccountType(Context context, String authenticatorPackageName) {
         this.accountType = ACCOUNT_TYPE;
-        this.resPackageName = null;
-        this.summaryResPackageName = resPackageName;
+        this.resourcePackageName = null;
+        this.syncAdapterPackageName = authenticatorPackageName;
 
         try {
             addDataKindStructuredName(context);
@@ -169,8 +169,8 @@
 
         kind.typeColumn = Phone.TYPE;
         kind.typeList = Lists.newArrayList();
-        kind.typeList.add(buildPhoneType(Phone.TYPE_HOME).setSpecificMax(2));
         kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE).setSpecificMax(1));
+        kind.typeList.add(buildPhoneType(Phone.TYPE_HOME).setSpecificMax(2));
         kind.typeList.add(buildPhoneType(Phone.TYPE_WORK).setSpecificMax(2));
         kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true)
                 .setSpecificMax(1));
diff --git a/src/com/android/contacts/model/ExternalAccountType.java b/src/com/android/contacts/model/ExternalAccountType.java
index f36e9e0..d7420af 100644
--- a/src/com/android/contacts/model/ExternalAccountType.java
+++ b/src/com/android/contacts/model/ExternalAccountType.java
@@ -101,17 +101,17 @@
      * @param injectedMetadata If non-null, it'll be used to initialize the type.  Only set by
      *     tests.  If null, the metadata is loaded from the specified package.
      */
-    ExternalAccountType(Context context, String resPackageName, boolean isExtension,
+    ExternalAccountType(Context context, String packageName, boolean isExtension,
             XmlResourceParser injectedMetadata) {
         this.mIsExtension = isExtension;
-        this.resPackageName = resPackageName;
-        this.summaryResPackageName = resPackageName;
+        this.resourcePackageName = packageName;
+        this.syncAdapterPackageName = packageName;
 
         final PackageManager pm = context.getPackageManager();
         final XmlResourceParser parser;
         if (injectedMetadata == null) {
             try {
-                parser = loadContactsXml(context, resPackageName);
+                parser = loadContactsXml(context, packageName);
             } catch (NameNotFoundException e1) {
                 // If the package name is not found, we can't initialize this account type.
                 return;
@@ -147,7 +147,7 @@
                 error.append(parser.getLineNumber());
             }
             error.append(" for external package ");
-            error.append(resPackageName);
+            error.append(packageName);
 
             Log.e(TAG, error.toString(), e);
             return;
@@ -159,13 +159,13 @@
 
         mExtensionPackageNames = new ArrayList<String>();
         mInviteActionLabelResId = resolveExternalResId(context, mInviteActionLabelAttribute,
-                summaryResPackageName, ATTR_INVITE_CONTACT_ACTION_LABEL);
+                syncAdapterPackageName, ATTR_INVITE_CONTACT_ACTION_LABEL);
         mViewGroupLabelResId = resolveExternalResId(context, mViewGroupLabelAttribute,
-                summaryResPackageName, ATTR_VIEW_GROUP_ACTION_LABEL);
+                syncAdapterPackageName, ATTR_VIEW_GROUP_ACTION_LABEL);
         titleRes = resolveExternalResId(context, mAccountTypeLabelAttribute,
-                this.resPackageName, ATTR_ACCOUNT_LABEL);
+                syncAdapterPackageName, ATTR_ACCOUNT_LABEL);
         iconRes = resolveExternalResId(context, mAccountTypeIconAttribute,
-                this.resPackageName, ATTR_ACCOUNT_ICON);
+                syncAdapterPackageName, ATTR_ACCOUNT_ICON);
 
         // If we reach this point, the account type has been successfully initialized.
         mIsInitialized = true;
diff --git a/src/com/android/contacts/model/FallbackAccountType.java b/src/com/android/contacts/model/FallbackAccountType.java
index d81f2f5..892c049 100644
--- a/src/com/android/contacts/model/FallbackAccountType.java
+++ b/src/com/android/contacts/model/FallbackAccountType.java
@@ -17,6 +17,7 @@
 package com.android.contacts.model;
 
 import com.android.contacts.R;
+import com.android.contacts.test.NeededForTesting;
 
 import android.content.Context;
 import android.util.Log;
@@ -30,8 +31,9 @@
         this.titleRes = R.string.account_phone;
         this.iconRes = R.mipmap.ic_launcher_contacts;
 
-        this.resPackageName = resPackageName;
-        this.summaryResPackageName = resPackageName;
+        // Note those are only set for unit tests.
+        this.resourcePackageName = resPackageName;
+        this.syncAdapterPackageName = resPackageName;
 
         try {
             addDataKindStructuredName(context);
@@ -63,7 +65,8 @@
      * In order to build {@link DataKind}s with the same resource package name,
      * {@code resPackageName} is injectable.
      */
-    static AccountType createForTest(Context context, String resPackageName) {
+    @NeededForTesting
+    static AccountType createWithPackageNameForTest(Context context, String resPackageName) {
         return new FallbackAccountType(context, resPackageName);
     }
 
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/GoogleAccountType.java
index 822d829..a8a4069 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/GoogleAccountType.java
@@ -39,10 +39,10 @@
     private static final List<String> mExtensionPackages =
             Lists.newArrayList("com.google.android.apps.plus");
 
-    public GoogleAccountType(Context context, String resPackageName) {
+    public GoogleAccountType(Context context, String authenticatorPackageName) {
         this.accountType = ACCOUNT_TYPE;
-        this.resPackageName = null;
-        this.summaryResPackageName = resPackageName;
+        this.resourcePackageName = null;
+        this.syncAdapterPackageName = authenticatorPackageName;
 
         try {
             addDataKindStructuredName(context);
@@ -183,4 +183,15 @@
     public boolean areContactsWritable() {
         return true;
     }
+
+    @Override
+    public String getViewContactNotifyServiceClassName() {
+        return "com.google.android.syncadapters.contacts." +
+                "SyncHighResPhotoIntentService";
+    }
+
+    @Override
+    public String getViewContactNotifyServicePackageName() {
+        return "com.google.android.syncadapters.contacts";
+    }
 }
diff --git a/src/com/android/contacts/preference/DisplayOrderPreference.java b/src/com/android/contacts/preference/DisplayOrderPreference.java
index fea01c8..bedce48 100644
--- a/src/com/android/contacts/preference/DisplayOrderPreference.java
+++ b/src/com/android/contacts/preference/DisplayOrderPreference.java
@@ -18,6 +18,7 @@
 
 import com.android.contacts.R;
 
+import android.app.AlertDialog.Builder;
 import android.content.Context;
 import android.preference.ListPreference;
 import android.provider.ContactsContract;
@@ -80,4 +81,11 @@
         }
         return true;
     }
+
+    @Override
+    // UX recommendation is not to show cancel button on such lists.
+    protected void onPrepareDialogBuilder(Builder builder) {
+        super.onPrepareDialogBuilder(builder);
+        builder.setNegativeButton(null, null);
+    }
 }
diff --git a/src/com/android/contacts/preference/SortOrderPreference.java b/src/com/android/contacts/preference/SortOrderPreference.java
index 81b034c..2ac9557 100644
--- a/src/com/android/contacts/preference/SortOrderPreference.java
+++ b/src/com/android/contacts/preference/SortOrderPreference.java
@@ -18,6 +18,7 @@
 
 import com.android.contacts.R;
 
+import android.app.AlertDialog.Builder;
 import android.content.Context;
 import android.preference.ListPreference;
 import android.provider.ContactsContract;
@@ -80,4 +81,11 @@
         }
         return true;
     }
+
+    @Override
+    // UX recommendation is not to show cancel button on such lists.
+    protected void onPrepareDialogBuilder(Builder builder) {
+        super.onPrepareDialogBuilder(builder);
+        builder.setNegativeButton(null, null);
+    }
 }
diff --git a/src/com/android/contacts/quickcontact/Action.java b/src/com/android/contacts/quickcontact/Action.java
index b2d869d..3a283fb 100644
--- a/src/com/android/contacts/quickcontact/Action.java
+++ b/src/com/android/contacts/quickcontact/Action.java
@@ -58,4 +58,7 @@
      * row
      */
     public long getDataId();
+
+    /** Returns the presence of this item or -1 if it was never set */
+    public int getPresence();
 }
diff --git a/src/com/android/contacts/quickcontact/ActionMultiMap.java b/src/com/android/contacts/quickcontact/ActionMultiMap.java
index 21234ce..ff9d677 100644
--- a/src/com/android/contacts/quickcontact/ActionMultiMap.java
+++ b/src/com/android/contacts/quickcontact/ActionMultiMap.java
@@ -25,12 +25,26 @@
  */
 public class ActionMultiMap extends HashMap<String, ArrayList<Action>> {
     public void put(String mimeType, Action info) {
-        // Create list for this MIME-type when needed
+       put(mimeType, info, false);
+    }
+
+    /**
+     * Puts the (mimeType,Action) tuple into the multimap at the front if
+     * the 'front' flag is set to true
+     */
+    public void put(String mimeType, Action info, boolean front) {
+        // Put the info first
         ArrayList<Action> collectList = get(mimeType);
+
+        // Create list for this MIME-type if needed
         if (collectList == null) {
             collectList = new ArrayList<Action>();
             put(mimeType, collectList);
         }
-        collectList.add(info);
+        if (front) {
+            collectList.add(0, info);
+        } else {
+            collectList.add(info);
+        }
     }
 }
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 266fd02..ddec799 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -21,14 +21,14 @@
 import com.android.contacts.model.AccountType.EditType;
 import com.android.contacts.model.DataKind;
 import com.android.contacts.util.Constants;
-import com.android.contacts.util.StructuredPostalUtils;
 import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.util.StructuredPostalUtils;
 
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.database.Cursor;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.net.WebAddress;
@@ -59,6 +59,7 @@
     private Intent mAlternateIntent;
     private int mAlternateIconDescriptionRes;
     private int mAlternateIconRes;
+    private int mPresence = -1;
 
     private Uri mDataUri;
     private long mDataId;
@@ -67,7 +68,8 @@
     /**
      * Create an action from common {@link Data} elements.
      */
-    public DataAction(Context context, String mimeType, DataKind kind, long dataId, Cursor cursor) {
+    public DataAction(Context context, String mimeType, DataKind kind, long dataId,
+            ContentValues entryValues) {
         mContext = context;
         mKind = kind;
         mMimeType = mimeType;
@@ -75,9 +77,8 @@
         // Determine type for subtitle
         mSubtitle = "";
         if (kind.typeColumn != null) {
-            final int typeColumnIndex = cursor.getColumnIndex(kind.typeColumn);
-            if (typeColumnIndex != -1) {
-                final int typeValue = cursor.getInt(typeColumnIndex);
+            if (entryValues.containsKey(kind.typeColumn)) {
+                final int typeValue = entryValues.getAsInteger(kind.typeColumn);
 
                 // get type string
                 for (EditType type : kind.typeList) {
@@ -87,8 +88,7 @@
                             mSubtitle = context.getString(type.labelRes);
                         } else {
                             // Custom type. Read it from the database
-                            mSubtitle = cursor.getString(cursor.getColumnIndexOrThrow(
-                                    type.customColumn));
+                            mSubtitle = entryValues.getAsString(type.customColumn);
                         }
                         break;
                     }
@@ -96,12 +96,11 @@
             }
         }
 
-        if (getAsInt(cursor, Data.IS_SUPER_PRIMARY) != 0) {
-            mIsPrimary = true;
-        }
+        final Integer superPrimary = entryValues.getAsInteger(Data.IS_SUPER_PRIMARY);
+        mIsPrimary = superPrimary != null && superPrimary != 0;
 
         if (mKind.actionBody != null) {
-            mBody = mKind.actionBody.inflateUsing(context, cursor);
+            mBody = mKind.actionBody.inflateUsing(context, entryValues);
         }
 
         mDataId = dataId;
@@ -113,11 +112,11 @@
         // Handle well-known MIME-types with special care
         if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
             if (PhoneCapabilityTester.isPhone(mContext)) {
-                final String number = getAsString(cursor, Phone.NUMBER);
+                final String number = entryValues.getAsString(Phone.NUMBER);
                 if (!TextUtils.isEmpty(number)) {
 
-                    final Intent phoneIntent = hasPhone ? new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            Uri.fromParts(Constants.SCHEME_TEL, number, null)) : null;
+                    final Intent phoneIntent = hasPhone ? ContactsUtils.getCallIntent(number)
+                            : null;
                     final Intent smsIntent = hasSms ? new Intent(Intent.ACTION_SENDTO,
                             Uri.fromParts(Constants.SCHEME_SMSTO, number, null)) : null;
 
@@ -136,10 +135,10 @@
             }
         } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
             if (PhoneCapabilityTester.isSipPhone(mContext)) {
-                final String address = getAsString(cursor, SipAddress.SIP_ADDRESS);
+                final String address = entryValues.getAsString(SipAddress.SIP_ADDRESS);
                 if (!TextUtils.isEmpty(address)) {
                     final Uri callUri = Uri.fromParts(Constants.SCHEME_SIP, address, null);
-                    mIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, callUri);
+                    mIntent = ContactsUtils.getCallIntent(callUri);
                     // Note that this item will get a SIP-specific variant
                     // of the "call phone" icon, rather than the standard
                     // app icon for the Phone app (which we show for
@@ -149,14 +148,14 @@
                 }
             }
         } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            final String address = getAsString(cursor, Email.DATA);
+            final String address = entryValues.getAsString(Email.DATA);
             if (!TextUtils.isEmpty(address)) {
                 final Uri mailUri = Uri.fromParts(Constants.SCHEME_MAILTO, address, null);
                 mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
             }
 
         } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            final String url = getAsString(cursor, Website.URL);
+            final String url = entryValues.getAsString(Website.URL);
             if (!TextUtils.isEmpty(url)) {
                 WebAddress webAddress = new WebAddress(url);
                 mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(webAddress.toString()));
@@ -164,21 +163,21 @@
 
         } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
             final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(
-                    getAsString(cursor, Data.MIMETYPE));
-            if (isEmail || isProtocolValid(cursor)) {
+                    entryValues.getAsString(Data.MIMETYPE));
+            if (isEmail || isProtocolValid(entryValues)) {
                 final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK :
-                        getAsInt(cursor, Im.PROTOCOL);
+                        entryValues.getAsInteger(Im.PROTOCOL);
 
                 if (isEmail) {
                     // Use Google Talk string when using Email, and clear data
                     // Uri so we don't try saving Email as primary.
-                    mSubtitle = context.getText(R.string.chat_gtalk);
+                    mSubtitle = Im.getProtocolLabel(context.getResources(), Im.PROTOCOL_GOOGLE_TALK,
+                            null);
                     mDataUri = null;
                 }
 
-                String host = getAsString(cursor, Im.CUSTOM_PROTOCOL);
-                String data = getAsString(cursor,
-                        isEmail ? Email.DATA : Im.DATA);
+                String host = entryValues.getAsString(Im.CUSTOM_PROTOCOL);
+                String data = entryValues.getAsString(isEmail ? Email.DATA : Im.DATA);
                 if (protocol != Im.PROTOCOL_CUSTOM) {
                     // Try bringing in a well-known host for specific protocols
                     host = ContactsUtils.lookupProviderNameFromId(protocol);
@@ -192,7 +191,8 @@
 
                     // If the address is also available for a video chat, we'll show the capability
                     // as a secondary action.
-                    final int chatCapability = getAsInt(cursor, Data.CHAT_CAPABILITY);
+                    final Integer chatCapabilityObj = entryValues.getAsInteger(Im.CHAT_CAPABILITY);
+                    final int chatCapability = chatCapabilityObj == null ? 0 : chatCapabilityObj;
                     final boolean isVideoChatCapable =
                             (chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0;
                     final boolean isAudioChatCapable =
@@ -211,7 +211,8 @@
                 }
             }
         } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            final String postalAddress = getAsString(cursor, StructuredPostal.FORMATTED_ADDRESS);
+            final String postalAddress =
+                    entryValues.getAsString(StructuredPostal.FORMATTED_ADDRESS);
             if (!TextUtils.isEmpty(postalAddress)) {
                 mIntent = StructuredPostalUtils.getViewPostalAddressIntent(postalAddress);
             }
@@ -223,29 +224,25 @@
             mIntent.setDataAndType(mDataUri, mimeType);
         }
 
-        // Always launch as new task, since we're like a launcher
-        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
     }
 
-    /** Read {@link String} from the given {@link Cursor}. */
-    private static String getAsString(Cursor cursor, String columnName) {
-        final int index = cursor.getColumnIndex(columnName);
-        return cursor.getString(index);
+    @Override
+    public int getPresence() {
+        return mPresence;
     }
 
-    /** Read {@link Integer} from the given {@link Cursor}. */
-    private static int getAsInt(Cursor cursor, String columnName) {
-        final int index = cursor.getColumnIndex(columnName);
-        return cursor.getInt(index);
+    public void setPresence(int presence) {
+        mPresence = presence;
     }
 
-    private boolean isProtocolValid(Cursor cursor) {
-        final int columnIndex = cursor.getColumnIndex(Im.PROTOCOL);
-        if (cursor.isNull(columnIndex)) {
+    private boolean isProtocolValid(ContentValues entryValues) {
+        final String protocol = entryValues.getAsString(Im.PROTOCOL);
+        if (protocol == null) {
             return false;
         }
         try {
-            Integer.valueOf(cursor.getString(columnIndex));
+            Integer.valueOf(protocol);
         } catch (NumberFormatException e) {
             return false;
         }
@@ -286,13 +283,13 @@
     public Drawable getAlternateIcon() {
         if (mAlternateIconRes == 0) return null;
 
-        final String resPackageName = mKind.resPackageName;
-        if (resPackageName == null) {
+        final String resourcePackageName = mKind.resourcePackageName;
+        if (resourcePackageName == null) {
             return mContext.getResources().getDrawable(mAlternateIconRes);
         }
 
         final PackageManager pm = mContext.getPackageManager();
-        return pm.getDrawable(resPackageName, mAlternateIconRes, null);
+        return pm.getDrawable(resourcePackageName, mAlternateIconRes, null);
     }
 
     @Override
diff --git a/src/com/android/contacts/quickcontact/FloatingChildLayout.java b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
index 5358aca..20a3c1e 100644
--- a/src/com/android/contacts/quickcontact/FloatingChildLayout.java
+++ b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
@@ -17,17 +17,21 @@
 package com.android.contacts.quickcontact;
 
 import com.android.contacts.R;
+import com.android.contacts.test.NeededForReflection;
+import com.android.contacts.util.SchedulingUtils;
 
 import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewPropertyAnimator;
 import android.view.animation.AnimationUtils;
 import android.widget.FrameLayout;
 import android.widget.PopupWindow;
@@ -46,18 +50,46 @@
  * {@link PopupWindow} might work better.
  */
 public class FloatingChildLayout extends FrameLayout {
-    private static final String TAG = "FloatingChild";
+    private static final String TAG = "FloatingChildLayout";
     private int mFixedTopPosition;
     private View mChild;
     private Rect mTargetScreen = new Rect();
     private final int mAnimationDuration;
 
+    /** The phase of the background dim. This is one of the values of {@link BackgroundPhase}  */
+    private int mBackgroundPhase = BackgroundPhase.BEFORE;
+
+    private ObjectAnimator mBackgroundAnimator = ObjectAnimator.ofInt(this,
+            "backgroundColorAlpha", 0, DIM_BACKGROUND_ALPHA);
+
+    private interface BackgroundPhase {
+        public static final int BEFORE = 0;
+        public static final int APPEARING_OR_VISIBLE = 1;
+        public static final int DISAPPEARING_OR_GONE = 3;
+    }
+
+    /** The phase of the contents window. This is one of the values of {@link ForegroundPhase}  */
+    private int mForegroundPhase = ForegroundPhase.BEFORE;
+
+    private interface ForegroundPhase {
+        public static final int BEFORE = 0;
+        public static final int APPEARING = 1;
+        public static final int IDLE = 2;
+        public static final int DISAPPEARING = 3;
+        public static final int AFTER = 4;
+    }
+
+    // Black, 50% alpha as per the system default.
+    private static final int DIM_BACKGROUND_ALPHA = 0x7F;
+
     public FloatingChildLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         final Resources resources = getResources();
         mFixedTopPosition =
                 resources.getDimensionPixelOffset(R.dimen.quick_contact_top_position);
         mAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime);
+
+        super.setBackground(new ColorDrawable(0));
     }
 
     @Override
@@ -66,8 +98,8 @@
         mChild.setDuplicateParentStateEnabled(true);
 
         // this will be expanded in showChild()
-        mChild.setScaleX(0.0f);
-        mChild.setScaleY(0.0f);
+        mChild.setScaleX(0.5f);
+        mChild.setScaleY(0.5f);
         mChild.setAlpha(0.0f);
     }
 
@@ -76,6 +108,14 @@
     }
 
     /**
+     * FloatingChildLayout manages its own background, don't set it.
+     */
+    @Override
+    public void setBackground(Drawable background) {
+        Log.wtf(TAG, "don't setBackground(), it is managed internally");
+    }
+
+    /**
      * Set {@link Rect} in screen coordinates that {@link #getChild()} should be
      * centered around.
      */
@@ -139,49 +179,111 @@
         child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
     }
 
-    /** Begin animating {@link #getChild()} visible. */
-    public void showChild(Runnable onAnimationEndRunnable) {
-        animateScale(false, onAnimationEndRunnable);
+    @NeededForReflection
+    public void setBackgroundColorAlpha(int alpha) {
+        setBackgroundColor(alpha << 24);
     }
 
-    /** Begin animating {@link #getChild()} invisible. */
-    public void hideChild(Runnable onAnimationEndRunnable) {
-        animateScale(true, onAnimationEndRunnable);
-    }
+    public void fadeInBackground() {
+        if (mBackgroundPhase == BackgroundPhase.BEFORE) {
+            mBackgroundPhase = BackgroundPhase.APPEARING_OR_VISIBLE;
 
-    /** Creates the open/close animation */
-    private void animateScale(boolean isExitAnimation, final Runnable onAnimationEndRunnable) {
-        mChild.setPivotX(mTargetScreen.centerX() - mChild.getLeft());
-        mChild.setPivotY(mTargetScreen.centerY() - mChild.getTop());
-        ViewPropertyAnimator animator = mChild.animate();
-        animator.setDuration(mAnimationDuration);
-        final int scaleInterpolator = isExitAnimation ? android.R.interpolator.accelerate_quint
-                : android.R.interpolator.decelerate_quint;
-        animator.setInterpolator(AnimationUtils.loadInterpolator(getContext(), scaleInterpolator));
-        final float scaleTarget = isExitAnimation ? 0.5f : 1.0f;
-        animator.scaleX(scaleTarget);
-        animator.scaleY(scaleTarget);
-        animator.alpha(isExitAnimation ? 0.0f : 1.0f);
+            createChildLayer();
 
-        if (onAnimationEndRunnable != null) {
-            animator.setListener(new AnimatorListener() {
+            SchedulingUtils.doAfterDraw(this, new Runnable() {
                 @Override
-                public void onAnimationStart(Animator animation) {}
-
-                @Override
-                public void onAnimationRepeat(Animator animation) {}
-
-                @Override
-                public void onAnimationCancel(Animator animation) {}
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    onAnimationEndRunnable.run();
+                public void run() {
+                    mBackgroundAnimator.setDuration(mAnimationDuration).start();
                 }
             });
         }
     }
 
+    public void fadeOutBackground() {
+        if (mBackgroundPhase == BackgroundPhase.APPEARING_OR_VISIBLE) {
+            mBackgroundPhase = BackgroundPhase.DISAPPEARING_OR_GONE;
+            if (mBackgroundAnimator.isRunning()) {
+                mBackgroundAnimator.reverse();
+            } else {
+                ObjectAnimator.ofInt(this, "backgroundColorAlpha", DIM_BACKGROUND_ALPHA, 0).
+                        setDuration(mAnimationDuration).start();
+            }
+        }
+    }
+
+    public boolean isContentFullyVisible() {
+        return mForegroundPhase == ForegroundPhase.IDLE;
+    }
+
+    /** Begin animating {@link #getChild()} visible. */
+    public void showContent(final Runnable onAnimationEndRunnable) {
+        if (mForegroundPhase == ForegroundPhase.BEFORE) {
+            mForegroundPhase = ForegroundPhase.APPEARING;
+            animateScale(false, onAnimationEndRunnable);
+        }
+    }
+
+    /**
+     * Begin animating {@link #getChild()} invisible. Returns false if animation is not valid in
+     * this state
+     */
+    public boolean hideContent(final Runnable onAnimationEndRunnable) {
+        if (mForegroundPhase == ForegroundPhase.APPEARING ||
+                mForegroundPhase == ForegroundPhase.IDLE) {
+            mForegroundPhase = ForegroundPhase.DISAPPEARING;
+
+            createChildLayer();
+
+            animateScale(true, onAnimationEndRunnable);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void createChildLayer() {
+        mChild.invalidate();
+        mChild.setLayerType(LAYER_TYPE_HARDWARE, null);
+        mChild.buildLayer();
+    }
+
+    /** Creates the open/close animation */
+    private void animateScale(
+            final boolean isExitAnimation,
+            final Runnable onAnimationEndRunnable) {
+        mChild.setPivotX(mTargetScreen.centerX() - mChild.getLeft());
+        mChild.setPivotY(mTargetScreen.centerY() - mChild.getTop());
+
+        final int scaleInterpolator = isExitAnimation
+                ? android.R.interpolator.accelerate_quint
+                : android.R.interpolator.decelerate_quint;
+        final float scaleTarget = isExitAnimation ? 0.5f : 1.0f;
+
+        mChild.animate()
+                .setDuration(mAnimationDuration)
+                .setInterpolator(AnimationUtils.loadInterpolator(getContext(), scaleInterpolator))
+                .scaleX(scaleTarget)
+                .scaleY(scaleTarget)
+                .alpha(isExitAnimation ? 0.0f : 1.0f)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        mChild.setLayerType(LAYER_TYPE_NONE, null);
+                        if (isExitAnimation) {
+                            if (mForegroundPhase == ForegroundPhase.DISAPPEARING) {
+                                mForegroundPhase = ForegroundPhase.AFTER;
+                                if (onAnimationEndRunnable != null) onAnimationEndRunnable.run();
+                            }
+                        } else {
+                            if (mForegroundPhase == ForegroundPhase.APPEARING) {
+                                mForegroundPhase = ForegroundPhase.IDLE;
+                                if (onAnimationEndRunnable != null) onAnimationEndRunnable.run();
+                            }
+                        }
+                    }
+                });
+    }
+
     private View.OnTouchListener mOutsideTouchListener;
 
     public void setOnOutsideTouchListener(View.OnTouchListener listener) {
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 2c62fe4..7c93a26 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -17,44 +17,44 @@
 package com.android.contacts.quickcontact;
 
 import com.android.contacts.Collapser;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactLoader;
 import com.android.contacts.R;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.DataKind;
+import com.android.contacts.util.Constants;
 import com.android.contacts.util.DataStatus;
-import com.android.contacts.util.NotifyingAsyncQueryHandler;
-import com.android.contacts.util.NotifyingAsyncQueryHandler.AsyncQueryListener;
+import com.android.contacts.util.ImageViewDrawableSetter;
+import com.android.contacts.util.SchedulingUtils;
+import com.android.contacts.util.StopWatch;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentManager;
+import android.app.LoaderManager.LoaderCallbacks;
 import android.content.ActivityNotFoundException;
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
+import android.content.Entity;
+import android.content.Entity.NamedContentValues;
 import android.content.Intent;
+import android.content.Loader;
 import android.content.pm.PackageManager;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.provider.ContactsContract.CommonDataKinds.Website;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.DisplayPhoto;
 import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.RawContacts;
 import android.support.v13.app.FragmentPagerAdapter;
@@ -74,7 +74,6 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -92,19 +91,17 @@
 
     private static final boolean TRACE_LAUNCH = false;
     private static final String TRACE_TAG = "quickcontact";
+    private static final int POST_DRAW_WAIT_DURATION = 60;
+    private static final boolean ENABLE_STOPWATCH = false;
+
 
     @SuppressWarnings("deprecation")
     private static final String LEGACY_AUTHORITY = android.provider.Contacts.AUTHORITY;
 
-    private NotifyingAsyncQueryHandler mHandler;
-
     private Uri mLookupUri;
     private String[] mExcludeMimes;
     private List<String> mSortedActionMimeTypes = Lists.newArrayList();
 
-    private boolean mHasFinishedAnimatingIn = false;
-    private boolean mHasStartedAnimatingOut = false;
-
     private FloatingChildLayout mFloatingLayout;
 
     private View mPhotoContainer;
@@ -117,6 +114,10 @@
     private ImageButton mOpenDetailsPushLayerButton;
     private ViewPager mListPager;
 
+    private ContactLoader mContactLoader;
+
+    private final ImageViewDrawableSetter mPhotoSetter = new ImageViewDrawableSetter();
+
     /**
      * Keeps the default action per mimetype. Empty if no default actions are set
      */
@@ -147,19 +148,52 @@
     private static final List<String> TRAILING_MIMETYPES = Lists.newArrayList(
             StructuredPostal.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE);
 
-    /** Id for the background handler that loads the data */
-    private static final int HANDLER_ID_DATA = 1;
+    /** Id for the background loader */
+    private static final int LOADER_ID = 0;
+
+    private StopWatch mStopWatch = ENABLE_STOPWATCH
+            ? StopWatch.start("QuickContact") : StopWatch.getNullStopWatch();
 
     @Override
     protected void onCreate(Bundle icicle) {
+        mStopWatch.lap("c"); // create start
         super.onCreate(icicle);
 
+        mStopWatch.lap("sc"); // super.onCreate
+
+        if (TRACE_LAUNCH) android.os.Debug.startMethodTracing(TRACE_TAG);
+
+        // Parse intent
+        final Intent intent = getIntent();
+
+        Uri lookupUri = intent.getData();
+
+        // Check to see whether it comes from the old version.
+        if (lookupUri != null && LEGACY_AUTHORITY.equals(lookupUri.getAuthority())) {
+            final long rawContactId = ContentUris.parseId(lookupUri);
+            lookupUri = RawContacts.getContactLookupUri(getContentResolver(),
+                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId));
+        }
+
+        mLookupUri = Preconditions.checkNotNull(lookupUri, "missing lookupUri");
+
+        mExcludeMimes = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
+
+        mStopWatch.lap("i"); // intent parsed
+
+        mContactLoader = (ContactLoader) getLoaderManager().initLoader(
+                LOADER_ID, null, mLoaderCallbacks);
+
+        mStopWatch.lap("ld"); // loader started
+
         // Show QuickContact in front of soft input
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
 
         setContentView(R.layout.quickcontact_activity);
 
+        mStopWatch.lap("l"); // layout inflated
+
         mFloatingLayout = (FloatingChildLayout) findViewById(R.id.floating_layout);
         mTrack = (ViewGroup) findViewById(R.id.track);
         mTrackScroller = (HorizontalScrollView) findViewById(R.id.track_scroller);
@@ -172,7 +206,8 @@
         mFloatingLayout.setOnOutsideTouchListener(new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
-                return handleOutsideTouch();
+                handleOutsideTouch();
+                return true;
             }
         });
 
@@ -180,9 +215,10 @@
             @Override
             public void onClick(View v) {
                 final Intent intent = new Intent(Intent.ACTION_VIEW, mLookupUri);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                mContactLoader.cacheResult();
+                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                 startActivity(intent);
-                hide(false);
+                close(false);
             }
         };
         mOpenDetailsButton.setOnClickListener(openDetailsClickHandler);
@@ -190,125 +226,78 @@
         mListPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
         mListPager.setOnPageChangeListener(new PageChangeListener());
 
-        mHandler = new NotifyingAsyncQueryHandler(this, mQueryListener);
-
-        show();
-    }
-
-    private void show() {
-
-        if (TRACE_LAUNCH) {
-            android.os.Debug.startMethodTracing(TRACE_TAG);
+        final Rect sourceBounds = intent.getSourceBounds();
+        if (sourceBounds != null) {
+            mFloatingLayout.setChildTargetScreen(sourceBounds);
         }
 
-        final Intent intent = getIntent();
-
-        Uri lookupUri = intent.getData();
-
-        // Check to see whether it comes from the old version.
-        if (LEGACY_AUTHORITY.equals(lookupUri.getAuthority())) {
-            final long rawContactId = ContentUris.parseId(lookupUri);
-            lookupUri = RawContacts.getContactLookupUri(getContentResolver(),
-                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId));
-        }
-
-        mLookupUri = Preconditions.checkNotNull(lookupUri, "missing lookupUri");
-
-        // Read requested parameters for displaying
-        final Rect targetScreen = intent.getSourceBounds();
-        Preconditions.checkNotNull(targetScreen, "missing targetScreen");
-        mFloatingLayout.setChildTargetScreen(targetScreen);
-
-        mExcludeMimes = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
-
         // find and prepare correct header view
         mPhotoContainer = findViewById(R.id.photo_container);
         setHeaderNameText(R.id.name, R.string.missing_name);
 
-        // Start background query for data, but only select photo rows when they
-        // directly match the super-primary PHOTO_ID.
-        final Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
-        mHandler.cancelOperation(HANDLER_ID_DATA);
+        mStopWatch.lap("v"); // view initialized
 
-        // Select all data items of the contact (except for photos, where we only select the display
-        // photo)
-        mHandler.startQuery(HANDLER_ID_DATA, lookupUri, dataUri, DataQuery.PROJECTION, Data.MIMETYPE
-                + "!=? OR (" + Data.MIMETYPE + "=? AND " + Data._ID + "=" + Contacts.PHOTO_ID
-                + ")", new String[] { Photo.CONTENT_ITEM_TYPE, Photo.CONTENT_ITEM_TYPE }, null);
+        SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() {
+            @Override
+            public void run() {
+                mFloatingLayout.fadeInBackground();
+            }
+        });
+
+        mStopWatch.lap("cf"); // onCreate finished
     }
 
-    private boolean handleOutsideTouch() {
-        if (!mHasFinishedAnimatingIn) return false;
-        if (mHasStartedAnimatingOut) return false;
-
-        mHasStartedAnimatingOut = true;
-        hide(true);
-        return true;
+    private void handleOutsideTouch() {
+        if (mFloatingLayout.isContentFullyVisible()) {
+            close(true);
+        }
     }
 
-    private void hide(boolean withAnimation) {
+    private void close(boolean withAnimation) {
         // cancel any pending queries
-        mHandler.cancelOperation(HANDLER_ID_DATA);
+        getLoaderManager().destroyLoader(LOADER_ID);
 
         if (withAnimation) {
-            mFloatingLayout.hideChild(new Runnable() {
+            mFloatingLayout.fadeOutBackground();
+            final boolean animated = mFloatingLayout.hideContent(new Runnable() {
                 @Override
                 public void run() {
-                    finish();
+                    // Wait until the final animation frame has been drawn, otherwise
+                    // there is jank as the framework transitions to the next Activity.
+                    SchedulingUtils.doAfterDraw(mFloatingLayout, new Runnable() {
+                        @Override
+                        public void run() {
+                            // Unfortunately, we need to also use postDelayed() to wait a moment
+                            // for the frame to be drawn, else the framework's activity-transition
+                            // animation will kick in before the final frame is available to it.
+                            // This seems unavoidable.  The problem isn't merely that there is no
+                            // post-draw listener API; if that were so, it would be sufficient to
+                            // call post() instead of postDelayed().
+                            new Handler().postDelayed(new Runnable() {
+                                @Override
+                                public void run() {
+                                    finish();
+                                }
+                            }, POST_DRAW_WAIT_DURATION);
+                        }
+                    });
                 }
             });
+            if (!animated) {
+                // If we were in the wrong state, simply quit (this can happen for example
+                // if the user pushes BACK before anything has loaded)
+                finish();
+            }
         } else {
-            mFloatingLayout.hideChild(null);
             finish();
         }
     }
 
     @Override
     public void onBackPressed() {
-        hide(true);
+        close(true);
     }
 
-    private final AsyncQueryListener mQueryListener = new AsyncQueryListener() {
-        @Override
-        public synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
-            try {
-                if (isFinishing()) {
-                    hide(false);
-                    return;
-                } else if (cursor == null || cursor.getCount() == 0) {
-                    Toast.makeText(QuickContactActivity.this, R.string.invalidContactMessage,
-                            Toast.LENGTH_LONG).show();
-                    hide(false);
-                    return;
-                }
-
-                bindData(cursor);
-
-                if (TRACE_LAUNCH) {
-                    android.os.Debug.stopMethodTracing();
-                }
-
-                // Data bound and ready, pull curtain to show. Put this on the Handler to ensure
-                // that the layout passes are completed
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mFloatingLayout.showChild(new Runnable() {
-                            @Override
-                            public void run() {
-                                mHasFinishedAnimatingIn = true;
-                            }
-                        });
-                    }
-                });
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-    };
-
     /** Assign this string to the view if it is not empty. */
     private void setHeaderNameText(int id, int resId) {
         setHeaderNameText(id, getText(resId));
@@ -325,35 +314,6 @@
     }
 
     /**
-     * Assign this string to the view (if found in {@link #mPhotoContainer}), or hiding this view
-     * if there is no string.
-     */
-    private void setHeaderText(int id, int resId) {
-        setHeaderText(id, getText(resId));
-    }
-
-    /**
-     * Assign this string to the view (if found in {@link #mPhotoContainer}), or hiding this view
-     * if there is no string.
-     */
-    private void setHeaderText(int id, CharSequence value) {
-        final View view = mPhotoContainer.findViewById(id);
-        if (view instanceof TextView) {
-            ((TextView)view).setText(value);
-            view.setVisibility(TextUtils.isEmpty(value) ? View.GONE : View.VISIBLE);
-        }
-    }
-
-    /** Assign this image to the view, if found in {@link #mPhotoContainer}. */
-    private void setHeaderImage(int id, Drawable drawable) {
-        final View view = mPhotoContainer.findViewById(id);
-        if (view instanceof ImageView) {
-            ((ImageView)view).setImageDrawable(drawable);
-            view.setVisibility(drawable == null ? View.GONE : View.VISIBLE);
-        }
-    }
-
-    /**
      * Check if the given MIME-type appears in the list of excluded MIME-types
      * that the most-recent caller requested.
      */
@@ -368,9 +328,9 @@
     }
 
     /**
-     * Handle the result from the {@link #TOKEN_DATA} query.
+     * Handle the result from the ContactLoader
      */
-    private void bindData(Cursor cursor) {
+    private void bindData(ContactLoader.Result data) {
         final ResolveCache cache = ResolveCache.getInstance(this);
         final Context context = this;
 
@@ -379,113 +339,76 @@
 
         mDefaultsMap.clear();
 
-        final DataStatus status = new DataStatus();
+        mStopWatch.lap("atm"); // AccountTypeManager initialization start
         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(
                 context.getApplicationContext());
+        mStopWatch.lap("fatm"); // AccountTypeManager initialization finished
+
         final ImageView photoView = (ImageView) mPhotoContainer.findViewById(R.id.photo);
+        mPhotoSetter.setupContactPhoto(data, photoView);
 
-        Bitmap photoBitmap = null;
-        while (cursor.moveToNext()) {
-            // Handle any social status updates from this row
-            status.possibleUpdate(cursor);
+        mStopWatch.lap("ph"); // Photo set
 
-            final String mimeType = cursor.getString(DataQuery.MIMETYPE);
+        for (Entity entity : data.getEntities()) {
+            final ContentValues entityValues = entity.getEntityValues();
+            final String accountType = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
+            final String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
+            for (NamedContentValues subValue : entity.getSubValues()) {
+                final ContentValues entryValues = subValue.values;
+                final String mimeType = entryValues.getAsString(Data.MIMETYPE);
 
-            // Skip this data item if MIME-type excluded
-            if (isMimeExcluded(mimeType)) continue;
+                // Skip this data item if MIME-type excluded
+                if (isMimeExcluded(mimeType)) continue;
 
-            final long dataId = cursor.getLong(DataQuery._ID);
-            final String accountType = cursor.getString(DataQuery.ACCOUNT_TYPE);
-            final String dataSet = cursor.getString(DataQuery.DATA_SET);
-            final boolean isPrimary = cursor.getInt(DataQuery.IS_PRIMARY) != 0;
-            final boolean isSuperPrimary = cursor.getInt(DataQuery.IS_SUPER_PRIMARY) != 0;
+                final long dataId = entryValues.getAsLong(Data._ID);
+                final Integer primary = entryValues.getAsInteger(Data.IS_PRIMARY);
+                final boolean isPrimary = primary != null && primary != 0;
+                final Integer superPrimary = entryValues.getAsInteger(Data.IS_SUPER_PRIMARY);
+                final boolean isSuperPrimary = superPrimary != null && superPrimary != 0;
 
-            // Handle photos included as data row
-            if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                final int displayPhotoColumnIndex = cursor.getColumnIndex(Photo.PHOTO_FILE_ID);
-                final boolean hasDisplayPhoto = !cursor.isNull(displayPhotoColumnIndex);
-                if (hasDisplayPhoto) {
-                    final long displayPhotoId = cursor.getLong(displayPhotoColumnIndex);
-                    final Uri displayPhotoUri = ContentUris.withAppendedId(
-                            DisplayPhoto.CONTENT_URI, displayPhotoId);
-                    // Fetch and JPEG uncompress on the background thread
-                    new AsyncTask<Void, Void, Bitmap>() {
-                        @Override
-                        protected Bitmap doInBackground(Void... params) {
-                            try {
-                                AssetFileDescriptor fd = getContentResolver()
-                                        .openAssetFileDescriptor(displayPhotoUri, "r");
-                                return BitmapFactory.decodeStream(fd.createInputStream());
-                            } catch (IOException e) {
-                                Log.e(TAG, "Error getting display photo. Ignoring, as we already " +
-                                        "have the thumbnail", e);
-                                return null;
-                            }
+                final DataKind kind =
+                        accountTypes.getKindOrFallback(accountType, dataSet, mimeType);
+
+                if (kind != null) {
+                    // Build an action for this data entry, find a mapping to a UI
+                    // element, build its summary from the cursor, and collect it
+                    // along with all others of this MIME-type.
+                    final Action action = new DataAction(context, mimeType, kind, dataId,
+                            entryValues);
+                    final boolean wasAdded = considerAdd(action, cache, isSuperPrimary);
+                    if (wasAdded) {
+                        // Remember the default
+                        if (isSuperPrimary || (isPrimary && (mDefaultsMap.get(mimeType) == null))) {
+                            mDefaultsMap.put(mimeType, action);
                         }
-
-                        @Override
-                        protected void onPostExecute(Bitmap result) {
-                            if (result == null) return;
-                            photoView.setImageBitmap(result);
-                        }
-                    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+                    }
                 }
-                final int photoColumnIndex = cursor.getColumnIndex(Photo.PHOTO);
-                final byte[] photoBlob = cursor.getBlob(photoColumnIndex);
-                if (photoBlob != null) {
-                    photoBitmap = BitmapFactory.decodeByteArray(photoBlob, 0, photoBlob.length);
-                }
-                continue;
-            }
 
-            final DataKind kind = accountTypes.getKindOrFallback(accountType, dataSet, mimeType);
-
-            if (kind != null) {
-                // Build an action for this data entry, find a mapping to a UI
-                // element, build its summary from the cursor, and collect it
-                // along with all others of this MIME-type.
-                final Action action = new DataAction(context, mimeType, kind, dataId, cursor);
-                final boolean wasAdded = considerAdd(action, cache);
-                if (wasAdded) {
-                    // Remember the default
-                    if (isSuperPrimary || (isPrimary && (mDefaultsMap.get(mimeType) == null))) {
-                        mDefaultsMap.put(mimeType, action);
+                // Handle Email rows with presence data as Im entry
+                final DataStatus status = data.getStatuses().get(dataId);
+                if (status != null && Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                    final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
+                            Im.CONTENT_ITEM_TYPE);
+                    if (imKind != null) {
+                        final DataAction action = new DataAction(context, Im.CONTENT_ITEM_TYPE,
+                                imKind, dataId, entryValues);
+                        action.setPresence(status.getPresence());
+                        considerAdd(action, cache, isSuperPrimary);
                     }
                 }
             }
-
-            // Handle Email rows with presence data as Im entry
-            final boolean hasPresence = !cursor.isNull(DataQuery.PRESENCE);
-            if (hasPresence && Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
-                        Im.CONTENT_ITEM_TYPE);
-                if (imKind != null) {
-                    final DataAction action = new DataAction(context, Im.CONTENT_ITEM_TYPE, imKind,
-                            dataId, cursor);
-                    considerAdd(action, cache);
-                }
-            }
         }
 
+        mStopWatch.lap("e"); // Entities inflated
+
         // Collapse Action Lists (remove e.g. duplicate e-mail addresses from different sources)
         for (List<Action> actionChildren : mActions.values()) {
             Collapser.collapseList(actionChildren);
         }
 
-        if (cursor.moveToLast()) {
-            // Read contact name from last data row
-            final String name = cursor.getString(DataQuery.DISPLAY_NAME);
-            setHeaderNameText(R.id.name, name);
-        }
+        mStopWatch.lap("c"); // List collapsed
 
-        if (photoView != null) {
-            // Place photo when discovered in data, otherwise show generic avatar
-            if (photoBitmap != null) {
-                photoView.setImageBitmap(photoBitmap);
-            } else {
-                photoView.setImageResource(ContactPhotoManager.getDefaultAvatarResId(true, false));
-            }
-        }
+        setHeaderNameText(R.id.name, data.getDisplayName());
 
         // All the mime-types to add.
         final Set<String> containedTypes = new HashSet<String>(mActions.keySet());
@@ -514,12 +437,17 @@
             }
         }
 
+        mStopWatch.lap("mt"); // Mime types initialized
+
         // Add buttons for each mimetype
+        mTrack.removeAllViews();
         for (String mimeType : mSortedActionMimeTypes) {
             final View actionView = inflateAction(mimeType, cache, mTrack);
             mTrack.addView(actionView);
         }
 
+        mStopWatch.lap("mt"); // Buttons added
+
         final boolean hasData = !mSortedActionMimeTypes.isEmpty();
         mTrackScroller.setVisibility(hasData ? View.VISIBLE : View.GONE);
         mSelectedTabRectangle.setVisibility(hasData ? View.VISIBLE : View.GONE);
@@ -531,11 +459,14 @@
      * Consider adding the given {@link Action}, which will only happen if
      * {@link PackageManager} finds an application to handle
      * {@link Action#getIntent()}.
+     * @param action the action to handle
+     * @param resolveCache cache of applications that can handle actions
+     * @param front indicates whether to add the action to the front of the list
      * @return true if action has been added
      */
-    private boolean considerAdd(Action action, ResolveCache resolveCache) {
+    private boolean considerAdd(Action action, ResolveCache resolveCache, boolean front) {
         if (resolveCache.hasResolve(action)) {
-            mActions.put(action.getMimeType(), action);
+            mActions.put(action.getMimeType(), action, front);
             return true;
         }
         return false;
@@ -574,6 +505,67 @@
         listFragment.setListener(mListFragmentListener);
     }
 
+    private LoaderCallbacks<ContactLoader.Result> mLoaderCallbacks =
+            new LoaderCallbacks<ContactLoader.Result>() {
+        @Override
+        public void onLoaderReset(Loader<ContactLoader.Result> loader) {
+        }
+
+        @Override
+        public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
+            mStopWatch.lap("lf"); // onLoadFinished
+            if (isFinishing()) {
+                close(false);
+                return;
+            }
+            if (data.isError()) {
+                // This shouldn't ever happen, so throw an exception. The {@link ContactLoader}
+                // should log the actual exception.
+                throw new IllegalStateException("Failed to load contact", data.getException());
+            }
+            if (data.isNotFound()) {
+                Log.i(TAG, "No contact found: " + ((ContactLoader)loader).getLookupUri());
+                Toast.makeText(QuickContactActivity.this, R.string.invalidContactMessage,
+                        Toast.LENGTH_LONG).show();
+                close(false);
+                return;
+            }
+
+            bindData(data);
+
+            mStopWatch.lap("bd"); // bindData finished
+
+            if (TRACE_LAUNCH) android.os.Debug.stopMethodTracing();
+            if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
+                Log.d(Constants.PERFORMANCE_TAG, "QuickContact shown");
+            }
+
+            // Data bound and ready, pull curtain to show. Put this on the Handler to ensure
+            // that the layout passes are completed
+            SchedulingUtils.doAfterLayout(mFloatingLayout, new Runnable() {
+                @Override
+                public void run() {
+                    mFloatingLayout.showContent(new Runnable() {
+                        @Override
+                        public void run() {
+                            mContactLoader.upgradeToFullContact();
+                        }
+                    });
+                }
+            });
+            mStopWatch.stopAndLog(TAG, 0);
+            mStopWatch = StopWatch.getNullStopWatch(); // We're done with it.
+        }
+
+        @Override
+        public Loader<ContactLoader.Result> onCreateLoader(int id, Bundle args) {
+            if (mLookupUri == null) {
+                Log.wtf(TAG, "Lookup uri wasn't initialized. Loader was started too early");
+            }
+            return new ContactLoader(getApplicationContext(), mLookupUri, false);
+        }
+    };
+
     /** A type (e.g. Call/Addresses was clicked) */
     private final OnClickListener mTypeViewClickListener = new OnClickListener() {
         @Override
@@ -646,60 +638,11 @@
                                 Toast.LENGTH_SHORT).show();
                     }
 
-                    hide(false);
+                    close(false);
                 }
             };
             // Defer the action to make the window properly repaint
             new Handler().post(startAppRunnable);
         }
     };
-
-    private interface DataQuery {
-        final String[] PROJECTION = new String[] {
-                Data._ID,
-
-                RawContacts.ACCOUNT_TYPE,
-                RawContacts.DATA_SET,
-                Contacts.STARRED,
-                Contacts.DISPLAY_NAME,
-
-                Data.STATUS,
-                Data.STATUS_RES_PACKAGE,
-                Data.STATUS_ICON,
-                Data.STATUS_LABEL,
-                Data.STATUS_TIMESTAMP,
-                Data.PRESENCE,
-                Data.CHAT_CAPABILITY,
-
-                Data.RES_PACKAGE,
-                Data.MIMETYPE,
-                Data.IS_PRIMARY,
-                Data.IS_SUPER_PRIMARY,
-                Data.RAW_CONTACT_ID,
-
-                Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA4, Data.DATA5,
-                Data.DATA6, Data.DATA7, Data.DATA8, Data.DATA9, Data.DATA10, Data.DATA11,
-                Data.DATA12, Data.DATA13, Data.DATA14, Data.DATA15,
-        };
-
-        final int _ID = 0;
-
-        final int ACCOUNT_TYPE = 1;
-        final int DATA_SET = 2;
-        final int STARRED = 3;
-        final int DISPLAY_NAME = 4;
-
-        final int STATUS = 5;
-        final int STATUS_RES_PACKAGE = 6;
-        final int STATUS_ICON = 7;
-        final int STATUS_LABEL = 8;
-        final int STATUS_TIMESTAMP = 9;
-        final int PRESENCE = 10;
-        final int CHAT_CAPABILITY = 11;
-
-        final int RES_PACKAGE = 12;
-        final int MIMETYPE = 13;
-        final int IS_PRIMARY = 14;
-        final int IS_SUPER_PRIMARY = 15;
-    }
 }
diff --git a/src/com/android/contacts/quickcontact/QuickContactBroadcastReceiver.java b/src/com/android/contacts/quickcontact/QuickContactBroadcastReceiver.java
new file mode 100644
index 0000000..e0850d7
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/QuickContactBroadcastReceiver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.ContactsContract.QuickContact;
+
+/**
+ * Broadcast receiver for invoking QuickContact using the widget. The purpose of this pass-through
+ * intent receiver is to disable the animation that RemoveViews typically do, which interfere
+ * with our own animation
+ */
+public class QuickContactBroadcastReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final Uri dataUri = intent.getData();
+        final Intent newIntent = new Intent(QuickContact.ACTION_QUICK_CONTACT);
+        newIntent.setSourceBounds(intent.getSourceBounds());
+        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        newIntent.setData(dataUri);
+        context.startActivity(newIntent);
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/QuickContactListFragment.java b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
index c6187e9..117480a 100644
--- a/src/com/android/contacts/quickcontact/QuickContactListFragment.java
+++ b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
@@ -16,14 +16,14 @@
 
 package com.android.contacts.quickcontact;
 
+import com.android.contacts.ContactPresenceIconUtil;
 import com.android.contacts.R;
 
 import android.app.Fragment;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -31,7 +31,7 @@
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
 import android.widget.ListView;
 import android.widget.TextView;
 
@@ -41,7 +41,7 @@
 public class QuickContactListFragment extends Fragment {
     private ListView mListView;
     private List<Action> mActions;
-    private LinearLayout mFragmentContainer;
+    private RelativeLayout mFragmentContainer;
     private Listener mListener;
 
     public QuickContactListFragment() {
@@ -50,7 +50,7 @@
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        mFragmentContainer = (LinearLayout) inflater.inflate(R.layout.quickcontact_list_fragment,
+        mFragmentContainer = (RelativeLayout) inflater.inflate(R.layout.quickcontact_list_fragment,
                 container, false);
         mListView = (ListView) mFragmentContainer.findViewById(R.id.list);
         mListView.setItemsCanFocus(true);
@@ -111,6 +111,8 @@
                 final ImageView alternateActionButton = (ImageView) resultView.findViewById(
                         R.id.secondary_action_button);
                 final View alternateActionDivider = resultView.findViewById(R.id.vertical_divider);
+                final ImageView presenceIconView =
+                        (ImageView) resultView.findViewById(R.id.presence_icon);
 
                 actionsContainer.setOnClickListener(mPrimaryActionClickListener);
                 actionsContainer.setTag(action);
@@ -143,6 +145,14 @@
                         text2.setVisibility(View.VISIBLE);
                     }
                 }
+                final Drawable presenceIcon = ContactPresenceIconUtil.getPresenceIcon(
+                        getActivity(), action.getPresence());
+                if (presenceIcon != null) {
+                    presenceIconView.setImageDrawable(presenceIcon);
+                    presenceIconView.setVisibility(View.VISIBLE);
+                } else {
+                    presenceIconView.setVisibility(View.GONE);
+                }
                 return resultView;
             }
         });
diff --git a/src/com/android/contacts/quickcontact/ResolveCache.java b/src/com/android/contacts/quickcontact/ResolveCache.java
index aae2ee7..026e0f4 100644
--- a/src/com/android/contacts/quickcontact/ResolveCache.java
+++ b/src/com/android/contacts/quickcontact/ResolveCache.java
@@ -46,13 +46,18 @@
      * multiple {@link ResolveInfo} are found to match. This only happens when
      * the user has not selected a default app yet, and they will still be
      * presented with the system disambiguation dialog.
+     * If several of this list match (e.g. Android Browser vs. Chrome), we will pick either one
      */
     private static final HashSet<String> sPreferResolve = Sets.newHashSet(
             "com.android.email",
-            "com.android.calendar",
-            "com.android.contacts",
-            "com.android.mms",
+            "com.google.android.email",
+
             "com.android.phone",
+
+            "com.google.android.apps.maps",
+
+            "com.android.chrome",
+            "com.google.android.browser",
             "com.android.browser");
 
     private final Context mContext;
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetConfigureActivity.java b/src/com/android/contacts/socialwidget/SocialWidgetConfigureActivity.java
index 98812d9..39307bf 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetConfigureActivity.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetConfigureActivity.java
@@ -23,12 +23,19 @@
 import android.provider.ContactsContract.Contacts;
 
 public class SocialWidgetConfigureActivity extends Activity {
+    private static final String KEY_LAUNCHED = "already_launched_picker_activity";
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         // If the user presses back, we want to cancel
         setResult(RESULT_CANCELED);
 
+        // Don't launch contact-picker if we already launched it (for example, if
+        // we launched it in a previous onCreate() and the device orientation changes
+        // before the picker returns its result, then this activity will be recreated).
+        if (savedInstanceState != null && savedInstanceState.getBoolean(KEY_LAUNCHED)) return;
+
         // Forward the Intent to the picker
         final Intent pickerIntent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
         pickerIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -36,6 +43,14 @@
     }
 
     @Override
+    protected void onSaveInstanceState(Bundle savedInstanceState) {
+        super.onSaveInstanceState(savedInstanceState);
+
+        // We know for sure that we've launched the contact-picker... see onCreate()
+        savedInstanceState.putBoolean(KEY_LAUNCHED, true);
+    }
+
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         // We came back from the Picker. If the user actually selected a contact,
         // return it now
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index 593c4b2..3283efd 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -18,8 +18,10 @@
 
 import com.android.contacts.ContactLoader;
 import com.android.contacts.R;
+import com.android.contacts.list.ShortcutIntentBuilder;
 import com.android.contacts.model.AccountType;
 import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.quickcontact.QuickContactBroadcastReceiver;
 import com.android.contacts.util.ContactBadgeUtil;
 import com.android.contacts.util.HtmlUtils;
 import com.android.contacts.util.StreamItemEntry;
@@ -27,6 +29,7 @@
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
+import android.content.ComponentName;
 import android.content.ContentUris;
 import android.content.Context;
 import android.content.Intent;
@@ -76,7 +79,7 @@
             ContactLoader loader = sLoaders.get(appWidgetId);
             if (loader != null) {
                 Log.d(TAG, "Stopping loader for widget with id=" + appWidgetId);
-                loader.stopLoading();
+                loader.reset();
                 sLoaders.delete(appWidgetId);
             }
         }
@@ -113,7 +116,7 @@
             return;
         }
         final ContactLoader contactLoader = new ContactLoader(context, contactUri, false, true,
-                false);
+                false, true);
         contactLoader.registerListener(0,
                 new ContactLoader.OnLoadCompleteListener<ContactLoader.Result>() {
                     @Override
@@ -145,17 +148,10 @@
 
             // TODO: Rotate between all the stream items?
 
-            // OnClick launch QuickContact
-            final Intent intent = new Intent(QuickContact.ACTION_QUICK_CONTACT);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_CLEAR_TOP
-                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
+            final Intent intent = new Intent(context, QuickContactBroadcastReceiver.class);
             intent.setData(contactData.getLookupUri());
-            intent.putExtra(QuickContact.EXTRA_MODE, QuickContact.MODE_SMALL);
-
-            final PendingIntent pendingIntent = PendingIntent.getActivity(context,
-                    0, intent, 0);
+            final PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
             views.setOnClickPendingIntent(R.id.border, pendingIntent);
 
             setDisplayNameAndSnippet(context, views, contactData.getDisplayName(),
@@ -228,7 +224,7 @@
                 final Uri uri = ContentUris.withAppendedId(StreamItems.CONTENT_URI,
                         streamItem.getId());
                 final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-                intent.setClassName(accountType.resPackageName,
+                intent.setClassName(accountType.syncAdapterPackageName,
                         accountType.getViewStreamItemActivity());
                 views.setOnClickPendingIntent(R.id.name_and_snippet_container,
                         PendingIntent.getActivity(context, 0, intent, 0));
diff --git a/src/com/android/contacts/test/NeededForReflection.java b/src/com/android/contacts/test/NeededForReflection.java
new file mode 100644
index 0000000..feacca5
--- /dev/null
+++ b/src/com/android/contacts/test/NeededForReflection.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 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.contacts.test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that the class, constructor, method or field is used by tests and therefore cannot be
+ * removed by tools like ProGuard.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD})
+public @interface NeededForReflection{}
diff --git a/src/com/android/contacts/util/AccountFilterUtil.java b/src/com/android/contacts/util/AccountFilterUtil.java
index 955c195..3f055d0 100644
--- a/src/com/android/contacts/util/AccountFilterUtil.java
+++ b/src/com/android/contacts/util/AccountFilterUtil.java
@@ -44,9 +44,8 @@
      * showing or hiding this entire view.
      */
     public static boolean updateAccountFilterTitleForPeople(View filterContainer,
-            ContactListFilter filter, boolean isLoading, boolean showTitleForAllAccounts) {
-        return updateAccountFilterTitle(
-                filterContainer, filter, isLoading, showTitleForAllAccounts, false);
+            ContactListFilter filter, boolean showTitleForAllAccounts) {
+        return updateAccountFilterTitle(filterContainer, filter, showTitleForAllAccounts, false);
     }
 
     /**
@@ -54,22 +53,20 @@
      * boolean)}, but for Phone UI.
      */
     public static boolean updateAccountFilterTitleForPhone(View filterContainer,
-            ContactListFilter filter, boolean isLoading, boolean showTitleForAllAccounts) {
+            ContactListFilter filter, boolean showTitleForAllAccounts) {
         return updateAccountFilterTitle(
-                filterContainer, filter, isLoading, showTitleForAllAccounts, true);
+                filterContainer, filter, showTitleForAllAccounts, true);
     }
 
     private static boolean updateAccountFilterTitle(View filterContainer,
-            ContactListFilter filter, boolean isLoading, boolean showTitleForAllAccounts,
+            ContactListFilter filter, boolean showTitleForAllAccounts,
             boolean forPhone) {
         final Context context = filterContainer.getContext();
         final TextView headerTextView = (TextView)
                 filterContainer.findViewById(R.id.account_filter_header);
 
         boolean textWasSet = false;
-        if (isLoading) {
-            headerTextView.setText(R.string.contact_list_loading);
-        } else if (filter != null) {
+        if (filter != null) {
             if (forPhone) {
                 if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
                     if (showTitleForAllAccounts) {
@@ -118,22 +115,26 @@
      *
      * @param activity
      * @param requestCode requestCode for {@link Activity#startActivityForResult(Intent, int)}
+     * @param currentFilter currently-selected filter, so that it can be displayed as activated.
      */
     public static void startAccountFilterActivityForResult(
-            Activity activity, int requestCode) {
+            Activity activity, int requestCode, ContactListFilter currentFilter) {
         final Intent intent = new Intent(activity, AccountFilterActivity.class);
+        intent.putExtra(AccountFilterActivity.KEY_EXTRA_CURRENT_FILTER, currentFilter);
         activity.startActivityForResult(intent, requestCode);
     }
 
     /**
-     * Very similar to {@link #startAccountFilterActivityForResult(Activity, int)} but uses
-     * Fragment instead.
+     * Very similar to
+     * {@link #startAccountFilterActivityForResult(Activity, int, ContactListFilter)}
+     * but uses Fragment instead.
      */
     public static void startAccountFilterActivityForResult(
-            Fragment fragment, int requestCode) {
+            Fragment fragment, int requestCode, ContactListFilter currentFilter) {
         final Activity activity = fragment.getActivity();
         if (activity != null) {
             final Intent intent = new Intent(activity, AccountFilterActivity.class);
+            intent.putExtra(AccountFilterActivity.KEY_EXTRA_CURRENT_FILTER, currentFilter);
             fragment.startActivityForResult(intent, requestCode);
         } else {
             Log.w(TAG, "getActivity() returned null. Ignored");
diff --git a/src/com/android/contacts/util/BitmapUtil.java b/src/com/android/contacts/util/BitmapUtil.java
new file mode 100644
index 0000000..6f6650f
--- /dev/null
+++ b/src/com/android/contacts/util/BitmapUtil.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+/**
+ * Provides static functions to decode bitmaps at the optimal size
+ */
+public class BitmapUtil {
+    private BitmapUtil() {}
+
+    /**
+     * Returns Width or Height of the picture, depending on which size is smaller. Doesn't actually
+     * decode the picture, so it is pretty efficient to run.
+     */
+    public static int getSmallerExtentFromBytes(byte[] bytes) {
+        final BitmapFactory.Options options = new BitmapFactory.Options();
+
+        // don't actually decode the picture, just return its bounds
+        options.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
+
+        // test what the best sample size is
+        return Math.min(options.outWidth, options.outHeight);
+    }
+
+    /**
+     * Finds the optimal sampleSize for loading the picture
+     * @param originalSmallerExtent Width or height of the picture, whichever is smaller
+     * @param targetExtent Width or height of the target view, whichever is bigger.
+     *
+     * If either one of the parameters is 0 or smaller, no sampling is applied
+     */
+    public static int findOptimalSampleSize(int originalSmallerExtent, int targetExtent) {
+        // If we don't know sizes, we can't do sampling.
+        if (targetExtent < 1) return 1;
+        if (originalSmallerExtent < 1) return 1;
+
+        // test what the best sample size is
+        int extent = originalSmallerExtent;
+        int sampleSize = 1;
+        while ((extent >> 1) >= targetExtent) {
+            sampleSize <<= 1;
+            extent >>= 1;
+        }
+
+        return sampleSize;
+    }
+
+    /**
+     * Decodes the bitmap with the given sample size
+     */
+    public static Bitmap decodeBitmapFromBytes(byte[] bytes, int sampleSize) {
+        final BitmapFactory.Options options;
+        if (sampleSize <= 1) {
+            options = null;
+        } else {
+            options = new BitmapFactory.Options();
+            options.inSampleSize = sampleSize;
+        }
+        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
+    }
+}
diff --git a/src/com/android/contacts/util/CallerInfoCacheUtils.java b/src/com/android/contacts/util/CallerInfoCacheUtils.java
new file mode 100644
index 0000000..9e53159
--- /dev/null
+++ b/src/com/android/contacts/util/CallerInfoCacheUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Utilities for managing CallerInfoCache.
+ *
+ * The cache lives in Phone package and is used as fallback storage when database lookup is slower
+ * than expected. It remembers some information necessary for responding to incoming calls
+ * (e.g. custom ringtone settings, send-to-voicemail).
+ *
+ * Even though the cache will be updated periodically, Contacts app can request the cache update
+ * via broadcast Intent. This class provides that mechanism, and possibly other misc utilities
+ * for the update mechanism.
+ */
+public final class CallerInfoCacheUtils {
+    private static final String UPDATE_CALLER_INFO_CACHE =
+            "com.android.phone.UPDATE_CALLER_INFO_CACHE";
+
+    private CallerInfoCacheUtils() {
+    }
+
+    /**
+     * Sends an Intent, notifying CallerInfo cache should be updated.
+     *
+     * Note: CallerInfo is *not* part of public API, and no guarantee is available around its
+     * specific behavior. In practice this will only be used by Phone package, but may change
+     * in the future.
+     *
+     * See also CallerInfoCache in Phone package for more information.
+     */
+    public static void sendUpdateCallerInfoCacheIntent(Context context) {
+        context.sendBroadcast(new Intent(UPDATE_CALLER_INFO_CACHE));
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/contacts/util/ClipboardUtils.java b/src/com/android/contacts/util/ClipboardUtils.java
new file mode 100644
index 0000000..a160668
--- /dev/null
+++ b/src/com/android/contacts/util/ClipboardUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import com.android.contacts.R;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.text.TextUtils;
+import android.widget.Toast;
+
+public class ClipboardUtils {
+    private static final String TAG = "ClipboardUtils";
+
+    private ClipboardUtils() { }
+
+    /**
+     * Copy a text to clipboard.
+     *
+     * @param context Context
+     * @param label Label to show to the user describing this clip.
+     * @param text Text to copy.
+     * @param showToast If {@code true}, a toast is shown to the user.
+     */
+    public static void copyText(Context context, CharSequence label, CharSequence text,
+            boolean showToast) {
+        if (TextUtils.isEmpty(text)) return;
+
+        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(
+                Context.CLIPBOARD_SERVICE);
+        ClipData clipData = ClipData.newPlainText(label == null ? "" : label, text);
+        clipboardManager.setPrimaryClip(clipData);
+
+        if (showToast) {
+            String toastText = context.getString(R.string.toast_text_copied);
+            Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show();
+        }
+    }
+}
diff --git a/src/com/android/contacts/util/ContactPhotoUtils.java b/src/com/android/contacts/util/ContactPhotoUtils.java
new file mode 100644
index 0000000..2bd8e80
--- /dev/null
+++ b/src/com/android/contacts/util/ContactPhotoUtils.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Utilities related to loading/saving contact photos.
+ *
+ */
+public class ContactPhotoUtils {
+    private static final String TAG = "ContactPhotoUtils";
+
+    private static final String PHOTO_DATE_FORMAT = "'IMG'_yyyyMMdd_HHmmss";
+    private static final String NEW_PHOTO_DIR_PATH =
+            Environment.getExternalStorageDirectory() + "/DCIM/Camera";
+
+
+    /**
+     * Generate a new, unique file to be used as an out-of-band communication
+     * channel, since hi-res Bitmaps are too big to serialize into a Bundle.
+     * This file will be passed to other activities (such as the gallery/camera/cropper/etc.),
+     * and read by us once they are finished writing it.
+     */
+    public static File generateTempPhotoFile(Context context) {
+        return new File(pathForCroppedPhoto(context, generateTempPhotoFileName()));
+    }
+
+    public static String pathForCroppedPhoto(Context context, String fileName) {
+        final File dir = new File(context.getExternalCacheDir() + "/tmp");
+        dir.mkdirs();
+        final File f = new File(dir, fileName);
+        return f.getAbsolutePath();
+    }
+
+    public static String pathForNewCameraPhoto(String fileName) {
+        final File dir = new File(NEW_PHOTO_DIR_PATH);
+        dir.mkdirs();
+        final File f = new File(dir, fileName);
+        return f.getAbsolutePath();
+    }
+
+    public static String generateTempPhotoFileName() {
+        Date date = new Date(System.currentTimeMillis());
+        SimpleDateFormat dateFormat = new SimpleDateFormat(PHOTO_DATE_FORMAT);
+        return "ContactPhoto-" + dateFormat.format(date) + ".jpg";
+    }
+
+    /**
+     * Creates a byte[] containing the PNG-compressed bitmap, or null if
+     * something goes wrong.
+     */
+    public static byte[] compressBitmap(Bitmap bitmap) {
+        final int size = bitmap.getWidth() * bitmap.getHeight() * 4;
+        final ByteArrayOutputStream out = new ByteArrayOutputStream(size);
+        try {
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+            out.flush();
+            out.close();
+            return out.toByteArray();
+        } catch (IOException e) {
+            Log.w(TAG, "Unable to serialize photo: " + e.toString());
+            return null;
+        }
+    }
+}
+
+
diff --git a/src/com/android/contacts/util/DateUtils.java b/src/com/android/contacts/util/DateUtils.java
index 1ea84a1..d0bb68f 100644
--- a/src/com/android/contacts/util/DateUtils.java
+++ b/src/com/android/contacts/util/DateUtils.java
@@ -56,7 +56,7 @@
     private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_MONTH_FIRST =
             new SimpleDateFormat("MMMM dd");
 
-    private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_DATE_FIRST =
+    private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_DAY_FIRST =
             new SimpleDateFormat("dd MMMM");
 
     static {
@@ -66,7 +66,7 @@
         }
         NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE);
         FORMAT_WITHOUT_YEAR_MONTH_FIRST.setTimeZone(UTC_TIMEZONE);
-        FORMAT_WITHOUT_YEAR_DATE_FIRST.setTimeZone(UTC_TIMEZONE);
+        FORMAT_WITHOUT_YEAR_DAY_FIRST.setTimeZone(UTC_TIMEZONE);
     }
 
     /**
@@ -112,9 +112,9 @@
         }
 
         if (parsePosition.getIndex() == string.length()) {
-            java.text.DateFormat outFormat = isMonthBeforeDate(context)
+            java.text.DateFormat outFormat = isMonthBeforeDay(context)
                     ? FORMAT_WITHOUT_YEAR_MONTH_FIRST
-                    : FORMAT_WITHOUT_YEAR_DATE_FIRST;
+                    : FORMAT_WITHOUT_YEAR_DAY_FIRST;
             synchronized (outFormat) {
                 return outFormat.format(date);
             }
@@ -135,7 +135,7 @@
         return string;
     }
 
-    private static boolean isMonthBeforeDate(Context context) {
+    public static boolean isMonthBeforeDay(Context context) {
         char[] dateFormatOrder = DateFormat.getDateFormatOrder(context);
         for (int i = 0; i < dateFormatOrder.length; i++) {
             if (dateFormatOrder[i] == DateFormat.DATE) {
diff --git a/src/com/android/contacts/util/HelpUtils.java b/src/com/android/contacts/util/HelpUtils.java
new file mode 100644
index 0000000..814e3ab
--- /dev/null
+++ b/src/com/android/contacts/util/HelpUtils.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.MenuItem;
+
+import java.util.Locale;
+
+/**
+ * Functions to easily prepare contextual help menu option items with an intent that opens up the
+ * browser to a particular URL, while taking into account the preferred language and app version.
+ */
+public class HelpUtils {
+    private final static String TAG = HelpUtils.class.getName();
+
+    /**
+     * Help URL query parameter key for the preferred language.
+     */
+    private final static String PARAM_LANGUAGE_CODE = "hl";
+
+    /**
+     * Help URL query parameter key for the app version.
+     */
+    private final static String PARAM_VERSION = "version";
+
+    /**
+     * Cached version code to prevent repeated calls to the package manager.
+     */
+    private static String sCachedVersionCode = null;
+
+    /** Static helper that is not instantiable*/
+    private HelpUtils() { }
+
+    /**
+     * Prepares the help menu item by doing the following.
+     * - If the string corresponding to the helpUrlResourceId is empty or null, then the help menu
+     *   item is made invisible.
+     * - Otherwise, this makes the help menu item visible and sets the intent for the help menu
+     *   item to view the URL.
+     *
+     * @return returns whether the help menu item has been made visible.
+     */
+    public static boolean prepareHelpMenuItem(Context context, MenuItem helpMenuItem,
+            int helpUrlResourceId) {
+        String helpUrlString = context.getResources().getString(helpUrlResourceId);
+        return prepareHelpMenuItem(context, helpMenuItem, helpUrlString);
+    }
+
+    /**
+     * Prepares the help menu item by doing the following.
+     * - If the helpUrlString is empty or null, the help menu item is made invisible.
+     * - Otherwise, this makes the help menu item visible and sets the intent for the help menu
+     *   item to view the URL.
+     *
+     * @return returns whether the help menu item has been made visible.
+     */
+    public static boolean prepareHelpMenuItem(Context context, MenuItem helpMenuItem,
+            String helpUrlString) {
+        if (TextUtils.isEmpty(helpUrlString)) {
+            // The help url string is empty or null, so set the help menu item to be invisible.
+            helpMenuItem.setVisible(false);
+
+            // return that the help menu item is not visible (i.e. false)
+            return false;
+        } else {
+            // The help url string exists, so first add in some extra query parameters.
+            final Uri fullUri = uriWithAddedParameters(context, Uri.parse(helpUrlString));
+
+            // Then, create an intent that will be fired when the user
+            // selects this help menu item.
+            Intent intent = new Intent(Intent.ACTION_VIEW, fullUri);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+
+            // Set the intent to the help menu item, show the help menu item in the overflow
+            // menu, and make it visible.
+            helpMenuItem.setIntent(intent);
+            helpMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+            helpMenuItem.setVisible(true);
+
+            // return that the help menu item is visible (i.e., true)
+            return true;
+        }
+    }
+
+    /**
+     * Adds two query parameters into the Uri, namely the language code and the version code
+     * of the app's package as gotten via the context.
+     * @return the uri with added query parameters
+     */
+    private static Uri uriWithAddedParameters(Context context, Uri baseUri) {
+        Uri.Builder builder = baseUri.buildUpon();
+
+        // Add in the preferred language
+        builder.appendQueryParameter(PARAM_LANGUAGE_CODE, Locale.getDefault().toString());
+
+        // Add in the package version code
+        if (sCachedVersionCode == null) {
+            // There is no cached version code, so try to get it from the package manager.
+            try {
+                // cache the version code
+                PackageInfo info = context.getPackageManager().getPackageInfo(
+                        context.getPackageName(), 0);
+                sCachedVersionCode = Integer.toString(info.versionCode);
+
+                // append the version code to the uri
+                builder.appendQueryParameter(PARAM_VERSION, sCachedVersionCode);
+            } catch (NameNotFoundException e) {
+                // Cannot find the package name, so don't add in the version parameter
+                // This shouldn't happen.
+                Log.wtf(TAG, "Invalid package name for context", e);
+            }
+        } else {
+            builder.appendQueryParameter(PARAM_VERSION, sCachedVersionCode);
+        }
+
+        // Build the full uri and return it
+        return builder.build();
+    }
+}
diff --git a/src/com/android/contacts/util/ImageViewDrawableSetter.java b/src/com/android/contacts/util/ImageViewDrawableSetter.java
new file mode 100644
index 0000000..1d23dd0
--- /dev/null
+++ b/src/com/android/contacts/util/ImageViewDrawableSetter.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import com.android.contacts.ContactLoader.Result;
+import com.android.contacts.ContactPhotoManager;
+
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.util.Arrays;
+
+/**
+ * Initialized with a target ImageView. When provided with a compressed image
+ * (i.e. a byte[]), it appropriately updates the ImageView's Drawable.
+ */
+public class ImageViewDrawableSetter {
+    private ImageView mTarget;
+    private byte[] mCompressed;
+    private Drawable mPreviousDrawable;
+    private int mDurationInMillis = 0;
+    private static final String TAG = "ImageViewDrawableSetter";
+
+    public ImageViewDrawableSetter() {
+    }
+
+    public ImageViewDrawableSetter(ImageView target) {
+        mTarget = target;
+    }
+
+    public void setupContactPhoto(Result contactData, ImageView photoView) {
+        setTarget(photoView);
+        setCompressedImage(contactData.getPhotoBinaryData());
+    }
+
+    public void setTransitionDuration(int durationInMillis) {
+        mDurationInMillis = durationInMillis;
+    }
+
+    public ImageView getTarget() {
+        return mTarget;
+    }
+
+    /**
+     * Re-initialize to use new target. As a result, the next time a new image
+     * is set, it will immediately be applied to the target (there will be no
+     * fade transition).
+     */
+    protected void setTarget(ImageView target) {
+        if (mTarget != target) {
+            mTarget = target;
+            mCompressed = null;
+            mPreviousDrawable = null;
+        }
+    }
+
+    protected byte[] getCompressedImage() {
+        return mCompressed;
+    }
+
+    protected Bitmap setCompressedImage(byte[] compressed) {
+        if (mPreviousDrawable == null) {
+            // If we don't already have a drawable, skip the exit-early test
+            // below; otherwise we might not end up setting the default image.
+        } else if (mPreviousDrawable != null && Arrays.equals(mCompressed, compressed)) {
+            // TODO: the worst case is when the arrays are equal but not
+            // identical. This takes about 1ms (more with high-res photos). A
+            // possible optimization is to sparsely sample chunks of the arrays
+            // to compare.
+            return previousBitmap();
+        }
+
+        final Drawable newDrawable = (compressed == null)
+                ? defaultDrawable()
+                : decodedBitmapDrawable(compressed);
+
+        // Remember this for next time, so that we can check if it changed.
+        mCompressed = compressed;
+
+        // If we don't have a new Drawable, something went wrong... bail out.
+        if (newDrawable == null) return previousBitmap();
+
+        if (mPreviousDrawable == null || mDurationInMillis == 0) {
+            // Set the new one immediately.
+            mTarget.setImageDrawable(newDrawable);
+        } else {
+            // Set up a transition from the previous Drawable to the new one.
+            final Drawable[] beforeAndAfter = new Drawable[2];
+            beforeAndAfter[0] = mPreviousDrawable;
+            beforeAndAfter[1] = newDrawable;
+            final TransitionDrawable transition = new TransitionDrawable(beforeAndAfter);
+            mTarget.setImageDrawable(transition);
+            transition.startTransition(mDurationInMillis);
+        }
+
+        // Remember this for next time, so that we can transition from it to the
+        // new one.
+        mPreviousDrawable = newDrawable;
+
+        return previousBitmap();
+    }
+
+    private Bitmap previousBitmap() {
+        return (mPreviousDrawable == null)
+                ? null
+                : ((BitmapDrawable) mPreviousDrawable).getBitmap();
+    }
+
+    /**
+     * Obtain the default drawable for a contact when no photo is available.
+     */
+    private Drawable defaultDrawable() {
+        Resources resources = mTarget.getResources();
+        final int resId = ContactPhotoManager.getDefaultAvatarResId(true, false);
+        try {
+            return resources.getDrawable(resId);
+        } catch (NotFoundException e) {
+            Log.wtf(TAG, "Cannot load default avatar resource.");
+            return null;
+        }
+    }
+
+    private BitmapDrawable decodedBitmapDrawable(byte[] compressed) {
+        Resources rsrc = mTarget.getResources();
+        Bitmap bitmap = BitmapFactory.decodeByteArray(compressed, 0, compressed.length);
+        return new BitmapDrawable(rsrc, bitmap);
+    }
+
+}
diff --git a/src/com/android/contacts/util/MoreMath.java b/src/com/android/contacts/util/MoreMath.java
new file mode 100644
index 0000000..db76fe4
--- /dev/null
+++ b/src/com/android/contacts/util/MoreMath.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+/**
+ * Useful math functions that aren't in java.lang.Math
+ */
+public class MoreMath {
+    /**
+     * If the input value lies outside of the specified range, return the nearer
+     * bound. Otherwise, return the input value, unchanged.
+     */
+    public static int clamp(int input, int lowerBound, int upperBound) {
+        if (input < lowerBound) return lowerBound;
+        if (input > upperBound) return upperBound;
+        return input;
+    }
+
+    /**
+     * If the input value lies outside of the specified range, return the nearer
+     * bound. Otherwise, return the input value, unchanged.
+     */
+    public static float clamp(float input, float lowerBound, float upperBound) {
+        if (input < lowerBound) return lowerBound;
+        if (input > upperBound) return upperBound;
+        return input;
+    }
+
+    /**
+     * If the input value lies outside of the specified range, return the nearer
+     * bound. Otherwise, return the input value, unchanged.
+     */
+    public static double clamp(double input, double lowerBound, double upperBound) {
+        if (input < lowerBound) return lowerBound;
+        if (input > upperBound) return upperBound;
+        return input;
+    }
+}
diff --git a/src/com/android/contacts/util/PhoneCapabilityTester.java b/src/com/android/contacts/util/PhoneCapabilityTester.java
index d3a8060..ce248bb 100644
--- a/src/com/android/contacts/util/PhoneCapabilityTester.java
+++ b/src/com/android/contacts/util/PhoneCapabilityTester.java
@@ -89,4 +89,11 @@
     public static boolean isUsingTwoPanes(Context context) {
         return context.getResources().getBoolean(R.bool.config_use_two_panes);
     }
+
+    /**
+     * True if the favorites tab should be shown in two-pane mode.  False, otherwise.
+     */
+    public static boolean isUsingTwoPanesInFavorites(Context context) {
+        return context.getResources().getBoolean(R.bool.config_use_two_panes_in_favorites);
+    }
 }
diff --git a/src/com/android/contacts/util/SchedulingUtils.java b/src/com/android/contacts/util/SchedulingUtils.java
new file mode 100644
index 0000000..c55bc16
--- /dev/null
+++ b/src/com/android/contacts/util/SchedulingUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.view.View;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.ViewTreeObserver.OnDrawListener;
+
+/** Static methods that are useful for scheduling actions to occur at a later time. */
+public class SchedulingUtils {
+
+
+    /** Runs a piece of code after the next layout run */
+    public static void doAfterLayout(final View view, final Runnable runnable) {
+        final OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                // Layout pass done, unregister for further events
+                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                runnable.run();
+            }
+        };
+        view.getViewTreeObserver().addOnGlobalLayoutListener(listener);
+    }
+
+    /** Runs a piece of code just before the next draw. */
+    public static void doAfterDraw(final View view, final Runnable runnable) {
+        final OnDrawListener listener = new OnDrawListener() {
+            @Override
+            public void onDraw() {
+                view.getViewTreeObserver().removeOnDrawListener(this);
+                runnable.run();
+            }
+        };
+        view.getViewTreeObserver().addOnDrawListener(listener);
+    }
+}
diff --git a/src/com/android/contacts/util/StopWatch.java b/src/com/android/contacts/util/StopWatch.java
new file mode 100644
index 0000000..1accfe2
--- /dev/null
+++ b/src/com/android/contacts/util/StopWatch.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import com.google.android.collect.Lists;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * A {@link StopWatch} records start, laps and stop, and print them to logcat.
+ */
+public class StopWatch {
+
+    private final String mLabel;
+
+    private final ArrayList<Long> mTimes = Lists.newArrayList();
+    private final ArrayList<String> mLapLabels = Lists.newArrayList();
+
+    private StopWatch(String label) {
+        mLabel = label;
+        lap("");
+    }
+
+    /**
+     * Create a new instance and start it.
+     */
+    public static StopWatch start(String label) {
+        return new StopWatch(label);
+    }
+
+    /**
+     * Record a lap.
+     */
+    public void lap(String lapLabel) {
+        mTimes.add(System.currentTimeMillis());
+        mLapLabels.add(lapLabel);
+    }
+
+    /**
+     * Stop it and log the result, if the total time >= {@code timeThresholdToLog}.
+     */
+    public void stopAndLog(String TAG, int timeThresholdToLog) {
+
+        lap("");
+
+        final long start = mTimes.get(0);
+        final long stop = mTimes.get(mTimes.size() - 1);
+
+        final long total = stop - start;
+        if (total < timeThresholdToLog) return;
+
+        final StringBuilder sb = new StringBuilder();
+        sb.append(mLabel);
+        sb.append(",");
+        sb.append(total);
+        sb.append(": ");
+
+        long last = start;
+        for (int i = 1; i < mTimes.size(); i++) {
+            final long current = mTimes.get(i);
+            sb.append(mLapLabels.get(i));
+            sb.append(",");
+            sb.append((current - last));
+            sb.append(" ");
+            last = current;
+        }
+        Log.v(TAG, sb.toString());
+    }
+
+    /**
+     * Return a dummy instance that does no operations.
+     */
+    public static StopWatch getNullStopWatch() {
+        return NullStopWatch.INSTANCE;
+    }
+
+    private static class NullStopWatch extends StopWatch {
+        public static final NullStopWatch INSTANCE = new NullStopWatch();
+
+        public NullStopWatch() {
+            super(null);
+        }
+
+        @Override
+        public void lap(String lapLabel) {
+            // noop
+        }
+
+        @Override
+        public void stopAndLog(String TAG, int timeThresholdToLog) {
+            // noop
+        }
+    }
+}
diff --git a/src/com/android/contacts/util/StreamItemEntry.java b/src/com/android/contacts/util/StreamItemEntry.java
index 5959c46..f9c8700 100644
--- a/src/com/android/contacts/util/StreamItemEntry.java
+++ b/src/com/android/contacts/util/StreamItemEntry.java
@@ -16,10 +16,13 @@
 
 package com.android.contacts.util;
 
+import com.android.contacts.detail.ContactDetailDisplayUtils;
 import com.android.contacts.test.NeededForTesting;
 
+import android.content.Context;
 import android.database.Cursor;
 import android.provider.ContactsContract.StreamItems;
+import android.text.Html;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -41,6 +44,10 @@
     private final String mAccountName;
     private final String mDataSet;
 
+    private boolean mDecoded;
+    private CharSequence mDecodedText;
+    private CharSequence mDecodedComments;
+
     // Package references for label and icon resources.
     private final String mResPackage;
     private final String mIconRes;
@@ -50,7 +57,14 @@
     private List<StreamItemPhotoEntry> mPhotos;
 
     @NeededForTesting
-    public StreamItemEntry(long id, String text, String comments, long timestamp,
+    public static StreamItemEntry createForTest(long id, String text, String comments,
+            long timestamp, String accountType, String accountName, String dataSet,
+            String resPackage, String iconRes, String labelRes) {
+        return new StreamItemEntry(id, text, comments, timestamp, accountType, accountName, dataSet,
+                resPackage, iconRes, labelRes);
+    }
+
+    private StreamItemEntry(long id, String text, String comments, long timestamp,
             String accountType, String accountName, String dataSet, String resPackage,
             String iconRes, String labelRes) {
         mId = id;
@@ -136,6 +150,39 @@
         return mPhotos;
     }
 
+    /**
+     * Make {@link #getDecodedText} and {@link #getDecodedComments} available.  Must be called
+     * before calling those.
+     *
+     * We can't do this automatically in the getters, because it'll require a {@link Context}.
+     */
+    public void decodeHtml(Context context) {
+        final Html.ImageGetter imageGetter = ContactDetailDisplayUtils.getImageGetter(context);
+        if (mText != null) {
+            mDecodedText = HtmlUtils.fromHtml(context, mText, imageGetter, null);
+        }
+        if (mComments != null) {
+            mDecodedComments = HtmlUtils.fromHtml(context, mComments, imageGetter, null);
+        }
+        mDecoded = true;
+    }
+
+    public CharSequence getDecodedText() {
+        checkDecoded();
+        return mDecodedText;
+    }
+
+    public CharSequence getDecodedComments() {
+        checkDecoded();
+        return mDecodedComments;
+    }
+
+    private void checkDecoded() {
+        if (!mDecoded) {
+            throw new IllegalStateException("decodeHtml must have been called");
+        }
+    }
+
     private static String getString(Cursor cursor, String columnName) {
         return cursor.getString(cursor.getColumnIndex(columnName));
     }
diff --git a/src/com/android/contacts/util/ViewUtil.java b/src/com/android/contacts/util/ViewUtil.java
new file mode 100644
index 0000000..89ab73d
--- /dev/null
+++ b/src/com/android/contacts/util/ViewUtil.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Provides static functions to work with views
+ */
+public class ViewUtil {
+    private ViewUtil() {}
+
+    /**
+     * Returns the width as specified in the LayoutParams
+     * @throws IllegalStateException Thrown if the view's width is unknown before a layout pass
+     * s
+     */
+    public static int getConstantPreLayoutWidth(View view) {
+        // We haven't been layed out yet, so get the size from the LayoutParams
+        final ViewGroup.LayoutParams p = view.getLayoutParams();
+        if (p.width < 0) {
+            throw new IllegalStateException("Expecting view's width to be a constant rather " +
+                    "than a result of the layout pass");
+        }
+        return p.width;
+    }
+}
diff --git a/src/com/android/contacts/vcard/CancelActivity.java b/src/com/android/contacts/vcard/CancelActivity.java
index c890607..5dafa53 100644
--- a/src/com/android/contacts/vcard/CancelActivity.java
+++ b/src/com/android/contacts/vcard/CancelActivity.java
@@ -87,17 +87,13 @@
     protected Dialog onCreateDialog(int id, Bundle bundle) {
         switch (id) {
         case R.id.dialog_cancel_confirmation: {
-            final String title;
             final String message;
             if (mType == VCardService.TYPE_IMPORT) {
-                title = getString(R.string.cancel_import_confirmation_title);
                 message = getString(R.string.cancel_import_confirmation_message, mDisplayName);
             } else {
-                title = getString(R.string.cancel_export_confirmation_title);
                 message = getString(R.string.cancel_export_confirmation_message, mDisplayName);
             }
             final AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(title)
                     .setMessage(message)
                     .setPositiveButton(android.R.string.ok, new RequestCancelListener())
                     .setOnCancelListener(mCancelListener)
diff --git a/src/com/android/contacts/vcard/ExportVCardActivity.java b/src/com/android/contacts/vcard/ExportVCardActivity.java
index c36cc38..f38c9df 100644
--- a/src/com/android/contacts/vcard/ExportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ExportVCardActivity.java
@@ -235,7 +235,6 @@
             case R.id.dialog_sdcard_not_found: {
                 mProcessOngoing = false;
                 return new AlertDialog.Builder(this)
-                        .setTitle(R.string.no_sdcard_title)
                         .setIconAttribute(android.R.attr.alertDialogIcon)
                         .setMessage(R.string.no_sdcard_message)
                         .setPositiveButton(android.R.string.ok, this).create();
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index 18b9cc1..2dc92af 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -901,10 +901,9 @@
             }
             case R.id.dialog_searching_vcard: {
                 if (mProgressDialogForScanVCard == null) {
-                    String title = getString(R.string.searching_vcard_title);
                     String message = getString(R.string.searching_vcard_message);
                     mProgressDialogForScanVCard =
-                        ProgressDialog.show(this, title, message, true, false);
+                        ProgressDialog.show(this, "", message, true, false);
                     mProgressDialogForScanVCard.setOnCancelListener(mVCardScanThread);
                     mVCardScanThread.start();
                 }
@@ -912,7 +911,6 @@
             }
             case R.id.dialog_sdcard_not_found: {
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(R.string.no_sdcard_title)
                     .setIconAttribute(android.R.attr.alertDialogIcon)
                     .setMessage(R.string.no_sdcard_message)
                     .setOnCancelListener(mCancelListener)
@@ -922,7 +920,6 @@
             case R.id.dialog_vcard_not_found: {
                 final String message = getString(R.string.import_failure_no_vcard_file);
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                        .setTitle(R.string.scanning_sdcard_failed_title)
                         .setMessage(message)
                         .setOnCancelListener(mCancelListener)
                         .setPositiveButton(android.R.string.ok, mCancelListener);
@@ -954,7 +951,6 @@
                 String message = (getString(R.string.scanning_sdcard_failed_message,
                         getString(R.string.fail_reason_io_error)));
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(R.string.scanning_sdcard_failed_title)
                     .setIconAttribute(android.R.attr.alertDialogIcon)
                     .setMessage(message)
                     .setOnCancelListener(mCancelListener)
diff --git a/src/com/android/contacts/vcard/NfcImportVCardActivity.java b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
index d182cfd..c3a55d2 100644
--- a/src/com/android/contacts/vcard/NfcImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
@@ -154,25 +154,20 @@
         if (!NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
             Log.w(TAG, "Unknowon intent " + intent);
             finish();
-        }
-
-        NdefMessage msg = (NdefMessage) intent.getParcelableArrayExtra(
-                NfcAdapter.EXTRA_NDEF_MESSAGES)[0];
-        NdefRecord records[] = msg.getRecords();
-        if (records == null || records.length == 0) {
-            Log.w(TAG, "No records " + intent);
-            finish();
-        }
-
-        NdefRecord record = records[0];
-        String type = new String(record.getType(), Charset.forName("UTF8"));
-        if (record.getTnf() != NdefRecord.TNF_MIME_MEDIA ||
-                (!"text/x-vcard".equalsIgnoreCase(type) && !"text/vcard".equals(type))) {
-            Log.w(TAG, "Not a vcard");
-            //setStatus(getString(R.string.fail_reason_not_supported));
             return;
         }
-        mRecord = record;
+
+        String type = intent.getType();
+        if (type == null ||
+                (!"text/x-vcard".equals(type) && !"text/vcard".equals(type))) {
+            Log.w(TAG, "Not a vcard");
+            //setStatus(getString(R.string.fail_reason_not_supported));
+            finish();
+            return;
+        }
+        NdefMessage msg = (NdefMessage) intent.getParcelableArrayExtra(
+                NfcAdapter.EXTRA_NDEF_MESSAGES)[0];
+        mRecord = msg.getRecords()[0];
 
         final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
         final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
diff --git a/src/com/android/contacts/vcard/VCardService.java b/src/com/android/contacts/vcard/VCardService.java
index 71b0214..34c4acb 100644
--- a/src/com/android/contacts/vcard/VCardService.java
+++ b/src/com/android/contacts/vcard/VCardService.java
@@ -15,8 +15,6 @@
  */
 package com.android.contacts.vcard;
 
-import com.android.contacts.R;
-
 import android.app.Service;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -24,17 +22,18 @@
 import android.media.MediaScannerConnection.MediaScannerConnectionClient;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.contacts.R;
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -108,8 +107,7 @@
 
     // Stores all unfinished import/export jobs which will be executed by mExecutorService.
     // Key is jobId.
-    private final Map<Integer, ProcessorBase> mRunningJobMap =
-            new HashMap<Integer, ProcessorBase>();
+    private final SparseArray<ProcessorBase> mRunningJobMap = new SparseArray<ProcessorBase>();
     // Stores ScannerConnectionClient objects until they finish scanning requested files.
     // Uses List class for simplicity. It's not costly as we won't have multiple objects in
     // almost all cases.
@@ -272,7 +270,9 @@
             VCardImportExportListener listener) {
         final int jobId = request.jobId;
         if (DEBUG) Log.d(LOG_TAG, String.format("Received cancel request. (id: %d)", jobId));
-        final ProcessorBase processor = mRunningJobMap.remove(jobId);
+
+        final ProcessorBase processor = mRunningJobMap.get(jobId);
+        mRunningJobMap.remove(jobId);
 
         if (processor != null) {
             processor.cancel(true);
@@ -321,16 +321,37 @@
      */
     private synchronized void stopServiceIfAppropriate() {
         if (mRunningJobMap.size() > 0) {
-            for (final Map.Entry<Integer, ProcessorBase> entry : mRunningJobMap.entrySet()) {
-                final int jobId = entry.getKey();
-                final ProcessorBase processor = entry.getValue();
-                if (processor.isDone()) {
-                    mRunningJobMap.remove(jobId);
-                } else {
+            final int size = mRunningJobMap.size();
+
+            // Check if there are processors which aren't finished yet. If we still have ones to
+            // process, we cannot stop the service yet. Also clean up already finished processors
+            // here.
+
+            // Job-ids to be removed. At first all elements in the array are invalid and will
+            // be filled with real job-ids from the array's top. When we find a not-yet-finished
+            // processor, then we start removing those finished jobs. In that case latter half of
+            // this array will be invalid.
+            final int[] toBeRemoved = new int[size];
+            for (int i = 0; i < size; i++) {
+                final int jobId = mRunningJobMap.keyAt(i);
+                final ProcessorBase processor = mRunningJobMap.valueAt(i);
+                if (!processor.isDone()) {
                     Log.i(LOG_TAG, String.format("Found unfinished job (id: %d)", jobId));
+
+                    // Remove processors which are already "done", all of which should be before
+                    // processors which aren't done yet.
+                    for (int j = 0; j < i; j++) {
+                        mRunningJobMap.remove(toBeRemoved[j]);
+                    }
                     return;
                 }
+
+                // Remember the finished processor.
+                toBeRemoved[i] = jobId;
             }
+
+            // We're sure we can remove all. Instead of removing one by one, just call clear().
+            mRunningJobMap.clear();
         }
 
         if (!mRemainingScannerConnections.isEmpty()) {
@@ -374,9 +395,7 @@
             Log.d(LOG_TAG, String.format("Received vCard import finish notification (id: %d). "
                     + "Result: %b", jobId, (successful ? "success" : "failure")));
         }
-        if (mRunningJobMap.remove(jobId) == null) {
-            Log.w(LOG_TAG, String.format("Tried to remove unknown job (id: %d)", jobId));
-        }
+        mRunningJobMap.remove(jobId);
         stopServiceIfAppropriate();
     }
 
@@ -386,7 +405,8 @@
             Log.d(LOG_TAG, String.format("Received vCard export finish notification (id: %d). "
                     + "Result: %b", jobId, (successful ? "success" : "failure")));
         }
-        final ProcessorBase job = mRunningJobMap.remove(jobId);
+        final ProcessorBase job = mRunningJobMap.get(jobId);
+        mRunningJobMap.remove(jobId);
         if (job == null) {
             Log.w(LOG_TAG, String.format("Tried to remove unknown job (id: %d)", jobId));
         } else if (!(job instanceof ExportProcessor)) {
@@ -408,8 +428,8 @@
      * Mainly called from onDestroy().
      */
     private synchronized void cancelAllRequestsAndShutdown() {
-        for (final Map.Entry<Integer, ProcessorBase> entry : mRunningJobMap.entrySet()) {
-            entry.getValue().cancel(true);
+        for (int i = 0; i < mRunningJobMap.size(); i++) {
+            mRunningJobMap.valueAt(i).cancel(true);
         }
         mRunningJobMap.clear();
         mExecutorService.shutdown();
diff --git a/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java b/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java
new file mode 100644
index 0000000..a7d219c
--- /dev/null
+++ b/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 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.contacts.widget;
+
+import com.android.contacts.detail.ContactDetailDisplayUtils;
+import com.android.contacts.util.ThemeUtils;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.FrameLayout;
+
+/**
+ * A View that other Views can use to create a touch-interceptor layer above
+ * their other sub-views. This layer can be enabled and disabled; when enabled,
+ * clicks are intercepted and passed to a listener.
+ *
+ * Also supports an alpha layer to dim the content underneath.  By default, the
+ * alpha layer is the same View as the touch-interceptor layer.  However, for
+ * some use-cases, you want a few Views to not be dimmed, but still have touches
+ * intercepted (for example, {@link CarouselTab}'s label appears above the alpha
+ * layer).  In this case, you can specify the View to use as the alpha layer via
+ * setAlphaLayer(); in this case you are responsible for managing the z-order of
+ * the alpha-layer with respect to your other sub-views.
+ *
+ * Typically, you would not use this class directly, but rather use another class
+ * that uses it, for example {@link FrameLayoutWithOverlay}.
+ */
+public class AlphaTouchInterceptorOverlay extends FrameLayout {
+
+    private View mInterceptorLayer;
+    private View mAlphaLayer;
+    private float mAlpha = 0.0f;
+
+    public AlphaTouchInterceptorOverlay(Context context) {
+        super(context);
+
+        mInterceptorLayer = new View(context);
+        final int resId = ThemeUtils.getSelectableItemBackground(context.getTheme());
+        mInterceptorLayer.setBackgroundResource(resId);
+        addView(mInterceptorLayer);
+
+        mAlphaLayer = this;
+    }
+
+    /**
+     * Set the View that the overlay will use as its alpha-layer.  If
+     * none is set it will use itself.  Only necessary to set this if
+     * some child views need to appear above the alpha-layer but below
+     * the touch-interceptor.
+     */
+    public void setAlphaLayer(View alphaLayer) {
+        if (mAlphaLayer == alphaLayer) return;
+
+        // We're no longer the alpha-layer, so make ourself invisible.
+        if (mAlphaLayer == this) ContactDetailDisplayUtils.setAlphaOnViewBackground(this, 0.0f);
+
+        mAlphaLayer = (alphaLayer == null) ? this : alphaLayer;
+        setAlphaLayerValue(mAlpha);
+    }
+
+    /** Sets the alpha value on the alpha layer. */
+    public void setAlphaLayerValue(float alpha) {
+        mAlpha = alpha;
+        if (mAlphaLayer != null) {
+            ContactDetailDisplayUtils.setAlphaOnViewBackground(mAlphaLayer, mAlpha);
+        }
+    }
+
+    /** Delegate to interceptor-layer. */
+    public void setOverlayOnClickListener(OnClickListener listener) {
+        mInterceptorLayer.setOnClickListener(listener);
+    }
+
+    /** Delegate to interceptor-layer. */
+    public void setOverlayClickable(boolean clickable) {
+        mInterceptorLayer.setClickable(clickable);
+    }
+}
diff --git a/src/com/android/contacts/widget/CompositeListAdapter.java b/src/com/android/contacts/widget/CompositeListAdapter.java
index 692e073..610b97f 100644
--- a/src/com/android/contacts/widget/CompositeListAdapter.java
+++ b/src/com/android/contacts/widget/CompositeListAdapter.java
@@ -15,6 +15,7 @@
  */
 package com.android.contacts.widget;
 
+import com.android.contacts.test.NeededForTesting;
 import com.google.common.annotations.VisibleForTesting;
 
 import android.database.DataSetObserver;
@@ -27,7 +28,11 @@
  * A general purpose adapter that is composed of multiple sub-adapters. It just
  * appends them in the order they are added. It listens to changes from all
  * sub-adapters and propagates them to its own listeners.
+ *
+ * This class not used for now -- but let's keep running the test in case we want to revive it...
+ * (So NeededForTesting)
  */
+@NeededForTesting
 public class CompositeListAdapter extends BaseAdapter {
 
     private static final int INITIAL_CAPACITY = 2;
diff --git a/src/com/android/contacts/widget/FrameLayoutWithOverlay.java b/src/com/android/contacts/widget/FrameLayoutWithOverlay.java
new file mode 100644
index 0000000..6d7106b
--- /dev/null
+++ b/src/com/android/contacts/widget/FrameLayoutWithOverlay.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 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.contacts.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+/**
+ * A FrameLayout whose contents are kept beneath an {@link AlphaTouchInterceptorOverlay}.
+ * If necessary, you can specify your own alpha-layer and manually manage its z-order.
+ */
+public class FrameLayoutWithOverlay extends FrameLayout {
+    private final AlphaTouchInterceptorOverlay mOverlay;
+
+    public FrameLayoutWithOverlay(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        // Programmatically create touch-interceptor View.
+        mOverlay = new AlphaTouchInterceptorOverlay(context);
+
+        addView(mOverlay);
+    }
+
+    /** After adding the View, bring the overlay to the front to ensure it's always on top. */
+    @Override
+    public void addView(View child, int index, ViewGroup.LayoutParams params) {
+        super.addView(child, index, params);
+        mOverlay.bringToFront();
+    }
+
+    /**
+     * Delegate to overlay:  set the View that it will use as its alpha-layer.
+     * If none is set, the overlay will use its own alpha layer.  Only
+     * necessary to set this if some child views need to appear above the
+     * alpha-layer.
+     */
+    protected void setAlphaLayer(View layer) {
+        mOverlay.setAlphaLayer(layer);
+    }
+
+    /** Delegate to overlay: set the alpha value on the alpha layer. */
+    public void setAlphaLayerValue(float alpha) {
+        mOverlay.setAlphaLayerValue(alpha);
+    }
+
+    /** Delegate to overlay. */
+    public void setOverlayOnClickListener(OnClickListener listener) {
+        mOverlay.setOverlayOnClickListener(listener);
+    }
+
+    /** Delegate to overlay. */
+    public void setOverlayClickable(boolean clickable) {
+        mOverlay.setOverlayClickable(clickable);
+    }
+}
diff --git a/src/com/android/contacts/widget/LayoutSuppressingImageView.java b/src/com/android/contacts/widget/LayoutSuppressingImageView.java
new file mode 100644
index 0000000..d80aeea
--- /dev/null
+++ b/src/com/android/contacts/widget/LayoutSuppressingImageView.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.contacts.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * Custom {@link ImageView} that improves layouting performance.
+ *
+ * This improves the performance by not passing requestLayout() to its parent, taking advantage
+ * of knowing that image size won't change once set.
+ */
+public class LayoutSuppressingImageView extends ImageView {
+
+    public LayoutSuppressingImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void requestLayout() {
+        forceLayout();
+    }
+}
diff --git a/src/com/android/contacts/widget/LayoutSuppressingQuickContactBadge.java b/src/com/android/contacts/widget/LayoutSuppressingQuickContactBadge.java
new file mode 100644
index 0000000..3413e53
--- /dev/null
+++ b/src/com/android/contacts/widget/LayoutSuppressingQuickContactBadge.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.contacts.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.QuickContactBadge;
+
+/**
+ * Custom {@link QuickContactBadge} that improves layouting performance.
+ *
+ * This improves the performance by not passing requestLayout() to its parent, taking advantage
+ * of knowing that image size won't change once set.
+ */
+public class LayoutSuppressingQuickContactBadge extends QuickContactBadge {
+
+    public LayoutSuppressingQuickContactBadge(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void requestLayout() {
+        forceLayout();
+    }
+}
diff --git a/src/com/android/contacts/widget/PinnedHeaderListAdapter.java b/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
index a4d375e..a39cfcc 100644
--- a/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
+++ b/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
@@ -48,6 +48,7 @@
         this.mPinnedPartitionHeadersEnabled = flag;
     }
 
+    @Override
     public int getPinnedHeaderCount() {
         if (mPinnedPartitionHeadersEnabled) {
             return getPartitionCount();
@@ -65,6 +66,7 @@
      * The default implementation creates the same type of view as a normal
      * partition header.
      */
+    @Override
     public View getPinnedHeaderView(int partition, View convertView, ViewGroup parent) {
         if (hasHeader(partition)) {
             View view = null;
@@ -87,6 +89,7 @@
         }
     }
 
+    @Override
     public void configurePinnedHeaders(PinnedHeaderListView listView) {
         if (!mPinnedPartitionHeadersEnabled) {
             return;
@@ -161,6 +164,7 @@
         }
     }
 
+    @Override
     public int getScrollPositionForHeader(int viewIndex) {
         return getPositionForPartition(viewIndex);
     }
diff --git a/src/com/android/contacts/widget/PinnedHeaderListView.java b/src/com/android/contacts/widget/PinnedHeaderListView.java
index cef7203..1503879 100644
--- a/src/com/android/contacts/widget/PinnedHeaderListView.java
+++ b/src/com/android/contacts/widget/PinnedHeaderListView.java
@@ -74,7 +74,7 @@
     private static final int BOTTOM = 1;
     private static final int FADING = 2;
 
-    private static final int DEFAULT_ANIMATION_DURATION = 100;
+    private static final int DEFAULT_ANIMATION_DURATION = 20;
 
     private static final class PinnedHeader {
         View view;
@@ -149,6 +149,7 @@
         super.setOnItemSelectedListener(this);
     }
 
+    @Override
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
             int totalItemCount) {
         if (mAdapter != null) {
@@ -187,6 +188,7 @@
         return mSize > 0 ? 0 : super.getTopFadingEdgeStrength();
     }
 
+    @Override
     public void onScrollStateChanged(AbsListView view, int scrollState) {
         mScrollState = scrollState;
         if (mOnScrollListener != null) {
@@ -198,13 +200,13 @@
      * Ensures that the selected item is positioned below the top-pinned headers
      * and above the bottom-pinned ones.
      */
+    @Override
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
         int height = getHeight();
 
         int windowTop = 0;
         int windowBottom = height;
 
-        int prevHeaderBottom = 0;
         for (int i = 0; i < mSize; i++) {
             PinnedHeader header = mHeaders[i];
             if (header.visible) {
@@ -231,6 +233,7 @@
         }
     }
 
+    @Override
     public void onNothingSelected(AdapterView<?> parent) {
         if (mOnItemSelectedListener != null) {
             mOnItemSelectedListener.onNothingSelected(parent);
diff --git a/src/com/android/contacts/widget/SearchEditText.java b/src/com/android/contacts/widget/SearchEditText.java
deleted file mode 100644
index d8ea2be..0000000
--- a/src/com/android/contacts/widget/SearchEditText.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.widget;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-
-/**
- * A custom text editor that helps automatically dismiss the activity along with the soft
- * keyboard.
- */
-public class SearchEditText extends EditText implements OnEditorActionListener, TextWatcher {
-
-    private boolean mMaginfyingGlassEnabled = true;
-    private Drawable mMagnifyingGlass;
-    private OnFilterTextListener mListener;
-
-    private boolean mMagnifyingGlassShown;
-
-    public interface OnFilterTextListener {
-        void onFilterChange(String queryString);
-        void onCancelSearch();
-    }
-
-    public SearchEditText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        addTextChangedListener(this);
-        setOnEditorActionListener(this);
-        mMagnifyingGlass = getCompoundDrawables()[2];
-        setCompoundDrawables(null, null, null, null);
-    }
-
-    public boolean isMaginfyingGlassEnabled() {
-        return mMaginfyingGlassEnabled;
-    }
-
-    public void setMaginfyingGlassEnabled(boolean flag) {
-        this.mMaginfyingGlassEnabled = flag;
-    }
-
-    public void setOnFilterTextListener(OnFilterTextListener listener) {
-        this.mListener = listener;
-    }
-
-    /**
-     * Conditionally shows a magnifying glass icon on the right side of the text field
-     * when the text it empty.
-     */
-    @Override
-    public boolean onPreDraw() {
-        boolean emptyText = TextUtils.isEmpty(getText());
-        if (mMagnifyingGlassShown != emptyText) {
-            mMagnifyingGlassShown = emptyText;
-            if (mMagnifyingGlassShown && mMaginfyingGlassEnabled) {
-                setCompoundDrawables(null, null, mMagnifyingGlass, null);
-            } else {
-                setCompoundDrawables(null, null, null, null);
-            }
-            return false;
-        }
-        return super.onPreDraw();
-    }
-
-    /**
-     * Dismisses the search UI along with the keyboard if the filter text is empty.
-     */
-    @Override
-    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK && TextUtils.isEmpty(getText()) && mListener != null) {
-            mListener.onCancelSearch();
-            return true;
-        }
-        return false;
-    }
-
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
-    /**
-     * Event handler for search UI.
-     */
-    public void afterTextChanged(Editable s) {
-        if (mListener != null) {
-            mListener.onFilterChange(trim(s));
-        }
-    }
-
-    private String trim(Editable s) {
-        return s.toString().trim();
-    }
-
-    /**
-     * Event handler for search UI.
-     */
-    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-        if (actionId == EditorInfo.IME_ACTION_DONE) {
-            hideSoftKeyboard();
-            if (TextUtils.isEmpty(trim(getText())) && mListener != null) {
-                mListener.onCancelSearch();
-            }
-            return true;
-        }
-        return false;
-    }
-
-    private void hideSoftKeyboard() {
-        // Hide soft keyboard, if visible
-        InputMethodManager inputMethodManager = (InputMethodManager)
-                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-        inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-    }
-
-}
diff --git a/src/com/android/contacts/widget/TransitionAnimationView.java b/src/com/android/contacts/widget/TransitionAnimationView.java
index e2f8a87..28d728b 100644
--- a/src/com/android/contacts/widget/TransitionAnimationView.java
+++ b/src/com/android/contacts/widget/TransitionAnimationView.java
@@ -15,43 +15,20 @@
  */
 package com.android.contacts.widget;
 
-import com.android.contacts.R;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorInflater;
+import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.ViewParent;
 import android.widget.FrameLayout;
 
 /**
- * A container for a view that needs to have exit/enter animations when rebinding data.
- * This layout should have a single child.  Just before rebinding data that child
- * should make this call:
- * <pre>
- *   TransitionAnimationView.startAnimation(this);
- * </pre>
+ * A container that places a masking view on top of all other views.  The masking view can be
+ * faded in and out.  Currently, the masking view is solid color white.
  */
-public class TransitionAnimationView extends FrameLayout implements AnimatorListener {
-
-    private View mPreviousStateView;
-    private Bitmap mPreviousStateBitmap;
-    private int mEnterAnimationId;
-    private int mExitAnimationId;
-    private int mAnimationDuration;
-    private Rect mClipMargins = new Rect();
-    private Rect mClipRect = new Rect();
-    private Animator mEnterAnimation;
-    private Animator mExitAnimation;
+public class TransitionAnimationView extends FrameLayout {
+    private View mMaskingView;
+    private ObjectAnimator mAnimator;
 
     public TransitionAnimationView(Context context) {
         this(context, null, 0);
@@ -63,144 +40,48 @@
 
     public TransitionAnimationView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-
-        TypedArray a = getContext().obtainStyledAttributes(
-                attrs, R.styleable.TransitionAnimationView);
-
-        mEnterAnimationId = a.getResourceId(R.styleable.TransitionAnimationView_enterAnimation,
-                android.R.animator.fade_in);
-        mExitAnimationId = a.getResourceId(R.styleable.TransitionAnimationView_exitAnimation,
-                android.R.animator.fade_out);
-        mClipMargins.left = a.getDimensionPixelOffset(
-                R.styleable.TransitionAnimationView_clipMarginLeft, 0);
-        mClipMargins.top = a.getDimensionPixelOffset(
-                R.styleable.TransitionAnimationView_clipMarginTop, 0);
-        mClipMargins.right = a.getDimensionPixelOffset(
-                R.styleable.TransitionAnimationView_clipMarginRight, 0);
-        mClipMargins.bottom = a.getDimensionPixelOffset(
-                R.styleable.TransitionAnimationView_clipMarginBottom, 0);
-        mAnimationDuration = a.getInt(
-                R.styleable.TransitionAnimationView_animationDuration, 100);
-
-        a.recycle();
-
-        mPreviousStateView = new View(context);
-        mPreviousStateView.setVisibility(View.INVISIBLE);
-        addView(mPreviousStateView);
-
-        mEnterAnimation = AnimatorInflater.loadAnimator(getContext(), mEnterAnimationId);
-        if (mEnterAnimation == null) {
-            throw new IllegalArgumentException("Invalid enter animation: " + mEnterAnimationId);
-        }
-        mEnterAnimation.addListener(this);
-        mEnterAnimation.setDuration(mAnimationDuration);
-
-        mExitAnimation = AnimatorInflater.loadAnimator(getContext(), mExitAnimationId);
-        if (mExitAnimation == null) {
-            throw new IllegalArgumentException("Invalid exit animation: " + mExitAnimationId);
-        }
-
     }
 
     @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (changed || mPreviousStateBitmap == null) {
-            if (mPreviousStateBitmap != null) {
-                mPreviousStateBitmap.recycle();
-                mPreviousStateBitmap = null;
-            }
-            int width = right - left;
-            int height = bottom - top;
-            if (width > 0 && height > 0) {
-                mPreviousStateBitmap = Bitmap.createBitmap(
-                        width, height, Bitmap.Config.ARGB_8888);
-                mPreviousStateView.setBackgroundDrawable(
-                        new BitmapDrawable(getContext().getResources(), mPreviousStateBitmap));
-                mClipRect.set(mClipMargins.left, mClipMargins.top,
-                        width - mClipMargins.right, height - mClipMargins.bottom);
-            } else {
-                mPreviousStateBitmap = null;
-                mPreviousStateView.setBackgroundDrawable(null);
-            }
-        }
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mMaskingView = new View(getContext());
+        mMaskingView.setVisibility(View.INVISIBLE);
+        mMaskingView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT));
+        mMaskingView.setBackgroundColor(Color.WHITE);
+        addView(mMaskingView);
     }
 
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mPreviousStateView.setBackgroundDrawable(null);
-        if (mPreviousStateBitmap != null) {
-            mPreviousStateBitmap.recycle();
-            mPreviousStateBitmap = null;
-        }
-    }
-
-    public static void startAnimation(View view, boolean closing) {
-        TransitionAnimationView container = null;
-        ViewParent parent = view.getParent();
-        while (parent instanceof View) {
-            if (parent instanceof TransitionAnimationView) {
-                container = (TransitionAnimationView) parent;
-                break;
-            }
-            parent = parent.getParent();
-        }
-
-        if (container != null) {
-            container.start(view, closing);
-        }
-    }
-
-    private void start(View view, boolean closing) {
-        if (mEnterAnimation.isRunning()) {
-            mEnterAnimation.end();
-        }
-        if (mExitAnimation.isRunning()) {
-            mExitAnimation.end();
-        }
-        if (view.getVisibility() != View.VISIBLE) {
-            if (!closing) {
-                mEnterAnimation.setTarget(view);
-                mEnterAnimation.start();
-            }
-        } else if (closing) {
-            mExitAnimation.setTarget(view);
-            mExitAnimation.start();
+    public void setMaskVisibility(boolean flag) {
+        if (flag) {
+            mMaskingView.setAlpha(1.0f);
+            mMaskingView.setVisibility(View.VISIBLE);
         } else {
-            if (mPreviousStateBitmap == null) {
-                return;
-            }
-
-            Canvas canvas = new Canvas(mPreviousStateBitmap);
-            Paint paint = new Paint();
-            paint.setColor(Color.TRANSPARENT);
-            canvas.drawRect(0, 0, mPreviousStateBitmap.getWidth(), mPreviousStateBitmap.getHeight(),
-                    paint);
-            canvas.clipRect(mClipRect);
-            view.draw(canvas);
-            canvas.setBitmap(null);
-            mPreviousStateView.setVisibility(View.VISIBLE);
-
-            mEnterAnimation.setTarget(view);
-            mEnterAnimation.start();
+            mMaskingView.setVisibility(View.INVISIBLE);
         }
     }
 
-    @Override
-    public void onAnimationEnd(Animator animation) {
-        mPreviousStateView.setVisibility(View.INVISIBLE);
-    }
+    /**
+     * Starts the transition of showing or hiding the mask.
+     * If showMask is true, the mask will be set to be invisible then fade into hide the other
+     * views in this container.  If showMask is false, the mask will be set to be hide other views
+     * initially.  Then, the other views in this container will be revealed.
+     */
+    public void startMaskTransition(boolean showMask) {
+        // Stop any animation that may still be running.
+        if (mAnimator != null && mAnimator.isRunning()) {
+            mAnimator.end();
+        }
 
-    @Override
-    public void onAnimationCancel(Animator animation) {
-    }
-
-    @Override
-    public void onAnimationStart(Animator animation) {
-    }
-
-    @Override
-    public void onAnimationRepeat(Animator animation) {
+        mMaskingView.setVisibility(View.VISIBLE);
+        if (showMask) {
+            mAnimator = ObjectAnimator.ofFloat(mMaskingView, View.ALPHA, 0.0f, 1.0f);
+            mAnimator.start();
+        } else {
+            // asked to hide the view
+            mAnimator = ObjectAnimator.ofFloat(mMaskingView, View.ALPHA, 1.0f, 0.0f);
+            mAnimator.start();
+        }
     }
 }
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 6ea42d6..d80a35d 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -19,6 +19,8 @@
 
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_CALL_LOG" />
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
 
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
@@ -28,6 +30,9 @@
     <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
 
+    <uses-permission android:name="android.permission.READ_PROFILE" />
+    <uses-permission android:name="android.permission.READ_SOCIAL_STREAM" />
+
     <application>
         <uses-library android:name="android.test.runner" />
         <meta-data android:name="com.android.contacts.iconset" android:resource="@xml/iconset" />
@@ -119,6 +124,9 @@
                 android:name="android.provider.CONTACTS_STRUCTURE"
                 android:resource="@xml/test_basic_contacts" />
         </service>
+
+        <service android:name=".QueryService" />
+        <service android:name=".PhoneNumberTestService" />
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/tests/res/drawable/ic_contact_picture.png b/tests/res/drawable/ic_contact_picture.png
index 3a338e8..6876777 100644
--- a/tests/res/drawable/ic_contact_picture.png
+++ b/tests/res/drawable/ic_contact_picture.png
Binary files differ
diff --git a/tests/res/layout/fill_call_log_test.xml b/tests/res/layout/fill_call_log_test.xml
index a5f64f5..01ade3e 100644
--- a/tests/res/layout/fill_call_log_test.xml
+++ b/tests/res/layout/fill_call_log_test.xml
@@ -31,7 +31,14 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:inputType="number"
+        android:text="10"
         />
+    <CheckBox
+        android:id="@+id/use_random_numbers"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/useRandomNumbers"
+    />
     <Button
         android:id="@+id/add"
         android:layout_width="match_parent"
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 19ebde3..be6b5a7 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -23,7 +23,7 @@
         <!-- List modes -->
         <item>LIST_DEFAULT</item>
         <item>LIST_ALL_CONTACTS_ACTION</item>
-        <item>LIST_CONTACTS_WITH_PHONES_ACTION</item>
+        <item>LIST_CONTACTS_WITH_PHONES_ACTION (deprecated)</item>
         <item>LIST_STARRED_ACTION</item>
         <item>LIST_FREQUENT_ACTION</item>
         <item>LIST_STREQUENT_ACTION</item>
@@ -46,6 +46,8 @@
         <item>ACTION_GET_CONTENT: postal</item>
         <item>ACTION_GET_CONTENT: postal (legacy)</item>
         <item>ACTION_INSERT_OR_EDIT</item>
+        <item>ACTION_INSERT_OR_EDIT_PHONE_NUMBER</item>
+        <item>ACTION_INSERT_OR_EDIT_EMAIL_ADDRESS</item>
         <item>ACTION_SEARCH (call button)</item>
         <item>ACTION_SEARCH: contact</item>
         <item>ACTION_SEARCH: email</item>
@@ -96,8 +98,9 @@
     <string name="fillCallLogTest">Fill call log test</string>
     <string name="addToCallLogButton">Add</string>
     <string name="numberOfCallLogEntries">Number of call log entries to add:</string>
+    <string name="useRandomNumbers">Use random numbers</string>
     <string name="addedLogEntriesToast">Added %1$d call log entries.</string>
-    <string name="noLogEntriesToast">No entries in the call log yet.</string>
+    <string name="noLogEntriesToast">No entries in the call log yet.  Need at least one record for the template.  Or use random numbers.</string>
 
     <string name="chooseAContactButton">Choose a contact to add stream items to</string>
     <string name="exitButton">Exit</string>
diff --git a/tests/src/com/android/contacts/CallDetailActivityTest.java b/tests/src/com/android/contacts/CallDetailActivityTest.java
index ac02588..689f946 100644
--- a/tests/src/com/android/contacts/CallDetailActivityTest.java
+++ b/tests/src/com/android/contacts/CallDetailActivityTest.java
@@ -25,7 +25,6 @@
 import com.android.contacts.util.IntegrationTestUtils;
 import com.android.contacts.util.LocaleTestUtils;
 import com.android.internal.view.menu.ContextMenuBuilder;
-import com.google.common.base.Preconditions;
 import com.google.common.io.Closeables;
 
 import android.content.ContentResolver;
@@ -227,7 +226,7 @@
     }
 
     private void setActivityIntentForTestCallEntry() {
-        Preconditions.checkState(mCallLogUri == null, "mUri should be null");
+        assertNull(mCallLogUri);
         ContentResolver contentResolver = getContentResolver();
         ContentValues values = new ContentValues();
         values.put(CallLog.Calls.NUMBER, CONTACT_NUMBER);
@@ -237,7 +236,7 @@
     }
 
     private void setActivityIntentForTestVoicemailEntry() {
-        Preconditions.checkState(mVoicemailUri == null, "mUri should be null");
+        assertNull(mVoicemailUri);
         ContentResolver contentResolver = getContentResolver();
         ContentValues values = new ContentValues();
         values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
@@ -252,7 +251,7 @@
     }
 
     private void setActivityIntentForRealFileVoicemailEntry() throws IOException {
-        Preconditions.checkState(mVoicemailUri == null, "mUri should be null");
+        assertNull(mVoicemailUri);
         ContentValues values = new ContentValues();
         values.put(VoicemailContract.Voicemails.DATE, String.valueOf(System.currentTimeMillis()));
         values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
@@ -307,7 +306,7 @@
     }
 
     private TextView assertHasOneTextViewContaining(String text) throws Throwable {
-        Preconditions.checkNotNull(mActivityUnderTest, "forget to call startActivityUnderTest()?");
+        assertNotNull(mActivityUnderTest);
         List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, text);
         assertEquals("There should have been one TextView with text '" + text + "' but found "
                 + views, 1, views.size());
@@ -315,14 +314,14 @@
     }
 
     private void assertZeroTextViewsContaining(String text) throws Throwable {
-        Preconditions.checkNotNull(mActivityUnderTest, "forget to call startActivityUnderTest()?");
+        assertNotNull(mActivityUnderTest);
         List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, text);
         assertEquals("There should have been no TextViews with text '" + text + "' but found "
                 + views, 0,  views.size());
     }
 
     private void startActivityUnderTest() throws Throwable {
-        Preconditions.checkState(mActivityUnderTest == null, "must only start the activity once");
+        assertNull(mActivityUnderTest);
         mActivityUnderTest = getActivity();
         assertNotNull("activity should not be null", mActivityUnderTest);
         // We have to run all tasks, not just one.
diff --git a/tests/src/com/android/contacts/ContactDetailTest.java b/tests/src/com/android/contacts/ContactDetailTest.java
index e8d1550..b2c19f4 100644
--- a/tests/src/com/android/contacts/ContactDetailTest.java
+++ b/tests/src/com/android/contacts/ContactDetailTest.java
@@ -21,7 +21,9 @@
 import com.android.contacts.tests.mocks.MockContentProvider;
 
 import android.test.ActivityUnitTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
+@SmallTest
 public class ContactDetailTest extends ActivityUnitTestCase<ContactDetailActivity> {
     private ContactsMockContext mContext;
     private MockContentProvider mContactsProvider;
diff --git a/tests/src/com/android/contacts/ContactLoaderTest.java b/tests/src/com/android/contacts/ContactLoaderTest.java
index f88b64e..5c215f9 100644
--- a/tests/src/com/android/contacts/ContactLoaderTest.java
+++ b/tests/src/com/android/contacts/ContactLoaderTest.java
@@ -75,7 +75,7 @@
     }
 
     private ContactLoader.Result assertLoadContact(Uri uri) {
-        final ContactLoader loader = new ContactLoader(mMockContext, uri);
+        final ContactLoader loader = new ContactLoader(mMockContext, uri, true);
         return getLoaderResultSynchronously(loader);
     }
 
diff --git a/tests/src/com/android/contacts/ContactsUtilsTests.java b/tests/src/com/android/contacts/ContactsUtilsTests.java
index 82d0cb0..d2d5bbb 100644
--- a/tests/src/com/android/contacts/ContactsUtilsTests.java
+++ b/tests/src/com/android/contacts/ContactsUtilsTests.java
@@ -126,7 +126,7 @@
         assertCollapses("72", true,
                 Phone.CONTENT_ITEM_TYPE, "+49 (8092) 1234",
                 Phone.CONTENT_ITEM_TYPE, "+49 (8092)1234");
-        assertCollapses("73", true,
+        assertCollapses("73", false,
                 Phone.CONTENT_ITEM_TYPE, "0049 (8092) 1234",
                 Phone.CONTENT_ITEM_TYPE, "+49/80921234");
         assertCollapses("74", false,
@@ -147,14 +147,37 @@
                 Phone.CONTENT_ITEM_TYPE, "1234567;+49 (8092) 1234",
                 Phone.CONTENT_ITEM_TYPE, "1234567;+49/80921234");
 
-        // this makes sure that if if two segments are identical, we don't even try to parse
-        // (and therefore allow invalid phone numbers)
-        assertCollapses("84", true,
-                Phone.CONTENT_ITEM_TYPE, "+49/80921234;a89",
-                Phone.CONTENT_ITEM_TYPE, "+49 (8092) 1234;a89");
-        assertCollapses("85", false,
-                Phone.CONTENT_ITEM_TYPE, "+49/80921234;a89",
-                Phone.CONTENT_ITEM_TYPE, "+49/80921234;b89");
+        assertCollapses("86", true,
+                Phone.CONTENT_ITEM_TYPE, "",
+                Phone.CONTENT_ITEM_TYPE, "");
+
+        assertCollapses("87", false,
+                Phone.CONTENT_ITEM_TYPE, "1",
+                Phone.CONTENT_ITEM_TYPE, "");
+
+        assertCollapses("88", false,
+                Phone.CONTENT_ITEM_TYPE, "",
+                Phone.CONTENT_ITEM_TYPE, "1");
+
+        assertCollapses("89", true,
+                Phone.CONTENT_ITEM_TYPE, "---",
+                Phone.CONTENT_ITEM_TYPE, "---");
+
+        assertCollapses("90", true,
+                Phone.CONTENT_ITEM_TYPE, "1-/().",
+                Phone.CONTENT_ITEM_TYPE, "--$%1");
+
+        assertCollapses("91", true,
+                Phone.CONTENT_ITEM_TYPE, "abcdefghijklmnopqrstuvwxyz",
+                Phone.CONTENT_ITEM_TYPE, "22233344455566677778889999");
+
+        assertCollapses("92", false,
+                Phone.CONTENT_ITEM_TYPE, "1;2",
+                Phone.CONTENT_ITEM_TYPE, "12");
+
+        assertCollapses("93", false,
+                Phone.CONTENT_ITEM_TYPE, "1,2",
+                Phone.CONTENT_ITEM_TYPE, "12");
     }
 
     private void assertCollapses(String message, boolean expected, CharSequence mimetype1,
@@ -164,12 +187,17 @@
         assertEquals(message, expected,
                 ContactsUtils.shouldCollapse(mimetype2, data2, mimetype1, data1));
 
+        // If data1 and data2 are the same instance, make sure the same test passes with different
+        // instances.
         if (data1 == data2 && data1 != null) {
-            // make sure we also do a test where object equality is not given
-            final CharSequence data2_newref = data2 + "";
+            // Create a different instance
+            final CharSequence data2_newref = new StringBuilder(data2).append("").toString();
 
-            // this just makes sure the test is working
-            assertFalse(data1 == data2_newref);
+            if (data1 == data2_newref) {
+                // In some cases no matter what we do the runtime reuses the same instance, so
+                // we can't do the "different instance" test.
+                return;
+            }
 
             // we have two different instances, now make sure we get the same result as before
             assertEquals(message, expected,
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
index 6872604..df4934a 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -1130,6 +1130,25 @@
         AccountType newAccountType = new ExchangeAccountType(getContext(), "");
         DataKind kind = newAccountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
 
+        // Create 5 numbers.
+        // - "1" -- HOME
+        // - "2" -- WORK
+        // - "3" -- CUSTOM
+        // - "4" -- WORK
+        // - "5" -- WORK_MOBILE
+        // Then we convert it to Exchange account type.
+        // - "1" -- HOME
+        // - "2" -- WORK
+        // - "3" -- Because CUSTOM is not supported, it'll be changed to the default, MOBILE
+        // - "4" -- WORK
+        // - "5" -- WORK_MOBILE not suppoted again, so will be MOBILE.
+        // But then, Exchange doesn't support multiple MOBILE numbers, so "5" will be removed.
+        // i.e. the result will be:
+        // - "1" -- HOME
+        // - "2" -- WORK
+        // - "3" -- MOBILE
+        // - "4" -- WORK
+
         EntityDelta oldState = new EntityDelta();
         ContentValues mockNameValues = new ContentValues();
         mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
@@ -1138,12 +1157,12 @@
         oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
         mockNameValues = new ContentValues();
         mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Phone.TYPE, Phone.TYPE_MOBILE);
+        mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK);
         mockNameValues.put(Phone.NUMBER, "2");
         oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
         mockNameValues = new ContentValues();
         mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        // Exchange doesn't support this type. Default to HOME
+        // Exchange doesn't support this type. Default to MOBILE
         mockNameValues.put(Phone.TYPE, Phone.TYPE_CUSTOM);
         mockNameValues.put(Phone.LABEL, "custom_type");
         mockNameValues.put(Phone.NUMBER, "3");
@@ -1155,8 +1174,6 @@
         oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
         mockNameValues = new ContentValues();
 
-        // This field should be ignored, as Exchange only allows 2 HOME phone numbers while we
-        // already have that number of HOME phones.
         mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
         mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK_MOBILE);
         mockNameValues.put(Phone.NUMBER, "5");
@@ -1169,13 +1186,13 @@
         assertNotNull(list);
         assertEquals(4, list.size());
 
-        int defaultType = kind.typeList.get(0).rawValue;
+        int defaultType = Phone.TYPE_MOBILE;
 
         ContentValues outputValues = list.get(0).getAfter();
         assertEquals(Phone.TYPE_HOME, outputValues.getAsInteger(Phone.TYPE).intValue());
         assertEquals("1", outputValues.getAsString(Phone.NUMBER));
         outputValues = list.get(1).getAfter();
-        assertEquals(Phone.TYPE_MOBILE, outputValues.getAsInteger(Phone.TYPE).intValue());
+        assertEquals(Phone.TYPE_WORK, outputValues.getAsInteger(Phone.TYPE).intValue());
         assertEquals("2", outputValues.getAsString(Phone.NUMBER));
         outputValues = list.get(2).getAfter();
         assertEquals(defaultType, outputValues.getAsInteger(Phone.TYPE).intValue());
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index 66c2c5a..ea7c3dc 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -48,7 +48,7 @@
 import android.provider.ContactsContract.ProviderStatus;
 import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.TextView;
 
 /**
@@ -64,7 +64,7 @@
  *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
  *
  */
-@Smoke
+@SmallTest
 public class PeopleActivityTest
         extends ActivityInstrumentationTestCase2<PeopleActivity>
 {
diff --git a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
index 9cac8fe..89c0a99 100644
--- a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
@@ -619,14 +619,14 @@
 
     /** Asserts that the number and label text view contains the given text. */
     private void assertNumberAndLabelAre(CallLogListItemViews views, CharSequence number,
-            CharSequence numberLabel) {
+            CharSequence label) {
         assertEquals(View.VISIBLE, views.phoneCallDetailsViews.numberView.getVisibility());
-        final CharSequence expectedText;
-        if (numberLabel == null) {
-            expectedText = number;
-        } else {
-            expectedText = numberLabel + " " + number;
+        assertEquals(number, views.phoneCallDetailsViews.numberView.getText().toString());
+
+        assertEquals(label == null ? View.GONE : View.VISIBLE,
+                views.phoneCallDetailsViews.labelView.getVisibility());
+        if (label != null) {
+            assertEquals(label, views.phoneCallDetailsViews.labelView.getText().toString());
         }
-        assertEquals(expectedText, views.phoneCallDetailsViews.numberView.getText().toString());
     }
 }
diff --git a/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java b/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
index 3d383ff..419cac8 100644
--- a/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
+++ b/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
@@ -51,19 +51,20 @@
     }
 
     public void testAddStreamItemText_IncludesComments() {
-        StreamItemEntry streamItem = getTestBuilder().setComment("1 comment").build();
+        StreamItemEntry streamItem = getTestBuilder().setComment("1 comment").build(getContext());
         View streamItemView = addStreamItemText(streamItem);
         assertHasText(streamItemView, R.id.stream_item_comments, "1 comment");
     }
 
     public void testAddStreamItemText_IncludesHtmlComments() {
-        StreamItemEntry streamItem = getTestBuilder().setComment("1 <b>comment</b>").build();
+        StreamItemEntry streamItem = getTestBuilder().setComment("1 <b>comment</b>")
+                .build(getContext());
         View streamItemView = addStreamItemText(streamItem);
         assertHasHtmlText(streamItemView, R.id.stream_item_comments, "1 <b>comment<b>");
     }
 
     public void testAddStreamItemText_NoComments() {
-        StreamItemEntry streamItem = getTestBuilder().setComment(null).build();
+        StreamItemEntry streamItem = getTestBuilder().setComment(null).build(getContext());
         View streamItemView = addStreamItemText(streamItem);
         assertGone(streamItemView, R.id.stream_item_comments);
     }
@@ -108,7 +109,7 @@
      */
     private View addStreamItemText(StreamItemEntry streamItem) {
         return ContactDetailDisplayUtils.addStreamItemText(getContext(), streamItem,
-                mLayoutInflater.inflate(R.layout.stream_item_row_text, null));
+                mLayoutInflater.inflate(R.layout.stream_item_container, null));
     }
 
     private StreamItemEntryBuilder getTestBuilder() {
diff --git a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
index 19b14d9..cd2d6bf 100644
--- a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
+++ b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
@@ -21,6 +21,7 @@
 import com.google.common.collect.Lists;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 
 import java.util.ArrayList;
@@ -33,6 +34,7 @@
 /**
  * Unit tests for {@link StreamItemAdapter}.
  */
+@SmallTest
 public class StreamItemAdapterTest extends AndroidTestCase {
     private StreamItemAdapter mAdapter;
     private FakeOnClickListener mListener;
@@ -83,7 +85,7 @@
     private ArrayList<StreamItemEntry> createStreamItemList(int count) {
         ArrayList<StreamItemEntry> list = Lists.newArrayList();
         for (int index = 0; index < count; ++index) {
-            list.add(createStreamItemEntryBuilder().build());
+            list.add(createStreamItemEntryBuilder().build(getContext()));
         }
         return list;
     }
diff --git a/tests/src/com/android/contacts/format/PrefixHighligherTest.java b/tests/src/com/android/contacts/format/PrefixHighligherTest.java
index a0c0ff3..668330b 100644
--- a/tests/src/com/android/contacts/format/PrefixHighligherTest.java
+++ b/tests/src/com/android/contacts/format/PrefixHighligherTest.java
@@ -17,11 +17,13 @@
 package com.android.contacts.format;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.TextView;
 
 /**
  * Unit tests for {@link PrefixHighlighter}.
  */
+@SmallTest
 public class PrefixHighligherTest extends AndroidTestCase {
     private static final int TEST_PREFIX_HIGHLIGHT_COLOR = 0xFF0000;
     /** The HTML code used to mark the start of the highlighted part. */
diff --git a/tests/src/com/android/contacts/format/SpannedTestUtils.java b/tests/src/com/android/contacts/format/SpannedTestUtils.java
index 625c6aa..ce228a7 100644
--- a/tests/src/com/android/contacts/format/SpannedTestUtils.java
+++ b/tests/src/com/android/contacts/format/SpannedTestUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.format;
 
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Html;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -26,6 +27,7 @@
 /**
  * Utility class to check the value of spanned text in text views.
  */
+@SmallTest
 public class SpannedTestUtils {
     /**
      * Checks that the text contained in the text view matches the given HTML text.
@@ -39,7 +41,7 @@
             // If the text is empty, it does not add the <p></p> bits to it.
             Assert.assertEquals("", actualHtmlText);
         } else {
-            Assert.assertEquals("<p>" + expectedHtmlText + "</p>\n", actualHtmlText);
+            Assert.assertEquals("<p dir=ltr>" + expectedHtmlText + "</p>\n", actualHtmlText);
         }
     }
 
diff --git a/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java b/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
index f2848d0..2deaef3 100644
--- a/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
+++ b/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
@@ -21,10 +21,12 @@
 
 import android.database.CharArrayBuffer;
 import android.graphics.Typeface;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableStringBuilder;
 import android.text.style.StyleSpan;
 
 /** A factory for {@link TextWithHighlighting} that wraps its parts in italics. */
+@SmallTest
 public final class TestTextWithHighlightingFactory implements TextWithHighlightingFactory {
     /** A {@link TextWithHighlighting} implementation that wraps its parts in italics. */
     private final static class TestTextWithHighlighting extends SpannableStringBuilder
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index 2c4b74c..b37d24f 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -35,7 +35,7 @@
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Contacts.Entity;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Tests for {@link ContactDeletionInteraction}.
@@ -47,7 +47,7 @@
  *   adb shell am instrument \
  *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
  */
-@Smoke
+@SmallTest
 public class ContactDeletionInteractionTest
         extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
 
diff --git a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
index e0b443a..2da8859 100644
--- a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
@@ -29,11 +29,12 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -48,7 +49,7 @@
  *   adb shell am instrument \
  *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
  */
-@Smoke
+@SmallTest
 public class PhoneNumberInteractionTest extends InstrumentationTestCase {
 
     static {
@@ -89,7 +90,8 @@
     public void testSendSmsWhenOnlyOneNumberAvailable() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null);
+                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.SMS, null);
@@ -107,7 +109,8 @@
     public void testSendSmsWhenDataIdIsProvided() {
         Uri dataUri = ContentUris.withAppendedId(Data.CONTENT_URI, 1);
         expectQuery(dataUri, true /* isDataUri */ )
-                .returnRow(1, "987", 0, null, null, Phone.TYPE_HOME, null);
+                .returnRow(1, "987", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.SMS, null);
@@ -125,8 +128,10 @@
     public void testSendSmsWhenThereIsPrimaryNumber() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null)
-                .returnRow(2, "456", 1, null, null, Phone.TYPE_HOME, null);
+                .returnRow(
+                        1, "123", 0, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE)
+                .returnRow(
+                        2, "456", 1, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.SMS, null);
@@ -164,8 +169,10 @@
     public void testCallNumberWhenThereAreDuplicates() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null)
-                .returnRow(2, "123", 0, null, null, Phone.TYPE_WORK, null);
+                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE)
+                .returnRow(2, "123", 0, null, null, Phone.TYPE_WORK, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.PHONE_CALL, null);
@@ -180,11 +187,31 @@
         assertEquals("tel:123", intent.getDataString());
     }
 
+    public void testCallWithSip() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(1, "example@example.com", 0, null, null, Phone.TYPE_HOME, null,
+                        SipAddress.CONTENT_ITEM_TYPE);
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, InteractionType.PHONE_CALL, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
+        assertEquals("sip:example%40example.com", intent.getDataString());
+    }
+
     public void testShowDisambigDialogForCalling() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, "account", null, Phone.TYPE_HOME, "label")
-                .returnRow(2, "456", 0, null, null, Phone.TYPE_WORK, null);
+                .returnRow(1, "123", 0, "account", null, Phone.TYPE_HOME, "label",
+                        Phone.CONTENT_ITEM_TYPE)
+                .returnRow(2, "456", 0, null, null, Phone.TYPE_WORK, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.PHONE_CALL, null);
@@ -224,7 +251,9 @@
                         RawContacts.ACCOUNT_TYPE,
                         RawContacts.DATA_SET,
                         Phone.TYPE,
-                        Phone.LABEL)
-                .withSelection("mimetype='vnd.android.cursor.item/phone_v2' AND data1 NOT NULL");
+                        Phone.LABEL,
+                        Phone.MIMETYPE)
+                .withSelection("mimetype IN ('vnd.android.cursor.item/phone_v2',"
+                        + " 'vnd.android.cursor.item/sip_address') AND data1 NOT NULL");
     }
 }
diff --git a/tests/src/com/android/contacts/model/AccountTypeTest.java b/tests/src/com/android/contacts/model/AccountTypeTest.java
index 8bc7429..6d4d6b0 100644
--- a/tests/src/com/android/contacts/model/AccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/AccountTypeTest.java
@@ -66,8 +66,8 @@
 
         AccountType accountType = new AccountType() {
             {
-                resPackageName = packageName;
-                summaryResPackageName = packageName;
+                resourcePackageName = packageName;
+                syncAdapterPackageName = packageName;
             }
             @Override protected int getInviteContactActionResId() {
                 return externalResID;
diff --git a/tests/src/com/android/contacts/model/ExternalAccountTypeTest.java b/tests/src/com/android/contacts/model/ExternalAccountTypeTest.java
index 27c645a..4c47d68 100644
--- a/tests/src/com/android/contacts/model/ExternalAccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/ExternalAccountTypeTest.java
@@ -126,8 +126,8 @@
 
         // Create a fallback type with the same resource package name, and compare all the data
         // kinds to its.
-        final AccountType reference = FallbackAccountType.createForTest(
-                getContext(), type.resPackageName);
+        final AccountType reference = FallbackAccountType.createWithPackageNameForTest(
+                getContext(), type.resourcePackageName);
 
         assertsDataKindEquals(reference.getSortedDataKinds(), type.getSortedDataKinds());
     }
diff --git a/tests/src/com/android/contacts/tests/PhoneNumberTestService.java b/tests/src/com/android/contacts/tests/PhoneNumberTestService.java
new file mode 100644
index 0000000..894e66e
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/PhoneNumberTestService.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 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.contacts.tests;
+
+import com.android.i18n.phonenumbers.NumberParseException;
+import com.android.i18n.phonenumbers.PhoneNumberUtil;
+import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.location.CountryDetector;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * A service to test various phone number formatters.
+ *
+   Usage:
+     adb shell am startservice -e n PHONE_NUMBER \
+       [-e c OPTIONAL COUNTRY CODE]  \
+       com.android.contacts.tests/.PhoneNumberTestService
+
+   Example:
+
+   adb shell am startservice -e n '6502530000' \
+     com.android.contacts.tests/.PhoneNumberTestService
+ */
+public class PhoneNumberTestService extends IntentService {
+    private static final String TAG = "phonenumber";
+
+    private static final String EXTRA_PHONE_NUMBER = "n";
+    private static final String EXTRA_COUNTRY_CODE = "c";
+
+    public PhoneNumberTestService() {
+        super("PhoneNumberTestService");
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        final String number = intent.getStringExtra(EXTRA_PHONE_NUMBER);
+        final String country = intent.getStringExtra(EXTRA_COUNTRY_CODE);
+        final String defaultCountry = getCurrentCountryCode();
+
+        Log.i(TAG, "Input phone number: " + number);
+        Log.i(TAG, "Input country code: " + country);
+        Log.i(TAG, "Current country code: " + defaultCountry);
+
+        // Dump for the given country, the current country, US, GB and JP.
+        Set<String> countries = new LinkedHashSet<String>();
+        if (country != null) countries.add(country);
+        countries.add(defaultCountry);
+        countries.add("US");
+        countries.add("GB");
+        countries.add("JP");
+
+        for (String c : countries) {
+            dump(number, c);
+        }
+    }
+
+    private void dump(String number, String country) {
+        Log.i(TAG, "Result for: " + number + " / " +country);
+        dump_PhoneNumberUtils_formatNumberToE164(number, country);
+        dump_PhoneNumberUtil_format(number, country, PhoneNumberFormat.E164);
+        dump_PhoneNumberUtil_format(number, country, PhoneNumberFormat.INTERNATIONAL);
+        dump_PhoneNumberUtil_format(number, country, PhoneNumberFormat.NATIONAL);
+        dump_PhoneNumberUtil_format(number, country, PhoneNumberFormat.RFC3966);
+    }
+
+    private void dump_PhoneNumberUtils_formatNumberToE164(String number, String country) {
+        Log.i(TAG, "  formatNumberToE164(" + number + ", " + country
+                + ") = " + PhoneNumberUtils.formatNumberToE164(number, country));
+    }
+
+    private void dump_PhoneNumberUtil_format(String number, String country,
+            PhoneNumberFormat format) {
+        String formatted;
+        boolean isValid = false;
+        try {
+            final PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+            final PhoneNumber pn = util.parse(number, country);
+            isValid = util.isValidNumber(pn);
+            formatted = util.format(pn, format);
+        } catch (NumberParseException e) {
+            formatted = "Error: " + e.toString();
+        }
+        Log.i(TAG, "  PhoneNumberUtil.format(parse(" + number + ", " + country + "), " + format
+                + ") = " + formatted + (isValid ? " (valid)" : " (invalid)"));
+    }
+
+    private String getCurrentCountryCode() {
+        final CountryDetector countryDetector =
+                (CountryDetector) getSystemService(Context.COUNTRY_DETECTOR);
+        return countryDetector.detectCountry().getCountryIso();
+    }
+}
+
diff --git a/tests/src/com/android/contacts/tests/QueryService.java b/tests/src/com/android/contacts/tests/QueryService.java
new file mode 100644
index 0000000..04a95c5
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/QueryService.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2011 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.contacts.tests;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * A service that executes a query specified by an intent and dump the result on logcat.  Use the
+ * "am" command to launch it.
+ *
+   Usage:
+     adb shell am startservice -d URI \
+       [-e p OPTIONAL PROJECTION] [-e s OPTIONAL SELECTION] [-e s OPTIONAL ORDER BY]  \
+       com.android.contacts.tests/.QueryService
+
+   Example:
+
+   adb shell am startservice -d content://com.android.contacts/directories \
+     -e p accountName,accountType -e s 'accountName NOT NULL' -e o '_id'  \
+     com.android.contacts.tests/.QueryService
+ */
+public class QueryService extends IntentService {
+    private static final String TAG = "contactsquery";
+
+    private static final String EXTRA_PROJECTION = "p";
+    private static final String EXTRA_SELECTION = "s";
+    private static final String EXTRA_ORDER = "o";
+    private static final String NULL_STRING = "*null*";
+    private static final String SEPARATOR = "|";
+
+    public QueryService() {
+        super("ContactsQueryService");
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        final Uri uri = intent.getData();
+        // Unfortunately "am" doesn't support string arrays...
+        final String projection = intent.getStringExtra(EXTRA_PROJECTION);
+        final String selection = intent.getStringExtra(EXTRA_SELECTION);
+        final String order = intent.getStringExtra(EXTRA_ORDER);
+
+        Log.i(TAG, "URI: " + uri);
+        Log.i(TAG, "Projection: " + projection);
+        Log.i(TAG, "Selection: " + selection);
+
+        try {
+            Cursor c = getContentResolver().query(uri, parseProjection(projection), selection, null,
+                    order);
+            if (c == null) {
+                Log.i(TAG, "(no results)");
+                return;
+            }
+            StringBuilder sb = new StringBuilder();
+            try {
+                Log.i(TAG, "Result count: " + c.getCount());
+
+                final int columnCount = c.getColumnCount();
+
+                sb.setLength(0);
+                for (int i = 0; i < columnCount; i++) {
+                    add(sb, c.getColumnName(i));
+                }
+                Log.i(TAG, sb.toString());
+
+                c.moveToPosition(-1);
+                while (c.moveToNext()) {
+                    sb.setLength(0);
+                    for (int i = 0; i < columnCount; i++) {
+                        add(sb, c.getString(i));
+                    }
+                    Log.i(TAG, sb.toString());
+                }
+            } finally {
+                c.close();
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Exeption while executing query", e);
+        }
+    }
+
+    private StringBuilder add(StringBuilder sb, String s) {
+        if (sb.length() > 0) {
+            sb.append(SEPARATOR);
+        }
+        sb.append(s == null ? NULL_STRING : s);
+        return sb;
+    }
+
+    private static String[] parseProjection(String projectionString) {
+        if (TextUtils.isEmpty(projectionString)) {
+            return null; // all columns
+        }
+        final String[] columns = projectionString.split(",");
+        if (columns.length == 0) {
+            return null; // all columns
+        }
+        return columns;
+    }
+}
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index 555b339..c6577b8 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -90,6 +90,8 @@
         ACTION_GET_CONTENT_POSTAL,
         ACTION_GET_CONTENT_POSTAL_LEGACY,
         ACTION_INSERT_OR_EDIT,
+        ACTION_INSERT_OR_EDIT_PHONE_NUMBER,
+        ACTION_INSERT_OR_EDIT_EMAIL_ADDRESS,
         ACTION_SEARCH_CALL,
         ACTION_SEARCH_CONTACT,
         ACTION_SEARCH_EMAIL,
@@ -275,6 +277,20 @@
                 startActivity(intent);
                 break;
             }
+            case ACTION_INSERT_OR_EDIT_PHONE_NUMBER: {
+                Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+                intent.setType(Contacts.CONTENT_ITEM_TYPE);
+                intent.putExtra(Insert.PHONE, "5123456789");
+                startActivity(intent);
+                break;
+            }
+            case ACTION_INSERT_OR_EDIT_EMAIL_ADDRESS: {
+                Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+                intent.setType(Contacts.CONTENT_ITEM_TYPE);
+                intent.putExtra(Insert.EMAIL, "android@android.com");
+                startActivity(intent);
+                break;
+            }
             case ACTION_SEARCH_CALL: {
                 Intent intent = new Intent(Intent.ACTION_SEARCH);
                 intent.putExtra(SearchManager.ACTION_MSG, "call");
@@ -290,11 +306,15 @@
                 break;
             }
             case ACTION_SEARCH_EMAIL: {
-                Toast.makeText(this, "Unsupported", Toast.LENGTH_SHORT).show();
+                Intent intent = new Intent(Intent.ACTION_SEARCH);
+                intent.putExtra(Insert.EMAIL, "a");
+                startSearchResultActivity(intent);
                 break;
             }
             case ACTION_SEARCH_PHONE: {
-                Toast.makeText(this, "Unsupported", Toast.LENGTH_SHORT).show();
+                Intent intent = new Intent(Intent.ACTION_SEARCH);
+                intent.putExtra(Insert.PHONE, "800");
+                startSearchResultActivity(intent);
                 break;
             }
             case SEARCH_SUGGESTION_CLICKED_CALL_BUTTON: {
diff --git a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java b/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
index 189cd1f..3fc44cb 100644
--- a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
+++ b/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
@@ -32,11 +32,12 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
+import android.widget.CheckBox;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import java.security.SecureRandom;
+import java.util.Random;
 
 /**
  * Activity to add entries to the call log for testing.
@@ -46,9 +47,15 @@
     /** Identifier of the loader for querying the call log. */
     private static final int CALLLOG_LOADER_ID = 1;
 
+    private static final Random RNG = new Random();
+    private static final int[] CALL_TYPES = new int[] {
+        Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.MISSED_TYPE,
+    };
+
     private TextView mNumberTextView;
     private Button mAddButton;
     private ProgressBar mProgressBar;
+    private CheckBox mUseRandomNumbers;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -57,12 +64,23 @@
         mNumberTextView = (TextView) findViewById(R.id.number);
         mAddButton = (Button) findViewById(R.id.add);
         mProgressBar = (ProgressBar) findViewById(R.id.progress);
+        mUseRandomNumbers = (CheckBox) findViewById(R.id.use_random_numbers);
 
         mAddButton.setOnClickListener(new View.OnClickListener(){
             @Override
             public void onClick(View v) {
-                int count = Integer.parseInt(mNumberTextView.getText().toString());
-                addEntriesToCallLog(count);
+                int count;
+                try {
+                    count = Integer.parseInt(mNumberTextView.getText().toString());
+                    if (count > 100) {
+                        throw new RuntimeException("Number too large.  Max=100");
+                    }
+                } catch (RuntimeException e) {
+                    Toast.makeText(FillCallLogTestActivity.this, e.toString(), Toast.LENGTH_LONG)
+                            .show();
+                    return;
+                }
+                addEntriesToCallLog(count, mUseRandomNumbers.isChecked());
                 mNumberTextView.setEnabled(false);
                 mAddButton.setEnabled(false);
                 mProgressBar.setProgress(0);
@@ -78,8 +96,13 @@
      *
      * @param count the number of entries to add
      */
-    private void addEntriesToCallLog(final int count) {
-        getLoaderManager().initLoader(CALLLOG_LOADER_ID, null, new CallLogLoaderListener(count));
+    private void addEntriesToCallLog(final int count, boolean useRandomNumbers) {
+        if (useRandomNumbers) {
+            addRandomNumbers(count);
+        } else {
+            getLoaderManager().initLoader(CALLLOG_LOADER_ID, null,
+                    new CallLogLoaderListener(count));
+        }
     }
 
     /**
@@ -133,6 +156,21 @@
         return values;
     }
 
+    private void addRandomNumbers(int count) {
+        ContentValues[] values = new ContentValues[count];
+        for (int i = 0; i < count; i++) {
+            values[i] = new ContentValues();
+            values[i].put(Calls.NUMBER, generateRandomNumber());
+            values[i].put(Calls.DATE, System.currentTimeMillis()); // Will be randomized later
+            values[i].put(Calls.DURATION, 1); // Will be overwritten later
+        }
+        new AsyncCallLogInserter(values).execute(new Void[0]);
+    }
+
+    private static String generateRandomNumber() {
+        return String.format("5%09d", RNG.nextInt(1000000000));
+    }
+
     /** Invokes {@link AsyncCallLogInserter} when the call log has loaded. */
     private final class CallLogLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
         /** The number of items to insert when done. */
@@ -151,31 +189,29 @@
 
         @Override
         public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-            Log.d(TAG, "onLoadFinished");
-            // Stores the content values associated with the various entries in call log.
-            // It needs at most as many entries as the number of entries in the templates, or the
-            // number of entries to insert, whichever is smaller.
-            int dataCount = Math.min(data.getCount(), mCount);
+            try {
+                Log.d(TAG, "onLoadFinished");
 
-            if (dataCount == 0) {
-                // If there are no entries in the call log, we cannot generate new ones.
-                insertCompleted(getString(R.string.noLogEntriesToast));
-                return;
-            }
-
-            ContentValues[] values = new ContentValues[dataCount];
-            for (int index = 0; index < dataCount; ++index) {
-                if (!data.moveToNext()) {
-                    throw new IllegalStateException("unexpected end of data");
+                if (data.getCount() == 0) {
+                    // If there are no entries in the call log, we cannot generate new ones.
+                    insertCompleted(getString(R.string.noLogEntriesToast));
+                    return;
                 }
-                if (values[index] == null) {
-                    // Create the content value at most once.
+
+                data.moveToPosition(-1);
+
+                ContentValues[] values = new ContentValues[mCount];
+                for (int index = 0; index < mCount; ++index) {
+                    if (!data.moveToNext()) {
+                        data.moveToFirst();
+                    }
                     values[index] = createContentValuesFromCursor(data);
                 }
+                new AsyncCallLogInserter(values).execute(new Void[0]);
+            } finally {
+                // This is a one shot loader.
+                getLoaderManager().destroyLoader(CALLLOG_LOADER_ID);
             }
-            new AsyncCallLogInserter(mCount, values).execute(new Void[0]);
-            // This is a one shot loader.
-            getLoaderManager().destroyLoader(CALLLOG_LOADER_ID);
         }
 
         @Override
@@ -185,14 +221,10 @@
     /** Inserts a given number of entries in the call log based on the values given. */
     private final class AsyncCallLogInserter extends AsyncTask<Void, Integer, Integer> {
         /** The number of items to insert. */
-        private final int mCount;
         private final ContentValues[] mValues;
-        private final SecureRandom mRandom;
 
-        public AsyncCallLogInserter(int count, ContentValues[] values) {
-            mCount = count;
+        public AsyncCallLogInserter(ContentValues[] values) {
             mValues = values;
-            mRandom = new SecureRandom();
         }
 
         @Override
@@ -221,19 +253,33 @@
         private Integer insertIntoCallLog() {
             int inserted = 0;
 
-            for (int index = 0; index < mCount; ++index) {
-                ContentValues values = mValues[index % mValues.length];
+            for (int index = 0; index < mValues.length; ++index) {
+                ContentValues values = mValues[index];
                 // These should not be set.
                 values.putNull(Calls._ID);
                 // Add some randomness to the date. For each new entry being added, add an extra
                 // day to the maximum possible offset from the original.
                 values.put(Calls.DATE,
                         values.getAsLong(Calls.DATE)
-                        - mRandom.nextInt(24 * 60 * 60 * (index + 1)) * 1000L);
+                        - RNG.nextInt(24 * 60 * 60 * (index + 1)) * 1000L);
                 // Add some randomness to the duration.
                 if (values.getAsLong(Calls.DURATION) > 0) {
-                    values.put(Calls.DURATION, mRandom.nextInt(30 * 60 * 60 * 1000));
+                    values.put(Calls.DURATION, RNG.nextInt(30 * 60 * 60 * 1000));
                 }
+
+                // Overwrite type.
+                values.put(Calls.TYPE, CALL_TYPES[RNG.nextInt(CALL_TYPES.length)]);
+
+                // Clear cached columns.
+                values.putNull(Calls.CACHED_FORMATTED_NUMBER);
+                values.putNull(Calls.CACHED_LOOKUP_URI);
+                values.putNull(Calls.CACHED_MATCHED_NUMBER);
+                values.putNull(Calls.CACHED_NAME);
+                values.putNull(Calls.CACHED_NORMALIZED_NUMBER);
+                values.putNull(Calls.CACHED_NUMBER_LABEL);
+                values.putNull(Calls.CACHED_NUMBER_TYPE);
+                values.putNull(Calls.CACHED_PHOTO_ID);
+
                 // Insert into the call log the newly generated entry.
                 ContentProviderClient contentProvider =
                         getContentResolver().acquireContentProviderClient(
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
index 51c665f..10682c1 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
@@ -18,6 +18,7 @@
 
 import com.android.contacts.ContactPhotoManager;
 
+import android.graphics.Bitmap;
 import android.net.Uri;
 import android.widget.ImageView;
 
@@ -27,15 +28,15 @@
  */
 public class MockContactPhotoManager extends ContactPhotoManager {
     @Override
-    public void loadPhoto(ImageView view, long photoId, boolean hires, boolean darkTheme,
+    public void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
             DefaultImageProvider defaultProvider) {
-        defaultProvider.applyDefaultImage(view, hires, darkTheme);
+        defaultProvider.applyDefaultImage(view, -1, darkTheme);
     }
 
     @Override
-    public void loadPhoto(ImageView view, Uri photoUri, boolean hires, boolean darkTheme,
+    public void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme,
             DefaultImageProvider defaultProvider) {
-        defaultProvider.applyDefaultImage(view, hires, darkTheme);
+        defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme);
     }
 
     @Override
@@ -56,6 +57,10 @@
     }
 
     @Override
+    public void cacheBitmap(Uri photoUri, Bitmap bitmap, byte[] photoBytes) {
+    }
+
+    @Override
     public void preloadPhotosInBackground() {
     }
 }
diff --git a/tests/src/com/android/contacts/util/BitmapUtilTests.java b/tests/src/com/android/contacts/util/BitmapUtilTests.java
new file mode 100644
index 0000000..554fc97
--- /dev/null
+++ b/tests/src/com/android/contacts/util/BitmapUtilTests.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2012 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.contacts.util;
+
+import android.graphics.Bitmap;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Tests for {@link BitmapUtil}.
+ */
+@SmallTest
+public class BitmapUtilTests extends AndroidTestCase {
+    public void testGetSmallerExtentFromBytes1() throws Exception {
+        assertEquals(100, BitmapUtil.getSmallerExtentFromBytes(createJpegRawData(100, 100)));
+        assertEquals(100, BitmapUtil.getSmallerExtentFromBytes(createPngRawData(100, 100)));
+    }
+
+    public void testGetSmallerExtentFromBytes2() throws Exception {
+        assertEquals(50, BitmapUtil.getSmallerExtentFromBytes(createJpegRawData(200, 50)));
+        assertEquals(50, BitmapUtil.getSmallerExtentFromBytes(createPngRawData(200, 50)));
+    }
+
+    public void testGetSmallerExtentFromBytes3() throws Exception {
+        assertEquals(40, BitmapUtil.getSmallerExtentFromBytes(createJpegRawData(40, 150)));
+        assertEquals(40, BitmapUtil.getSmallerExtentFromBytes(createPngRawData(40, 150)));
+    }
+
+    public void testFindOptimalSampleSizeExact() throws Exception {
+        assertEquals(1, BitmapUtil.findOptimalSampleSize(512, 512));
+    }
+
+    public void testFindOptimalSampleSizeBigger() throws Exception {
+        assertEquals(1, BitmapUtil.findOptimalSampleSize(512, 1024));
+    }
+
+    public void testFindOptimalSampleSizeSmaller1() throws Exception {
+        assertEquals(2, BitmapUtil.findOptimalSampleSize(512, 256));
+    }
+
+    public void testFindOptimalSampleSizeSmaller2() throws Exception {
+        assertEquals(2, BitmapUtil.findOptimalSampleSize(512, 230));
+    }
+
+    public void testFindOptimalSampleSizeSmaller3() throws Exception {
+        assertEquals(2, BitmapUtil.findOptimalSampleSize(512, 129));
+    }
+
+    public void testFindOptimalSampleSizeSmaller4() throws Exception {
+        assertEquals(4, BitmapUtil.findOptimalSampleSize(512, 128));
+    }
+
+    public void testFindOptimalSampleSizeUnknownOriginal() throws Exception {
+        assertEquals(1, BitmapUtil.findOptimalSampleSize(-1, 128));
+    }
+
+    public void testFindOptimalSampleSizeUnknownTarget() throws Exception {
+        assertEquals(1, BitmapUtil.findOptimalSampleSize(128, -1));
+    }
+
+    public void testDecodeWithSampleSize1() throws IOException {
+        assertBitmapSize(128, 64, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(128, 64), 1));
+        assertBitmapSize(128, 64, BitmapUtil.decodeBitmapFromBytes(createPngRawData(128, 64), 1));
+    }
+
+    public void testDecodeWithSampleSize2() throws IOException {
+        assertBitmapSize(64, 32, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(128, 64), 2));
+        assertBitmapSize(64, 32, BitmapUtil.decodeBitmapFromBytes(createPngRawData(128, 64), 2));
+    }
+
+    public void testDecodeWithSampleSize2a() throws IOException {
+        assertBitmapSize(25, 20, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(50, 40), 2));
+        assertBitmapSize(25, 20, BitmapUtil.decodeBitmapFromBytes(createPngRawData(50, 40), 2));
+    }
+
+    public void testDecodeWithSampleSize4() throws IOException {
+        assertBitmapSize(32, 16, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(128, 64), 4));
+        assertBitmapSize(32, 16, BitmapUtil.decodeBitmapFromBytes(createPngRawData(128, 64), 4));
+    }
+
+    private void assertBitmapSize(int expectedWidth, int expectedHeight, Bitmap bitmap) {
+        assertEquals(expectedWidth, bitmap.getWidth());
+        assertEquals(expectedHeight, bitmap.getHeight());
+    }
+
+    private byte[] createJpegRawData(int sourceWidth, int sourceHeight) throws IOException {
+        return createRawData(Bitmap.CompressFormat.JPEG, sourceWidth, sourceHeight);
+    }
+
+    private byte[] createPngRawData(int sourceWidth, int sourceHeight) throws IOException {
+        return createRawData(Bitmap.CompressFormat.PNG, sourceWidth, sourceHeight);
+    }
+
+    private byte[] createRawData(Bitmap.CompressFormat format, int sourceWidth,
+            int sourceHeight) throws IOException {
+        // Create a temp bitmap as our source
+        Bitmap b = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        b.compress(format, 50, outputStream);
+        final byte[] data = outputStream.toByteArray();
+        outputStream.close();
+        return data;
+    }
+}
diff --git a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java b/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
index 960f0bf..e68c0ec 100644
--- a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
+++ b/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
@@ -16,10 +16,6 @@
 
 package com.android.contacts.util;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 
 import android.app.Instrumentation;
@@ -65,7 +61,8 @@
 
     /** Create a fake AsyncTaskExecutor for use in unit tests. */
     public FakeAsyncTaskExecutor(Instrumentation instrumentation) {
-        mInstrumentation = checkNotNull(instrumentation);
+        Assert.assertNotNull(instrumentation);
+        mInstrumentation = instrumentation;
     }
 
     /** Encapsulates an async task with the params and identifier it was submitted with. */
@@ -116,8 +113,9 @@
         @Override
         public void execute(Runnable command) {
             synchronized (mNextLock) {
+                Assert.assertNotNull(mNextTask);
                 mSubmittedTasks.add(new SubmittedTaskImpl(mNextIdentifier,
-                        command, checkNotNull(mNextTask)));
+                        command, mNextTask));
                 mNextIdentifier = null;
                 mNextTask = null;
             }
@@ -126,13 +124,14 @@
         public <T> AsyncTask<T, ?, ?> submit(Object identifier,
                 AsyncTask<T, ?, ?> task, T... params) {
             synchronized (mNextLock) {
-                checkState(mNextIdentifier == null);
-                checkState(mNextTask == null);
+                Assert.assertNull(mNextIdentifier);
+                Assert.assertNull(mNextTask);
                 mNextIdentifier = identifier;
-                mNextTask = checkNotNull(task, "Already had a valid task.\n"
+                Assert.assertNotNull("Already had a valid task.\n"
                         + "Are you calling AsyncTaskExecutor.submit(...) from within the "
                         + "onPreExecute() method of another task being submitted?\n"
-                        + "Sorry!  Not that's not supported.");
+                        + "Sorry!  Not that's not supported.", task);
+                mNextTask = task;
             }
             return task.executeOnExecutor(this, params);
         }
@@ -205,7 +204,7 @@
 
     private List<SubmittedTask> getSubmittedTasksByIdentifier(
             Object identifier, boolean remove) {
-        Preconditions.checkNotNull(identifier, "can't lookup tasks by 'null' identifier");
+        Assert.assertNotNull(identifier);
         List<SubmittedTask> results = Lists.newArrayList();
         synchronized (mLock) {
             Iterator<SubmittedTask> iter = mSubmittedTasks.iterator();
diff --git a/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java b/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java
index 319ba48..d8d8cf5 100644
--- a/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java
+++ b/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java
@@ -16,6 +16,10 @@
 
 package com.android.contacts.util;
 
+import com.android.contacts.util.StreamItemEntry;
+
+import android.content.Context;
+
 /**
  * Builder for {@link StreamItemEntry}s to make writing tests easier.
  */
@@ -58,8 +62,10 @@
         return this;
     }
 
-    public StreamItemEntry build() {
-        return new StreamItemEntry(mId, mText, mComment, mTimestamp, mAccountType, mAccountName,
-                mDataSet, mResPackage, mIconRes, mLabelRes);
+    public StreamItemEntry build(Context context) {
+        StreamItemEntry ret = StreamItemEntry.createForTest(mId, mText, mComment, mTimestamp,
+                mAccountType, mAccountName, mDataSet, mResPackage, mIconRes, mLabelRes);
+        ret.decodeHtml(context);
+        return ret;
     }
 }
\ No newline at end of file