Merge "Fix broken touch-interception in ContactDetailFragmentCarousel."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a1f8b4a..56c7b9f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -407,7 +407,7 @@
             android:launchMode="singleTop"
             android:excludeFromRecents="true"
             android:noHistory="true"
-            android:taskAffinity="android.task.quickcontact"
+            android:taskAffinity=""
             android:windowSoftInputMode="stateUnchanged">
 
             <intent-filter>
@@ -474,7 +474,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" />
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/menu-sw580dp-w720dp/people_options.xml b/res/menu-sw580dp-w720dp/people_options.xml
index 5f939cc..6974d80 100644
--- a/res/menu-sw580dp-w720dp/people_options.xml
+++ b/res/menu-sw580dp-w720dp/people_options.xml
@@ -43,6 +43,10 @@
         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:orderInCategory="3"
         android:title="@string/menu_accounts" />
diff --git a/res/menu-sw580dp/people_options.xml b/res/menu-sw580dp/people_options.xml
index c8c114a..07d9c94 100644
--- a/res/menu-sw580dp/people_options.xml
+++ b/res/menu-sw580dp/people_options.xml
@@ -46,6 +46,10 @@
         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:orderInCategory="3"
         android:title="@string/menu_accounts" />
diff --git a/res/menu/people_options.xml b/res/menu/people_options.xml
index 0c82f99..4003038 100644
--- a/res/menu/people_options.xml
+++ b/res/menu/people_options.xml
@@ -41,6 +41,10 @@
         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:title="@string/menu_accounts" />
 
diff --git a/res/menu/phone_favorite_options.xml b/res/menu/phone_favorite_options.xml
index ac67d6e..e37759c 100644
--- a/res/menu/phone_favorite_options.xml
+++ b/res/menu/phone_favorite_options.xml
@@ -19,6 +19,10 @@
         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:title="@string/menu_accounts" />
 </menu>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4c02c94..bfc9631 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Stemboodskap"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 2cedd03..d316507 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -151,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"የጥሪ ማስታወሻ አጥራ"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"ሁሉም የጥሪ ማህደሮችህ ይሰረዛሉ፡፡"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"የጥሪ ምዝግብ ማስታወሻ በማጥራት ላይ…"</string>
+    <!-- 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">"የድምፅ መልዕክት"</string>
@@ -282,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"ይህን እርምጃ ለማስተናገድ ምንም መተግበሪያ አልተገኘም፡፡"</string>
     <string name="missing_name" msgid="8745511583852904385">"(ስም የለም)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"መለያዎች"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"ዕውቂያዎች አሳይ"</string>
     <string name="menu_import_export" msgid="26217871113229507">"አስመጣ/ላክ"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"ዕውቂያዎች አስመጣ/ላክ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index bd6c46b..ea5af0c 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -151,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"محو سجل المكالمات؟"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"سيتم حذف جميع سجلات المكالمات."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"جارٍ محو سجل المكالمات..."</string>
+    <!-- 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">"البريد الصوتي"</string>
@@ -282,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"لم يتم العثور على تطبيق يمكنه مباشرة هذا الإجراء."</string>
     <string name="missing_name" msgid="8745511583852904385">"(بلا اسم)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"الحسابات"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"جهات الاتصال التي يتم عرضها"</string>
     <string name="menu_import_export" msgid="26217871113229507">"استيراد/تصدير"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"استيراد/تصدير جهات اتصال"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index afb0c0e..613fd7c 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"Выдаліць з Выбранага"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Рэдагаваць"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Выдаліць"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ачысціць спіс выклікаў?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Усе вашы запісы выклікаў будуць выдалены."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Выдаленне гiсторыi выклiкаў..."</string>
+    <!-- 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">"Галасавая пошта"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Не знойдзена прыкладанне для гэтага дзеяння."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Без назвы)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Уліковыя запісы"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Паказаць кантакты"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Імпарт/экспарт"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Імпарт/экспарт кантактаў"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 2f8ecdb..da9a655 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"Премахване от любими"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Редактиране"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Изтриване"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Да се изчисти ли списъкът с обаждания?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Всичките ви записи на обажданията ще бъдат изтрити."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Списъкът с обаждания се изчиства..."</string>
+    <!-- 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">"Гласова поща"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Не бе намерено приложение за извършване на това действие."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Няма име)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Профили"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Контакти за показване"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Импортиране/Експортиране"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Импортиране/Експортиране на контакти"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 7f1983e..c325e2a 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Correu de veu"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 3366aaf..79f9c43 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Hlasová schránka"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index a901937..1fcb207 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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-nummer"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 36adf42..40c98b6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 620de1c..9c887a2 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -151,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Εκκαθάριση αρχείου;"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Όλα τα αρχεία κλήσεων θα διαγραφούν."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Εκκαθάριση αρχ. καταγραφής κλήσεων…"</string>
+    <!-- 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">"Αριθμός ΙΜΕΙ"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Αυτόματος τηλεφωνητής"</string>
@@ -282,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Δεν βρέθηκε εφαρμογή για τη διαχείριση αυτής της ενέργειας."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Χωρίς όνομα)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Λογαριασμοί"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Επαφές για εμφάνιση"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Εισαγωγή/Εξαγωγή"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Εισαγωγή/Εξαγωγή επαφών"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index ae1e793..c438d3c 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Voicemail"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 8bdecf7..fc29934 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Correo de voz"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 695f5cb..b733005 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Buzón de voz"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index bf0978e..6a9a266 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Kõnepost"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 583c19d..d3dcd8a 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"حذف از موارد دلخواه"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"ویرایش"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"حذف"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"گزارش تماس پاک شود؟"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"تمام سابقه تماس شما حذف خواهد شد."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"در حال پاک کردن گزارش تماس..."</string>
+    <!-- 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">"پست صوتی"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"برنامه‌ای برای انجام این عملکرد یافت نشد."</string>
     <string name="missing_name" msgid="8745511583852904385">"(بدون نام)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"حساب‌ها"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"مخاطبین جهت نمایش"</string>
     <string name="menu_import_export" msgid="26217871113229507">"وارد کردن/صادر کردن"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"وارد کردن/صادر کردن مخاطبین"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 057be46..7fea26c 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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-koodi"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Vastaaja"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 6f3337f..47936d1 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Code IMEI"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Messagerie vocale"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index e722f45..9bb07c2 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"पसंदीदा से निकालें"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"संपादित करें"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"हटाएं"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"कॉल लॉग साफ़ करें?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"आपके सभी कॉल रिकॉर्ड हटा दिए जाएंगे."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"कॉल लॉग साफ़ हो रहा है..."</string>
