Fix NPE in loading group items am: 6942b708b6
am: 28583f8825

Change-Id: Ide2515e87958d0239c7fe857d9db66ec16e44fff
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7d7579d..6f146f0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,8 +16,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.contacts"
-    android:versionCode="20000"
-    android:versionName="2.0.0">
+    android:versionCode="20100"
+    android:versionName="2.1.0">
 
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="25" />
 
@@ -49,6 +49,8 @@
     <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL" />
     <!-- Following used for Contact metadata syncing -->
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+    <!-- Following used for getting the status of the contacts sync adapter -->
+    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
 
     <uses-feature android:name="android.hardware.telephony" android:required="false"/>
 
diff --git a/proguard.flags b/proguard.flags
index d9dad57..d74b6c5 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -82,6 +82,7 @@
 -keep class com.android.contacts.interactions.CallLogInteractionsLoader { *; }
 -keep class com.android.contacts.interactions.ContactDeletionInteraction { *; }
 -keep class com.android.contacts.interactions.ContactInteractionUtil { *; }
+-keep class com.android.contacts.util.SyncUtil { *; }
 -keep class com.android.contacts.widget.CompositeListAdapter { *; }
 -keep class com.google.common.base.Objects { *; }
 -keep class com.google.common.base.Preconditions { *; }
diff --git a/res/color/tab_text_color.xml b/res/color/tab_text_color.xml
deleted file mode 100644
index 5ef1fe3..0000000
--- a/res/color/tab_text_color.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@color/actionbar_text_color" android:state_selected="true"/>
-    <item android:color="@color/actionbar_unselected_text_color" />
-</selector>
\ No newline at end of file
diff --git a/res/drawable-v21/view_pager_tab_background.xml b/res/drawable-v21/view_pager_tab_background.xml
deleted file mode 100644
index b9e0805..0000000
--- a/res/drawable-v21/view_pager_tab_background.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 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
-  -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@color/tab_ripple_color">
-    <item android:id="@android:id/mask">
-        <color android:color="@android:color/white" />
-    </item>
-</ripple>
diff --git a/res/drawable/unread_count_background.xml b/res/drawable/unread_count_background.xml
deleted file mode 100644
index f70f84a..0000000
--- a/res/drawable/unread_count_background.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<shape
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <corners android:radius="@dimen/tab_unread_count_background_radius"/>
-    <solid android:color="@color/tab_unread_count_background_color" />
-</shape>
diff --git a/res/drawable/view_pager_tab_background.xml b/res/drawable/view_pager_tab_background.xml
deleted file mode 100644
index 9f59845..0000000
--- a/res/drawable/view_pager_tab_background.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:state_pressed="true"
-        android:drawable="@color/tab_ripple_color"/>
-</selector>
\ No newline at end of file
diff --git a/res/layout-ldrtl/unread_count_tab.xml b/res/layout-ldrtl/unread_count_tab.xml
deleted file mode 100644
index b23ab57..0000000
--- a/res/layout-ldrtl/unread_count_tab.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<!-- layoutDirection set to ltr as a workaround to a framework bug (b/22010411) causing view with
-     layout_centerInParent inside a RelativeLayout to expand to screen width when RTL is active -->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/view_pager_tab_background"
-    android:layoutDirection="ltr">
-    <!-- The tab icon -->
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true"/>
-    <TextView
-        android:id="@+id/count"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/tab_unread_count_background_size"
-        android:layout_marginTop="@dimen/tab_unread_count_margin_top"
-        android:layout_marginStart="@dimen/tab_unread_count_margin_left"
-        android:layout_toStartOf="@id/icon"
-        android:paddingLeft="@dimen/tab_unread_count_text_padding"
-        android:paddingRight="@dimen/tab_unread_count_text_padding"
-        android:background="@drawable/unread_count_background"
-        android:fontFamily="sans-serif-medium"
-        android:importantForAccessibility="no"
-        android:minWidth="@dimen/tab_unread_count_background_size"
-        android:textAlignment="center"
-        android:textColor="@color/tab_accent_color"
-        android:textSize="@dimen/tab_unread_count_text_size"
-        android:layoutDirection="locale"/>
-</RelativeLayout>
-
diff --git a/res/layout/contact_list_content.xml b/res/layout/contact_list_content.xml
index f18267d..8420b26 100644
--- a/res/layout/contact_list_content.xml
+++ b/res/layout/contact_list_content.xml
@@ -39,20 +39,29 @@
         android:id="@+id/contact_list">
 
         <include layout="@layout/contact_list_card"/>
-        <view
-            class="com.android.contacts.common.list.PinnedHeaderListView"
-            android:id="@android:id/list"
+
+        <android.support.v4.widget.SwipeRefreshLayout
+            android:id="@+id/swipe_refresh"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_marginLeft="?attr/contact_browser_list_padding_left"
-            android:layout_marginRight="?attr/contact_browser_list_padding_right"
-            android:layout_marginStart="?attr/contact_browser_list_padding_left"
-            android:layout_marginEnd="?attr/contact_browser_list_padding_right"
-            android:paddingTop="?attr/list_item_padding_top"
-            android:clipToPadding="false"
-            android:fastScrollEnabled="true"
-            android:visibility="gone"
-            android:fadingEdge="none" />
+            android:enabled="false" >
+
+            <view
+                class="com.android.contacts.common.list.PinnedHeaderListView"
+                android:id="@android:id/list"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="?attr/contact_browser_list_padding_left"
+                android:layout_marginRight="?attr/contact_browser_list_padding_right"
+                android:layout_marginStart="?attr/contact_browser_list_padding_left"
+                android:layout_marginEnd="?attr/contact_browser_list_padding_right"
+                android:paddingTop="?attr/list_item_padding_top"
+                android:clipToPadding="false"
+                android:fastScrollEnabled="true"
+		android:visibility="gone"
+                android:fadingEdge="none" />
+        </android.support.v4.widget.SwipeRefreshLayout>
+
         <ProgressBar
             android:id="@+id/search_progress"
             style="?android:attr/progressBarStyleLarge"
diff --git a/res/layout/people_activity.xml b/res/layout/people_activity.xml
index 9fd1a69..46f0976 100644
--- a/res/layout/people_activity.xml
+++ b/res/layout/people_activity.xml
@@ -25,18 +25,16 @@
                     android:layout_width="match_parent"
                     android:layout_height="match_parent">
 
-        <!--
-            ViewPager for swiping between tabs.  We put fragments at runtime.
-
-            (Adding them directly as the children of this view is not recommended.  ViewPager should
-            be treated like a ListView, which doesn't expect children to be added from the layout.)
-        -->
-        <android.support.v4.view.ViewPager
-            android:id="@+id/tab_pager"
-            android:layout_height="match_parent"
+        <FrameLayout
+            android:id="@+id/contacts_view"
             android:layout_width="match_parent"
-            android:layout_below="@id/toolbar_parent"
-            />
+            android:layout_height="match_parent"
+            android:layout_below="@id/toolbar_parent">
+            <FrameLayout
+                android:id="@+id/contacts_list_container"
+                android:layout_height="match_parent"
+                android:layout_width="match_parent" />
+        </FrameLayout>
 
         <FrameLayout
             android:id="@+id/contacts_unavailable_view"
diff --git a/res/layout/people_activity_tabs_lands.xml b/res/layout/people_activity_tabs_lands.xml
deleted file mode 100644
index 8d7b42b..0000000
--- a/res/layout/people_activity_tabs_lands.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<com.android.contacts.common.list.ViewPagerTabs
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/lists_pager_header"
-    android:layout_width="@dimen/people_activity_landscape_tabs_width"
-    android:layout_height="match_parent"
-    android:textAllCaps="true"
-    android:orientation="horizontal"
-    android:layout_gravity="top"
-    android:layout_weight="0"
-    android:visibility="gone"
-    android:textSize="@dimen/people_activity_landscape_tabs_text_size"
-    style="@style/ContactsActionBarTabTextStyle" />
diff --git a/res/layout/people_activity_toolbar.xml b/res/layout/people_activity_toolbar.xml
index edca3ba..3599f0c 100644
--- a/res/layout/people_activity_toolbar.xml
+++ b/res/layout/people_activity_toolbar.xml
@@ -36,17 +36,4 @@
             style="@style/ContactsToolbarStyle" />
 
     </FrameLayout>
-
-    <com.android.contacts.common.list.ViewPagerTabs
-        android:id="@+id/lists_pager_header"
-        android:layout_width="match_parent"
-        android:layout_height="?attr/actionBarSize"
-        android:textAllCaps="true"
-        android:orientation="horizontal"
-        android:layout_gravity="top"
-        android:layout_weight="0"
-        android:layout_below="@id/toolbar"
-        android:visibility="gone"
-        style="@style/ContactsActionBarTabTextStyle" />
-
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/unread_count_tab.xml b/res/layout/unread_count_tab.xml
deleted file mode 100644
index 783f1c1..0000000
--- a/res/layout/unread_count_tab.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/view_pager_tab_background">
-    <!-- The tab icon -->
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true" />
-    <TextView
-        android:id="@+id/count"
-        android:background="@drawable/unread_count_background"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/tab_unread_count_background_size"
-        android:gravity="center"
-        android:minWidth="@dimen/tab_unread_count_background_size"
-        android:layout_marginStart="@dimen/tab_unread_count_margin_left"
-        android:layout_marginTop="@dimen/tab_unread_count_margin_top"
-        android:layout_toEndOf="@id/icon"
-        android:paddingLeft="@dimen/tab_unread_count_text_padding"
-        android:paddingRight="@dimen/tab_unread_count_text_padding"
-        android:textAlignment="center"
-        android:textSize="@dimen/tab_unread_count_text_size"
-        android:textColor="@color/tab_accent_color"
-        android:fontFamily="sans-serif-medium"
-        android:importantForAccessibility="no" />
-</RelativeLayout>
diff --git a/res/values-b+sr+Latn-sw600dp/strings.xml b/res/values-b+sr+Latn-sw600dp/strings.xml
new file mode 100644
index 0000000..f6727a7
--- /dev/null
+++ b/res/values-b+sr+Latn-sw600dp/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2012 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="account_phone" msgid="347665663520819575">"Uređaj"</string>
+    <string name="composer_has_no_exportable_contact" msgid="5998889616701036804">"Nema kontakata za izvoz. Ako imate kontakte na tabletu, neki dobavljači podataka možda neće dozvoliti izvoz kontakata sa tableta."</string>
+</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 3078976..adb82b5 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -17,9 +17,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="applicationLabel" msgid="3906689777043645443">"Kontakti"</string>
-    <string name="launcherActivityLabel" msgid="6497230399032392417">"Kontakti"</string>
-    <string name="quickContactActivityLabel" msgid="7985456650689347268">"Prikaži kontakt"</string>
-    <string name="editContactActivityLabel" msgid="1129944572070802839">"Izmeni kontakt"</string>
     <string name="contactsList" msgid="8661624236494819731">"Kontakti"</string>
     <string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
     <string name="shortcutDialContact" msgid="746622101599186779">"Direktno biranje"</string>
@@ -31,12 +28,7 @@
     <string name="contactPickerActivityTitle" msgid="4301062192337417640">"Izaberite kontakt"</string>
     <string name="groupMemberPickerActivityTitle" msgid="1431750793695262522">"Izaberite"</string>
     <string name="header_entry_contact_list_adapter_header_title" msgid="2436981165830115659">"Napravi novi kontakt"</string>
-    <string name="starredList" msgid="4817256136413959463">"Sa zvezdicom"</string>
-    <string name="frequentList" msgid="7154768136473953056">"Česti"</string>
-    <string name="strequentList" msgid="5640192862059373511">"Omiljeno"</string>
     <string name="viewContactTitle" msgid="7989394521836644384">"Detalji o kontaktu"</string>
-    <string name="editContactDescription" msgid="2947202828256214947">"Izmeni kontakt"</string>
-    <string name="insertContactDescription" msgid="4709878105452681987">"Napravi kontakt"</string>
     <string name="contactDetailAbout" msgid="5430408883907061400">"Osnovni podaci"</string>
     <string name="contactDetailUpdates" msgid="3780588624763446941">"Ažuriranja"</string>
     <string name="searchHint" msgid="8482945356247760701">"Pretraži kontakte"</string>
@@ -52,7 +44,7 @@
     <string name="menu_call" msgid="3992595586042260618">"Pozovi kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Pošalji SMS kontaktu"</string>
     <string name="menu_splitAggregate" msgid="2627252205317945563">"Razdvoji"</string>
-    <string name="menu_editGroup" msgid="5062005185370983720">"Izmeni"</string>
+    <string name="menu_editGroup" msgid="6696843438454341063">"Ukloni kontakte"</string>
     <string name="menu_renameGroup" msgid="7169512355179757182">"Preimenuj oznaku"</string>
     <string name="menu_deleteGroup" msgid="1126469629233412249">"Izbriši oznaku"</string>
     <string name="menu_addToGroup" msgid="3267409983764370041">"Dodaj kontakt"</string>
@@ -80,10 +72,15 @@
       <item quantity="few">Kontakti su izbrisani</item>
       <item quantity="other">Kontakti su izbrisani</item>
     </plurals>
-    <plurals name="contacts_count" formatted="false" msgid="3287407967505649458">
-      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> kontakt</item>
-      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> kontakta</item>
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> kontakata</item>
+    <plurals name="contacts_count" formatted="false" msgid="8696793457340503668">
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> kontakt</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> kontakta</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> kontakata</item>
+    </plurals>
+    <plurals name="contacts_count_with_account" formatted="false" msgid="7402583111980220575">
+      <item quantity="one"><xliff:g id="COUNT_2">%d</xliff:g> kontakt · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="few"><xliff:g id="COUNT_2">%d</xliff:g> kontakta · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="other"><xliff:g id="COUNT_2">%d</xliff:g> kontakata · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
     </plurals>
     <string name="title_from_google" msgid="4664084747121207202">"Sa Google-a"</string>
     <string name="title_from_other_accounts" msgid="8307885412426754288">"Sa <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
@@ -110,11 +107,13 @@
     <string name="attach_photo_dialog_title" msgid="5599827035558557169">"Slika kontakta"</string>
     <string name="customLabelPickerTitle" msgid="1081475101983255212">"Naziv prilagođene oznake"</string>
     <string name="send_to_voicemail_checkbox" msgid="9001686764070676353">"Šalji pozive direktno u glasovnu poštu"</string>
-    <string name="removePhoto" msgid="4898105274130284565">"Ukloni fotografiju"</string>
-    <string name="noContacts" msgid="4955659076981974652">"Nema kontakata"</string>
+    <string name="removePhoto" msgid="4898105274130284565">"Ukloni sliku"</string>
+    <string name="noContacts" msgid="2228592924476426108">"Lista kontakata je prazna"</string>
     <string name="noGroups" msgid="4607906327968232225">"Nema oznaka."</string>
     <string name="noAccounts" msgid="7768267764545265909">"Morate da imate nalog da biste mogli da pravite grupe."</string>
     <string name="emptyGroup" msgid="5102411903247859575">"Nema kontakata sa ovom oznakom"</string>
+    <string name="emptyAccount" msgid="6873962901497975964">"Nema kontakata na ovom nalogu"</string>
+    <string name="emptyMainList" msgid="2772242747899664460">"Lista kontakata je prazna"</string>
     <string name="contactSavedToast" msgid="9171862279493213075">"Kontakt je sačuvan"</string>
     <string name="contactUnlinkedToast" msgid="7122823195786012553">"Kontakti su razdvojeni"</string>
     <string name="contactSavedErrorToast" msgid="3207250533172944892">"Nije moguće sačuvati izmene kontakata."</string>
@@ -131,6 +130,7 @@
     <string name="groupMembersRemovedToast" msgid="3510563559799376603">"Uklonili smo iz oznake"</string>
     <string name="groupMembersAddedToast" msgid="4824834898718972768">"Dodato je u oznaku"</string>
     <string name="groupSavedErrorToast" msgid="8121032018490980184">"Čuvanje promena oznake nije uspelo."</string>
+    <string name="groupExistsErrorMessage" msgid="5196811283836946189">"Ta oznaka već postoji"</string>
     <plurals name="listTotalPhoneContacts" formatted="false" msgid="3692277679143308755">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> kontakt sa brojem telefona</item>
       <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> kontakta sa brojevima telefona</item>
@@ -153,7 +153,7 @@
     <string name="callAgain" msgid="3197312117049874778">"Pozovi ponovo"</string>
     <string name="returnCall" msgid="8171961914203617813">"Uzvrati poziv"</string>
     <string name="add_contact_dlg_message_fmt" msgid="7986472669444326576">"Želite li da dodate imejl adresu „<xliff:g id="EMAIL">%s</xliff:g>“ u kontakte?"</string>
-    <string name="description_contact_photo" msgid="3387458082667894062">"fotografija kontakta"</string>
+    <string name="description_contact_photo" msgid="3387458082667894062">"slika kontakta"</string>
     <string name="description_plus_button" msgid="515164827856229880">"plus"</string>
     <string name="exporting_contact_list_progress" msgid="560522409559101193">"<xliff:g id="CURRENT_NUMBER">%s</xliff:g> od <xliff:g id="TOTAL_NUMBER">%s</xliff:g> kontak(a)ta"</string>
     <string name="search_settings_description" msgid="2675223022992445813">"Imena kontakata"</string>
@@ -184,8 +184,8 @@
     <string name="google_account_type_format" msgid="5283997303922067997">"<xliff:g id="SOURCE">%1$s</xliff:g> nalog"</string>
     <!-- no translation found for from_account_format (4469138575127580203) -->
     <skip />
-    <string name="take_photo" msgid="7496128293167402354">"Snimi fotografiju"</string>
-    <string name="take_new_photo" msgid="7341354729436576304">"Napravi novu fotografiju"</string>
+    <string name="take_photo" msgid="7496128293167402354">"Slikaj"</string>
+    <string name="take_new_photo" msgid="7341354729436576304">"Slikaj novu sliku"</string>
     <string name="pick_photo" msgid="2129509985223564942">"Izaberi sliku"</string>
     <string name="pick_new_photo" msgid="9122450996263688237">"Izaberite novu sliku"</string>
     <string name="upgrade_in_progress" msgid="474511436863451061">"Kontakt lista se ažurira."</string>
@@ -223,8 +223,7 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Učitava se…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Napravi novi kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="4347232421410561500">"Dodajte nalog"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Uvezi kontakte"</string>
-    <string name="create_group_dialog_title" msgid="5363404287877384473">"Napravite novu oznaku"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="3182801738595937144">"Uvezi"</string>
     <string name="create_group_item_label" msgid="3263064599743742865">"Napravi novu…"</string>
     <string name="delete_group_dialog_message" msgid="335713829185261371">"Želite da izbrišete oznaku „<xliff:g id="GROUP_LABEL">%1$s</xliff:g>“? (Kontakti neće biti izbrisani.)"</string>
     <string name="toast_join_with_empty_contact" msgid="1215465657839085613">"Unesite ime kontakta pre nego što ga objedinite sa drugim kontaktom."</string>
@@ -232,24 +231,23 @@
     <string name="set_default" msgid="4417505153468300351">"Postavi na podrazumevano"</string>
     <string name="clear_default" msgid="7193185801596678067">"Obriši podrazumevanu vrednost"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst je kopiran"</string>
-    <string name="cancel_confirmation_dialog_message" msgid="5058226498605989285">"Želite li da odbacite promene i prekinete sa izmenama?"</string>
+    <string name="cancel_confirmation_dialog_message" msgid="9008214737653278989">"Želite da odbacite promene?"</string>
     <string name="cancel_confirmation_dialog_cancel_editing_button" msgid="3057023972074640671">"Odbaci"</string>
-    <string name="cancel_confirmation_dialog_keep_editing_button" msgid="7737724111972855348">"Nastavi izmene"</string>
+    <string name="cancel_confirmation_dialog_keep_editing_button" msgid="3316573928085916146">"Otkaži"</string>
+    <string name="leave_customize_confirmation_dialog_message" msgid="4277114551206032979">"Želite da odbacite prilagođavanja?"</string>
     <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="enter_contact_name" msgid="4594274696120278368">"Pretražite kontakte"</string>
-    <!-- no translation found for title_edit_group (1889302367574226969) -->
-    <skip />
+    <string name="title_edit_group" msgid="8602752287270586734">"Uklonite kontakte"</string>
     <string name="local_profile_title" msgid="2021416826991393684">"Moj lokalni profil"</string>
     <string name="external_profile_title" msgid="8034998767621359438">"Moj <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g> profil"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Prikazani su svi kontakti"</string>
     <string name="generic_no_account_prompt" msgid="7218827704367325460">"Očuvajte bezbednost kontakata čak i ako izgubite telefon – sinhronizujte sa uslugom na mreži."</string>
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"Dodavanje naloga"</string>
-    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Neće biti napravljena rezervna kopija novog kontakta. Želite li da dodate nalog koji pravi rezervnu kopiju kontakata onlajn?"</string>
+    <string name="contact_editor_prompt_zero_accounts" msgid="6648376557574360096">"Odvojte malo vremena da biste dodali nalog pomoću kog ćete napraviti rezervnu kopiju kontakata na Google-u."</string>
     <string name="contact_editor_prompt_one_account" msgid="3087691056345099310">"Novi kontakti će biti sačuvani na nalogu <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
     <string name="contact_editor_prompt_multiple_accounts" msgid="8565761674283473549">"Izaberite podrazumevani nalog za nove kontakte:"</string>
     <string name="contact_editor_title_new_contact" msgid="7192223018128934940">"Dodaj novi kontakt"</string>
     <string name="contact_editor_title_existing_contact" msgid="4898475703683187798">"Izmeni kontakt"</string>
-    <string name="keep_local" msgid="1258761699192993322">"Zadrži lokalno"</string>
     <string name="add_account" msgid="8201790677994503186">"Dodaj nalog"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Dodaj novi nalog"</string>
     <string name="menu_export_database" msgid="2659719297530170820">"Izvezi datoteke baze podataka"</string>
@@ -261,7 +259,6 @@
     <string name="about_card_title" msgid="2920942314212825637">"Osnovni podaci"</string>
     <string name="send_message" msgid="8938418965550543196">"Pošalji poruku"</string>
     <string name="toast_making_personal_copy" msgid="288549957278065542">"Pravljenje lične kopije..."</string>
-    <string name="yesterday" msgid="6840858548955018569">"Juče"</string>
     <string name="tomorrow" msgid="6241969467795308581">"Sutra"</string>
     <string name="today" msgid="8041090779381781781">"Danas"</string>
     <string name="today_at_time_fmt" msgid="605665249491030460">"Danas u <xliff:g id="TIME_INTERVAL">%s</xliff:g>"</string>
@@ -346,4 +343,275 @@
     <string name="permission_explanation_subheader_calendar_and_SMS" msgid="630115334220569184">"Događaji i poruke"</string>
     <string name="permission_explanation_subheader_calendar" msgid="8785323496211704613">"Događaji"</string>
     <string name="permission_explanation_subheader_SMS" msgid="1904552086449525567">"Poruke"</string>
+    <string name="hamburger_feature_highlight_header" msgid="7442308698936786415">"Organizujte listu"</string>
+    <string name="hamburger_feature_highlight_body" msgid="6268711111318172098">"Uklonite duplikate i grupišite kontakte prema oznaci"</string>
+    <string name="undo" msgid="1425165101664071422">"Opozovi"</string>
+    <string name="toast_text_copied" msgid="5143776250008541719">"Tekst je kopiran"</string>
+    <string name="copy_text" msgid="3257145021583508761">"Kopiraj u priv. memoriju"</string>
+    <string name="call_custom" msgid="7756571794763171802">"Pozovi <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="call_home" msgid="1990519474420545392">"Pozovi kućni telefon"</string>
+    <string name="call_mobile" msgid="7502236805487609178">"Pozovi mobilni telefon"</string>
+    <string name="call_work" msgid="5328785911463744028">"Pozovi poslovni telefon"</string>
+    <string name="call_fax_work" msgid="7467763592359059243">"Pozovi faks"</string>
+    <string name="call_fax_home" msgid="8342175628887571876">"Pozovi kućni faks"</string>
+    <string name="call_pager" msgid="9003902812293983281">"Pozovi pejdžer"</string>
+    <string name="call_other" msgid="8563753966926932052">"Pozovi"</string>
+    <string name="call_callback" msgid="1910165691349426858">"Pozovi za povratni poziv"</string>
+    <string name="call_car" msgid="3280537320306436445">"Pozovi telefon u automobilu"</string>
+    <string name="call_company_main" msgid="6105120947138711257">"Pozovi glavni telefon preduzeća"</string>
+    <string name="call_isdn" msgid="1541590690193403411">"Pozovi ISDN"</string>
+    <string name="call_main" msgid="6082900571803441339">"Pozovi glavni telefon"</string>
+    <string name="call_other_fax" msgid="5745314124619636674">"Pozovi faks"</string>
+    <string name="call_radio" msgid="8296755876398357063">"Pozovi mobilni telefon"</string>
+    <string name="call_telex" msgid="2223170774548648114">"Pozovi teleks"</string>
+    <string name="call_tty_tdd" msgid="8951266948204379604">"Pozovi TTY/TDD"</string>
+    <string name="call_work_mobile" msgid="8707874281430105394">"Pozovi poslovni mobilni telefon"</string>
+    <string name="call_work_pager" msgid="3419348514157949008">"Pozovi poslovni pejdžer"</string>
+    <string name="call_assistant" msgid="2141641383068514308">"Pozovi <xliff:g id="ASSISTANT">%s</xliff:g>"</string>
+    <string name="call_mms" msgid="6274041545876221437">"Pozovi MMS"</string>
+    <string name="call_by_shortcut" msgid="2566802538698913124">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (pozovi)"</string>
+    <string name="sms_custom" msgid="5932736853732191825">"Pošalji SMS na <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="sms_home" msgid="7524332261493162995">"Pošalji SMS na kućni telefon"</string>
+    <string name="sms_mobile" msgid="5200107250451030769">"Pošalji SMS na mobilni telefon"</string>
+    <string name="sms_work" msgid="2269624156655267740">"Pošalji SMS na poslovni telefon"</string>
+    <string name="sms_fax_work" msgid="8028189067816907075">"Pošalji SMS na poslovni faks"</string>
+    <string name="sms_fax_home" msgid="9204042076306809634">"Pošalji SMS na kućni faks"</string>
+    <string name="sms_pager" msgid="7730404569637015192">"Pošalji SMS na pejdžer"</string>
+    <string name="sms_other" msgid="806127844607642331">"Tekst"</string>
+    <string name="sms_callback" msgid="5004824430094288752">"Pošalji SMS za povratni poziv"</string>
+    <string name="sms_car" msgid="7444227058437359641">"Pošalji SMS na telefon u automobilu"</string>
+    <string name="sms_company_main" msgid="118970873419678087">"Pošalji SMS na glavni broj telefona preduzeća"</string>
+    <string name="sms_isdn" msgid="8153785037515047845">"Pošalji SMS na ISDN"</string>
+    <string name="sms_main" msgid="8621625784504541679">"Pošalji SMS na glavni telefon"</string>
+    <string name="sms_other_fax" msgid="3888842199855843152">"Pošalji SMS na faks"</string>
+    <string name="sms_radio" msgid="3329166673433967820">"Pošalji SMS na mobilni telefon"</string>
+    <string name="sms_telex" msgid="9034802430065267848">"Pošalji SMS na teleks"</string>
+    <string name="sms_tty_tdd" msgid="6782284969132531532">"Pošalji SMS na TTY/TDD"</string>
+    <string name="sms_work_mobile" msgid="2459939960512702560">"Pošalji SMS na poslovni mobilni telefon"</string>
+    <string name="sms_work_pager" msgid="5566924423316960597">"Pošalji SMS na pejdžer"</string>
+    <string name="sms_assistant" msgid="2773424339923116234">"Pošalji SMS na <xliff:g id="ASSISTANT">%s</xliff:g>"</string>
+    <string name="sms_mms" msgid="4069352461380762677">"Pošalji SMS na MMS"</string>
+    <string name="sms_by_shortcut" msgid="7741770672976099517">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (pošalji SMS)"</string>
+    <string name="description_video_call" msgid="7120921378651700947">"Uputite video poziv"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Brisanje često kontaktiranih?"</string>
+    <string name="clearFrequentsConfirmation" msgid="2270554975938265734">"Obrisaćete listu često kontaktiranih u aplikacijama Kontakti i Telefon, pa će imejl aplikacije morati iz početka da prikupe informacije o adresiranju."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Brisanje često kontaktiranih..."</string>
+    <string name="status_available" msgid="5586870015822828392">"Dostupan/na"</string>
+    <string name="status_away" msgid="1838861100379804730">"Odsutan/na"</string>
+    <string name="status_busy" msgid="9147992455450257136">"Zauzet/a"</string>
+    <string name="contactsList" msgid="8661624236494819731">"Kontakti"</string>
+    <string name="local_invisible_directory" msgid="6046691709127661065">"Drugi"</string>
+    <string name="directory_search_label" msgid="1887759056597975053">"Katalog"</string>
+    <string name="directory_search_label_work" msgid="8618292129829443176">"Katalog za Work"</string>
+    <string name="local_search_label" msgid="2551177578246113614">"Svi kontakti"</string>
+    <string name="search_results_searching" msgid="3984833028938569930">"Pretražuje se..."</string>
+    <string name="foundTooManyContacts" msgid="5163335650920020220">"Pronađeno je više od <xliff:g id="COUNT">%d</xliff:g>."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nema kontakata"</string>
+    <plurals name="searchFoundContacts" formatted="false" msgid="7223023725334884618">
+      <item quantity="one">pronađen je <xliff:g id="COUNT">%d</xliff:g></item>
+      <item quantity="few">pronađena su <xliff:g id="COUNT">%d</xliff:g></item>
+      <item quantity="other">pronađeno je <xliff:g id="COUNT">%d</xliff:g></item>
+    </plurals>
+    <string name="description_quick_contact_for" msgid="6737516415168327789">"Brzi kontakt za korisnika <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="missing_name" msgid="8745511583852904385">"(Bez imena)"</string>
+    <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Često kontaktirani"</string>
+    <string name="description_view_contact_detail" msgid="9133251213656414807">"Prikaži kontakt"</string>
+    <string name="list_filter_phones" msgid="735313795643493365">"Svi kontakti sa brojevima telefona"</string>
+    <string name="list_filter_phones_work" msgid="1470173699551475015">"Kontakti sa profila za Work"</string>
+    <string name="view_updates_from_group" msgid="1782685984905600034">"Prikaži ažuriranja"</string>
+    <string name="account_phone" msgid="7128032778471187553">"Uređaj"</string>
+    <string name="nameLabelsGroup" msgid="2034640839640477827">"Ime"</string>
+    <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Nadimak"</string>
+    <string name="full_name" msgid="6602579550613988977">"Naziv"</string>
+    <string name="name_given" msgid="4280790853455320619">"Ime"</string>
+    <string name="name_family" msgid="7466985689626017037">"Prezime"</string>
+    <string name="name_prefix" msgid="59756378548779822">"Prefiks za ime"</string>
+    <string name="name_middle" msgid="8467433655992690326">"Srednje slovo"</string>
+    <string name="name_suffix" msgid="3855278445375651441">"Sufiks imena"</string>
+    <string name="name_phonetic" msgid="4259595234312430484">"Ime – fonetski"</string>
+    <string name="name_phonetic_given" msgid="8723179018384187631">"Ime – fonetski"</string>
+    <string name="name_phonetic_middle" msgid="8643721493320405200">"Srednje ime – fonetski"</string>
+    <string name="name_phonetic_family" msgid="2640133663656011626">"Prezime – fonetski"</string>
+    <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefon"</string>
+    <string name="emailLabelsGroup" msgid="8389931313045344406">"Pošalji imejlom"</string>
+    <string name="postalLabelsGroup" msgid="3487738141112589324">"Adresa"</string>
+    <string name="imLabelsGroup" msgid="3898238486262614027">"Razmena trenutnih poruka"</string>
+    <string name="organizationLabelsGroup" msgid="2478611760751832035">"Organizacija"</string>
+    <string name="relationLabelsGroup" msgid="1854373894284572781">"Odnos"</string>
+    <string name="eventLabelsGroup" msgid="7960408705307831289">"Poseban dan"</string>
+    <string name="sms" msgid="1756857139634224222">"Tekstualna poruka"</string>
+    <string name="postal_address" msgid="8765560217149624536">"Adresa"</string>
+    <string name="ghostData_company" msgid="5414421120553765775">"Preduzeće"</string>
+    <string name="ghostData_title" msgid="7496735200318496110">"Naslov"</string>
+    <string name="label_notes" msgid="8337354953278341042">"Beleške"</string>
+    <!-- no translation found for label_custom_field (1994056912242214426) -->
+    <skip />
+    <string name="label_sip_address" msgid="7252153678613978127">"SIP"</string>
+    <string name="websiteLabelsGroup" msgid="4202998982804009261">"Veb-sajt"</string>
+    <string name="groupsLabel" msgid="7000816729542098972">"Oznake"</string>
+    <string name="email_home" msgid="8573740658148184279">"Pošalji imejl na kućnu imejl adresu"</string>
+    <string name="email_mobile" msgid="2042889209787989814">"Pošalji imejl na broj mobilnog telefona"</string>
+    <string name="email_work" msgid="2807430017302722689">"Pošalji imejl na poslovni broj telefona"</string>
+    <string name="email_other" msgid="3454004077967657109">"Pošalji imejlom"</string>
+    <string name="email_custom" msgid="7548003991586214105">"Pošalji imejl na adresu <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="email" msgid="5668400997660065897">"Pošalji imejlom"</string>
+    <string name="postal_street" msgid="8133143961580058972">"Ulica"</string>
+    <string name="postal_pobox" msgid="4431938829180269821">"Poštansko sanduče"</string>
+    <string name="postal_neighborhood" msgid="1450783874558956739">"Komšiluk"</string>
+    <string name="postal_city" msgid="6597491300084895548">"Grad"</string>
+    <string name="postal_region" msgid="6045263193478437672">"Država"</string>
+    <string name="postal_postcode" msgid="572136414136673751">"Poštanski broj"</string>
+    <string name="postal_country" msgid="7638264508416368690">"Zemlja"</string>
+    <string name="map_home" msgid="1243547733423343982">"Prikaži kućnu adresu"</string>
+    <string name="map_work" msgid="1360474076921878088">"Prikaži poslovnu adresu"</string>
+    <string name="map_other" msgid="3817820803587012641">"Prikaži adresu"</string>
+    <string name="map_custom" msgid="6184363799976265281">"Prikaži adresu <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="chat_aim" msgid="2588492205291249142">"Započni ćaskanje preko AIM-a"</string>
+    <string name="chat_msn" msgid="8041633440091073484">"Započni ćaskanje preko Windows Live-a"</string>
+    <string name="chat_yahoo" msgid="6629211142719943666">"Započni ćaskanje preko Yahoo-a"</string>
+    <string name="chat_skype" msgid="1210045020427480566">"Započni ćaskanje preko Skype-a"</string>
+    <string name="chat_qq" msgid="4294637812847719693">"Započni ćaskanje preko QQ-a"</string>
+    <string name="chat_gtalk" msgid="981575737258117697">"Ćaskaj preko Google Talk-a"</string>
+    <string name="chat_icq" msgid="8438405386153745775">"Započni ćaskanje preko ICQ-a"</string>
+    <string name="chat_jabber" msgid="7561444230307829609">"Započni ćaskanje preko Jabber-a"</string>
+    <string name="chat" msgid="9025361898797412245">"Ćaskanje"</string>
+    <string name="description_minus_button" msgid="6908099247930477551">"izbriši"</string>
+    <string name="expand_collapse_name_fields_description" msgid="8682630859539604311">"Proširivanje ili skupljanje polja za ime"</string>
+    <string name="expand_collapse_phonetic_name_fields_description" msgid="3306777588073354509">"Proširite ili skupite polja za fonetsko ime"</string>
+    <string name="list_filter_all_accounts" msgid="8908683398914322369">"Svi kontakti"</string>
+    <string name="list_filter_all_starred" msgid="5031734941601931356">"Sa zvezdicom"</string>
+    <string name="list_filter_customize" msgid="4789963356004169321">"Prilagodi"</string>
+    <string name="list_filter_single" msgid="5871400283515893087">"Kontakt"</string>
+    <string name="display_ungrouped" msgid="6885954210243119591">"Svi drugi kontakti"</string>
+    <string name="display_all_contacts" msgid="2031647544742889505">"Svi kontakti"</string>
+    <string name="menu_sync_remove" msgid="3266725887008450161">"Ukloni grupu za sinhronizaciju"</string>
+    <string name="dialog_sync_add" msgid="8267045393119375803">"Dodaj grupu za sinhronizaciju"</string>
+    <string name="display_more_groups" msgid="2682547080423434170">"Još grupa…"</string>
+    <string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"Uklanjanjem grupe „<xliff:g id="GROUP">%s</xliff:g>“ sa liste za sinhronizaciju uklonićete i sve negrupisane kontakte sa te liste."</string>
+    <string name="savingDisplayGroups" msgid="2133152192716475939">"Čuvanje opcija prikaza je u toku..."</string>
+    <string name="menu_done" msgid="796017761764190697">"Gotovo"</string>
+    <string name="menu_doNotSave" msgid="58593876893538465">"Otkaži"</string>
+    <string name="listCustomView" msgid="1840624396582117590">"Prilagođeni prikaz"</string>
+    <string name="dialog_new_contact_account" msgid="4969619718062454756">"Sačuvajte uvezene kontakte na:"</string>
+    <string name="import_from_sim" msgid="3859272228033941659">"Uvezi sa SIM kartice"</string>
+    <string name="import_from_sim_summary" msgid="5815105584445743740">"Uvezi sa SIM kartice <xliff:g id="SIM_NAME">^1</xliff:g> – <xliff:g id="SIM_NUMBER">^2</xliff:g>"</string>
+    <string name="import_from_sim_summary_no_number" msgid="880612418352086012">"Uvezi sa SIM kartice <xliff:g id="SIM_NAME">%1$s</xliff:g>"</string>
+    <string name="import_from_vcf_file" product="default" msgid="5304572242183878086">"Uvezi iz .vcf datoteke"</string>
+    <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Želite li da otkažete uvoz datoteke <xliff:g id="FILENAME">%s</xliff:g>?"</string>
+    <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Želite li da otkažete izvoz datoteke <xliff:g id="FILENAME">%s</xliff:g>?"</string>
+    <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Nije moguće otkazati vCard uvoz/izvoz"</string>
+    <string name="fail_reason_unknown" msgid="1714092345030570863">"Nepoznata greška."</string>
+    <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Nije moguće otvoriti datoteku „<xliff:g id="FILE_NAME">%s</xliff:g>“: <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
+    <string name="fail_reason_could_not_initialize_exporter" msgid="707260459259688510">"Nije moguće pokrenuti program za izvoz: „<xliff:g id="EXACT_REASON">%s</xliff:g>“"</string>
+    <string name="fail_reason_no_exportable_contact" msgid="8728506011371262065">"Nema kontakata za izvoz."</string>
+    <string name="missing_required_permission" msgid="5865884842972833120">"Onemogućili ste obaveznu dozvolu."</string>
+    <string name="fail_reason_error_occurred_during_export" msgid="3018855323913649063">"Došlo je do greške pri izvozu: „<xliff:g id="EXACT_REASON">%s</xliff:g>“"</string>
+    <string name="fail_reason_too_long_filename" msgid="3393764245254738333">"Zahtevani naziv datoteke je predugačak („<xliff:g id="FILENAME">%s</xliff:g>“)"</string>
+    <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O greška"</string>
+    <string name="fail_reason_low_memory_during_import" msgid="875222757734882898">"Nema dovoljno memorije. Datoteka je možda prevelika."</string>
+    <string name="fail_reason_vcard_parse_error" msgid="888263542360355784">"Iz neočekivanog razloga nije bilo moguće raščlaniti vCard datoteku."</string>
+    <string name="fail_reason_not_supported" msgid="8219562769267148825">"Format nije podržan."</string>
+    <string name="fail_reason_failed_to_collect_vcard_meta_info" msgid="6427931733267328564">"Nije moguće prikupiti metapodatke datih vCard datoteka."</string>
+    <string name="fail_reason_failed_to_read_files" msgid="5823434810622484922">"Nije moguće uvesti jednu ili više datoteka (%s)."</string>
+    <string name="exporting_vcard_finished_title" msgid="4767045779458185251">"Izvoz datoteke <xliff:g id="FILENAME">%s</xliff:g> je završen."</string>
+    <string name="exporting_vcard_finished_title_fallback" msgid="6060472638008218274">"Izvoz kontakata je završen."</string>
+    <string name="exporting_vcard_finished_toast" msgid="1739055986856453882">"Izvoz kontakata je završen. Kliknite na obaveštenje da biste ih delili."</string>
+    <string name="touch_to_share_contacts" msgid="4882485525268469736">"Dodirnite da biste delili kontakte."</string>
+    <string name="exporting_vcard_canceled_title" msgid="2652222370493306887">"Izvoz datoteke <xliff:g id="FILENAME">%s</xliff:g> je otkazan"</string>
+    <string name="exporting_contact_list_title" msgid="9072240631534457415">"Izvoz podataka o kontaktima je u toku"</string>
+    <string name="exporting_contact_list_message" msgid="3367949209642931952">"Podaci o kontaktima se izvoze."</string>
+    <string name="composer_failed_to_get_database_infomation" msgid="1765944280846236723">"Nije moguće preuzeti informacije iz baze podataka"</string>
+    <string name="composer_has_no_exportable_contact" msgid="3296493229040294335">"Nema kontakata za izvoz. Ako imate kontakata na telefonu, neki dobavljači podataka možda neće dozvoliti da se kontakti izvoze sa telefona."</string>
+    <string name="composer_not_initialized" msgid="2321648986367005254">"Program za izradu vCard datoteka se nije ispravno pokrenuo."</string>
+    <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Nije moguće izvesti"</string>
+    <string name="exporting_contact_failed_message" msgid="4938527850142003141">"Podaci o kontaktima nizu izvezeni.\nRazlog: „<xliff:g id="FAIL_REASON">%s</xliff:g>“"</string>
+    <string name="importing_vcard_description" msgid="4245275224298571351">"Uvoz <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="reading_vcard_failed_title" msgid="4251647443358422855">"Nije moguće čitati vCard podatke"</string>
+    <string name="reading_vcard_canceled_title" msgid="1925216585981542019">"Otkazano je čitanje podataka sa vCard datoteke"</string>
+    <string name="importing_vcard_finished_title" msgid="3341541727268747967">"Uvoz datoteke <xliff:g id="FILENAME">%s</xliff:g> je završen"</string>
+    <string name="importing_vcard_canceled_title" msgid="2147475978165599336">"Uvoz datoteke <xliff:g id="FILENAME">%s</xliff:g> je  otkazan"</string>
+    <string name="vcard_import_will_start_message" msgid="2804911199145873396">"Datoteka <xliff:g id="FILENAME">%s</xliff:g> će uskoro biti uvezena."</string>
+    <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"Datoteka će uskoro biti uvezena."</string>
+    <string name="vcard_import_request_rejected_message" msgid="2890471184508516011">"Zahtev za izvoz vCard datoteke je odbijen. Pokušajte kasnije."</string>
+    <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Datoteka <xliff:g id="FILENAME">%s</xliff:g> će uskoro biti izvezena."</string>
+    <string name="vcard_export_will_start_message_fallback" msgid="6553826997490909749">"Datoteka će uskoro biti izvezena."</string>
+    <string name="contacts_export_will_start_message" msgid="8538705791417534431">"Kontakti će uskoro biti izvezeni."</string>
+    <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Zahtev za izvoz vCard datoteke je odbijen. Pokušajte kasnije."</string>
+    <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
+    <string name="caching_vcard_message" msgid="4926308675041506756">"Keširanje vCard datoteke u lokalnu privremenu memoriju. Uvoz će uskoro započeti."</string>
+    <string name="vcard_import_failed" msgid="5223531255894842406">"Nije moguće uvesti vCard datoteku."</string>
+    <string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt preko NFC-a"</string>
+    <string name="confirm_export_title" msgid="6834385377255286349">"Želite li da izvezete kontakte?"</string>
+    <string name="caching_vcard_title" msgid="1226272312940516605">"Keširanje..."</string>
+    <string name="progress_notifier_message" msgid="2311011466908220528">"Uvoz <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="export_to_vcf_file" product="default" msgid="4407527157056120858">"Izvezi u .vcf datoteku"</string>
+    <string name="display_options_sort_list_by" msgid="7028809117272018712">"Sortiraj prema"</string>
+    <string name="display_options_sort_by_given_name" msgid="2778421332815687873">"Ime"</string>
+    <string name="display_options_sort_by_family_name" msgid="2684905041926954793">"Prezime"</string>
+    <string name="display_options_view_names_as" msgid="6514632499276563482">"Format imena"</string>
+    <string name="display_options_view_given_name_first" msgid="3616004640258761473">"Prvo ime"</string>
+    <string name="display_options_view_family_name_first" msgid="956445100777296467">"Prvo prezime"</string>
+    <string name="settings_accounts" msgid="350219740670774576">"Nalozi"</string>
+    <string name="default_editor_account" msgid="699591683362420991">"Podrazumevani nalog za nove kontakte"</string>
+    <string name="sync_contact_metadata_title" msgid="6957956139306960211">"Sinhronizuj metapodatke kontakata [DOGFOOD]"</string>
+    <string name="sync_contact_metadata_dialog_title" msgid="6192335951588820553">"Sinhronizujte metapodatke kontakata"</string>
+    <string name="settings_my_info_title" msgid="1534272456405343119">"Moje informacije"</string>
+    <string name="set_up_profile" msgid="7370213843590143771">"Podesite profil"</string>
+    <string name="setting_about" msgid="7014388749752042863">"O Kontaktima"</string>
+    <string name="activity_title_settings" msgid="5464130076132770781">"Podešavanja"</string>
+    <string name="share_visible_contacts" msgid="890150378880783797">"Deli vidljive kontakte"</string>
+    <string name="share_visible_contacts_failure" msgid="7324717548166915560">"Deljenje vidljivih kontakata nije uspelo."</string>
+    <string name="share_favorite_contacts" msgid="4280926751003081042">"Deli omiljene kontakte"</string>
+    <string name="share_contacts" msgid="8109287987498711664">"Deli sve kontakte"</string>
+    <string name="share_contacts_failure" msgid="1216431977330560559">"Deljenje kontakata nije uspelo."</string>
+    <string name="dialog_import_export" msgid="4360648034889921624">"Uvoz/izvoz kontakata"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Uvoz kontakata"</string>
+    <string name="share_error" msgid="948429331673358107">"Ovaj kontakt ne može da se deli."</string>
+    <string name="no_contact_to_share" msgid="1276397530378323033">"Nema kontakata za deljenje."</string>
+    <string name="menu_search" msgid="9147752853603483719">"Pretraga"</string>
+    <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakti za prikaz"</string>
+    <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakti za prikaz"</string>
+    <string name="custom_list_filter" msgid="2105275443109077687">"Definišite prilagođeni prikaz"</string>
+    <string name="menu_custom_filter_save" msgid="2679793632208086460">"Sačuvaj"</string>
+    <string name="hint_findContacts" msgid="7128627979899070325">"Pretražite kontakte"</string>
+    <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Omiljeno"</string>
+    <string name="listTotalAllContactsZero" msgid="5513001821794568211">"Nema kontakata."</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Obriši često kontaktirane"</string>
+    <string name="menu_select_sim" msgid="3603578201960504010">"Izaberite SIM karticu"</string>
+    <string name="menu_accounts" msgid="1424330057450189074">"Upravljaj nalozima"</string>
+    <string name="menu_import_export" msgid="26217871113229507">"Uvoz/izvoz"</string>
+    <string name="menu_blocked_numbers" msgid="5272951629083025995">"Blokirani brojevi"</string>
+    <string name="contact_status_update_attribution" msgid="752179367353018597">"preko <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
+    <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g> preko <xliff:g id="SOURCE">%2$s</xliff:g>"</string>
+    <string name="action_menu_back_from_search" msgid="8793348588949233348">"zaustavite pretraživanje"</string>
+    <string name="description_clear_search" msgid="688023606766232904">"Brisanje pretrage"</string>
+    <string name="settings_contact_display_options_title" msgid="4890258244494248687">"Opcije prikazivanja kontakata"</string>
+    <string name="select_account_dialog_title" msgid="5478489655696599219">"Nalog"</string>
+    <string name="set_default_account" msgid="4311613760725609801">"Uvek koristi ovo za pozive"</string>
+    <string name="select_phone_account_for_calls" msgid="3810607744451014540">"Pozovi pomoću"</string>
+    <string name="call_with_a_note" msgid="8389827628360791676">"Uputi poziv sa beleškom"</string>
+    <string name="call_subject_hint" msgid="3637498418381454511">"Unesite belešku koju ćete poslati uz poziv..."</string>
+    <string name="send_and_call_button" msgid="7740295432834590737">"POŠALJI I POZOVI"</string>
+    <string name="call_subject_limit" msgid="4545212901205397669">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
+    <string name="call_subject_type_and_number" msgid="7667188212129152558">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+    <plurals name="tab_title_with_unread_items" formatted="false" msgid="7682024005130747825">
+      <item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
+      <item quantity="few"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitane stavke. </item>
+      <item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitanih stavki. </item>
+    </plurals>
+    <string name="about_build_version" msgid="1765533099416999801">"Verzija"</string>
+    <string name="about_open_source_licenses" msgid="6479990452352919641">"Licence otvorenog koda"</string>
+    <string name="about_open_source_licenses_summary" msgid="57418386931763994">"Podaci o licenci za softver otvorenog koda"</string>
+    <string name="about_privacy_policy" msgid="3705518622499152626">"Politika privatnosti"</string>
+    <string name="about_terms_of_service" msgid="4642400812150296723">"Uslovi korišćenja usluge"</string>
+    <string name="activity_title_licenses" msgid="5467767062737708066">"Licence otvorenog koda"</string>
+    <string name="url_open_error_toast" msgid="452592089815420457">"Otvaranje URL-a nije uspelo."</string>
+    <string name="account_filter_view_checked" msgid="6696859503887762213">"Označeno: <xliff:g id="ACCOUNT_INFO">%s</xliff:g>"</string>
+    <string name="account_filter_view_not_checked" msgid="2248684521205038389">"Nije označeno: <xliff:g id="ACCOUNT_INFO">%s</xliff:g>"</string>
+    <string name="description_search_video_call" msgid="5841525580339803272">"Uputite video poziv"</string>
+    <string name="description_delete_contact" msgid="53835657343783663">"Izbrišite"</string>
+    <string name="description_no_name_header" msgid="8884991311595943271">"Tri tačke"</string>
+    <string name="callDurationSecondFormat" msgid="7067644915903528776">"<xliff:g id="SECONDS">%s</xliff:g> sek"</string>
+    <string name="callDurationMinuteFormat" msgid="4647095486747447674">"<xliff:g id="MINUTES">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> sek"</string>
+    <string name="callDurationHourFormat" msgid="7392254193808506640">"<xliff:g id="MINUTES_0">%s</xliff:g> s <xliff:g id="MINUTES_1">%s</xliff:g> min <xliff:g id="SECONDS">%s</xliff:g> sek"</string>
 </resources>
diff --git a/res/values-be-rBY-sw600dp/strings.xml b/res/values-be-rBY-sw600dp/strings.xml
new file mode 100644
index 0000000..8e0b10f
--- /dev/null
+++ b/res/values-be-rBY-sw600dp/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2012 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="account_phone" msgid="347665663520819575">"Прылада"</string>
+    <string name="composer_has_no_exportable_contact" msgid="5998889616701036804">"Няма кантактаў, якія можна экспартаваць. Калі ў вас ёсць кантакты на планшэце, некаторыя пастаўшчыкі даных могуць не дазваляць экспарт кантактаў з планшэта."</string>
+</resources>
diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml
index 2eee399..8b64477 100644
--- a/res/values-be-rBY/strings.xml
+++ b/res/values-be-rBY/strings.xml
@@ -17,9 +17,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="applicationLabel" msgid="3906689777043645443">"Кантакты"</string>
-    <string name="launcherActivityLabel" msgid="6497230399032392417">"Кантакты"</string>
-    <string name="quickContactActivityLabel" msgid="7985456650689347268">"Прагледзець кантакт"</string>
-    <string name="editContactActivityLabel" msgid="1129944572070802839">"Рэдагаваць кантакт"</string>
     <string name="contactsList" msgid="8661624236494819731">"Кантакты"</string>
     <string name="shortcutContact" msgid="749243779392912958">"Кантакт"</string>
     <string name="shortcutDialContact" msgid="746622101599186779">"Хуткі выклік"</string>
@@ -31,12 +28,7 @@
     <string name="contactPickerActivityTitle" msgid="4301062192337417640">"Выберыце кантакт"</string>
     <string name="groupMemberPickerActivityTitle" msgid="1431750793695262522">"Выбраць"</string>
     <string name="header_entry_contact_list_adapter_header_title" msgid="2436981165830115659">"Стварыць новы кантакт"</string>
-    <string name="starredList" msgid="4817256136413959463">"Пазначана"</string>
-    <string name="frequentList" msgid="7154768136473953056">"Частыя"</string>
-    <string name="strequentList" msgid="5640192862059373511">"Любімыя"</string>
     <string name="viewContactTitle" msgid="7989394521836644384">"Дадзеныя кантакта"</string>
-    <string name="editContactDescription" msgid="2947202828256214947">"Рэдагаваць кантакт"</string>
-    <string name="insertContactDescription" msgid="4709878105452681987">"Стварыць кантакт"</string>
     <string name="contactDetailAbout" msgid="5430408883907061400">"Інфармацыя"</string>
     <string name="contactDetailUpdates" msgid="3780588624763446941">"Абнаўленні"</string>
     <string name="searchHint" msgid="8482945356247760701">"Пошук кантактаў"</string>
@@ -52,7 +44,7 @@
     <string name="menu_call" msgid="3992595586042260618">"Выклікаць кантакт"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Паведамленне кантакту"</string>
     <string name="menu_splitAggregate" msgid="2627252205317945563">"Выдаліць сувязь"</string>
-    <string name="menu_editGroup" msgid="5062005185370983720">"Рэдагаваць"</string>
+    <string name="menu_editGroup" msgid="6696843438454341063">"Выдаліць кантакты"</string>
     <string name="menu_renameGroup" msgid="7169512355179757182">"Перайменаваць метку"</string>
     <string name="menu_deleteGroup" msgid="1126469629233412249">"Выдаліць метку"</string>
     <string name="menu_addToGroup" msgid="3267409983764370041">"Дадаць кантакт"</string>
@@ -81,11 +73,17 @@
       <item quantity="many">Кантакты выдалены</item>
       <item quantity="other">Кантакты выдалены</item>
     </plurals>
-    <plurals name="contacts_count" formatted="false" msgid="3287407967505649458">
-      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> кантакт</item>
-      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> кантакты</item>
-      <item quantity="many"><xliff:g id="COUNT">%d</xliff:g> кантактаў</item>
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> кантакту</item>
+    <plurals name="contacts_count" formatted="false" msgid="8696793457340503668">
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> кантакт</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> кантакты</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> кантактаў</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> кантакту</item>
+    </plurals>
+    <plurals name="contacts_count_with_account" formatted="false" msgid="7402583111980220575">
+      <item quantity="one"><xliff:g id="COUNT_2">%d</xliff:g> кантакт · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="few"><xliff:g id="COUNT_2">%d</xliff:g> кантакты · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="many"><xliff:g id="COUNT_2">%d</xliff:g> кантактаў · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="other"><xliff:g id="COUNT_2">%d</xliff:g> кантакту · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
     </plurals>
     <string name="title_from_google" msgid="4664084747121207202">"З Google"</string>
     <string name="title_from_other_accounts" msgid="8307885412426754288">"З <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
@@ -113,10 +111,12 @@
     <string name="customLabelPickerTitle" msgid="1081475101983255212">"Імя карыстальніцкага цэтліка"</string>
     <string name="send_to_voicemail_checkbox" msgid="9001686764070676353">"Адпраўляць выклікі непасрэдна на галасавую пошту"</string>
     <string name="removePhoto" msgid="4898105274130284565">"Выдаліць фота"</string>
-    <string name="noContacts" msgid="4955659076981974652">"Няма кантактаў"</string>
+    <string name="noContacts" msgid="2228592924476426108">"Ваш спіс кантактаў пусты"</string>
     <string name="noGroups" msgid="4607906327968232225">"Метак няма."</string>
     <string name="noAccounts" msgid="7768267764545265909">"Для стварэння групы патрабуецца ўліковы запіс."</string>
     <string name="emptyGroup" msgid="5102411903247859575">"Няма кантактаў з гэтай меткай"</string>
+    <string name="emptyAccount" msgid="6873962901497975964">"Няма кантактаў у гэтым уліковым запісе"</string>
+    <string name="emptyMainList" msgid="2772242747899664460">"Ваш спіс кантактаў пусты"</string>
     <string name="contactSavedToast" msgid="9171862279493213075">"Кантакт захаваны"</string>
     <string name="contactUnlinkedToast" msgid="7122823195786012553">"Кантакты адлучаны"</string>
     <string name="contactSavedErrorToast" msgid="3207250533172944892">"Немагчыма захаваць змены кантакта."</string>
@@ -133,6 +133,7 @@
     <string name="groupMembersRemovedToast" msgid="3510563559799376603">"Выдалена з меткі"</string>
     <string name="groupMembersAddedToast" msgid="4824834898718972768">"Дададзена да этыкеткі"</string>
     <string name="groupSavedErrorToast" msgid="8121032018490980184">"Не ўдалося захаваць змяненні меткі."</string>
+    <string name="groupExistsErrorMessage" msgid="5196811283836946189">"Гэта пазнака ўжо існуе"</string>
     <plurals name="listTotalPhoneContacts" formatted="false" msgid="3692277679143308755">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> кантакт з нумарам(і) тэлефона(ў)</item>
       <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> кантакты з нумарамі тэлефонаў</item>
@@ -229,8 +230,7 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Загрузка..."</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Стварыць новы кантакт"</string>
     <string name="contacts_unavailable_add_account" msgid="4347232421410561500">"Дадаць уліковы запіс"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Імпартаваць кантакты"</string>
-    <string name="create_group_dialog_title" msgid="5363404287877384473">"Стварыць новую метку"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="3182801738595937144">"Імпартаваць"</string>
     <string name="create_group_item_label" msgid="3263064599743742865">"Стварыць новую..."</string>
     <string name="delete_group_dialog_message" msgid="335713829185261371">"Выдаліць метку \"<xliff:g id="GROUP_LABEL">%1$s</xliff:g>\"? (Самі кантакты не будуць выдалены.)"</string>
     <string name="toast_join_with_empty_contact" msgid="1215465657839085613">"Перад звязваннем кантакту з іншым увядзіце імя кантакту."</string>
@@ -238,24 +238,24 @@
     <string name="set_default" msgid="4417505153468300351">"Усталяваць па змаўчанні"</string>
     <string name="clear_default" msgid="7193185801596678067">"Скінуць налады па змаўчанні"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Тэкст скапіяваны"</string>
-    <string name="cancel_confirmation_dialog_message" msgid="5058226498605989285">"Адхіліць змены і скончыць рэдагаванне?"</string>
+    <string name="cancel_confirmation_dialog_message" msgid="9008214737653278989">"Скасаваць змены?"</string>
     <string name="cancel_confirmation_dialog_cancel_editing_button" msgid="3057023972074640671">"Адхіліць"</string>
-    <string name="cancel_confirmation_dialog_keep_editing_button" msgid="7737724111972855348">"Працягнуць рэдагаванне"</string>
+    <string name="cancel_confirmation_dialog_keep_editing_button" msgid="3316573928085916146">"Скасаваць"</string>
+    <!-- no translation found for leave_customize_confirmation_dialog_message (4277114551206032979) -->
+    <skip />
     <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="enter_contact_name" msgid="4594274696120278368">"Пошук кантактаў"</string>
-    <!-- no translation found for title_edit_group (1889302367574226969) -->
-    <skip />
+    <string name="title_edit_group" msgid="8602752287270586734">"Выдаліць кантакты"</string>
     <string name="local_profile_title" msgid="2021416826991393684">"Мой лакальны профіль"</string>
     <string name="external_profile_title" msgid="8034998767621359438">"Мой профіль у <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g>"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Адлюстраванне ўсіх кантактаў"</string>
     <string name="generic_no_account_prompt" msgid="7218827704367325460">"Абаранiце свае кантакты, нават калі страціце тэлефон: сінхранізуйце iх з вэб-службай."</string>
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"Дадаць уліковы запіс"</string>
-    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Рэзервовая копiя вашага новага кантакту не будзе створана. Дадаць улiковы запiс, у якiм будуць захоўвацца рэзервовыя копii кантактаў у Iнтэрнэце?"</string>
+    <string name="contact_editor_prompt_zero_accounts" msgid="6648376557574360096">"Знайдзіце хвілінку, каб дадаць уліковы запіс, які дазволіць стварыць рэзервовую копію вашых кантактаў у Google."</string>
     <string name="contact_editor_prompt_one_account" msgid="3087691056345099310">"Новыя кантакты будуць захаваны ва ўліковы запіс <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
     <string name="contact_editor_prompt_multiple_accounts" msgid="8565761674283473549">"Выбраць уліковы запіс па змаўчанні для новых кантактаў:"</string>
     <string name="contact_editor_title_new_contact" msgid="7192223018128934940">"Дадаць новы кантакт"</string>
     <string name="contact_editor_title_existing_contact" msgid="4898475703683187798">"Рэдагаваць кантакт"</string>
-    <string name="keep_local" msgid="1258761699192993322">"Захоўваць лакальна"</string>
     <string name="add_account" msgid="8201790677994503186">"Дадаць уліковы запіс"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Дадаць новы ўліковы запіс"</string>
     <string name="menu_export_database" msgid="2659719297530170820">"Экспарт базы дадзеных файлаў"</string>
@@ -267,7 +267,6 @@
     <string name="about_card_title" msgid="2920942314212825637">"Інфармацыя"</string>
     <string name="send_message" msgid="8938418965550543196">"Адправiць паведамленне"</string>
     <string name="toast_making_personal_copy" msgid="288549957278065542">"Стварэнне асабістай копіі..."</string>
-    <string name="yesterday" msgid="6840858548955018569">"Учора"</string>
     <string name="tomorrow" msgid="6241969467795308581">"Заўтра"</string>
     <string name="today" msgid="8041090779381781781">"Сёння"</string>
     <string name="today_at_time_fmt" msgid="605665249491030460">"Сёння ў перыяд <xliff:g id="TIME_INTERVAL">%s</xliff:g>"</string>
@@ -356,4 +355,281 @@
     <string name="permission_explanation_subheader_calendar_and_SMS" msgid="630115334220569184">"Падзеі і паведамленні"</string>
     <string name="permission_explanation_subheader_calendar" msgid="8785323496211704613">"Падзеі"</string>
     <string name="permission_explanation_subheader_SMS" msgid="1904552086449525567">"Паведамленні"</string>
+    <string name="hamburger_feature_highlight_header" msgid="7442308698936786415">"Арганізуйце свой спіс"</string>
+    <string name="hamburger_feature_highlight_body" msgid="6268711111318172098">"Выдаліце дублікаты і згрупуйце кантакты па метках"</string>
+    <!-- no translation found for undo (1425165101664071422) -->
+    <skip />
+    <string name="toast_text_copied" msgid="5143776250008541719">"Тэкст скапіяваны"</string>
+    <string name="copy_text" msgid="3257145021583508761">"Скапіраваць у буфер абмену"</string>
+    <string name="call_custom" msgid="7756571794763171802">"Выклікаць <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="call_home" msgid="1990519474420545392">"Патэлефанаваць на хатні нумар"</string>
+    <string name="call_mobile" msgid="7502236805487609178">"Набраць нумар мабільнага тэлефону"</string>
+    <string name="call_work" msgid="5328785911463744028">"Выклікаць працоўны нумар тэлефона"</string>
+    <string name="call_fax_work" msgid="7467763592359059243">"Набраць нумар працоўнага факса"</string>
+    <string name="call_fax_home" msgid="8342175628887571876">"Патэлефанаваць на хатні факс"</string>
+    <string name="call_pager" msgid="9003902812293983281">"Выклікаць пэйджар"</string>
+    <string name="call_other" msgid="8563753966926932052">"Выклікаць"</string>
+    <string name="call_callback" msgid="1910165691349426858">"Зрабіць зваротны выклік"</string>
+    <string name="call_car" msgid="3280537320306436445">"Выклікаць нумар у машыне"</string>
+    <string name="call_company_main" msgid="6105120947138711257">"Выклікаць асноўны нумар кампаніі"</string>
+    <string name="call_isdn" msgid="1541590690193403411">"Выклік ISDN"</string>
+    <string name="call_main" msgid="6082900571803441339">"Выклікаць асноўны нумар"</string>
+    <string name="call_other_fax" msgid="5745314124619636674">"Выклік факса"</string>
+    <string name="call_radio" msgid="8296755876398357063">"Патэлефанаваць на радыётэлефон"</string>
+    <string name="call_telex" msgid="2223170774548648114">"Выклік на тэлекс"</string>
+    <string name="call_tty_tdd" msgid="8951266948204379604">"Выклікаць TTY/TDD"</string>
+    <string name="call_work_mobile" msgid="8707874281430105394">"Патэлефанаваць на працоўны мабільны"</string>
+    <string name="call_work_pager" msgid="3419348514157949008">"Выклікаць працоўны пэйджар"</string>
+    <string name="call_assistant" msgid="2141641383068514308">"Выклікаць <xliff:g id="ASSISTANT">%s</xliff:g>"</string>
+    <string name="call_mms" msgid="6274041545876221437">"Выклік MMS"</string>
+    <string name="call_by_shortcut" msgid="2566802538698913124">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (Выклікаць)"</string>
+    <string name="sms_custom" msgid="5932736853732191825">"Тэкставае паведамленне на <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="sms_home" msgid="7524332261493162995">"Тэкставае паведамленне на хатні тэлефон"</string>
+    <string name="sms_mobile" msgid="5200107250451030769">"Тэкставае паведамленне на мабільны тэлефон"</string>
+    <string name="sms_work" msgid="2269624156655267740">"Тэкставае паведамленне на працоўны тэлефон"</string>
+    <string name="sms_fax_work" msgid="8028189067816907075">"Тэкставае паведамленне на працоўны факс"</string>
+    <string name="sms_fax_home" msgid="9204042076306809634">"Тэкставае паведамленне на хатні факс"</string>
+    <string name="sms_pager" msgid="7730404569637015192">"Тэкставае паведамленне на пэйджар"</string>
+    <string name="sms_other" msgid="806127844607642331">"Тэкст"</string>
+    <string name="sms_callback" msgid="5004824430094288752">"Тэкст на нумар зваротнага выкліку"</string>
+    <string name="sms_car" msgid="7444227058437359641">"Тэкставае паведамленне ў аўтамабіль"</string>
+    <string name="sms_company_main" msgid="118970873419678087">"Паведамленне на асноўны нумар кампаніі"</string>
+    <string name="sms_isdn" msgid="8153785037515047845">"Тэкст ISDN"</string>
+    <string name="sms_main" msgid="8621625784504541679">"Паведамленне на асноўны нумар"</string>
+    <string name="sms_other_fax" msgid="3888842199855843152">"Тэкставае паведамленне на факс"</string>
+    <string name="sms_radio" msgid="3329166673433967820">"Тэкставае паведамленее на радыётэлефон"</string>
+    <string name="sms_telex" msgid="9034802430065267848">"Тэкставае паведамленне на тэлекс"</string>
+    <string name="sms_tty_tdd" msgid="6782284969132531532">"Тэкставае паведамленне на TTY/TDD"</string>
+    <string name="sms_work_mobile" msgid="2459939960512702560">"Тэкставае паведамленне на працоўны мабільны тэлефон"</string>
+    <string name="sms_work_pager" msgid="5566924423316960597">"Тэкставае паведамленне на працоўны пэйджар"</string>
+    <string name="sms_assistant" msgid="2773424339923116234">"Напiсаць тэкставае паведамленне: <xliff:g id="ASSISTANT">%s</xliff:g>"</string>
+    <string name="sms_mms" msgid="4069352461380762677">"Паведамленне MMS"</string>
+    <string name="sms_by_shortcut" msgid="7741770672976099517">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (Паведамленне)"</string>
+    <string name="description_video_call" msgid="7120921378651700947">"Зрабіць відэавыклік"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Выдалiць частыя кантакты?"</string>
+    <string name="clearFrequentsConfirmation" msgid="2270554975938265734">"Спіс найчасцей ужываных кантактаў праграм \"Кантакты\" i \"Тэлефон\" ачысціцца, а параметры адрасацыі паштовых праграм абнуляцца."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Выдаленне частых кантактаў..."</string>
+    <string name="status_available" msgid="5586870015822828392">"Даступны"</string>
+    <string name="status_away" msgid="1838861100379804730">"Адсутнічае"</string>
+    <string name="status_busy" msgid="9147992455450257136">"Заняты"</string>
+    <string name="contactsList" msgid="8661624236494819731">"Кантакты"</string>
+    <string name="local_invisible_directory" msgid="6046691709127661065">"Іншае"</string>
+    <string name="directory_search_label" msgid="1887759056597975053">"Дырэкторыя"</string>
+    <string name="directory_search_label_work" msgid="8618292129829443176">"Працоўны каталог"</string>
+    <string name="local_search_label" msgid="2551177578246113614">"Усе кантакты"</string>
+    <string name="search_results_searching" msgid="3984833028938569930">"Пошук..."</string>
+    <string name="foundTooManyContacts" msgid="5163335650920020220">"Знойдзена вынікаў: больш за <xliff:g id="COUNT">%d</xliff:g>."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Кантактаў няма"</string>
+    <plurals name="searchFoundContacts" formatted="false" msgid="7223023725334884618">
+      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> знойдзены</item>
+      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> знойдзены</item>
+      <item quantity="many"><xliff:g id="COUNT">%d</xliff:g> знойдзена</item>
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> знойдзена</item>
+    </plurals>
+    <string name="description_quick_contact_for" msgid="6737516415168327789">"Хуткі кантакт для карыстальніка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="missing_name" msgid="8745511583852904385">"(Без назвы)"</string>
+    <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Частая сувязь"</string>
+    <string name="description_view_contact_detail" msgid="9133251213656414807">"Прагледзець кантакт"</string>
+    <string name="list_filter_phones" msgid="735313795643493365">"Усе кантакты з нумарамі тэлефонаў"</string>
+    <string name="list_filter_phones_work" msgid="1470173699551475015">"Кантакты працоўнага профілю"</string>
+    <string name="view_updates_from_group" msgid="1782685984905600034">"Прагл. абнаўленняў"</string>
+    <string name="account_phone" msgid="7128032778471187553">"Прылада"</string>
+    <string name="nameLabelsGroup" msgid="2034640839640477827">"Імя"</string>
+    <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Псеўданiм"</string>
+    <string name="full_name" msgid="6602579550613988977">"Iмя"</string>
+    <string name="name_given" msgid="4280790853455320619">"Імя"</string>
+    <string name="name_family" msgid="7466985689626017037">"Прозвішча"</string>
+    <string name="name_prefix" msgid="59756378548779822">"Прэфікс імені"</string>
+    <string name="name_middle" msgid="8467433655992690326">"Імя па бацьку"</string>
+    <string name="name_suffix" msgid="3855278445375651441">"Суфікс да імені"</string>
+    <string name="name_phonetic" msgid="4259595234312430484">"Фанетычны запіс імя"</string>
+    <string name="name_phonetic_given" msgid="8723179018384187631">"Вымаўленне імя"</string>
+    <string name="name_phonetic_middle" msgid="8643721493320405200">"Фанетычны запіс імя па бацьку"</string>
+    <string name="name_phonetic_family" msgid="2640133663656011626">"Вымаўленне прозвішча"</string>
+    <string name="phoneLabelsGroup" msgid="6468091477851199285">"Тэлефон"</string>
+    <string name="emailLabelsGroup" msgid="8389931313045344406">"Электронная пошта"</string>
+    <string name="postalLabelsGroup" msgid="3487738141112589324">"Адрас"</string>
+    <string name="imLabelsGroup" msgid="3898238486262614027">"ІМ"</string>
+    <string name="organizationLabelsGroup" msgid="2478611760751832035">"Арганізацыя"</string>
+    <string name="relationLabelsGroup" msgid="1854373894284572781">"Сувязі"</string>
+    <string name="eventLabelsGroup" msgid="7960408705307831289">"Асаблівая дата"</string>
+    <string name="sms" msgid="1756857139634224222">"Тэкставае паведамленне"</string>
+    <string name="postal_address" msgid="8765560217149624536">"Адрас"</string>
+    <string name="ghostData_company" msgid="5414421120553765775">"Кампанія"</string>
+    <string name="ghostData_title" msgid="7496735200318496110">"Назва"</string>
+    <string name="label_notes" msgid="8337354953278341042">"Нататкі"</string>
+    <!-- no translation found for label_custom_field (1994056912242214426) -->
+    <skip />
+    <string name="label_sip_address" msgid="7252153678613978127">"SIP"</string>
+    <string name="websiteLabelsGroup" msgid="4202998982804009261">"Вэб-старонка"</string>
+    <string name="groupsLabel" msgid="7000816729542098972">"Меткі"</string>
+    <string name="email_home" msgid="8573740658148184279">"Паведамленне на хатні адрас электроннай пошты"</string>
+    <string name="email_mobile" msgid="2042889209787989814">"Адправіць электронную пошту на мабільны адрас"</string>
+    <string name="email_work" msgid="2807430017302722689">"Паведамленне на працоўную электронную пошту"</string>
+    <string name="email_other" msgid="3454004077967657109">"Электронная пошта"</string>
+    <string name="email_custom" msgid="7548003991586214105">"Напiсаць паведамленне на <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="email" msgid="5668400997660065897">"Электронная пошта"</string>
+    <string name="postal_street" msgid="8133143961580058972">"Вуліца"</string>
+    <string name="postal_pobox" msgid="4431938829180269821">"Паштовая скрыня"</string>
+    <string name="postal_neighborhood" msgid="1450783874558956739">"Наваколле"</string>
+    <string name="postal_city" msgid="6597491300084895548">"Горад"</string>
+    <string name="postal_region" msgid="6045263193478437672">"Штат"</string>
+    <string name="postal_postcode" msgid="572136414136673751">"Паштовы індэкс"</string>
+    <string name="postal_country" msgid="7638264508416368690">"Краіна"</string>
+    <string name="map_home" msgid="1243547733423343982">"Прагледзець хатні адрас"</string>
+    <string name="map_work" msgid="1360474076921878088">"Паглядзець працоўны адрас"</string>
+    <string name="map_other" msgid="3817820803587012641">"Прагледзець адрас"</string>
+    <string name="map_custom" msgid="6184363799976265281">"Прагледзець адрас <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="chat_aim" msgid="2588492205291249142">"Чат у AIM"</string>
+    <string name="chat_msn" msgid="8041633440091073484">"Чат у Windows Live"</string>
+    <string name="chat_yahoo" msgid="6629211142719943666">"Чат праз Yahoo"</string>
+    <string name="chat_skype" msgid="1210045020427480566">"Чат у Skype"</string>
+    <string name="chat_qq" msgid="4294637812847719693">"Чат у QQ"</string>
+    <string name="chat_gtalk" msgid="981575737258117697">"Чат у Google Talk"</string>
+    <string name="chat_icq" msgid="8438405386153745775">"Чат праз ICQ"</string>
+    <string name="chat_jabber" msgid="7561444230307829609">"Чат у Jabber"</string>
+    <string name="chat" msgid="9025361898797412245">"Чат"</string>
+    <string name="description_minus_button" msgid="6908099247930477551">"выдаліць"</string>
+    <string name="expand_collapse_name_fields_description" msgid="8682630859539604311">"Разгарнуць ці згарнуць назвы палёў"</string>
+    <string name="expand_collapse_phonetic_name_fields_description" msgid="3306777588073354509">"Разгарнуць ці згарнуць палі вымаўлення імён"</string>
+    <string name="list_filter_all_accounts" msgid="8908683398914322369">"Усе кантакты"</string>
+    <string name="list_filter_all_starred" msgid="5031734941601931356">"Пазначана"</string>
+    <string name="list_filter_customize" msgid="4789963356004169321">"Карыстальнiцкi"</string>
+    <string name="list_filter_single" msgid="5871400283515893087">"Кантакт"</string>
+    <string name="display_ungrouped" msgid="6885954210243119591">"Усе кантакты з тэчкі \"Іншыя\""</string>
+    <string name="display_all_contacts" msgid="2031647544742889505">"Усе кантакты"</string>
+    <string name="menu_sync_remove" msgid="3266725887008450161">"Выдаліць групу сінхранізацыі"</string>
+    <string name="dialog_sync_add" msgid="8267045393119375803">"Дадаць групу сінхранізацыі"</string>
+    <string name="display_more_groups" msgid="2682547080423434170">"Больш груп..."</string>
+    <string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"Выдаленне групы \"<xliff:g id="GROUP">%s</xliff:g>\" з сінхранізацыі таксама выдаліць любыя разгрупаваныя кантакты з сінхранізацыі."</string>
+    <string name="savingDisplayGroups" msgid="2133152192716475939">"Захаванне параметраў адлюстравання..."</string>
+    <string name="menu_done" msgid="796017761764190697">"Зроблена"</string>
+    <string name="menu_doNotSave" msgid="58593876893538465">"Адмена"</string>
+    <string name="listCustomView" msgid="1840624396582117590">"Карыстальніцкі выгляд"</string>
+    <string name="dialog_new_contact_account" msgid="4969619718062454756">"Захаваць імпартаваныя кантакты ў:"</string>
+    <string name="import_from_sim" msgid="3859272228033941659">"Імпарт з SIM-карты"</string>
+    <string name="import_from_sim_summary" msgid="5815105584445743740">"Імпартаваць з SIM-карты <xliff:g id="SIM_NAME">^1</xliff:g> – <xliff:g id="SIM_NUMBER">^2</xliff:g>"</string>
+    <string name="import_from_sim_summary_no_number" msgid="880612418352086012">"Імпартаваць з SIM-карты <xliff:g id="SIM_NAME">%1$s</xliff:g>"</string>
+    <string name="import_from_vcf_file" product="default" msgid="5304572242183878086">"Імпартаваць з файла .vcf"</string>
+    <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Адмянiць iмпарт файла <xliff:g id="FILENAME">%s</xliff:g>?"</string>
+    <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Адмянiць экспарт файла <xliff:g id="FILENAME">%s</xliff:g>?"</string>
+    <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Немагчыма адмяніць імпарт/экспарт vCard"</string>
+    <string name="fail_reason_unknown" msgid="1714092345030570863">"Невядомая памылка."</string>
+    <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Немагчыма адкрыць файл \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>"</string>
+    <string name="fail_reason_could_not_initialize_exporter" msgid="707260459259688510">"Не атрымалася запусцiць экспарцёр: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
+    <string name="fail_reason_no_exportable_contact" msgid="8728506011371262065">"Няма кантактаў для экспарту."</string>
+    <string name="missing_required_permission" msgid="5865884842972833120">"Вы адключылі дазвол, які патрабуецца."</string>
+    <string name="fail_reason_error_occurred_during_export" msgid="3018855323913649063">"Памылка экспарту: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
+    <string name="fail_reason_too_long_filename" msgid="3393764245254738333">"Патрабаванае імя файла (\"<xliff:g id="FILENAME">%s</xliff:g>\") занадта доўгае."</string>
+    <string name="fail_reason_io_error" msgid="6748358842976073255">"Памылка ўводу/вываду"</string>
+    <string name="fail_reason_low_memory_during_import" msgid="875222757734882898">"Недастаткова памяці (магчыма, занадта вялікі файл)"</string>
+    <string name="fail_reason_vcard_parse_error" msgid="888263542360355784">"Немагчыма разабраць файл vCard па нечаканай прычыне."</string>
+    <string name="fail_reason_not_supported" msgid="8219562769267148825">"Фармат не падтрымліваецца."</string>
+    <string name="fail_reason_failed_to_collect_vcard_meta_info" msgid="6427931733267328564">"Немагчыма сабраць мета-інфармацыю з гэтых файлаў vCard."</string>
+    <string name="fail_reason_failed_to_read_files" msgid="5823434810622484922">"Адзін або некалькі файлаў не могуць быць імпартаваныя (%s)."</string>
+    <string name="exporting_vcard_finished_title" msgid="4767045779458185251">"Экспарт файла <xliff:g id="FILENAME">%s</xliff:g> завершаны."</string>
+    <string name="exporting_vcard_finished_title_fallback" msgid="6060472638008218274">"Экспартаванне кантактаў завершана."</string>
+    <string name="exporting_vcard_finished_toast" msgid="1739055986856453882">"Экспартаванне кантактаў завершана, націсніце на апавяшчэнне, каб абагуліць кантакты."</string>
+    <string name="touch_to_share_contacts" msgid="4882485525268469736">"Дакраніцеся, каб абагуліць кантакты."</string>
+    <string name="exporting_vcard_canceled_title" msgid="2652222370493306887">"Экспарт файла <xliff:g id="FILENAME">%s</xliff:g> адменены."</string>
+    <string name="exporting_contact_list_title" msgid="9072240631534457415">"Экспарт дадзеных кантакту"</string>
+    <string name="exporting_contact_list_message" msgid="3367949209642931952">"Кантактныя даныя экспартуюцца."</string>
+    <string name="composer_failed_to_get_database_infomation" msgid="1765944280846236723">"Немагчыма атрымаць інфармацыю з базы дадзеных."</string>
+    <string name="composer_has_no_exportable_contact" msgid="3296493229040294335">"Няма кантактаў, якiя можна экспартаваць. Калi ў вашым тэлефоне няма кантактаў, некаторыя пастаўшчыкi дадзеных могуць забараняць экспарт кантактаў з тэлефона."</string>
+    <string name="composer_not_initialized" msgid="2321648986367005254">"Памылка запуску складальнiка файлаў vCard."</string>
+    <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Не атрымалася экспартаваць"</string>
+    <string name="exporting_contact_failed_message" msgid="4938527850142003141">"Памылка экспарта кантактных дадзеных. \nПрычына: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\""</string>
+    <string name="importing_vcard_description" msgid="4245275224298571351">"Імпарт <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="reading_vcard_failed_title" msgid="4251647443358422855">"Немагчыма прачытаць дадзеныя vCard"</string>
+    <string name="reading_vcard_canceled_title" msgid="1925216585981542019">"Чытанне дадзеных з vCard адменена"</string>
+    <string name="importing_vcard_finished_title" msgid="3341541727268747967">"Заканчэнне імпартавання vCard <xliff:g id="FILENAME">%s</xliff:g>"</string>
+    <string name="importing_vcard_canceled_title" msgid="2147475978165599336">"Імпарт файла <xliff:g id="FILENAME">%s</xliff:g> адменены"</string>
+    <string name="vcard_import_will_start_message" msgid="2804911199145873396">"Файл <xliff:g id="FILENAME">%s</xliff:g> будзе імпартаваны ў бліжэйшы час."</string>
+    <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"Файл будзе імпартаваны ў бліжэйшы час."</string>
+    <string name="vcard_import_request_rejected_message" msgid="2890471184508516011">"Запыт экспарту vCard адхілены. Паспрабуйце пазней."</string>
+    <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Файл <xliff:g id="FILENAME">%s</xliff:g> будзе экспартаваны ў бліжэйшы час."</string>
+    <string name="vcard_export_will_start_message_fallback" msgid="6553826997490909749">"Неўзабаве файл будзе экспартаваны."</string>
+    <string name="contacts_export_will_start_message" msgid="8538705791417534431">"Неўзабаве кантакты будуць экспартаваны."</string>
+    <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Запыт экспарту vCard адхілены. Паспрабуйце пазней."</string>
+    <string name="vcard_unknown_filename" msgid="7171709890959915954">"кантакт"</string>
+    <string name="caching_vcard_message" msgid="4926308675041506756">"Кэшуе файлы vCard у лакальнае часовае сховішча. Фактычны імпарт пачнецца ў бліжэйшы час."</string>
+    <string name="vcard_import_failed" msgid="5223531255894842406">"Немагчыма імпартаваць vCard."</string>
+    <string name="nfc_vcard_file_name" msgid="2823095213265993609">"Кант. атр. праз NFC"</string>
+    <string name="confirm_export_title" msgid="6834385377255286349">"Экспартаваць кантакты?"</string>
+    <string name="caching_vcard_title" msgid="1226272312940516605">"Кэшаванне..."</string>
+    <string name="progress_notifier_message" msgid="2311011466908220528">"Імпарт <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="export_to_vcf_file" product="default" msgid="4407527157056120858">"Экспартаваць у файл .vcf"</string>
+    <string name="display_options_sort_list_by" msgid="7028809117272018712">"Сартаваць па"</string>
+    <string name="display_options_sort_by_given_name" msgid="2778421332815687873">"Імя"</string>
+    <string name="display_options_sort_by_family_name" msgid="2684905041926954793">"Прозвішча"</string>
+    <string name="display_options_view_names_as" msgid="6514632499276563482">"Фармат імя"</string>
+    <string name="display_options_view_given_name_first" msgid="3616004640258761473">"Спачатку імя"</string>
+    <string name="display_options_view_family_name_first" msgid="956445100777296467">"Спачатку прозвішча"</string>
+    <string name="settings_accounts" msgid="350219740670774576">"Уліковыя запісы"</string>
+    <string name="default_editor_account" msgid="699591683362420991">"Стандартны ўліковы запіс для новых кантактаў"</string>
+    <string name="sync_contact_metadata_title" msgid="6957956139306960211">"Сінхранізаваць метаданыя кантактаў [DOGFOOD]"</string>
+    <string name="sync_contact_metadata_dialog_title" msgid="6192335951588820553">"Сінхранізаваць метаданыя кантактаў"</string>
+    <string name="settings_my_info_title" msgid="1534272456405343119">"Мая інфармацыя"</string>
+    <string name="set_up_profile" msgid="7370213843590143771">"Наладзьце ваш профіль"</string>
+    <string name="setting_about" msgid="7014388749752042863">"Інфармацыя аб Кантактах"</string>
+    <string name="activity_title_settings" msgid="5464130076132770781">"Налады"</string>
+    <string name="share_visible_contacts" msgid="890150378880783797">"Адкрыць бачныя кантакты"</string>
+    <string name="share_visible_contacts_failure" msgid="7324717548166915560">"Збой абагульвання бачных кантактаў."</string>
+    <string name="share_favorite_contacts" msgid="4280926751003081042">"Абагуліць улюбёныя кантакты"</string>
+    <string name="share_contacts" msgid="8109287987498711664">"Абагуліць усе кантакты"</string>
+    <string name="share_contacts_failure" msgid="1216431977330560559">"Збой абагульвання кантактаў."</string>
+    <string name="dialog_import_export" msgid="4360648034889921624">"Імпарт/экспарт кантактаў"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Імпартаваць кантакты"</string>
+    <string name="share_error" msgid="948429331673358107">"Нельга падзялiцца гэтым кантактам."</string>
+    <string name="no_contact_to_share" msgid="1276397530378323033">"Няма кантактаў, якія можна абагуліць."</string>
+    <string name="menu_search" msgid="9147752853603483719">"Пошук"</string>
+    <string name="menu_contacts_filter" msgid="2165153460860262501">"Паказаць кантакты"</string>
+    <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Кантакты для адлюстр."</string>
+    <string name="custom_list_filter" msgid="2105275443109077687">"Вызначыце карыстальніцкі выгляд"</string>
+    <string name="menu_custom_filter_save" msgid="2679793632208086460">"Захаваць"</string>
+    <string name="hint_findContacts" msgid="7128627979899070325">"Шукаць у кантактах"</string>
+    <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Выбранае"</string>
+    <string name="listTotalAllContactsZero" msgid="5513001821794568211">"Няма кантактаў."</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Выдалiць частыя кантакты"</string>
+    <string name="menu_select_sim" msgid="3603578201960504010">"Выбраць SIM-карту"</string>
+    <string name="menu_accounts" msgid="1424330057450189074">"Кіраваць уліковымі запісамі"</string>
+    <string name="menu_import_export" msgid="26217871113229507">"Імпарт/экспарт"</string>
+    <string name="menu_blocked_numbers" msgid="5272951629083025995">"Заблакіраваныя нумары"</string>
+    <string name="contact_status_update_attribution" msgid="752179367353018597">"праз <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
+    <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g> праз <xliff:g id="SOURCE">%2$s</xliff:g>"</string>
+    <string name="action_menu_back_from_search" msgid="8793348588949233348">"спыніць пошук"</string>
+    <string name="description_clear_search" msgid="688023606766232904">"Ачысціць пошук"</string>
+    <string name="settings_contact_display_options_title" msgid="4890258244494248687">"Параметры адлюстравання кантактаў"</string>
+    <string name="select_account_dialog_title" msgid="5478489655696599219">"Уліковы запіс"</string>
+    <string name="set_default_account" msgid="4311613760725609801">"Заўсёды ўжываць гэта для выклікаў"</string>
+    <string name="select_phone_account_for_calls" msgid="3810607744451014540">"Выклікаць праз"</string>
+    <string name="call_with_a_note" msgid="8389827628360791676">"Выклікаць з нататкай"</string>
+    <string name="call_subject_hint" msgid="3637498418381454511">"Увядзіце нататку, якую хочаце адправіць разам з выклікам…"</string>
+    <string name="send_and_call_button" msgid="7740295432834590737">"АДПРАВІЦЬ І ВЫКЛІКАЦЬ"</string>
+    <string name="call_subject_limit" msgid="4545212901205397669">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
+    <string name="call_subject_type_and_number" msgid="7667188212129152558">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+    <plurals name="tab_title_with_unread_items" formatted="false" msgid="7682024005130747825">
+      <item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрачытаны элемент. </item>
+      <item quantity="few"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрачытаныя элементы. </item>
+      <item quantity="many"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрачытаных элементаў. </item>
+      <item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрачытанага элемента. </item>
+    </plurals>
+    <string name="about_build_version" msgid="1765533099416999801">"Версія зборкі"</string>
+    <string name="about_open_source_licenses" msgid="6479990452352919641">"Ліцэнзіі на ПЗ з адкрытым зыходным кодам"</string>
+    <string name="about_open_source_licenses_summary" msgid="57418386931763994">"Звесткі аб ліцэнзіі на праграмнае забеспячэнне з адкрытым зыходным кодам"</string>
+    <string name="about_privacy_policy" msgid="3705518622499152626">"Палітыка прыватнасці"</string>
+    <string name="about_terms_of_service" msgid="4642400812150296723">"Умовы абслугоўвання"</string>
+    <string name="activity_title_licenses" msgid="5467767062737708066">"Ліцэнзіі на ПЗ з адкрытым зыходным кодам"</string>
+    <string name="url_open_error_toast" msgid="452592089815420457">"Збой адкрыцця URL-адраса."</string>
+    <string name="account_filter_view_checked" msgid="6696859503887762213">"<xliff:g id="ACCOUNT_INFO">%s</xliff:g> - пазначана"</string>
+    <string name="account_filter_view_not_checked" msgid="2248684521205038389">"<xliff:g id="ACCOUNT_INFO">%s</xliff:g> - не пазначана"</string>
+    <string name="description_search_video_call" msgid="5841525580339803272">"Пачаць відэавыклік"</string>
+    <string name="description_delete_contact" msgid="53835657343783663">"Выдаліць"</string>
+    <string name="description_no_name_header" msgid="8884991311595943271">"Шматкроп\'е"</string>
+    <!-- no translation found for callDurationSecondFormat (7067644915903528776) -->
+    <skip />
+    <!-- no translation found for callDurationMinuteFormat (4647095486747447674) -->
+    <skip />
+    <!-- no translation found for callDurationHourFormat (7392254193808506640) -->
+    <skip />
 </resources>
diff --git a/res/values-bs-rBA-sw600dp/strings.xml b/res/values-bs-rBA-sw600dp/strings.xml
new file mode 100644
index 0000000..6b0ac29
--- /dev/null
+++ b/res/values-bs-rBA-sw600dp/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2012 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="account_phone" msgid="347665663520819575">"Uređaj"</string>
+    <string name="composer_has_no_exportable_contact" msgid="5998889616701036804">"Nema kontakata koji se mogu izvoziti. Ako imate kontakte na tabletu, neki dobavljači podataka možda ne dozvoljavaju izvoz kontakata s tableta."</string>
+</resources>
diff --git a/res/values-bs-rBA/strings.xml b/res/values-bs-rBA/strings.xml
index 67f5166..9145837 100644
--- a/res/values-bs-rBA/strings.xml
+++ b/res/values-bs-rBA/strings.xml
@@ -17,9 +17,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="applicationLabel" msgid="3906689777043645443">"Kontakti"</string>
-    <string name="launcherActivityLabel" msgid="6497230399032392417">"Kontakti"</string>
-    <string name="quickContactActivityLabel" msgid="7985456650689347268">"Prikaži kontakt"</string>
-    <string name="editContactActivityLabel" msgid="1129944572070802839">"Uredi kontakt"</string>
     <string name="contactsList" msgid="8661624236494819731">"Kontakti"</string>
     <string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
     <string name="shortcutDialContact" msgid="746622101599186779">"Direktno biranje"</string>
@@ -31,12 +28,7 @@
     <string name="contactPickerActivityTitle" msgid="4301062192337417640">"Izaberi kontakt"</string>
     <string name="groupMemberPickerActivityTitle" msgid="1431750793695262522">"Odaberi"</string>
     <string name="header_entry_contact_list_adapter_header_title" msgid="2436981165830115659">"Napravi novi kontakt"</string>
-    <string name="starredList" msgid="4817256136413959463">"Označeno zvijezdom"</string>
-    <string name="frequentList" msgid="7154768136473953056">"Često kontaktirani"</string>
-    <string name="strequentList" msgid="5640192862059373511">"Favoriti"</string>
     <string name="viewContactTitle" msgid="7989394521836644384">"Detalji o kontaktu"</string>
-    <string name="editContactDescription" msgid="2947202828256214947">"Uredi kontakt"</string>
-    <string name="insertContactDescription" msgid="4709878105452681987">"Napravi kontakt"</string>
     <string name="contactDetailAbout" msgid="5430408883907061400">"O kontaktu"</string>
     <string name="contactDetailUpdates" msgid="3780588624763446941">"Ažuriranja"</string>
     <string name="searchHint" msgid="8482945356247760701">"Traži kontakte"</string>
@@ -52,7 +44,7 @@
     <string name="menu_call" msgid="3992595586042260618">"Pozovi kontakt"</string>
     <string name="menu_sendSMS" msgid="5535886767547006515">"Pošalji tekstualnu poruku kontaktu"</string>
     <string name="menu_splitAggregate" msgid="2627252205317945563">"Razdvoji"</string>
-    <string name="menu_editGroup" msgid="5062005185370983720">"Uredi"</string>
+    <string name="menu_editGroup" msgid="6696843438454341063">"Ukloni kontakte"</string>
     <string name="menu_renameGroup" msgid="7169512355179757182">"Preimenuj oznaku"</string>
     <string name="menu_deleteGroup" msgid="1126469629233412249">"Izbriši oznaku"</string>
     <string name="menu_addToGroup" msgid="3267409983764370041">"Dodaj kontakt"</string>
@@ -80,10 +72,15 @@
       <item quantity="few">Kontakti su izbrisani</item>
       <item quantity="other">Kontakti su izbrisani</item>
     </plurals>
-    <plurals name="contacts_count" formatted="false" msgid="3287407967505649458">
-      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> kontakt</item>
-      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> kontakta</item>
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> kontakata</item>
+    <plurals name="contacts_count" formatted="false" msgid="8696793457340503668">
+      <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> kontakt</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> kontakta</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> kontakata</item>
+    </plurals>
+    <plurals name="contacts_count_with_account" formatted="false" msgid="7402583111980220575">
+      <item quantity="one"><xliff:g id="COUNT_2">%d</xliff:g> kontakt · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="few"><xliff:g id="COUNT_2">%d</xliff:g> kontakta · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
+      <item quantity="other"><xliff:g id="COUNT_2">%d</xliff:g> kontakata · <xliff:g id="ACCOUNT_3">%s</xliff:g></item>
     </plurals>
     <string name="title_from_google" msgid="4664084747121207202">"Sa Googlea"</string>
     <string name="title_from_other_accounts" msgid="8307885412426754288">"Sa računa <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
@@ -111,10 +108,12 @@
     <string name="customLabelPickerTitle" msgid="1081475101983255212">"Prilagođeni naziv oznake"</string>
     <string name="send_to_voicemail_checkbox" msgid="9001686764070676353">"Pošalji pozive direktno na govornu poštu"</string>
     <string name="removePhoto" msgid="4898105274130284565">"Ukloni fotografiju"</string>
-    <string name="noContacts" msgid="4955659076981974652">"Nema kontakata"</string>
+    <string name="noContacts" msgid="2228592924476426108">"Spisak kontakata je prazan"</string>
     <string name="noGroups" msgid="4607906327968232225">"Nema oznaka."</string>
     <string name="noAccounts" msgid="7768267764545265909">"Potreban vam je račun da napravite grupe."</string>
     <string name="emptyGroup" msgid="5102411903247859575">"Nema kontakata s ovom oznakom"</string>
+    <string name="emptyAccount" msgid="6873962901497975964">"Nema kontakata na ovom računu"</string>
+    <string name="emptyMainList" msgid="2772242747899664460">"Spisak kontakata je prazan"</string>
     <string name="contactSavedToast" msgid="9171862279493213075">"Kontakt je sačuvan"</string>
     <string name="contactUnlinkedToast" msgid="7122823195786012553">"Kontakti su razdvojeni"</string>
     <string name="contactSavedErrorToast" msgid="3207250533172944892">"Nije moguće sačuvati promjene kontakta."</string>
@@ -131,6 +130,7 @@
     <string name="groupMembersRemovedToast" msgid="3510563559799376603">"Uklonjeno iz oznake"</string>
     <string name="groupMembersAddedToast" msgid="4824834898718972768">"Dodano oznaci"</string>
     <string name="groupSavedErrorToast" msgid="8121032018490980184">"Nije moguće sačuvati promjene oznake."</string>
+    <string name="groupExistsErrorMessage" msgid="5196811283836946189">"Ta oznaka već postoji"</string>
     <plurals name="listTotalPhoneContacts" formatted="false" msgid="3692277679143308755">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> kontakt s brojem telefona</item>
       <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> kontakta s brojevima telefona</item>
@@ -223,8 +223,7 @@
     <string name="social_widget_loading" msgid="5327336597364074608">"Učitavanje…"</string>
     <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Napravi novi kontakt"</string>
     <string name="contacts_unavailable_add_account" msgid="4347232421410561500">"Dodaj račun"</string>
-    <string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Uvezi kontakte"</string>
-    <string name="create_group_dialog_title" msgid="5363404287877384473">"Napravi novu oznaku"</string>
+    <string name="contacts_unavailable_import_contacts" msgid="3182801738595937144">"Uvezi"</string>
     <string name="create_group_item_label" msgid="3263064599743742865">"Napravi novu…"</string>
     <string name="delete_group_dialog_message" msgid="335713829185261371">"Izbrisati oznaku \"<xliff:g id="GROUP_LABEL">%1$s</xliff:g>\"? (Kontakti neće biti izbrisani.)"</string>
     <string name="toast_join_with_empty_contact" msgid="1215465657839085613">"Upišite ime kontakta prije povezivanja s drugim kontaktom."</string>
@@ -232,24 +231,23 @@
     <string name="set_default" msgid="4417505153468300351">"Postavi zadano"</string>
     <string name="clear_default" msgid="7193185801596678067">"Obriši zadano"</string>
     <string name="toast_text_copied" msgid="5143776250008541719">"Tekst je kopiran"</string>
-    <string name="cancel_confirmation_dialog_message" msgid="5058226498605989285">"Želite li odbaciti napravljene promjene i prekinuti uređivanje?"</string>
+    <string name="cancel_confirmation_dialog_message" msgid="9008214737653278989">"Odbaciti promjene?"</string>
     <string name="cancel_confirmation_dialog_cancel_editing_button" msgid="3057023972074640671">"Odbaci"</string>
-    <string name="cancel_confirmation_dialog_keep_editing_button" msgid="7737724111972855348">"Nastavi uređivanje"</string>
+    <string name="cancel_confirmation_dialog_keep_editing_button" msgid="3316573928085916146">"Otkaži"</string>
+    <string name="leave_customize_confirmation_dialog_message" msgid="4277114551206032979">"Odbaciti prilagođavanja?"</string>
     <string name="call_type_and_date" msgid="747163730039311423">"<xliff:g id="CALL_TYPE">%1$s</xliff:g> <xliff:g id="CALL_SHORT_DATE">%2$s</xliff:g>"</string>
     <string name="enter_contact_name" msgid="4594274696120278368">"Traži kontakte"</string>
-    <!-- no translation found for title_edit_group (1889302367574226969) -->
-    <skip />
+    <string name="title_edit_group" msgid="8602752287270586734">"Ukloni kontakte"</string>
     <string name="local_profile_title" msgid="2021416826991393684">"Moj lokalni profil"</string>
     <string name="external_profile_title" msgid="8034998767621359438">"Moj profil <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g>"</string>
     <string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Prikazuju se svi kontakti"</string>
     <string name="generic_no_account_prompt" msgid="7218827704367325460">"Očuvajte sigurnost svojih kontakata čak i ako izgubite telefon: sinhronizirajte ih s mrežnom uslugom."</string>
     <string name="generic_no_account_prompt_title" msgid="753783911899054860">"Dodajte račun"</string>
-    <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Neće biti napravljena sigurnosna kopija novog računa. Dodati račun za pravljenje sigurnosnih kopija kontakata na mreži?"</string>
+    <string name="contact_editor_prompt_zero_accounts" msgid="6648376557574360096">"Odvojite trenutak da dodate račun putem kojeg će se kontakti sigurnosno kopirati na Google."</string>
     <string name="contact_editor_prompt_one_account" msgid="3087691056345099310">"Novi kontakti će biti sačuvani na račun <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
     <string name="contact_editor_prompt_multiple_accounts" msgid="8565761674283473549">"Izaberite zadani račun za nove kontakte:"</string>
     <string name="contact_editor_title_new_contact" msgid="7192223018128934940">"Dodaj novi kontakt"</string>
     <string name="contact_editor_title_existing_contact" msgid="4898475703683187798">"Uredi kontakt"</string>
-    <string name="keep_local" msgid="1258761699192993322">"Zadrži na uređaju"</string>
     <string name="add_account" msgid="8201790677994503186">"Dodajte račun"</string>
     <string name="add_new_account" msgid="5748627740680940264">"Dodaj novi račun"</string>
     <string name="menu_export_database" msgid="2659719297530170820">"Izvezi fajlove baze podataka"</string>
@@ -261,7 +259,6 @@
     <string name="about_card_title" msgid="2920942314212825637">"O kontaktu"</string>
     <string name="send_message" msgid="8938418965550543196">"Pošalji poruku"</string>
     <string name="toast_making_personal_copy" msgid="288549957278065542">"Izrađivanje lične kopije u toku…"</string>
-    <string name="yesterday" msgid="6840858548955018569">"Jučer"</string>
     <string name="tomorrow" msgid="6241969467795308581">"Sutra"</string>
     <string name="today" msgid="8041090779381781781">"Danas"</string>
     <string name="today_at_time_fmt" msgid="605665249491030460">"Danas u <xliff:g id="TIME_INTERVAL">%s</xliff:g>"</string>
@@ -346,4 +343,275 @@
     <string name="permission_explanation_subheader_calendar_and_SMS" msgid="630115334220569184">"Događaji i poruke"</string>
     <string name="permission_explanation_subheader_calendar" msgid="8785323496211704613">"Događaji"</string>
     <string name="permission_explanation_subheader_SMS" msgid="1904552086449525567">"Poruke"</string>
+    <string name="hamburger_feature_highlight_header" msgid="7442308698936786415">"Organizirajte spisak"</string>
+    <string name="hamburger_feature_highlight_body" msgid="6268711111318172098">"Uklonite duplikate i grupirajte kontakte prema oznaci"</string>
+    <string name="undo" msgid="1425165101664071422">"Opozovi radnju"</string>
+    <string name="toast_text_copied" msgid="5143776250008541719">"Tekst je kopiran"</string>
+    <string name="copy_text" msgid="3257145021583508761">"Kopiraj u međumemoriju"</string>
+    <string name="call_custom" msgid="7756571794763171802">"Pozovi <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="call_home" msgid="1990519474420545392">"Pozovi kuću"</string>
+    <string name="call_mobile" msgid="7502236805487609178">"Pozovi mobitel"</string>
+    <string name="call_work" msgid="5328785911463744028">"Pozovi posao"</string>
+    <string name="call_fax_work" msgid="7467763592359059243">"Pozovi poslovni faks"</string>
+    <string name="call_fax_home" msgid="8342175628887571876">"Pozovi kućni faks"</string>
+    <string name="call_pager" msgid="9003902812293983281">"Pozovi pejdžer"</string>
+    <string name="call_other" msgid="8563753966926932052">"Pozovi"</string>
+    <string name="call_callback" msgid="1910165691349426858">"Pozovi broj za uzvraćanje poziva"</string>
+    <string name="call_car" msgid="3280537320306436445">"Pozovi automobil"</string>
+    <string name="call_company_main" msgid="6105120947138711257">"Pozovi glavni broj kompanije"</string>
+    <string name="call_isdn" msgid="1541590690193403411">"Pozovi ISDN"</string>
+    <string name="call_main" msgid="6082900571803441339">"Pozovi glavni broj"</string>
+    <string name="call_other_fax" msgid="5745314124619636674">"Pozovi faks"</string>
+    <string name="call_radio" msgid="8296755876398357063">"Pozovi radio"</string>
+    <string name="call_telex" msgid="2223170774548648114">"Pozovi teleks"</string>
+    <string name="call_tty_tdd" msgid="8951266948204379604">"Pozovi TTY/TDD"</string>
+    <string name="call_work_mobile" msgid="8707874281430105394">"Pozovi poslovni mobitel"</string>
+    <string name="call_work_pager" msgid="3419348514157949008">"Pozovi poslovni pejdžer"</string>
+    <string name="call_assistant" msgid="2141641383068514308">"Pozovi <xliff:g id="ASSISTANT">%s</xliff:g>"</string>
+    <string name="call_mms" msgid="6274041545876221437">"Pozovi MMS"</string>
+    <string name="call_by_shortcut" msgid="2566802538698913124">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (Poziv)"</string>
+    <string name="sms_custom" msgid="5932736853732191825">"Pošalji tekstualnu poruku na <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="sms_home" msgid="7524332261493162995">"Pošalji tekstualnu poruku na kućni broj"</string>
+    <string name="sms_mobile" msgid="5200107250451030769">"Pošalji tekstualnu poruku na mobilni"</string>
+    <string name="sms_work" msgid="2269624156655267740">"Pošalji tekstualnu poruku na poslovni broj"</string>
+    <string name="sms_fax_work" msgid="8028189067816907075">"Pošalji tekstualnu poruku na poslovni faks"</string>
+    <string name="sms_fax_home" msgid="9204042076306809634">"Pošalji tekstualnu poruku na kućni faks"</string>
+    <string name="sms_pager" msgid="7730404569637015192">"Pošalji tekstualnu poruku na pejdžer"</string>
+    <string name="sms_other" msgid="806127844607642331">"Tekst"</string>
+    <string name="sms_callback" msgid="5004824430094288752">"Pošalji tekstualnu poruku na broj za povratni poziv"</string>
+    <string name="sms_car" msgid="7444227058437359641">"Pošalji tekstualnu poruku na automobil"</string>
+    <string name="sms_company_main" msgid="118970873419678087">"Pošalji tekstualnu poruku na glavni broj kompanije"</string>
+    <string name="sms_isdn" msgid="8153785037515047845">"Pošalji tekstualnu poruku na ISDN"</string>
+    <string name="sms_main" msgid="8621625784504541679">"Pošalji tekstualnu poruku na glavni broj"</string>
+    <string name="sms_other_fax" msgid="3888842199855843152">"Pošalji tekstualnu poruku na faks"</string>
+    <string name="sms_radio" msgid="3329166673433967820">"Pošalji tekstualnu poruku na radio"</string>
+    <string name="sms_telex" msgid="9034802430065267848">"Pošalji tekstualnu poruku na teleks"</string>
+    <string name="sms_tty_tdd" msgid="6782284969132531532">"Pošalji tekstualnu poruku na TTY/TDD"</string>
+    <string name="sms_work_mobile" msgid="2459939960512702560">"Pošalji tekstualnu poruku na poslovni mobitel"</string>
+    <string name="sms_work_pager" msgid="5566924423316960597">"Pošalji tekstualnu poruku na poslovni pejdžer"</string>
+    <string name="sms_assistant" msgid="2773424339923116234">"Pošalji tekstualnu poruku <xliff:g id="ASSISTANT">%s</xliff:g>"</string>
+    <string name="sms_mms" msgid="4069352461380762677">"Pošalji tekstualnu poruku na MMS broj"</string>
+    <string name="sms_by_shortcut" msgid="7741770672976099517">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (Poruka)"</string>
+    <string name="description_video_call" msgid="7120921378651700947">"Uputi videopoziv"</string>
+    <string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Obrisati često kontaktirane osobe?"</string>
+    <string name="clearFrequentsConfirmation" msgid="2270554975938265734">"Obrisat ćete listu često kontaktiranih osoba u aplikaciji Kontakti i Aplikaciji za telefon, pa će aplikacije za e-poštu morati ispočetka učiti vaše postavke adresa."</string>
+    <string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Brisanje često kontaktiranih osoba…"</string>
+    <string name="status_available" msgid="5586870015822828392">"Dostupno"</string>
+    <string name="status_away" msgid="1838861100379804730">"Odsutan"</string>
+    <string name="status_busy" msgid="9147992455450257136">"Zauzeto"</string>
+    <string name="contactsList" msgid="8661624236494819731">"Kontakti"</string>
+    <string name="local_invisible_directory" msgid="6046691709127661065">"Ostali"</string>
+    <string name="directory_search_label" msgid="1887759056597975053">"Direktorij"</string>
+    <string name="directory_search_label_work" msgid="8618292129829443176">"Poslovni imenik"</string>
+    <string name="local_search_label" msgid="2551177578246113614">"Svi kontakti"</string>
+    <string name="search_results_searching" msgid="3984833028938569930">"Pretraživanje…"</string>
+    <string name="foundTooManyContacts" msgid="5163335650920020220">"Pronađeno je više od <xliff:g id="COUNT">%d</xliff:g>."</string>
+    <string name="listFoundAllContactsZero" msgid="922980883593159444">"Nema kontakata"</string>
+    <plurals name="searchFoundContacts" formatted="false" msgid="7223023725334884618">
+      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> kontakt pronađen</item>
+      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> kontakta pronađena</item>
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> kontakata pronađeno</item>
+    </plurals>
+    <string name="description_quick_contact_for" msgid="6737516415168327789">"Brzi kontakt za <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="missing_name" msgid="8745511583852904385">"(Bez imena)"</string>
+    <string name="favoritesFrequentContacted" msgid="6184232487472425690">"Često kontaktirani"</string>
+    <string name="description_view_contact_detail" msgid="9133251213656414807">"Prikaži kontakt"</string>
+    <string name="list_filter_phones" msgid="735313795643493365">"Svi kontakti s brojevima telefona"</string>
+    <string name="list_filter_phones_work" msgid="1470173699551475015">"Kontakti radnog profila"</string>
+    <string name="view_updates_from_group" msgid="1782685984905600034">"Prikaži ažuriranja"</string>
+    <string name="account_phone" msgid="7128032778471187553">"Uređaj"</string>
+    <string name="nameLabelsGroup" msgid="2034640839640477827">"Ime"</string>
+    <string name="nicknameLabelsGroup" msgid="2891682101053358010">"Nadimak"</string>
+    <string name="full_name" msgid="6602579550613988977">"Ime"</string>
+    <string name="name_given" msgid="4280790853455320619">"Ime"</string>
+    <string name="name_family" msgid="7466985689626017037">"Prezime"</string>
+    <string name="name_prefix" msgid="59756378548779822">"Prefiks imena"</string>
+    <string name="name_middle" msgid="8467433655992690326">"Srednje ime"</string>
+    <string name="name_suffix" msgid="3855278445375651441">"Sufiks imena"</string>
+    <string name="name_phonetic" msgid="4259595234312430484">"Fonetsko ime"</string>
+    <string name="name_phonetic_given" msgid="8723179018384187631">"Fonetsko ime"</string>
+    <string name="name_phonetic_middle" msgid="8643721493320405200">"Fonetsko srednje ime"</string>
+    <string name="name_phonetic_family" msgid="2640133663656011626">"Fonetsko prezime"</string>
+    <string name="phoneLabelsGroup" msgid="6468091477851199285">"Telefoniraj"</string>
+    <string name="emailLabelsGroup" msgid="8389931313045344406">"E-pošta"</string>
+    <string name="postalLabelsGroup" msgid="3487738141112589324">"Adresa"</string>
+    <string name="imLabelsGroup" msgid="3898238486262614027">"IM"</string>
+    <string name="organizationLabelsGroup" msgid="2478611760751832035">"Organizacija"</string>
+    <string name="relationLabelsGroup" msgid="1854373894284572781">"Odnos"</string>
+    <string name="eventLabelsGroup" msgid="7960408705307831289">"Posebni datum"</string>
+    <string name="sms" msgid="1756857139634224222">"Tekstualna poruka"</string>
+    <string name="postal_address" msgid="8765560217149624536">"Adresa"</string>
+    <string name="ghostData_company" msgid="5414421120553765775">"Kompanija"</string>
+    <string name="ghostData_title" msgid="7496735200318496110">"Naslov"</string>
+    <string name="label_notes" msgid="8337354953278341042">"Bilješke"</string>
+    <!-- no translation found for label_custom_field (1994056912242214426) -->
+    <skip />
+    <string name="label_sip_address" msgid="7252153678613978127">"SIP"</string>
+    <string name="websiteLabelsGroup" msgid="4202998982804009261">"Web stranica"</string>
+    <string name="groupsLabel" msgid="7000816729542098972">"Oznake"</string>
+    <string name="email_home" msgid="8573740658148184279">"Pošalji poruku e-pošte na kućnu adresu e-pošte"</string>
+    <string name="email_mobile" msgid="2042889209787989814">"Mobilna e-pošta"</string>
+    <string name="email_work" msgid="2807430017302722689">"Pošalji poruku e-pošte na poslovnu adresu e-pošte"</string>
+    <string name="email_other" msgid="3454004077967657109">"E-pošta"</string>
+    <string name="email_custom" msgid="7548003991586214105">"E-pošta <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="email" msgid="5668400997660065897">"E-pošta"</string>
+    <string name="postal_street" msgid="8133143961580058972">"Ulica"</string>
+    <string name="postal_pobox" msgid="4431938829180269821">"Poštanski pretinac"</string>
+    <string name="postal_neighborhood" msgid="1450783874558956739">"Naselje"</string>
+    <string name="postal_city" msgid="6597491300084895548">"Grad"</string>
+    <string name="postal_region" msgid="6045263193478437672">"Država"</string>
+    <string name="postal_postcode" msgid="572136414136673751">"Poštanski broj"</string>
+    <string name="postal_country" msgid="7638264508416368690">"Država"</string>
+    <string name="map_home" msgid="1243547733423343982">"Prikaži kućnu adresu"</string>
+    <string name="map_work" msgid="1360474076921878088">"Prikaži poslovnu adresu"</string>
+    <string name="map_other" msgid="3817820803587012641">"Prikaži adresu"</string>
+    <string name="map_custom" msgid="6184363799976265281">"Prikaži adresu <xliff:g id="CUSTOM">%s</xliff:g>"</string>
+    <string name="chat_aim" msgid="2588492205291249142">"Ćaskanje putem aplikacije AIM"</string>
+    <string name="chat_msn" msgid="8041633440091073484">"Ćaskanje putem aplikacije Windows Live"</string>
+    <string name="chat_yahoo" msgid="6629211142719943666">"Ćaskanje putem aplikacije Yahoo"</string>
+    <string name="chat_skype" msgid="1210045020427480566">"Ćaskanje putem aplikacije Skype"</string>
+    <string name="chat_qq" msgid="4294637812847719693">"Ćaskanje putem aplikacije QQ"</string>
+    <string name="chat_gtalk" msgid="981575737258117697">"Ćaskanje putem aplikacije Google Talk"</string>
+    <string name="chat_icq" msgid="8438405386153745775">"Ćaskanje putem aplikacije ICQ"</string>
+    <string name="chat_jabber" msgid="7561444230307829609">"Ćaskanje putem aplikacije Jabber"</string>
+    <string name="chat" msgid="9025361898797412245">"Ćaskanje"</string>
+    <string name="description_minus_button" msgid="6908099247930477551">"izbriši"</string>
+    <string name="expand_collapse_name_fields_description" msgid="8682630859539604311">"Proširi ili skupi polja za imena"</string>
+    <string name="expand_collapse_phonetic_name_fields_description" msgid="3306777588073354509">"Proširi ili skupi polja za fonetska imena"</string>
+    <string name="list_filter_all_accounts" msgid="8908683398914322369">"Svi kontakti"</string>
+    <string name="list_filter_all_starred" msgid="5031734941601931356">"Označeno zvijezdom"</string>
+    <string name="list_filter_customize" msgid="4789963356004169321">"Prilagodi"</string>
+    <string name="list_filter_single" msgid="5871400283515893087">"Kontakt"</string>
+    <string name="display_ungrouped" msgid="6885954210243119591">"Svi drugi kontakti"</string>
+    <string name="display_all_contacts" msgid="2031647544742889505">"Svi kontakti"</string>
+    <string name="menu_sync_remove" msgid="3266725887008450161">"Ukloni grupu za sinhronizaciju"</string>
+    <string name="dialog_sync_add" msgid="8267045393119375803">"Dodaj grupu za sinhronizaciju"</string>
+    <string name="display_more_groups" msgid="2682547080423434170">"Više grupa…"</string>
+    <string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"Uklanjanje grupe \"<xliff:g id="GROUP">%s</xliff:g>\" iz sinhronizacije će također ukloniti sve negrupirane kontakte iz sinhronizacije."</string>
+    <string name="savingDisplayGroups" msgid="2133152192716475939">"Čuvanje opcija prikaza u toku…"</string>
+    <string name="menu_done" msgid="796017761764190697">"Gotovo"</string>
+    <string name="menu_doNotSave" msgid="58593876893538465">"Otkaži"</string>
+    <string name="listCustomView" msgid="1840624396582117590">"Prilagođeni prikaz"</string>
+    <string name="dialog_new_contact_account" msgid="4969619718062454756">"Sačuvaj uvezene kontakte na karticu:"</string>
+    <string name="import_from_sim" msgid="3859272228033941659">"Uvezi sa SIM kartice"</string>
+    <string name="import_from_sim_summary" msgid="5815105584445743740">"Uvezi sa SIM kartice <xliff:g id="SIM_NAME">^1</xliff:g> - <xliff:g id="SIM_NUMBER">^2</xliff:g>"</string>
+    <string name="import_from_sim_summary_no_number" msgid="880612418352086012">"Uvezi sa SIM kartice <xliff:g id="SIM_NAME">%1$s</xliff:g>"</string>
+    <string name="import_from_vcf_file" product="default" msgid="5304572242183878086">"Uvezi iz .vcf fajla"</string>
+    <string name="cancel_import_confirmation_message" msgid="3929951040347726757">"Otkazati uvoz fajla <xliff:g id="FILENAME">%s</xliff:g>?"</string>
+    <string name="cancel_export_confirmation_message" msgid="1995462401949262638">"Otkazati izvoz fajla <xliff:g id="FILENAME">%s</xliff:g>?"</string>
+    <string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"Nemoguće otkazati uvoz/izvoz vCard fajla"</string>
+    <string name="fail_reason_unknown" msgid="1714092345030570863">"Nepoznata greška."</string>
+    <string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"Nije moguće otvoriti \"<xliff:g id="FILE_NAME">%s</xliff:g>\": <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
+    <string name="fail_reason_could_not_initialize_exporter" msgid="707260459259688510">"Nije moguće pokrenuti program za izvoz: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
+    <string name="fail_reason_no_exportable_contact" msgid="8728506011371262065">"Nema sadržaja za izvoz."</string>
+    <string name="missing_required_permission" msgid="5865884842972833120">"Onemogućili ste potrebnu dozvolu."</string>
+    <string name="fail_reason_error_occurred_during_export" msgid="3018855323913649063">"Došlo je do greške prilikom izvoza: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
+    <string name="fail_reason_too_long_filename" msgid="3393764245254738333">"Zahtijevano ime fajla je predugo (\"<xliff:g id="FILENAME">%s</xliff:g>\")."</string>
+    <string name="fail_reason_io_error" msgid="6748358842976073255">"I/O greška"</string>
+    <string name="fail_reason_low_memory_during_import" msgid="875222757734882898">"Nema dovoljno memorije. Možda je fajl prevelik."</string>
+    <string name="fail_reason_vcard_parse_error" msgid="888263542360355784">"Nije moguće raščlaniti vCard fajl iz neočekivanog razloga."</string>
+    <string name="fail_reason_not_supported" msgid="8219562769267148825">"Format nije podržan."</string>
+    <string name="fail_reason_failed_to_collect_vcard_meta_info" msgid="6427931733267328564">"Nije moguće otvoriti metapodatke vCard fajl(ov)a."</string>
+    <string name="fail_reason_failed_to_read_files" msgid="5823434810622484922">"Nije moguće uvesti jedan ili više fajlova (%s)."</string>
+    <string name="exporting_vcard_finished_title" msgid="4767045779458185251">"Izvoz fajla <xliff:g id="FILENAME">%s</xliff:g> je završen."</string>
+    <string name="exporting_vcard_finished_title_fallback" msgid="6060472638008218274">"Izvoz kontakata je završen."</string>
+    <string name="exporting_vcard_finished_toast" msgid="1739055986856453882">"Izvoz kontakata je završen. Kliknite obavještenje da podijelite kontakte."</string>
+    <string name="touch_to_share_contacts" msgid="4882485525268469736">"Dodirnite da podijelite kontakte."</string>
+    <string name="exporting_vcard_canceled_title" msgid="2652222370493306887">"Izvoz fajla <xliff:g id="FILENAME">%s</xliff:g> je otkazan."</string>
+    <string name="exporting_contact_list_title" msgid="9072240631534457415">"Izvoz podataka kontakta u toku"</string>
+    <string name="exporting_contact_list_message" msgid="3367949209642931952">"Podaci kontakta se izvoze."</string>
+    <string name="composer_failed_to_get_database_infomation" msgid="1765944280846236723">"Nije moguće preuzeti informacije iz baze podataka."</string>
+    <string name="composer_has_no_exportable_contact" msgid="3296493229040294335">"Nema kontakata koji se mogu izvoziti. Ako imate kontakte na telefonu, neki dobavljači podataka možda ne dozvoljavaju izvoz kontakata s telefona."</string>
+    <string name="composer_not_initialized" msgid="2321648986367005254">"Program za izradu kartica vCard nije pravilno pokrenut."</string>
+    <string name="exporting_contact_failed_title" msgid="4892358112409576342">"Izvoz nije uspio"</string>
+    <string name="exporting_contact_failed_message" msgid="4938527850142003141">"Podaci kontakta nisu izvezeni.\nRazlog: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\""</string>
+    <string name="importing_vcard_description" msgid="4245275224298571351">"Uvozi se kontakt <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="reading_vcard_failed_title" msgid="4251647443358422855">"Čitanje podataka vCard nije uspjelo"</string>
+    <string name="reading_vcard_canceled_title" msgid="1925216585981542019">"Čitanje vCard podataka je otkazano"</string>
+    <string name="importing_vcard_finished_title" msgid="3341541727268747967">"Završen uvoz vCard fajla <xliff:g id="FILENAME">%s</xliff:g>"</string>
+    <string name="importing_vcard_canceled_title" msgid="2147475978165599336">"Uvoz fajla <xliff:g id="FILENAME">%s</xliff:g> je otkazan"</string>
+    <string name="vcard_import_will_start_message" msgid="2804911199145873396">"Fajl <xliff:g id="FILENAME">%s</xliff:g> će uskoro biti uvezen."</string>
+    <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"Fajl će uskoro biti uvezen."</string>
+    <string name="vcard_import_request_rejected_message" msgid="2890471184508516011">"Zahtjev za uvoz vCard fajla je odbijen. Pokušajte ponovo kasnije."</string>
+    <string name="vcard_export_will_start_message" msgid="2210241345252081463">"Fajl <xliff:g id="FILENAME">%s</xliff:g> će uskoro biti izvezen."</string>
+    <string name="vcard_export_will_start_message_fallback" msgid="6553826997490909749">"Fajl će uskoro biti izvezen."</string>
+    <string name="contacts_export_will_start_message" msgid="8538705791417534431">"Kontakti će uskoro biti izvezeni."</string>
+    <string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"Zahtjev za izvoz vCard fajla je odbijen. Pokušajte ponovo kasnije."</string>
+    <string name="vcard_unknown_filename" msgid="7171709890959915954">"kontakt"</string>
+    <string name="caching_vcard_message" msgid="4926308675041506756">"Spremanje vCard fajlova u lokalnu privremenu pohranu. Uvoz će započeti uskoro."</string>
+    <string name="vcard_import_failed" msgid="5223531255894842406">"Uvoz vCard kartice nije uspio."</string>
+    <string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt NFC-om"</string>
+    <string name="confirm_export_title" msgid="6834385377255286349">"Izvesti kontakte?"</string>
+    <string name="caching_vcard_title" msgid="1226272312940516605">"Spremanje u privremenu pohranu u toku"</string>
+    <string name="progress_notifier_message" msgid="2311011466908220528">"Uvozi se <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="export_to_vcf_file" product="default" msgid="4407527157056120858">"Izvezi u .vcf fajl"</string>
+    <string name="display_options_sort_list_by" msgid="7028809117272018712">"Poredaj po"</string>
+    <string name="display_options_sort_by_given_name" msgid="2778421332815687873">"Ime"</string>
+    <string name="display_options_sort_by_family_name" msgid="2684905041926954793">"Prezime"</string>
+    <string name="display_options_view_names_as" msgid="6514632499276563482">"Format imena"</string>
+    <string name="display_options_view_given_name_first" msgid="3616004640258761473">"Ime prvo"</string>
+    <string name="display_options_view_family_name_first" msgid="956445100777296467">"Prezime prvo"</string>
+    <string name="settings_accounts" msgid="350219740670774576">"Računi"</string>
+    <string name="default_editor_account" msgid="699591683362420991">"Zadani račun za nove kontakte"</string>
+    <string name="sync_contact_metadata_title" msgid="6957956139306960211">"Sinhroniziraj metapodatke kontakata [DOGFOOD]"</string>
+    <string name="sync_contact_metadata_dialog_title" msgid="6192335951588820553">"Sinhroniziraj metapodatke kontakata"</string>
+    <string name="settings_my_info_title" msgid="1534272456405343119">"Moje informacije"</string>
+    <string name="set_up_profile" msgid="7370213843590143771">"Postavite svoj profil"</string>
+    <string name="setting_about" msgid="7014388749752042863">"O kontaktima"</string>
+    <string name="activity_title_settings" msgid="5464130076132770781">"Postavke"</string>
+    <string name="share_visible_contacts" msgid="890150378880783797">"Podijeli vidljive kontakte"</string>
+    <string name="share_visible_contacts_failure" msgid="7324717548166915560">"Dijeljenje vidljivih kontakata nije uspjelo."</string>
+    <string name="share_favorite_contacts" msgid="4280926751003081042">"Dijeli omiljene kontakte"</string>
+    <string name="share_contacts" msgid="8109287987498711664">"Dijeli sve kontakte"</string>
+    <string name="share_contacts_failure" msgid="1216431977330560559">"Dijeljenje kontakata nije uspjelo."</string>
+    <string name="dialog_import_export" msgid="4360648034889921624">"Uvoz/izvoz kontakata"</string>
+    <string name="dialog_import" msgid="2431698729761448759">"Uvezi kontakte"</string>
+    <string name="share_error" msgid="948429331673358107">"Ovaj kontakt se ne može podijeliti."</string>
+    <string name="no_contact_to_share" msgid="1276397530378323033">"Nema kontakata za dijeljenje."</string>
+    <string name="menu_search" msgid="9147752853603483719">"Traži"</string>
+    <string name="menu_contacts_filter" msgid="2165153460860262501">"Kontakti za prikaz"</string>
+    <string name="activity_title_contacts_filter" msgid="8275542497615516969">"Kontakti za prikaz"</string>
+    <string name="custom_list_filter" msgid="2105275443109077687">"Definirajte prilagođeni prikaz"</string>
+    <string name="menu_custom_filter_save" msgid="2679793632208086460">"Sačuvaj"</string>
+    <string name="hint_findContacts" msgid="7128627979899070325">"Traži kontakte"</string>
+    <string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriti"</string>
+    <string name="listTotalAllContactsZero" msgid="5513001821794568211">"Nema kontakata."</string>
+    <string name="menu_clear_frequents" msgid="7688250191932838833">"Obriši često kontaktirane"</string>
+    <string name="menu_select_sim" msgid="3603578201960504010">"Odaberi SIM karticu"</string>
+    <string name="menu_accounts" msgid="1424330057450189074">"Upravljaj računima"</string>
+    <string name="menu_import_export" msgid="26217871113229507">"Uvoz/izvoz"</string>
+    <string name="menu_blocked_numbers" msgid="5272951629083025995">"Blokirani brojevi"</string>
+    <string name="contact_status_update_attribution" msgid="752179367353018597">"putem <xliff:g id="SOURCE">%1$s</xliff:g>"</string>
+    <string name="contact_status_update_attribution_with_date" msgid="7358045508107825068">"<xliff:g id="DATE">%1$s</xliff:g> putem <xliff:g id="SOURCE">%2$s</xliff:g>"</string>
+    <string name="action_menu_back_from_search" msgid="8793348588949233348">"zaustavi pretraživanje"</string>
+    <string name="description_clear_search" msgid="688023606766232904">"Obriši pretragu"</string>
+    <string name="settings_contact_display_options_title" msgid="4890258244494248687">"Opcije prikaza kontakata"</string>
+    <string name="select_account_dialog_title" msgid="5478489655696599219">"Račun"</string>
+    <string name="set_default_account" msgid="4311613760725609801">"Uvijek koristi ovu karticu za poziv"</string>
+    <string name="select_phone_account_for_calls" msgid="3810607744451014540">"Poziv putem"</string>
+    <string name="call_with_a_note" msgid="8389827628360791676">"Poziv s bilješkom"</string>
+    <string name="call_subject_hint" msgid="3637498418381454511">"Upišite bilješku koja će se poslati uz poziv ..."</string>
+    <string name="send_and_call_button" msgid="7740295432834590737">"POŠALJI I POZOVI"</string>
+    <string name="call_subject_limit" msgid="4545212901205397669">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
+    <string name="call_subject_type_and_number" msgid="7667188212129152558">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+    <plurals name="tab_title_with_unread_items" formatted="false" msgid="7682024005130747825">
+      <item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
+      <item quantity="few"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
+      <item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
+    </plurals>
+    <string name="about_build_version" msgid="1765533099416999801">"Podverzija"</string>
+    <string name="about_open_source_licenses" msgid="6479990452352919641">"Licence otvorenog koda"</string>
+    <string name="about_open_source_licenses_summary" msgid="57418386931763994">"Detalji o licenci za softver otvorenog koda"</string>
+    <string name="about_privacy_policy" msgid="3705518622499152626">"Pravila o privatnosti"</string>
+    <string name="about_terms_of_service" msgid="4642400812150296723">"Uslovi pružanja usluge"</string>
+    <string name="activity_title_licenses" msgid="5467767062737708066">"Licence otvorenog koda"</string>
+    <string name="url_open_error_toast" msgid="452592089815420457">"Otvaranje URL-a nije uspjelo."</string>
+    <string name="account_filter_view_checked" msgid="6696859503887762213">"<xliff:g id="ACCOUNT_INFO">%s</xliff:g> je označen"</string>
+    <string name="account_filter_view_not_checked" msgid="2248684521205038389">"<xliff:g id="ACCOUNT_INFO">%s</xliff:g> nije označen"</string>
+    <string name="description_search_video_call" msgid="5841525580339803272">"Uputi videopoziv"</string>
+    <string name="description_delete_contact" msgid="53835657343783663">"Izbriši"</string>
+    <string name="description_no_name_header" msgid="8884991311595943271">"Elipsa"</string>
+    <string name="callDurationSecondFormat" msgid="7067644915903528776">"<xliff:g id="SECONDS">%s</xliff:g> sek."</string>
+    <string name="callDurationMinuteFormat" msgid="4647095486747447674">"<xliff:g id="MINUTES">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sek."</string>
+    <string name="callDurationHourFormat" msgid="7392254193808506640">"<xliff:g id="MINUTES_0">%s</xliff:g> h <xliff:g id="MINUTES_1">%s</xliff:g> min. <xliff:g id="SECONDS">%s</xliff:g> sek."</string>
 </resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 6f6f4e1..8dd1ba9 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -28,10 +28,6 @@
     <dimen name="contact_browser_list_top_margin">18dp</dimen>
 
     <dimen name="quick_contact_photo_container_height">360dip</dimen>
-    <!-- Height of the selection indicator of a tab. -->
-    <dimen name="tab_selected_underline_height">3dp</dimen>
-    <!-- Size of text in tabs. -->
-    <dimen name="tab_text_size">16sp</dimen>
 
     <!-- Because the "join" screen has the vertical scroll bar on right,
       we cannot use @dimen/contact_browser_list_header_left_margin as is. -->
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index b89c2c1..baa8498 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -18,5 +18,4 @@
     <dimen name="group_editor_side_padding">64dip</dimen>
     <dimen name="contact_detail_list_top_padding">32dip</dimen>
     <dimen name="detail_contact_photo_size">256dip</dimen>
-    <dimen name="people_activity_landscape_tabs_text_size">16dp</dimen>
 </resources>
diff --git a/res/values-w470dp/dimens.xml b/res/values-w470dp/dimens.xml
deleted file mode 100644
index 2c04e5d..0000000
--- a/res/values-w470dp/dimens.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <!-- The width the that the tabs occupy in the ActionBar when in landscape mode.
-         470dp is the height of a "normal" screen. We should leave 240dp for
-         the title and menu items -->
-    <dimen name="people_activity_landscape_tabs_width">230dip</dimen>
-    <!-- The size of the text displayed in the ActionBar tabs in landscape mode.
-         Text in the tabs should must be width dependent, otherwise it won't fit in the tabs.
-         In portrait mode, the tabs look okay when overflowing their allocated space.
-         We have to be more careful in landscape. -->
-    <dimen name="people_activity_landscape_tabs_text_size">9dp</dimen>
-
-</resources>
\ No newline at end of file
diff --git a/res/values-w590dp/dimens.xml b/res/values-w590dp/dimens.xml
deleted file mode 100644
index 2fff6ca..0000000
--- a/res/values-w590dp/dimens.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <!-- The width the that the tabs occupy in the ActionBar when in landscape mode.
-         590dp is almost the height of a "large" screen. We should leave 240dp for
-         the title and menu items -->
-    <dimen name="people_activity_landscape_tabs_width">350dip</dimen>
-    <!-- The size of the text displayed in the ActionBar tabs in landscape mode.
-         Text in the tabs should must be width dependent, otherwise it won't fit in the tabs.
-         In portrait mode, the tabs look okay when overflowing their allocated space.
-         We have to be more careful in landscape. -->
-    <dimen name="people_activity_landscape_tabs_text_size">14dp</dimen>
-
-</resources>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 355a4e8..26e2315 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -81,6 +81,12 @@
     <!-- Color of background of all empty states. -->
     <color name="empty_state_background">#efefef</color>
 
+    <!-- Colors of swipeRefreshLayout's spinning circle. -->
+    <color name="swipe_refresh_color1">#0f9d58</color>
+    <color name="swipe_refresh_color2">#dd4b37</color>
+    <color name="swipe_refresh_color3">#4285f4</color>
+    <color name="swipe_refresh_color4">#f4b400</color>
+
     <!-- Color of hamburger icon in promo -->
     <color name="hamburger_feature_highlight_inner_color">#00ffffff</color>
 
@@ -190,11 +196,6 @@
     <!-- Color for icons in the actionbar -->
     <color name="actionbar_icon_color">#ffffff</color>
 
-    <color name="tab_ripple_color">@color/tab_accent_color</color>
-    <color name="tab_accent_color">#ffffff</color>
-    <color name="tab_selected_underline_color">@color/tab_accent_color</color>
-    <color name="tab_unread_count_background_color">#700f4b70</color>
-
     <!-- Color of the title to the Frequently Contacted section -->
     <color name="frequently_contacted_title_color">@color/actionbar_background_color</color>
 
@@ -207,7 +208,6 @@
     <color name="actionbar_text_color_black">#DF000000</color>
     <!-- Solid grey for status bar overlay-->
     <color name="actionbar_color_grey_solid">#777777</color>
-    <color name="actionbar_unselected_text_color">#a6ffffff</color>
 
     <!-- Text color of the search box text as entered by user  -->
     <color name="searchbox_text_color">#000000</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d355021..2eb4b22 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -238,16 +238,6 @@
     <dimen name="quickcontact_expanding_button_section_height">48dp</dimen>
     <dimen name="quickcontact_expanding_button_section_padding">8dp</dimen>
 
-    <!-- The width the that the tabs occupy in the ActionBar when in landscape mode.
-         426dp is the height of a "small" screen. We should leave 240dp for
-         the title and menu items -->
-    <dimen name="people_activity_landscape_tabs_width">186dip</dimen>
-    <!-- The size of the text displayed in the ActionBar tabs in landscape mode.
-         Text in the tabs should must be width dependent, otherwise it won't fit in the tabs.
-         In portrait mode, the tabs look okay when overflowing their allocated space.
-         We have to be more careful in landscape. -->
-    <dimen name="people_activity_landscape_tabs_text_size">8dp</dimen>
-
     <!-- Top margin of the text message when provider status is busy -->
     <dimen name="update_contact_list_top_margin">188dp</dimen>
 
@@ -295,6 +285,9 @@
     <!-- Minimum height for group name EditText -->
     <dimen name="group_name_edit_text_min_height">48dp</dimen>
 
+    <!-- Distance to pull down before causing a refresh. -->
+    <dimen name="pull_to_refresh_distance">40dp</dimen>
+
     <!-- Elevation of contact list header -->
     <dimen name="contact_list_header_elevation">2dp</dimen>
 
@@ -428,17 +421,8 @@
     <!-- Offset of bottom margin of the floating action button used when dialpad is up -->
     <dimen name="floating_action_button_dialpad_margin_bottom_offset">4dp</dimen>
 
-    <!-- Height of the selection indicator of a tab. -->
-    <dimen name="tab_selected_underline_height">2dp</dimen>
     <!-- Size of text in tabs. -->
-    <dimen name="tab_text_size">14sp</dimen>
     <dimen name="tab_elevation">2dp</dimen>
-    <dimen name="tab_unread_count_background_size">16dp</dimen>
-    <dimen name="tab_unread_count_background_radius">2dp</dimen>
-    <dimen name="tab_unread_count_margin_left">10dp</dimen>
-    <dimen name="tab_unread_count_margin_top">2dp</dimen>
-    <dimen name="tab_unread_count_text_size">12sp</dimen>
-    <dimen name="tab_unread_count_text_padding">2dp</dimen>
 
     <!-- Padding around the icon in the search box. -->
     <dimen name="search_box_icon_margin">4dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8ebe761..e7b6582 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -41,10 +41,6 @@
 
     <style name="PeopleTheme" parent="@android:style/Theme.Material.Light">
         <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
-        <!-- Style for the tab bar (for the divider between tabs) -->
-        <item name="android:actionBarTabBarStyle">@style/ContactsActionBarTabBarStyle</item>
-        <!-- Style for the tab bar text (for text on tabs) -->
-        <item name="android:actionBarTabTextStyle">@style/ContactsActionBarTabTextStyle</item>
         <!--  Drawable for the back button -->
         <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
         <!-- Style for the overflow button in the actionbar. -->
@@ -107,12 +103,6 @@
         <!-- Styles that require AppCompat compatibility, remember to update both sets -->
         <item name="android:actionBarStyle">@style/ContactsActionBarStyleAppCompat</item>
         <item name="actionBarStyle">@style/ContactsActionBarStyleAppCompat</item>
-        <!-- Style for the tab bar (for the divider between tabs) -->
-        <item name="android:actionBarTabBarStyle">@style/ContactsActionBarTabBarStyle</item>
-        <item name="actionBarTabBarStyle">@style/ContactsActionBarTabBarStyle</item>
-        <!-- Style for the tab bar text (for text on tabs) -->
-        <item name="android:actionBarTabTextStyle">@style/ContactsActionBarTabTextStyle</item>
-        <item name="actionBarTabTextStyle">@style/ContactsActionBarTabTextStyle</item>
         <item name="android:actionButtonStyle">@style/ContactsActionButtonStyle</item>
         <item name="actionButtonStyle">@style/ContactsActionButtonStyle</item>
         <!--  Drawable for the back button -->
@@ -244,22 +234,6 @@
         <item name="android:textColor">@color/actionbar_text_color_black</item>
     </style>
 
-    <!-- Styling for the tab bar; handles styling of the divider line. -->
-    <style name="ContactsActionBarTabBarStyle"
-           parent="@android:style/Widget.Material.ActionBar.TabBar">
-        <item name="android:showDividers">none</item>
-    </style>
-
-    <!-- Text style for tabs. -->
-    <style name="ContactsActionBarTabTextStyle"
-           parent="android:style/Widget.Material.Light.ActionBar.TabText">
-        <item name="android:textColor">@color/tab_text_color</item>
-        <item name="android:textSize">@dimen/tab_text_size</item>
-        <item name="android:fontFamily">@string/tab_font_family</item>
-        <item name="android:elevation">0dp</item>
-        <item name="android:textStyle">bold</item>
-    </style>
-
     <!-- Action bar overflow menu icon. -->
     <style name="ContactsActionBarOverflowQP"
            parent="Widget.AppCompat.Light.ActionButton.Overflow">
diff --git a/src-bind/com/android/contactsbind/ObjectFactory.java b/src-bind/com/android/contactsbind/ObjectFactory.java
index f6dc0c7..0020b55 100644
--- a/src-bind/com/android/contactsbind/ObjectFactory.java
+++ b/src-bind/com/android/contactsbind/ObjectFactory.java
@@ -15,6 +15,7 @@
 
 import com.android.contacts.common.logging.Logger;
 import com.android.contacts.common.preference.PreferenceManager;
+import com.android.contactsbind.search.AutocompleteHelper;
 import com.android.contacts.common.util.DeviceAccountFilter;
 import com.android.contacts.common.util.DeviceAccountPresentationValues;
 
@@ -31,6 +32,10 @@
 
     public static PreferenceManager getPreferenceManager(Context context) { return null; }
 
+    public static AutocompleteHelper getAutocompleteHelper(Context context) {
+        return null;
+    }
+
     public static DeviceAccountPresentationValues createDeviceAccountPresentationValues(Context context) {
         return new DeviceAccountPresentationValues.Default(context);
     }
diff --git a/src-bind/com/android/contactsbind/experiments/Flags.java b/src-bind/com/android/contactsbind/experiments/Flags.java
index 5bf47e8..72cf481 100644
--- a/src-bind/com/android/contactsbind/experiments/Flags.java
+++ b/src-bind/com/android/contactsbind/experiments/Flags.java
@@ -17,8 +17,6 @@
 
 import android.content.Context;
 
-import com.android.contacts.common.Experiments;
-
 import java.util.HashMap;
 import java.util.Map;
 
diff --git a/src-bind/com/android/contactsbind/search/AutocompleteHelper.java b/src-bind/com/android/contactsbind/search/AutocompleteHelper.java
new file mode 100644
index 0000000..c37a828
--- /dev/null
+++ b/src-bind/com/android/contactsbind/search/AutocompleteHelper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.contactsbind.search;
+
+import android.database.Cursor;
+
+public final class AutocompleteHelper {
+
+    public static final String TAG = "Autocomplete";
+
+    public interface Listener {
+        void onAutocompletesAvailable(Cursor cursor);
+    }
+
+    private AutocompleteHelper() {
+    }
+
+    public void setListener(Listener listener) {
+    }
+
+    public void setProjection(String[] projection) {
+    }
+
+    public void setQuery(String query) {
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/contacts/ContactsDrawerActivity.java b/src/com/android/contacts/ContactsDrawerActivity.java
index f976807..047046b 100644
--- a/src/com/android/contacts/ContactsDrawerActivity.java
+++ b/src/com/android/contacts/ContactsDrawerActivity.java
@@ -237,6 +237,10 @@
         }
     }
 
+    public Toolbar getToolbar() {
+        return mToolbar;
+    }
+
     private void maybeUpdateScrollPosition(int position) {
         if (mDrawer.isDrawerOpen(GravityCompat.START)) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Don't scroll menu when drawer open");
@@ -282,6 +286,7 @@
 
     @Override
     protected void onNewIntent(Intent newIntent) {
+        mContactListFilterController.checkFilterValidity(false);
         if (ACTION_CREATE_GROUP.equals(newIntent.getAction())) {
             final Uri groupUri = newIntent.getData();
             if (groupUri == null) {
@@ -418,7 +423,8 @@
         }
     }
 
-    protected void updateGroupMenu(GroupMetadata groupMetadata) {
+    // TODO(wenyiw) the method is public for now; we should remove it after b/30944495 is fixed.
+    public void updateGroupMenu(GroupMetadata groupMetadata) {
         clearCheckedMenus();
         if (groupMetadata != null && mGroupMenuMap != null
                 && mGroupMenuMap.get(groupMetadata.groupId) != null) {
@@ -522,7 +528,7 @@
         }
     }
 
-    protected void updateFilterMenu(ContactListFilter filter) {
+    public void updateFilterMenu(ContactListFilter filter) {
         clearCheckedMenus();
         if (filter != null && filter.isContactsFilterType()) {
             if (mIdMenuMap != null && mIdMenuMap.get(R.id.nav_all_contacts) != null) {
@@ -591,7 +597,7 @@
 
     protected void switchToAllContacts() {
         final Intent intent = new Intent();
-        final ContactListFilter filter = createContactsFilter();
+        final ContactListFilter filter = AccountFilterUtil.createContactsFilter(this);
         intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter);
         AccountFilterUtil.handleAccountFilterResult(
                 mContactListFilterController, AppCompatActivity.RESULT_OK, intent);
@@ -605,19 +611,6 @@
                 Assistants.getDuplicatesActivityIntent(this));
     }
 
-    /**
-     * Returns a {@link ContactListFilter} of type
-     * {@link ContactListFilter#FILTER_TYPE_ALL_ACCOUNTS}, or if a custom "Contacts to display"
-     * filter has been set, then one of type {@link ContactListFilter#FILTER_TYPE_CUSTOM}.
-     */
-    protected ContactListFilter createContactsFilter() {
-        final int filterType =
-                ContactListFilterController.getInstance(this).isCustomFilterPersisted()
-                        ? ContactListFilter.FILTER_TYPE_CUSTOM
-                        : ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS;
-        return ContactListFilter.createFilterWithType(filterType);
-    }
-
     private void clearCheckedMenus() {
         clearCheckedMenu(mFilterMenuMap);
         clearCheckedMenu(mGroupMenuMap);
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index 9d7907d..824d4ea 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -20,11 +20,8 @@
 import android.animation.ValueAnimator;
 import android.app.Activity;
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
 import android.os.Bundle;
-import android.preference.PreferenceManager;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.app.ActionBar;
 import android.support.v7.widget.Toolbar;
@@ -69,41 +66,26 @@
 
         void onAction(int action);
 
-        /**
-         * Called when the user selects a tab.  The new tab can be obtained using
-         * {@link #getCurrentTab}.
-         */
-        void onSelectedTabChanged();
-
         void onUpButtonPressed();
     }
 
     private static final String EXTRA_KEY_SEARCH_MODE = "navBar.searchMode";
     private static final String EXTRA_KEY_QUERY = "navBar.query";
-    private static final String EXTRA_KEY_SELECTED_TAB = "navBar.selectedTab";
     private static final String EXTRA_KEY_SELECTED_MODE = "navBar.selectionMode";
 
-    private static final String PERSISTENT_LAST_TAB = "actionBarAdapter.lastTab";
-
     private boolean mSelectionMode;
     private boolean mSearchMode;
     private String mQueryString;
 
     private EditText mSearchView;
     private View mClearSearchView;
-    /** The view that represents tabs when we are in portrait mode **/
-    private View mPortraitTabs;
-    /** The view that represents tabs when we are in landscape mode **/
-    private View mLandscapeTabs;
     private View mSearchContainer;
     private View mSelectionContainer;
 
-    private int mMaxPortraitTabHeight;
     private int mMaxToolbarContentInsetStart;
     private int mActionBarAnimationDuration;
 
     private final Activity mActivity;
-    private final SharedPreferences mPrefs;
 
     private Listener mListener;
 
@@ -122,29 +104,16 @@
 
     private ValueAnimator mStatusBarAnimator;
 
-    public interface TabState {
-        public static int ALL = 0;
-
-        public static int COUNT = 1;
-        public static int DEFAULT = ALL;
-    }
-
-    private int mCurrentTab = TabState.DEFAULT;
-
     public ActionBarAdapter(Activity activity, Listener listener, ActionBar actionBar,
-            View portraitTabs, View landscapeTabs, Toolbar toolbar) {
-        this(activity, listener, actionBar, portraitTabs, landscapeTabs, toolbar,
-                R.string.hint_findContacts);
+            Toolbar toolbar) {
+        this(activity, listener, actionBar, toolbar, R.string.hint_findContacts);
     }
 
     public ActionBarAdapter(Activity activity, Listener listener, ActionBar actionBar,
-            View portraitTabs, View landscapeTabs, Toolbar toolbar, int searchHintResId) {
+            Toolbar toolbar, int searchHintResId) {
         mActivity = activity;
         mListener = listener;
         mActionBar = actionBar;
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(mActivity);
-        mPortraitTabs = portraitTabs;
-        mLandscapeTabs = landscapeTabs;
         mToolbar = toolbar;
         mToolBarFrame = (FrameLayout) mToolbar.getParent();
         mMaxToolbarContentInsetStart = mToolbar.getContentInsetStart();
@@ -153,7 +122,6 @@
                 mActivity.getResources().getInteger(R.integer.action_bar_animation_duration);
 
         setupSearchAndSelectionViews();
-        setupTabs(mActivity);
     }
 
     public void setShowHomeIcon(boolean showHomeIcon) {
@@ -164,22 +132,10 @@
         mShowHomeAsUp = showHomeAsUp;
     }
 
-    public EditText getSearchView() {
-        return mSearchView;
-    }
-
     public View getSelectionContainer() {
         return mSelectionContainer;
     }
 
-    private void setupTabs(Context context) {
-        final TypedArray attributeArray = context.obtainStyledAttributes(
-                new int[]{android.R.attr.actionBarSize});
-        mMaxPortraitTabHeight = attributeArray.getDimensionPixelSize(0, 0);
-        // Hide tabs initially
-        setPortraitTabHeight(0);
-    }
-
     private void setupSearchAndSelectionViews() {
         final LayoutInflater inflater = (LayoutInflater) mToolbar.getContext().getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
@@ -234,19 +190,11 @@
         if (savedState == null) {
             mSearchMode = request.isSearchMode();
             mQueryString = request.getQueryString();
-            mCurrentTab = loadLastTabPreference();
             mSelectionMode = false;
         } else {
             mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
             mSelectionMode = savedState.getBoolean(EXTRA_KEY_SELECTED_MODE);
             mQueryString = savedState.getString(EXTRA_KEY_QUERY);
-
-            // Just set to the field here.  The listener will be notified by update().
-            mCurrentTab = savedState.getInt(EXTRA_KEY_SELECTED_TAB);
-        }
-        if (mCurrentTab >= TabState.COUNT || mCurrentTab < 0) {
-            // Invalid tab index was saved (b/12938207). Restore the default.
-            mCurrentTab = TabState.DEFAULT;
         }
         // Show tabs or the expanded {@link SearchView}, depending on whether or not we are in
         // search mode.
@@ -289,30 +237,6 @@
     }
 
     /**
-     * Save the current tab selection, and notify the listener.
-     */
-    public void setCurrentTab(int tab) {
-        setCurrentTab(tab, true);
-    }
-
-    /**
-     * Save the current tab selection.
-     */
-    public void setCurrentTab(int tab, boolean notifyListener) {
-        if (tab == mCurrentTab) {
-            return;
-        }
-        mCurrentTab = tab;
-
-        if (notifyListener && mListener != null) mListener.onSelectedTabChanged();
-        saveLastTabPreference(mCurrentTab);
-    }
-
-    public int getCurrentTab() {
-        return mCurrentTab;
-    }
-
-    /**
      * @return Whether in search mode, i.e. if the search view is visible/expanded.
      *
      * Note even if the action bar is in search mode, if the query is empty, the search fragment
@@ -448,18 +372,12 @@
         // to adding the desired container.
         if (skipAnimation || isSwitchingFromSearchToSelection) {
             if (isTabHeightChanging || isSwitchingFromSearchToSelection) {
-                mToolbar.removeView(mLandscapeTabs);
                 mToolbar.removeView(mSearchContainer);
                 mToolBarFrame.removeView(mSelectionContainer);
                 if (mSelectionMode) {
-                    setPortraitTabHeight(0);
                     addSelectionContainer();
                 } else if (mSearchMode) {
-                    setPortraitTabHeight(0);
                     addSearchContainer();
-                } else {
-                    setPortraitTabHeight(mMaxPortraitTabHeight);
-                    addLandscapeViewPagerTabs();
                 }
                 updateDisplayOptions(isSearchModeChanging);
             }
@@ -468,25 +386,21 @@
 
         // Handle a switch to/from selection mode, due to UI interaction.
         if (isSelectionModeChanging) {
-            mToolbar.removeView(mLandscapeTabs);
             if (mSelectionMode) {
                 addSelectionContainer();
                 mSelectionContainer.setAlpha(0);
                 mSelectionContainer.animate().alpha(1).setDuration(mActionBarAnimationDuration);
-                animateTabHeightChange(mMaxPortraitTabHeight, 0);
                 updateDisplayOptions(isSearchModeChanging);
             } else {
                 if (mListener != null) {
                     mListener.onAction(Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE);
                 }
                 mSelectionContainer.setAlpha(1);
-                animateTabHeightChange(0, mMaxPortraitTabHeight);
                 mSelectionContainer.animate().alpha(0).setDuration(mActionBarAnimationDuration)
                         .withEndAction(new Runnable() {
                     @Override
                     public void run() {
                         updateDisplayOptions(isSearchModeChanging);
-                        addLandscapeViewPagerTabs();
                         mToolBarFrame.removeView(mSelectionContainer);
                     }
                 });
@@ -495,22 +409,18 @@
 
         // Handle a switch to/from search mode, due to UI interaction.
         if (isSearchModeChanging) {
-            mToolbar.removeView(mLandscapeTabs);
             if (mSearchMode) {
                 addSearchContainer();
                 mSearchContainer.setAlpha(0);
                 mSearchContainer.animate().alpha(1).setDuration(mActionBarAnimationDuration);
-                animateTabHeightChange(mMaxPortraitTabHeight, 0);
                 updateDisplayOptions(isSearchModeChanging);
             } else {
                 mSearchContainer.setAlpha(1);
-                animateTabHeightChange(0, mMaxPortraitTabHeight);
                 mSearchContainer.animate().alpha(0).setDuration(mActionBarAnimationDuration)
                         .withEndAction(new Runnable() {
                     @Override
                     public void run() {
                         updateDisplayOptions(isSearchModeChanging);
-                        addLandscapeViewPagerTabs();
                         mToolbar.removeView(mSearchContainer);
                     }
                 });
@@ -617,13 +527,6 @@
         }
     }
 
-    private void addLandscapeViewPagerTabs() {
-        if (mLandscapeTabs != null) {
-            mToolbar.removeView(mLandscapeTabs);
-            mToolbar.addView(mLandscapeTabs);
-        }
-    }
-
     private void addSearchContainer() {
         mToolbar.removeView(mSearchContainer);
         mToolbar.addView(mSearchContainer);
@@ -658,7 +561,6 @@
             }
             if (!mSearchMode && !mSelectionMode) {
                 mListener.onAction(Action.STOP_SEARCH_AND_SELECTION_MODE);
-                mListener.onSelectedTabChanged();
             }
         }
         updateDisplayOptionsInner();
@@ -674,7 +576,6 @@
         outState.putBoolean(EXTRA_KEY_SEARCH_MODE, mSearchMode);
         outState.putBoolean(EXTRA_KEY_SELECTED_MODE, mSelectionMode);
         outState.putString(EXTRA_KEY_QUERY, mQueryString);
-        outState.putInt(EXTRA_KEY_SELECTED_TAB, mCurrentTab);
     }
 
     public void setFocusOnSearchView() {
@@ -689,41 +590,4 @@
             imm.showSoftInput(view, 0);
         }
     }
-
-    private void saveLastTabPreference(int tab) {
-        mPrefs.edit().putInt(PERSISTENT_LAST_TAB, tab).apply();
-    }
-
-    private int loadLastTabPreference() {
-        try {
-            return mPrefs.getInt(PERSISTENT_LAST_TAB, TabState.DEFAULT);
-        } catch (IllegalArgumentException e) {
-            // Preference is corrupt?
-            return TabState.DEFAULT;
-        }
-    }
-
-    private void animateTabHeightChange(int start, int end) {
-        if (mPortraitTabs == null) {
-            return;
-        }
-        final ValueAnimator animator = ValueAnimator.ofInt(start, end);
-        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                int value = (Integer) valueAnimator.getAnimatedValue();
-                setPortraitTabHeight(value);
-            }
-        });
-        animator.setDuration(100).start();
-    }
-
-    private void setPortraitTabHeight(int height) {
-        if (mPortraitTabs == null) {
-            return;
-        }
-        ViewGroup.LayoutParams layoutParams = mPortraitTabs.getLayoutParams();
-        layoutParams.height = height;
-        mPortraitTabs.setLayoutParams(layoutParams);
-    }
 }
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index 7bb921d..57c460a 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -146,8 +146,7 @@
         // Add a shadow under the toolbar.
         ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources());
 
-        mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(),
-                /* portraitTabs */ null, /* landscapeTabs */ null, mToolbar,
+        mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(), mToolbar,
                 R.string.enter_contact_name);
         mActionBarAdapter.setShowHomeIcon(true);
         mActionBarAdapter.setShowHomeAsUp(true);
@@ -436,10 +435,6 @@
     }
 
     @Override
-    public void onSelectedTabChanged() {
-    }
-
-    @Override
     public void onUpButtonPressed() {
         onBackPressed();
     }
diff --git a/src/com/android/contacts/activities/GroupMembersActivity.java b/src/com/android/contacts/activities/GroupMembersActivity.java
index 000cae4..e4b052c 100644
--- a/src/com/android/contacts/activities/GroupMembersActivity.java
+++ b/src/com/android/contacts/activities/GroupMembersActivity.java
@@ -17,163 +17,33 @@
 
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
-import android.content.Context;
 import android.content.Intent;
-import android.database.Cursor;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
-import android.provider.ContactsContract.RawContacts;
 import android.support.v4.view.GravityCompat;
 import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
 import android.widget.Toast;
 
-import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.R;
-import com.android.contacts.common.GroupMetaData;
-import com.android.contacts.common.logging.ListEvent;
-import com.android.contacts.common.logging.Logger;
-import com.android.contacts.common.logging.ScreenEvent.ScreenType;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.group.GroupMembersFragment;
 import com.android.contacts.group.GroupMetadata;
-import com.android.contacts.group.GroupNameEditDialogFragment;
 import com.android.contacts.group.GroupUtil;
-import com.android.contacts.interactions.GroupDeletionDialogFragment;
-import com.android.contacts.list.ContactsRequest;
-import com.android.contacts.list.MultiSelectContactsListFragment;
-import com.android.contacts.list.UiIntentActions;
-import com.android.contacts.quickcontact.QuickContactActivity;
 
 /**
  * Displays the members of a group and allows the user to edit it.
  */
-public class GroupMembersActivity extends ContactsDrawerActivity implements
-        ActionBarAdapter.Listener,
-        MultiSelectContactsListFragment.OnCheckBoxListActionListener,
-        GroupMembersFragment.GroupMembersListener {
+public class GroupMembersActivity extends ContactsDrawerActivity {
 
     private static final String TAG = "GroupMembers";
 
     private static final String KEY_GROUP_URI = "groupUri";
-    private static final String KEY_GROUP_METADATA = "groupMetadata";
-    private static final String KEY_IS_EDIT_MODE = "editMode";
 
     private static final String TAG_GROUP_MEMBERS = "groupMembers";
-    private static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog";
-
-    private static final String ACTION_DELETE_GROUP = "deleteGroup";
-    private static final String ACTION_UPDATE_GROUP = "updateGroup";
-    private static final String ACTION_ADD_TO_GROUP = "addToGroup";
-    private static final String ACTION_REMOVE_FROM_GROUP = "removeFromGroup";
-
-    private static final int RESULT_GROUP_ADD_MEMBER = 100;
-
-    /**
-     * Starts an Intent to add/remove the raw contacts for the given contact IDs to/from a group.
-     * Only the raw contacts that belong to the specified account are added or removed.
-     */
-    private static class UpdateGroupMembersAsyncTask extends AsyncTask<Void, Void, Intent> {
-
-        static final int TYPE_ADD = 0;
-        static final int TYPE_REMOVE = 1;
-
-        private final Context mContext;
-        private final int mType;
-        private final long[] mContactIds;
-        private final long mGroupId;
-        private final String mAccountName;
-        private final String mAccountType;
-
-        private UpdateGroupMembersAsyncTask(int type, Context context, long[] contactIds,
-                long groupId, String accountName, String accountType) {
-            mContext = context;
-            mType = type;
-            mContactIds = contactIds;
-            mGroupId = groupId;
-            mAccountName = accountName;
-            mAccountType = accountType;
-        }
-
-        @Override
-        protected Intent doInBackground(Void... params) {
-            final long[] rawContactIds = getRawContactIds();
-            if (rawContactIds.length == 0) {
-                return null;
-            }
-            final long[] rawContactIdsToAdd;
-            final long[] rawContactIdsToRemove;
-            final String action;
-            if (mType == TYPE_ADD) {
-                rawContactIdsToAdd = rawContactIds;
-                rawContactIdsToRemove = null;
-                action = GroupMembersActivity.ACTION_ADD_TO_GROUP;
-            } else if (mType == TYPE_REMOVE) {
-                rawContactIdsToAdd = null;
-                rawContactIdsToRemove = rawContactIds;
-                action = GroupMembersActivity.ACTION_REMOVE_FROM_GROUP;
-            } else {
-                throw new IllegalStateException("Unrecognized type " + mType);
-            }
-            return ContactSaveService.createGroupUpdateIntent(
-                    mContext, mGroupId, /* newLabel */ null, rawContactIdsToAdd,
-                    rawContactIdsToRemove, GroupMembersActivity.class, action);
-        }
-
-        // TODO(wjang): prune raw contacts that are already in the group; ContactSaveService will
-        // log a warning if the raw contact is already a member and keep going but it is not ideal.
-        private long[] getRawContactIds() {
-            final Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon()
-                    .appendQueryParameter(RawContacts.ACCOUNT_NAME, mAccountName)
-                    .appendQueryParameter(RawContacts.ACCOUNT_TYPE, mAccountType)
-                    .build();
-            final String[] projection = new String[]{RawContacts._ID};
-            final StringBuilder selection = new StringBuilder();
-            final String[] selectionArgs = new String[mContactIds.length];
-            for (int i = 0; i < mContactIds.length; i++) {
-                if (i > 0) {
-                    selection.append(" OR ");
-                }
-                selection.append(RawContacts.CONTACT_ID).append("=?");
-                selectionArgs[i] = Long.toString(mContactIds[i]);
-            }
-            final Cursor cursor = mContext.getContentResolver().query(
-                    rawContactUri, projection, selection.toString(), selectionArgs, null, null);
-            final long[] rawContactIds = new long[cursor.getCount()];
-            try {
-                int i = 0;
-                while (cursor.moveToNext()) {
-                    rawContactIds[i] = cursor.getLong(0);
-                    i++;
-                }
-            } finally {
-                cursor.close();
-            }
-            return rawContactIds;
-        }
-
-        @Override
-        protected void onPostExecute(Intent intent) {
-            if (intent == null) {
-                Toast.makeText(mContext, R.string.groupSavedErrorToast, Toast.LENGTH_SHORT).show();
-            } else {
-                mContext.startService(intent);
-            }
-        }
-    }
-
-    private ActionBarAdapter mActionBarAdapter;
 
     private GroupMembersFragment mMembersFragment;
 
     private Uri mGroupUri;
-    private boolean mIsEditMode;
-
-    private GroupMetadata mGroupMetadata;
 
     @Override
     public void onCreate(Bundle savedState) {
@@ -182,8 +52,6 @@
         // Parse the Intent
         if (savedState != null) {
             mGroupUri = savedState.getParcelable(KEY_GROUP_URI);
-            mIsEditMode = savedState.getBoolean(KEY_IS_EDIT_MODE);
-            mGroupMetadata = savedState.getParcelable(KEY_GROUP_METADATA);
         } else {
             mGroupUri = getIntent().getData();
             setTitle(getIntent().getStringExtra(GroupUtil.EXTRA_GROUP_NAME));
@@ -196,12 +64,6 @@
         // Set up the view
         setContentView(R.layout.group_members_activity);
 
-        // Set up the action bar
-        mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(),
-                /* portraitTabs */ null, /* landscapeTabs */ null, mToolbar,
-                R.string.enter_contact_name);
-        mActionBarAdapter.setShowHomeIcon(true);
-
         // Add the members list fragment
         final FragmentManager fragmentManager = getFragmentManager();
         mMembersFragment = (GroupMembersFragment)
@@ -211,26 +73,12 @@
             fragmentManager.beginTransaction().replace(R.id.fragment_container_inner,
                     mMembersFragment, TAG_GROUP_MEMBERS).commitAllowingStateLoss();
         }
-        mMembersFragment.setListener(this);
-        if (mGroupMetadata != null && mGroupMetadata.editable) {
-            mMembersFragment.setCheckBoxListListener(this);
-        }
-
-        // Delay action bar initialization until after the fragment is added
-        final ContactsRequest contactsRequest = new ContactsRequest();
-        contactsRequest.setActionCode(ContactsRequest.ACTION_GROUP);
-        mActionBarAdapter.initialize(savedState, contactsRequest);
     }
 
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        if (mActionBarAdapter != null) {
-            mActionBarAdapter.onSaveInstanceState(outState);
-        }
         outState.putParcelable(KEY_GROUP_URI, mGroupUri);
-        outState.putBoolean(KEY_IS_EDIT_MODE, mIsEditMode);
-        outState.putParcelable(KEY_GROUP_METADATA, mGroupMetadata);
     }
 
     // Invoked with results from the ContactSaveService
@@ -256,14 +104,14 @@
 
             toast(getToastMessageForSaveAction(newIntent.getAction()));
 
-            if (mIsEditMode) {
+            if (mMembersFragment.isEditMode()) {
                 // If we're removing group members one at a time, don't reload the fragment so
                 // the user can continue to remove group members one by one
                 if (getGroupCount() == 1) {
                     // If we're deleting the last group member, exit edit mode
                     onBackPressed();
                 }
-            } else if (!ACTION_REMOVE_FROM_GROUP.equals(newIntent.getAction())) {
+            } else if (!GroupUtil.ACTION_REMOVE_FROM_GROUP.equals(newIntent.getAction())) {
                 replaceGroupMembersFragment();
                 invalidateOptionsMenu();
             }
@@ -271,19 +119,20 @@
     }
 
     private static boolean isDeleteAction(String action) {
-        return ACTION_DELETE_GROUP.equals(action);
+        return GroupUtil.ACTION_DELETE_GROUP.equals(action);
     }
 
     private static boolean isSaveAction(String action) {
-        return ACTION_UPDATE_GROUP.equals(action)
-                || ACTION_ADD_TO_GROUP.equals(action)
-                || ACTION_REMOVE_FROM_GROUP.equals(action);
+        return GroupUtil.ACTION_UPDATE_GROUP.equals(action)
+                || GroupUtil.ACTION_ADD_TO_GROUP.equals(action)
+                || GroupUtil.ACTION_REMOVE_FROM_GROUP.equals(action);
     }
 
     private static int getToastMessageForSaveAction(String action) {
-        if (ACTION_UPDATE_GROUP.equals(action)) return R.string.groupUpdatedToast;
-        if (ACTION_ADD_TO_GROUP.equals(action)) return R.string.groupMembersAddedToast;
-        if (ACTION_REMOVE_FROM_GROUP.equals(action)) return R.string.groupMembersRemovedToast;
+        if (GroupUtil.ACTION_UPDATE_GROUP.equals(action)) return R.string.groupUpdatedToast;
+        if (GroupUtil.ACTION_ADD_TO_GROUP.equals(action)) return R.string.groupMembersAddedToast;
+        if (GroupUtil.ACTION_REMOVE_FROM_GROUP.equals(action))
+            return R.string.groupMembersRemovedToast;
         throw new IllegalArgumentException("Unhanded contact save action " + action);
     }
 
@@ -294,19 +143,15 @@
 
     private void replaceGroupMembersFragment() {
         mMembersFragment = GroupMembersFragment.newInstance(mGroupUri);
-        mMembersFragment.setListener(this);
         final FragmentTransaction transaction = getFragmentManager().beginTransaction();
         addGroupsAndFiltersFragments(transaction);
         transaction.replace(R.id.fragment_container_inner, mMembersFragment, TAG_GROUP_MEMBERS)
                 .commitAllowingStateLoss();
-        if (mGroupMetadata != null && mGroupMetadata.editable) {
-            mMembersFragment.setCheckBoxListListener(this);
-        }
     }
 
     @Override
     protected void onGroupMenuItemClicked(long groupId, String title) {
-        if (mGroupMetadata.groupId != groupId) {
+        if (mMembersFragment.getGroupMetadata().groupId != groupId) {
             super.onGroupMenuItemClicked(groupId, title);
         }
     }
@@ -322,129 +167,6 @@
         finish();
     }
 
-    public boolean isEditMode() {
-        return mIsEditMode;
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        if (mGroupMetadata == null) {
-            // Hide menu options until metadata is fully loaded
-            return false;
-        }
-        super.onCreateOptionsMenu(menu);
-        getMenuInflater().inflate(R.menu.view_group, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        final boolean isSelectionMode = mActionBarAdapter.isSelectionMode();
-        final boolean isGroupEditable = mGroupMetadata != null && mGroupMetadata.editable;
-        final boolean isGroupReadOnly = mGroupMetadata != null && mGroupMetadata.readOnly;
-
-        setVisible(menu, R.id.menu_add, isGroupEditable && !isSelectionMode);
-        setVisible(menu, R.id.menu_rename_group, !isGroupReadOnly && !isSelectionMode);
-        setVisible(menu, R.id.menu_delete_group, !isGroupReadOnly && !isSelectionMode);
-        setVisible(menu, R.id.menu_edit_group, isGroupEditable && !mIsEditMode && !isSelectionMode
-                && !isGroupEmpty());
-        setVisible(menu, R.id.menu_remove_from_group, isGroupEditable && isSelectionMode &&
-                !mIsEditMode);
-
-        return true;
-    }
-
-    private boolean isGroupEmpty() {
-        return mMembersFragment != null && mMembersFragment.getAdapter() != null &&
-                mMembersFragment.getAdapter().isEmpty();
-    }
-
-    private static void setVisible(Menu menu, int id, boolean visible) {
-        final MenuItem menuItem = menu.findItem(id);
-        if (menuItem != null) {
-            menuItem.setVisible(visible);
-        }
-    }
-
-    public void startGroupAddMemberActivity() {
-        startActivityForResult(GroupUtil.createPickMemberIntent(this, mGroupMetadata,
-                mMembersFragment.getMemberContactIds()), RESULT_GROUP_ADD_MEMBER);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home: {
-                onBackPressed();
-                return true;
-            }
-            case R.id.menu_add: {
-                startGroupAddMemberActivity();
-                return true;
-            }
-            case R.id.menu_rename_group: {
-                GroupNameEditDialogFragment.newInstanceForUpdate(
-                        new AccountWithDataSet(mGroupMetadata.accountName,
-                                mGroupMetadata.accountType, mGroupMetadata.dataSet),
-                        ACTION_UPDATE_GROUP, mGroupMetadata.groupId, mGroupMetadata.groupName)
-                        .show(getFragmentManager(), TAG_GROUP_NAME_EDIT_DIALOG);
-                return true;
-            }
-            case R.id.menu_delete_group: {
-                deleteGroup();
-                return true;
-            }
-            case R.id.menu_edit_group: {
-                if (mMembersFragment == null) {
-                    return false;
-                }
-                mIsEditMode = true;
-                mActionBarAdapter.setSelectionMode(true);
-                mMembersFragment.displayDeleteButtons(true);
-                return true;
-            }
-            case R.id.menu_remove_from_group: {
-                if (mMembersFragment == null) {
-                    return false;
-                }
-                logListEvent();
-                removeSelectedContacts();
-                return true;
-            }
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void deleteGroup() {
-        if (mMembersFragment.getMemberCount() == 0) {
-            final Intent intent = ContactSaveService.createGroupDeletionIntent(this,
-                    mGroupMetadata.groupId);
-            startService(intent);
-            finish();
-        } else {
-            GroupDeletionDialogFragment.show(getFragmentManager(), mGroupMetadata.groupId,
-                    mGroupMetadata.groupName);
-        }
-    }
-
-    private void logListEvent() {
-        Logger.logListEvent(
-                ListEvent.ActionType.REMOVE_LABEL,
-                mMembersFragment.getListType(),
-                mMembersFragment.getAdapter().getCount(),
-                /* clickedIndex */ -1,
-                mMembersFragment.getAdapter().getSelectedContactIdsArray().length);
-    }
-
-    private void removeSelectedContacts() {
-        final long[] contactIds = mMembersFragment.getAdapter().getSelectedContactIdsArray();
-        new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
-                this, contactIds, mGroupMetadata.groupId, mGroupMetadata.accountName,
-                mGroupMetadata.accountType).execute();
-
-        mActionBarAdapter.setSelectionMode(false);
-    }
-
     @Override
     public void onBackPressed() {
         if (!isSafeToCommitTransactions()) {
@@ -452,44 +174,21 @@
         }
         if (mDrawer.isDrawerOpen(GravityCompat.START)) {
             mDrawer.closeDrawer(GravityCompat.START);
-        } else if (mIsEditMode) {
-            mIsEditMode = false;
-            mActionBarAdapter.setSelectionMode(false);
-            if (mMembersFragment != null) {
-                mMembersFragment.displayDeleteButtons(false);
-            }
-        } else if (mActionBarAdapter.isSelectionMode()) {
-            mActionBarAdapter.setSelectionMode(false);
-            if (mMembersFragment != null) {
-                mMembersFragment.displayCheckBoxes(false);
-            }
-        } else if (mActionBarAdapter.isSearchMode()) {
-            mActionBarAdapter.setSearchMode(false);
+        } else if (mMembersFragment.isEditMode()) {
+            mMembersFragment.setEditMode(false);
+            mMembersFragment.getActionBarAdapter().setSelectionMode(false);
+            mMembersFragment.displayDeleteButtons(false);
+        } else if (mMembersFragment.getActionBarAdapter().isSelectionMode()) {
+            mMembersFragment.getActionBarAdapter().setSelectionMode(false);
+            mMembersFragment.displayCheckBoxes(false);
+        } else if (mMembersFragment.getActionBarAdapter().isSearchMode()) {
+            mMembersFragment.getActionBarAdapter().setSearchMode(false);
         } else {
             switchToAllContacts();
             super.onBackPressed();
         }
     }
 
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == RESULT_GROUP_ADD_MEMBER && resultCode == RESULT_OK && data != null) {
-            long[] contactIds = data.getLongArrayExtra(
-                    UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY);
-            if (contactIds == null) {
-                final long contactId = data.getLongExtra(
-                        UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1);
-                if (contactId > -1) {
-                    contactIds = new long[1];
-                    contactIds[0] = contactId;
-                }
-            }
-            new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_ADD,
-                    this, contactIds, mGroupMetadata.groupId, mGroupMetadata.accountName,
-                    mGroupMetadata.accountType).execute();
-        }
-    }
-
     private void setResultCanceledAndFinish(int resId) {
         toast(resId);
         setResult(RESULT_CANCELED);
@@ -502,112 +201,8 @@
         }
     }
 
-    // ActionBarAdapter callbacks
-
-    @Override
-    public void onAction(int action) {
-        switch (action) {
-            case ActionBarAdapter.Listener.Action.START_SELECTION_MODE:
-                if (mMembersFragment != null) {
-                    if (mIsEditMode) {
-                        mMembersFragment.displayDeleteButtons(true);
-                        mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group));
-                    } else {
-                        mMembersFragment.displayCheckBoxes(true);
-                    }
-                }
-                invalidateOptionsMenu();
-                showFabWithAnimation(/* showFabWithAnimation = */ false);
-                break;
-            case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
-                mActionBarAdapter.setSearchMode(false);
-                if (mMembersFragment != null) {
-                    if (mIsEditMode) {
-                        mMembersFragment.displayDeleteButtons(false);
-                    } else {
-                        mMembersFragment.displayCheckBoxes(false);
-                    }
-                }
-                invalidateOptionsMenu();
-                showFabWithAnimation(/* showFabWithAnimation */ true);
-                break;
-            case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE:
-                showFabWithAnimation(/* showFabWithAnimation */ true);
-                break;
-        }
-    }
-
-    private void showFabWithAnimation(boolean showFab) {
-        // TODO: b/28497108
-    }
-
-    @Override
-    public void onSelectedTabChanged() {
-    }
-
-    @Override
-    public void onUpButtonPressed() {
-        onBackPressed();
-    }
-
-    // MultiSelect checkbox callbacks
-
-    @Override
-    public void onStartDisplayingCheckBoxes() {
-        mActionBarAdapter.setSelectionMode(true);
-    }
-
-    @Override
-    public void onSelectedContactIdsChanged() {
-        if (mIsEditMode) {
-            mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group));
-        } else {
-            mActionBarAdapter.setSelectionCount(mMembersFragment.getSelectedContactIds().size());
-        }
-    }
-
-    @Override
-    public void onStopDisplayingCheckBoxes() {
-        mActionBarAdapter.setSelectionMode(false);
-    }
-
-    // GroupMembersFragment callbacks
-
-    @Override
-    public void onGroupMetadataLoaded(GroupMetadata groupMetadata) {
-        mGroupMetadata = groupMetadata;
-        updateGroupMenu(mGroupMetadata);
-        setTitle(mGroupMetadata.groupName);
-        invalidateOptionsMenu();
-    }
-
-    @Override
-    public void onGroupMetadataLoadFailed() {
-        setResultCanceledAndFinish(R.string.groupLoadErrorToast);
-    }
-
     @Override
     protected GroupMetadata getGroupMetadata() {
-        return mGroupMetadata;
-    }
-
-    @Override
-    public void onGroupMemberListItemClicked(int position, Uri contactLookupUri) {
-        final int count = mMembersFragment.getAdapter().getCount();
-        Logger.logListEvent(ListEvent.ActionType.CLICK, ListEvent.ListType.GROUP, count,
-                /* clickedIndex */ position, /* numSelected */ 0);
-        final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(this,
-                contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED);
-        intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, ScreenType.LIST_GROUP);
-        startActivity(intent);
-    }
-
-    @Override
-    public void onGroupMemberListItemDeleted(int position, long contactId) {
-        final long[] contactIds = new long[1];
-        contactIds[0] = contactId;
-        new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
-                this, contactIds, mGroupMetadata.groupId, mGroupMetadata.accountName,
-                mGroupMetadata.accountType).execute();
+        return mMembersFragment.getGroupMetadata();
     }
 }
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 492cd8b..406ef00 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -21,114 +21,80 @@
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
 import android.content.BroadcastReceiver;
-import android.content.ContentUris;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SyncStatusObserver;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Parcelable;
+import android.os.Handler;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.ProviderStatus;
-import android.provider.ContactsContract.QuickContact;
 import android.support.design.widget.CoordinatorLayout;
-import android.support.design.widget.FloatingActionButton;
 import android.support.design.widget.Snackbar;
-import android.support.v13.app.FragmentPagerAdapter;
 import android.support.v4.content.LocalBroadcastManager;
 import android.support.v4.view.GravityCompat;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.text.TextUtils;
+import android.support.v4.widget.SwipeRefreshLayout;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
 import android.widget.ImageButton;
 import android.widget.Toast;
 
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.R;
-import com.android.contacts.activities.ActionBarAdapter.TabState;
+import com.android.contacts.common.Experiments;
 import com.android.contacts.common.activity.RequestPermissionsActivity;
-import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.interactions.ImportExportDialogFragment;
-import com.android.contacts.common.list.ContactEntryListFragment;
 import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.common.list.ContactListFilterController;
 import com.android.contacts.common.list.DirectoryListLoader;
 import com.android.contacts.common.list.ProviderStatusWatcher;
 import com.android.contacts.common.list.ProviderStatusWatcher.ProviderStatusListener;
-import com.android.contacts.common.list.ViewPagerTabs;
-import com.android.contacts.common.logging.ListEvent;
 import com.android.contacts.common.logging.Logger;
 import com.android.contacts.common.logging.ScreenEvent.ScreenType;
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.model.account.GoogleAccountType;
+import com.android.contacts.common.util.AccountFilterUtil;
 import com.android.contacts.common.util.Constants;
 import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.common.widget.FloatingActionButtonController;
 import com.android.contacts.editor.EditorIntents;
-import com.android.contacts.interactions.ContactDeletionInteraction;
-import com.android.contacts.interactions.ContactMultiDeletionInteraction;
-import com.android.contacts.interactions.ContactMultiDeletionInteraction.MultiContactDeleteListener;
 import com.android.contacts.list.ContactsIntentResolver;
 import com.android.contacts.list.ContactsRequest;
 import com.android.contacts.list.ContactsUnavailableFragment;
 import com.android.contacts.list.DefaultContactBrowseListFragment;
-import com.android.contacts.list.MultiSelectContactsListFragment.OnCheckBoxListActionListener;
-import com.android.contacts.list.OnContactBrowserActionListener;
 import com.android.contacts.list.OnContactsUnavailableActionListener;
 import com.android.contacts.quickcontact.QuickContactActivity;
-import com.android.contacts.util.DialogManager;
-import com.android.contacts.util.SharedPreferenceUtil;
+import com.android.contacts.util.SyncUtil;
+import com.android.contactsbind.experiments.Flags;
 import com.android.contacts.widget.FloatingActionButtonBehavior;
 import com.android.contactsbind.FeatureHighlightHelper;
 
 import java.util.List;
-import java.util.Locale;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Displays a list to browse contacts.
  */
-public class PeopleActivity extends ContactsDrawerActivity implements
-        View.OnCreateContextMenuListener,
-        View.OnClickListener,
-        ActionBarAdapter.Listener,
-        DialogManager.DialogShowingViewActivity,
-        ContactListFilterController.ContactListFilterListener,
-        ProviderStatusListener,
-        MultiContactDeleteListener,
-        DefaultContactBrowseListFragment.FeatureHighlightCallback {
+public class PeopleActivity extends ContactsDrawerActivity implements ProviderStatusListener {
 
     private static final String TAG = "PeopleActivity";
 
-    private static final String ENABLE_DEBUG_OPTIONS_HIDDEN_CODE = "debug debug!";
-
-    private static final int ACTIVITY_REQUEST_CODE_SHARE = 0;
-
-    private final DialogManager mDialogManager = new DialogManager(this);
+    private static final String TAG_ALL = "contacts-all";
 
     private ContactsIntentResolver mIntentResolver;
     private ContactsRequest mRequest;
 
-    private ActionBarAdapter mActionBarAdapter;
-    private List<AccountWithDataSet> mWritableAccounts;
     private FloatingActionButtonController mFloatingActionButtonController;
     private View mFloatingActionButtonContainer;
     private boolean wasLastFabAnimationScaleIn = false;
@@ -139,8 +105,6 @@
 
     private BroadcastReceiver mSaveServiceListener;
 
-    private boolean mOptionsMenuContactsAvailable;
-
     private CoordinatorLayout mLayoutRoot;
 
     /**
@@ -148,14 +112,7 @@
      */
     private DefaultContactBrowseListFragment mAllFragment;
 
-    /** ViewPager for swipe */
-    private ViewPager mTabPager;
-    private ViewPagerTabs mViewPagerTabs;
-    private TabPagerAdapter mTabPagerAdapter;
-    private String[] mTabTitles;
-    private final TabPagerListener mTabPagerListener = new TabPagerListener();
-
-    private boolean mEnableDebugMenuOptions;
+    private View mContactsView;
 
     /**
      * True if this activity instance is a re-created one.  i.e. set true after orientation change.
@@ -171,15 +128,60 @@
      */
     private boolean mFragmentInitialized;
 
-    /**
-     * This is to disable {@link #onOptionsItemSelected} when we trying to stop the activity.
-     */
-    private boolean mDisableOptionItemSelected;
 
     /** Sequential ID assigned to each instance; used for logging */
     private final int mInstanceId;
     private static final AtomicInteger sNextInstanceId = new AtomicInteger();
 
+    private Object mStatusChangeListenerHandle;
+
+    private final Handler mHandler = new Handler();
+
+    private SyncStatusObserver mSyncStatusObserver = new SyncStatusObserver() {
+        public void onStatusChanged(int which) {
+            mHandler.post(new Runnable() {
+                public void run() {
+                    onSyncStateUpdated();
+                }
+            });
+        }
+    };
+
+    // Update sync status for accounts in current ContactListFilter
+    private void onSyncStateUpdated() {
+        if (mAllFragment.getActionBarAdapter().isSearchMode()
+                || mAllFragment.getActionBarAdapter().isSelectionMode()) {
+            return;
+        }
+
+        final ContactListFilter filter = mAllFragment.getFilter();
+        if (filter != null) {
+            final SwipeRefreshLayout swipeRefreshLayout = mAllFragment.getSwipeRefreshLayout();
+            if (swipeRefreshLayout == null) {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Can not load swipeRefreshLayout, swipeRefreshLayout is null");
+                }
+                return;
+            }
+
+            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(this)
+                    .getAccounts(/* contactsWritableOnly */ true);
+            final List<Account> syncableAccounts = filter.getSyncableAccounts(accounts);
+            // If one of the accounts is active or pending, use spinning circle to indicate one of
+            // the syncs is in progress.
+            if (syncableAccounts != null && syncableAccounts.size() > 0) {
+                for (Account account: syncableAccounts) {
+                    if (SyncUtil.isSyncStatusPendingOrActive(account)
+                            || SyncUtil.isUnsyncableGoogleAccount(account)) {
+                        swipeRefreshLayout.setRefreshing(true);
+                        return;
+                    }
+                }
+            }
+            swipeRefreshLayout.setRefreshing(false);
+        }
+    }
+
     public PeopleActivity() {
         mInstanceId = sNextInstanceId.getAndIncrement();
         mIntentResolver = new ContactsIntentResolver(this);
@@ -231,22 +233,12 @@
             finish();
             return;
         }
-        mContactListFilterController = ContactListFilterController.getInstance(this);
-        mContactListFilterController.checkFilterValidity(false);
-        mContactListFilterController.addListener(this);
 
         mProviderStatusWatcher.addListener(this);
 
         mIsRecreatedInstance = (savedState != null);
 
-        // Use FILTER_TYPE_ALL_ACCOUNTS filter if the activity is not a re-created one.
-        // This is useful when user upgrades app while an account filter or a custom filter was
-        // stored in sharedPreference in a previous version of Contacts app.
-        final ContactListFilter filter = mIsRecreatedInstance
-                ? mContactListFilterController.getFilter() : createContactsFilter();
-        persistFilterIfNeeded(filter);
-
-        createViewsAndFragments(savedState);
+        createViewsAndFragments();
 
         if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
             Log.d(Constants.PERFORMANCE_TAG, "PeopleActivity.onCreate finish");
@@ -254,15 +246,6 @@
         getWindow().setBackgroundDrawable(null);
     }
 
-    private void maybeShowHamburgerFeatureHighlight() {
-        if (!mActionBarAdapter.isSearchMode() && !mActionBarAdapter.isSelectionMode()
-                && SharedPreferenceUtil.getShouldShowHamburgerPromo(this)) {
-            if (FeatureHighlightHelper.showHamburgerFeatureHighlight(this)) {
-                SharedPreferenceUtil.setHamburgerPromoDisplayedBefore(this);
-            }
-        }
-    }
-
     @Override
     protected void onNewIntent(Intent intent) {
         if (ContactsDrawerActivity.ACTION_CREATE_GROUP.equals(intent.getAction())) {
@@ -275,9 +258,12 @@
             finish();
             return;
         }
-        mActionBarAdapter.initialize(null, mRequest);
 
-        mContactListFilterController.checkFilterValidity(false);
+        // Re-initialize ActionBarAdapter because {@link #onNewIntent(Intent)} doesn't invoke
+        // {@link Fragment#onActivityCreated(Bundle)} where we initialize ActionBarAdapter
+        // initially.
+        mAllFragment.setContactsRequest(mRequest);
+        mAllFragment.initializeActionBarAdapter(null);
 
         // Re-configure fragments.
         configureFragments(true /* from request */);
@@ -323,75 +309,43 @@
         return true;
     }
 
-    private void createViewsAndFragments(Bundle savedState) {
+    private void createViewsAndFragments() {
         setContentView(R.layout.people_activity);
 
         final FragmentManager fragmentManager = getFragmentManager();
 
-        // Hide all tabs (the current tab will later be reshown once a tab is selected)
         final FragmentTransaction transaction = fragmentManager.beginTransaction();
 
-        mTabTitles = new String[TabState.COUNT];
-        mTabTitles[TabState.ALL] = getString(R.string.all_contacts_tab_label);
-        mTabPager = getView(R.id.tab_pager);
-        mTabPagerAdapter = new TabPagerAdapter();
-        mTabPager.setAdapter(mTabPagerAdapter);
-        mTabPager.setOnPageChangeListener(mTabPagerListener);
-
-        // Configure toolbar and toolbar tabs. If in landscape mode, we configure tabs differently.
-        final ViewPagerTabs portraitViewPagerTabs
-                = (ViewPagerTabs) findViewById(R.id.lists_pager_header);
-        ViewPagerTabs landscapeViewPagerTabs = null;
-        if (portraitViewPagerTabs ==  null) {
-            landscapeViewPagerTabs = (ViewPagerTabs) getLayoutInflater().inflate(
-                    R.layout.people_activity_tabs_lands, mToolbar, /* attachToRoot = */ false);
-            mViewPagerTabs = landscapeViewPagerTabs;
-        } else {
-            mViewPagerTabs = portraitViewPagerTabs;
-        }
-        mViewPagerTabs.setViewPager(mTabPager);
-
-        final String ALL_TAG = "tab-pager-all";
-
-        // Create the fragments and add as children of the view pager.
-        // The pager adapter will only change the visibility; it'll never create/destroy
-        // fragments.
-        // However, if it's after screen rotation, the fragments have been re-created by
-        // the fragment manager, so first see if there're already the target fragments
-        // existing.
         mAllFragment = (DefaultContactBrowseListFragment)
-                fragmentManager.findFragmentByTag(ALL_TAG);
+                fragmentManager.findFragmentByTag(TAG_ALL);
+
+        mContactsView = getView(R.id.contacts_view);
 
         if (mAllFragment == null) {
             mAllFragment = new DefaultContactBrowseListFragment();
             mAllFragment.setAnimateOnLoad(true);
-            transaction.add(R.id.tab_pager, mAllFragment, ALL_TAG);
+            transaction.add(R.id.contacts_list_container, mAllFragment, TAG_ALL);
         }
 
-        mAllFragment.setFeatureHighlightCallback(this);
-        mAllFragment.setOnContactListActionListener(new ContactBrowserActionListener());
-        mAllFragment.setCheckBoxListListener(new CheckBoxListListener());
-        mAllFragment.setListType(mContactListFilterController.getFilterListType());
-
-        // Hide all fragments for now.  We adjust visibility when we get onSelectedTabChanged()
-        // from ActionBarAdapter.
-        transaction.hide(mAllFragment);
+        mAllFragment.setContactsAvailable(areContactsAvailable());
+        mAllFragment.setListType();
+        mAllFragment.setContactsRequest(mRequest);
 
         transaction.commitAllowingStateLoss();
         fragmentManager.executePendingTransactions();
 
-        mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(),
-                portraitViewPagerTabs, landscapeViewPagerTabs, mToolbar);
-        mActionBarAdapter.initialize(savedState, mRequest);
-
         // Configure floating action button
         mFloatingActionButtonContainer = findViewById(R.id.floating_action_button_container);
         final ImageButton floatingActionButton
                 = (ImageButton) findViewById(R.id.floating_action_button);
-        floatingActionButton.setOnClickListener(this);
+        floatingActionButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                onFabClicked();
+            }
+        });
         mFloatingActionButtonController = new FloatingActionButtonController(this,
                 mFloatingActionButtonContainer, floatingActionButton);
-        initializeFabVisibility();
 
         invalidateOptionsMenuIfNeeded();
 
@@ -433,13 +387,16 @@
 
     @Override
     protected void onPause() {
-        mOptionsMenuContactsAvailable = false;
         mProviderStatusWatcher.stop();
 
         LocalBroadcastManager.getInstance(this).unregisterReceiver(mSaveServiceListener);
 
         super.onPause();
 
+        if (Flags.getInstance(this).getBoolean(Experiments.PULL_TO_REFRESH)) {
+            ContentResolver.removeStatusChangeListener(mStatusChangeListenerHandle);
+            onSyncStateUpdated();
+        }
     }
 
     @Override
@@ -449,17 +406,16 @@
         mProviderStatusWatcher.start();
         updateViewConfiguration(true);
 
-        // Re-register the listener, which may have been cleared when onSaveInstanceState was
-        // called.  See also: onSaveInstanceState
-        mActionBarAdapter.setListener(this);
-        mDisableOptionItemSelected = false;
-        if (mTabPager != null) {
-            mTabPager.setOnPageChangeListener(mTabPagerListener);
+        if (Flags.getInstance(this).getBoolean(Experiments.PULL_TO_REFRESH)) {
+            mStatusChangeListenerHandle = ContentResolver.addStatusChangeListener(
+                    ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
+                            | ContentResolver.SYNC_OBSERVER_TYPE_PENDING
+                            | ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
+                    mSyncStatusObserver);
+            onSyncStateUpdated();
         }
-        // Current tab may have changed since the last onSaveInstanceState().  Make sure
-        // the actual contents match the tab.
-        updateFragmentsVisibility();
-        maybeShowHamburgerFeatureHighlight();
+        mAllFragment.maybeShowHamburgerFeatureHighlight();
+        initializeFabVisibility();
 
         mSaveServiceListener = new SaveServiceListener();
         LocalBroadcastManager.getInstance(this).registerReceiver(mSaveServiceListener,
@@ -469,16 +425,6 @@
     @Override
     protected void onDestroy() {
         mProviderStatusWatcher.removeListener(this);
-
-        // Some of variables will be null if this Activity redirects Intent.
-        // See also onCreate() or other methods called during the Activity's initialization.
-        if (mActionBarAdapter != null) {
-            mActionBarAdapter.setListener(null);
-        }
-        if (mContactListFilterController != null) {
-            mContactListFilterController.removeListener(this);
-        }
-
         super.onDestroy();
     }
 
@@ -487,36 +433,25 @@
             ContactListFilter filter = null;
             int actionCode = mRequest.getActionCode();
             boolean searchMode = mRequest.isSearchMode();
-            final int tabToOpen;
             switch (actionCode) {
                 case ContactsRequest.ACTION_ALL_CONTACTS:
-                    filter = createContactsFilter();
-                    tabToOpen = TabState.ALL;
+                    filter = AccountFilterUtil.createContactsFilter(this);
                     break;
                 case ContactsRequest.ACTION_CONTACTS_WITH_PHONES:
                     filter = ContactListFilter.createFilterWithType(
                             ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY);
-                    tabToOpen = TabState.ALL;
                     break;
 
                 case ContactsRequest.ACTION_FREQUENT:
                 case ContactsRequest.ACTION_STREQUENT:
                 case ContactsRequest.ACTION_STARRED:
-                    tabToOpen = TabState.ALL;
-                    break;
                 case ContactsRequest.ACTION_VIEW_CONTACT:
-                    tabToOpen = TabState.ALL;
-                    break;
                 default:
-                    tabToOpen = -1;
                     break;
             }
-            if (tabToOpen != -1) {
-                mActionBarAdapter.setCurrentTab(tabToOpen);
-            }
 
             if (filter != null) {
-                mContactListFilterController.setContactListFilter(filter, /* persistent */ false);
+                mAllFragment.setContactListFilter(filter);
                 searchMode = false;
             }
 
@@ -524,39 +459,26 @@
                 searchMode = false;
             }
 
-            mActionBarAdapter.setSearchMode(searchMode);
+            mAllFragment.getActionBarAdapter().setSearchMode(searchMode);
             configureContactListFragmentForRequest();
         }
 
-        configureContactListFragment();
-
-        invalidateOptionsMenuIfNeeded();
+        mAllFragment.configureContactListFragment();
     }
 
     private void initializeFabVisibility() {
-        final boolean hideFab = mActionBarAdapter.isSearchMode()
-                || mActionBarAdapter.isSelectionMode()
-                || !shouldShowFabForAccount();
-        mFloatingActionButtonContainer.setVisibility(hideFab ? View.GONE : View.VISIBLE);
+        mFloatingActionButtonContainer.setVisibility(shouldHideFab() ? View.GONE : View.VISIBLE);
         mFloatingActionButtonController.resetIn();
-        wasLastFabAnimationScaleIn = !hideFab;
+        wasLastFabAnimationScaleIn = !shouldHideFab();
     }
 
-    private boolean shouldShowFabForAccount() {
-        return isCurrentAccountFilterWritable()
-                || isAllContactsFilter(mContactListFilterController.getFilter());
+    private boolean shouldHideFab() {
+        if (mAllFragment.getActionBarAdapter() == null) return false;
+        return mAllFragment.getActionBarAdapter().isSearchMode()
+                || mAllFragment.getActionBarAdapter().isSelectionMode();
     }
 
-    private boolean isCurrentAccountFilterWritable() {
-        final ContactListFilter currentFilter = mContactListFilterController.getFilter();
-        final AccountWithDataSet accountOfCurrentFilter = new AccountWithDataSet(
-                currentFilter.accountName, currentFilter.accountType, currentFilter.dataSet);
-        return accountOfCurrentFilter.isLocalAccount()
-                || (mWritableAccounts != null
-                && mWritableAccounts.contains(accountOfCurrentFilter));
-    }
-
-    private void showFabWithAnimation(boolean showFab) {
+    public void showFabWithAnimation(boolean showFab) {
         if (mFloatingActionButtonContainer == null) {
             return;
         }
@@ -576,310 +498,6 @@
         }
     }
 
-    @Override
-    public void onContactListFilterChanged() {
-        if (mAllFragment == null || !mAllFragment.isAdded()) {
-            return;
-        }
-
-        setFilterAndUpdateTitle(mContactListFilterController.getFilter());
-        // Scroll to top after filter is changed.
-        mAllFragment.getListView().setSelection(0);
-        showFabWithAnimation(shouldShowFabForAccount());
-
-        invalidateOptionsMenuIfNeeded();
-    }
-
-    /**
-     * Handler for action bar actions.
-     */
-    @Override
-    public void onAction(int action) {
-        switch (action) {
-            case ActionBarAdapter.Listener.Action.START_SELECTION_MODE:
-                mAllFragment.displayCheckBoxes(true);
-                startSearchOrSelectionMode();
-                break;
-            case ActionBarAdapter.Listener.Action.START_SEARCH_MODE:
-                if (!mIsRecreatedInstance) {
-                    Logger.logScreenView(this, ScreenType.SEARCH);
-                }
-                startSearchOrSelectionMode();
-                break;
-            case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE:
-                showFabWithAnimation(shouldShowFabForAccount());
-                break;
-            case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
-                // If queryString is empty, fragment data will not be reloaded,
-                // so hamburger promo should be checked now.
-                // If not empty, promo should be checked and displayed after reloading. (b/30706521)
-                if (TextUtils.isEmpty(mAllFragment.getQueryString())) {
-                    maybeShowHamburgerFeatureHighlight();
-                }
-                setQueryTextToFragment("");
-                updateFragmentsVisibility();
-                invalidateOptionsMenu();
-                showFabWithAnimation(shouldShowFabForAccount());
-                break;
-            case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY:
-                final String queryString = mActionBarAdapter.getQueryString();
-                setQueryTextToFragment(queryString);
-                updateDebugOptionsVisibility(
-                        ENABLE_DEBUG_OPTIONS_HIDDEN_CODE.equals(queryString));
-                break;
-            default:
-                throw new IllegalStateException("Unkonwn ActionBarAdapter action: " + action);
-        }
-    }
-
-    private void startSearchOrSelectionMode() {
-        configureFragments(false /* from request */);
-        updateFragmentsVisibility();
-        invalidateOptionsMenu();
-        showFabWithAnimation(/* showFab */ false);
-        if (!SharedPreferenceUtil.getHamburgerPromoTriggerActionHappenedBefore(this)) {
-            SharedPreferenceUtil.setHamburgerPromoTriggerActionHappenedBefore(this);
-        }
-    }
-
-    @Override
-    public void onSelectedTabChanged() {
-        updateFragmentsVisibility();
-    }
-
-    @Override
-    public void onUpButtonPressed() {
-        onBackPressed();
-    }
-
-    private void updateDebugOptionsVisibility(boolean visible) {
-        if (mEnableDebugMenuOptions != visible) {
-            mEnableDebugMenuOptions = visible;
-            invalidateOptionsMenu();
-        }
-    }
-
-    /**
-     * Updates the fragment/view visibility according to the current mode, such as
-     * {@link ActionBarAdapter#isSearchMode()} and {@link ActionBarAdapter#getCurrentTab()}.
-     */
-    private void updateFragmentsVisibility() {
-        int tab = mActionBarAdapter.getCurrentTab();
-
-        if (mActionBarAdapter.isSearchMode() || mActionBarAdapter.isSelectionMode()) {
-            mTabPagerAdapter.setTabsHidden(true);
-        } else {
-            // No smooth scrolling if quitting from the search/selection mode.
-            final boolean wereTabsHidden = mTabPagerAdapter.areTabsHidden()
-                    || mActionBarAdapter.isSelectionMode();
-            mTabPagerAdapter.setTabsHidden(false);
-            if (mTabPager.getCurrentItem() != tab) {
-                mTabPager.setCurrentItem(tab, !wereTabsHidden);
-            }
-        }
-        if (!mActionBarAdapter.isSelectionMode()) {
-            mAllFragment.displayCheckBoxes(false);
-        }
-        invalidateOptionsMenu();
-        showEmptyStateForTab(tab);
-    }
-
-    private void showEmptyStateForTab(int tab) {
-        if (mContactsUnavailableFragment != null) {
-            switch (getTabPositionForTextDirection(tab)) {
-                case TabState.ALL:
-                    mContactsUnavailableFragment.setTabInfo(R.string.noContacts, TabState.ALL);
-                    break;
-            }
-            // When using the mContactsUnavailableFragment the ViewPager doesn't contain two views.
-            // Therefore, we have to trick the ViewPagerTabs into thinking we have changed tabs
-            // when the mContactsUnavailableFragment changes. Otherwise the tab strip won't move.
-            mViewPagerTabs.onPageScrolled(tab, 0, 0);
-        }
-    }
-
-    private class TabPagerListener implements ViewPager.OnPageChangeListener {
-
-        // This package-protected constructor is here because of a possible compiler bug.
-        // PeopleActivity$1.class should be generated due to the private outer/inner class access
-        // needed here.  But for some reason, PeopleActivity$1.class is missing.
-        // Since $1 class is needed as a jvm work around to get access to the inner class,
-        // changing the constructor to package-protected or public will solve the problem.
-        // To verify whether $1 class is needed, javap PeopleActivity$TabPagerListener and look for
-        // references to PeopleActivity$1.
-        //
-        // When the constructor is private and PeopleActivity$1.class is missing, proguard will
-        // correctly catch this and throw warnings and error out the build on user/userdebug builds.
-        //
-        // All private inner classes below also need this fix.
-        TabPagerListener() {}
-
-        @Override
-        public void onPageScrollStateChanged(int state) {
-            if (!mTabPagerAdapter.areTabsHidden()) {
-                mViewPagerTabs.onPageScrollStateChanged(state);
-            }
-        }
-
-        @Override
-        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-            if (!mTabPagerAdapter.areTabsHidden()) {
-                mViewPagerTabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
-            }
-        }
-
-        @Override
-        public void onPageSelected(int position) {
-            // Make sure not in the search mode, in which case position != TabState.ordinal().
-            if (!mTabPagerAdapter.areTabsHidden()) {
-                mActionBarAdapter.setCurrentTab(position, false);
-                mViewPagerTabs.onPageSelected(position);
-                showEmptyStateForTab(position);
-                invalidateOptionsMenu();
-            }
-        }
-    }
-
-    /**
-     * Adapter for the {@link ViewPager}.  Unlike {@link FragmentPagerAdapter},
-     * {@link #instantiateItem} returns existing fragments, and {@link #instantiateItem}/
-     * {@link #destroyItem} show/hide fragments instead of attaching/detaching.
-     *
-     * In search mode, we always show the "all" fragment, and disable the swipe.  We change the
-     * number of items to 1 to disable the swipe.
-     *
-     * TODO figure out a more straight way to disable swipe.
-     */
-    private class TabPagerAdapter extends PagerAdapter {
-        private final FragmentManager mFragmentManager;
-        private FragmentTransaction mCurTransaction = null;
-
-        private boolean mAreTabsHiddenInTabPager;
-
-        private Fragment mCurrentPrimaryItem;
-
-        public TabPagerAdapter() {
-            mFragmentManager = getFragmentManager();
-        }
-
-        public boolean areTabsHidden() {
-            return mAreTabsHiddenInTabPager;
-        }
-
-        public void setTabsHidden(boolean hideTabs) {
-            if (hideTabs == mAreTabsHiddenInTabPager) {
-                return;
-            }
-            mAreTabsHiddenInTabPager = hideTabs;
-            notifyDataSetChanged();
-        }
-
-        @Override
-        public int getCount() {
-            return mAreTabsHiddenInTabPager ? 1 : TabState.COUNT;
-        }
-
-        /** Gets called when the number of items changes. */
-        @Override
-        public int getItemPosition(Object object) {
-            if (mAreTabsHiddenInTabPager) {
-                if (object == mAllFragment) {
-                    return 0; // Only 1 page in search mode
-                }
-            } else {
-                if (object == mAllFragment) {
-                    return getTabPositionForTextDirection(TabState.ALL);
-                }
-            }
-            return POSITION_NONE;
-        }
-
-        @Override
-        public void startUpdate(ViewGroup container) {
-        }
-
-        private Fragment getFragment(int position) {
-            position = getTabPositionForTextDirection(position);
-            if (mAreTabsHiddenInTabPager) {
-                if (position != 0) {
-                    // This has only been observed in monkey tests.
-                    // Let's log this issue, but not crash
-                    Log.w(TAG, "Request fragment at position=" + position + ", eventhough we " +
-                            "are in search mode");
-                }
-                return mAllFragment;
-            } else {
-                if (position == TabState.ALL) {
-                    return mAllFragment;
-                }
-            }
-            throw new IllegalArgumentException("position: " + position);
-        }
-
-        @Override
-        public Object instantiateItem(ViewGroup container, int position) {
-            if (mCurTransaction == null) {
-                mCurTransaction = mFragmentManager.beginTransaction();
-            }
-            Fragment f = getFragment(position);
-            mCurTransaction.show(f);
-
-            // Non primary pages are not visible.
-            f.setUserVisibleHint(f == mCurrentPrimaryItem);
-            return f;
-        }
-
-        @Override
-        public void destroyItem(ViewGroup container, int position, Object object) {
-            if (mCurTransaction == null) {
-                mCurTransaction = mFragmentManager.beginTransaction();
-            }
-            mCurTransaction.hide((Fragment) object);
-        }
-
-        @Override
-        public void finishUpdate(ViewGroup container) {
-            if (mCurTransaction != null) {
-                mCurTransaction.commitAllowingStateLoss();
-                mCurTransaction = null;
-                mFragmentManager.executePendingTransactions();
-            }
-        }
-
-        @Override
-        public boolean isViewFromObject(View view, Object object) {
-            return ((Fragment) object).getView() == view;
-        }
-
-        @Override
-        public void setPrimaryItem(ViewGroup container, int position, Object object) {
-            Fragment fragment = (Fragment) object;
-            if (mCurrentPrimaryItem != fragment) {
-                if (mCurrentPrimaryItem != null) {
-                    mCurrentPrimaryItem.setUserVisibleHint(false);
-                }
-                if (fragment != null) {
-                    fragment.setUserVisibleHint(true);
-                }
-                mCurrentPrimaryItem = fragment;
-            }
-        }
-
-        @Override
-        public Parcelable saveState() {
-            return null;
-        }
-
-        @Override
-        public void restoreState(Parcelable state, ClassLoader loader) {
-        }
-
-        @Override
-        public CharSequence getPageTitle(int position) {
-            return mTabTitles[position];
-        }
-    }
-
     private void setQueryTextToFragment(String query) {
         mAllFragment.setQueryString(query, true);
         mAllFragment.setVisibleScrollbarEnabled(!mAllFragment.isSearchMode());
@@ -891,8 +509,7 @@
             mAllFragment.setSelectedContactUri(contactUri);
         }
 
-        setFilterAndUpdateTitle(mContactListFilterController.getFilter());
-        setQueryTextToFragment(mActionBarAdapter.getQueryString());
+        setQueryTextToFragment(mAllFragment.getActionBarAdapter().getQueryString());
 
         if (mRequest.isDirectorySearchEnabled()) {
             mAllFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
@@ -901,28 +518,9 @@
         }
     }
 
-    private void configureContactListFragment() {
-        // Filter may be changed when this Activity is in background.
-        setFilterAndUpdateTitle(mContactListFilterController.getFilter());
-
-        mAllFragment.setVerticalScrollbarPosition(getScrollBarPosition());
-        mAllFragment.setSelectionVisible(false);
-    }
-
-    private int getScrollBarPosition() {
-        return isRTL() ? View.SCROLLBAR_POSITION_LEFT : View.SCROLLBAR_POSITION_RIGHT;
-    }
-
-    private boolean isRTL() {
-        final Locale locale = Locale.getDefault();
-        return TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL;
-    }
-
     @Override
     public void onFiltersLoaded(List<ContactListFilter> accountFilterItems) {
         super.onFiltersLoaded(accountFilterItems);
-        mWritableAccounts =
-                AccountTypeManager.getInstance(this).getAccounts(/* contactWritableOnly */ true);
         initializeFabVisibility();
     }
 
@@ -959,39 +557,43 @@
         // actually at least one real account (not "local" account) on device.
         if ((mProviderStatus.equals(ProviderStatus.STATUS_EMPTY) && hasNonLocalAccount())
                 || mProviderStatus.equals(ProviderStatus.STATUS_NORMAL)) {
-            // Ensure that the mTabPager is visible; we may have made it invisible below.
+            // Ensure that the mContactsView is visible; we may have made it invisible below.
             contactsUnavailableView.setVisibility(View.GONE);
-            if (mTabPager != null) {
-                mTabPager.setVisibility(View.VISIBLE);
+            if (mContactsView != null) {
+                mContactsView.setVisibility(View.VISIBLE);
             }
 
             if (mAllFragment != null) {
+                getFragmentManager().beginTransaction()
+                        .show(mAllFragment)
+                        .commitAllowingStateLoss();
+                mAllFragment.setContactsAvailable(areContactsAvailable());
                 mAllFragment.setEnabled(true);
             }
         } else {
+            final FragmentTransaction transaction = getFragmentManager().beginTransaction();
             // Setting up the page so that the user can still use the app
             // even without an account.
             if (mAllFragment != null) {
                 mAllFragment.setEnabled(false);
+                transaction.hide(mAllFragment);
             }
             if (mContactsUnavailableFragment == null) {
                 mContactsUnavailableFragment = new ContactsUnavailableFragment();
                 mContactsUnavailableFragment.setOnContactsUnavailableActionListener(
                         new ContactsUnavailableFragmentListener());
-                getFragmentManager().beginTransaction()
-                        .replace(R.id.contacts_unavailable_container, mContactsUnavailableFragment)
-                        .commitAllowingStateLoss();
+                transaction.replace(
+                        R.id.contacts_unavailable_container, mContactsUnavailableFragment);
             }
+            transaction.commitAllowingStateLoss();
             mContactsUnavailableFragment.updateStatus(mProviderStatus);
 
-            // Show the contactsUnavailableView, and hide the mTabPager so that we don't
+            // Show the contactsUnavailableView, and hide the mContactsView so that we don't
             // see it sliding in underneath the contactsUnavailableView at the edges.
             contactsUnavailableView.setVisibility(View.VISIBLE);
-            if (mTabPager != null) {
-                mTabPager.setVisibility(View.GONE);
+            if (mContactsView != null) {
+                mContactsView.setVisibility(View.GONE);
             }
-
-            showEmptyStateForTab(mActionBarAdapter.getCurrentTab());
         }
 
         invalidateOptionsMenuIfNeeded();
@@ -1010,94 +612,6 @@
         return !allAccounts.get(0).isLocalAccount();
     }
 
-    private final class ContactBrowserActionListener implements OnContactBrowserActionListener {
-        ContactBrowserActionListener() {}
-
-        @Override
-        public void onSelectionChange() {
-
-        }
-
-        @Override
-        public void onViewContactAction(int position, Uri contactLookupUri,
-                boolean isEnterpriseContact) {
-            if (isEnterpriseContact) {
-                // No implicit intent as user may have a different contacts app in work profile.
-                QuickContact.showQuickContact(PeopleActivity.this, new Rect(), contactLookupUri,
-                        QuickContactActivity.MODE_FULLY_EXPANDED, null);
-            } else {
-                final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(
-                        PeopleActivity.this, contactLookupUri,
-                        QuickContactActivity.MODE_FULLY_EXPANDED);
-                final int previousScreen;
-                if (mAllFragment.isSearchMode()) {
-                    previousScreen = ScreenType.SEARCH;
-                } else {
-                    if (isAllContactsFilter(mContactListFilterController.getFilter())) {
-                        if (position < mAllFragment.getAdapter().getNumberOfFavorites()) {
-                            previousScreen = ScreenType.FAVORITES;
-                        } else {
-                            previousScreen = ScreenType.ALL_CONTACTS;
-                        }
-                    } else {
-                        previousScreen = ScreenType.LIST_ACCOUNT;
-                    }
-                }
-                Logger.logListEvent(ListEvent.ActionType.CLICK,
-                        /* listType */ getListTypeIncludingSearch(),
-                        /* count */ mAllFragment.getAdapter().getCount(),
-                        /* clickedIndex */ position, /* numSelected */ 0);
-                intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, previousScreen);
-                ImplicitIntentsUtil.startActivityInApp(PeopleActivity.this, intent);
-            }
-        }
-
-        @Override
-        public void onDeleteContactAction(Uri contactUri) {
-            ContactDeletionInteraction.start(PeopleActivity.this, contactUri, false);
-        }
-
-        @Override
-        public void onFinishAction() {
-            onBackPressed();
-        }
-
-        @Override
-        public void onInvalidSelection() {
-            ContactListFilter filter;
-            ContactListFilter currentFilter = mAllFragment.getFilter();
-            if (currentFilter != null
-                    && currentFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
-                filter = createContactsFilter();
-                setFilterAndUpdateTitle(filter);
-            } else {
-                filter = ContactListFilter.createFilterWithType(
-                        ContactListFilter.FILTER_TYPE_SINGLE_CONTACT);
-                setFilterAndUpdateTitle(filter, /* restoreSelectedUri */ false);
-            }
-            persistFilterIfNeeded(filter);
-        }
-    }
-
-    private final class CheckBoxListListener implements OnCheckBoxListActionListener {
-        @Override
-        public void onStartDisplayingCheckBoxes() {
-            mActionBarAdapter.setSelectionMode(true);
-            invalidateOptionsMenu();
-        }
-
-        @Override
-        public void onSelectedContactIdsChanged() {
-            mActionBarAdapter.setSelectionCount(mAllFragment.getSelectedContactIds().size());
-            invalidateOptionsMenu();
-        }
-
-        @Override
-        public void onStopDisplayingCheckBoxes() {
-            mActionBarAdapter.setSelectionMode(false);
-        }
-    }
-
     private class ContactsUnavailableFragmentListener
             implements OnContactsUnavailableActionListener {
         ContactsUnavailableFragmentListener() {}
@@ -1120,232 +634,19 @@
         }
     }
 
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        if (!areContactsAvailable()) {
-            // If contacts aren't available, hide all menu items.
-            return false;
-        }
-        super.onCreateOptionsMenu(menu);
-
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.people_options, menu);
-
-        return true;
-    }
-
     private void invalidateOptionsMenuIfNeeded() {
-        if (isOptionsMenuChanged()) {
+        if (mAllFragment != null
+                || mAllFragment.getOptionsMenuContactsAvailable() != areContactsAvailable()) {
             invalidateOptionsMenu();
         }
     }
 
-    public boolean isOptionsMenuChanged() {
-        if (mOptionsMenuContactsAvailable != areContactsAvailable()) {
-            return true;
-        }
-
-        if (mAllFragment != null && mAllFragment.isOptionsMenuChanged()) {
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        mOptionsMenuContactsAvailable = areContactsAvailable();
-        if (!mOptionsMenuContactsAvailable) {
-            return false;
-        }
-
-        final boolean isSearchOrSelectionMode = mActionBarAdapter.isSearchMode()
-                || mActionBarAdapter.isSelectionMode();
-        makeMenuItemVisible(menu, R.id.menu_search, !isSearchOrSelectionMode);
-
-        final boolean showSelectedContactOptions = mActionBarAdapter.isSelectionMode()
-                && mAllFragment.getSelectedContactIds().size() != 0;
-        makeMenuItemVisible(menu, R.id.menu_share, showSelectedContactOptions);
-        makeMenuItemVisible(menu, R.id.menu_delete, showSelectedContactOptions);
-        final boolean showLinkContactsOptions = mActionBarAdapter.isSelectionMode()
-                && mAllFragment.getSelectedContactIds().size() > 1;
-        makeMenuItemVisible(menu, R.id.menu_join, showLinkContactsOptions);
-
-        // Debug options need to be visible even in search mode.
-        makeMenuItemVisible(menu, R.id.export_database, mEnableDebugMenuOptions &&
-                hasExportIntentHandler());
-
-        return true;
-    }
-
-    private boolean hasExportIntentHandler() {
-        final Intent intent = new Intent();
-        intent.setAction("com.android.providers.contacts.DUMP_DATABASE");
-        final List<ResolveInfo> receivers = getPackageManager().queryIntentActivities(intent,
-                PackageManager.MATCH_DEFAULT_ONLY);
-        return receivers != null && receivers.size() > 0;
-    }
-
-    private void makeMenuItemVisible(Menu menu, int itemId, boolean visible) {
-        final MenuItem item = menu.findItem(itemId);
-        if (item != null) {
-            item.setVisible(visible);
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (mDisableOptionItemSelected) {
-            return false;
-        }
-
-        switch (item.getItemId()) {
-            case android.R.id.home: {
-                // The home icon on the action bar is pressed
-                if (mActionBarAdapter.isUpShowing()) {
-                    // "UP" icon press -- should be treated as "back".
-                    onBackPressed();
-                }
-                return true;
-            }
-            case R.id.menu_search: {
-                onSearchRequested();
-                return true;
-            }
-            case R.id.menu_share: {
-                shareSelectedContacts();
-                return true;
-            }
-            case R.id.menu_join: {
-                Logger.logListEvent(ListEvent.ActionType.LINK,
-                        /* listType */ getListTypeIncludingSearch(),
-                        /* count */ mAllFragment.getAdapter().getCount(), /* clickedIndex */ -1,
-                        /* numSelected */ mAllFragment.getAdapter().getSelectedContactIds().size());
-                joinSelectedContacts();
-                return true;
-            }
-            case R.id.menu_delete: {
-                deleteSelectedContacts();
-                return true;
-            }
-            case R.id.export_database: {
-                final Intent intent = new Intent("com.android.providers.contacts.DUMP_DATABASE");
-                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-                ImplicitIntentsUtil.startActivityOutsideApp(this, intent);
-                return true;
-            }
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
     private void showImportExportDialogFragment(){
         ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable(),
                 PeopleActivity.class, ImportExportDialogFragment.EXPORT_MODE_ALL_CONTACTS);
     }
 
     @Override
-    public boolean onSearchRequested() { // Search key pressed.
-        if (!mActionBarAdapter.isSelectionMode()) {
-            mActionBarAdapter.setSearchMode(true);
-        }
-        return true;
-    }
-
-    /**
-     * Share all contacts that are currently selected in mAllFragment. This method is pretty
-     * inefficient for handling large numbers of contacts. I don't expect this to be a problem.
-     */
-    private void shareSelectedContacts() {
-        final StringBuilder uriListBuilder = new StringBuilder();
-        for (Long contactId : mAllFragment.getSelectedContactIds()) {
-            final Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-            final Uri lookupUri = Contacts.getLookupUri(getContentResolver(), contactUri);
-            if (lookupUri == null) {
-                continue;
-            }
-            final List<String> pathSegments = lookupUri.getPathSegments();
-            if (pathSegments.size() < 2) {
-                continue;
-            }
-            final String lookupKey = pathSegments.get(pathSegments.size() - 2);
-            if (uriListBuilder.length() > 0) {
-                uriListBuilder.append(':');
-            }
-            uriListBuilder.append(Uri.encode(lookupKey));
-        }
-        if (uriListBuilder.length() == 0) {
-            return;
-        }
-        final Uri uri = Uri.withAppendedPath(
-                Contacts.CONTENT_MULTI_VCARD_URI,
-                Uri.encode(uriListBuilder.toString()));
-        final Intent intent = new Intent(Intent.ACTION_SEND);
-        intent.setType(Contacts.CONTENT_VCARD_TYPE);
-        intent.putExtra(Intent.EXTRA_STREAM, uri);
-        try {
-            startActivityForResult(Intent.createChooser(intent, getResources().getQuantityString(
-                    R.plurals.title_share_via,
-                    /* quantity */ mAllFragment.getSelectedContactIds().size()))
-                    , ACTIVITY_REQUEST_CODE_SHARE);
-        } catch (final ActivityNotFoundException ex) {
-            Toast.makeText(this, R.string.share_error, Toast.LENGTH_SHORT).show();
-        }
-    }
-
-    private void joinSelectedContacts() {
-        final Intent intent = ContactSaveService.createJoinSeveralContactsIntent(
-                this, mAllFragment.getSelectedContactIdsArray());
-        this.startService(intent);
-
-        mActionBarAdapter.setSelectionMode(false);
-    }
-
-    private void deleteSelectedContacts() {
-        ContactMultiDeletionInteraction.start(PeopleActivity.this,
-                mAllFragment.getSelectedContactIds());
-    }
-
-    @Override
-    public void onDeletionFinished() {
-        // The parameters count and numSelected are both the number of contacts before deletion.
-        Logger.logListEvent(ListEvent.ActionType.DELETE,
-                /* listType */ getListTypeIncludingSearch(),
-                /* count */ mAllFragment.getAdapter().getCount(), /* clickedIndex */ -1,
-                /* numSelected */ mAllFragment.getSelectedContactIds().size());
-        mActionBarAdapter.setSelectionMode(false);
-    }
-
-    private int getListTypeIncludingSearch() {
-        return mAllFragment.isSearchMode()
-                ? ListEvent.ListType.SEARCH_RESULT : mAllFragment.getListType();
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        switch (requestCode) {
-            // TODO: Using the new startActivityWithResultFromFragment API this should not be needed
-            // anymore
-            case ContactEntryListFragment.ACTIVITY_REQUEST_CODE_PICKER:
-                if (resultCode == RESULT_OK) {
-                    mAllFragment.onPickerResult(data);
-                }
-            case ACTIVITY_REQUEST_CODE_SHARE:
-                Logger.logListEvent(ListEvent.ActionType.SHARE,
-                    /* listType */ getListTypeIncludingSearch(),
-                    /* count */ mAllFragment.getAdapter().getCount(), /* clickedIndex */ -1,
-                    /* numSelected */ mAllFragment.getAdapter().getSelectedContactIds().size());
-
-// TODO fix or remove multipicker code
-//                else if (resultCode == RESULT_CANCELED && mMode == MODE_PICK_MULTIPLE_PHONES) {
-//                    // Finish the activity if the sub activity was canceled as back key is used
-//                    // to confirm user selection in MODE_PICK_MULTIPLE_PHONES.
-//                    finish();
-//                }
-//                break;
-        }
-    }
-
-    @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         // TODO move to the fragment
 
@@ -1355,14 +656,14 @@
                 // If COMBINING_ACCENT is set, it's not a unicode character.
                 && ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) == 0)
                 && !Character.isWhitespace(unicodeChar)) {
-            if (mActionBarAdapter.isSelectionMode()) {
+            if (mAllFragment.getActionBarAdapter().isSelectionMode()) {
                 // Ignore keyboard input when in selection mode.
                 return true;
             }
             String query = new String(new int[]{unicodeChar}, 0, 1);
-            if (!mActionBarAdapter.isSearchMode()) {
-                mActionBarAdapter.setSearchMode(true);
-                mActionBarAdapter.setQueryString(query);
+            if (!mAllFragment.getActionBarAdapter().isSearchMode()) {
+                mAllFragment.getActionBarAdapter().setSearchMode(true);
+                mAllFragment.getActionBarAdapter().setQueryString(query);
                 return true;
             }
         }
@@ -1378,142 +679,47 @@
 
         if (mDrawer.isDrawerOpen(GravityCompat.START)) {
             mDrawer.closeDrawer(GravityCompat.START);
-        } else if (mActionBarAdapter.isSelectionMode()) {
-            mActionBarAdapter.setSelectionMode(false);
+        } else if (mAllFragment.getActionBarAdapter().isSelectionMode()) {
+            mAllFragment.getActionBarAdapter().setSelectionMode(false);
             mAllFragment.displayCheckBoxes(false);
-        } else if (mActionBarAdapter.isSearchMode()) {
-            mActionBarAdapter.setSearchMode(false);
-
+        } else if (mAllFragment.getActionBarAdapter().isSearchMode()) {
+            mAllFragment.getActionBarAdapter().setSearchMode(false);
             if (mAllFragment.wasSearchResultClicked()) {
                 mAllFragment.resetSearchResultClicked();
             } else {
                 Logger.logScreenView(this, ScreenType.SEARCH_EXIT);
                 Logger.logSearchEvent(mAllFragment.createSearchState());
             }
-        } else if (!isAllContactsFilter(mContactListFilterController.getFilter())) {
+        } else if (!isAllContactsFilter(mAllFragment.getFilter())) {
             switchToAllContacts();
         } else {
             super.onBackPressed();
         }
     }
 
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        mActionBarAdapter.onSaveInstanceState(outState);
-
-        // Clear the listener to make sure we don't get callbacks after onSaveInstanceState,
-        // in order to avoid doing fragment transactions after it.
-        // TODO Figure out a better way to deal with the issue.
-        mDisableOptionItemSelected = true;
-        mActionBarAdapter.setListener(null);
-        if (mTabPager != null) {
-            mTabPager.setOnPageChangeListener(null);
-        }
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle savedInstanceState) {
-        super.onRestoreInstanceState(savedInstanceState);
-        // In our own lifecycle, the focus is saved and restore but later taken away by the
-        // ViewPager. As a hack, we force focus on the SearchView if we know that we are searching.
-        // This fixes the keyboard going away on screen rotation
-        if (mActionBarAdapter.isSearchMode()) {
-            mActionBarAdapter.setFocusOnSearchView();
-        }
-    }
-
-    @Override
-    public DialogManager getDialogManager() {
-        return mDialogManager;
-    }
-
-    @Override
-    public void onClick(View view) {
-        switch (view.getId()) {
-            case R.id.floating_action_button:
-                onFabClicked();
-                break;
-            default:
-                Log.wtf(TAG, "Unexpected onClick event from " + view);
-        }
-    }
-
     public void onFabClicked() {
         final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
-        final Bundle extras = getIntent().getExtras();
-        if (extras != null) {
-            final ContactListFilter filter = mContactListFilterController.getFilter();
-            // If we are in account view, we pass the account explicitly in order to
-            // create contact in the account. This will prevent the default account dialog
-            // from being displayed.
-            if (!isAllContactsFilter(filter) && !isDeviceContactsFilter(filter)) {
-                final Account account = new Account(filter.accountName, filter.accountType);
-                extras.putParcelable(Intents.Insert.EXTRA_ACCOUNT, account);
-                extras.putString(Intents.Insert.EXTRA_DATA_SET, filter.dataSet);
-            }
-            intent.putExtras(extras);
+        Bundle extras = getIntent().getExtras();
+        if (extras == null) {
+            extras = new Bundle();
         }
+        final ContactListFilter filter = mAllFragment.getFilter();
+        // If we are in account view, we pass the account explicitly in order to
+        // create contact in the account. This will prevent the default account dialog
+        // from being displayed.
+        if (!isAllContactsFilter(filter) && !isDeviceContactsFilter(filter)) {
+            final Account account = new Account(filter.accountName, filter.accountType);
+            extras.putParcelable(Intents.Insert.EXTRA_ACCOUNT, account);
+            extras.putString(Intents.Insert.EXTRA_DATA_SET, filter.dataSet);
+        }
+        intent.putExtras(extras);
         try {
             ImplicitIntentsUtil.startActivityInApp(PeopleActivity.this, intent);
         } catch (ActivityNotFoundException ex) {
-            Toast.makeText(PeopleActivity.this, R.string.missing_app,
-                    Toast.LENGTH_SHORT).show();
+            Toast.makeText(PeopleActivity.this, R.string.missing_app, Toast.LENGTH_SHORT).show();
         }
     }
 
-    /**
-     * Returns the tab position adjusted for the text direction.
-     */
-    private int getTabPositionForTextDirection(int position) {
-        if (isRTL()) {
-            return TabState.COUNT - 1 - position;
-        }
-        return position;
-    }
-
-    private void setFilterAndUpdateTitle(ContactListFilter filter) {
-        setFilterAndUpdateTitle(filter, true);
-    }
-
-    private void setFilterAndUpdateTitle(ContactListFilter filter, boolean restoreSelectedUri) {
-        mAllFragment.setFilter(filter, restoreSelectedUri);
-
-        mAllFragment.setListType(mContactListFilterController.getFilterListType());
-
-        updateFilterMenu(filter);
-
-        if (getSupportActionBar() != null) {
-            String actionBarTitle;
-            if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS) {
-                actionBarTitle = getString(R.string.account_phone);
-            } else if (!TextUtils.isEmpty(filter.accountName)) {
-                actionBarTitle = getActionBarTitleForAccount(filter);
-            } else {
-                actionBarTitle = getString(R.string.contactsList);
-            }
-            getSupportActionBar().setTitle(actionBarTitle);
-            if (CompatUtils.isNCompatible()) {
-                this.setTitle(actionBarTitle);
-                getWindow().getDecorView()
-                        .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-            }
-        }
-    }
-
-    private String getActionBarTitleForAccount(ContactListFilter filter) {
-        if (GoogleAccountType.ACCOUNT_TYPE.equals(filter.accountType)) {
-            return getString(R.string.title_from_google);
-        }
-        return getString(R.string.title_from_other_accounts, filter.accountName);
-    }
-
-    // Persist filter only when it's of the type FILTER_TYPE_ALL_ACCOUNTS.
-    private void persistFilterIfNeeded(ContactListFilter filter) {
-        mContactListFilterController.setContactListFilter(filter,
-                /* persistent */ isAllContactsFilter(filter));
-    }
-
     private boolean isAllContactsFilter(ContactListFilter filter) {
         return filter != null && filter.isContactsFilterType();
     }
@@ -1529,12 +735,7 @@
 
     @Override
     protected ContactListFilter getContactListFilter() {
-        return mContactListFilterController.getFilter();
-    }
-
-    @Override
-    public void onLoadFinishedCallback() {
-        maybeShowHamburgerFeatureHighlight();
+        return mAllFragment.getFilter();
     }
 
     private void onGroupDeleted(Intent intent) {
diff --git a/src/com/android/contacts/common/Experiments.java b/src/com/android/contacts/common/Experiments.java
index c811e27..8932cac 100644
--- a/src/com/android/contacts/common/Experiments.java
+++ b/src/com/android/contacts/common/Experiments.java
@@ -20,6 +20,21 @@
  */
 public final class Experiments {
 
+    /**
+     * Experiment to enable dynamic strequent shortcuts.
+     */
+    public static final String DYNAMIC_SHORTCUTS = "Shortcuts__dynamic_shortcuts";
+
+    /**
+     * Experiment to toggle contacts sync using the pull to refresh gesture.
+     */
+    public static final String PULL_TO_REFRESH = "PullToRefresh__pull_to_refresh";
+
+    /**
+     * Search study boolean indicating whether to inject yenta search results before CP2 results.
+     */
+    public static final String SEARCH_YENTA = "Search__yenta";
+
     private Experiments() {
     }
 }
diff --git a/src/com/android/contacts/common/list/ContactEntryListFragment.java b/src/com/android/contacts/common/list/ContactEntryListFragment.java
index 0c72d68..387b303 100644
--- a/src/com/android/contacts/common/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/common/list/ContactEntryListFragment.java
@@ -119,7 +119,7 @@
     private boolean mEnabled = true;
 
     private T mAdapter;
-    private View mView;
+    protected View mView;
     private ListView mListView;
 
     /**
diff --git a/src/com/android/contacts/common/list/ContactListFilter.java b/src/com/android/contacts/common/list/ContactListFilter.java
index e99c374..3eca435 100644
--- a/src/com/android/contacts/common/list/ContactListFilter.java
+++ b/src/com/android/contacts/common/list/ContactListFilter.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.common.list;
 
+import android.accounts.Account;
 import android.content.SharedPreferences;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -25,6 +26,11 @@
 import android.text.TextUtils;
 
 import com.android.contacts.common.logging.ListEvent;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.model.account.GoogleAccountType;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Contact list filter parameters.
@@ -366,4 +372,59 @@
                 return "(unknown)";
         }
     }
+
+    /**
+     * Returns true if this ContactListFilter contains at least one Google account.
+     * (see {@link #isGoogleAccountType)
+     */
+    public boolean isSyncable(List<AccountWithDataSet> accounts) {
+        // TODO(samchen): Check FILTER_TYPE_CUSTOM
+        if (isGoogleAccountType() && filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
+            return true;
+        }
+        if (filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS
+                || filterType == ContactListFilter.FILTER_TYPE_DEFAULT) {
+            if (accounts != null && accounts.size() > 0) {
+                // If we're showing all contacts and there is any Google account on the device then
+                // we're syncable.
+                for (AccountWithDataSet account : accounts) {
+                    if (GoogleAccountType.ACCOUNT_TYPE.equals(account.type)
+                            && account.dataSet == null) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the Google accounts (see {@link #isGoogleAccountType) for this ContactListFilter.
+     */
+    public List<Account> getSyncableAccounts(List<AccountWithDataSet> accounts) {
+        final List<Account> syncableAccounts = new ArrayList<>();
+        // TODO(samchen): Check FILTER_TYPE_CUSTOM
+        if (isGoogleAccountType() && filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
+            syncableAccounts.add(new Account(accountName, accountType));
+        } else if (filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS
+                || filterType == ContactListFilter.FILTER_TYPE_DEFAULT) {
+            if (accounts != null && accounts.size() > 0) {
+                for (AccountWithDataSet account : accounts) {
+                    if (GoogleAccountType.ACCOUNT_TYPE.equals(account.type)
+                            && account.dataSet == null) {
+                        syncableAccounts.add(new Account(account.name, account.type));
+                    }
+                }
+            }
+        }
+        return syncableAccounts;
+    }
+
+    /**
+     * Returns true if this ContactListFilter is Google account type. (i.e. where
+     * accountType = "com.google" and dataSet = null)
+     */
+    public boolean isGoogleAccountType() {
+        return GoogleAccountType.ACCOUNT_TYPE.equals(accountType) && dataSet == null;
+    }
 }
diff --git a/src/com/android/contacts/common/list/DefaultContactListAdapter.java b/src/com/android/contacts/common/list/DefaultContactListAdapter.java
index 43cca1a..c42b1bd 100644
--- a/src/com/android/contacts/common/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/common/list/DefaultContactListAdapter.java
@@ -31,6 +31,7 @@
 import android.text.TextUtils;
 import android.view.View;
 
+import com.android.contacts.common.Experiments;
 import com.android.contacts.common.compat.ContactsCompat;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.preference.ContactsPreferences;
@@ -115,6 +116,13 @@
                 loader.setUri(builder.build());
                 loader.setProjection(getProjection(true));
                 sortOrder = STREQUENT_SORT;
+                if (Flags.getInstance(getContext()).getBoolean(Experiments.SEARCH_YENTA)
+                        && loader instanceof FavoritesAndContactsLoader
+                        && directoryId == Directory.DEFAULT) {
+                    final FavoritesAndContactsLoader favoritesAndContactsLoader =
+                            (FavoritesAndContactsLoader) loader;
+                    favoritesAndContactsLoader.setAutocompleteQuery(query);
+                }
             }
         } else {
             final ContactListFilter filter = getFilter();
diff --git a/src/com/android/contacts/common/list/FavoritesAndContactsLoader.java b/src/com/android/contacts/common/list/FavoritesAndContactsLoader.java
index d1ae911..c679110 100644
--- a/src/com/android/contacts/common/list/FavoritesAndContactsLoader.java
+++ b/src/com/android/contacts/common/list/FavoritesAndContactsLoader.java
@@ -19,29 +19,33 @@
 import android.content.CursorLoader;
 import android.database.Cursor;
 import android.database.MergeCursor;
-import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
+import android.util.Log;
 
+import com.android.contactsbind.ObjectFactory;
+import com.android.contactsbind.search.AutocompleteHelper;
 import com.google.common.collect.Lists;
 
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * A loader for use in the default contact list, which will also query for favorite contacts
  * if configured to do so.
  */
-public class FavoritesAndContactsLoader extends CursorLoader {
+public class FavoritesAndContactsLoader extends CursorLoader implements AutocompleteHelper.Listener {
+
+    private static final int AUTOCOMPLETE_TIMEOUT_MS = 1000;
 
     private boolean mLoadFavorites;
 
     private String[] mProjection;
 
-    private Uri mExtraUri;
-    private String[] mExtraProjection;
-    private String mExtraSelection;
-    private String[] mExtraSelectionArgs;
-    private boolean mMergeExtraContactsAfterPrimary;
+    private String mAutocompleteQuery;
+    private CountDownLatch mAutocompleteLatch = new CountDownLatch(1);
+    private Cursor mAutocompleteCursor;
 
     public FavoritesAndContactsLoader(Context context) {
         super(context);
@@ -52,54 +56,51 @@
         mLoadFavorites = flag;
     }
 
+    public void setAutocompleteQuery(String autocompleteQuery) {
+        mAutocompleteQuery = autocompleteQuery;
+    }
+
     public void setProjection(String[] projection) {
         super.setProjection(projection);
         mProjection = projection;
     }
 
-    /** Configure an extra query and merge results in before the primary results. */
-    public void setLoadExtraContactsFirst(Uri uri, String[] projection) {
-        mExtraUri = uri;
-        mExtraProjection = projection;
-        mMergeExtraContactsAfterPrimary = false;
-    }
-
-    /** Configure an extra query and merge results in after the primary results. */
-    public void setLoadExtraContactsLast(Uri uri, String[] projection, String selection,
-            String[] selectionArgs) {
-        mExtraUri = uri;
-        mExtraProjection = projection;
-        mExtraSelection = selection;
-        mExtraSelectionArgs = selectionArgs;
-        mMergeExtraContactsAfterPrimary = true;
-    }
-
-    private boolean canLoadExtraContacts() {
-        return mExtraUri != null && mExtraProjection != null;
-    }
-
     @Override
     public Cursor loadInBackground() {
         List<Cursor> cursors = Lists.newArrayList();
         if (mLoadFavorites) {
             cursors.add(loadFavoritesContacts());
         }
-        if (canLoadExtraContacts() && !mMergeExtraContactsAfterPrimary) {
-            cursors.add(loadExtraContacts());
+
+        if (mAutocompleteQuery != null) {
+            final AutocompleteHelper autocompleteHelper =
+                    ObjectFactory.getAutocompleteHelper(getContext());
+            if (autocompleteHelper != null) {
+                autocompleteHelper.setListener(this);
+                autocompleteHelper.setProjection(mProjection);
+                autocompleteHelper.setQuery(mAutocompleteQuery);
+                try {
+                    if (!mAutocompleteLatch.await(AUTOCOMPLETE_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                        logw("Timeout expired before receiving autocompletions");
+                    }
+                } catch (InterruptedException e) {
+                    logw("Interrupted while waiting for autocompletions");
+                }
+                if (mAutocompleteCursor != null) {
+                    cursors.add(mAutocompleteCursor);
+                    // TODO: exclude these results from the main loader results, see b/30742359
+                }
+            }
         }
-        // ContactsCursor.loadInBackground() can return null; MergeCursor
-        // correctly handles null cursors.
-        Cursor cursor = null;
-        try {
-            cursor = super.loadInBackground();
-        } catch (NullPointerException | SecurityException e) {
-            // Ignore NPEs and SecurityExceptions thrown by providers
+
+        // TODO: if the autocomplete experiment in on, only show those results even if they're empty
+        final Cursor contactsCursor = mAutocompleteQuery == null ? loadContacts() : null;
+        if (mAutocompleteQuery == null) {
+            cursors.add(contactsCursor);
         }
-        final Cursor contactsCursor = cursor;
-        cursors.add(contactsCursor);
-        if (canLoadExtraContacts() && mMergeExtraContactsAfterPrimary) {
-            cursors.add(loadExtraContacts());
-        }
+        // Guard against passing an empty array to the MergeCursor constructor
+        if (cursors.isEmpty()) cursors.add(null);
+
         return new MergeCursor(cursors.toArray(new Cursor[cursors.size()])) {
             @Override
             public Bundle getExtras() {
@@ -109,9 +110,15 @@
         };
     }
 
-    private Cursor loadExtraContacts() {
-        return getContext().getContentResolver().query(
-                mExtraUri, mExtraProjection, mExtraSelection, mExtraSelectionArgs, null);
+    private Cursor loadContacts() {
+        // ContactsCursor.loadInBackground() can return null; MergeCursor
+        // correctly handles null cursors.
+        try {
+            return super.loadInBackground();
+        } catch (NullPointerException | SecurityException e) {
+            // Ignore NPEs and SecurityExceptions thrown by providers
+        }
+        return null;
     }
 
     private Cursor loadFavoritesContacts() {
@@ -119,4 +126,20 @@
                 Contacts.CONTENT_URI, mProjection, Contacts.STARRED + "=?", new String[]{"1"},
                 getSortOrder());
     }
+
+    @Override
+    public void onAutocompletesAvailable(Cursor cursor) {
+        if (cursor == null || cursor.getCount() == 0) {
+            logw("Ignoring null or empty autocompletions");
+        } else {
+            mAutocompleteCursor = cursor;
+            mAutocompleteLatch.countDown();
+        }
+    }
+
+    private static void logw(String message) {
+        if (Log.isLoggable(AutocompleteHelper.TAG, Log.WARN)) {
+            Log.w(AutocompleteHelper.TAG, message);
+        }
+    }
 }
diff --git a/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java b/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java
index 9ab6e1c..dbfd70e 100644
--- a/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java
+++ b/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java
@@ -113,9 +113,6 @@
      * Not guaranteed to work with all configurations of this adapter.
      */
     public void setDisplayCheckBoxes(boolean showCheckBoxes) {
-        if (!mDisplayCheckBoxes && showCheckBoxes) {
-            setSelectedContactIds(new TreeSet<Long>());
-        }
         mDisplayCheckBoxes = showCheckBoxes;
         notifyDataSetChanged();
         if (mSelectedContactsListener != null) {
diff --git a/src/com/android/contacts/common/list/ViewPagerTabStrip.java b/src/com/android/contacts/common/list/ViewPagerTabStrip.java
deleted file mode 100644
index c8ae21a..0000000
--- a/src/com/android/contacts/common/list/ViewPagerTabStrip.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2014 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.common.list;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.contacts.common.R;
-
-public class ViewPagerTabStrip extends LinearLayout {
-    private int mSelectedUnderlineThickness;
-    private final Paint mSelectedUnderlinePaint;
-
-    private int mIndexForSelection;
-    private float mSelectionOffset;
-
-    public ViewPagerTabStrip(Context context) {
-        this(context, null);
-    }
-
-    public ViewPagerTabStrip(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        final Resources res = context.getResources();
-
-        mSelectedUnderlineThickness =
-                res.getDimensionPixelSize(R.dimen.tab_selected_underline_height);
-        int underlineColor = res.getColor(R.color.tab_selected_underline_color);
-        int backgroundColor = res.getColor(R.color.actionbar_background_color);
-
-        mSelectedUnderlinePaint = new Paint();
-        mSelectedUnderlinePaint.setColor(underlineColor);
-
-        setBackgroundColor(backgroundColor);
-        setWillNotDraw(false);
-    }
-
-    /**
-     * Notifies this view that view pager has been scrolled. We save the tab index
-     * and selection offset for interpolating the position and width of selection
-     * underline.
-     */
-    void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-        mIndexForSelection = position;
-        mSelectionOffset = positionOffset;
-        invalidate();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        int childCount = getChildCount();
-
-        // Thick colored underline below the current selection
-        if (childCount > 0) {
-            View selectedTitle = getChildAt(mIndexForSelection);
-
-            if (selectedTitle == null) {
-                // The view pager's tab count changed but we weren't notified yet. Ignore this draw
-                // pass, when we get a new selection we will update and draw the selection strip in
-                // the correct place.
-                return;
-            }
-            int selectedLeft = selectedTitle.getLeft();
-            int selectedRight = selectedTitle.getRight();
-            final boolean isRtl = isRtl();
-            final boolean hasNextTab = isRtl ? mIndexForSelection > 0
-                    : (mIndexForSelection < (getChildCount() - 1));
-            if ((mSelectionOffset > 0.0f) && hasNextTab) {
-                // Draw the selection partway between the tabs
-                View nextTitle = getChildAt(mIndexForSelection + (isRtl ? -1 : 1));
-                int nextLeft = nextTitle.getLeft();
-                int nextRight = nextTitle.getRight();
-
-                selectedLeft = (int) (mSelectionOffset * nextLeft +
-                        (1.0f - mSelectionOffset) * selectedLeft);
-                selectedRight = (int) (mSelectionOffset * nextRight +
-                        (1.0f - mSelectionOffset) * selectedRight);
-            }
-
-            int height = getHeight();
-            canvas.drawRect(selectedLeft, height - mSelectedUnderlineThickness,
-                    selectedRight, height, mSelectedUnderlinePaint);
-        }
-    }
-
-    private boolean isRtl() {
-        return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/common/list/ViewPagerTabs.java b/src/com/android/contacts/common/list/ViewPagerTabs.java
deleted file mode 100644
index 48de6af..0000000
--- a/src/com/android/contacts/common/list/ViewPagerTabs.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2014 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.common.list;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
-import android.graphics.Outline;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewOutlineProvider;
-import android.widget.FrameLayout;
-import android.widget.HorizontalScrollView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.contacts.common.R;
-import com.android.contacts.common.compat.CompatUtils;
-
-/**
- * Lightweight implementation of ViewPager tabs. This looks similar to traditional actionBar tabs,
- * but allows for the view containing the tabs to be placed anywhere on screen. Text-related
- * attributes can also be assigned in XML - these will get propogated to the child TextViews
- * automatically.
- */
-public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
-
-    ViewPager mPager;
-    private ViewPagerTabStrip mTabStrip;
-
-    /**
-     * Linearlayout that will contain the TextViews serving as tabs. This is the only child
-     * of the parent HorizontalScrollView.
-     */
-    final int mTextStyle;
-    final ColorStateList mTextColor;
-    final int mTextSize;
-    final boolean mTextAllCaps;
-    int mPrevSelected = -1;
-    int mSidePadding;
-
-    private int[] mTabIcons;
-    // For displaying the unread count next to the tab icon.
-    private int[] mUnreadCounts;
-
-    private static final ViewOutlineProvider VIEW_BOUNDS_OUTLINE_PROVIDER;
-    static {
-        if (CompatUtils.isLollipopCompatible()) {
-            VIEW_BOUNDS_OUTLINE_PROVIDER = new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    outline.setRect(0, 0, view.getWidth(), view.getHeight());
-                }
-            };
-        } else {
-            VIEW_BOUNDS_OUTLINE_PROVIDER = null;
-        }
-    }
-
-    private static final int TAB_SIDE_PADDING_IN_DPS = 10;
-
-    // TODO: This should use <declare-styleable> in the future
-    private static final int[] ATTRS = new int[] {
-        android.R.attr.textSize,
-        android.R.attr.textStyle,
-        android.R.attr.textColor,
-        android.R.attr.textAllCaps
-    };
-
-    /**
-     * Simulates actionbar tab behavior by showing a toast with the tab title when long clicked.
-     */
-    private class OnTabLongClickListener implements OnLongClickListener {
-        final int mPosition;
-
-        public OnTabLongClickListener(int position) {
-            mPosition = position;
-        }
-
-        @Override
-        public boolean onLongClick(View v) {
-            final int[] screenPos = new int[2];
-            getLocationOnScreen(screenPos);
-
-            final Context context = getContext();
-            final int width = getWidth();
-            final int height = getHeight();
-            final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
-
-            Toast toast = Toast.makeText(context, mPager.getAdapter().getPageTitle(mPosition),
-                    Toast.LENGTH_SHORT);
-
-            // Show the toast under the tab
-            toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
-                    (screenPos[0] + width / 2) - screenWidth / 2, screenPos[1] + height);
-
-            toast.show();
-            return true;
-        }
-    }
-
-    public ViewPagerTabs(Context context) {
-        this(context, null);
-    }
-
-    public ViewPagerTabs(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ViewPagerTabs(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        setFillViewport(true);
-
-        mSidePadding = (int) (getResources().getDisplayMetrics().density * TAB_SIDE_PADDING_IN_DPS);
-
-        final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
-        mTextSize = a.getDimensionPixelSize(0, 0);
-        mTextStyle = a.getInt(1, 0);
-        mTextColor = a.getColorStateList(2);
-        mTextAllCaps = a.getBoolean(3, false);
-
-        mTabStrip = new ViewPagerTabStrip(context);
-        addView(mTabStrip,
-                new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
-        a.recycle();
-
-        if (CompatUtils.isLollipopCompatible()) {
-            // enable shadow casting from view bounds
-            setOutlineProvider(VIEW_BOUNDS_OUTLINE_PROVIDER);
-        }
-    }
-
-    public void setViewPager(ViewPager viewPager) {
-        mPager = viewPager;
-        addTabs(mPager.getAdapter());
-    }
-
-    /**
-     * Set the tab icons and initialize an array for unread counts the same length as the icon
-     * array.
-     *
-     * @param tabIcons An array representing the tab icons in order.
-     */
-    public void configureTabIcons(int[] tabIcons) {
-        mTabIcons = tabIcons;
-        mUnreadCounts = new int[tabIcons.length];
-    }
-
-    public void setUnreadCount(int count, int position) {
-        if (mUnreadCounts == null || position >= mUnreadCounts.length) {
-            return;
-        }
-        mUnreadCounts[position] = count;
-    }
-
-    private void addTabs(PagerAdapter adapter) {
-        mTabStrip.removeAllViews();
-
-        final int count = adapter.getCount();
-        for (int i = 0; i < count; i++) {
-            addTab(adapter.getPageTitle(i), i);
-        }
-    }
-
-    private void addTab(CharSequence tabTitle, final int position) {
-        View tabView;
-        if (mTabIcons != null && position < mTabIcons.length) {
-            View layout = LayoutInflater.from(getContext()).inflate(
-                    R.layout.unread_count_tab, null);
-            View iconView = layout.findViewById(R.id.icon);
-            iconView.setBackgroundResource(mTabIcons[position]);
-            iconView.setContentDescription(tabTitle);
-            TextView textView = (TextView) layout.findViewById(R.id.count);
-            if (mUnreadCounts != null && mUnreadCounts[position] > 0) {
-                textView.setText(Integer.toString(mUnreadCounts[position]));
-                textView.setVisibility(View.VISIBLE);
-                iconView.setContentDescription(getResources().getQuantityString(
-                        R.plurals.tab_title_with_unread_items,
-                        mUnreadCounts[position],
-                        tabTitle.toString(),
-                        mUnreadCounts[position]));
-            } else {
-                textView.setVisibility(View.INVISIBLE);
-                iconView.setContentDescription(tabTitle);
-            }
-            tabView = layout;
-        } else {
-            final TextView textView = new TextView(getContext());
-            textView.setText(tabTitle);
-            textView.setBackgroundResource(R.drawable.view_pager_tab_background);
-
-            // Assign various text appearance related attributes to child views.
-            if (mTextStyle > 0) {
-                textView.setTypeface(textView.getTypeface(), mTextStyle);
-            }
-            if (mTextSize > 0) {
-                textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
-            }
-            if (mTextColor != null) {
-                textView.setTextColor(mTextColor);
-            }
-            textView.setAllCaps(mTextAllCaps);
-            textView.setGravity(Gravity.CENTER);
-
-            tabView = textView;
-        }
-
-        tabView.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mPager.setCurrentItem(getRtlPosition(position));
-            }
-        });
-
-        tabView.setOnLongClickListener(new OnTabLongClickListener(position));
-
-        tabView.setPadding(mSidePadding, 0, mSidePadding, 0);
-
-        mTabStrip.addView(tabView, position, new LinearLayout.LayoutParams(
-                LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1));
-
-        // Default to the first child being selected
-        if (position == 0) {
-            mPrevSelected = 0;
-            tabView.setSelected(true);
-        }
-    }
-
-    /**
-     * Remove a tab at a certain index.
-     *
-     * @param index The index of the tab view we wish to remove.
-     */
-    public void removeTab(int index) {
-        View view = mTabStrip.getChildAt(index);
-        if (view != null) {
-            mTabStrip.removeView(view);
-        }
-    }
-
-    /**
-     * Refresh a tab at a certain index by removing it and reconstructing it.
-     *
-     * @param index The index of the tab view we wish to update.
-     */
-    public void updateTab(int index) {
-        removeTab(index);
-
-        if (index < mPager.getAdapter().getCount()) {
-            addTab(mPager.getAdapter().getPageTitle(index), index);
-        }
-    }
-
-    @Override
-    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-        position = getRtlPosition(position);
-        int tabStripChildCount = mTabStrip.getChildCount();
-        if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
-            return;
-        }
-
-        mTabStrip.onPageScrolled(position, positionOffset, positionOffsetPixels);
-    }
-
-    @Override
-    public void onPageSelected(int position) {
-        position = getRtlPosition(position);
-        int tabStripChildCount = mTabStrip.getChildCount();
-        if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
-            return;
-        }
-
-        if (mPrevSelected >= 0 && mPrevSelected < tabStripChildCount) {
-            mTabStrip.getChildAt(mPrevSelected).setSelected(false);
-        }
-        final View selectedChild = mTabStrip.getChildAt(position);
-        selectedChild.setSelected(true);
-
-        // Update scroll position
-        final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2;
-        smoothScrollTo(scrollPos, 0);
-        mPrevSelected = position;
-    }
-
-    @Override
-    public void onPageScrollStateChanged(int state) {
-    }
-
-    private int getRtlPosition(int position) {
-        if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
-            return mTabStrip.getChildCount() - 1 - position;
-        }
-        return position;
-    }
-}
-
diff --git a/src/com/android/contacts/common/model/AccountTypeManager.java b/src/com/android/contacts/common/model/AccountTypeManager.java
index 35a7a3a..5fee951 100644
--- a/src/com/android/contacts/common/model/AccountTypeManager.java
+++ b/src/com/android/contacts/common/model/AccountTypeManager.java
@@ -511,7 +511,7 @@
             boolean syncable =
                 ContentResolver.getIsSyncable(account, ContactsContract.AUTHORITY) > 0;
 
-            if (syncable) {
+            if (syncable || GoogleAccountType.ACCOUNT_TYPE.equals(account.type)) {
                 List<AccountType> accountTypes = accountTypesByType.get(account.type);
                 if (accountTypes != null) {
                     // Add an account-with-data-set entry for each account type that is
diff --git a/src/com/android/contacts/common/util/AccountFilterUtil.java b/src/com/android/contacts/common/util/AccountFilterUtil.java
index 2d59981..3c0520c 100644
--- a/src/com/android/contacts/common/util/AccountFilterUtil.java
+++ b/src/com/android/contacts/common/util/AccountFilterUtil.java
@@ -161,4 +161,17 @@
             return null;
         }
     }
+
+    /**
+     * Returns a {@link ContactListFilter} of type
+     * {@link ContactListFilter#FILTER_TYPE_ALL_ACCOUNTS}, or if a custom "Contacts to display"
+     * filter has been set, then one of type {@link ContactListFilter#FILTER_TYPE_CUSTOM}.
+     */
+    public static ContactListFilter createContactsFilter(Context context) {
+        final int filterType =
+                ContactListFilterController.getInstance(context).isCustomFilterPersisted()
+                        ? ContactListFilter.FILTER_TYPE_CUSTOM
+                        : ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS;
+        return ContactListFilter.createFilterWithType(filterType);
+    }
 }
diff --git a/src/com/android/contacts/common/util/DateUtils.java b/src/com/android/contacts/common/util/DateUtils.java
index c695ec6..097230c 100644
--- a/src/com/android/contacts/common/util/DateUtils.java
+++ b/src/com/android/contacts/common/util/DateUtils.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.text.format.DateFormat;
-import android.text.format.Time;
-
 
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
@@ -269,23 +267,4 @@
         }
         return anniversary.getTime();
     }
-
-    /**
-     * Determine the difference, in days between two dates.  Uses similar logic as the
-     * {@link android.text.format.DateUtils.getRelativeTimeSpanString} method.
-     *
-     * @param time Instance of time object to use for calculations.
-     * @param date1 First date to check.
-     * @param date2 Second date to check.
-     * @return The absolute difference in days between the two dates.
-     */
-    public static int getDayDifference(Time time, long date1, long date2) {
-        time.set(date1);
-        int startDay = Time.getJulianDay(date1, time.gmtoff);
-
-        time.set(date2);
-        int currentDay = Time.getJulianDay(date2, time.gmtoff);
-
-        return Math.abs(currentDay - startDay);
-    }
 }
diff --git a/src/com/android/contacts/common/vcard/NfcImportVCardActivity.java b/src/com/android/contacts/common/vcard/NfcImportVCardActivity.java
index 0634df4..6093405 100644
--- a/src/com/android/contacts/common/vcard/NfcImportVCardActivity.java
+++ b/src/com/android/contacts/common/vcard/NfcImportVCardActivity.java
@@ -17,6 +17,8 @@
 package com.android.contacts.common.vcard;
 
 import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -27,9 +29,11 @@
 import android.nfc.NfcAdapter;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.provider.ContactsContract.RawContacts;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.android.contacts.common.R;
 import com.android.contacts.common.activity.RequestPermissionsActivity;
@@ -59,6 +63,12 @@
 
     private NdefRecord mRecord;
     private AccountWithDataSet mAccount;
+    private Handler mHandler = new Handler();
+
+    /**
+     * Notification id used when error happened before sending an import request to VCardServer.
+     */
+    private static final int FAILURE_NOTIFICATION_ID = 1;
 
     /* package */ class ImportTask extends AsyncTask<VCardService, Void, ImportRequest> {
         @Override
@@ -81,6 +91,10 @@
 
         @Override
         public void onPostExecute(ImportRequest request) {
+            if (request == null) {
+                // Finish the activity in case of error so it doesn't stay in view.
+                finish();
+            }
             unbindService(NfcImportVCardActivity.this);
         }
     }
@@ -111,6 +125,8 @@
                     parser.addInterpreter(detector);
                     parser.parse(is);
                 } catch (VCardVersionException e2) {
+                    Log.e(TAG, "vCard with unsupported version.");
+                    showFailureNotification(R.string.fail_reason_not_supported);
                     return null;
                 }
             } finally {
@@ -120,14 +136,16 @@
                 }
             }
         } catch (IOException e) {
-            Log.e(TAG, "Failed reading vcard data", e);
+            Log.e(TAG, "Failed reading vCard data", e);
+            showFailureNotification(R.string.fail_reason_io_error);
             return null;
         } catch (VCardNestedException e) {
             Log.w(TAG, "Nested Exception is found (it may be false-positive).");
             // Go through without throwing the Exception, as we may be able to detect the
             // version before it
         } catch (VCardException e) {
-            Log.e(TAG, "Error parsing vcard", e);
+            Log.e(TAG, "Error parsing vCard", e);
+            showFailureNotification(R.string.fail_reason_not_supported);
             return null;
         }
 
@@ -242,7 +260,8 @@
             Log.i(TAG, "Late import failure -- ignoring");
             return;
         }
-        // TODO: report failure
+        showFailureNotification(R.string.vcard_import_request_rejected_message);
+        finish();
     }
 
     @Override
@@ -269,4 +288,22 @@
     public void onComplete() {
         // do nothing
     }
+
+    /* package */ void showFailureNotification(int reasonId) {
+        final NotificationManager notificationManager =
+                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+        final Notification notification =
+                NotificationImportExportListener.constructImportFailureNotification(
+                        this,
+                        getString(reasonId));
+        notificationManager.notify(NotificationImportExportListener.FAILURE_NOTIFICATION_TAG,
+                FAILURE_NOTIFICATION_ID, notification);
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(NfcImportVCardActivity.this,
+                        getString(R.string.vcard_import_failed), Toast.LENGTH_LONG).show();
+            }
+        });
+    }
 }
diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java
index 1d7fa46..4ce0d98 100644
--- a/src/com/android/contacts/editor/CompactContactEditorFragment.java
+++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java
@@ -98,7 +98,9 @@
         final CompactRawContactsEditorView editorView = getContent();
         editorView.setListener(this);
         editorView.setState(mState, getMaterialPalette(), mViewIdGenerator, mPhotoId,
-                mHasNewContact, mIsUserProfile, mAccountWithDataSet);
+                mHasNewContact, mIsUserProfile, mAccountWithDataSet,
+                mRawContactIdToDisplayAlone, mRawContactDisplayAloneIsReadOnly,
+                isEditingReadOnlyRawContactWithNewContact());
         if (mHasNewContact && !TextUtils.isEmpty(mReadOnlyDisplayName)) {
             mReadOnlyNameEditorView = editorView.getPrimaryNameEditorView();
             editorView.maybeSetReadOnlyDisplayNameAsPrimary(mReadOnlyDisplayName);
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index ece3829..d023d35 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -327,6 +327,10 @@
     private boolean mHasNewContact;
     private boolean mIsUserProfile;
     private AccountWithDataSet mPrimaryAccount;
+    private RawContactDeltaList mRawContactDeltas;
+    private long mRawContactIdToDisplayAlone = -1;
+    private boolean mRawContactDisplayAloneIsReadOnly;
+    private boolean mIsEditingReadOnlyRawContactWithNewContact;
     private Map<String,KindSectionDataList> mKindSectionDataMap = new HashMap<>();
 
     // Account header
@@ -621,7 +625,14 @@
     public void setState(RawContactDeltaList rawContactDeltas,
             MaterialColorMapUtils.MaterialPalette materialPalette, ViewIdGenerator viewIdGenerator,
             long photoId, boolean hasNewContact, boolean isUserProfile,
-            AccountWithDataSet primaryAccount) {
+            AccountWithDataSet primaryAccount, long rawContactIdToDisplayAlone,
+            boolean rawContactDisplayAloneIsReadOnly,
+            boolean isEditingReadOnlyRawContactWithNewContact) {
+        mRawContactDeltas = rawContactDeltas;
+        mRawContactIdToDisplayAlone = rawContactIdToDisplayAlone;
+        mRawContactDisplayAloneIsReadOnly = rawContactDisplayAloneIsReadOnly;
+        mIsEditingReadOnlyRawContactWithNewContact = isEditingReadOnlyRawContactWithNewContact;
+
         mKindSectionDataMap.clear();
         mKindSectionViews.removeAllViews();
         mMoreFields.setVisibility(View.VISIBLE);
@@ -669,15 +680,48 @@
         }
 
         // Setup the view
-        addAccountInfo(rawContactDeltas);
         addPhotoView();
-        addKindSectionViews();
+        if (isSingleReadOnlyRawContact()) {
+            // We're want to display the inputs fields for a single read only raw contact
+            addReadOnlyRawContactEditorViews();
+            // Hide the "More fields" link
+            mMoreFields.setVisibility(View.GONE);
+        } else if (mIsEditingReadOnlyRawContactWithNewContact) {
+            // A new writable raw contact was created and joined with the read only contact
+            // that the user is trying to edit.
+            setupCompactEditorNormally();
 
-        if (mIsExpanded) showAllFields();
+            // TODO: Hide the raw contact selector since it will just contain the read-only raw
+            // contact and clicking that will just open the exact same editor.  When we clean up
+            // the whole account header, selector, and raw contact selector mess, we can prevent
+            // the selector from being displayed in a less hacky way.
+            mRawContactContainer.setVisibility(View.GONE);
+        } else if (mRawContactDeltas.size() > 1) {
+            // We're editing an aggregate composed of more than one writable raw contacts
 
+            // TODO: Don't render any input fields. Eventually we will show a list of account
+            // types and names but for now just show the account selector and hide the "More fields"
+            // link.
+            addAccountInfo(rawContactDeltas);
+            mMoreFields.setVisibility(View.GONE);
+        } else {
+            setupCompactEditorNormally();
+        }
         if (mListener != null) mListener.onEditorsBound();
     }
 
+    private void setupCompactEditorNormally() {
+        addAccountInfo(mRawContactDeltas);
+        addKindSectionViews();
+        if (mIsExpanded) showAllFields();
+    }
+
+    private boolean isSingleReadOnlyRawContact() {
+        return mRawContactDeltas.size() == 1
+                && mRawContactDeltas.get(0).getRawContactId() == mRawContactIdToDisplayAlone
+                && mRawContactDisplayAloneIsReadOnly;
+    }
+
     private void parseRawContactDeltas(RawContactDeltaList rawContactDeltas) {
         // Build the kind section data list map
         vlog("parse: " + rawContactDeltas.size() + " rawContactDelta(s)");
@@ -692,8 +736,8 @@
             vlog("parse: " + dataKindSize + " dataKinds(s)");
             for (int i = 0; i < dataKindSize; i++) {
                 final DataKind dataKind = dataKinds.get(i);
-                if (dataKind == null || !dataKind.editable) {
-                    vlog("parse: " + i + " " + dataKind.mimeType + " dropped read-only");
+                if (dataKind == null) {
+                    vlog("parse: " + i + " " + dataKind.mimeType + " dropped null data kind");
                     continue;
                 }
                 final String mimeType = dataKind.mimeType;
@@ -729,6 +773,27 @@
         return kindSectionDataList;
     }
 
+    private void addReadOnlyRawContactEditorViews() {
+        final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(
+                getContext());
+
+        for (int i = 0; i < mRawContactDeltas.size(); i++) {
+            final RawContactDelta rawContactDelta = mRawContactDeltas.get(i);
+            if (!rawContactDelta.isVisible()) continue;
+            final AccountType type = rawContactDelta.getAccountType(accountTypes);
+            if (type.areContactsWritable()) continue;
+
+            final BaseRawContactEditorView editor = (BaseRawContactEditorView) inflater.inflate(
+                        R.layout.raw_contact_readonly_editor_view, mKindSectionViews, false);
+            editor.setCollapsed(false);
+            mKindSectionViews.addView(editor);
+            editor.setState(rawContactDelta, type, mViewIdGenerator, mIsUserProfile);
+        }
+    }
+
+    // TODO: we have mRawContactDeltas, we don't need to pass the RawContactDeltaList to this method
     private void addAccountInfo(RawContactDeltaList rawContactDeltas) {
         mAccountHeaderContainer.setVisibility(View.GONE);
         mAccountSelectorContainer.setVisibility(View.GONE);
diff --git a/src/com/android/contacts/editor/ContactEditorBaseFragment.java b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
index d8045cf..2d363bd 100644
--- a/src/com/android/contacts/editor/ContactEditorBaseFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
@@ -83,13 +83,17 @@
 import com.android.contacts.util.UiClosables;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import com.google.common.collect.UnmodifiableIterator;
 
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Set;
 
+import javax.annotation.Nullable;
+
 /**
  * Base Fragment for contact editors.
  */
@@ -1165,8 +1169,24 @@
             return;
         }
 
+        // Prune raw contacts besides the one we want to edit
+        if (mRawContactIdToDisplayAlone > 0) {
+            final ImmutableList.Builder<RawContact> rawContactsBuilder =
+                    new ImmutableList.Builder<>();
+            for (RawContact rawContact : contact.getRawContacts()) {
+                if (rawContact.getId() == mRawContactIdToDisplayAlone) {
+                    rawContactsBuilder.add(rawContact);
+                    break;
+                }
+            }
+            mRawContacts = rawContactsBuilder.build();
+            Log.v(TAG, "Raw contact deltas trimmed from " + contact.getRawContacts().size() +
+                    " to " + mRawContacts.size());
+        } else {
+            mRawContacts = contact.getRawContacts();
+        }
+
         // See if this edit operation needs to be redirected to a custom editor
-        mRawContacts = contact.getRawContacts();
         if (mRawContacts.size() == 1) {
             RawContact rawContact = mRawContacts.get(0);
             String type = rawContact.getAccountTypeString();
@@ -1296,7 +1316,9 @@
                 }
             }
             // Editor should always present a local profile for editing
-            if (!localProfileExists) {
+            // TODO(wjang): Need to figure out when this case comes up.  We can't do this if we're
+            // going to prune all but the one raw contact that we're trying to display by itself.
+            if (!localProfileExists && mRawContactIdToDisplayAlone <= 0) {
                 mState.add(createLocalRawContactDelta());
             }
         }
diff --git a/src/com/android/contacts/editor/EditorIntents.java b/src/com/android/contacts/editor/EditorIntents.java
index 14476c8..badc697 100644
--- a/src/com/android/contacts/editor/EditorIntents.java
+++ b/src/com/android/contacts/editor/EditorIntents.java
@@ -126,13 +126,12 @@
     }
 
     /**
-     * Returns an Intent to start the full editor for the given raw contact. The full editor will
-     * only display this one raw contact.
+     * Returns an Intent to start the compact editor for the given raw contact.
      */
     public static Intent createEditContactIntentForRawContact(Context context,
-            Uri rawContactUri, long rawContactId, boolean isReadOnly) {
-        final Intent intent = new Intent(ContactEditorBaseActivity.ACTION_EDIT, rawContactUri,
-                context, ContactEditorActivity.class);
+            Uri contactLookupUri, long rawContactId, boolean isReadOnly) {
+        final Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri, context,
+                CompactContactEditorActivity.class);
         intent.putExtra(ContactEditorFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE,
                 rawContactId);
         intent.putExtra(
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 947f35e..8b29b7e 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -303,13 +303,13 @@
                             mEntry.getAsString(mType.customColumn),
                             getContext().getString(mKind.titleRes)));
         } else {
-            if (mType != null) {
+            if (mType != null && mType.labelRes > 0 && mKind.titleRes > 0) {
                 mLabel.setSelection(mEditTypeAdapter.getPosition(mType));
                 mDeleteContainer.setContentDescription(
                         getContext().getString(R.string.editor_delete_view_description,
                                 getContext().getString(mType.labelRes),
                                 getContext().getString(mKind.titleRes)));
-            } else {
+            } else if (mKind.titleRes > 0) {
                 mDeleteContainer.setContentDescription(
                         getContext().getString(R.string.editor_delete_view_description_short,
                                 getContext().getString(mKind.titleRes)));
@@ -409,8 +409,9 @@
         final boolean hasTypes = RawContactModifier.hasEditTypes(kind);
         setupLabelButton(hasTypes);
         mLabel.setEnabled(!readOnly && isEnabled());
-        mLabel.setContentDescription(getContext().getResources().getString(mKind.titleRes));
-
+        if (mKind.titleRes > 0) {
+            mLabel.setContentDescription(getContext().getResources().getString(mKind.titleRes));
+        }
         mType = RawContactModifier.getCurrentType(entry, kind);
         rebuildLabel();
     }
diff --git a/src/com/android/contacts/group/GroupMembersFragment.java b/src/com/android/contacts/group/GroupMembersFragment.java
index 769a083..a68b6cf 100644
--- a/src/com/android/contacts/group/GroupMembersFragment.java
+++ b/src/com/android/contacts/group/GroupMembersFragment.java
@@ -18,33 +18,49 @@
 import android.app.Activity;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.CursorLoader;
+import android.content.Intent;
 import android.content.Loader;
 import android.database.Cursor;
 import android.database.CursorWrapper;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
+import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.Toast;
 
+import com.android.contacts.ContactSaveService;
 import com.android.contacts.GroupMetaDataLoader;
 import com.android.contacts.R;
+import com.android.contacts.activities.ActionBarAdapter;
 import com.android.contacts.activities.GroupMembersActivity;
 import com.android.contacts.common.list.ContactsSectionIndexer;
-import com.android.contacts.common.list.MultiSelectEntryContactListAdapter;
+import com.android.contacts.common.list.MultiSelectEntryContactListAdapter.DeleteContactListener;
+import com.android.contacts.common.logging.ListEvent;
 import com.android.contacts.common.logging.ListEvent.ListType;
+import com.android.contacts.common.logging.Logger;
+import com.android.contacts.common.logging.ScreenEvent;
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.group.GroupMembersAdapter.GroupMembersQuery;
+import com.android.contacts.interactions.GroupDeletionDialogFragment;
+import com.android.contacts.list.ContactsRequest;
 import com.android.contacts.list.MultiSelectContactsListFragment;
+import com.android.contacts.list.UiIntentActions;
+import com.android.contacts.quickcontact.QuickContactActivity;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -52,33 +68,20 @@
 import java.util.Set;
 
 /** Displays the members of a group. */
-public class GroupMembersFragment extends MultiSelectContactsListFragment<GroupMembersAdapter>
-        implements MultiSelectEntryContactListAdapter.DeleteContactListener {
+public class GroupMembersFragment extends MultiSelectContactsListFragment<GroupMembersAdapter> {
 
     private static final String TAG = "GroupMembers";
 
+    private static final String KEY_IS_EDIT_MODE = "editMode";
     private static final String KEY_GROUP_URI = "groupUri";
     private static final String KEY_GROUP_METADATA = "groupMetadata";
 
+    public static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog";
+
     private static final String ARG_GROUP_URI = "groupUri";
 
     private static final int LOADER_GROUP_METADATA = 0;
-
-    /** Callbacks for hosts of {@link GroupMembersFragment}. */
-    public interface GroupMembersListener {
-
-        /** Invoked after group metadata for the passed in group URI has loaded. */
-        void onGroupMetadataLoaded(GroupMetadata groupMetadata);
-
-        /** Invoked if group metadata can't be loaded for the passed in group URI. */
-        void onGroupMetadataLoadFailed();
-
-        /** Invoked when a group member in the list is clicked. */
-        void onGroupMemberListItemClicked(int position, Uri contactLookupUri);
-
-        /** Invoked when a the delete button for a group member in the list is clicked. */
-        void onGroupMemberListItemDeleted(int position, long contactId);
-    }
+    private static final int RESULT_GROUP_ADD_MEMBER = 100;
 
     /** Filters out duplicate contacts. */
     private class FilterCursorWrapper extends CursorWrapper {
@@ -191,9 +194,11 @@
         public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
             if (cursor == null || cursor.isClosed() || !cursor.moveToNext()) {
                 Log.e(TAG, "Failed to load group metadata for " + mGroupUri);
-                if (mListener != null) {
-                    mListener.onGroupMetadataLoadFailed();
-                }
+                final Activity activity = getActivity();
+                Toast.makeText(getContext(), R.string.groupLoadErrorToast, Toast.LENGTH_SHORT)
+                        .show();
+                activity.setResult(AppCompatActivity.RESULT_CANCELED);
+                activity.finish();
                 return;
             }
             mGroupMetadata = new GroupMetadata();
@@ -218,9 +223,11 @@
         public void onLoaderReset(Loader<Cursor> loader) {}
     };
 
+    private ActionBarAdapter mActionBarAdapter;
+
     private Uri mGroupUri;
 
-    private GroupMembersListener mListener;
+    private boolean mIsEditMode;
 
     private GroupMetadata mGroupMetadata;
 
@@ -243,8 +250,211 @@
         setListType(ListType.GROUP);
     }
 
-    public void setListener(GroupMembersListener listener) {
-        mListener = listener;
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        if (mGroupMetadata == null) {
+            // Hide menu options until metadata is fully loaded
+            return;
+        }
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.view_group, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final boolean isSelectionMode = mActionBarAdapter.isSelectionMode();
+        final boolean isGroupEditable = mGroupMetadata != null && mGroupMetadata.editable;
+        final boolean isGroupReadOnly = mGroupMetadata != null && mGroupMetadata.readOnly;
+
+        setVisible(menu, R.id.menu_add, isGroupEditable && !isSelectionMode);
+        setVisible(menu, R.id.menu_rename_group, !isGroupReadOnly && !isSelectionMode);
+        setVisible(menu, R.id.menu_delete_group, !isGroupReadOnly && !isSelectionMode);
+        setVisible(menu, R.id.menu_edit_group, isGroupEditable && !mIsEditMode && !isSelectionMode
+                && !isGroupEmpty());
+        setVisible(menu, R.id.menu_remove_from_group, isGroupEditable && isSelectionMode &&
+                !mIsEditMode);
+    }
+
+    private boolean isGroupEmpty() {
+        return getAdapter() != null && getAdapter().isEmpty();
+    }
+
+    private static void setVisible(Menu menu, int id, boolean visible) {
+        final MenuItem menuItem = menu.findItem(id);
+        if (menuItem != null) {
+            menuItem.setVisible(visible);
+        }
+    }
+
+    private void startGroupAddMemberActivity() {
+        startActivityForResult(GroupUtil.createPickMemberIntent(getContext(), mGroupMetadata,
+                getMemberContactIds()), RESULT_GROUP_ADD_MEMBER);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home: {
+                getActivity().onBackPressed();
+                return true;
+            }
+            case R.id.menu_add: {
+                startGroupAddMemberActivity();
+                return true;
+            }
+            case R.id.menu_rename_group: {
+                GroupNameEditDialogFragment.newInstanceForUpdate(
+                        new AccountWithDataSet(mGroupMetadata.accountName,
+                                mGroupMetadata.accountType, mGroupMetadata.dataSet),
+                        GroupUtil.ACTION_UPDATE_GROUP, mGroupMetadata.groupId,
+                        mGroupMetadata.groupName).show(getFragmentManager(),
+                        TAG_GROUP_NAME_EDIT_DIALOG);
+                return true;
+            }
+            case R.id.menu_delete_group: {
+                deleteGroup();
+                return true;
+            }
+            case R.id.menu_edit_group: {
+                mIsEditMode = true;
+                mActionBarAdapter.setSelectionMode(true);
+                displayDeleteButtons(true);
+                return true;
+            }
+            case R.id.menu_remove_from_group: {
+                logListEvent();
+                removeSelectedContacts();
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void removeSelectedContacts() {
+        final long[] contactIds = getAdapter().getSelectedContactIdsArray();
+        new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
+                getContext(), contactIds, mGroupMetadata.groupId, mGroupMetadata.accountName,
+                mGroupMetadata.accountType).execute();
+
+        mActionBarAdapter.setSelectionMode(false);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == RESULT_GROUP_ADD_MEMBER && resultCode ==
+                Activity.RESULT_OK && data != null) {
+            long[] contactIds = data.getLongArrayExtra(
+                    UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY);
+            if (contactIds == null) {
+                final long contactId = data.getLongExtra(
+                        UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1);
+                if (contactId > -1) {
+                    contactIds = new long[1];
+                    contactIds[0] = contactId;
+                }
+            }
+            new UpdateGroupMembersAsyncTask(
+                    UpdateGroupMembersAsyncTask.TYPE_ADD,
+                    getContext(), contactIds, mGroupMetadata.groupId, mGroupMetadata.accountName,
+                    mGroupMetadata.accountType).execute();
+        }
+    }
+
+    private final ActionBarAdapter.Listener mActionBarListener = new ActionBarAdapter.Listener() {
+        @Override
+        public void onAction(int action) {
+            switch (action) {
+                case ActionBarAdapter.Listener.Action.START_SELECTION_MODE:
+                    if (mIsEditMode) {
+                        displayDeleteButtons(true);
+                        mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group));
+                    } else {
+                        displayCheckBoxes(true);
+                    }
+                    getActivity().invalidateOptionsMenu();
+                    break;
+                case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
+                    mActionBarAdapter.setSearchMode(false);
+                    if (mIsEditMode) {
+                        displayDeleteButtons(false);
+                    } else {
+                        displayCheckBoxes(false);
+                    }
+                    getActivity().invalidateOptionsMenu();
+                    break;
+                case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE:
+                    break;
+            }
+        }
+
+        @Override
+        public void onUpButtonPressed() {
+            getActivity().onBackPressed();
+        }
+    };
+
+    private final OnCheckBoxListActionListener mCheckBoxListener =
+            new OnCheckBoxListActionListener() {
+                @Override
+                public void onStartDisplayingCheckBoxes() {
+                    mActionBarAdapter.setSelectionMode(true);
+                }
+
+                @Override
+                public void onSelectedContactIdsChanged() {
+                    if (mActionBarAdapter == null) {
+                        return;
+                    }
+                    if (mIsEditMode) {
+                        mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group));
+                    } else {
+                        mActionBarAdapter.setSelectionCount(getSelectedContactIds().size());
+                    }
+                }
+
+                @Override
+                public void onStopDisplayingCheckBoxes() {
+                    mActionBarAdapter.setSelectionMode(false);
+                }
+            };
+
+    private void logListEvent() {
+        Logger.logListEvent(
+                ListEvent.ActionType.REMOVE_LABEL,
+                getListType(),
+                getAdapter().getCount(),
+                /* clickedIndex */ -1,
+                getAdapter().getSelectedContactIdsArray().length);
+    }
+
+    private void deleteGroup() {
+        if (getMemberCount() == 0) {
+            final Intent intent = ContactSaveService.createGroupDeletionIntent(
+                    getContext(), mGroupMetadata.groupId);
+            getContext().startService(intent);
+            getActivity().finish();
+        } else {
+            GroupDeletionDialogFragment.show(getFragmentManager(), mGroupMetadata.groupId,
+                    mGroupMetadata.groupName);
+        }
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        // This is the first safe place in the fragment lifecycle to know getActivity() will not
+        // be null (i.e. it can be null in onCreateView() of this fragment)
+        final GroupMembersActivity activity = (GroupMembersActivity) getActivity();
+        mActionBarAdapter = new ActionBarAdapter(activity, mActionBarListener,
+                activity.getSupportActionBar(), activity.getToolbar(), R.string.enter_contact_name);
+        mActionBarAdapter.setShowHomeIcon(true);
+        final ContactsRequest contactsRequest = new ContactsRequest();
+        contactsRequest.setActionCode(ContactsRequest.ACTION_GROUP);
+        mActionBarAdapter.initialize(savedInstanceState, contactsRequest);
+    }
+
+    public ActionBarAdapter getActionBarAdapter() {
+        return mActionBarAdapter;
     }
 
     public void displayDeleteButtons(boolean displayDeleteButtons) {
@@ -259,15 +469,33 @@
         return mGroupMemberContactIds.size();
     }
 
+    public boolean isEditMode() {
+        return mIsEditMode;
+    }
+
+    public void setEditMode(boolean isEditMode) {
+        mIsEditMode = isEditMode;
+    }
+
     @Override
     public void onCreate(Bundle savedState) {
         super.onCreate(savedState);
         if (savedState == null) {
             mGroupUri = getArguments().getParcelable(ARG_GROUP_URI);
         } else {
+            mIsEditMode = savedState.getBoolean(KEY_IS_EDIT_MODE);
             mGroupUri = savedState.getParcelable(KEY_GROUP_URI);
             mGroupMetadata = savedState.getParcelable(KEY_GROUP_METADATA);
         }
+        maybeAttachCheckBoxListener();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // Re-register the listener, which may have been cleared when onSaveInstanceState was
+        // called. See also: onSaveInstanceState
+        mActionBarAdapter.setListener(mActionBarListener);
     }
 
     @Override
@@ -312,6 +540,11 @@
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
+        if (mActionBarAdapter != null) {
+            mActionBarAdapter.setListener(null);
+            mActionBarAdapter.onSaveInstanceState(outState);
+        }
+        outState.putBoolean(KEY_IS_EDIT_MODE, mIsEditMode);
         outState.putParcelable(KEY_GROUP_URI, mGroupUri);
         outState.putParcelable(KEY_GROUP_METADATA, mGroupMetadata);
     }
@@ -321,9 +554,10 @@
 
         maybeAttachCheckBoxListener();
 
-        if (mListener != null) {
-            mListener.onGroupMetadataLoaded(mGroupMetadata);
-        }
+        final GroupMembersActivity activity = (GroupMembersActivity) getActivity();
+        activity.updateGroupMenu(mGroupMetadata);
+        activity.setTitle(mGroupMetadata.groupName);
+        activity.invalidateOptionsMenu();
 
         // Start loading the group members
         super.startLoading();
@@ -332,12 +566,7 @@
     private void maybeAttachCheckBoxListener() {
         // Don't attach the multi select check box listener if we can't edit the group
         if (mGroupMetadata != null && mGroupMetadata.editable) {
-            try {
-                setCheckBoxListListener((OnCheckBoxListActionListener) getActivity());
-            } catch (ClassCastException e) {
-                throw new ClassCastException(getActivity() + " must implement " +
-                        OnCheckBoxListActionListener.class.getSimpleName());
-            }
+            setCheckBoxListListener(mCheckBoxListener);
         }
     }
 
@@ -346,7 +575,7 @@
         final GroupMembersAdapter adapter = new GroupMembersAdapter(getContext());
         adapter.setSectionHeaderDisplayEnabled(true);
         adapter.setDisplayPhotos(true);
-        adapter.setDeleteContactListener(this);
+        adapter.setDeleteContactListener(new DeletionListener());
         return adapter;
     }
 
@@ -380,7 +609,8 @@
         addContactsButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                ((GroupMembersActivity) getActivity()).startGroupAddMemberActivity();
+                startActivityForResult(GroupUtil.createPickMemberIntent(getContext(),
+                        mGroupMetadata, getMemberContactIds()), RESULT_GROUP_ADD_MEMBER);
             }
         });
         return view;
@@ -396,25 +626,48 @@
             super.onItemClick(position, id);
             return;
         }
-        if (mListener != null) {
-            mListener.onGroupMemberListItemClicked(position, uri);
-        }
+        final int count = getAdapter().getCount();
+        Logger.logListEvent(ListEvent.ActionType.CLICK, ListEvent.ListType.GROUP, count,
+                /* clickedIndex */ position, /* numSelected */ 0);
+        final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(
+                getContext(), uri, QuickContactActivity.MODE_FULLY_EXPANDED);
+        intent.putExtra(
+                QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, ScreenEvent.ScreenType.LIST_GROUP);
+        startActivity(intent);
     }
 
     @Override
     protected boolean onItemLongClick(int position, long id) {
         final Activity activity = getActivity();
         if (activity != null && activity instanceof GroupMembersActivity) {
-            if (((GroupMembersActivity) activity).isEditMode()) {
+            if (mIsEditMode) {
                 return true;
             }
         }
         return super.onItemLongClick(position, id);
     }
 
+    private final class DeletionListener implements DeleteContactListener {
+        @Override
+        public void onContactDeleteClicked(int position) {
+            final long contactId = getAdapter().getContactId(position);
+            final long[] contactIds = new long[1];
+            contactIds[0] = contactId;
+            new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
+                    getContext(), contactIds, mGroupMetadata.groupId, mGroupMetadata.accountName,
+                    mGroupMetadata.accountType).execute();
+        }
+    }
+
+    public GroupMetadata getGroupMetadata() {
+        return mGroupMetadata;
+    }
+
     @Override
-    public void onContactDeleteClicked(int position) {
-        final long contactId = getAdapter().getContactId(position);
-        mListener.onGroupMemberListItemDeleted(position, contactId);
+    public void onDestroy() {
+        if (mActionBarAdapter != null) {
+            mActionBarAdapter.setListener(null);
+        }
+        super.onDestroy();
     }
 }
diff --git a/src/com/android/contacts/group/GroupUtil.java b/src/com/android/contacts/group/GroupUtil.java
index 3e8cd61..63a4fa8 100644
--- a/src/com/android/contacts/group/GroupUtil.java
+++ b/src/com/android/contacts/group/GroupUtil.java
@@ -48,6 +48,11 @@
  */
 public final class GroupUtil {
 
+    public static final String ACTION_DELETE_GROUP = "deleteGroup";
+    public static final String ACTION_UPDATE_GROUP = "updateGroup";
+    public static final String ACTION_ADD_TO_GROUP = "addToGroup";
+    public static final String ACTION_REMOVE_FROM_GROUP = "removeFromGroup";
+
     // System IDs of FFC groups in Google accounts
     private static final Set<String> FFC_GROUPS =
             new HashSet(Arrays.asList("Friends", "Family", "Coworkers"));
diff --git a/src/com/android/contacts/group/UpdateGroupMembersAsyncTask.java b/src/com/android/contacts/group/UpdateGroupMembersAsyncTask.java
new file mode 100644
index 0000000..a040ddc
--- /dev/null
+++ b/src/com/android/contacts/group/UpdateGroupMembersAsyncTask.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 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.group;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.ContactsContract;
+import android.widget.Toast;
+
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+import com.android.contacts.activities.GroupMembersActivity;
+
+/**
+ * Starts an Intent to add/remove the raw contacts for the given contact IDs to/from a group.
+ * Only the raw contacts that belong to the specified account are added or removed.
+ */
+public class UpdateGroupMembersAsyncTask extends AsyncTask<Void, Void, Intent> {
+    static final int TYPE_ADD = 0;
+    static final int TYPE_REMOVE = 1;
+
+    private final Context mContext;
+    private final int mType;
+    private final long[] mContactIds;
+    private final long mGroupId;
+    private final String mAccountName;
+    private final String mAccountType;
+
+    public UpdateGroupMembersAsyncTask(int type, Context context, long[] contactIds,
+            long groupId, String accountName, String accountType) {
+        mContext = context;
+        mType = type;
+        mContactIds = contactIds;
+        mGroupId = groupId;
+        mAccountName = accountName;
+        mAccountType = accountType;
+    }
+
+    @Override
+    protected Intent doInBackground(Void... params) {
+        final long[] rawContactIds = getRawContactIds();
+        if (rawContactIds.length == 0) {
+            return null;
+        }
+        final long[] rawContactIdsToAdd;
+        final long[] rawContactIdsToRemove;
+        final String action;
+        if (mType == TYPE_ADD) {
+            rawContactIdsToAdd = rawContactIds;
+            rawContactIdsToRemove = null;
+            action = GroupUtil.ACTION_ADD_TO_GROUP;
+        } else if (mType == TYPE_REMOVE) {
+            rawContactIdsToAdd = null;
+            rawContactIdsToRemove = rawContactIds;
+            action = GroupUtil.ACTION_REMOVE_FROM_GROUP;
+        } else {
+            throw new IllegalStateException("Unrecognized type " + mType);
+        }
+        return ContactSaveService.createGroupUpdateIntent(
+                mContext, mGroupId, /* newLabel */ null, rawContactIdsToAdd,
+                rawContactIdsToRemove, GroupMembersActivity.class, action);
+    }
+
+    // TODO(wjang): prune raw contacts that are already in the group; ContactSaveService will
+    // log a warning if the raw contact is already a member and keep going but it is not ideal.
+    private long[] getRawContactIds() {
+        final Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon()
+                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountName)
+                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountType)
+                .build();
+        final String[] projection = new String[]{ContactsContract.RawContacts._ID};
+        final StringBuilder selection = new StringBuilder();
+        final String[] selectionArgs = new String[mContactIds.length];
+        for (int i = 0; i < mContactIds.length; i++) {
+            if (i > 0) {
+                selection.append(" OR ");
+            }
+            selection.append(ContactsContract.RawContacts.CONTACT_ID).append("=?");
+            selectionArgs[i] = Long.toString(mContactIds[i]);
+        }
+        final Cursor cursor = mContext.getContentResolver().query(
+                rawContactUri, projection, selection.toString(), selectionArgs, null, null);
+        final long[] rawContactIds = new long[cursor.getCount()];
+        try {
+            int i = 0;
+            while (cursor.moveToNext()) {
+                rawContactIds[i] = cursor.getLong(0);
+                i++;
+            }
+        } finally {
+            cursor.close();
+        }
+        return rawContactIds;
+    }
+
+    @Override
+    protected void onPostExecute(Intent intent) {
+        if (intent == null) {
+            Toast.makeText(mContext, R.string.groupSavedErrorToast, Toast.LENGTH_SHORT).show();
+        } else {
+            mContext.startService(intent);
+        }
+    }
+}
diff --git a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
index 173f66e..ff0d978 100644
--- a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
@@ -75,21 +75,22 @@
     private TreeSet<Long> mContactIds;
     private Context mContext;
     private AlertDialog mDialog;
+    private MultiContactDeleteListener mListener;
 
     /**
      * Starts the interaction.
      *
-     * @param activity the activity within which to start the interaction
+     * @param hostFragment the fragment within which to start the interaction
      * @param contactIds the IDs of contacts to be deleted
      * @return the newly created interaction
      */
     public static ContactMultiDeletionInteraction start(
-            Activity activity, TreeSet<Long> contactIds) {
+            Fragment hostFragment, TreeSet<Long> contactIds) {
         if (contactIds == null) {
             return null;
         }
 
-        final FragmentManager fragmentManager = activity.getFragmentManager();
+        final FragmentManager fragmentManager = hostFragment.getFragmentManager();
         ContactMultiDeletionInteraction fragment =
                 (ContactMultiDeletionInteraction) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
         if (fragment == null) {
@@ -291,13 +292,10 @@
     protected void doDeleteContact(long[] contactIds) {
         mContext.startService(ContactSaveService.createDeleteMultipleContactsIntent(mContext,
                 contactIds));
-        notifyListenerActivity();
+        mListener.onDeletionFinished();
     }
 
-    private void notifyListenerActivity() {
-        if (getActivity() instanceof MultiContactDeleteListener) {
-            final MultiContactDeleteListener listener = (MultiContactDeleteListener) getActivity();
-            listener.onDeletionFinished();
-        }
+    public void setListener(MultiContactDeleteListener listener) {
+        mListener = listener;
     }
 }
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 2060068..262856c 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -92,7 +92,7 @@
     private boolean mSelectionVerified;
     private int mLastSelectedPosition = -1;
     private boolean mRefreshingContactUri;
-    private ContactListFilter mFilter;
+    protected ContactListFilter mFilter;
     private String mPersistentSelectionPrefix = PERSISTENT_SELECTION_PREFIX;
 
     protected OnContactBrowserActionListener mListener;
@@ -680,9 +680,4 @@
             return mPersistentSelectionPrefix + "-" + mFilter.getId();
         }
     }
-
-    public boolean isOptionsMenuChanged() {
-        // This fragment does not have an option menu of its own
-        return false;
-    }
 }
diff --git a/src/com/android/contacts/list/ContactsUnavailableFragment.java b/src/com/android/contacts/list/ContactsUnavailableFragment.java
index 1b122cc..aa08a32 100644
--- a/src/com/android/contacts/list/ContactsUnavailableFragment.java
+++ b/src/com/android/contacts/list/ContactsUnavailableFragment.java
@@ -33,7 +33,6 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
-import com.android.contacts.activities.ActionBarAdapter.TabState;
 import com.android.contacts.common.compat.ProviderStatusCompat;
 
 /**
@@ -50,7 +49,6 @@
     private ProgressBar mProgress;
     private View mButtonsContainer;
     private int mNoContactsMsgResId = -1;
-    private int mLastTab = -1;
 
     private OnContactsUnavailableActionListener mListener;
 
@@ -125,10 +123,6 @@
      * Update views in the fragment when provider status is empty.
      */
     private void updateViewsForEmptyStatus() {
-        setTabInfo(mNoContactsMsgResId, mLastTab);
-        if (mLastTab == TabState.ALL) {
-            updateButtonVisibilty(View.VISIBLE);
-        }
         mProgress.setVisibility(View.GONE);
     }
 
@@ -167,29 +161,6 @@
         }
     }
 
-    /**
-     * Set the message to be shown if no data is available for the selected tab
-     *
-     * @param resId - String resource ID of the message , -1 means view will not be visible
-     */
-    public void setTabInfo(int resId, int callerTab) {
-        mNoContactsMsgResId = resId;
-        mLastTab = callerTab;
-        if ((mMessageView != null) && (mProviderStatus != null) &&
-                mProviderStatus.equals(ProviderStatusCompat.STATUS_EMPTY)) {
-            if (resId != -1) {
-                mMessageView.setText(mNoContactsMsgResId);
-                mMessageView.setGravity(Gravity.CENTER_HORIZONTAL);
-                mMessageView.setVisibility(View.VISIBLE);
-                if (callerTab == TabState.ALL) {
-                    updateButtonVisibilty(View.VISIBLE);
-                }
-            } else {
-                mMessageView.setVisibility(View.GONE);
-            }
-        }
-    }
-
     private void updateButtonVisibilty(int visibility) {
         if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
             mAddAccountButton.setVisibility(visibility);
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index afaafb7..2fcf5da 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -15,15 +15,32 @@
  */
 package com.android.contacts.list;
 
+import android.accounts.Account;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.ContentUris;
 import android.content.Context;
 import android.content.CursorLoader;
+import android.content.Intent;
 import android.content.Loader;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.database.Cursor;
+import android.graphics.Rect;
 import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Directory;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.widget.SwipeRefreshLayout;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -32,32 +49,170 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout.LayoutParams;
 import android.widget.TextView;
+import android.widget.Toast;
 
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.R;
+import com.android.contacts.activities.ActionBarAdapter;
 import com.android.contacts.activities.PeopleActivity;
+import com.android.contacts.common.Experiments;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.list.ContactEntryListFragment;
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
+import com.android.contacts.common.list.ContactListFilterController;
+import com.android.contacts.common.list.ContactListFilterController.ContactListFilterListener;
 import com.android.contacts.common.list.ContactListItemView;
 import com.android.contacts.common.list.DefaultContactListAdapter;
 import com.android.contacts.common.list.FavoritesAndContactsLoader;
+import com.android.contacts.common.logging.ListEvent;
+import com.android.contacts.common.logging.Logger;
+import com.android.contacts.common.logging.ScreenEvent;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.model.account.GoogleAccountType;
+import com.android.contacts.common.util.AccountFilterUtil;
+import com.android.contacts.common.util.ImplicitIntentsUtil;
+import com.android.contacts.interactions.ContactDeletionInteraction;
+import com.android.contacts.interactions.ContactMultiDeletionInteraction;
+import com.android.contacts.interactions.ContactMultiDeletionInteraction.MultiContactDeleteListener;
+import com.android.contacts.quickcontact.QuickContactActivity;
+import com.android.contacts.util.SharedPreferenceUtil;
+import com.android.contacts.util.SyncUtil;
+import com.android.contactsbind.experiments.Flags;
+import com.android.contactsbind.FeatureHighlightHelper;
+
+import java.util.List;
+import java.util.Locale;
 
 /**
  * Fragment containing a contact list used for browsing (as compared to
  * picking a contact with one of the PICK intents).
  */
 public class DefaultContactBrowseListFragment extends ContactBrowseListFragment {
+
+    private static final String TAG = "DefaultListFragment";
+    private static final String ENABLE_DEBUG_OPTIONS_HIDDEN_CODE = "debug debug!";
+    private static final String KEY_DELETION_IN_PROGRESS = "deletionInProgress";
+
+    private static final int ACTIVITY_REQUEST_CODE_SHARE = 0;
+
     private View mSearchHeaderView;
     private View mSearchProgress;
     private View mEmptyAccountView;
     private View mEmptyHomeView;
     private View mAccountFilterContainer;
     private TextView mSearchProgressText;
-    private FeatureHighlightCallback mCallback;
+    private SwipeRefreshLayout mSwipeRefreshLayout;
 
-    public interface FeatureHighlightCallback {
-        void onLoadFinishedCallback();
-    }
+    private boolean mContactsAvailable;
+    private boolean mEnableDebugMenuOptions;
+    private boolean mIsRecreatedInstance;
+    private boolean mOptionsMenuContactsAvailable;
+
+    /**
+     * This is to tell whether we need to restart ContactMultiDeletionInteraction and set listener.
+     * if screen is rotated while deletion dialog is shown.
+     */
+    private boolean mIsDeletionInProgress;
+
+    /**
+     * This is to disable {@link #onOptionsItemSelected} when we trying to stop the
+     * activity/fragment.
+     */
+    private boolean mDisableOptionItemSelected;
+
+    private ActionBarAdapter mActionBarAdapter;
+    private ContactMultiDeletionInteraction mMultiDeletionInteraction;
+    private ContactsRequest mContactsRequest;
+    protected ContactListFilterController mContactListFilterController;
+
+    private final ContactListFilterListener mFilterListener = new ContactListFilterListener() {
+        @Override
+        public void onContactListFilterChanged() {
+            final ContactListFilter filter = mContactListFilterController.getFilter();
+            setFilterAndUpdateTitle(filter);
+
+            // Scroll to top after filter is changed.
+            getListView().setSelection(0);
+
+            getActivity().invalidateOptionsMenu();
+        }
+    };
+
+    private final ActionBarAdapter.Listener mActionBarListener = new ActionBarAdapter.Listener() {
+        @Override
+        public void onAction(int action) {
+            switch (action) {
+                case ActionBarAdapter.Listener.Action.START_SELECTION_MODE:
+                    displayCheckBoxes(true);
+                    startSearchOrSelectionMode();
+                    break;
+                case ActionBarAdapter.Listener.Action.START_SEARCH_MODE:
+                    if (!mIsRecreatedInstance) {
+                        Logger.logScreenView(getActivity(), ScreenEvent.ScreenType.SEARCH);
+                    }
+                    startSearchOrSelectionMode();
+                    break;
+                case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE:
+                    ((PeopleActivity) getActivity()).showFabWithAnimation(/* showFab */ true);
+                    break;
+                case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
+                    // If queryString is empty, fragment data will not be reloaded,
+                    // so hamburger promo should be checked now.
+                    // Otherwise, promo should be checked and displayed after reloading, b/30706521.
+                    if (TextUtils.isEmpty(getQueryString())) {
+                        maybeShowHamburgerFeatureHighlight();
+                    }
+                    setQueryTextToFragment("");
+                    maybeHideCheckBoxes();
+                    getActivity().invalidateOptionsMenu();
+                    ((PeopleActivity) getActivity()).showFabWithAnimation(/* showFab */ true);
+                    // Determine whether the account has pullToRefresh feature
+                    if (Flags.getInstance(getContext()).getBoolean(Experiments.PULL_TO_REFRESH)) {
+                        setSwipeRefreshLayoutEnabledOrNot(getFilter());
+                    }
+                    break;
+                case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY:
+                    final String queryString = mActionBarAdapter.getQueryString();
+                    setQueryTextToFragment(queryString);
+                    updateDebugOptionsVisibility(
+                            ENABLE_DEBUG_OPTIONS_HIDDEN_CODE.equals(queryString));
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown ActionBarAdapter action: " + action);
+            }
+        }
+
+        private void startSearchOrSelectionMode() {
+            configureContactListFragment();
+            maybeHideCheckBoxes();
+            getActivity().invalidateOptionsMenu();
+            ((PeopleActivity) getActivity()).showFabWithAnimation(/* showFab */ false);
+            final Context context = getContext();
+            if (!SharedPreferenceUtil.getHamburgerPromoTriggerActionHappenedBefore(context)) {
+                SharedPreferenceUtil.setHamburgerPromoTriggerActionHappenedBefore(context);
+            }
+        }
+
+        private void updateDebugOptionsVisibility(boolean visible) {
+            if (mEnableDebugMenuOptions != visible) {
+                mEnableDebugMenuOptions = visible;
+                getActivity().invalidateOptionsMenu();
+            }
+        }
+
+        private void setQueryTextToFragment(String query) {
+            setQueryString(query, true);
+            setVisibleScrollbarEnabled(!isSearchMode());
+        }
+
+        @Override
+        public void onUpButtonPressed() {
+            getActivity().onBackPressed();
+        }
+    };
 
     public DefaultContactBrowseListFragment() {
         setPhotoLoaderEnabled(true);
@@ -67,10 +222,7 @@
         setSectionHeaderDisplayEnabled(true);
         setVisibleScrollbarEnabled(true);
         setDisplayDirectoryHeader(false);
-    }
-
-    public void setFeatureHighlightCallback(FeatureHighlightCallback callback) {
-        mCallback = callback;
+        setHasOptionsMenu(true);
     }
 
     @Override
@@ -84,14 +236,27 @@
             bindListHeader(data.getCount());
         }
         super.onLoadFinished(loader, data);
-        if (!isSearchMode() && mCallback != null) {
-            mCallback.onLoadFinishedCallback();
+        if (!isSearchMode()) {
+            maybeShowHamburgerFeatureHighlight();
+        }
+    }
+
+    public void maybeShowHamburgerFeatureHighlight() {
+        if (mActionBarAdapter!= null && !mActionBarAdapter.isSearchMode()
+                && !mActionBarAdapter.isSelectionMode()
+                && SharedPreferenceUtil.getShouldShowHamburgerPromo(getContext())) {
+            if (FeatureHighlightHelper.showHamburgerFeatureHighlight(
+                    (FragmentActivity) getActivity())) {
+                SharedPreferenceUtil.setHamburgerPromoDisplayedBefore(getContext());
+            }
         }
     }
 
     private void bindListHeader(int numberOfContacts) {
         final ContactListFilter filter = getFilter();
-        if (!isSearchMode() && numberOfContacts <= 0) {
+        // If the phone has at least one Google account whose sync status is unsyncable or pending
+        // or active, we have to make mAccountFilterContainer visible.
+        if (!isSearchMode() && numberOfContacts <= 0 && shouldShowEmptyView(filter)) {
             if (filter != null && filter.isContactsFilterType()) {
                 makeViewVisible(mEmptyHomeView);
             } else {
@@ -114,6 +279,38 @@
         }
     }
 
+    /**
+     * If at least one Google account is unsyncable or its sync status is pending or active, we
+     * should not show empty view even if the number of contacts is 0. We should show sync status
+     * with empty list instead.
+     */
+    private boolean shouldShowEmptyView(ContactListFilter filter) {
+        if (filter == null) {
+            return true;
+        }
+        // TODO(samchen) : Check ContactListFilter.FILTER_TYPE_CUSTOM
+        if (ContactListFilter.FILTER_TYPE_DEFAULT == filter.filterType
+                || ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS == filter.filterType) {
+            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(getContext())
+                    .getAccounts(/* contactsWritableOnly */ true);
+            final List<Account> syncableAccounts = filter.getSyncableAccounts(accounts);
+
+            if (syncableAccounts != null && syncableAccounts.size() > 0) {
+                for (Account account : syncableAccounts) {
+                    if (SyncUtil.isSyncStatusPendingOrActive(account)
+                            || SyncUtil.isUnsyncableGoogleAccount(account)) {
+                        return false;
+                    }
+                }
+            }
+        } else if (ContactListFilter.FILTER_TYPE_ACCOUNT == filter.filterType) {
+            final Account account = new Account(filter.accountName, filter.accountType);
+            return !(SyncUtil.isSyncStatusPendingOrActive(account)
+                    || SyncUtil.isUnsyncableGoogleAccount(account));
+        }
+        return true;
+    }
+
     // Show the view that's specified by id and hide the other two.
     private void makeViewVisible(View view) {
         mEmptyAccountView.setVisibility(view == mEmptyAccountView ? View.VISIBLE : View.GONE);
@@ -215,9 +412,12 @@
     protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
         super.onCreateView(inflater, container);
 
+        if (Flags.getInstance(getActivity()).getBoolean(Experiments.PULL_TO_REFRESH)) {
+            initSwipeRefreshLayout();
+        }
         // Putting the header view inside a container will allow us to make
         // it invisible later. See checkHeaderViewVisibility()
-        FrameLayout headerContainer = new FrameLayout(inflater.getContext());
+        final FrameLayout headerContainer = new FrameLayout(inflater.getContext());
         mSearchHeaderView = inflater.inflate(R.layout.search_header, null, false);
         headerContainer.addView(mSearchHeaderView);
         getListView().addHeaderView(headerContainer, null, false);
@@ -227,6 +427,113 @@
         mSearchProgressText = (TextView) mSearchHeaderView.findViewById(R.id.totalContactsText);
     }
 
+    private void initSwipeRefreshLayout() {
+        mSwipeRefreshLayout = (SwipeRefreshLayout) mView.findViewById(R.id.swipe_refresh);
+        if (mSwipeRefreshLayout == null) {
+            return;
+        }
+
+        mSwipeRefreshLayout.setEnabled(true);
+        // Request sync contacts
+        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                syncContacts(mFilter);
+            }
+        });
+        mSwipeRefreshLayout.setColorSchemeResources(
+                R.color.swipe_refresh_color1,
+                R.color.swipe_refresh_color2,
+                R.color.swipe_refresh_color3,
+                R.color.swipe_refresh_color4);
+        mSwipeRefreshLayout.setDistanceToTriggerSync(
+                (int) getResources().getDimension(R.dimen.pull_to_refresh_distance));
+    }
+
+    /**
+     * Request sync for the Google accounts (not include Google+ accounts) specified by the given
+     * filter.
+     */
+    private void syncContacts(ContactListFilter filter) {
+        if (filter == null) {
+            return;
+        }
+        final Bundle bundle = new Bundle();
+        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+
+        final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(
+                getActivity()).getAccounts(/* contactsWritableOnly */ true);
+        final List<Account> syncableAccounts = filter.getSyncableAccounts(accounts);
+        if (syncableAccounts != null && syncableAccounts.size() > 0) {
+            for (Account account : syncableAccounts) {
+                // We can prioritize Contacts sync if sync is not initialized yet.
+                if (!SyncUtil.isSyncStatusPendingOrActive(account)
+                        || SyncUtil.isUnsyncableGoogleAccount(account)) {
+                    ContentResolver.requestSync(account, ContactsContract.AUTHORITY, bundle);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        mIsRecreatedInstance = (savedInstanceState != null);
+        mContactListFilterController = ContactListFilterController.getInstance(getContext());
+        mContactListFilterController.checkFilterValidity(false);
+        mContactListFilterController.addListener(mFilterListener);
+
+        // Use FILTER_TYPE_ALL_ACCOUNTS filter if the instance is not a re-created one.
+        // This is useful when user upgrades app while an account filter or a custom filter was
+        // stored in sharedPreference in a previous version of Contacts app.
+        final ContactListFilter filter = mIsRecreatedInstance
+                ? mContactListFilterController.getFilter()
+                : AccountFilterUtil.createContactsFilter(getContext());
+        setContactListFilter(filter);
+
+        final ContactsDrawerActivity activity = (ContactsDrawerActivity) getActivity();
+        mActionBarAdapter = new ActionBarAdapter(activity, mActionBarListener,
+                activity.getSupportActionBar(), activity.getToolbar(), R.string.enter_contact_name);
+        mActionBarAdapter.setShowHomeIcon(true);
+        initializeActionBarAdapter(savedInstanceState);
+        if (isSearchMode()) {
+            mActionBarAdapter.setFocusOnSearchView();
+        }
+
+        setCheckBoxListListener(new CheckBoxListListener());
+        setOnContactListActionListener(new ContactBrowserActionListener());
+        if (mIsRecreatedInstance && savedInstanceState.getBoolean(KEY_DELETION_IN_PROGRESS)) {
+            deleteSelectedContacts();
+        }
+    }
+
+    public void initializeActionBarAdapter(Bundle savedInstanceState) {
+        if (mActionBarAdapter != null) {
+            mActionBarAdapter.initialize(savedInstanceState, mContactsRequest);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // Re-register the listener, which may have been cleared when onSaveInstanceState was
+        // called. See also: onSaveInstanceState
+        mActionBarAdapter.setListener(mActionBarListener);
+        mDisableOptionItemSelected = false;
+        maybeHideCheckBoxes();
+    }
+
+    private void maybeHideCheckBoxes() {
+        if (!mActionBarAdapter.isSelectionMode()) {
+            displayCheckBoxes(false);
+        }
+    }
+
+    public ActionBarAdapter getActionBarAdapter(){
+        return mActionBarAdapter;
+    }
+
     @Override
     protected void setSearchMode(boolean flag) {
         super.setSearchMode(flag);
@@ -275,4 +582,427 @@
             }
         }
     }
-}
\ No newline at end of file
+
+    public SwipeRefreshLayout getSwipeRefreshLayout() {
+        return mSwipeRefreshLayout;
+    }
+
+    private final class CheckBoxListListener implements OnCheckBoxListActionListener {
+        @Override
+        public void onStartDisplayingCheckBoxes() {
+            mActionBarAdapter.setSelectionMode(true);
+            getActivity().invalidateOptionsMenu();
+        }
+
+        @Override
+        public void onSelectedContactIdsChanged() {
+            mActionBarAdapter.setSelectionCount(getSelectedContactIds().size());
+            getActivity().invalidateOptionsMenu();
+        }
+
+        @Override
+        public void onStopDisplayingCheckBoxes() {
+            mActionBarAdapter.setSelectionMode(false);
+        }
+    }
+
+    private void setFilterAndUpdateTitle(ContactListFilter filter) {
+        setFilterAndUpdateTitle(filter, true);
+    }
+
+    private void setFilterAndUpdateTitle(ContactListFilter filter, boolean restoreSelectedUri) {
+        setFilter(filter, restoreSelectedUri);
+        setListType(mContactListFilterController.getFilterListType());
+
+        ((ContactsDrawerActivity) getActivity()).updateFilterMenu(filter);
+
+        final String actionBarTitle;
+        if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS) {
+            actionBarTitle = getString(R.string.account_phone);
+        } else if (!TextUtils.isEmpty(filter.accountName)) {
+            actionBarTitle = getActionBarTitleForAccount(filter);
+        } else {
+            actionBarTitle = getString(R.string.contactsList);
+        }
+        getActivity().setTitle(actionBarTitle);
+
+        if (CompatUtils.isNCompatible()) {
+            getActivity().setTitle(actionBarTitle);
+            getActivity().getWindow().getDecorView()
+                    .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+        }
+        // Determine whether the account has pullToRefresh feature
+        if (Flags.getInstance(getContext()).getBoolean(Experiments.PULL_TO_REFRESH)) {
+            setSwipeRefreshLayoutEnabledOrNot(filter);
+        }
+    }
+
+    private String getActionBarTitleForAccount(ContactListFilter filter) {
+        if (GoogleAccountType.ACCOUNT_TYPE.equals(filter.accountType)) {
+            return getString(R.string.title_from_google);
+        }
+        return getString(R.string.title_from_other_accounts, filter.accountName);
+    }
+
+    public void setSwipeRefreshLayoutEnabledOrNot(ContactListFilter filter) {
+        final SwipeRefreshLayout swipeRefreshLayout = getSwipeRefreshLayout();
+        if (swipeRefreshLayout == null) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "Can not load swipeRefreshLayout, swipeRefreshLayout is null");
+            }
+            return;
+        }
+
+        swipeRefreshLayout.setRefreshing(false);
+        swipeRefreshLayout.setEnabled(false);
+
+        if (filter != null && !mActionBarAdapter.isSearchMode()
+                && !mActionBarAdapter.isSelectionMode()) {
+            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(getContext())
+                    .getAccounts(/* contactsWritableOnly */ true);
+            if (filter.isSyncable(accounts)) {
+                swipeRefreshLayout.setEnabled(true);
+            }
+        }
+    }
+
+    public void configureContactListFragment() {
+        // Filter may be changed when activity is in background.
+        setFilterAndUpdateTitle(getFilter());
+        setVerticalScrollbarPosition(getScrollBarPosition());
+        setSelectionVisible(false);
+        getActivity().invalidateOptionsMenu();
+    }
+
+    private int getScrollBarPosition() {
+        final Locale locale = Locale.getDefault();
+        final boolean isRTL =
+                TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL;
+        return isRTL ? View.SCROLLBAR_POSITION_LEFT : View.SCROLLBAR_POSITION_RIGHT;
+    }
+
+    private final class ContactBrowserActionListener implements OnContactBrowserActionListener {
+        ContactBrowserActionListener() {}
+
+        @Override
+        public void onSelectionChange() {
+
+        }
+
+        @Override
+        public void onViewContactAction(int position, Uri contactLookupUri,
+                boolean isEnterpriseContact) {
+            if (isEnterpriseContact) {
+                // No implicit intent as user may have a different contacts app in work profile.
+                ContactsContract.QuickContact.showQuickContact(getContext(), new Rect(),
+                        contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED, null);
+            } else {
+                final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(
+                        getContext(), contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED);
+                final int previousScreen;
+                if (isSearchMode()) {
+                    previousScreen = ScreenEvent.ScreenType.SEARCH;
+                } else {
+                    if (isAllContactsFilter(mContactListFilterController.getFilter())) {
+                        if (position < getAdapter().getNumberOfFavorites()) {
+                            previousScreen = ScreenEvent.ScreenType.FAVORITES;
+                        } else {
+                            previousScreen = ScreenEvent.ScreenType.ALL_CONTACTS;
+                        }
+                    } else {
+                        previousScreen = ScreenEvent.ScreenType.LIST_ACCOUNT;
+                    }
+                }
+                Logger.logListEvent(ListEvent.ActionType.CLICK,
+                        /* listType */ getListTypeIncludingSearch(),
+                        /* count */ getAdapter().getCount(),
+                        /* clickedIndex */ position, /* numSelected */ 0);
+                intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, previousScreen);
+                ImplicitIntentsUtil.startActivityInApp(getContext(), intent);
+            }
+        }
+
+        @Override
+        public void onDeleteContactAction(Uri contactUri) {
+            ContactDeletionInteraction.start(getActivity(), contactUri, false);
+        }
+
+        @Override
+        public void onFinishAction() {
+            getActivity().onBackPressed();
+        }
+
+        @Override
+        public void onInvalidSelection() {
+            ContactListFilter filter;
+            ContactListFilter currentFilter = getFilter();
+            if (currentFilter != null
+                    && currentFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
+                filter = AccountFilterUtil.createContactsFilter(getContext());
+                setFilterAndUpdateTitle(filter);
+            } else {
+                filter = ContactListFilter.createFilterWithType(
+                        ContactListFilter.FILTER_TYPE_SINGLE_CONTACT);
+                setFilterAndUpdateTitle(filter, /* restoreSelectedUri */ false);
+            }
+            setContactListFilter(filter);
+        }
+    }
+
+    private boolean isAllContactsFilter(ContactListFilter filter) {
+        return filter != null && filter.isContactsFilterType();
+    }
+
+    public void setContactsAvailable(boolean contactsAvailable) {
+        mContactsAvailable = contactsAvailable;
+    }
+
+    /**
+     * Set filter via ContactListFilterController
+     */
+    public void setContactListFilter(ContactListFilter filter) {
+        mContactListFilterController.setContactListFilter(filter,
+                /* persistent */ isAllContactsFilter(filter));
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        if (!mContactsAvailable) {
+            // If contacts aren't available, hide all menu items.
+            return;
+        }
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.people_options, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        mOptionsMenuContactsAvailable = mContactsAvailable;
+        if (!mOptionsMenuContactsAvailable) {
+            return;
+        }
+
+        final boolean isSearchOrSelectionMode = mActionBarAdapter.isSearchMode()
+                || mActionBarAdapter.isSelectionMode();
+        makeMenuItemVisible(menu, R.id.menu_search, !isSearchOrSelectionMode);
+
+        final boolean showSelectedContactOptions = mActionBarAdapter.isSelectionMode()
+                && getSelectedContactIds().size() != 0;
+        makeMenuItemVisible(menu, R.id.menu_share, showSelectedContactOptions);
+        makeMenuItemVisible(menu, R.id.menu_delete, showSelectedContactOptions);
+        final boolean showLinkContactsOptions = mActionBarAdapter.isSelectionMode()
+                && getSelectedContactIds().size() > 1;
+        makeMenuItemVisible(menu, R.id.menu_join, showLinkContactsOptions);
+
+        // Debug options need to be visible even in search mode.
+        makeMenuItemVisible(menu, R.id.export_database, mEnableDebugMenuOptions &&
+                hasExportIntentHandler());
+    }
+
+    private void makeMenuItemVisible(Menu menu, int itemId, boolean visible) {
+        final MenuItem item = menu.findItem(itemId);
+        if (item != null) {
+            item.setVisible(visible);
+        }
+    }
+
+    private boolean hasExportIntentHandler() {
+        final Intent intent = new Intent();
+        intent.setAction("com.android.providers.contacts.DUMP_DATABASE");
+        final List<ResolveInfo> receivers =
+                getContext().getPackageManager().queryIntentActivities(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        return receivers != null && receivers.size() > 0;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (mDisableOptionItemSelected) {
+            return false;
+        }
+
+        switch (item.getItemId()) {
+            case android.R.id.home: {
+                // The home icon on the action bar is pressed
+                if (mActionBarAdapter.isUpShowing()) {
+                    // "UP" icon press -- should be treated as "back".
+                    getActivity().onBackPressed();
+                }
+                return true;
+            }
+            case R.id.menu_search: {
+                if (!mActionBarAdapter.isSelectionMode()) {
+                    mActionBarAdapter.setSearchMode(true);
+                }
+                return true;
+            }
+            case R.id.menu_share: {
+                shareSelectedContacts();
+                return true;
+            }
+            case R.id.menu_join: {
+                Logger.logListEvent(ListEvent.ActionType.LINK,
+                        /* listType */ getListTypeIncludingSearch(),
+                        /* count */ getAdapter().getCount(), /* clickedIndex */ -1,
+                        /* numSelected */ getAdapter().getSelectedContactIds().size());
+                joinSelectedContacts();
+                return true;
+            }
+            case R.id.menu_delete: {
+                deleteSelectedContacts();
+                return true;
+            }
+            case R.id.export_database: {
+                final Intent intent = new Intent("com.android.providers.contacts.DUMP_DATABASE");
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                ImplicitIntentsUtil.startActivityOutsideApp(getContext(), intent);
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /**
+     * Share all contacts that are currently selected in mAllFragment. This method is pretty
+     * inefficient for handling large numbers of contacts. I don't expect this to be a problem.
+     */
+    private void shareSelectedContacts() {
+        final StringBuilder uriListBuilder = new StringBuilder();
+        for (Long contactId : getSelectedContactIds()) {
+            final Uri contactUri = ContentUris.withAppendedId(
+                    ContactsContract.Contacts.CONTENT_URI, contactId);
+            final Uri lookupUri = ContactsContract.Contacts.getLookupUri(
+                    getContext().getContentResolver(), contactUri);
+            if (lookupUri == null) {
+                continue;
+            }
+            final List<String> pathSegments = lookupUri.getPathSegments();
+            if (pathSegments.size() < 2) {
+                continue;
+            }
+            final String lookupKey = pathSegments.get(pathSegments.size() - 2);
+            if (uriListBuilder.length() > 0) {
+                uriListBuilder.append(':');
+            }
+            uriListBuilder.append(Uri.encode(lookupKey));
+        }
+        if (uriListBuilder.length() == 0) {
+            return;
+        }
+        final Uri uri = Uri.withAppendedPath(
+                ContactsContract.Contacts.CONTENT_MULTI_VCARD_URI,
+                Uri.encode(uriListBuilder.toString()));
+        final Intent intent = new Intent(Intent.ACTION_SEND);
+        intent.setType(ContactsContract.Contacts.CONTENT_VCARD_TYPE);
+        intent.putExtra(Intent.EXTRA_STREAM, uri);
+        try {
+            startActivityForResult(Intent.createChooser(intent, getResources().getQuantityString(
+                    R.plurals.title_share_via,/* quantity */ getSelectedContactIds().size()))
+                    , ACTIVITY_REQUEST_CODE_SHARE);
+        } catch (final ActivityNotFoundException ex) {
+            Toast.makeText(getContext(), R.string.share_error, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    private void joinSelectedContacts() {
+        final Context context = getContext();
+        final Intent intent = ContactSaveService.createJoinSeveralContactsIntent(
+                context, getSelectedContactIdsArray());
+        context.startService(intent);
+
+        mActionBarAdapter.setSelectionMode(false);
+    }
+
+    private void deleteSelectedContacts() {
+        mMultiDeletionInteraction =
+                ContactMultiDeletionInteraction.start(this, getSelectedContactIds());
+        mMultiDeletionInteraction.setListener(new MultiDeleteListener());
+        mIsDeletionInProgress = true;
+    }
+
+    private final class MultiDeleteListener implements MultiContactDeleteListener {
+        @Override
+        public void onDeletionFinished() {
+            // The parameters count and numSelected are both the number of contacts before deletion.
+            Logger.logListEvent(ListEvent.ActionType.DELETE,
+                /* listType */ getListTypeIncludingSearch(),
+                /* count */ getAdapter().getCount(), /* clickedIndex */ -1,
+                /* numSelected */ getSelectedContactIds().size());
+            mActionBarAdapter.setSelectionMode(false);
+            mIsDeletionInProgress = false;
+        }
+    }
+
+    private int getListTypeIncludingSearch() {
+        return isSearchMode() ? ListEvent.ListType.SEARCH_RESULT : getListType();
+    }
+
+    public void setListType() {
+        mContactListFilterController = ContactListFilterController.getInstance(getContext());
+        setListType(mContactListFilterController.getFilterListType());
+    }
+
+    public void setContactsRequest(ContactsRequest contactsRequest) {
+        mContactsRequest = contactsRequest;
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            // TODO: Using the new startActivityWithResultFromFragment API this should not be needed
+            // anymore
+            case ContactEntryListFragment.ACTIVITY_REQUEST_CODE_PICKER:
+                if (resultCode == Activity.RESULT_OK) {
+                    onPickerResult(data);
+                }
+            case ACTIVITY_REQUEST_CODE_SHARE:
+                Logger.logListEvent(ListEvent.ActionType.SHARE,
+                    /* listType */ getListTypeIncludingSearch(),
+                    /* count */ getAdapter().getCount(), /* clickedIndex */ -1,
+                    /* numSelected */ getAdapter().getSelectedContactIds().size());
+
+// TODO fix or remove multipicker code: ag/54762
+//                else if (resultCode == RESULT_CANCELED && mMode == MODE_PICK_MULTIPLE_PHONES) {
+//                    // Finish the activity if the sub activity was canceled as back key is used
+//                    // to confirm user selection in MODE_PICK_MULTIPLE_PHONES.
+//                    finish();
+//                }
+//                break;
+        }
+    }
+
+    public boolean getOptionsMenuContactsAvailable() {
+        return mOptionsMenuContactsAvailable;
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        // Clear the listener to make sure we don't get callbacks after onSaveInstanceState,
+        // in order to avoid doing fragment transactions after it.
+        // TODO Figure out a better way to deal with the issue (ag/120686).
+        if (mActionBarAdapter != null) {
+            mActionBarAdapter.setListener(null);
+            mActionBarAdapter.onSaveInstanceState(outState);
+        }
+        mDisableOptionItemSelected = true;
+        outState.putBoolean(KEY_DELETION_IN_PROGRESS, mIsDeletionInProgress);
+    }
+
+    @Override
+    public void onPause() {
+        mOptionsMenuContactsAvailable = false;
+        super.onPause();
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mActionBarAdapter != null) {
+            mActionBarAdapter.setListener(null);
+        }
+        if (mContactListFilterController != null) {
+            mContactListFilterController.removeListener(mFilterListener);
+        }
+        super.onDestroy();
+    }
+}
diff --git a/src/com/android/contacts/list/MultiSelectContactsListFragment.java b/src/com/android/contacts/list/MultiSelectContactsListFragment.java
index f5c6d34..ea74834 100644
--- a/src/com/android/contacts/list/MultiSelectContactsListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectContactsListFragment.java
@@ -129,13 +129,18 @@
             final TreeSet<Long> selectedContactIds = (TreeSet<Long>)
                     savedInstanceState.getSerializable(EXTRA_KEY_SELECTED_CONTACTS);
             getAdapter().setSelectedContactIds(selectedContactIds);
-            if (mCheckBoxListListener != null) {
-                mCheckBoxListListener.onSelectedContactIdsChanged();
-            }
             mSearchResultClicked = savedInstanceState.getBoolean(KEY_SEARCH_RESULT_CLICKED);
         }
     }
 
+    @Override
+    public void onStart() {
+        super.onStart();
+        if (mCheckBoxListListener != null) {
+            mCheckBoxListListener.onSelectedContactIdsChanged();
+        }
+    }
+
     public TreeSet<Long> getSelectedContactIds() {
         return getAdapter().getSelectedContactIds();
     }
diff --git a/src/com/android/contacts/util/SyncUtil.java b/src/com/android/contacts/util/SyncUtil.java
new file mode 100644
index 0000000..cef2223
--- /dev/null
+++ b/src/com/android/contacts/util/SyncUtil.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 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.accounts.Account;
+import android.content.ContentResolver;
+import android.provider.ContactsContract;
+
+import com.android.contacts.common.model.account.GoogleAccountType;
+
+import java.util.List;
+
+/**
+ * Utilities related to sync.
+ */
+public final class SyncUtil {
+    private static final String TAG = "SyncUtil";
+
+    private SyncUtil() {
+    }
+
+    public static final boolean isSyncStatusPendingOrActive(Account account) {
+        if (account == null) {
+            return false;
+        }
+        return ContentResolver.isSyncPending(account, ContactsContract.AUTHORITY)
+                || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY);
+    }
+
+    /**
+     * Returns true if the given Google account is not syncable.
+     */
+    public static final boolean isUnsyncableGoogleAccount(Account account) {
+        if (account == null || !GoogleAccountType.ACCOUNT_TYPE.equals(account.type)) {
+            return false;
+        }
+        return ContentResolver.getIsSyncable(account, ContactsContract.AUTHORITY) <= 0;
+    }
+}
diff --git a/tests/Android.mk b/tests/Android.mk
index 48a00f4..82276de 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -5,8 +5,6 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := shared
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
-
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, res)
 
diff --git a/tests/src/com/android/contacts/common/util/DateUtilTests.java b/tests/src/com/android/contacts/common/util/DateUtilTests.java
deleted file mode 100644
index f460289..0000000
--- a/tests/src/com/android/contacts/common/util/DateUtilTests.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 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.common.util;
-
-import junit.framework.TestCase;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.format.Time;
-
-/**
- * Unit tests for {@link com.android.contacts.common.util.DateUtils}.
- */
-@SmallTest
-public class DateUtilTests extends TestCase {
-
-    /**
-     * Test date differences which are in the same day.
-     */
-    public void testDayDiffNone() {
-        Time time = new Time();
-        long date1 = System.currentTimeMillis();
-        long date2 = System.currentTimeMillis() + android.text.format.DateUtils.HOUR_IN_MILLIS;
-        assertEquals(0, DateUtils.getDayDifference(time, date1, date2));
-        assertEquals(0, DateUtils.getDayDifference(time, date2, date1));
-    }
-
-    /**
-     * Test date differences which are a day apart.
-     */
-    public void testDayDiffOne() {
-        Time time = new Time();
-        long date1 = System.currentTimeMillis();
-        long date2 = date1 + android.text.format.DateUtils.DAY_IN_MILLIS;
-        assertEquals(1, DateUtils.getDayDifference(time, date1, date2));
-        assertEquals(1, DateUtils.getDayDifference(time, date2, date1));
-    }
-
-    /**
-     * Test date differences which are two days apart.
-     */
-    public void testDayDiffTwo() {
-        Time time = new Time();
-        long date1 = System.currentTimeMillis();
-        long date2 = date1 + 2*android.text.format.DateUtils.DAY_IN_MILLIS;
-        assertEquals(2, DateUtils.getDayDifference(time, date1, date2));
-        assertEquals(2, DateUtils.getDayDifference(time, date2, date1));
-    }
-}
diff --git a/tests/src/com/android/contacts/util/SyncUtilTests.java b/tests/src/com/android/contacts/util/SyncUtilTests.java
new file mode 100644
index 0000000..372a652
--- /dev/null
+++ b/tests/src/com/android/contacts/util/SyncUtilTests.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 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.accounts.Account;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for SyncUtil.
+ */
+@SmallTest
+public class SyncUtilTests extends AndroidTestCase {
+    private static final String TAG = "SyncUtilTests";
+
+    private static final String GOOGLE_TYPE = "com.google";
+    private static final String NOT_GOOGLE_TYPE = "com.abc";
+    private static final String ACCOUNT_NAME = "ACCOUNT_NAME";
+
+    private final Account mGoogleAccount;
+    private final Account mOtherAccount;
+
+    public SyncUtilTests() {
+        mGoogleAccount = new Account(ACCOUNT_NAME, GOOGLE_TYPE);
+        mOtherAccount = new Account(ACCOUNT_NAME, NOT_GOOGLE_TYPE);
+    }
+
+    public void testIsUnsyncableGoogleAccount() throws Exception {
+        // The account names of mGoogleAccount and mOtherAccount are not valid, so both accounts
+        // are not syncable.
+        assertTrue(SyncUtil.isUnsyncableGoogleAccount(mGoogleAccount));
+        assertFalse(SyncUtil.isUnsyncableGoogleAccount(mOtherAccount));
+        assertFalse(SyncUtil.isUnsyncableGoogleAccount(null));
+    }
+}