+    <!-- 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">"ध्वनिमेल"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"यह कार्यवाही प्रबंधित करने के लिए कोई एप्लिकेशन नहीं मिला."</string>
     <string name="missing_name" msgid="8745511583852904385">"(कोई नाम नहीं)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"खाते"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"प्रदर्शन के लिए संपर्क"</string>
     <string name="menu_import_export" msgid="26217871113229507">"आयात करें/निर्यात करें"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"संपर्क आयात/निर्यात करें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 90a9ce6..1bc2fb5f 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Govorna pošta"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 4da7367..ac8dc89 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Hangposta"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 56cef84..1d307fa 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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 kenalan"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"SMS kenalan"</string>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Kotak Pesan"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Kenalan 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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 61375de..50e2d72 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Segreteria"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index ada49ed..beeeaf6 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -151,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"לנקות את יומן השיחות?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"כל רשומות השיחה שלך יימחקו."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"מנקה את יומן השיחות..."</string>
+    <!-- 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">"דואר קולי"</string>
@@ -282,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"לא נמצא יישום שיכול לטפל בפעולה זו."</string>
     <string name="missing_name" msgid="8745511583852904385">"(ללא שם)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"חשבונות Google"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"אנשי קשר להצגה"</string>
     <string name="menu_import_export" msgid="26217871113229507">"ייבוא/ייצוא"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"יבא/יצא אנשי קשר"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index e06f7e8..b2ad898 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"お気に入りから削除"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"編集"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"削除"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"通話履歴を消しますか?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"すべての通話記録は削除されます。"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"通話履歴を消去しています..."</string>
+    <!-- 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">"ボイスメール"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"この操作を行うアプリが見つかりませんでした。"</string>
     <string name="missing_name" msgid="8745511583852904385">"(名前なし)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"アカウント"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"表示する連絡先"</string>
     <string name="menu_import_export" msgid="26217871113229507">"インポート/エクスポート"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"連絡先のインポート/エクスポート"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 785ae3a..47e7535 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"즐겨찾기에서 삭제"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"수정"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"삭제"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"통화기록을 지우시겠습니까?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"모든 통화 기록을 삭제합니다."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"통화기록을 지우는 중..."</string>
+    <!-- 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">"음성사서함"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"이 작업을 처리하는 앱을 찾을 수 없습니다."</string>
     <string name="missing_name" msgid="8745511583852904385">"(이름 없음)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"계정"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"표시할 연락처"</string>
     <string name="menu_import_export" msgid="26217871113229507">"가져오기/내보내기"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"주소록 가져오기/내보내기"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index bfd4aeb..26ae006 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Balso paštas"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 315a88b..ac81005 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Balss pasts"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index de613bd..1d1d680 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Mel suara"</string>
@@ -285,6 +290,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index d22dc0b..9c71726 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"Telefonsvarer"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 16aa2d9..2ac3259 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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-nummer"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index a6ceedc..901144f 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Numer MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Poczta głosowa"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index a6404ab..beecebc 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Correio de voz"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 8bc6f8c..2c6979a 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Correio de voz"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 66f9414..72373f9 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -202,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>
@@ -401,6 +407,8 @@
     <!-- 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) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 5e3ba7b..6f143cd 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Mesagerie vocală"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 81c8de5..87b6a8a 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -151,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Удаление данных"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Журнал звонков будет очищен."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Очистка списка вызовов..."</string>
+    <!-- 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">"Голосовая почта"</string>
@@ -282,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Действие не поддерживается ни в одном приложении."</string>
     <string name="missing_name" msgid="8745511583852904385">"Имя не указано"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Аккаунты"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Фильтр контактов"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Импорт/экспорт"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Импорт/экспорт контактов"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index d26a5fb..9be63a8 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Hlasová schránka"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 7644981..463bb7a 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -152,6 +152,12 @@
     <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>
+    <!-- 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">"Glasovna pošta"</string>
@@ -283,6 +289,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index b915a4f..42dca3e 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"Уклони из омиљених контаката"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"Измени"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"Избриши"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Обрисати евиденцију позива?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Све евиденције позива ће бити избрисане."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Брисање евиденције позива..."</string>
+    <!-- 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">"Говорна пошта"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Није пронађена ниједна апликација која би могла да изврши ову радњу."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Без имена)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Налози"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Контакти за приказ"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Увоз/извоз"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Увоз/извоз контаката"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index c0d5f8f..e170261 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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-kod"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Röstbrevlåda"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index db88e7c..da48e0d 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Barua ya sauti"</string>
@@ -285,6 +290,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index d3c5bb6..d72c0a9 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"ลบจากรายการโปรด"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"แก้ไข"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"ลบ"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"ล้างบันทึกการโทร"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"บันทึกการโทรทั้งหมดของคุณจะถูกลบออก"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"กำลังล้างบันทึกการโทร..."</string>
+    <!-- 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">"ข้อความเสียง"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
     <string name="missing_name" msgid="8745511583852904385">"(ไม่มีชื่อ)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"บัญชี"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"รายชื่อติดต่อที่จะแสดง"</string>
     <string name="menu_import_export" msgid="26217871113229507">"นำเข้า/ส่งออก"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"นำเข้า/ส่งออกผู้ติดต่อ"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 5d9c938..ed388cf 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Voicemail"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 2dade84..8c7480e 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Sesli Mesaj"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 469f899..947793e 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -151,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Очистити журнал викликів?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Усі записи викликів буде видалено."</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Очищення журналу викликів..."</string>
+    <!-- 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">"Голос. пошта"</string>
@@ -282,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"Не знайдено програму для обробки цієї дії."</string>
     <string name="missing_name" msgid="8745511583852904385">"(Без імені)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"Обл. записи"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"Контакти для показу"</string>
     <string name="menu_import_export" msgid="26217871113229507">"Імпорт або експорт"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"Імпорт/експорт контактів"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 874744f..64628e4 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -46,8 +46,7 @@
     <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>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <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>
+    <!-- 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">"Thư thoại"</string>
@@ -283,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3f0ed47..a3f5a5e 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"从收藏中删除"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"修改"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"删除"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"要清除通话记录吗?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"系统将删除您的所有通话记录。"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"正在清除通话记录..."</string>
+    <!-- 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">"移动通信国际识别码"</string>
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"语音信箱"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"未找到可处理此操作的应用。"</string>
     <string name="missing_name" msgid="8745511583852904385">"(无姓名)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"帐户"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"要显示的联系人"</string>
     <string name="menu_import_export" msgid="26217871113229507">"导入/导出"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"导入/导出联系人"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index b9cacf1..75d499f 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -46,8 +46,7 @@
     <string name="menu_removeStar" msgid="5844227078364227030">"從我的最愛中移除"</string>
     <string name="menu_editContact" msgid="9042415603857662633">"編輯"</string>
     <string name="menu_deleteContact" msgid="6788644058868189393">"刪除"</string>
-    <!-- no translation found for menu_copy (6108677035381940698) -->
-    <skip />
+    <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>
@@ -152,6 +151,12 @@
     <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"確定要清除通話記錄?"</string>
     <string name="clearCallLogConfirmation" msgid="5043563133171583152">"即將刪除您所有的通話記錄。"</string>
     <string name="clearCallLogProgress_title" msgid="8365943000154295771">"正在清除通話記錄…"</string>
+    <!-- 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">"語音留言"</string>
@@ -283,6 +288,8 @@
     <string name="quickcontact_missing_app" msgid="358168575340921552">"找不到可以處理這個動作的應用程式。"</string>
     <string name="missing_name" msgid="8745511583852904385">"(無姓名)"</string>
     <string name="menu_accounts" msgid="8499114602017077970">"帳戶"</string>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <string name="menu_contacts_filter" msgid="2165153460860262501">"要顯示的聯絡人"</string>
     <string name="menu_import_export" msgid="26217871113229507">"匯入/匯出"</string>
     <string name="dialog_import_export" msgid="4360648034889921624">"匯入/匯出聯絡人"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 0ceb87a..c6b3cfe 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -151,6 +151,12 @@
     <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>
+    <!-- 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">"I-MEID"</string>
     <string name="voicemail" msgid="3851469869202611441">"Ivoyisimeyili"</string>
@@ -282,6 +288,8 @@
     <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>
+    <!-- no translation found for menu_clear_frequents (7688250191932838833) -->
+    <skip />
     <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>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b030f43..c5d0703 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -433,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>
 
@@ -1002,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>
 
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index 17cd1e7..5f5c1cb 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -19,6 +19,7 @@
 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;
@@ -71,7 +72,7 @@
  * Loads a single Contact and all it constituent RawContacts.
  */
 public class ContactLoader extends AsyncTaskLoader<ContactLoader.Result> {
-    private static final String TAG = "ContactLoader";
+    private static final String TAG = ContactLoader.class.getSimpleName();
 
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -313,6 +314,13 @@
         }
 
         /**
+         * Instantiate a new EntityDeltaList for this contact.
+         */
+        public EntityDeltaList createEntityDeltaList() {
+            return EntityDeltaList.fromIterator(getEntities().iterator());
+        }
+
+        /**
          * Returns the contact ID.
          */
         @VisibleForTesting
@@ -419,16 +427,31 @@
          *         writable raw-contact, and false otherwise.
          */
         public boolean isWritableContact(final Context context) {
-            if (isDirectoryEntry()) return false;
+            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 rawContact : getEntities()) {
-                final ContentValues rawValues = rawContact.getEntityValues();
-                final String accountType = rawValues.getAsString(RawContacts.ACCOUNT_TYPE);
-                final String dataSet = rawValues.getAsString(RawContacts.DATA_SET);
-                final AccountType type = accountTypes.getAccountType(accountType, dataSet);
-                if (type != null && type.areContactsWritable()) return true;
+            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);
+                }
             }
-            return false;
+            // No writable raw-contact was found.
+            return -1;
         }
 
         public int getDirectoryExportSupport() {
@@ -1274,6 +1297,9 @@
      * new result will be delivered
      */
     public void upgradeToFullContact() {
+        // Everything requested already? Nothing to do, so let's bail out
+        if (mLoadGroupMetaData && mLoadInvitableAccountTypes && mLoadStreamItems) return;
+
         mLoadGroupMetaData = true;
         mLoadInvitableAccountTypes = true;
         mLoadStreamItems = true;
@@ -1323,6 +1349,6 @@
      * contact. If the next load is for a different contact, the cached result will be dropped
      */
     public void cacheResult() {
-        sCachedResult = mContact;
+        sCachedResult = new Result(mContact);
     }
 }
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 3fbca54..fdfd0f7 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -222,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);
@@ -290,8 +290,9 @@
      * @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, long rawContactId, String updatedPhotoPath) {
+            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,
@@ -306,8 +307,9 @@
      * @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<?> callbackActivity,
-            String callbackAction, Bundle updatedPhotos) {
+            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);
@@ -317,19 +319,20 @@
             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);
 
@@ -462,15 +465,17 @@
             }
         }
 
-        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);
+        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);
         }
-        callbackIntent.setData(lookupUri);
-
-        deliverCallback(callbackIntent);
     }
 
     /**
@@ -554,7 +559,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);
@@ -618,7 +623,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);
@@ -689,7 +694,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);
@@ -959,7 +964,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/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index 8d4cb5d..5981e9b 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -18,29 +18,31 @@
 
 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.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 com.android.contacts.ContactLoader;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsUtils;
 
-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,25 +51,38 @@
  * 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 {
+            mTempPhotoFile = ContactPhotoUtils.generateTempPhotoFile();
+            mTempPhotoUri = Uri.fromFile(mTempPhotoFile);
+
             Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
             intent.setType(Contacts.CONTENT_ITEM_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,94 @@
             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.PNG, 100, 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 ContactLoader.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 ContactLoader.Listener listener) {
+        final ContactLoader loader = new ContactLoader(this, contactUri);
+        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();
     }
 
     /**
-     * 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 98abfbc..f98e47b 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -78,17 +78,16 @@
  * 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.
  */
 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 +101,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 +171,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 +183,7 @@
     private final OnClickListener mDetailsButtonClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
-            if (mIsReadyOnly) {
+            if (mIsReadOnly) {
                 onSaveCompleted(true);
             } else {
                 doSaveAction();
@@ -250,7 +253,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 +286,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 +297,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);
@@ -420,9 +414,6 @@
                 return;
             }
             activityTarget.setEntityDeltaList(entityList);
-            activityTarget.findEditableRawContact();
-            activityTarget.parseExtras();
-            activityTarget.bindEditor();
         }
     }
 
@@ -477,12 +468,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;
@@ -500,7 +490,7 @@
                             // If there are no other contacts with this name,
                             // then display the name.
                             setDisplayName();
-                            onLoadDataFinished();
+                            showDialogContent();
                         }
                         break;
                     }
@@ -535,14 +525,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;
                     }
@@ -555,37 +545,35 @@
         }
     }
 
-    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 type.
+        mEntityDelta = mEntityDeltaList.getFirstWritableRawContact(this);
+        if (mEntityDelta == null) {
+            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);
             }
         }
-    }
 
-    public void parseExtras() {
-        if (mEditableAccountType == null || mState == null) {
-            return;
-        }
-        // 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);
-        }
+        bindEditor();
     }
 
     /**
@@ -593,19 +581,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;
         }
 
@@ -614,11 +601,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;
                     }
                 }
@@ -669,7 +656,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);
     }
 
@@ -682,14 +669,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;
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index ea9e116..1ccf32c 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -57,17 +57,8 @@
     /** Shows a toogle button for hiding/showing updates. Don't submit with true */
     private static final boolean DEBUG_TRANSITIONS = false;
 
-    /**
-     * 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";
-
     private ContactLoader.Result mContactData;
     private Uri mLookupUri;
-    private boolean mFinishActivityOnUpSelected;
 
     private ContactDetailLayoutController mContactDetailLayoutController;
     private ContactLoaderFragment mLoaderFragment;
@@ -94,9 +85,6 @@
             return;
         }
 
-        mFinishActivityOnUpSelected = getIntent().getBooleanExtra(
-                INTENT_KEY_FINISH_ACTIVITY_ON_UP_SELECTED, false);
-
         setContentView(R.layout.contact_detail_activity);
 
         mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
@@ -309,24 +297,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/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index ae8fe09..6f13924 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -569,7 +569,7 @@
             Log.d(TAG, "onStart(). current position: " + mPageChangeListener.getCurrentPosition()
                     + ". Reset all menu visibility state.");
         }
-        updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER);
+        updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER && !mInSearchUi);
         for (int i = 0; i < TAB_INDEX_COUNT; i++) {
             sendFragmentVisibilityChange(i, i == currentPosition);
         }
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index 6c36b5d..6562278 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);
         }
 
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 5915a7a..0283e06 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;
@@ -1055,12 +1056,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);
             }
         }
@@ -1390,6 +1385,7 @@
             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);
 
@@ -1398,22 +1394,27 @@
             addGroupMenu = menu.findItem(R.id.menu_custom_add_group);
         }
 
+        final MenuItem clearFrequentsMenu = menu.findItem(R.id.menu_clear_frequents);
+
         final boolean isSearchMode = mActionBarAdapter.isSearchMode();
         if (isSearchMode) {
             addContactMenu.setVisible(false);
             addGroupMenu.setVisible(false);
             contactsFilterMenu.setVisible(false);
+            clearFrequentsMenu.setVisible(false);
         } else {
             switch (mActionBarAdapter.getCurrentTab()) {
                 case TabState.FAVORITES:
                     addContactMenu.setVisible(false);
                     addGroupMenu.setVisible(false);
                     contactsFilterMenu.setVisible(false);
+                    clearFrequentsMenu.setVisible(hasFrequents());
                     break;
                 case TabState.ALL:
                     addContactMenu.setVisible(true);
                     addGroupMenu.setVisible(false);
                     contactsFilterMenu.setVisible(true);
+                    clearFrequentsMenu.setVisible(false);
                     break;
                 case TabState.GROUPS:
                     // Do not display the "new group" button if no accounts are available
@@ -1424,6 +1425,7 @@
                     }
                     addContactMenu.setVisible(false);
                     contactsFilterMenu.setVisible(false);
+                    clearFrequentsMenu.setVisible(false);
                     break;
             }
         }
@@ -1437,6 +1439,18 @@
         return true;
     }
 
+    /**
+     * Returns whether there are any frequently contacted people being displayed
+     * @return
+     */
+    private boolean hasFrequents() {
+        if (PhoneCapabilityTester.isUsingTwoPanes(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) {
@@ -1504,6 +1518,10 @@
                 ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable());
                 return true;
             }
+            case R.id.menu_clear_frequents: {
+                ClearFrequentsDialog.show(getFragmentManager());
+                return true;
+            }
             case R.id.menu_accounts: {
                 final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
                 intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
diff --git a/src/com/android/contacts/activities/PhotoSelectionActivity.java b/src/com/android/contacts/activities/PhotoSelectionActivity.java
index d76af25..d443782 100644
--- a/src/com/android/contacts/activities/PhotoSelectionActivity.java
+++ b/src/com/android/contacts/activities/PhotoSelectionActivity.java
@@ -449,45 +449,36 @@
     }
 
     private final class PhotoHandler extends PhotoSelectionHandler {
-        private PhotoHandler(Context context, View photoView, int photoMode,
-                EntityDeltaList state) {
-            super(context, photoView, photoMode, mIsDirectoryContact, state);
-            setListener(new PhotoListener(context, mIsProfile));
+        private 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, File photoFile) {
+            mSubActivityInProgress = true;
+            mCurrentPhotoFile = photoFile;
+            PhotoSelectionActivity.this.startActivityForResult(intent, requestCode);
         }
 
         private final class PhotoListener extends PhotoActionListener {
-            @SuppressWarnings("hiding")
-            private final boolean mIsProfile;
-            private final Context mContext;
-
-            private PhotoListener(Context context, boolean isProfile) {
-                mContext = context;
-                mIsProfile = isProfile;
-            }
-
-            @Override
-            public void startTakePhotoActivity(Intent intent, int requestCode, File photoFile) {
-                mSubActivityInProgress = true;
-                mCurrentPhotoFile = photoFile;
-                startActivityForResult(intent, requestCode);
-            }
-
-            @Override
-            public void startPickFromGalleryActivity(Intent intent, int requestCode,
-                    File photoFile) {
-                mSubActivityInProgress = true;
-                mCurrentPhotoFile = photoFile;
-                startActivityForResult(intent, requestCode);
-            }
 
             @Override
             public void onPhotoSelected(Bitmap bitmap) {
                 EntityDeltaList delta = getDeltaForAttachingPhotoToContact();
                 long rawContactId = getWritableEntityId();
                 String filePath = mCurrentPhotoFile.getAbsolutePath();
-                Intent intent = ContactSaveService.createSaveContactIntent(mContext, delta,
-                        "", 0, mIsProfile, PhotoSelectionActivity.class,
-                        ContactEditorActivity.ACTION_SAVE_COMPLETED, rawContactId, filePath);
+                Intent intent = ContactSaveService.createSaveContactIntent(
+                        mContext, delta, "", 0, mIsProfile, null, null, rawContactId, filePath);
                 startService(intent);
                 finish();
             }
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 48a299d..603d2fa 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -1943,8 +1943,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);
diff --git a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
index 13f5970..b674dc0 100644
--- a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
+++ b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
@@ -63,8 +63,7 @@
         @Override
         public void onClick(View v) {
             // Assemble the intent.
-            EntityDeltaList delta = EntityDeltaList.fromIterator(
-                    mContactData.getEntities().iterator());
+            EntityDeltaList delta = mContactData.createEntityDeltaList();
 
             // Find location and bounds of target view, adjusting based on the
             // assumed local density.
diff --git a/src/com/android/contacts/detail/PhotoSelectionHandler.java b/src/com/android/contacts/detail/PhotoSelectionHandler.java
index 1423c65..e11a054 100644
--- a/src/com/android/contacts/detail/PhotoSelectionHandler.java
+++ b/src/com/android/contacts/detail/PhotoSelectionHandler.java
@@ -24,6 +24,7 @@
 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;
@@ -35,7 +36,6 @@
 import android.graphics.BitmapFactory;
 import android.media.MediaScannerConnection;
 import android.net.Uri;
-import android.os.Environment;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.DisplayPhoto;
 import android.provider.ContactsContract.RawContacts;
@@ -46,38 +46,26 @@
 import android.widget.ListPopupWindow;
 import android.widget.PopupWindow.OnDismissListener;
 import android.widget.Toast;
-
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
 
 /**
  * Handles displaying a photo selection popup for a given photo view and dealing with the results
  * that come back.
  */
-public class PhotoSelectionHandler implements OnClickListener {
+public abstract class PhotoSelectionHandler implements OnClickListener {
 
     private static final String TAG = PhotoSelectionHandler.class.getSimpleName();
 
-    private static final File PHOTO_DIR = new File(
-            Environment.getExternalStorageDirectory() + "/DCIM/Camera");
-
-    private static final String PHOTO_DATE_FORMAT = "'IMG'_yyyyMMdd_HHmmss";
-
     private static final int REQUEST_CODE_CAMERA_WITH_DATA = 1001;
     private static final int REQUEST_CODE_PHOTO_PICKED_WITH_DATA = 1002;
 
-    private final Context mContext;
+    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;
-    private AccountType mWritableAccount;
-    private PhotoActionListener mListener;
 
     public PhotoSelectionHandler(Context context, View photoView, int photoMode,
             boolean isDirectoryContact, EntityDeltaList state) {
@@ -95,24 +83,19 @@
         }
     }
 
-    public PhotoActionListener getListener() {
-        return mListener;
-    }
-
-    public void setListener(PhotoActionListener listener) {
-        mListener = listener;
-    }
+    public abstract PhotoActionListener getListener();
 
     @Override
     public void onClick(View v) {
-        if (mListener != null) {
+        final PhotoActionListener listener = getListener();
+        if (listener != null) {
             if (getWritableEntityIndex() != -1) {
                 mPopup = PhotoActionPopup.createPopupMenu(
-                        mContext, mPhotoView, mListener, mPhotoMode);
+                        mContext, mPhotoView, listener, mPhotoMode);
                 mPopup.setOnDismissListener(new OnDismissListener() {
                     @Override
                     public void onDismiss() {
-                        mListener.onPhotoSelectionDismissed();
+                        listener.onPhotoSelectionDismissed();
                     }
                 });
                 mPopup.show();
@@ -129,16 +112,17 @@
      * @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) {
                 case REQUEST_CODE_PHOTO_PICKED_WITH_DATA: {
                     Bitmap bitmap = BitmapFactory.decodeFile(
-                            mListener.getCurrentPhotoFile().getAbsolutePath());
-                    mListener.onPhotoSelected(bitmap);
+                            listener.getCurrentPhotoFile().getAbsolutePath());
+                    listener.onPhotoSelected(bitmap);
                     return true;
                 }
                 case REQUEST_CODE_CAMERA_WITH_DATA: {
-                    doCropPhoto(mListener.getCurrentPhotoFile());
+                    doCropPhoto(listener.getCurrentPhotoFile());
                     return true;
                 }
             }
@@ -152,25 +136,8 @@
      */
     private int getWritableEntityIndex() {
         // Directory entries are non-writable.
-        if (mIsDirectoryContact) {
-            return -1;
-        }
-
-        // Find the first writable entity.
-        int entityIndex = 0;
-        for (EntityDelta delta : mState) {
-            ContentValues entityValues = delta.getValues().getCompleteValues();
-            String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
-            String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
-            AccountType accountType = AccountTypeManager.getInstance(mContext).getAccountType(
-                    type, dataSet);
-            if (accountType.areContactsWritable()) {
-                mWritableAccount = accountType;
-                return entityIndex;
-            }
-            entityIndex++;
-        }
-        return -1;
+        if (mIsDirectoryContact) return -1;
+        return mState.indexOfFirstWritableRawContact(mContext);
     }
 
     /**
@@ -187,7 +154,6 @@
      * 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.
-     * @param bitmap The photo to use.
      * @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.
@@ -196,10 +162,18 @@
         // Find the first writable entity.
         int writableEntityIndex = getWritableEntityIndex();
         if (writableEntityIndex != -1) {
-            // Note - guaranteed to have contact data if we have a writable entity index.
-            EntityDelta delta = mState.get(writableEntityIndex);
-            ValuesDelta child = EntityModifier.ensureKindExists(
-                    delta, mWritableAccount, Photo.CONTENT_ITEM_TYPE);
+            // 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);
 
@@ -208,6 +182,9 @@
         return null;
     }
 
+    /** Used by subclasses to delegate to their enclosing Activity or Fragment. */
+    protected abstract void startPhotoActivity(Intent intent, int requestCode, File photoFile);
+
     /**
      * Sends a newly acquired photo to Gallery for cropping
      */
@@ -222,22 +199,33 @@
 
             // Launch gallery to crop the photo
             final Intent intent = getCropImageIntent(f);
-            mListener.startPickFromGalleryActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, f);
+            startPhotoActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, f);
         } catch (Exception e) {
             Log.e(TAG, "Cannot crop image", e);
             Toast.makeText(mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
         }
     }
 
-    private String getPhotoFileName() {
-        Date date = new Date(System.currentTimeMillis());
-        SimpleDateFormat dateFormat = new SimpleDateFormat(PHOTO_DATE_FORMAT);
-        return dateFormat.format(date) + ".jpg";
+    /**
+     * 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(File photoFile) {
+        final Intent intent = getTakePhotoIntent(photoFile);
+        startPhotoActivity(intent, REQUEST_CODE_CAMERA_WITH_DATA, photoFile);
     }
 
-    private File getPhotoFile() {
-        PHOTO_DIR.mkdirs();
-        return new File(PHOTO_DIR, getPhotoFileName());
+    /**
+     * 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(File photoFile) {
+        final Intent intent = getPhotoPickIntent(photoFile);
+        startPhotoActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, photoFile);
     }
 
     private int getPhotoPickSize() {
@@ -308,9 +296,7 @@
         public void onTakePhotoChosen() {
             try {
                 // Launch camera to take photo for selected contact
-                File f = getPhotoFile();
-                final Intent intent = getTakePhotoIntent(f);
-                startTakePhotoActivity(intent, REQUEST_CODE_CAMERA_WITH_DATA, f);
+                startTakePhotoActivity(ContactPhotoUtils.generateTempPhotoFile());
             } catch (ActivityNotFoundException e) {
                 Toast.makeText(mContext, R.string.photoPickerNotFoundText,
                         Toast.LENGTH_LONG).show();
@@ -321,9 +307,7 @@
         public void onPickFromGalleryChosen() {
             try {
                 // Launch picker to choose photo for selected contact
-                File f = getPhotoFile();
-                final Intent intent = getPhotoPickIntent(f);
-                startPickFromGalleryActivity(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA, f);
+                startPickFromGalleryActivity(ContactPhotoUtils.generateTempPhotoFile());
             } catch (ActivityNotFoundException e) {
                 Toast.makeText(mContext, R.string.photoPickerNotFoundText,
                         Toast.LENGTH_LONG).show();
@@ -331,28 +315,6 @@
         }
 
         /**
-         * Should initiate an activity to take a photo using the camera.
-         * @param intent The image capture intent.
-         * @param requestCode The request code to use, suitable for handling by
-         *     {@link PhotoSelectionHandler#handlePhotoActivityResult(int, int, Intent)}.
-         * @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()}.
-         */
-        public abstract void startTakePhotoActivity(Intent intent, int requestCode, File photoFile);
-
-        /**
-         * Should initiate an activity pick a photo from the gallery.
-         * @param intent The image capture intent.
-         * @param requestCode The request code to use, suitable for handling by
-         * @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)}.
-         */
-        public abstract void startPickFromGalleryActivity(Intent intent, int requestCode,
-                File photoFile);
-
-        /**
          * Called when the user has completed selection of a photo.
          * @param bitmap The selected and cropped photo.
          */
diff --git a/src/com/android/contacts/dialog/ClearFrequentsDialog.java b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
new file mode 100644
index 0000000..ecb1a27
--- /dev/null
+++ b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
@@ -0,0 +1,67 @@
+/*
+ * 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 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;
+                    }
+                };
+                task.execute();
+            }
+        };
+        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/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index b9f1afc..275a463 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -462,15 +462,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) {
@@ -1714,21 +1714,32 @@
     private final class PhotoHandler extends PhotoSelectionHandler {
 
         final long mRawContactId;
+        private final BaseRawContactEditorView mEditor;
+        private PhotoActionListener mPhotoEditorListener;
 
         public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
                 EntityDeltaList state) {
             super(context, editor.getPhotoEditor(), photoMode, false, state);
-            setListener(new PhotoEditorListener(editor));
+            mEditor = editor;
             mRawContactId = editor.getRawContactId();
+            mPhotoEditorListener = new PhotoEditorListener();
+        }
+
+        @Override
+        public PhotoActionListener getListener() {
+            return mPhotoEditorListener;
+        }
+
+        @Override
+        public void startPhotoActivity(Intent intent, int requestCode, File photoFile) {
+            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
+            mStatus = Status.SUB_ACTIVITY;
+            mCurrentPhotoFile = photoFile;
+            ContactEditorFragment.this.startActivityForResult(intent, requestCode);
         }
 
         private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
                 implements EditorListener {
-            private final BaseRawContactEditorView mEditor;
-
-            private PhotoEditorListener(BaseRawContactEditorView editor) {
-                mEditor = editor;
-            }
 
             @Override
             public void onRequest(int request) {
@@ -1776,23 +1787,6 @@
             }
 
             @Override
-            public void startTakePhotoActivity(Intent intent, int requestCode, File photoFile) {
-                mRawContactIdRequestingPhoto = mEditor.getRawContactId();
-                mStatus = Status.SUB_ACTIVITY;
-                mCurrentPhotoFile = photoFile;
-                startActivityForResult(intent, requestCode);
-            }
-
-            @Override
-            public void startPickFromGalleryActivity(Intent intent, int requestCode,
-                    File photoFile) {
-                mRawContactIdRequestingPhoto = mEditor.getRawContactId();
-                mStatus = Status.SUB_ACTIVITY;
-                mCurrentPhotoFile = photoFile;
-                startActivityForResult(intent, requestCode);
-            }
-
-            @Override
             public void onPhotoSelected(Bitmap bitmap) {
                 setPhoto(mRawContactIdRequestingPhoto, bitmap, mCurrentPhotoFile);
                 mRawContactIdRequestingPhoto = -1;
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 8a0dd0e..0cbe97e 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -20,6 +20,7 @@
 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 com.android.contacts.ContactsUtils;
 
 import android.content.Context;
@@ -27,19 +28,14 @@
 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;
-
 /**
  * Simple editor for {@link Photo}.
  */
 public class PhotoEditorView extends FrameLayout implements Editor {
-    private static final String TAG = "PhotoEditorView";
 
     private ImageView mPhotoImageView;
     private View mFrameView;
@@ -127,23 +123,7 @@
         return mHasSetPhoto;
     }
 
-    /**
-     * Creates a byte[] containing the PNG-compressed bitmap, or null if
-     * something goes wrong.
-     */
-    private 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;
-        }
-    }
+
 
     /**
      * Assign the given {@link Bitmap} as the new value, updating UI and
@@ -172,7 +152,8 @@
         // 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());
-        byte[] compressed = compressBitmap(Bitmap.createScaledBitmap(photo, size, size, false));
+        final Bitmap scaled = Bitmap.createScaledBitmap(photo, size, size, false);
+        final byte[] compressed = ContactPhotoUtils.compressBitmap(scaled);
         if (compressed != null) mEntry.put(Photo.PHOTO, compressed);
     }
 
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index 9ea0468..ddf88b0 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -53,6 +53,7 @@
     private Resources mResources;
     private Cursor mContactCursor = null;
     private ContactPhotoManager mPhotoManager;
+    private int mNumFrequents;
 
     /**
      * Index of the first NON starred contact in the {@link Cursor}
@@ -119,6 +120,7 @@
         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()
@@ -184,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();
     }
 
@@ -274,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()) {
@@ -289,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;
diff --git a/src/com/android/contacts/list/ContactTileListFragment.java b/src/com/android/contacts/list/ContactTileListFragment.java
index 92ff41d..9f34c54 100644
--- a/src/com/android/contacts/list/ContactTileListFragment.java
+++ b/src/com/android/contacts/list/ContactTileListFragment.java
@@ -61,6 +61,8 @@
     private TextView mEmptyView;
     private ListView mListView;
 
+    private boolean mOptionsMenuHasFrequents;
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
@@ -98,6 +100,24 @@
         getLoaderManager().initLoader(LOADER_CONTACTS, null, mContactTileLoaderListener);
     }
 
+    /**
+     * 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) {
         mAdapter.setColumnCount(columnCount);
     }
@@ -136,12 +156,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) {
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index 79dec09..e8a6367 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -149,7 +149,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);
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index 7c6767b..f8fc4cd 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -24,6 +24,7 @@
 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;
@@ -148,14 +149,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
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index 011a811..a8eafdc 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -18,6 +18,7 @@
 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;
@@ -25,7 +26,6 @@
 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;
@@ -33,6 +33,8 @@
 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;
@@ -106,6 +108,9 @@
             // Show the filter header with "loading" state.
             updateFilterHeaderView();
             mAccountFilterHeader.setVisibility(View.VISIBLE);
+
+            // invalidate the options menu if needed
+            invalidateOptionsMenuIfNeeded();
         }
 
         @Override
@@ -128,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
@@ -198,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;
@@ -225,6 +244,12 @@
     private FrameLayout mAccountFilterHeaderContainer;
     private View mAccountFilterHeader;
 
+    /**
+     * 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 =
@@ -236,6 +261,8 @@
             new ContactsPreferenceChangeListener();
     private final ScrollListener mScrollListener = new ScrollListener();
 
+    private boolean mOptionsMenuHasFrequents;
+
     @Override
     public void onAttach(Activity activity) {
         if (DEBUG) Log.d(TAG, "onAttach()");
@@ -317,10 +344,12 @@
                 mListView, false);
         mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
         mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
-        mAccountFilterHeaderContainer.setVisibility(View.GONE);
+
+        mLoadingView = inflater.inflate(R.layout.phone_loading_contacts, mListView, false);
 
         mAdapter = new PhoneFavoriteMergedAdapter(getActivity(),
-                mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter);
+                mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter,
+                mLoadingView);
 
         mListView.setAdapter(mAdapter);
 
@@ -337,6 +366,16 @@
         return listLayout;
     }
 
+    private boolean isOptionsMenuChanged() {
+        return mOptionsMenuHasFrequents != hasFrequents();
+    }
+
+    private void invalidateOptionsMenuIfNeeded() {
+        if (isOptionsMenuChanged()) {
+            getActivity().invalidateOptionsMenu();
+        }
+    }
+
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
@@ -344,6 +383,17 @@
     }
 
     @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:
@@ -361,6 +411,9 @@
                 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;
     }
@@ -381,6 +434,12 @@
         // 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
@@ -472,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() {
diff --git a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
index 205e156..b35d446 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,8 @@
         mObserver = new CustomDataSetObserver();
         mContactTileAdapter.registerDataSetObserver(mObserver);
         mContactEntryListAdapter.registerDataSetObserver(mObserver);
+
+        mLoadingView = loadingView;
     }
 
     @Override
@@ -77,9 +81,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 +95,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 +117,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 +184,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 +203,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 +244,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 +273,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/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index 6886e81..9be53f6 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -114,7 +114,7 @@
             return;
         }
         final boolean shouldShowHeader = AccountFilterUtil.updateAccountFilterTitleForPhone(
-                mAccountFilterHeader, filter, false, false);
+                mAccountFilterHeader, filter, false);
         if (shouldShowHeader) {
             mPaddingView.setVisibility(View.GONE);
             mAccountFilterHeader.setVisibility(View.VISIBLE);
diff --git a/src/com/android/contacts/list/ShortcutIntentBuilder.java b/src/com/android/contacts/list/ShortcutIntentBuilder.java
index 1be0b74..074d7ec 100644
--- a/src/com/android/contacts/list/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/list/ShortcutIntentBuilder.java
@@ -248,22 +248,30 @@
         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);
+
+        // 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);
 
         shortcutIntent.setData(contactUri);
         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/EntityDelta.java b/src/com/android/contacts/model/EntityDelta.java
index 2cbfa26..bc6ba59 100644
--- a/src/com/android/contacts/model/EntityDelta.java
+++ b/src/com/android/contacts/model/EntityDelta.java
@@ -24,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;
@@ -77,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() {
     }
@@ -210,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.
      */
@@ -339,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();
     }
 
@@ -850,6 +868,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/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 6728913..45565a1 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -224,13 +224,7 @@
             mIntent.setDataAndType(mDataUri, mimeType);
         }
 
-        // Always launch as new task, since we're like a launcher
-        setCommonIntentFlags(mIntent);
-        if (mAlternateIntent != null) setCommonIntentFlags(mAlternateIntent);
-    }
-
-    private static void setCommonIntentFlags(Intent intent) {
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
     }
 
     @Override
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 81aa2e8..11f3da1 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -180,8 +180,8 @@
             @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);
             }
@@ -224,7 +224,8 @@
         mPhotoContainer = findViewById(R.id.photo_container);
         setHeaderNameText(R.id.name, R.string.missing_name);
 
-        getLoaderManager().initLoader(LOADER_ID, null, mLoaderCallbacks);
+        mContactLoader = (ContactLoader) getLoaderManager().initLoader(
+                LOADER_ID, null, mLoaderCallbacks);
     }
 
     private boolean handleOutsideTouch() {
@@ -522,8 +523,7 @@
             if (mLookupUri == null) {
                 Log.wtf(TAG, "Lookup uri wasn't initialized. Loader was started too early");
             }
-            mContactLoader = new ContactLoader(getApplicationContext(), mLookupUri);
-            return mContactLoader;
+            return new ContactLoader(getApplicationContext(), mLookupUri);
         }
     };
 
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index afc88af..38dac60 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -147,9 +147,12 @@
 
             // 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);
+
+            // 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.
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 
             intent.setData(contactData.getLookupUri());
             intent.putExtra(QuickContact.EXTRA_MODE, QuickContact.MODE_SMALL);
diff --git a/src/com/android/contacts/util/AccountFilterUtil.java b/src/com/android/contacts/util/AccountFilterUtil.java
index d63db55..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) {
diff --git a/src/com/android/contacts/util/ContactPhotoUtils.java b/src/com/android/contacts/util/ContactPhotoUtils.java
new file mode 100644
index 0000000..f214e9f
--- /dev/null
+++ b/src/com/android/contacts/util/ContactPhotoUtils.java
@@ -0,0 +1,80 @@
+/*
+ * 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.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";
+
+    // TODO: /DCIM/Camera isn't the ideal place to stash cropped contact photos.
+    //       Where is the right place?
+    private static final File PHOTO_DIR = new File(
+            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() {
+        PHOTO_DIR.mkdirs();
+        return new File(PHOTO_DIR, generateTempPhotoFileName());
+    }
+
+    private static String generateTempPhotoFileName() {
+        Date date = new Date(System.currentTimeMillis());
+        SimpleDateFormat dateFormat = new SimpleDateFormat(PHOTO_DATE_FORMAT);
+        return 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;
+        }
+    }
+}
+
+