Merge "Fix overdraw in PeopleActivity"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b791d94..eff52d8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -220,13 +220,13 @@
 
         <!-- Used to filter contacts list by account -->
         <activity
-            android:name=".list.AccountFilterActivity"
+            android:name=".common.list.AccountFilterActivity"
             android:label="@string/activity_title_contacts_filter"
             android:theme="@style/ContactListFilterTheme" />
 
         <!-- Used to select display and sync groups -->
         <activity
-            android:name=".list.CustomContactListFilterActivity"
+            android:name=".common.list.CustomContactListFilterActivity"
             android:label="@string/custom_list_filter"
             android:theme="@style/ContactListFilterTheme" />
 
@@ -384,7 +384,7 @@
         <!-- Stub service used to keep our process alive long enough for
              background threads to finish their operations. -->
         <service
-            android:name=".util.EmptyService"
+            android:name=".common.util.EmptyService"
             android:exported="false" />
 
         <!-- Service to save a contact -->
@@ -418,7 +418,6 @@
         <!-- vCard related -->
         <activity android:name=".vcard.ImportVCardActivity"
             android:configChanges="orientation|screenSize|keyboardHidden"
-            android:screenOrientation="nosensor"
             android:theme="@style/BackgroundOnlyTheme">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
diff --git a/res/drawable-hdpi/badge_action_call.png b/res/drawable-hdpi/badge_action_call.png
deleted file mode 100644
index 0b1c6b4..0000000
--- a/res/drawable-hdpi/badge_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/badge_action_sms.png b/res/drawable-hdpi/badge_action_sms.png
deleted file mode 100644
index 0dfdbf5..0000000
--- a/res/drawable-hdpi/badge_action_sms.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_settings_holo_light.png b/res/drawable-hdpi/ic_menu_settings_holo_light.png
deleted file mode 100644
index b7bb5c4..0000000
--- a/res/drawable-hdpi/ic_menu_settings_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_star_holo_light.png b/res/drawable-hdpi/ic_menu_star_holo_light.png
deleted file mode 100644
index 4513796..0000000
--- a/res/drawable-hdpi/ic_menu_star_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/unknown_source.png b/res/drawable-hdpi/unknown_source.png
deleted file mode 100644
index 0a8f37d..0000000
--- a/res/drawable-hdpi/unknown_source.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/badge_action_call.png b/res/drawable-mdpi/badge_action_call.png
deleted file mode 100644
index af2abaa..0000000
--- a/res/drawable-mdpi/badge_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/badge_action_sms.png b/res/drawable-mdpi/badge_action_sms.png
deleted file mode 100644
index 13dd8bc..0000000
--- a/res/drawable-mdpi/badge_action_sms.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_settings_holo_light.png b/res/drawable-mdpi/ic_menu_settings_holo_light.png
deleted file mode 100644
index 1ebc112..0000000
--- a/res/drawable-mdpi/ic_menu_settings_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_star_holo_light.png b/res/drawable-mdpi/ic_menu_star_holo_light.png
deleted file mode 100644
index 8263b27..0000000
--- a/res/drawable-mdpi/ic_menu_star_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/unknown_source.png b/res/drawable-mdpi/unknown_source.png
deleted file mode 100644
index 356748f..0000000
--- a/res/drawable-mdpi/unknown_source.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/badge_action_call.png b/res/drawable-xhdpi/badge_action_call.png
deleted file mode 100644
index 2589e33..0000000
--- a/res/drawable-xhdpi/badge_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/badge_action_sms.png b/res/drawable-xhdpi/badge_action_sms.png
deleted file mode 100644
index 460451f..0000000
--- a/res/drawable-xhdpi/badge_action_sms.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_settings_holo_light.png b/res/drawable-xhdpi/ic_menu_settings_holo_light.png
deleted file mode 100644
index 68ba92b..0000000
--- a/res/drawable-xhdpi/ic_menu_settings_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_star_holo_light.png b/res/drawable-xhdpi/ic_menu_star_holo_light.png
deleted file mode 100644
index 9067911..0000000
--- a/res/drawable-xhdpi/ic_menu_star_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/unknown_source.png b/res/drawable-xhdpi/unknown_source.png
deleted file mode 100644
index 35e8fb4..0000000
--- a/res/drawable-xhdpi/unknown_source.png
+++ /dev/null
Binary files differ
diff --git a/res/layout/account_filter_header.xml b/res/layout/account_filter_header.xml
deleted file mode 100644
index 0ffb7e1..0000000
--- a/res/layout/account_filter_header.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- Layout showing the type of account filter
-     (e.g. All contacts filter, custom filter, etc.),
-     which is the header of all contact lists. -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/account_filter_header_container"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:paddingTop="@dimen/list_header_extra_top_padding"
-    android:layout_marginLeft="@dimen/contact_browser_list_header_left_margin"
-    android:layout_marginRight="@dimen/contact_browser_list_header_right_margin"
-    android:background="?android:attr/selectableItemBackground"
-    android:visibility="gone">
-    <TextView
-        android:id="@+id/account_filter_header"
-        style="@style/ContactListSeparatorTextViewStyle"
-        android:paddingLeft="@dimen/contact_browser_list_item_text_indent" />
-</LinearLayout>
diff --git a/res/layout/contact_list_content.xml b/res/layout/contact_list_content.xml
deleted file mode 100644
index 362209c..0000000
--- a/res/layout/contact_list_content.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- android:paddingTop is used instead of android:layout_marginTop. It looks
-     android:layout_marginTop is ignored when used with <fragment></fragment>, which
-     only happens in Tablet UI since we rely on ViewPager in Phone UI.
-     Instead, android:layout_marginTop inside <fragment /> is effective. -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/pinned_header_list_layout"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="?attr/contact_browser_background" >
-
-    <!-- Shown only when an Account filter is set.
-         - paddingTop should be here to show "shade" effect correctly. -->
-    <include
-        android:id="@+id/account_filter_header_container"
-        layout="@layout/account_filter_header" />
-
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1" >
-        <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:fastScrollEnabled="true"
-            android:fadingEdge="none" />
-        <ProgressBar
-            android:id="@+id/search_progress"
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:visibility="gone" />
-    </FrameLayout>
-
-    <ViewStub
-        android:id="@+id/footer_stub"
-        android:layout="@layout/footer_panel"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content" />
-
-</LinearLayout>
diff --git a/res/layout/contact_list_filter.xml b/res/layout/contact_list_filter.xml
deleted file mode 100644
index 37aaf53..0000000
--- a/res/layout/contact_list_filter.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:fillViewport="true">
-
-    <ListView
-        android:id="@android:id/list"
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1"
-        android:layout_marginLeft="@dimen/contact_filter_left_margin"
-        android:layout_marginRight="@dimen/contact_filter_right_margin" />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:layout_marginLeft="16dip"
-        android:layout_marginRight="16dip"
-        android:background="?android:attr/dividerHorizontal" />
-</LinearLayout>
diff --git a/res/layout/contact_list_filter_custom.xml b/res/layout/contact_list_filter_custom.xml
deleted file mode 100644
index 40d9c78..0000000
--- a/res/layout/contact_list_filter_custom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/CustomContactListFilterView"
-    android:orientation="vertical"
-    android:fillViewport="true">
-
-    <ExpandableListView
-        android:id="@android:id/list"
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1"
-        android:layout_marginLeft="@dimen/contact_filter_left_margin"
-        android:layout_marginRight="@dimen/contact_filter_right_margin"
-        android:overScrollMode="always" />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:layout_marginLeft="16dip"
-        android:layout_marginRight="16dip"
-        android:background="?android:attr/dividerHorizontal" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        style="?android:attr/buttonBarStyle">
-
-        <Button
-            android:id="@+id/btn_discard"
-            style="?android:attr/buttonBarButtonStyle"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@android:string/cancel" />
-
-        <Button
-            android:id="@+id/btn_done"
-            style="?android:attr/buttonBarButtonStyle"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@android:string/ok" />
-
-    </LinearLayout>
-</LinearLayout>
diff --git a/res/layout/contact_list_filter_item.xml b/res/layout/contact_list_filter_item.xml
deleted file mode 100644
index 7814565..0000000
--- a/res/layout/contact_list_filter_item.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<view
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.contacts.list.ContactListFilterView"
-    android:descendantFocusability="blocksDescendants"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="@dimen/contact_filter_item_min_height"
-    android:gravity="center_vertical">
-
-    <ImageView
-        android:id="@+id/icon"
-        android:scaleType="fitCenter"
-        android:layout_width="@dimen/contact_filter_icon_size"
-        android:layout_height="@dimen/contact_filter_icon_size"/>
-
-    <LinearLayout
-        android:layout_width="0dip"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:orientation="vertical"
-        android:layout_marginLeft="8dip">
-
-        <TextView
-            android:id="@+id/accountType"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:singleLine="true"
-            android:ellipsize="end"/>
-
-        <TextView
-            android:id="@+id/accountUserName"
-            android:layout_marginTop="-3dip"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="?android:attr/textColorTertiary"
-            android:singleLine="true"
-            android:ellipsize="end"/>
-    </LinearLayout>
-
-    <RadioButton
-        android:id="@+id/radioButton"
-        android:clickable="false"
-        android:layout_marginTop="1dip"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="right|center_vertical" />
-</view>
-
diff --git a/res/layout/custom_contact_list_filter_account.xml b/res/layout/custom_contact_list_filter_account.xml
deleted file mode 100644
index 8c1b6c1..0000000
--- a/res/layout/custom_contact_list_filter_account.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:gravity="center_vertical"
-    android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
-    android:paddingRight="?android:attr/scrollbarSize">
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginRight="6dip"
-        android:layout_marginTop="6dip"
-        android:layout_marginBottom="6dip"
-        android:layout_weight="1"
-        android:duplicateParentState="true">
-
-        <TextView
-            android:id="@android:id/text1"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:duplicateParentState="true" />
-
-        <TextView
-            android:id="@android:id/text2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/text1"
-            android:layout_alignLeft="@android:id/text1"
-            android:maxLines="1"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="?android:attr/textColorTertiary"
-            android:duplicateParentState="true" />
-
-    </RelativeLayout>
-
-</LinearLayout>
diff --git a/res/layout/custom_contact_list_filter_group.xml b/res/layout/custom_contact_list_filter_group.xml
deleted file mode 100644
index 65ef405..0000000
--- a/res/layout/custom_contact_list_filter_group.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:gravity="center_vertical"
-    android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
-    android:paddingRight="?android:attr/scrollbarSize"
->
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginRight="6dip"
-        android:layout_marginTop="6dip"
-        android:layout_marginBottom="6dip"
-        android:layout_weight="1"
-        android:duplicateParentState="true"
-    >
-
-        <TextView
-            android:id="@android:id/text1"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:duplicateParentState="true"
-        />
-
-        <TextView
-            android:id="@android:id/text2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/text1"
-            android:layout_alignLeft="@android:id/text1"
-            android:maxLines="2"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:duplicateParentState="true"
-        />
-
-    </RelativeLayout>
-
-    <CheckBox
-        android:id="@android:id/checkbox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginRight="4dip"
-        android:focusable="false"
-        android:clickable="false"
-        android:gravity="center_vertical"
-        android:orientation="vertical"
-        android:duplicateParentState="true"
-    />
-
-</LinearLayout>
diff --git a/res/layout/footer_panel.xml b/res/layout/footer_panel.xml
deleted file mode 100644
index 2625a43..0000000
--- a/res/layout/footer_panel.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/footer"
-    android:orientation="horizontal"
-    android:visibility="gone"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    style="@android:style/ButtonBar"
->
-
-    <Button android:id="@+id/done"
-        android:layout_width="0dip"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:text="@string/menu_done"
-    />
-
-    <Button android:id="@+id/revert"
-        android:layout_width="0dip"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:text="@string/menu_doNotSave"
-    />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0d64a04..51a70fd 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -286,7 +286,7 @@
     <string name="display_options_view_given_name_first" msgid="6968288511197363292">"이름 먼저 표시"</string>
     <string name="display_options_view_family_name_first" msgid="1447288164951453714">"성 먼저 표시"</string>
     <string name="take_photo" msgid="7496128293167402354">"사진 찍기"</string>
-    <string name="take_new_photo" msgid="7341354729436576304">"새 사진 가져오기"</string>
+    <string name="take_new_photo" msgid="7341354729436576304">"새 사진 찍기"</string>
     <string name="pick_photo" msgid="3746334626214970837">"갤러리에서 사진 선택"</string>
     <string name="pick_new_photo" msgid="7962368009197147617">"갤러리에서 새 사진 선택"</string>
     <string name="locale_change_in_progress" msgid="7583992153091537467">"변경된 언어를 반영하도록 주소록을 업데이트하는 중입니다. 잠시 기다려 주세요."</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index c25610a..d13000f 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -139,13 +139,13 @@
     <string name="simContacts_title" msgid="27341688347689769">"Kontakter från SIM-kort"</string>
     <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Du har inga kontakter att visa. (Om du nyss lade till ett konto kan det ta några minuter innan kontakterna synkroniserats.)"</string>
     <string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Du har inga kontakter att visa."</string>
-    <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"Det finns inga kontakter att visa."\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som du kan synkronisera med pekdatorn"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SIM- eller SD-kortet"\n</li></string>
+    <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"Det finns inga kontakter att visa."\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som du kan synkronisera med surfplattan"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SIM- eller SD-kortet"\n</li></string>
     <string name="noContactsHelpText" product="default" msgid="4405064135698982080">"Det finns inga kontakter att visa."\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som du kan synkronisera med mobilen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SIM- eller SD-kortet"\n</li></string>
     <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"Det finns inga kontakter att visa (Om du nyss har lagt till ett konto kan det ta några minuter att synkronisera kontakterna.)"\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som kan synkroniseras med pekdatorn"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativ"</b></font>" om du vill ändra vilka kontakter som är synliga"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SIM- eller SD-kortet"\n</li></string>
     <string name="noContactsHelpTextWithSync" product="default" msgid="7016825676090327312">"Det finns inga kontakter att visa (Om du nyss har lagt till ett konto kan det ta några minuter att synkronisera kontakterna.)"\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som kan synkroniseras med mobilen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativ"</b></font>" om du vill ändra vilka kontakter som är synliga"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SIM- eller SD-kortet"\n</li></string>
-    <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"Det finns inga kontakter att visa."\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som du kan synkronisera med pekdatorn"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SD-kortet"\n</li></string>
+    <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"Det finns inga kontakter att visa."\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som du kan synkronisera med surfplattan"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SD-kortet"\n</li></string>
     <string name="noContactsNoSimHelpText" product="default" msgid="6224952277619986841">"Det finns inga kontakter att visa."\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som du kan synkronisera med mobilen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SD-kortet"\n</li></string>
-    <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"Det finns inga kontakter att visa. (Om du nyss har lagt till ett konto kan det ta några minuter att synkronisera kontakterna.)"\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som kan synkroniseras med pekdatorn"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativ"</b></font>" om du vill ändra vilka kontakter som är synliga"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>"om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SD-kortet"\n</li></string>
+    <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"Det finns inga kontakter att visa. (Om du nyss har lagt till ett konto kan det ta några minuter att synkronisera kontakterna.)"\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som kan synkroniseras med surfplattan"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativ"</b></font>" om du vill ändra vilka kontakter som är synliga"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>"om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SD-kortet"\n</li></string>
     <string name="noContactsNoSimHelpTextWithSync" product="default" msgid="7443705129830284440">"Det finns inga kontakter att visa. (Om du nyss har lagt till ett konto kan det ta några minuter att synkronisera kontakterna.)"\n\n"Om du vill lägga till kontakter trycker du på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" och sedan på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Konton"</b></font>" om du vill lägga till eller konfigurera ett konto med kontakter som kan synkroniseras med mobilen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativ"</b></font>" om du vill ändra vilka kontakter som är synliga"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" om du vill skapa en ny kontakt från grunden"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importera/exportera"</b></font>" om du vill importera kontakter från SD-kortet"\n</li></string>
     <string name="noFavoritesHelpText" msgid="3744655776704833277">"Du har inte några favoriter."\n\n"Så här lägger du till kontakter i favoritlistan:"\n\n"        "<li>"Tryck på fliken "<b>"Kontakter"</b>\n</li>" "\n<li>"Tryck på den kontakt du vill lägga till i favoriterna"\n</li>" "\n<li>"Tryck på stjärnan bredvid kontaktens namn"\n</li></string>
     <string name="dialer_useDtmfDialpad" msgid="1707548397435075040">"Använda tonvalstelefon"</string>
diff --git a/res/values-sw580dp/dimens.xml b/res/values-sw580dp/dimens.xml
index d3a9bea..4c4505c 100644
--- a/res/values-sw580dp/dimens.xml
+++ b/res/values-sw580dp/dimens.xml
@@ -31,8 +31,6 @@
     <dimen name="quick_contact_top_position">-1px</dimen>
     <!-- Contact list (vertical scroll bar comes left) -->
     <dimen name="contact_browser_list_top_margin">16dip</dimen>
-    <dimen name="contact_browser_list_header_left_margin">@dimen/list_visible_scrollbar_padding</dimen>
-    <dimen name="contact_browser_list_header_right_margin">24dip</dimen>
     <dimen name="list_visible_scrollbar_padding">32dip</dimen>
     <dimen name="list_header_extra_top_padding">@dimen/contact_browser_list_top_margin</dimen>
 
diff --git a/res/values-sw580dp/styles.xml b/res/values-sw580dp/styles.xml
index 1181d5d..ce0ec15 100644
--- a/res/values-sw580dp/styles.xml
+++ b/res/values-sw580dp/styles.xml
@@ -97,16 +97,6 @@
         <item name="android:windowSoftInputMode">adjustUnspecified</item>
     </style>
 
-    <style name="ContactListFilterTheme" parent="@android:Theme.Holo.Light.Dialog">
-        <item name="android:windowCloseOnTouchOutside">true</item>
-        <item name="android:listViewStyle">@style/ListViewStyle</item>
-    </style>
-
-    <style name="CustomContactListFilterView" parent="ContactListFilterTheme">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">400dip</item>
-    </style>
-
     <style name="DetailActivityTheme" parent="@android:Theme.Dialog">
         <item name="android:windowContentOverlay">@null</item>
     </style>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 9f8ce83..d7845c4 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -56,12 +56,6 @@
         <attr name="ratio" format="float"/>
     </declare-styleable>
 
-    <declare-styleable name="ContactBrowser">
-        <attr name="contact_browser_list_padding_left" format="dimension"/>
-        <attr name="contact_browser_list_padding_right" format="dimension"/>
-        <attr name="contact_browser_background" format="reference"/>
-    </declare-styleable>
-
     <declare-styleable name="Favorites">
         <attr name="favorites_padding_bottom" format="dimension" />
     </declare-styleable>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 7a99cc3..99e917b 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -14,10 +14,6 @@
      limitations under the License.
 -->
 <resources>
-    <color name="textColorIconOverlay">#fff</color>
-    <color name="textColorIconOverlayShadow">#000</color>
-
-    <color name="shortcut_overlay_text_background">#7f000000</color>
 
     <color name="quickcontact_list_divider">#ffcdcdcd</color>
     <color name="quickcontact_list_background">#ffe2e2e2</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d22bf64..aaad313 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -91,27 +91,12 @@
          (phone number, email, etc.) and a secondary action button -->
     <dimen name="detail_vertical_divider_vertical_margin">16dip</dimen>
 
-    <!-- Padding to be used between a visible scrollbar and the contact list -->
-    <dimen name="list_visible_scrollbar_padding">32dip</dimen>
-
     <!-- Font size used for the contact name in the widget -->
     <dimen name="widget_text_size_name">14sp</dimen>
 
     <!-- Font size used for the social status in the widget -->
     <dimen name="widget_text_size_snippet">13sp</dimen>
 
-    <!-- Size of the shortcut icon. 0dip means: use the system default -->
-    <dimen name="shortcut_icon_size">0dip</dimen>
-
-    <!-- Width of darkened border for shortcut icon -->
-    <dimen name="shortcut_icon_border_width">1dp</dimen>
-
-    <!-- Text size of shortcut icon overlay text -->
-    <dimen name="shortcut_overlay_text_size">12dp</dimen>
-
-    <!-- Extra vertical padding for darkened background behind shortcut icon overlay text -->
-    <dimen name="shortcut_overlay_text_background_padding">1dp</dimen>
-
     <!-- Height of list sections (A, B, C) that show the first character of the contacts -->
     <dimen name="list_section_height">25dip</dimen>
 
@@ -143,10 +128,7 @@
     <dimen name="search_view_width">0dip</dimen>
 
     <!-- contact browser list margins -->
-    <dimen name="contact_browser_list_header_left_margin">16dip</dimen>
-    <dimen name="contact_browser_list_header_right_margin">@dimen/list_visible_scrollbar_padding</dimen>
     <dimen name="contact_browser_list_item_photo_size">64dip</dimen>
-    <dimen name="contact_browser_list_item_text_indent">8dip</dimen>
     <dimen name="contact_browser_list_top_margin">8dip</dimen>
     <!-- For join screen. Mainly for tablet. -->
     <dimen name="join_header_left_margin">@dimen/contact_browser_list_header_left_margin</dimen>
@@ -158,11 +140,6 @@
     <dimen name="empty_message_top_margin">48dip</dimen>
     <dimen name="no_accounts_message_margin">20dip</dimen>
 
-    <!-- For contact filter setting screens -->
-    <dimen name="contact_filter_left_margin">16dip</dimen>
-    <dimen name="contact_filter_right_margin">16dip</dimen>
-    <dimen name="contact_filter_item_min_height">48dip</dimen>
-    <dimen name="contact_filter_icon_size">32dip</dimen>
     <dimen name="contact_filter_header_min_height">24dip</dimen>
 
     <!--  Width of the lead margin on the left of a block quote inside a stream item -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4a84751..aadd05c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -184,12 +184,6 @@
     <!-- Confirmation dialog contents after users selects to delete a Writable contact. -->
     <string name="deleteConfirmation">This contact will be deleted.</string>
 
-    <!-- Menu item to indicate you are done editing a contact and want to save the changes you've made -->
-    <string name="menu_done">Done</string>
-
-    <!-- Menu item to indicate you want to cancel the current editing process and NOT save the changes you've made [CHAR LIMIT=12] -->
-    <string name="menu_doNotSave">Cancel</string>
-
     <!-- Menu item to indicate you want to stop editing a contact and NOT save the changes you've made [CHAR LIMIT=12] -->
     <string name="menu_discard">Discard</string>
 
@@ -246,12 +240,6 @@
     <!-- The text displayed when the groups list is empty and no accounts are set on the device while displaying all groups [CHAR LIMIT=NONE] -->
     <string name="noAccounts">To create groups you need an account.</string>
 
-    <!-- The text displayed when the contacts list is empty while displaying results after searching contacts -->
-    <string name="noMatchingContacts">No matching contacts found.</string>
-
-    <!-- The text displayed when the contacts list is empty while displaying only contacts that have phone numbers -->
-    <string name="noContactsWithPhoneNumbers">No contacts with phone numbers.</string>
-
     <!-- The text displayed when there are no members in the group while displaying the group detail page [CHAR LIMIT=40] -->
     <string name="emptyGroup">No people in this group.</string>
 
@@ -261,9 +249,6 @@
     <!-- Displayed in a spinner dialog after the user creates a contact and it's being saved to the database -->
     <string name="savingContact">Saving contact\u2026</string>
 
-    <!-- Displayed in a spinner dialog as user changes to display options are saved -->
-    <string name="savingDisplayGroups">Saving display options\u2026</string>
-
     <!-- Toast displayed when a contact is saved [CHAR LIMIT=NONE] -->
     <string name="contactSavedToast">Contact saved.</string>
 
@@ -303,15 +288,6 @@
     <!-- Displayed at the top of the contacts showing the zero total number of contacts visible when a group or account is selected  [CHAR LIMIT=64]-->
     <string name="listTotalAllContactsZeroGroup">No contacts in <xliff:g id="name" example="Friends">%s</xliff:g></string>
 
-    <!-- Displayed at the top of the contacts showing the account filter selected  [CHAR LIMIT=64] -->
-    <string name="listAllContactsInAccount">Contacts in <xliff:g id="name" example="abc@gmail.com">%s</xliff:g></string>
-
-    <!-- Displayed at the top of the contacts showing single contact. [CHAR LIMIT=64] -->
-    <string name="listSingleContact">Single contact</string>
-
-    <!-- Displayed at the top of the contacts showing single contact. [CHAR LIMIT=64] -->
-    <string name="listCustomView">Contacts in custom view</string>
-
     <!-- Displayed at the top of the contacts showing the total number of contacts found when "Only contacts with phones" not selected [CHAR LIMIT=30] -->
     <plurals name="listFoundAllContacts">
         <item quantity="one">1 found</item>
@@ -386,75 +362,6 @@
     <!-- Dialog title displayed when loading a phone number from the SIM card for speed dial -->
     <string name="simContacts_title">SIM card contacts</string>
 
-    <!-- Displayed full screen when the user want to create a shortcut, but there is no contacts, and contact syncing is enabled -->
-    <string name="noContactsHelpTextWithSyncForCreateShortcut">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)"</string>
-
-    <!-- Displayed full screen when the user want to create a shortcut, but there is no contacts -->
-    <string name="noContactsHelpTextForCreateShortcut">"You don't have any contacts to display."</string>
-
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled.  [CHAR LIMIT=NONE] -->
-    <string name="noContactsHelpText" product="tablet">"You don't have any contacts to display.\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the tablet\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/export</b></font> to import contacts from your SIM or SD card\n</li>"
-    </string>
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled.  [CHAR LIMIT=NONE] -->
-    <string name="noContactsHelpText" product="default">"You don't have any contacts to display.\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the phone\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SIM or SD card\n</li>"
-    </string>
-
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled.  [CHAR LIMIT=NONE] -->
-    <string name="noContactsHelpTextWithSync" product="tablet">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the tablet\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Display options</b></font> to change which contacts are visible\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SIM or SD card\n</li>"
-    </string>
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled.  [CHAR LIMIT=NONE] -->
-    <string name="noContactsHelpTextWithSync" product="default">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the phone\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Display options</b></font> to change which contacts are visible\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SIM or SD card\n</li>"
-    </string>
-
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled, and there is no sim card (cdma).  [CHAR LIMIT=NONE]-->
-    <string name="noContactsNoSimHelpText" product="tablet">"You don't have any contacts to display.\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the tablet\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SD card\n</li>"
-    </string>
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled, and there is no sim card (cdma).  [CHAR LIMIT=NONE]-->
-    <string name="noContactsNoSimHelpText" product="default">"You don't have any contacts to display.\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the phone\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SD card\n</li>"
-    </string>
-
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled, and there is no sim card (cdma).  [CHAR LIMIT=NONE] -->
-    <string name="noContactsNoSimHelpTextWithSync" product="tablet">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the tablet\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Display options</b></font> to change which contacts are visible\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SD card\n</li>"
-    </string>
-    <!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled, and there is no sim card (cdma).  [CHAR LIMIT=NONE] -->
-    <string name="noContactsNoSimHelpTextWithSync" product="default">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, touch <font fgcolor="#ffffffff"><b>Menu</b></font>, then touch:\n
-        \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or set up an account with contacts you can sync to the phone\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Display options</b></font> to change which contacts are visible\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
-        \n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font> to import contacts from your SD card\n</li>"
-    </string>
-
-    <!-- Displayed full screen when the user has no favorites and they are displaying the favorites tab. [CHAR LIMIT=NONE] -->
-    <string name="noFavoritesHelpText">"You don't have any favorites.\n\nTo add a contact to your list of favorites:\n
-        <li>Touch the <b>Contacts</b> tab\n</li>
-        \n<li>Touch the contact you want to add to your favorites\n</li>
-        \n<li>Touch the star next to the contact\'s name\n</li>"
-    </string>
-
     <!-- Item label: jump to the in-call DTMF dialpad.
          (Part of a list of options shown in the dialer when another call
          is already in progress.) -->
@@ -917,21 +824,6 @@
     <!-- Title for the disambiguation dialog that requests the user choose an account for the new group to be created under [CHAR LIMIT=NONE] -->
     <string name="dialog_new_group_account">Create group under account</string>
 
-    <string name="menu_sync_remove">Remove sync group</string>
-    <string name="dialog_sync_add">Add sync group</string>
-    <string name="display_more_groups">More groups\u2026</string>
-
-    <!-- List title for a special contacts group that covers all contacts. [CHAR LIMIT=25] -->
-    <string name="display_ungrouped">All other contacts</string>
-
-    <!-- List title for a special contacts group that covers all contacts that
-         aren't members of any other group. [CHAR LIMIT=25] -->
-    <string name="display_all_contacts">All contacts</string>
-
-    <!-- Warning message given to users just before they remove a currently syncing
-         group that would also cause all ungrouped contacts to stop syncing.  [CHAR LIMIT=NONE] -->
-    <string name="display_warn_remove_ungrouped">Removing \"<xliff:g id="group" example="Starred">%s</xliff:g>\" from sync will also remove any ungrouped contacts from sync.</string>
-
     <!-- Generic action string for starting an audio chat. Used by AccessibilityService to announce the purpose of the view. [CHAR LIMIT=NONE] -->
     <string name="audio_chat">Voice chat</string>
     <!-- Generic action string for starting a video chat. Used by AccessibilityService to announce the purpose of the view. [CHAR LIMIT=NONE] -->
@@ -1029,9 +921,6 @@
     <!-- Label to clear all selection in multiple picker -->
     <string name="menu_select_none">"Unselect all"</string>
 
-    <!-- The text displayed when the contacts list is empty while displaying only selected contacts in multiple picker -->
-    <string name="no_contacts_selected">"No contacts selected."</string>
-
     <!-- The add field button shown in the editor under each editable Raw Contact [CHAR LIMIT=30] -->
     <string name="add_field">Add another field</string>
 
@@ -1094,21 +983,9 @@
     <!-- Toast shown when creating a personal copy of a contact [CHAR LIMIT=100] -->
     <string name="toast_making_personal_copy">Creating a personal copy\u2026</string>
 
-    <!-- Contact list filter label indicating that the list is showing all available accounts [CHAR LIMIT=64] -->
-    <string name="list_filter_all_accounts">All contacts</string>
-
-    <!-- Contact list filter label indicating that the list is showing all starred contacts [CHAR LIMIT=64] -->
-    <string name="list_filter_all_starred">Starred</string>
-
     <!-- Contact list filter indicating that the list shows groups chosen by the user [CHAR LIMIT=64] -->
     <string name="list_filter_custom">Custom</string>
 
-    <!-- Contact list filter selection indicating that the list shows groups chosen by the user [CHAR LIMIT=64] -->
-    <string name="list_filter_customize">Customize</string>
-
-    <!-- Contact list filter selection indicating that the list shows only the selected contact [CHAR LIMIT=64] -->
-    <string name="list_filter_single">Contact</string>
-
     <!-- Title of the activity that allows the user to customize filtering of contact list [CHAR LIMIT=128] -->
     <string name="custom_list_filter">Define custom view</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 3d7da37..6208018 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -126,10 +126,6 @@
         <item name="android:listSelector">?android:attr/listChoiceBackgroundIndicator</item>
     </style>
 
-    <style name="ListViewStyle" parent="@android:style/Widget.Holo.Light.ListView">
-        <item name="android:overScrollMode">always</item>
-    </style>
-
     <style name="ContactPickerTheme" parent="@style/PeopleTheme" />
 
     <style name="ContactPickerLayout" parent="ContactPickerTheme">
@@ -148,11 +144,6 @@
         <item name="android:listViewStyle">@style/ListViewStyle</item>
     </style>
 
-    <style name="CustomContactListFilterView" parent="ContactListFilterTheme">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">match_parent</item>
-    </style>
-
     <style name="NonPhoneActivityTheme" parent="@android:Theme.Translucent.NoTitleBar">
     </style>
 
diff --git a/src/com/android/contacts/ContactListEmptyView.java b/src/com/android/contacts/ContactListEmptyView.java
deleted file mode 100644
index 40d5152..0000000
--- a/src/com/android/contacts/ContactListEmptyView.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentService;
-import android.os.RemoteException;
-import android.provider.ContactsContract;
-import android.telephony.TelephonyManager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-/**
- * Displays a message when there is nothing to display in a contact list.
- */
-public class ContactListEmptyView extends ScrollView {
-
-    private static final String TAG = "ContactListEmptyView";
-
-    public ContactListEmptyView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void hide() {
-        TextView empty = (TextView) findViewById(R.id.emptyText);
-        empty.setVisibility(GONE);
-    }
-
-    public void show(boolean searchMode, boolean displayOnlyPhones,
-            boolean isFavoritesMode, boolean isQueryMode, boolean isShortcutAction,
-            boolean isMultipleSelectionEnabled, boolean showSelectedOnly) {
-        if (searchMode) {
-            return;
-        }
-
-        TextView empty = (TextView) findViewById(R.id.emptyText);
-        Context context = getContext();
-        if (displayOnlyPhones) {
-            empty.setText(context.getText(R.string.noContactsWithPhoneNumbers));
-        } else if (isFavoritesMode) {
-            empty.setText(context.getText(R.string.noFavoritesHelpText));
-        } else if (isQueryMode) {
-            empty.setText(context.getText(R.string.noMatchingContacts));
-        } if (isMultipleSelectionEnabled) {
-            if (showSelectedOnly) {
-                empty.setText(context.getText(R.string.no_contacts_selected));
-            } else {
-                empty.setText(context.getText(R.string.noContactsWithPhoneNumbers));
-            }
-        } else {
-            TelephonyManager telephonyManager =
-                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-            boolean hasSim = telephonyManager.hasIccCard();
-            if (isSyncActive()) {
-                if (isShortcutAction) {
-                    // Help text is the same no matter whether there is SIM or not.
-                    empty.setText(
-                            context.getText(R.string.noContactsHelpTextWithSyncForCreateShortcut));
-                } else if (hasSim) {
-                    empty.setText(context.getText(R.string.noContactsHelpTextWithSync));
-                } else {
-                    empty.setText(context.getText(R.string.noContactsNoSimHelpTextWithSync));
-                }
-            } else {
-                if (isShortcutAction) {
-                    // Help text is the same no matter whether there is SIM or not.
-                    empty.setText(context.getText(R.string.noContactsHelpTextForCreateShortcut));
-                } else if (hasSim) {
-                    empty.setText(context.getText(R.string.noContactsHelpText));
-                } else {
-                    empty.setText(context.getText(R.string.noContactsNoSimHelpText));
-                }
-            }
-        }
-        empty.setVisibility(VISIBLE);
-    }
-
-    private boolean isSyncActive() {
-        Account[] accounts = AccountManager.get(getContext()).getAccounts();
-        if (accounts != null && accounts.length > 0) {
-            IContentService contentService = ContentResolver.getContentService();
-            for (Account account : accounts) {
-                try {
-                    if (contentService.isSyncActive(account, ContactsContract.AUTHORITY)) {
-                        return true;
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Could not get the sync status");
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 64d5531..d87a1a0 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -47,7 +47,7 @@
 import android.widget.Toast;
 
 import com.android.contacts.common.database.ContactUpdateUtils;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.RawContactDelta;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index ef07cf9..82b2a25 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -30,8 +30,8 @@
 import android.util.Log;
 
 import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.list.ContactListFilterController;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.test.InjectedServices;
 import com.android.contacts.common.util.Constants;
 import com.google.common.annotations.VisibleForTesting;
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 57976e5..b68109e 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -26,7 +26,7 @@
 
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.test.NeededForTesting;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 
 import java.util.List;
 
diff --git a/src/com/android/contacts/SplitAggregateView.java b/src/com/android/contacts/SplitAggregateView.java
index fabd58b..6e38549 100644
--- a/src/com/android/contacts/SplitAggregateView.java
+++ b/src/com/android/contacts/SplitAggregateView.java
@@ -35,7 +35,7 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 
 import java.util.ArrayList;
diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index 54f2de8..c0a751c 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -39,6 +39,7 @@
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.util.ContactPhotoUtils;
 
 import java.io.File;
@@ -195,7 +196,7 @@
         // the ContactSaveService would not create the new contact, and the
         // full-res photo would fail to be saved to the non-existent contact.
         AccountType account = raw.getRawContactAccountType(this);
-        RawContactDelta.ValuesDelta values =
+        ValuesDelta values =
                 RawContactModifier.ensureKindExists(raw, account, Photo.CONTENT_ITEM_TYPE);
         if (values == null) {
             Log.w(TAG, "cannot attach photo to this account type");
diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
index 9bd4f45..ae4cf94 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -61,17 +61,17 @@
 import com.android.contacts.R;
 import com.android.contacts.editor.Editor;
 import com.android.contacts.editor.ViewIdGenerator;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.RawContact;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.util.DialogManager;
-import com.android.contacts.util.EmptyService;
+import com.android.contacts.common.util.EmptyService;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
diff --git a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
index 13c49e1..26a8eae 100644
--- a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
@@ -30,7 +30,7 @@
 
 import com.android.contacts.R;
 import com.android.contacts.editor.ContactEditorUtils;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.util.AccountsListAdapter;
 import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index efdf7da..d12da85 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -36,7 +36,7 @@
 import com.android.contacts.R;
 import com.android.contacts.editor.ContactEditorFragment;
 import com.android.contacts.editor.ContactEditorFragment.SaveMode;
-import com.android.contacts.model.AccountTypeManager;
+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.util.DialogManager;
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index 6822494..b527f84 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -250,7 +250,7 @@
     }
 
     private void configureActivityTitle() {
-        if (mRequest.getActivityTitle() != null) {
+        if (!TextUtils.isEmpty(mRequest.getActivityTitle())) {
             setTitle(mRequest.getActivityTitle());
             return;
         }
@@ -527,16 +527,6 @@
     }
 
     @Override
-    public boolean onContextItemSelected(MenuItem item) {
-        ContextMenuAdapter menuAdapter = mListFragment.getContextMenuAdapter();
-        if (menuAdapter != null) {
-            return menuAdapter.onContextItemSelected(item);
-        }
-
-        return super.onContextItemSelected(item);
-    }
-
-    @Override
     public boolean onQueryTextChange(String newText) {
         mListFragment.setQueryString(newText, true);
         return false;
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index c2764c3..c24a42f 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -33,7 +33,7 @@
 import com.android.contacts.R;
 import com.android.contacts.group.GroupDetailDisplayUtils;
 import com.android.contacts.group.GroupDetailFragment;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 
 public class GroupDetailActivity extends ContactsActivity {
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 3a3bdc3..04f0621 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -66,7 +66,7 @@
 import com.android.contacts.list.ContactBrowseListFragment;
 import com.android.contacts.list.ContactEntryListFragment;
 import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.list.ContactListFilterController;
+import com.android.contacts.common.list.ContactListFilterController;
 import com.android.contacts.common.list.ContactTileAdapter.DisplayType;
 import com.android.contacts.list.ContactTileFrequentFragment;
 import com.android.contacts.list.ContactTileListFragment;
@@ -83,7 +83,7 @@
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.preference.ContactsPreferenceActivity;
 import com.android.contacts.preference.DisplayOptionsPreferenceFragment;
-import com.android.contacts.util.AccountFilterUtil;
+import com.android.contacts.common.util.AccountFilterUtil;
 import com.android.contacts.util.AccountPromptUtils;
 import com.android.contacts.common.util.Constants;
 import com.android.contacts.util.DialogManager;
@@ -323,7 +323,6 @@
             startActivity(redirect);
             return false;
         }
-        setTitle(mRequest.getActivityTitle());
         return true;
     }
 
@@ -1245,7 +1244,8 @@
 
         @Override
         public void onImportContactsFromFileAction() {
-            ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable());
+            ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable(),
+                    PeopleActivity.class);
         }
 
         @Override
@@ -1535,7 +1535,8 @@
                 return true;
             }
             case R.id.menu_import_export: {
-                ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable());
+                ImportExportDialogFragment.show(getFragmentManager(), areContactsAvailable(),
+                        PeopleActivity.class);
                 return true;
             }
             case R.id.menu_clear_frequents: {
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index fa71e72..e4af9b8 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -82,11 +82,11 @@
 import com.android.contacts.common.GeoUtil;
 import com.android.contacts.common.MoreContactUtils;
 import com.android.contacts.editor.SelectAccountDialogFragment;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.Contact;
 import com.android.contacts.model.RawContact;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
@@ -1866,6 +1866,11 @@
         menu.add(ContextMenu.NONE, ContextMenuIds.COPY_TEXT,
                 ContextMenu.NONE, getString(R.string.copy_text));
 
+        // Don't allow setting or clearing of defaults for directory contacts
+        if (mContactData.isDirectoryEntry()) {
+            return;
+        }
+
         String selectedMimeType = selectedEntry.mimetype;
 
         // Defaults to true will only enable the detail to be copied to the clipboard.
diff --git a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
index 46e4dad..b578d28 100644
--- a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
@@ -31,7 +31,7 @@
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
 import com.android.contacts.detail.ContactDetailDisplayUtils.StreamPhotoTag;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.Contact;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.util.StreamItemEntry;
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index c23e239..a239d47 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -42,8 +42,8 @@
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
-import com.android.contacts.list.ShortcutIntentBuilder;
-import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
+import com.android.contacts.common.list.ShortcutIntentBuilder;
+import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
 import com.android.contacts.model.Contact;
 import com.android.contacts.model.ContactLoader;
 import com.android.contacts.util.PhoneCapabilityTester;
diff --git a/src/com/android/contacts/detail/PhotoSelectionHandler.java b/src/com/android/contacts/detail/PhotoSelectionHandler.java
index d544b30..3f913f2 100644
--- a/src/com/android/contacts/detail/PhotoSelectionHandler.java
+++ b/src/com/android/contacts/detail/PhotoSelectionHandler.java
@@ -39,10 +39,10 @@
 
 import com.android.contacts.R;
 import com.android.contacts.editor.PhotoActionPopup;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.util.ContactPhotoUtils;
diff --git a/src/com/android/contacts/detail/StreamItemAdapter.java b/src/com/android/contacts/detail/StreamItemAdapter.java
index 398ac69..5c827dc 100644
--- a/src/com/android/contacts/detail/StreamItemAdapter.java
+++ b/src/com/android/contacts/detail/StreamItemAdapter.java
@@ -23,7 +23,7 @@
 import android.widget.BaseAdapter;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.util.StreamItemEntry;
 import com.google.common.collect.Lists;
diff --git a/src/com/android/contacts/editor/AggregationSuggestionEngine.java b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
index 0da05e8..2f77858 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionEngine.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
@@ -37,7 +37,7 @@
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
 
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index 19481fe..439b1df 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -28,7 +28,7 @@
 import com.android.contacts.R;
 import com.android.contacts.editor.AggregationSuggestionEngine.RawContact;
 import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.google.common.collect.Lists;
 
diff --git a/src/com/android/contacts/editor/BaseRawContactEditorView.java b/src/com/android/contacts/editor/BaseRawContactEditorView.java
index 1ff9ac2..c39d472 100644
--- a/src/com/android/contacts/editor/BaseRawContactEditorView.java
+++ b/src/com/android/contacts/editor/BaseRawContactEditorView.java
@@ -29,7 +29,7 @@
 
 import com.android.contacts.R;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountType.EditType;
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index b019542..4f6aad5 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -70,12 +70,12 @@
 import com.android.contacts.detail.PhotoSelectionHandler;
 import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
 import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.Contact;
 import com.android.contacts.model.ContactLoader;
 import com.android.contacts.model.RawContact;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
diff --git a/src/com/android/contacts/editor/ContactEditorUtils.java b/src/com/android/contacts/editor/ContactEditorUtils.java
index 735f8be..dfbcc6b 100644
--- a/src/com/android/contacts/editor/ContactEditorUtils.java
+++ b/src/com/android/contacts/editor/ContactEditorUtils.java
@@ -27,7 +27,7 @@
 import android.util.Log;
 
 import com.android.contacts.common.test.NeededForTesting;
-import com.android.contacts.model.AccountTypeManager;
+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.google.common.annotations.VisibleForTesting;
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index ec816f7..12ea201 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -19,7 +19,7 @@
 import android.provider.ContactsContract.Data;
 
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 
 /**
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 1f6cd43..9c91ff8 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -30,7 +30,7 @@
 import com.android.contacts.datepicker.DatePickerDialog;
 import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType.EditField;
 import com.android.contacts.common.model.account.AccountType.EventEditType;
 import com.android.contacts.common.model.dataitem.DataKind;
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index 97257f1..ab7895c 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -41,7 +41,7 @@
 import com.android.contacts.interactions.GroupCreationDialogFragment;
 import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCreatedListener;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactModifier;
 import com.google.common.base.Objects;
 
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index 4f70cd4..a119cb2 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -30,7 +30,7 @@
 import com.android.contacts.editor.Editor.EditorListener;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 
 import java.util.ArrayList;
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 91339ae..dc7664d 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -47,7 +47,7 @@
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType.EditType;
 import com.android.contacts.common.model.dataitem.DataKind;
diff --git a/src/com/android/contacts/editor/PhoneticNameEditorView.java b/src/com/android/contacts/editor/PhoneticNameEditorView.java
index 1ee7e21..2836c721 100644
--- a/src/com/android/contacts/editor/PhoneticNameEditorView.java
+++ b/src/com/android/contacts/editor/PhoneticNameEditorView.java
@@ -22,7 +22,7 @@
 import android.util.AttributeSet;
 
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.model.dataitem.StructuredNameDataItem;
 
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index e106eac..652c8e6 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -28,7 +28,7 @@
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.util.ContactPhotoUtils;
 
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 27f2ce4..c79ba2f 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -42,7 +42,7 @@
 import com.android.contacts.common.model.account.AccountType.EditType;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactModifier;
 import com.google.common.base.Objects;
 
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index 8f9dcb9..edfd372 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -41,7 +41,7 @@
 import com.android.contacts.common.GeoUtil;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.model.dataitem.DataKind;
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index fcafe75..f709021 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -26,7 +26,7 @@
 import android.util.AttributeSet;
 
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.dataitem.DataItem;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.model.dataitem.StructuredNameDataItem;
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 970bbbf..0c52a2a 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -38,7 +38,7 @@
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType.EditField;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.common.util.PhoneNumberFormatter;
diff --git a/src/com/android/contacts/editor/ViewIdGenerator.java b/src/com/android/contacts/editor/ViewIdGenerator.java
index 9f41623..8494e1a 100644
--- a/src/com/android/contacts/editor/ViewIdGenerator.java
+++ b/src/com/android/contacts/editor/ViewIdGenerator.java
@@ -21,7 +21,7 @@
 import android.os.Parcelable;
 
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 
 /**
diff --git a/src/com/android/contacts/group/GroupBrowseListAdapter.java b/src/com/android/contacts/group/GroupBrowseListAdapter.java
index f96b40d..32296c2 100644
--- a/src/com/android/contacts/group/GroupBrowseListAdapter.java
+++ b/src/com/android/contacts/group/GroupBrowseListAdapter.java
@@ -30,7 +30,7 @@
 import com.android.contacts.GroupListLoader;
 import com.android.contacts.R;
 import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.google.common.base.Objects;
 
 /**
diff --git a/src/com/android/contacts/group/GroupDetailDisplayUtils.java b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
index 1cf7831..fb0b0c8 100644
--- a/src/com/android/contacts/group/GroupDetailDisplayUtils.java
+++ b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
@@ -23,7 +23,7 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 
 public class GroupDetailDisplayUtils {
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index 3ab6bc8..69d5165 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -53,7 +53,7 @@
 import com.android.contacts.common.list.ContactTileAdapter;
 import com.android.contacts.common.list.ContactTileView;
 import com.android.contacts.list.GroupMemberTileAdapter;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 
 /**
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index 20a3334..16b7d86 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -68,7 +68,7 @@
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.editor.SelectAccountDialogFragment;
 import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
 import com.android.contacts.util.ViewUtil;
 import com.google.common.base.Objects;
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index c4387f3..2880f77 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -35,7 +35,7 @@
 
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Sets;
diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
index 3f409cb..99b3463 100644
--- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
@@ -39,11 +39,12 @@
 
 import com.android.contacts.R;
 import com.android.contacts.editor.SelectAccountDialogFragment;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.util.AccountSelectionUtil;
 import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
 import com.android.contacts.vcard.ExportVCardActivity;
+import com.android.contacts.vcard.VCardCommonArguments;
 
 import java.util.List;
 
@@ -62,10 +63,12 @@
     };
 
     /** Preferred way to show this dialog */
-    public static void show(FragmentManager fragmentManager, boolean contactsAreAvailable) {
+    public static void show(FragmentManager fragmentManager, boolean contactsAreAvailable,
+            Class callingActivity) {
         final ImportExportDialogFragment fragment = new ImportExportDialogFragment();
         Bundle args = new Bundle();
         args.putBoolean(ARG_CONTACTS_ARE_AVAILABLE, contactsAreAvailable);
+        args.putString(VCardCommonArguments.ARG_CALLING_ACTIVITY, callingActivity.getName());
         fragment.setArguments(args);
         fragment.show(fragmentManager, ImportExportDialogFragment.TAG);
     }
@@ -77,6 +80,8 @@
         final LayoutInflater dialogInflater = (LayoutInflater)getActivity()
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         final boolean contactsAreAvailable = getArguments().getBoolean(ARG_CONTACTS_ARE_AVAILABLE);
+        final String callingActivity = getArguments().getString(
+                VCardCommonArguments.ARG_CALLING_ACTIVITY);
 
         // Adapter that shows a list of string resources
         final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(getActivity(),
@@ -125,6 +130,8 @@
                     case R.string.export_to_sdcard: {
                         dismissDialog = true;
                         Intent exportIntent = new Intent(getActivity(), ExportVCardActivity.class);
+                        exportIntent.putExtra(VCardCommonArguments.ARG_CALLING_ACTIVITY,
+                                callingActivity);
                         getActivity().startActivity(exportIntent);
                         break;
                     }
diff --git a/src/com/android/contacts/list/AccountFilterActivity.java b/src/com/android/contacts/list/AccountFilterActivity.java
deleted file mode 100644
index cc986ad..0000000
--- a/src/com/android/contacts/list/AccountFilterActivity.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.list;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.AsyncTaskLoader;
-import android.content.Context;
-import android.content.Intent;
-import android.content.Loader;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.ListView;
-
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Shows a list of all available accounts, letting the user select under which account to view
- * contacts.
- */
-public class AccountFilterActivity extends ContactsActivity
-        implements AdapterView.OnItemClickListener {
-
-    private static final String TAG = AccountFilterActivity.class.getSimpleName();
-
-    private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 0;
-
-    public static final String KEY_EXTRA_CONTACT_LIST_FILTER = "contactListFilter";
-    public static final String KEY_EXTRA_CURRENT_FILTER = "currentFilter";
-
-    private static final int FILTER_LOADER_ID = 0;
-
-    private ListView mListView;
-
-    private ContactListFilter mCurrentFilter;
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        setContentView(R.layout.contact_list_filter);
-
-        mListView = (ListView) findViewById(android.R.id.list);
-        mListView.setOnItemClickListener(this);
-
-        ActionBar actionBar = getActionBar();
-        if (actionBar != null) {
-            actionBar.setDisplayHomeAsUpEnabled(true);
-        }
-
-        mCurrentFilter = getIntent().getParcelableExtra(KEY_EXTRA_CURRENT_FILTER);
-
-        getLoaderManager().initLoader(FILTER_LOADER_ID, null, new MyLoaderCallbacks());
-    }
-
-    private static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> {
-        private Context mContext;
-
-        public FilterLoader(Context context) {
-            super(context);
-            mContext = context;
-        }
-
-        @Override
-        public List<ContactListFilter> loadInBackground() {
-            return loadAccountFilters(mContext);
-        }
-
-        @Override
-        protected void onStartLoading() {
-            forceLoad();
-        }
-
-        @Override
-        protected void onStopLoading() {
-            cancelLoad();
-        }
-
-        @Override
-        protected void onReset() {
-            onStopLoading();
-        }
-    }
-
-    private static List<ContactListFilter> loadAccountFilters(Context context) {
-        final ArrayList<ContactListFilter> result = Lists.newArrayList();
-        final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList();
-        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
-        List<AccountWithDataSet> accounts = accountTypes.getAccounts(false);
-        for (AccountWithDataSet account : accounts) {
-            AccountType accountType = accountTypes.getAccountType(account.type, account.dataSet);
-            if (accountType.isExtension() && !account.hasData(context)) {
-                // Hide extensions with no raw_contacts.
-                continue;
-            }
-            Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null;
-            accountFilters.add(ContactListFilter.createAccountFilter(
-                    account.type, account.name, account.dataSet, icon));
-        }
-
-        // Always show "All", even when there's no accounts.  (We may have local contacts)
-        result.add(ContactListFilter.createFilterWithType(
-                ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
-
-        final int count = accountFilters.size();
-        if (count >= 1) {
-            // If we only have one account, don't show it as "account", instead show it as "all"
-            if (count > 1) {
-                result.addAll(accountFilters);
-            }
-            result.add(ContactListFilter.createFilterWithType(
-                    ContactListFilter.FILTER_TYPE_CUSTOM));
-        }
-        return result;
-    }
-
-    private class MyLoaderCallbacks implements LoaderCallbacks<List<ContactListFilter>> {
-        @Override
-        public Loader<List<ContactListFilter>> onCreateLoader(int id, Bundle args) {
-            return new FilterLoader(AccountFilterActivity.this);
-        }
-
-        @Override
-        public void onLoadFinished(
-                Loader<List<ContactListFilter>> loader, List<ContactListFilter> data) {
-            if (data == null) { // Just in case...
-                Log.e(TAG, "Failed to load filters");
-                return;
-            }
-            mListView.setAdapter(
-                    new FilterListAdapter(AccountFilterActivity.this, data, mCurrentFilter));
-        }
-
-        @Override
-        public void onLoaderReset(Loader<List<ContactListFilter>> loader) {
-        }
-    }
-
-    @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        final ContactListFilter filter = (ContactListFilter) view.getTag();
-        if (filter == null) return; // Just in case
-        if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
-            final Intent intent = new Intent(this,
-                    CustomContactListFilterActivity.class);
-            startActivityForResult(intent, SUBACTIVITY_CUSTOMIZE_FILTER);
-        } else {
-            final Intent intent = new Intent();
-            intent.putExtra(KEY_EXTRA_CONTACT_LIST_FILTER, filter);
-            setResult(Activity.RESULT_OK, intent);
-            finish();
-        }
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (resultCode != Activity.RESULT_OK) {
-            return;
-        }
-
-        switch (requestCode) {
-            case SUBACTIVITY_CUSTOMIZE_FILTER: {
-                final Intent intent = new Intent();
-                ContactListFilter filter = ContactListFilter.createFilterWithType(
-                        ContactListFilter.FILTER_TYPE_CUSTOM);
-                intent.putExtra(KEY_EXTRA_CONTACT_LIST_FILTER, filter);
-                setResult(Activity.RESULT_OK, intent);
-                finish();
-                break;
-            }
-        }
-    }
-
-    private static class FilterListAdapter extends BaseAdapter {
-        private final List<ContactListFilter> mFilters;
-        private final LayoutInflater mLayoutInflater;
-        private final AccountTypeManager mAccountTypes;
-        private final ContactListFilter mCurrentFilter;
-
-        public FilterListAdapter(
-                Context context, List<ContactListFilter> filters, ContactListFilter current) {
-            mLayoutInflater = (LayoutInflater) context.getSystemService
-                    (Context.LAYOUT_INFLATER_SERVICE);
-            mFilters = filters;
-            mCurrentFilter = current;
-            mAccountTypes = AccountTypeManager.getInstance(context);
-        }
-
-        @Override
-        public int getCount() {
-            return mFilters.size();
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public ContactListFilter getItem(int position) {
-            return mFilters.get(position);
-        }
-
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final ContactListFilterView view;
-            if (convertView != null) {
-                view = (ContactListFilterView) convertView;
-            } else {
-                view = (ContactListFilterView) mLayoutInflater.inflate(
-                        R.layout.contact_list_filter_item, parent, false);
-            }
-            view.setSingleAccount(mFilters.size() == 1);
-            final ContactListFilter filter = mFilters.get(position);
-            view.setContactListFilter(filter);
-            view.bindView(mAccountTypes);
-            view.setTag(filter);
-            view.setActivated(filter.equals(mCurrentFilter));
-            return view;
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                // We have two logical "up" Activities: People and Phone.
-                // Instead of having one static "up" direction, behave like back as an
-                // exceptional case.
-                onBackPressed();
-                return true;
-            default:
-                break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 8ea8c1c..64c4c3d 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -35,12 +35,11 @@
 import android.util.Log;
 
 import com.android.common.widget.CompositeCursorAdapter.Partition;
-import com.android.contacts.R;
+import com.android.contacts.common.list.AutoScrollListView;
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
 import com.android.contacts.common.list.DirectoryPartition;
 import com.android.contacts.util.ContactLoaderUtils;
-import com.android.contacts.common.list.AutoScrollListView;
 
 import java.util.List;
 
@@ -276,25 +275,6 @@
         checkSelection();
     }
 
-    @Override
-    protected void prepareEmptyView() {
-        if (isSearchMode()) {
-            return;
-        } else if (isSyncActive()) {
-            if (hasIccCard()) {
-                setEmptyText(R.string.noContactsHelpTextWithSync);
-            } else {
-                setEmptyText(R.string.noContactsNoSimHelpTextWithSync);
-            }
-        } else {
-            if (hasIccCard()) {
-                setEmptyText(R.string.noContactsHelpText);
-            } else {
-                setEmptyText(R.string.noContactsNoSimHelpText);
-            }
-        }
-    }
-
     public Uri getSelectedContactUri() {
         return mSelectedContactUri;
     }
@@ -493,8 +473,15 @@
                 mSelectionRequired = false;
 
                 // If we were looking at a different specific contact, just reload
+                // FILTER_TYPE_ALL_ACCOUNTS is needed for the case where a new contact is added
+                // on a tablet and the loader is returning a stale list.  In this case, the contact
+                // will not be found until the next load. b/7621855 This will only fix the most
+                // common case where all accounts are shown. It will not fix the one account case.
+                // TODO: we may want to add more FILTER_TYPEs or relax this check to fix all other
+                // FILTER_TYPE cases.
                 if (mFilter != null
-                        && mFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
+                        && (mFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT
+                        || mFilter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS)) {
                     reloadData();
                 } else {
                     // Otherwise, call the listener, which will adjust the filter.
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index d522b5e..e867b4d 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -16,16 +16,12 @@
 
 package com.android.contacts.list;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.LoaderManager;
 import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.CursorLoader;
-import android.content.IContentService;
 import android.content.Intent;
 import android.content.Loader;
 import android.database.Cursor;
@@ -33,12 +29,8 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.Parcelable;
-import android.os.RemoteException;
-import android.provider.ContactsContract;
 import android.provider.ContactsContract.Directory;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -51,17 +43,14 @@
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ListView;
-import android.widget.TextView;
 
 import com.android.common.widget.CompositeCursorAdapter.Partition;
-import com.android.contacts.ContactListEmptyView;
 import com.android.contacts.R;
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.DirectoryListLoader;
 import com.android.contacts.common.list.DirectoryPartition;
 import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.widget.ContextMenuAdapter;
 
 /**
  * Common base class for various contact-related list fragments.
@@ -128,9 +117,7 @@
     private int mSortOrder;
     private int mDirectoryResultLimit = DEFAULT_DIRECTORY_RESULT_LIMIT;
 
-    private ContextMenuAdapter mContextMenuAdapter;
     private ContactPhotoManager mPhotoManager;
-    private ContactListEmptyView mEmptyView;
     private ContactsPreferences mContactsPrefs;
 
     private boolean mForceLoad;
@@ -231,10 +218,6 @@
         return mListView;
     }
 
-    public ContactListEmptyView getEmptyView() {
-        return mEmptyView;
-    }
-
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
@@ -477,13 +460,6 @@
     }
 
     /**
-     * Configures the empty view. It is called when we are about to populate
-     * the list with an empty cursor.
-     */
-    protected void prepareEmptyView() {
-    }
-
-    /**
      * Shows the count of entries included in the list. The default
      * implementation does nothing.
      */
@@ -692,17 +668,6 @@
         mDirectoryResultLimit = limit;
     }
 
-    public void setContextMenuAdapter(ContextMenuAdapter adapter) {
-        mContextMenuAdapter = adapter;
-        if (mListView != null) {
-            mListView.setOnCreateContextMenuListener(adapter);
-        }
-    }
-
-    public ContextMenuAdapter getContextMenuAdapter() {
-        return mContextMenuAdapter;
-    }
-
     protected boolean loadPreferences() {
         boolean changed = false;
         if (getContactNameDisplayOrder() != mContactsPrefs.getDisplayOrder()) {
@@ -752,9 +717,6 @@
         View emptyView = mView.findViewById(android.R.id.empty);
         if (emptyView != null) {
             mListView.setEmptyView(emptyView);
-            if (emptyView instanceof ContactListEmptyView) {
-                mEmptyView = (ContactListEmptyView)emptyView;
-            }
         }
 
         mListView.setOnItemClickListener(this);
@@ -769,10 +731,6 @@
         // We manually save/restore the listview state
         mListView.setSaveEnabled(false);
 
-        if (mContextMenuAdapter != null) {
-            mListView.setOnCreateContextMenuListener(mContextMenuAdapter);
-        }
-
         configureVerticalScrollbar();
         configurePhotoLoader();
     }
@@ -868,14 +826,6 @@
     }
 
     /**
-     * Dismisses the search UI along with the keyboard if the filter text is empty.
-     */
-    public void onClose() {
-        hideSoftKeyboard();
-        finish();
-    }
-
-    /**
      * Restore the list state after the adapter is populated.
      */
     protected void completeRestoreInstanceState() {
@@ -885,36 +835,6 @@
         }
     }
 
-    protected void setEmptyText(int resourceId) {
-        TextView empty = (TextView) getEmptyView().findViewById(R.id.emptyText);
-        empty.setText(mContext.getText(resourceId));
-        empty.setVisibility(View.VISIBLE);
-    }
-
-    // TODO redesign into an async task or loader
-    protected boolean isSyncActive() {
-        Account[] accounts = AccountManager.get(mContext).getAccounts();
-        if (accounts != null && accounts.length > 0) {
-            IContentService contentService = ContentResolver.getContentService();
-            for (Account account : accounts) {
-                try {
-                    if (contentService.isSyncActive(account, ContactsContract.AUTHORITY)) {
-                        return true;
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Could not get the sync status");
-                }
-            }
-        }
-        return false;
-    }
-
-    protected boolean hasIccCard() {
-        TelephonyManager telephonyManager =
-                (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        return telephonyManager.hasIccCard();
-    }
-
     public void setDarkTheme(boolean value) {
         mDarkTheme = value;
         if (mAdapter != null) mAdapter.setDarkTheme(value);
diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java
deleted file mode 100644
index 569dd5d..0000000
--- a/src/com/android/contacts/list/ContactListFilterController.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.contacts.list;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Manages {@link com.android.contacts.common.list.ContactListFilter}. All methods must be called from UI thread.
- */
-public abstract class ContactListFilterController {
-
-    // singleton to cache the filter controller
-    private static ContactListFilterControllerImpl sFilterController = null;
-
-    public interface ContactListFilterListener {
-        void onContactListFilterChanged();
-    }
-
-    public static ContactListFilterController getInstance(Context context) {
-        // We may need to synchronize this in the future if background task will call this.
-        if (sFilterController == null) {
-            sFilterController = new ContactListFilterControllerImpl(context);
-        }
-        return sFilterController;
-    }
-
-    public abstract void addListener(ContactListFilterListener listener);
-
-    public abstract void removeListener(ContactListFilterListener listener);
-
-    /**
-     * Return the currently-active filter.
-     */
-    public abstract ContactListFilter getFilter();
-
-    /**
-     * @param filter the filter
-     * @param persistent True when the given filter should be saved soon. False when the filter
-     * should not be saved. The latter case may happen when some Intent requires a certain type of
-     * UI (e.g. single contact) temporarily.
-     */
-    public abstract void setContactListFilter(ContactListFilter filter, boolean persistent);
-
-    public abstract void selectCustomFilter();
-
-    /**
-     * Checks if the current filter is valid and reset the filter if not. It may happen when
-     * an account is removed while the filter points to the account with
-     * {@link ContactListFilter#FILTER_TYPE_ACCOUNT} type, for example. It may also happen if
-     * the current filter is {@link ContactListFilter#FILTER_TYPE_SINGLE_CONTACT}, in
-     * which case, we should switch to the last saved filter in {@link SharedPreferences}.
-     */
-    public abstract void checkFilterValidity(boolean notifyListeners);
-}
-
-/**
- * Stores the {@link ContactListFilter} selected by the user and saves it to
- * {@link SharedPreferences} if necessary.
- */
-class ContactListFilterControllerImpl extends ContactListFilterController {
-    private final Context mContext;
-    private final List<ContactListFilterListener> mListeners =
-            new ArrayList<ContactListFilterListener>();
-    private ContactListFilter mFilter;
-
-    public ContactListFilterControllerImpl(Context context) {
-        mContext = context;
-        mFilter = ContactListFilter.restoreDefaultPreferences(getSharedPreferences());
-        checkFilterValidity(true /* notify listeners */);
-    }
-
-    @Override
-    public void addListener(ContactListFilterListener listener) {
-        mListeners.add(listener);
-    }
-
-    @Override
-    public void removeListener(ContactListFilterListener listener) {
-        mListeners.remove(listener);
-    }
-
-    @Override
-    public ContactListFilter getFilter() {
-        return mFilter;
-    }
-
-    private SharedPreferences getSharedPreferences() {
-        return PreferenceManager.getDefaultSharedPreferences(mContext);
-    }
-
-    @Override
-    public void setContactListFilter(ContactListFilter filter, boolean persistent) {
-        setContactListFilter(filter, persistent, true);
-    }
-
-    private void setContactListFilter(ContactListFilter filter, boolean persistent,
-            boolean notifyListeners) {
-        if (!filter.equals(mFilter)) {
-            mFilter = filter;
-            if (persistent) {
-                ContactListFilter.storeToPreferences(getSharedPreferences(), mFilter);
-            }
-            if (notifyListeners && !mListeners.isEmpty()) {
-                notifyContactListFilterChanged();
-            }
-        }
-    }
-
-    @Override
-    public void selectCustomFilter() {
-        setContactListFilter(ContactListFilter.createFilterWithType(
-                ContactListFilter.FILTER_TYPE_CUSTOM), true);
-    }
-
-    private void notifyContactListFilterChanged() {
-        for (ContactListFilterListener listener : mListeners) {
-            listener.onContactListFilterChanged();
-        }
-    }
-
-    @Override
-    public void checkFilterValidity(boolean notifyListeners) {
-        if (mFilter == null) {
-            return;
-        }
-
-        switch (mFilter.filterType) {
-            case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT:
-                setContactListFilter(
-                        ContactListFilter.restoreDefaultPreferences(getSharedPreferences()),
-                        false, notifyListeners);
-                break;
-            case ContactListFilter.FILTER_TYPE_ACCOUNT:
-                if (!filterAccountExists()) {
-                    // The current account filter points to invalid account. Use "all" filter
-                    // instead.
-                    setContactListFilter(ContactListFilter.createFilterWithType(
-                            ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS), true, notifyListeners);
-                }
-        }
-    }
-
-    /**
-     * @return true if the Account for the current filter exists.
-     */
-    private boolean filterAccountExists() {
-        final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(mContext);
-        final AccountWithDataSet filterAccount = new AccountWithDataSet(
-                mFilter.accountName, mFilter.accountType, mFilter.dataSet);
-        return accountTypeManager.contains(filterAccount, false);
-    }
-}
diff --git a/src/com/android/contacts/list/ContactListFilterView.java b/src/com/android/contacts/list/ContactListFilterView.java
deleted file mode 100644
index 8102f65..0000000
--- a/src/com/android/contacts/list/ContactListFilterView.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.list;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.TextView;
-
-import com.android.contacts.R;
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-
-/**
- * Contact list filter parameters.
- */
-public class ContactListFilterView extends LinearLayout {
-
-    private static final String TAG = ContactListFilterView.class.getSimpleName();
-
-    private ImageView mIcon;
-    private TextView mAccountType;
-    private TextView mAccountUserName;
-    private RadioButton mRadioButton;
-    private ContactListFilter mFilter;
-    private boolean mSingleAccount;
-
-    public ContactListFilterView(Context context) {
-        super(context);
-    }
-
-    public ContactListFilterView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setContactListFilter(ContactListFilter filter) {
-        mFilter = filter;
-    }
-
-    public ContactListFilter getContactListFilter() {
-        return mFilter;
-    }
-
-    public void setSingleAccount(boolean flag) {
-        this.mSingleAccount = flag;
-    }
-
-    @Override
-    public void setActivated(boolean activated) {
-        super.setActivated(activated);
-        if (mRadioButton != null) {
-            mRadioButton.setChecked(activated);
-        } else {
-            // We're guarding against null-pointer exceptions,
-            // but otherwise this code is not expected to work
-            // properly if the button hasn't been initialized.
-            Log.wtf(TAG, "radio-button cannot be activated because it is null");
-        }
-    }
-
-    public void bindView(AccountTypeManager accountTypes) {
-        if (mAccountType == null) {
-            mIcon = (ImageView) findViewById(R.id.icon);
-            mAccountType = (TextView) findViewById(R.id.accountType);
-            mAccountUserName = (TextView) findViewById(R.id.accountUserName);
-            mRadioButton = (RadioButton) findViewById(R.id.radioButton);
-            mRadioButton.setChecked(isActivated());
-        }
-
-        if (mFilter == null) {
-            mAccountType.setText(R.string.contactsList);
-            return;
-        }
-
-        mAccountUserName.setVisibility(View.GONE);
-        switch (mFilter.filterType) {
-            case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS: {
-                bindView(0, R.string.list_filter_all_accounts);
-                break;
-            }
-            case ContactListFilter.FILTER_TYPE_STARRED: {
-                bindView(R.drawable.ic_menu_star_holo_light, R.string.list_filter_all_starred);
-                break;
-            }
-            case ContactListFilter.FILTER_TYPE_CUSTOM: {
-                bindView(R.drawable.ic_menu_settings_holo_light, R.string.list_filter_customize);
-                break;
-            }
-            case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY: {
-                bindView(0, R.string.list_filter_phones);
-                break;
-            }
-            case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT: {
-                bindView(0, R.string.list_filter_single);
-                break;
-            }
-            case ContactListFilter.FILTER_TYPE_ACCOUNT: {
-                mAccountUserName.setVisibility(View.VISIBLE);
-                mIcon.setVisibility(View.VISIBLE);
-                if (mFilter.icon != null) {
-                    mIcon.setImageDrawable(mFilter.icon);
-                } else {
-                    mIcon.setImageResource(R.drawable.unknown_source);
-                }
-                final AccountType accountType =
-                        accountTypes.getAccountType(mFilter.accountType, mFilter.dataSet);
-                mAccountUserName.setText(mFilter.accountName);
-                mAccountType.setText(accountType.getDisplayLabel(getContext()));
-                break;
-            }
-        }
-    }
-
-    private void bindView(int iconResource, int textResource) {
-        if (iconResource != 0) {
-            mIcon.setVisibility(View.VISIBLE);
-            mIcon.setImageResource(iconResource);
-        } else {
-            mIcon.setVisibility(View.GONE);
-        }
-
-        mAccountType.setText(textResource);
-    }
-}
diff --git a/src/com/android/contacts/list/ContactPickerFragment.java b/src/com/android/contacts/list/ContactPickerFragment.java
index 2de71be..c8ad712 100644
--- a/src/com/android/contacts/list/ContactPickerFragment.java
+++ b/src/com/android/contacts/list/ContactPickerFragment.java
@@ -29,7 +29,8 @@
 import com.android.contacts.common.list.ContactListFilter;
 import com.android.contacts.common.list.DefaultContactListAdapter;
 import com.android.contacts.common.list.DirectoryListLoader;
-import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
+import com.android.contacts.common.list.ShortcutIntentBuilder;
+import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
 
 /**
  * Fragment for the contact list used for browsing contacts (as compared to
@@ -75,10 +76,6 @@
         mEditMode = flag;
     }
 
-    public boolean isShortcutRequested() {
-        return mShortcutRequested;
-    }
-
     public void setShortcutRequested(boolean flag) {
         mShortcutRequested = flag;
     }
@@ -185,31 +182,6 @@
     }
 
     @Override
-    protected void prepareEmptyView() {
-        if (isSearchMode()) {
-            return;
-        } else if (isSyncActive()) {
-            if (mShortcutRequested) {
-                // Help text is the same no matter whether there is SIM or not.
-                setEmptyText(R.string.noContactsHelpTextWithSyncForCreateShortcut);
-            } else if (hasIccCard()) {
-                setEmptyText(R.string.noContactsHelpTextWithSync);
-            } else {
-                setEmptyText(R.string.noContactsNoSimHelpTextWithSync);
-            }
-        } else {
-            if (mShortcutRequested) {
-                // Help text is the same no matter whether there is SIM or not.
-                setEmptyText(R.string.noContactsHelpTextWithSyncForCreateShortcut);
-            } else if (hasIccCard()) {
-                setEmptyText(R.string.noContactsHelpText);
-            } else {
-                setEmptyText(R.string.noContactsNoSimHelpText);
-            }
-        }
-    }
-
-    @Override
     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
         mListener.onShortcutIntentCreated(shortcutIntent);
     }
diff --git a/src/com/android/contacts/list/CustomContactListFilterActivity.java b/src/com/android/contacts/list/CustomContactListFilterActivity.java
deleted file mode 100644
index 532bbee..0000000
--- a/src/com/android/contacts/list/CustomContactListFilterActivity.java
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.list;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.app.ProgressDialog;
-import android.content.AsyncTaskLoader;
-import android.content.ContentProviderOperation;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.OperationApplicationException;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.preference.PreferenceManager;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Groups;
-import android.provider.ContactsContract.Settings;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseExpandableListAdapter;
-import android.widget.CheckBox;
-import android.widget.ExpandableListAdapter;
-import android.widget.ExpandableListView;
-import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
-import android.widget.TextView;
-
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.model.account.GoogleAccountType;
-import com.android.contacts.util.EmptyService;
-import com.android.contacts.util.LocalizedNameResolver;
-import com.android.contacts.util.WeakAsyncTask;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-
-/**
- * Shows a list of all available {@link Groups} available, letting the user
- * select which ones they want to be visible.
- */
-public class CustomContactListFilterActivity extends ContactsActivity
-        implements View.OnClickListener, ExpandableListView.OnChildClickListener,
-        LoaderCallbacks<CustomContactListFilterActivity.AccountSet>
-{
-    private static final String TAG = "CustomContactListFilterActivity";
-
-    private static final int ACCOUNT_SET_LOADER_ID = 1;
-
-    private ExpandableListView mList;
-    private DisplayAdapter mAdapter;
-
-    private SharedPreferences mPrefs;
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        setContentView(R.layout.contact_list_filter_custom);
-
-        mList = (ExpandableListView) findViewById(android.R.id.list);
-        mList.setOnChildClickListener(this);
-        mList.setHeaderDividersEnabled(true);
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-        mAdapter = new DisplayAdapter(this);
-
-        final LayoutInflater inflater = getLayoutInflater();
-
-        findViewById(R.id.btn_done).setOnClickListener(this);
-        findViewById(R.id.btn_discard).setOnClickListener(this);
-
-        mList.setOnCreateContextMenuListener(this);
-
-        mList.setAdapter(mAdapter);
-
-        ActionBar actionBar = getActionBar();
-        if (actionBar != null) {
-            // android.R.id.home will be triggered in onOptionsItemSelected()
-            actionBar.setDisplayHomeAsUpEnabled(true);
-        }
-    }
-
-    public static class CustomFilterConfigurationLoader extends AsyncTaskLoader<AccountSet> {
-
-        private AccountSet mAccountSet;
-
-        public CustomFilterConfigurationLoader(Context context) {
-            super(context);
-        }
-
-        @Override
-        public AccountSet loadInBackground() {
-            Context context = getContext();
-            final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
-            final ContentResolver resolver = context.getContentResolver();
-
-            final AccountSet accounts = new AccountSet();
-            for (AccountWithDataSet account : accountTypes.getAccounts(false)) {
-                final AccountType accountType = accountTypes.getAccountTypeForAccount(account);
-                if (accountType.isExtension() && !account.hasData(context)) {
-                    // Extension with no data -- skip.
-                    continue;
-                }
-
-                AccountDisplay accountDisplay =
-                        new AccountDisplay(resolver, account.name, account.type, account.dataSet);
-
-                final Uri.Builder groupsUri = Groups.CONTENT_URI.buildUpon()
-                        .appendQueryParameter(Groups.ACCOUNT_NAME, account.name)
-                        .appendQueryParameter(Groups.ACCOUNT_TYPE, account.type);
-                if (account.dataSet != null) {
-                    groupsUri.appendQueryParameter(Groups.DATA_SET, account.dataSet).build();
-                }
-                android.content.EntityIterator iterator =
-                        ContactsContract.Groups.newEntityIterator(resolver.query(
-                        groupsUri.build(), null, null, null, null));
-                try {
-                    boolean hasGroups = false;
-
-                    // Create entries for each known group
-                    while (iterator.hasNext()) {
-                        final ContentValues values = iterator.next().getEntityValues();
-                        final GroupDelta group = GroupDelta.fromBefore(values);
-                        accountDisplay.addGroup(group);
-                        hasGroups = true;
-                    }
-                    // Create single entry handling ungrouped status
-                    accountDisplay.mUngrouped =
-                        GroupDelta.fromSettings(resolver, account.name, account.type,
-                                account.dataSet, hasGroups);
-                    accountDisplay.addGroup(accountDisplay.mUngrouped);
-                } finally {
-                    iterator.close();
-                }
-
-                accounts.add(accountDisplay);
-            }
-
-            return accounts;
-        }
-
-        @Override
-        public void deliverResult(AccountSet cursor) {
-            if (isReset()) {
-                return;
-            }
-
-            mAccountSet = cursor;
-
-            if (isStarted()) {
-                super.deliverResult(cursor);
-            }
-        }
-
-        @Override
-        protected void onStartLoading() {
-            if (mAccountSet != null) {
-                deliverResult(mAccountSet);
-            }
-            if (takeContentChanged() || mAccountSet == null) {
-                forceLoad();
-            }
-        }
-
-        @Override
-        protected void onStopLoading() {
-            cancelLoad();
-        }
-
-        @Override
-        protected void onReset() {
-            super.onReset();
-            onStopLoading();
-            mAccountSet = null;
-        }
-    }
-
-    @Override
-    protected void onStart() {
-        getLoaderManager().initLoader(ACCOUNT_SET_LOADER_ID, null, this);
-        super.onStart();
-    }
-
-    @Override
-    public Loader<AccountSet> onCreateLoader(int id, Bundle args) {
-        return new CustomFilterConfigurationLoader(this);
-    }
-
-    @Override
-    public void onLoadFinished(Loader<AccountSet> loader, AccountSet data) {
-        mAdapter.setAccounts(data);
-    }
-
-    @Override
-    public void onLoaderReset(Loader<AccountSet> loader) {
-        mAdapter.setAccounts(null);
-    }
-
-    private static final int DEFAULT_SHOULD_SYNC = 1;
-    private static final int DEFAULT_VISIBLE = 0;
-
-    /**
-     * Entry holding any changes to {@link Groups} or {@link Settings} rows,
-     * such as {@link Groups#SHOULD_SYNC} or {@link Groups#GROUP_VISIBLE}.
-     */
-    protected static class GroupDelta extends ValuesDelta {
-        private boolean mUngrouped = false;
-        private boolean mAccountHasGroups;
-
-        private GroupDelta() {
-            super();
-        }
-
-        /**
-         * Build {@link GroupDelta} from the {@link Settings} row for the given
-         * {@link Settings#ACCOUNT_NAME}, {@link Settings#ACCOUNT_TYPE}, and
-         * {@link Settings#DATA_SET}.
-         */
-        public static GroupDelta fromSettings(ContentResolver resolver, String accountName,
-                String accountType, String dataSet, boolean accountHasGroups) {
-            final Uri.Builder settingsUri = Settings.CONTENT_URI.buildUpon()
-                    .appendQueryParameter(Settings.ACCOUNT_NAME, accountName)
-                    .appendQueryParameter(Settings.ACCOUNT_TYPE, accountType);
-            if (dataSet != null) {
-                settingsUri.appendQueryParameter(Settings.DATA_SET, dataSet);
-            }
-            final Cursor cursor = resolver.query(settingsUri.build(), new String[] {
-                    Settings.SHOULD_SYNC, Settings.UNGROUPED_VISIBLE
-            }, null, null, null);
-
-            try {
-                final ContentValues values = new ContentValues();
-                values.put(Settings.ACCOUNT_NAME, accountName);
-                values.put(Settings.ACCOUNT_TYPE, accountType);
-                values.put(Settings.DATA_SET, dataSet);
-
-                if (cursor != null && cursor.moveToFirst()) {
-                    // Read existing values when present
-                    values.put(Settings.SHOULD_SYNC, cursor.getInt(0));
-                    values.put(Settings.UNGROUPED_VISIBLE, cursor.getInt(1));
-                    return fromBefore(values).setUngrouped(accountHasGroups);
-                } else {
-                    // Nothing found, so treat as create
-                    values.put(Settings.SHOULD_SYNC, DEFAULT_SHOULD_SYNC);
-                    values.put(Settings.UNGROUPED_VISIBLE, DEFAULT_VISIBLE);
-                    return fromAfter(values).setUngrouped(accountHasGroups);
-                }
-            } finally {
-                if (cursor != null) cursor.close();
-            }
-        }
-
-        public static GroupDelta fromBefore(ContentValues before) {
-            final GroupDelta entry = new GroupDelta();
-            entry.mBefore = before;
-            entry.mAfter = new ContentValues();
-            return entry;
-        }
-
-        public static GroupDelta fromAfter(ContentValues after) {
-            final GroupDelta entry = new GroupDelta();
-            entry.mBefore = null;
-            entry.mAfter = after;
-            return entry;
-        }
-
-        protected GroupDelta setUngrouped(boolean accountHasGroups) {
-            mUngrouped = true;
-            mAccountHasGroups = accountHasGroups;
-            return this;
-        }
-
-        @Override
-        public boolean beforeExists() {
-            return mBefore != null;
-        }
-
-        public boolean getShouldSync() {
-            return getAsInteger(mUngrouped ? Settings.SHOULD_SYNC : Groups.SHOULD_SYNC,
-                    DEFAULT_SHOULD_SYNC) != 0;
-        }
-
-        public boolean getVisible() {
-            return getAsInteger(mUngrouped ? Settings.UNGROUPED_VISIBLE : Groups.GROUP_VISIBLE,
-                    DEFAULT_VISIBLE) != 0;
-        }
-
-        public void putShouldSync(boolean shouldSync) {
-            put(mUngrouped ? Settings.SHOULD_SYNC : Groups.SHOULD_SYNC, shouldSync ? 1 : 0);
-        }
-
-        public void putVisible(boolean visible) {
-            put(mUngrouped ? Settings.UNGROUPED_VISIBLE : Groups.GROUP_VISIBLE, visible ? 1 : 0);
-        }
-
-        private String getAccountType() {
-            return (mBefore == null ? mAfter : mBefore).getAsString(Settings.ACCOUNT_TYPE);
-        }
-
-        public CharSequence getTitle(Context context) {
-            if (mUngrouped) {
-                final String customAllContactsName =
-                        LocalizedNameResolver.getAllContactsName(context, getAccountType());
-                if (customAllContactsName != null) {
-                    return customAllContactsName;
-                }
-                if (mAccountHasGroups) {
-                    return context.getText(R.string.display_ungrouped);
-                } else {
-                    return context.getText(R.string.display_all_contacts);
-                }
-            } else {
-                final Integer titleRes = getAsInteger(Groups.TITLE_RES);
-                if (titleRes != null) {
-                    final String packageName = getAsString(Groups.RES_PACKAGE);
-                    return context.getPackageManager().getText(packageName, titleRes, null);
-                } else {
-                    return getAsString(Groups.TITLE);
-                }
-            }
-        }
-
-        /**
-         * Build a possible {@link ContentProviderOperation} to persist any
-         * changes to the {@link Groups} or {@link Settings} row described by
-         * this {@link GroupDelta}.
-         */
-        public ContentProviderOperation buildDiff() {
-            if (isInsert()) {
-                // Only allow inserts for Settings
-                if (mUngrouped) {
-                    mAfter.remove(mIdColumn);
-                    return ContentProviderOperation.newInsert(Settings.CONTENT_URI)
-                            .withValues(mAfter)
-                            .build();
-                }
-                else {
-                    throw new IllegalStateException("Unexpected diff");
-                }
-            } else if (isUpdate()) {
-                if (mUngrouped) {
-                    String accountName = this.getAsString(Settings.ACCOUNT_NAME);
-                    String accountType = this.getAsString(Settings.ACCOUNT_TYPE);
-                    String dataSet = this.getAsString(Settings.DATA_SET);
-                    StringBuilder selection = new StringBuilder(Settings.ACCOUNT_NAME + "=? AND "
-                            + Settings.ACCOUNT_TYPE + "=?");
-                    String[] selectionArgs;
-                    if (dataSet == null) {
-                        selection.append(" AND " + Settings.DATA_SET + " IS NULL");
-                        selectionArgs = new String[] {accountName, accountType};
-                    } else {
-                        selection.append(" AND " + Settings.DATA_SET + "=?");
-                        selectionArgs = new String[] {accountName, accountType, dataSet};
-                    }
-                    return ContentProviderOperation.newUpdate(Settings.CONTENT_URI)
-                            .withSelection(selection.toString(), selectionArgs)
-                            .withValues(mAfter)
-                            .build();
-                } else {
-                    return ContentProviderOperation.newUpdate(
-                                    addCallerIsSyncAdapterParameter(Groups.CONTENT_URI))
-                            .withSelection(Groups._ID + "=" + this.getId(), null)
-                            .withValues(mAfter)
-                            .build();
-                }
-            } else {
-                return null;
-            }
-        }
-    }
-
-    private static Uri addCallerIsSyncAdapterParameter(Uri uri) {
-        return uri.buildUpon()
-            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
-            .build();
-    }
-
-    /**
-     * {@link Comparator} to sort by {@link Groups#_ID}.
-     */
-    private static Comparator<GroupDelta> sIdComparator = new Comparator<GroupDelta>() {
-        public int compare(GroupDelta object1, GroupDelta object2) {
-            final Long id1 = object1.getId();
-            final Long id2 = object2.getId();
-            if (id1 == null && id2 == null) {
-                return 0;
-            } else if (id1 == null) {
-                return -1;
-            } else if (id2 == null) {
-                return 1;
-            } else if (id1 < id2) {
-                return -1;
-            } else if (id1 > id2) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }
-    };
-
-    /**
-     * Set of all {@link AccountDisplay} entries, one for each source.
-     */
-    protected static class AccountSet extends ArrayList<AccountDisplay> {
-        public ArrayList<ContentProviderOperation> buildDiff() {
-            final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-            for (AccountDisplay account : this) {
-                account.buildDiff(diff);
-            }
-            return diff;
-        }
-    }
-
-    /**
-     * {@link GroupDelta} details for a single {@link AccountWithDataSet}, usually shown as
-     * children under a single expandable group.
-     */
-    protected static class AccountDisplay {
-        public final String mName;
-        public final String mType;
-        public final String mDataSet;
-
-        public GroupDelta mUngrouped;
-        public ArrayList<GroupDelta> mSyncedGroups = Lists.newArrayList();
-        public ArrayList<GroupDelta> mUnsyncedGroups = Lists.newArrayList();
-
-        /**
-         * Build an {@link AccountDisplay} covering all {@link Groups} under the
-         * given {@link AccountWithDataSet}.
-         */
-        public AccountDisplay(ContentResolver resolver, String accountName, String accountType,
-                String dataSet) {
-            mName = accountName;
-            mType = accountType;
-            mDataSet = dataSet;
-        }
-
-        /**
-         * Add the given {@link GroupDelta} internally, filing based on its
-         * {@link GroupDelta#getShouldSync()} status.
-         */
-        private void addGroup(GroupDelta group) {
-            if (group.getShouldSync()) {
-                mSyncedGroups.add(group);
-            } else {
-                mUnsyncedGroups.add(group);
-            }
-        }
-
-        /**
-         * Set the {@link GroupDelta#putShouldSync(boolean)} value for all
-         * children {@link GroupDelta} rows.
-         */
-        public void setShouldSync(boolean shouldSync) {
-            final Iterator<GroupDelta> oppositeChildren = shouldSync ?
-                    mUnsyncedGroups.iterator() : mSyncedGroups.iterator();
-            while (oppositeChildren.hasNext()) {
-                final GroupDelta child = oppositeChildren.next();
-                setShouldSync(child, shouldSync, false);
-                oppositeChildren.remove();
-            }
-        }
-
-        public void setShouldSync(GroupDelta child, boolean shouldSync) {
-            setShouldSync(child, shouldSync, true);
-        }
-
-        /**
-         * Set {@link GroupDelta#putShouldSync(boolean)}, and file internally
-         * based on updated state.
-         */
-        public void setShouldSync(GroupDelta child, boolean shouldSync, boolean attemptRemove) {
-            child.putShouldSync(shouldSync);
-            if (shouldSync) {
-                if (attemptRemove) {
-                    mUnsyncedGroups.remove(child);
-                }
-                mSyncedGroups.add(child);
-                Collections.sort(mSyncedGroups, sIdComparator);
-            } else {
-                if (attemptRemove) {
-                    mSyncedGroups.remove(child);
-                }
-                mUnsyncedGroups.add(child);
-            }
-        }
-
-        /**
-         * Build set of {@link ContentProviderOperation} to persist any user
-         * changes to {@link GroupDelta} rows under this {@link AccountWithDataSet}.
-         */
-        public void buildDiff(ArrayList<ContentProviderOperation> diff) {
-            for (GroupDelta group : mSyncedGroups) {
-                final ContentProviderOperation oper = group.buildDiff();
-                if (oper != null) diff.add(oper);
-            }
-            for (GroupDelta group : mUnsyncedGroups) {
-                final ContentProviderOperation oper = group.buildDiff();
-                if (oper != null) diff.add(oper);
-            }
-        }
-    }
-
-    /**
-     * {@link ExpandableListAdapter} that shows {@link GroupDelta} settings,
-     * grouped by {@link AccountWithDataSet} type. Shows footer row when any groups are
-     * unsynced, as determined through {@link AccountDisplay#mUnsyncedGroups}.
-     */
-    protected static class DisplayAdapter extends BaseExpandableListAdapter {
-        private Context mContext;
-        private LayoutInflater mInflater;
-        private AccountTypeManager mAccountTypes;
-        private AccountSet mAccounts;
-
-        private boolean mChildWithPhones = false;
-
-        public DisplayAdapter(Context context) {
-            mContext = context;
-            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            mAccountTypes = AccountTypeManager.getInstance(context);
-        }
-
-        public void setAccounts(AccountSet accounts) {
-            mAccounts = accounts;
-            notifyDataSetChanged();
-        }
-
-        /**
-         * In group descriptions, show the number of contacts with phone
-         * numbers, in addition to the total contacts.
-         */
-        public void setChildDescripWithPhones(boolean withPhones) {
-            mChildWithPhones = withPhones;
-        }
-
-        @Override
-        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
-                ViewGroup parent) {
-            if (convertView == null) {
-                convertView = mInflater.inflate(
-                        R.layout.custom_contact_list_filter_account, parent, false);
-            }
-
-            final TextView text1 = (TextView)convertView.findViewById(android.R.id.text1);
-            final TextView text2 = (TextView)convertView.findViewById(android.R.id.text2);
-
-            final AccountDisplay account = (AccountDisplay)this.getGroup(groupPosition);
-
-            final AccountType accountType = mAccountTypes.getAccountType(
-                    account.mType, account.mDataSet);
-
-            text1.setText(account.mName);
-            text1.setVisibility(account.mName == null ? View.GONE : View.VISIBLE);
-            text2.setText(accountType.getDisplayLabel(mContext));
-
-            return convertView;
-        }
-
-        @Override
-        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
-                View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = mInflater.inflate(
-                        R.layout.custom_contact_list_filter_group, parent, false);
-            }
-
-            final TextView text1 = (TextView)convertView.findViewById(android.R.id.text1);
-            final TextView text2 = (TextView)convertView.findViewById(android.R.id.text2);
-            final CheckBox checkbox = (CheckBox)convertView.findViewById(android.R.id.checkbox);
-
-            final AccountDisplay account = mAccounts.get(groupPosition);
-            final GroupDelta child = (GroupDelta)this.getChild(groupPosition, childPosition);
-            if (child != null) {
-                // Handle normal group, with title and checkbox
-                final boolean groupVisible = child.getVisible();
-                checkbox.setVisibility(View.VISIBLE);
-                checkbox.setChecked(groupVisible);
-
-                final CharSequence groupTitle = child.getTitle(mContext);
-                text1.setText(groupTitle);
-                text2.setVisibility(View.GONE);
-            } else {
-                // When unknown child, this is "more" footer view
-                checkbox.setVisibility(View.GONE);
-                text1.setText(R.string.display_more_groups);
-                text2.setVisibility(View.GONE);
-            }
-
-            return convertView;
-        }
-
-        @Override
-        public Object getChild(int groupPosition, int childPosition) {
-            final AccountDisplay account = mAccounts.get(groupPosition);
-            final boolean validChild = childPosition >= 0
-                    && childPosition < account.mSyncedGroups.size();
-            if (validChild) {
-                return account.mSyncedGroups.get(childPosition);
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public long getChildId(int groupPosition, int childPosition) {
-            final GroupDelta child = (GroupDelta)getChild(groupPosition, childPosition);
-            if (child != null) {
-                final Long childId = child.getId();
-                return childId != null ? childId : Long.MIN_VALUE;
-            } else {
-                return Long.MIN_VALUE;
-            }
-        }
-
-        @Override
-        public int getChildrenCount(int groupPosition) {
-            // Count is any synced groups, plus possible footer
-            final AccountDisplay account = mAccounts.get(groupPosition);
-            final boolean anyHidden = account.mUnsyncedGroups.size() > 0;
-            return account.mSyncedGroups.size() + (anyHidden ? 1 : 0);
-        }
-
-        @Override
-        public Object getGroup(int groupPosition) {
-            return mAccounts.get(groupPosition);
-        }
-
-        @Override
-        public int getGroupCount() {
-            if (mAccounts == null) {
-                return 0;
-            }
-            return mAccounts.size();
-        }
-
-        @Override
-        public long getGroupId(int groupPosition) {
-            return groupPosition;
-        }
-
-        @Override
-        public boolean hasStableIds() {
-            return true;
-        }
-
-        @Override
-        public boolean isChildSelectable(int groupPosition, int childPosition) {
-            return true;
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void onClick(View view) {
-        switch (view.getId()) {
-            case R.id.btn_done: {
-                this.doSaveAction();
-                break;
-            }
-            case R.id.btn_discard: {
-                this.finish();
-                break;
-            }
-        }
-    }
-
-    /**
-     * Handle any clicks on {@link ExpandableListAdapter} children, which
-     * usually mean toggling its visible state.
-     */
-    @Override
-    public boolean onChildClick(ExpandableListView parent, View view, int groupPosition,
-            int childPosition, long id) {
-        final CheckBox checkbox = (CheckBox)view.findViewById(android.R.id.checkbox);
-
-        final AccountDisplay account = (AccountDisplay)mAdapter.getGroup(groupPosition);
-        final GroupDelta child = (GroupDelta)mAdapter.getChild(groupPosition, childPosition);
-        if (child != null) {
-            checkbox.toggle();
-            child.putVisible(checkbox.isChecked());
-        } else {
-            // Open context menu for bringing back unsynced
-            this.openContextMenu(view);
-        }
-        return true;
-    }
-
-    // TODO: move these definitions to framework constants when we begin
-    // defining this mode through <sync-adapter> tags
-    private static final int SYNC_MODE_UNSUPPORTED = 0;
-    private static final int SYNC_MODE_UNGROUPED = 1;
-    private static final int SYNC_MODE_EVERYTHING = 2;
-
-    protected int getSyncMode(AccountDisplay account) {
-        // TODO: read sync mode through <sync-adapter> definition
-        if (GoogleAccountType.ACCOUNT_TYPE.equals(account.mType) && account.mDataSet == null) {
-            return SYNC_MODE_EVERYTHING;
-        } else {
-            return SYNC_MODE_UNSUPPORTED;
-        }
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View view,
-            ContextMenu.ContextMenuInfo menuInfo) {
-        super.onCreateContextMenu(menu, view, menuInfo);
-
-        // Bail if not working with expandable long-press, or if not child
-        if (!(menuInfo instanceof ExpandableListContextMenuInfo)) return;
-
-        final ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo;
-        final int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition);
-        final int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition);
-
-        // Skip long-press on expandable parents
-        if (childPosition == -1) return;
-
-        final AccountDisplay account = (AccountDisplay)mAdapter.getGroup(groupPosition);
-        final GroupDelta child = (GroupDelta)mAdapter.getChild(groupPosition, childPosition);
-
-        // Ignore when selective syncing unsupported
-        final int syncMode = getSyncMode(account);
-        if (syncMode == SYNC_MODE_UNSUPPORTED) return;
-
-        if (child != null) {
-            showRemoveSync(menu, account, child, syncMode);
-        } else {
-            showAddSync(menu, account, syncMode);
-        }
-    }
-
-    protected void showRemoveSync(ContextMenu menu, final AccountDisplay account,
-            final GroupDelta child, final int syncMode) {
-        final CharSequence title = child.getTitle(this);
-
-        menu.setHeaderTitle(title);
-        menu.add(R.string.menu_sync_remove).setOnMenuItemClickListener(
-                new OnMenuItemClickListener() {
-                    public boolean onMenuItemClick(MenuItem item) {
-                        handleRemoveSync(account, child, syncMode, title);
-                        return true;
-                    }
-                });
-    }
-
-    protected void handleRemoveSync(final AccountDisplay account, final GroupDelta child,
-            final int syncMode, CharSequence title) {
-        final boolean shouldSyncUngrouped = account.mUngrouped.getShouldSync();
-        if (syncMode == SYNC_MODE_EVERYTHING && shouldSyncUngrouped
-                && !child.equals(account.mUngrouped)) {
-            // Warn before removing this group when it would cause ungrouped to stop syncing
-            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            final CharSequence removeMessage = this.getString(
-                    R.string.display_warn_remove_ungrouped, title);
-            builder.setTitle(R.string.menu_sync_remove);
-            builder.setMessage(removeMessage);
-            builder.setNegativeButton(android.R.string.cancel, null);
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    // Mark both this group and ungrouped to stop syncing
-                    account.setShouldSync(account.mUngrouped, false);
-                    account.setShouldSync(child, false);
-                    mAdapter.notifyDataSetChanged();
-                }
-            });
-            builder.show();
-        } else {
-            // Mark this group to not sync
-            account.setShouldSync(child, false);
-            mAdapter.notifyDataSetChanged();
-        }
-    }
-
-    protected void showAddSync(ContextMenu menu, final AccountDisplay account, final int syncMode) {
-        menu.setHeaderTitle(R.string.dialog_sync_add);
-
-        // Create item for each available, unsynced group
-        for (final GroupDelta child : account.mUnsyncedGroups) {
-            if (!child.getShouldSync()) {
-                final CharSequence title = child.getTitle(this);
-                menu.add(title).setOnMenuItemClickListener(new OnMenuItemClickListener() {
-                    public boolean onMenuItemClick(MenuItem item) {
-                        // Adding specific group for syncing
-                        if (child.mUngrouped && syncMode == SYNC_MODE_EVERYTHING) {
-                            account.setShouldSync(true);
-                        } else {
-                            account.setShouldSync(child, true);
-                        }
-                        mAdapter.notifyDataSetChanged();
-                        return true;
-                    }
-                });
-            }
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private void doSaveAction() {
-        if (mAdapter == null || mAdapter.mAccounts == null) {
-            finish();
-            return;
-        }
-
-        setResult(RESULT_OK);
-
-        final ArrayList<ContentProviderOperation> diff = mAdapter.mAccounts.buildDiff();
-        if (diff.isEmpty()) {
-            finish();
-            return;
-        }
-
-        new UpdateTask(this).execute(diff);
-    }
-
-    /**
-     * Background task that persists changes to {@link Groups#GROUP_VISIBLE},
-     * showing spinner dialog to user while updating.
-     */
-    public static class UpdateTask extends
-            WeakAsyncTask<ArrayList<ContentProviderOperation>, Void, Void, Activity> {
-        private ProgressDialog mProgress;
-
-        public UpdateTask(Activity target) {
-            super(target);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        protected void onPreExecute(Activity target) {
-            final Context context = target;
-
-            mProgress = ProgressDialog.show(
-                    context, null, context.getText(R.string.savingDisplayGroups));
-
-            // Before starting this task, start an empty service to protect our
-            // process from being reclaimed by the system.
-            context.startService(new Intent(context, EmptyService.class));
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        protected Void doInBackground(
-                Activity target, ArrayList<ContentProviderOperation>... params) {
-            final Context context = target;
-            final ContentValues values = new ContentValues();
-            final ContentResolver resolver = context.getContentResolver();
-
-            try {
-                final ArrayList<ContentProviderOperation> diff = params[0];
-                resolver.applyBatch(ContactsContract.AUTHORITY, diff);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Problem saving display groups", e);
-            } catch (OperationApplicationException e) {
-                Log.e(TAG, "Problem saving display groups", e);
-            }
-
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        protected void onPostExecute(Activity target, Void result) {
-            final Context context = target;
-
-            try {
-                mProgress.dismiss();
-            } catch (Exception e) {
-                Log.e(TAG, "Error dismissing progress dialog", e);
-            }
-
-            target.finish();
-
-            // Stop the service that was protecting us
-            context.stopService(new Intent(context, EmptyService.class));
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                // Pretend cancel.
-                setResult(Activity.RESULT_CANCELED);
-                finish();
-                return true;
-            default:
-                break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index c9c895b..30d5b36 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -34,10 +34,11 @@
 import com.android.contacts.R;
 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.DefaultContactListAdapter;
 import com.android.contacts.common.list.ProfileAndContactsLoader;
 import com.android.contacts.editor.ContactEditorFragment;
-import com.android.contacts.util.AccountFilterUtil;
+import com.android.contacts.common.util.AccountFilterUtil;
 
 /**
  * Fragment containing a contact list used for browsing (as compared to
diff --git a/src/com/android/contacts/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index c7e4fc2..3fc3135 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -30,11 +30,13 @@
 import com.android.contacts.R;
 import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
+import com.android.contacts.common.list.ContactListFilterController;
 import com.android.contacts.common.list.ContactListItemView;
 import com.android.contacts.common.list.DirectoryListLoader;
 import com.android.contacts.common.list.PhoneNumberListAdapter;
-import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
-import com.android.contacts.util.AccountFilterUtil;
+import com.android.contacts.common.list.ShortcutIntentBuilder;
+import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
+import com.android.contacts.common.util.AccountFilterUtil;
 
 /**
  * Fragment containing a phone number list for picking.
diff --git a/src/com/android/contacts/list/ShortcutIntentBuilder.java b/src/com/android/contacts/list/ShortcutIntentBuilder.java
deleted file mode 100644
index 447328b..0000000
--- a/src/com/android/contacts/list/ShortcutIntentBuilder.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.contacts.list;
-
-import android.app.ActivityManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Paint.FontMetricsInt;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.text.TextUtils.TruncateAt;
-
-import com.android.contacts.common.CallUtil;
-import com.android.contacts.R;
-
-/**
- * Constructs shortcut intents.
- */
-public class ShortcutIntentBuilder {
-
-    private static final String[] CONTACT_COLUMNS = {
-        Contacts.DISPLAY_NAME,
-        Contacts.PHOTO_ID,
-    };
-
-    private static final int CONTACT_DISPLAY_NAME_COLUMN_INDEX = 0;
-    private static final int CONTACT_PHOTO_ID_COLUMN_INDEX = 1;
-
-    private static final String[] PHONE_COLUMNS = {
-        Phone.DISPLAY_NAME,
-        Phone.PHOTO_ID,
-        Phone.NUMBER,
-        Phone.TYPE,
-        Phone.LABEL
-    };
-
-    private static final int PHONE_DISPLAY_NAME_COLUMN_INDEX = 0;
-    private static final int PHONE_PHOTO_ID_COLUMN_INDEX = 1;
-    private static final int PHONE_NUMBER_COLUMN_INDEX = 2;
-    private static final int PHONE_TYPE_COLUMN_INDEX = 3;
-    private static final int PHONE_LABEL_COLUMN_INDEX = 4;
-
-    private static final String[] PHOTO_COLUMNS = {
-        Photo.PHOTO,
-    };
-
-    private static final int PHOTO_PHOTO_COLUMN_INDEX = 0;
-
-    private static final String PHOTO_SELECTION = Photo._ID + "=?";
-
-    private final OnShortcutIntentCreatedListener mListener;
-    private final Context mContext;
-    private int mIconSize;
-    private final int mIconDensity;
-    private final int mBorderWidth;
-    private final int mBorderColor;
-
-    /**
-     * This is a hidden API of the launcher in JellyBean that allows us to disable the animation
-     * that it would usually do, because it interferes with our own animation for QuickContact
-     */
-    public static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
-            "com.android.launcher.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";
-
-    /**
-     * Listener interface.
-     */
-    public interface OnShortcutIntentCreatedListener {
-
-        /**
-         * Callback for shortcut intent creation.
-         *
-         * @param uri the original URI for which the shortcut intent has been
-         *            created.
-         * @param shortcutIntent resulting shortcut intent.
-         */
-        void onShortcutIntentCreated(Uri uri, Intent shortcutIntent);
-    }
-
-    public ShortcutIntentBuilder(Context context, OnShortcutIntentCreatedListener listener) {
-        mContext = context;
-        mListener = listener;
-
-        final Resources r = context.getResources();
-        final ActivityManager am = (ActivityManager) context
-                .getSystemService(Context.ACTIVITY_SERVICE);
-        mIconSize = r.getDimensionPixelSize(R.dimen.shortcut_icon_size);
-        if (mIconSize == 0) {
-            mIconSize = am.getLauncherLargeIconSize();
-        }
-        mIconDensity = am.getLauncherLargeIconDensity();
-        mBorderWidth = r.getDimensionPixelOffset(
-                R.dimen.shortcut_icon_border_width);
-        mBorderColor = r.getColor(R.color.shortcut_overlay_text_background);
-    }
-
-    public void createContactShortcutIntent(Uri contactUri) {
-        new ContactLoadingAsyncTask(contactUri).execute();
-    }
-
-    public void createPhoneNumberShortcutIntent(Uri dataUri, String shortcutAction) {
-        new PhoneNumberLoadingAsyncTask(dataUri, shortcutAction).execute();
-    }
-
-    /**
-     * An asynchronous task that loads name, photo and other data from the database.
-     */
-    private abstract class LoadingAsyncTask extends AsyncTask<Void, Void, Void> {
-        protected Uri mUri;
-        protected String mContentType;
-        protected String mDisplayName;
-        protected byte[] mBitmapData;
-        protected long mPhotoId;
-
-        public LoadingAsyncTask(Uri uri) {
-            mUri = uri;
-        }
-
-        @Override
-        protected Void doInBackground(Void... params) {
-            mContentType = mContext.getContentResolver().getType(mUri);
-            loadData();
-            loadPhoto();
-            return null;
-        }
-
-        protected abstract void loadData();
-
-        private void loadPhoto() {
-            if (mPhotoId == 0) {
-                return;
-            }
-
-            ContentResolver resolver = mContext.getContentResolver();
-            Cursor cursor = resolver.query(Data.CONTENT_URI, PHOTO_COLUMNS, PHOTO_SELECTION,
-                    new String[] { String.valueOf(mPhotoId) }, null);
-            if (cursor != null) {
-                try {
-                    if (cursor.moveToFirst()) {
-                        mBitmapData = cursor.getBlob(PHOTO_PHOTO_COLUMN_INDEX);
-                    }
-                } finally {
-                    cursor.close();
-                }
-            }
-        }
-    }
-
-    private final class ContactLoadingAsyncTask extends LoadingAsyncTask {
-        public ContactLoadingAsyncTask(Uri uri) {
-            super(uri);
-        }
-
-        @Override
-        protected void loadData() {
-            ContentResolver resolver = mContext.getContentResolver();
-            Cursor cursor = resolver.query(mUri, CONTACT_COLUMNS, null, null, null);
-            if (cursor != null) {
-                try {
-                    if (cursor.moveToFirst()) {
-                        mDisplayName = cursor.getString(CONTACT_DISPLAY_NAME_COLUMN_INDEX);
-                        mPhotoId = cursor.getLong(CONTACT_PHOTO_ID_COLUMN_INDEX);
-                    }
-                } finally {
-                    cursor.close();
-                }
-            }
-        }
-        @Override
-        protected void onPostExecute(Void result) {
-            createContactShortcutIntent(mUri, mContentType, mDisplayName, mBitmapData);
-        }
-    }
-
-    private final class PhoneNumberLoadingAsyncTask extends LoadingAsyncTask {
-        private final String mShortcutAction;
-        private String mPhoneNumber;
-        private int mPhoneType;
-        private String mPhoneLabel;
-
-        public PhoneNumberLoadingAsyncTask(Uri uri, String shortcutAction) {
-            super(uri);
-            mShortcutAction = shortcutAction;
-        }
-
-        @Override
-        protected void loadData() {
-            ContentResolver resolver = mContext.getContentResolver();
-            Cursor cursor = resolver.query(mUri, PHONE_COLUMNS, null, null, null);
-            if (cursor != null) {
-                try {
-                    if (cursor.moveToFirst()) {
-                        mDisplayName = cursor.getString(PHONE_DISPLAY_NAME_COLUMN_INDEX);
-                        mPhotoId = cursor.getLong(PHONE_PHOTO_ID_COLUMN_INDEX);
-                        mPhoneNumber = cursor.getString(PHONE_NUMBER_COLUMN_INDEX);
-                        mPhoneType = cursor.getInt(PHONE_TYPE_COLUMN_INDEX);
-                        mPhoneLabel = cursor.getString(PHONE_LABEL_COLUMN_INDEX);
-                    }
-                } finally {
-                    cursor.close();
-                }
-            }
-        }
-
-        @Override
-        protected void onPostExecute(Void result) {
-            createPhoneNumberShortcutIntent(mUri, mDisplayName, mBitmapData, mPhoneNumber,
-                    mPhoneType, mPhoneLabel, mShortcutAction);
-        }
-    }
-
-    private Bitmap getPhotoBitmap(byte[] bitmapData) {
-        Bitmap bitmap;
-        if (bitmapData != null) {
-            bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length, null);
-        } else {
-            bitmap = ((BitmapDrawable) mContext.getResources().getDrawableForDensity(
-                    R.drawable.ic_contact_picture_holo_light, mIconDensity)).getBitmap();
-        }
-        return bitmap;
-    }
-
-    private void createContactShortcutIntent(Uri contactUri, String contentType, String displayName,
-            byte[] bitmapData) {
-        Bitmap bitmap = getPhotoBitmap(bitmapData);
-
-        Intent shortcutIntent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT);
-
-        // When starting from the launcher, start in a new, cleared task.
-        // CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we
-        // clear the whole thing preemptively here since QuickContactActivity will
-        // finish itself when launching other detail activities.
-        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-
-        // Tell the launcher to not do its animation, because we are doing our own
-        shortcutIntent.putExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION, true);
-
-        shortcutIntent.setDataAndType(contactUri, contentType);
-        shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_MODE,
-                ContactsContract.QuickContact.MODE_LARGE);
-        shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_EXCLUDE_MIMES,
-                (String[]) null);
-
-        final Bitmap icon = generateQuickContactIcon(bitmap);
-
-        Intent intent = new Intent();
-        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
-        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
-        if (TextUtils.isEmpty(displayName)) {
-            intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mContext.getResources().getString(
-                    R.string.missing_name));
-        } else {
-            intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName);
-        }
-
-        mListener.onShortcutIntentCreated(contactUri, intent);
-    }
-
-    private void createPhoneNumberShortcutIntent(Uri uri, String displayName, byte[] bitmapData,
-            String phoneNumber, int phoneType, String phoneLabel, String shortcutAction) {
-        Bitmap bitmap = getPhotoBitmap(bitmapData);
-
-        Uri phoneUri;
-        if (Intent.ACTION_CALL.equals(shortcutAction)) {
-            // Make the URI a direct tel: URI so that it will always continue to work
-            phoneUri = Uri.fromParts(CallUtil.SCHEME_TEL, phoneNumber, null);
-            bitmap = generatePhoneNumberIcon(bitmap, phoneType, phoneLabel,
-                    R.drawable.badge_action_call);
-        } else {
-            phoneUri = Uri.fromParts(CallUtil.SCHEME_SMSTO, phoneNumber, null);
-            bitmap = generatePhoneNumberIcon(bitmap, phoneType, phoneLabel,
-                    R.drawable.badge_action_sms);
-        }
-
-        Intent shortcutIntent = new Intent(shortcutAction, phoneUri);
-        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-
-        Intent intent = new Intent();
-        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
-        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
-        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName);
-
-        mListener.onShortcutIntentCreated(uri, intent);
-    }
-
-    private void drawBorder(Canvas canvas, Rect dst) {
-        // Darken the border
-        final Paint workPaint = new Paint();
-        workPaint.setColor(mBorderColor);
-        workPaint.setStyle(Paint.Style.STROKE);
-        // The stroke is drawn centered on the rect bounds, and since half will be drawn outside the
-        // bounds, we need to double the width for it to appear as intended.
-        workPaint.setStrokeWidth(mBorderWidth * 2);
-        canvas.drawRect(dst, workPaint);
-    }
-
-    private Bitmap generateQuickContactIcon(Bitmap photo) {
-
-        // Setup the drawing classes
-        Bitmap icon = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(icon);
-
-        // Copy in the photo
-        Paint photoPaint = new Paint();
-        photoPaint.setDither(true);
-        photoPaint.setFilterBitmap(true);
-        Rect src = new Rect(0,0, photo.getWidth(),photo.getHeight());
-        Rect dst = new Rect(0,0, mIconSize, mIconSize);
-        canvas.drawBitmap(photo, src, dst, photoPaint);
-
-        drawBorder(canvas, dst);
-
-        Drawable overlay = mContext.getResources().getDrawableForDensity(
-                com.android.internal.R.drawable.quickcontact_badge_overlay_dark, mIconDensity);
-
-        overlay.setBounds(dst);
-        overlay.draw(canvas);
-        canvas.setBitmap(null);
-
-        return icon;
-    }
-
-    /**
-     * Generates a phone number shortcut icon. Adds an overlay describing the type of the phone
-     * number, and if there is a photo also adds the call action icon.
-     */
-    private Bitmap generatePhoneNumberIcon(Bitmap photo, int phoneType, String phoneLabel,
-            int actionResId) {
-        final Resources r = mContext.getResources();
-        final float density = r.getDisplayMetrics().density;
-
-        Bitmap phoneIcon = ((BitmapDrawable) r.getDrawableForDensity(actionResId, mIconDensity))
-                .getBitmap();
-
-        // Setup the drawing classes
-        Bitmap icon = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(icon);
-
-        // Copy in the photo
-        Paint photoPaint = new Paint();
-        photoPaint.setDither(true);
-        photoPaint.setFilterBitmap(true);
-        Rect src = new Rect(0, 0, photo.getWidth(), photo.getHeight());
-        Rect dst = new Rect(0, 0, mIconSize, mIconSize);
-        canvas.drawBitmap(photo, src, dst, photoPaint);
-
-        drawBorder(canvas, dst);
-
-        // Create an overlay for the phone number type
-        CharSequence overlay = Phone.getTypeLabel(r, phoneType, phoneLabel);
-
-        if (overlay != null) {
-            TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
-            textPaint.setTextSize(r.getDimension(R.dimen.shortcut_overlay_text_size));
-            textPaint.setColor(r.getColor(R.color.textColorIconOverlay));
-            textPaint.setShadowLayer(4f, 0, 2f, r.getColor(R.color.textColorIconOverlayShadow));
-
-            final FontMetricsInt fmi = textPaint.getFontMetricsInt();
-
-            // First fill in a darker background around the text to be drawn
-            final Paint workPaint = new Paint();
-            workPaint.setColor(mBorderColor);
-            workPaint.setStyle(Paint.Style.FILL);
-            final int textPadding = r
-                    .getDimensionPixelOffset(R.dimen.shortcut_overlay_text_background_padding);
-            final int textBandHeight = (fmi.descent - fmi.ascent) + textPadding * 2;
-            dst.set(0 + mBorderWidth, mIconSize - textBandHeight, mIconSize - mBorderWidth,
-                    mIconSize - mBorderWidth);
-            canvas.drawRect(dst, workPaint);
-
-            final float sidePadding = mBorderWidth;
-            overlay = TextUtils.ellipsize(overlay, textPaint, mIconSize - 2 * sidePadding,
-                    TruncateAt.END_SMALL);
-            final float textWidth = textPaint.measureText(overlay, 0, overlay.length());
-            canvas.drawText(overlay, 0, overlay.length(), (mIconSize - textWidth) / 2, mIconSize
-                    - fmi.descent - textPadding, textPaint);
-        }
-
-        // Draw the phone action icon as an overlay
-        src.set(0, 0, phoneIcon.getWidth(), phoneIcon.getHeight());
-        int iconWidth = icon.getWidth();
-        dst.set(iconWidth - ((int) (20 * density)), -1,
-                iconWidth, ((int) (19 * density)));
-        dst.offset(-mBorderWidth, mBorderWidth);
-        canvas.drawBitmap(phoneIcon, src, dst, photoPaint);
-
-        canvas.setBitmap(null);
-
-        return icon;
-    }
-}
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
deleted file mode 100644
index f81179b..0000000
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.model;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorDescription;
-import android.accounts.OnAccountsUpdateListener;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentService;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SyncAdapterType;
-import android.content.SyncStatusObserver;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.ContactsContract;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.TimingLogger;
-
-import com.android.contacts.common.MoreContactUtils;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountTypeWithDataSet;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.model.account.ExchangeAccountType;
-import com.android.contacts.common.model.account.ExternalAccountType;
-import com.android.contacts.common.model.account.FallbackAccountType;
-import com.android.contacts.common.model.account.GoogleAccountType;
-import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.common.test.NeededForTesting;
-import com.android.contacts.common.util.Constants;
-import com.android.contacts.list.ContactListFilterController;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Singleton holder for all parsed {@link AccountType} available on the
- * system, typically filled through {@link PackageManager} queries.
- */
-public abstract class AccountTypeManager {
-    static final String TAG = "AccountTypeManager";
-
-    private static final Object mInitializationLock = new Object();
-    private static AccountTypeManager mAccountTypeManager;
-
-    /**
-     * Requests the singleton instance of {@link AccountTypeManager} with data bound from
-     * the available authenticators. This method can safely be called from the UI thread.
-     */
-    public static AccountTypeManager getInstance(Context context) {
-        synchronized (mInitializationLock) {
-            if (mAccountTypeManager == null) {
-                context = context.getApplicationContext();
-                mAccountTypeManager = new AccountTypeManagerImpl(context);
-            }
-        }
-        return mAccountTypeManager;
-    }
-
-    /**
-     * Set the instance of account type manager.  This is only for and should only be used by unit
-     * tests.  While having this method is not ideal, it's simpler than the alternative of
-     * holding this as a service in the ContactsApplication context class.
-     *
-     * @param mockManager The mock AccountTypeManager.
-     */
-    @NeededForTesting
-    public static void setInstanceForTest(AccountTypeManager mockManager) {
-        synchronized (mInitializationLock) {
-            mAccountTypeManager = mockManager;
-        }
-    }
-
-    /**
-     * Returns the list of all accounts (if contactWritableOnly is false) or just the list of
-     * contact writable accounts (if contactWritableOnly is true).
-     */
-    // TODO: Consider splitting this into getContactWritableAccounts() and getAllAccounts()
-    public abstract List<AccountWithDataSet> getAccounts(boolean contactWritableOnly);
-
-    /**
-     * Returns the list of accounts that are group writable.
-     */
-    public abstract List<AccountWithDataSet> getGroupWritableAccounts();
-
-    public abstract AccountType getAccountType(AccountTypeWithDataSet accountTypeWithDataSet);
-
-    public final AccountType getAccountType(String accountType, String dataSet) {
-        return getAccountType(AccountTypeWithDataSet.get(accountType, dataSet));
-    }
-
-    public final AccountType getAccountTypeForAccount(AccountWithDataSet account) {
-        return getAccountType(account.getAccountTypeWithDataSet());
-    }
-
-    /**
-     * @return Unmodifiable map from {@link AccountTypeWithDataSet}s to {@link AccountType}s
-     * which support the "invite" feature and have one or more account.
-     *
-     * This is a filtered down and more "usable" list compared to
-     * {@link #getAllInvitableAccountTypes}, where usable is defined as:
-     * (1) making sure that the app that contributed the account type is not disabled
-     * (in order to avoid presenting the user with an option that does nothing), and
-     * (2) that there is at least one raw contact with that account type in the database
-     * (assuming that the user probably doesn't use that account type).
-     *
-     * Warning: Don't use on the UI thread because this can scan the database.
-     */
-    public abstract Map<AccountTypeWithDataSet, AccountType> getUsableInvitableAccountTypes();
-
-    /**
-     * Find the best {@link DataKind} matching the requested
-     * {@link AccountType#accountType}, {@link AccountType#dataSet}, and {@link DataKind#mimeType}.
-     * If no direct match found, we try searching {@link FallbackAccountType}.
-     */
-    public DataKind getKindOrFallback(AccountType type, String mimeType) {
-        return type == null ? null : type.getKindForMimetype(mimeType);
-    }
-
-    /**
-     * Returns all registered {@link AccountType}s, including extension ones.
-     *
-     * @param contactWritableOnly if true, it only returns ones that support writing contacts.
-     */
-    public abstract List<AccountType> getAccountTypes(boolean contactWritableOnly);
-
-    /**
-     * @param contactWritableOnly if true, it only returns ones that support writing contacts.
-     * @return true when this instance contains the given account.
-     */
-    public boolean contains(AccountWithDataSet account, boolean contactWritableOnly) {
-        for (AccountWithDataSet account_2 : getAccounts(false)) {
-            if (account.equals(account_2)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
-
-class AccountTypeManagerImpl extends AccountTypeManager
-        implements OnAccountsUpdateListener, SyncStatusObserver {
-
-    private static final Map<AccountTypeWithDataSet, AccountType>
-            EMPTY_UNMODIFIABLE_ACCOUNT_TYPE_MAP =
-            Collections.unmodifiableMap(new HashMap<AccountTypeWithDataSet, AccountType>());
-
-    /**
-     * A sample contact URI used to test whether any activities will respond to an
-     * invitable intent with the given URI as the intent data. This doesn't need to be
-     * specific to a real contact because an app that intercepts the intent should probably do so
-     * for all types of contact URIs.
-     */
-    private static final Uri SAMPLE_CONTACT_URI = ContactsContract.Contacts.getLookupUri(
-            1, "xxx");
-
-    private Context mContext;
-    private AccountManager mAccountManager;
-
-    private AccountType mFallbackAccountType;
-
-    private List<AccountWithDataSet> mAccounts = Lists.newArrayList();
-    private List<AccountWithDataSet> mContactWritableAccounts = Lists.newArrayList();
-    private List<AccountWithDataSet> mGroupWritableAccounts = Lists.newArrayList();
-    private Map<AccountTypeWithDataSet, AccountType> mAccountTypesWithDataSets = Maps.newHashMap();
-    private Map<AccountTypeWithDataSet, AccountType> mInvitableAccountTypes =
-            EMPTY_UNMODIFIABLE_ACCOUNT_TYPE_MAP;
-
-    private final InvitableAccountTypeCache mInvitableAccountTypeCache;
-
-    /**
-     * The boolean value is equal to true if the {@link InvitableAccountTypeCache} has been
-     * initialized. False otherwise.
-     */
-    private final AtomicBoolean mInvitablesCacheIsInitialized = new AtomicBoolean(false);
-
-    /**
-     * The boolean value is equal to true if the {@link FindInvitablesTask} is still executing.
-     * False otherwise.
-     */
-    private final AtomicBoolean mInvitablesTaskIsRunning = new AtomicBoolean(false);
-
-    private static final int MESSAGE_LOAD_DATA = 0;
-    private static final int MESSAGE_PROCESS_BROADCAST_INTENT = 1;
-
-    private HandlerThread mListenerThread;
-    private Handler mListenerHandler;
-
-    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
-    private final Runnable mCheckFilterValidityRunnable = new Runnable () {
-        @Override
-        public void run() {
-            ContactListFilterController.getInstance(mContext).checkFilterValidity(true);
-        }
-    };
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Message msg = mListenerHandler.obtainMessage(MESSAGE_PROCESS_BROADCAST_INTENT, intent);
-            mListenerHandler.sendMessage(msg);
-        }
-
-    };
-
-    /* A latch that ensures that asynchronous initialization completes before data is used */
-    private volatile CountDownLatch mInitializationLatch = new CountDownLatch(1);
-
-    private static final Comparator<Account> ACCOUNT_COMPARATOR = new Comparator<Account>() {
-        @Override
-        public int compare(Account a, Account b) {
-            String aDataSet = null;
-            String bDataSet = null;
-            if (a instanceof AccountWithDataSet) {
-                aDataSet = ((AccountWithDataSet) a).dataSet;
-            }
-            if (b instanceof AccountWithDataSet) {
-                bDataSet = ((AccountWithDataSet) b).dataSet;
-            }
-
-            if (Objects.equal(a.name, b.name) && Objects.equal(a.type, b.type)
-                    && Objects.equal(aDataSet, bDataSet)) {
-                return 0;
-            } else if (b.name == null || b.type == null) {
-                return -1;
-            } else if (a.name == null || a.type == null) {
-                return 1;
-            } else {
-                int diff = a.name.compareTo(b.name);
-                if (diff != 0) {
-                    return diff;
-                }
-                diff = a.type.compareTo(b.type);
-                if (diff != 0) {
-                    return diff;
-                }
-
-                // Accounts without data sets get sorted before those that have them.
-                if (aDataSet != null) {
-                    return bDataSet == null ? 1 : aDataSet.compareTo(bDataSet);
-                } else {
-                    return -1;
-                }
-            }
-        }
-    };
-
-    /**
-     * Internal constructor that only performs initial parsing.
-     */
-    public AccountTypeManagerImpl(Context context) {
-        mContext = context;
-        mFallbackAccountType = new FallbackAccountType(context);
-
-        mAccountManager = AccountManager.get(mContext);
-
-        mListenerThread = new HandlerThread("AccountChangeListener");
-        mListenerThread.start();
-        mListenerHandler = new Handler(mListenerThread.getLooper()) {
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case MESSAGE_LOAD_DATA:
-                        loadAccountsInBackground();
-                        break;
-                    case MESSAGE_PROCESS_BROADCAST_INTENT:
-                        processBroadcastIntent((Intent) msg.obj);
-                        break;
-                }
-            }
-        };
-
-        mInvitableAccountTypeCache = new InvitableAccountTypeCache();
-
-        // Request updates when packages or accounts change
-        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
-        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        filter.addDataScheme("package");
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-        IntentFilter sdFilter = new IntentFilter();
-        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
-        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
-        mContext.registerReceiver(mBroadcastReceiver, sdFilter);
-
-        // Request updates when locale is changed so that the order of each field will
-        // be able to be changed on the locale change.
-        filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-
-        mAccountManager.addOnAccountsUpdatedListener(this, mListenerHandler, false);
-
-        ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, this);
-
-        mListenerHandler.sendEmptyMessage(MESSAGE_LOAD_DATA);
-    }
-
-    @Override
-    public void onStatusChanged(int which) {
-        mListenerHandler.sendEmptyMessage(MESSAGE_LOAD_DATA);
-    }
-
-    public void processBroadcastIntent(Intent intent) {
-        mListenerHandler.sendEmptyMessage(MESSAGE_LOAD_DATA);
-    }
-
-    /* This notification will arrive on the background thread */
-    public void onAccountsUpdated(Account[] accounts) {
-        // Refresh to catch any changed accounts
-        loadAccountsInBackground();
-    }
-
-    /**
-     * Returns instantly if accounts and account types have already been loaded.
-     * Otherwise waits for the background thread to complete the loading.
-     */
-    void ensureAccountsLoaded() {
-        CountDownLatch latch = mInitializationLatch;
-        if (latch == null) {
-            return;
-        }
-        while (true) {
-            try {
-                latch.await();
-                return;
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
-
-    /**
-     * Loads account list and corresponding account types (potentially with data sets). Always
-     * called on a background thread.
-     */
-    protected void loadAccountsInBackground() {
-        if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
-            Log.d(Constants.PERFORMANCE_TAG, "AccountTypeManager.loadAccountsInBackground start");
-        }
-        TimingLogger timings = new TimingLogger(TAG, "loadAccountsInBackground");
-        final long startTime = SystemClock.currentThreadTimeMillis();
-        final long startTimeWall = SystemClock.elapsedRealtime();
-
-        // Account types, keyed off the account type and data set concatenation.
-        final Map<AccountTypeWithDataSet, AccountType> accountTypesByTypeAndDataSet =
-                Maps.newHashMap();
-
-        // The same AccountTypes, but keyed off {@link RawContacts#ACCOUNT_TYPE}.  Since there can
-        // be multiple account types (with different data sets) for the same type of account, each
-        // type string may have multiple AccountType entries.
-        final Map<String, List<AccountType>> accountTypesByType = Maps.newHashMap();
-
-        final List<AccountWithDataSet> allAccounts = Lists.newArrayList();
-        final List<AccountWithDataSet> contactWritableAccounts = Lists.newArrayList();
-        final List<AccountWithDataSet> groupWritableAccounts = Lists.newArrayList();
-        final Set<String> extensionPackages = Sets.newHashSet();
-
-        final AccountManager am = mAccountManager;
-        final IContentService cs = ContentResolver.getContentService();
-
-        try {
-            final SyncAdapterType[] syncs = cs.getSyncAdapterTypes();
-            final AuthenticatorDescription[] auths = am.getAuthenticatorTypes();
-
-            // First process sync adapters to find any that provide contact data.
-            for (SyncAdapterType sync : syncs) {
-                if (!ContactsContract.AUTHORITY.equals(sync.authority)) {
-                    // Skip sync adapters that don't provide contact data.
-                    continue;
-                }
-
-                // Look for the formatting details provided by each sync
-                // adapter, using the authenticator to find general resources.
-                final String type = sync.accountType;
-                final AuthenticatorDescription auth = findAuthenticator(auths, type);
-                if (auth == null) {
-                    Log.w(TAG, "No authenticator found for type=" + type + ", ignoring it.");
-                    continue;
-                }
-
-                AccountType accountType;
-                if (GoogleAccountType.ACCOUNT_TYPE.equals(type)) {
-                    accountType = new GoogleAccountType(mContext, auth.packageName);
-                } else if (ExchangeAccountType.isExchangeType(type)) {
-                    accountType = new ExchangeAccountType(mContext, auth.packageName, type);
-                } else {
-                    // TODO: use syncadapter package instead, since it provides resources
-                    Log.d(TAG, "Registering external account type=" + type
-                            + ", packageName=" + auth.packageName);
-                    accountType = new ExternalAccountType(mContext, auth.packageName, false);
-                }
-                if (!accountType.isInitialized()) {
-                    if (accountType.isEmbedded()) {
-                        throw new IllegalStateException("Problem initializing embedded type "
-                                + accountType.getClass().getCanonicalName());
-                    } else {
-                        // Skip external account types that couldn't be initialized.
-                        continue;
-                    }
-                }
-
-                accountType.accountType = auth.type;
-                accountType.titleRes = auth.labelId;
-                accountType.iconRes = auth.iconId;
-
-                addAccountType(accountType, accountTypesByTypeAndDataSet, accountTypesByType);
-
-                // Check to see if the account type knows of any other non-sync-adapter packages
-                // that may provide other data sets of contact data.
-                extensionPackages.addAll(accountType.getExtensionPackageNames());
-            }
-
-            // If any extension packages were specified, process them as well.
-            if (!extensionPackages.isEmpty()) {
-                Log.d(TAG, "Registering " + extensionPackages.size() + " extension packages");
-                for (String extensionPackage : extensionPackages) {
-                    ExternalAccountType accountType =
-                            new ExternalAccountType(mContext, extensionPackage, true);
-                    if (!accountType.isInitialized()) {
-                        // Skip external account types that couldn't be initialized.
-                        continue;
-                    }
-                    if (!accountType.hasContactsMetadata()) {
-                        Log.w(TAG, "Skipping extension package " + extensionPackage + " because"
-                                + " it doesn't have the CONTACTS_STRUCTURE metadata");
-                        continue;
-                    }
-                    if (TextUtils.isEmpty(accountType.accountType)) {
-                        Log.w(TAG, "Skipping extension package " + extensionPackage + " because"
-                                + " the CONTACTS_STRUCTURE metadata doesn't have the accountType"
-                                + " attribute");
-                        continue;
-                    }
-                    Log.d(TAG, "Registering extension package account type="
-                            + accountType.accountType + ", dataSet=" + accountType.dataSet
-                            + ", packageName=" + extensionPackage);
-
-                    addAccountType(accountType, accountTypesByTypeAndDataSet, accountTypesByType);
-                }
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Problem loading accounts: " + e.toString());
-        }
-        timings.addSplit("Loaded account types");
-
-        // Map in accounts to associate the account names with each account type entry.
-        Account[] accounts = mAccountManager.getAccounts();
-        for (Account account : accounts) {
-            boolean syncable = false;
-            try {
-                syncable = cs.getIsSyncable(account, ContactsContract.AUTHORITY) > 0;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Cannot obtain sync flag for account: " + account, e);
-            }
-
-            if (syncable) {
-                List<AccountType> accountTypes = accountTypesByType.get(account.type);
-                if (accountTypes != null) {
-                    // Add an account-with-data-set entry for each account type that is
-                    // authenticated by this account.
-                    for (AccountType accountType : accountTypes) {
-                        AccountWithDataSet accountWithDataSet = new AccountWithDataSet(
-                                account.name, account.type, accountType.dataSet);
-                        allAccounts.add(accountWithDataSet);
-                        if (accountType.areContactsWritable()) {
-                            contactWritableAccounts.add(accountWithDataSet);
-                        }
-                        if (accountType.isGroupMembershipEditable()) {
-                            groupWritableAccounts.add(accountWithDataSet);
-                        }
-                    }
-                }
-            }
-        }
-
-        Collections.sort(allAccounts, ACCOUNT_COMPARATOR);
-        Collections.sort(contactWritableAccounts, ACCOUNT_COMPARATOR);
-        Collections.sort(groupWritableAccounts, ACCOUNT_COMPARATOR);
-
-        timings.addSplit("Loaded accounts");
-
-        synchronized (this) {
-            mAccountTypesWithDataSets = accountTypesByTypeAndDataSet;
-            mAccounts = allAccounts;
-            mContactWritableAccounts = contactWritableAccounts;
-            mGroupWritableAccounts = groupWritableAccounts;
-            mInvitableAccountTypes = findAllInvitableAccountTypes(
-                    mContext, allAccounts, accountTypesByTypeAndDataSet);
-        }
-
-        timings.dumpToLog();
-        final long endTimeWall = SystemClock.elapsedRealtime();
-        final long endTime = SystemClock.currentThreadTimeMillis();
-
-        Log.i(TAG, "Loaded meta-data for " + mAccountTypesWithDataSets.size() + " account types, "
-                + mAccounts.size() + " accounts in " + (endTimeWall - startTimeWall) + "ms(wall) "
-                + (endTime - startTime) + "ms(cpu)");
-
-        if (mInitializationLatch != null) {
-            mInitializationLatch.countDown();
-            mInitializationLatch = null;
-        }
-        if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
-            Log.d(Constants.PERFORMANCE_TAG, "AccountTypeManager.loadAccountsInBackground finish");
-        }
-
-        // Check filter validity since filter may become obsolete after account update. It must be
-        // done from UI thread.
-        mMainThreadHandler.post(mCheckFilterValidityRunnable);
-    }
-
-    // Bookkeeping method for tracking the known account types in the given maps.
-    private void addAccountType(AccountType accountType,
-            Map<AccountTypeWithDataSet, AccountType> accountTypesByTypeAndDataSet,
-            Map<String, List<AccountType>> accountTypesByType) {
-        accountTypesByTypeAndDataSet.put(accountType.getAccountTypeAndDataSet(), accountType);
-        List<AccountType> accountsForType = accountTypesByType.get(accountType.accountType);
-        if (accountsForType == null) {
-            accountsForType = Lists.newArrayList();
-        }
-        accountsForType.add(accountType);
-        accountTypesByType.put(accountType.accountType, accountsForType);
-    }
-
-    /**
-     * Find a specific {@link AuthenticatorDescription} in the provided list
-     * that matches the given account type.
-     */
-    protected static AuthenticatorDescription findAuthenticator(AuthenticatorDescription[] auths,
-            String accountType) {
-        for (AuthenticatorDescription auth : auths) {
-            if (accountType.equals(auth.type)) {
-                return auth;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return list of all known, contact writable {@link AccountWithDataSet}'s.
-     */
-    @Override
-    public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) {
-        ensureAccountsLoaded();
-        return contactWritableOnly ? mContactWritableAccounts : mAccounts;
-    }
-
-    /**
-     * Return the list of all known, group writable {@link AccountWithDataSet}'s.
-     */
-    public List<AccountWithDataSet> getGroupWritableAccounts() {
-        ensureAccountsLoaded();
-        return mGroupWritableAccounts;
-    }
-
-    /**
-     * Find the best {@link DataKind} matching the requested
-     * {@link AccountType#accountType}, {@link AccountType#dataSet}, and {@link DataKind#mimeType}.
-     * If no direct match found, we try searching {@link FallbackAccountType}.
-     */
-    @Override
-    public DataKind getKindOrFallback(AccountType type, String mimeType) {
-        ensureAccountsLoaded();
-        DataKind kind = null;
-
-        // Try finding account type and kind matching request
-        if (type != null) {
-            kind = type.getKindForMimetype(mimeType);
-        }
-
-        if (kind == null) {
-            // Nothing found, so try fallback as last resort
-            kind = mFallbackAccountType.getKindForMimetype(mimeType);
-        }
-
-        if (kind == null) {
-            Log.w(TAG, "Unknown type=" + type + ", mime=" + mimeType);
-        }
-
-        return kind;
-    }
-
-    /**
-     * Return {@link AccountType} for the given account type and data set.
-     */
-    @Override
-    public AccountType getAccountType(AccountTypeWithDataSet accountTypeWithDataSet) {
-        ensureAccountsLoaded();
-        synchronized (this) {
-            AccountType type = mAccountTypesWithDataSets.get(accountTypeWithDataSet);
-            return type != null ? type : mFallbackAccountType;
-        }
-    }
-
-    /**
-     * @return Unmodifiable map from {@link AccountTypeWithDataSet}s to {@link AccountType}s
-     * which support the "invite" feature and have one or more account. This is an unfiltered
-     * list. See {@link #getUsableInvitableAccountTypes()}.
-     */
-    private Map<AccountTypeWithDataSet, AccountType> getAllInvitableAccountTypes() {
-        ensureAccountsLoaded();
-        return mInvitableAccountTypes;
-    }
-
-    @Override
-    public Map<AccountTypeWithDataSet, AccountType> getUsableInvitableAccountTypes() {
-        ensureAccountsLoaded();
-        // Since this method is not thread-safe, it's possible for multiple threads to encounter
-        // the situation where (1) the cache has not been initialized yet or
-        // (2) an async task to refresh the account type list in the cache has already been
-        // started. Hence we use {@link AtomicBoolean}s and return cached values immediately
-        // while we compute the actual result in the background. We use this approach instead of
-        // using "synchronized" because computing the account type list involves a DB read, and
-        // can potentially cause a deadlock situation if this method is called from code which
-        // holds the DB lock. The trade-off of potentially having an incorrect list of invitable
-        // account types for a short period of time seems more manageable than enforcing the
-        // context in which this method is called.
-
-        // Computing the list of usable invitable account types is done on the fly as requested.
-        // If this method has never been called before, then block until the list has been computed.
-        if (!mInvitablesCacheIsInitialized.get()) {
-            mInvitableAccountTypeCache.setCachedValue(findUsableInvitableAccountTypes(mContext));
-            mInvitablesCacheIsInitialized.set(true);
-        } else {
-            // Otherwise, there is a value in the cache. If the value has expired and
-            // an async task has not already been started by another thread, then kick off a new
-            // async task to compute the list.
-            if (mInvitableAccountTypeCache.isExpired() &&
-                    mInvitablesTaskIsRunning.compareAndSet(false, true)) {
-                new FindInvitablesTask().execute();
-            }
-        }
-
-        return mInvitableAccountTypeCache.getCachedValue();
-    }
-
-    /**
-     * Return all {@link AccountType}s with at least one account which supports "invite", i.e.
-     * its {@link AccountType#getInviteContactActivityClassName()} is not empty.
-     */
-    @VisibleForTesting
-    static Map<AccountTypeWithDataSet, AccountType> findAllInvitableAccountTypes(Context context,
-            Collection<AccountWithDataSet> accounts,
-            Map<AccountTypeWithDataSet, AccountType> accountTypesByTypeAndDataSet) {
-        HashMap<AccountTypeWithDataSet, AccountType> result = Maps.newHashMap();
-        for (AccountWithDataSet account : accounts) {
-            AccountTypeWithDataSet accountTypeWithDataSet = account.getAccountTypeWithDataSet();
-            AccountType type = accountTypesByTypeAndDataSet.get(accountTypeWithDataSet);
-            if (type == null) continue; // just in case
-            if (result.containsKey(accountTypeWithDataSet)) continue;
-
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Type " + accountTypeWithDataSet
-                        + " inviteClass=" + type.getInviteContactActivityClassName());
-            }
-            if (!TextUtils.isEmpty(type.getInviteContactActivityClassName())) {
-                result.put(accountTypeWithDataSet, type);
-            }
-        }
-        return Collections.unmodifiableMap(result);
-    }
-
-    /**
-     * Return all usable {@link AccountType}s that support the "invite" feature from the
-     * list of all potential invitable account types (retrieved from
-     * {@link #getAllInvitableAccountTypes}). A usable invitable account type means:
-     * (1) there is at least 1 raw contact in the database with that account type, and
-     * (2) the app contributing the account type is not disabled.
-     *
-     * Warning: Don't use on the UI thread because this can scan the database.
-     */
-    private Map<AccountTypeWithDataSet, AccountType> findUsableInvitableAccountTypes(
-            Context context) {
-        Map<AccountTypeWithDataSet, AccountType> allInvitables = getAllInvitableAccountTypes();
-        if (allInvitables.isEmpty()) {
-            return EMPTY_UNMODIFIABLE_ACCOUNT_TYPE_MAP;
-        }
-
-        final HashMap<AccountTypeWithDataSet, AccountType> result = Maps.newHashMap();
-        result.putAll(allInvitables);
-
-        final PackageManager packageManager = context.getPackageManager();
-        for (AccountTypeWithDataSet accountTypeWithDataSet : allInvitables.keySet()) {
-            AccountType accountType = allInvitables.get(accountTypeWithDataSet);
-
-            // Make sure that account types don't come from apps that are disabled.
-            Intent invitableIntent = MoreContactUtils.getInvitableIntent(accountType,
-                    SAMPLE_CONTACT_URI);
-            if (invitableIntent == null) {
-                result.remove(accountTypeWithDataSet);
-                continue;
-            }
-            ResolveInfo resolveInfo = packageManager.resolveActivity(invitableIntent,
-                    PackageManager.MATCH_DEFAULT_ONLY);
-            if (resolveInfo == null) {
-                // If we can't find an activity to start for this intent, then there's no point in
-                // showing this option to the user.
-                result.remove(accountTypeWithDataSet);
-                continue;
-            }
-
-            // Make sure that there is at least 1 raw contact with this account type. This check
-            // is non-trivial and should not be done on the UI thread.
-            if (!accountTypeWithDataSet.hasData(context)) {
-                result.remove(accountTypeWithDataSet);
-            }
-        }
-
-        return Collections.unmodifiableMap(result);
-    }
-
-    @Override
-    public List<AccountType> getAccountTypes(boolean contactWritableOnly) {
-        ensureAccountsLoaded();
-        final List<AccountType> accountTypes = Lists.newArrayList();
-        synchronized (this) {
-            for (AccountType type : mAccountTypesWithDataSets.values()) {
-                if (!contactWritableOnly || type.areContactsWritable()) {
-                    accountTypes.add(type);
-                }
-            }
-        }
-        return accountTypes;
-    }
-
-    /**
-     * Background task to find all usable {@link AccountType}s that support the "invite" feature
-     * from the list of all potential invitable account types. Once the work is completed,
-     * the list of account types is stored in the {@link AccountTypeManager}'s
-     * {@link InvitableAccountTypeCache}.
-     */
-    private class FindInvitablesTask extends AsyncTask<Void, Void,
-            Map<AccountTypeWithDataSet, AccountType>> {
-
-        @Override
-        protected Map<AccountTypeWithDataSet, AccountType> doInBackground(Void... params) {
-            return findUsableInvitableAccountTypes(mContext);
-        }
-
-        @Override
-        protected void onPostExecute(Map<AccountTypeWithDataSet, AccountType> accountTypes) {
-            mInvitableAccountTypeCache.setCachedValue(accountTypes);
-            mInvitablesTaskIsRunning.set(false);
-        }
-    }
-
-    /**
-     * This cache holds a list of invitable {@link AccountTypeWithDataSet}s, in the form of a
-     * {@link Map<AccountTypeWithDataSet, AccountType>}. Note that the cached value is valid only
-     * for {@link #TIME_TO_LIVE} milliseconds.
-     */
-    private static final class InvitableAccountTypeCache {
-
-        /**
-         * The cached {@link #mInvitableAccountTypes} list expires after this number of milliseconds
-         * has elapsed.
-         */
-        private static final long TIME_TO_LIVE = 60000;
-
-        private Map<AccountTypeWithDataSet, AccountType> mInvitableAccountTypes;
-
-        private long mTimeLastSet;
-
-        /**
-         * Returns true if the data in this cache is stale and needs to be refreshed. Returns false
-         * otherwise.
-         */
-        public boolean isExpired() {
-             return SystemClock.elapsedRealtime() - mTimeLastSet > TIME_TO_LIVE;
-        }
-
-        /**
-         * Returns the cached value. Note that the caller is responsible for checking
-         * {@link #isExpired()} to ensure that the value is not stale.
-         */
-        public Map<AccountTypeWithDataSet, AccountType> getCachedValue() {
-            return mInvitableAccountTypes;
-        }
-
-        public void setCachedValue(Map<AccountTypeWithDataSet, AccountType> map) {
-            mInvitableAccountTypes = map;
-            mTimeLastSet = SystemClock.elapsedRealtime();
-        }
-    }
-}
diff --git a/src/com/android/contacts/model/ContactLoader.java b/src/com/android/contacts/model/ContactLoader.java
index 6259800..3c1fc9d 100644
--- a/src/com/android/contacts/model/ContactLoader.java
+++ b/src/com/android/contacts/model/ContactLoader.java
@@ -43,6 +43,7 @@
 
 import com.android.contacts.GroupMetaData;
 import com.android.contacts.common.GeoUtil;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountTypeWithDataSet;
 import com.android.contacts.model.dataitem.DataItem;
diff --git a/src/com/android/contacts/model/RawContact.java b/src/com/android/contacts/model/RawContact.java
index c4e5f3e..9ded00e 100644
--- a/src/com/android/contacts/model/RawContact.java
+++ b/src/com/android/contacts/model/RawContact.java
@@ -26,6 +26,7 @@
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 
+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.model.dataitem.DataItem;
diff --git a/src/com/android/contacts/model/RawContactDelta.java b/src/com/android/contacts/model/RawContactDelta.java
index f7ddcc9..373eabd 100644
--- a/src/com/android/contacts/model/RawContactDelta.java
+++ b/src/com/android/contacts/model/RawContactDelta.java
@@ -24,27 +24,21 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.BaseColumns;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Profile;
 import android.provider.ContactsContract.RawContacts;
 import android.util.Log;
 
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.test.NeededForTesting;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+
 /**
  * Contains a {@link RawContact} and records any modifications separately so the
  * original {@link RawContact} can be swapped out with a newer version and the
@@ -559,544 +553,4 @@
         }
     };
 
-    /**
-     * Type of {@link ContentValues} that maintains both an original state and a
-     * modified version of that state. This allows us to build insert, update,
-     * or delete operations based on a "before" {@link Entity} snapshot.
-     */
-    public static class ValuesDelta implements Parcelable {
-        protected ContentValues mBefore;
-        protected ContentValues mAfter;
-        protected String mIdColumn = BaseColumns._ID;
-        private boolean mFromTemplate;
-
-        /**
-         * Next value to assign to {@link #mIdColumn} when building an insert
-         * operation through {@link #fromAfter(ContentValues)}. This is used so
-         * we can concretely reference this {@link ValuesDelta} before it has
-         * been persisted.
-         */
-        protected static int sNextInsertId = -1;
-
-        protected ValuesDelta() {
-        }
-
-        /**
-         * Create {@link ValuesDelta}, using the given object as the
-         * "before" state, usually from an {@link Entity}.
-         */
-        public static ValuesDelta fromBefore(ContentValues before) {
-            final ValuesDelta entry = new ValuesDelta();
-            entry.mBefore = before;
-            entry.mAfter = new ContentValues();
-            return entry;
-        }
-
-        /**
-         * Create {@link ValuesDelta}, using the given object as the "after"
-         * state, usually when we are inserting a row instead of updating.
-         */
-        public static ValuesDelta fromAfter(ContentValues after) {
-            final ValuesDelta entry = new ValuesDelta();
-            entry.mBefore = null;
-            entry.mAfter = after;
-
-            // Assign temporary id which is dropped before insert.
-            entry.mAfter.put(entry.mIdColumn, sNextInsertId--);
-            return entry;
-        }
-
-        @NeededForTesting
-        public ContentValues getAfter() {
-            return mAfter;
-        }
-
-        public boolean containsKey(String key) {
-            return ((mAfter != null && mAfter.containsKey(key)) ||
-                    (mBefore != null && mBefore.containsKey(key)));
-        }
-
-        public String getAsString(String key) {
-            if (mAfter != null && mAfter.containsKey(key)) {
-                return mAfter.getAsString(key);
-            } else if (mBefore != null && mBefore.containsKey(key)) {
-                return mBefore.getAsString(key);
-            } else {
-                return null;
-            }
-        }
-
-        public byte[] getAsByteArray(String key) {
-            if (mAfter != null && mAfter.containsKey(key)) {
-                return mAfter.getAsByteArray(key);
-            } else if (mBefore != null && mBefore.containsKey(key)) {
-                return mBefore.getAsByteArray(key);
-            } else {
-                return null;
-            }
-        }
-
-        public Long getAsLong(String key) {
-            if (mAfter != null && mAfter.containsKey(key)) {
-                return mAfter.getAsLong(key);
-            } else if (mBefore != null && mBefore.containsKey(key)) {
-                return mBefore.getAsLong(key);
-            } else {
-                return null;
-            }
-        }
-
-        public Integer getAsInteger(String key) {
-            return getAsInteger(key, null);
-        }
-
-        public Integer getAsInteger(String key, Integer defaultValue) {
-            if (mAfter != null && mAfter.containsKey(key)) {
-                return mAfter.getAsInteger(key);
-            } else if (mBefore != null && mBefore.containsKey(key)) {
-                return mBefore.getAsInteger(key);
-            } else {
-                return defaultValue;
-            }
-        }
-
-        public boolean isChanged(String key) {
-            if (mAfter == null || !mAfter.containsKey(key)) {
-                return false;
-            }
-
-            Object newValue = mAfter.get(key);
-            Object oldValue = mBefore.get(key);
-
-            if (oldValue == null) {
-                return newValue != null;
-            }
-
-            return !oldValue.equals(newValue);
-        }
-
-        public String getMimetype() {
-            return getAsString(Data.MIMETYPE);
-        }
-
-        public Long getId() {
-            return getAsLong(mIdColumn);
-        }
-
-        public void setIdColumn(String idColumn) {
-            mIdColumn = idColumn;
-        }
-
-        public boolean isPrimary() {
-            final Long isPrimary = getAsLong(Data.IS_PRIMARY);
-            return isPrimary == null ? false : isPrimary != 0;
-        }
-
-        public void setFromTemplate(boolean isFromTemplate) {
-            mFromTemplate = isFromTemplate;
-        }
-
-        public boolean isFromTemplate() {
-            return mFromTemplate;
-        }
-
-        public boolean isSuperPrimary() {
-            final Long isSuperPrimary = getAsLong(Data.IS_SUPER_PRIMARY);
-            return isSuperPrimary == null ? false : isSuperPrimary != 0;
-        }
-
-        public boolean beforeExists() {
-            return (mBefore != null && mBefore.containsKey(mIdColumn));
-        }
-
-        /**
-         * When "after" is present, then visible
-         */
-        public boolean isVisible() {
-            return (mAfter != null);
-        }
-
-        /**
-         * When "after" is wiped, action is "delete"
-         */
-        public boolean isDelete() {
-            return beforeExists() && (mAfter == null);
-        }
-
-        /**
-         * When no "before" or "after", is transient
-         */
-        public boolean isTransient() {
-            return (mBefore == null) && (mAfter == null);
-        }
-
-        /**
-         * When "after" has some changes, action is "update"
-         */
-        public boolean isUpdate() {
-            if (!beforeExists() || mAfter == null || mAfter.size() == 0) {
-                return false;
-            }
-            for (String key : mAfter.keySet()) {
-                Object newValue = mAfter.get(key);
-                Object oldValue = mBefore.get(key);
-                if (oldValue == null) {
-                    if (newValue != null) {
-                        return true;
-                    }
-                } else if (!oldValue.equals(newValue)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * When "after" has no changes, action is no-op
-         */
-        public boolean isNoop() {
-            return beforeExists() && (mAfter != null && mAfter.size() == 0);
-        }
-
-        /**
-         * When no "before" id, and has "after", action is "insert"
-         */
-        public boolean isInsert() {
-            return !beforeExists() && (mAfter != null);
-        }
-
-        public void markDeleted() {
-            mAfter = null;
-        }
-
-        /**
-         * Ensure that our internal structure is ready for storing updates.
-         */
-        private void ensureUpdate() {
-            if (mAfter == null) {
-                mAfter = new ContentValues();
-            }
-        }
-
-        public void put(String key, String value) {
-            ensureUpdate();
-            mAfter.put(key, value);
-        }
-
-        public void put(String key, byte[] value) {
-            ensureUpdate();
-            mAfter.put(key, value);
-        }
-
-        public void put(String key, int value) {
-            ensureUpdate();
-            mAfter.put(key, value);
-        }
-
-        public void put(String key, long value) {
-            ensureUpdate();
-            mAfter.put(key, value);
-        }
-
-        public void putNull(String key) {
-            ensureUpdate();
-            mAfter.putNull(key);
-        }
-
-        public void copyStringFrom(ValuesDelta from, String key) {
-            ensureUpdate();
-            put(key, from.getAsString(key));
-        }
-
-        /**
-         * Return set of all keys defined through this object.
-         */
-        public Set<String> keySet() {
-            final HashSet<String> keys = Sets.newHashSet();
-
-            if (mBefore != null) {
-                for (Map.Entry<String, Object> entry : mBefore.valueSet()) {
-                    keys.add(entry.getKey());
-                }
-            }
-
-            if (mAfter != null) {
-                for (Map.Entry<String, Object> entry : mAfter.valueSet()) {
-                    keys.add(entry.getKey());
-                }
-            }
-
-            return keys;
-        }
-
-        /**
-         * Return complete set of "before" and "after" values mixed together,
-         * giving full state regardless of edits.
-         */
-        public ContentValues getCompleteValues() {
-            final ContentValues values = new ContentValues();
-            if (mBefore != null) {
-                values.putAll(mBefore);
-            }
-            if (mAfter != null) {
-                values.putAll(mAfter);
-            }
-            if (values.containsKey(GroupMembership.GROUP_ROW_ID)) {
-                // Clear to avoid double-definitions, and prefer rows
-                values.remove(GroupMembership.GROUP_SOURCE_ID);
-            }
-
-            return values;
-        }
-
-        /**
-         * Merge the "after" values from the given {@link ValuesDelta},
-         * discarding any existing "after" state. This is typically used when
-         * re-parenting changes onto an updated {@link Entity}.
-         */
-        public static ValuesDelta mergeAfter(ValuesDelta local, ValuesDelta remote) {
-            // Bail early if trying to merge delete with missing local
-            if (local == null && (remote.isDelete() || remote.isTransient())) return null;
-
-            // Create local version if none exists yet
-            if (local == null) local = new ValuesDelta();
-
-            if (!local.beforeExists()) {
-                // Any "before" record is missing, so take all values as "insert"
-                local.mAfter = remote.getCompleteValues();
-            } else {
-                // Existing "update" with only "after" values
-                local.mAfter = remote.mAfter;
-            }
-
-            return local;
-        }
-
-        @Override
-        public boolean equals(Object object) {
-            if (object instanceof ValuesDelta) {
-                // Only exactly equal with both are identical subsets
-                final ValuesDelta other = (ValuesDelta)object;
-                return this.subsetEquals(other) && other.subsetEquals(this);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            final StringBuilder builder = new StringBuilder();
-            toString(builder);
-            return builder.toString();
-        }
-
-        /**
-         * Helper for building string representation, leveraging the given
-         * {@link StringBuilder} to minimize allocations.
-         */
-        public void toString(StringBuilder builder) {
-            builder.append("{ ");
-            builder.append("IdColumn=");
-            builder.append(mIdColumn);
-            builder.append(", FromTemplate=");
-            builder.append(mFromTemplate);
-            builder.append(", ");
-            for (String key : this.keySet()) {
-                builder.append(key);
-                builder.append("=");
-                builder.append(this.getAsString(key));
-                builder.append(", ");
-            }
-            builder.append("}");
-        }
-
-        /**
-         * Check if the given {@link ValuesDelta} is both a subset of this
-         * object, and any defined keys have equal values.
-         */
-        public boolean subsetEquals(ValuesDelta other) {
-            for (String key : this.keySet()) {
-                final String ourValue = this.getAsString(key);
-                final String theirValue = other.getAsString(key);
-                if (ourValue == null) {
-                    // If they have value when we're null, no match
-                    if (theirValue != null) return false;
-                } else {
-                    // If both values defined and aren't equal, no match
-                    if (!ourValue.equals(theirValue)) return false;
-                }
-            }
-            // All values compared and matched
-            return true;
-        }
-
-        /**
-         * Build a {@link ContentProviderOperation} that will transform our
-         * "before" state into our "after" state, using insert, update, or
-         * delete as needed.
-         */
-        public ContentProviderOperation.Builder buildDiff(Uri targetUri) {
-            Builder builder = null;
-            if (isInsert()) {
-                // Changed values are "insert" back-referenced to Contact
-                mAfter.remove(mIdColumn);
-                builder = ContentProviderOperation.newInsert(targetUri);
-                builder.withValues(mAfter);
-            } else if (isDelete()) {
-                // When marked for deletion and "before" exists, then "delete"
-                builder = ContentProviderOperation.newDelete(targetUri);
-                builder.withSelection(mIdColumn + "=" + getId(), null);
-            } else if (isUpdate()) {
-                // When has changes and "before" exists, then "update"
-                builder = ContentProviderOperation.newUpdate(targetUri);
-                builder.withSelection(mIdColumn + "=" + getId(), null);
-                builder.withValues(mAfter);
-            }
-            return builder;
-        }
-
-        /** {@inheritDoc} */
-        public int describeContents() {
-            // Nothing special about this parcel
-            return 0;
-        }
-
-        /** {@inheritDoc} */
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeParcelable(mBefore, flags);
-            dest.writeParcelable(mAfter, flags);
-            dest.writeString(mIdColumn);
-        }
-
-        public void readFromParcel(Parcel source) {
-            final ClassLoader loader = getClass().getClassLoader();
-            mBefore = source.<ContentValues> readParcelable(loader);
-            mAfter = source.<ContentValues> readParcelable(loader);
-            mIdColumn = source.readString();
-        }
-
-        public static final Parcelable.Creator<ValuesDelta> CREATOR = new Parcelable.Creator<ValuesDelta>() {
-            public ValuesDelta createFromParcel(Parcel in) {
-                final ValuesDelta values = new ValuesDelta();
-                values.readFromParcel(in);
-                return values;
-            }
-
-            public ValuesDelta[] newArray(int size) {
-                return new ValuesDelta[size];
-            }
-        };
-
-        public void setGroupRowId(long groupId) {
-            put(GroupMembership.GROUP_ROW_ID, groupId);
-        }
-
-        public Long getGroupRowId() {
-            return getAsLong(GroupMembership.GROUP_ROW_ID);
-        }
-
-        public void setPhoto(byte[] value) {
-            put(Photo.PHOTO, value);
-        }
-
-        public byte[] getPhoto() {
-            return getAsByteArray(Photo.PHOTO);
-        }
-
-        public void setSuperPrimary(boolean val) {
-            if (val) {
-                put(Data.IS_SUPER_PRIMARY, 1);
-            } else {
-                put(Data.IS_SUPER_PRIMARY, 0);
-            }
-        }
-
-        public void setPhoneticFamilyName(String value) {
-            put(StructuredName.PHONETIC_FAMILY_NAME, value);
-        }
-
-        public void setPhoneticMiddleName(String value) {
-            put(StructuredName.PHONETIC_MIDDLE_NAME, value);
-        }
-
-        public void setPhoneticGivenName(String value) {
-            put(StructuredName.PHONETIC_GIVEN_NAME, value);
-        }
-
-        public String getPhoneticFamilyName() {
-            return getAsString(StructuredName.PHONETIC_FAMILY_NAME);
-        }
-
-        public String getPhoneticMiddleName() {
-            return getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
-        }
-
-        public String getPhoneticGivenName() {
-            return getAsString(StructuredName.PHONETIC_GIVEN_NAME);
-        }
-
-        public String getDisplayName() {
-            return getAsString(StructuredName.DISPLAY_NAME);
-        }
-
-        public void setDisplayName(String name) {
-            if (name == null) {
-                putNull(StructuredName.DISPLAY_NAME);
-            } else {
-                put(StructuredName.DISPLAY_NAME, name);
-            }
-        }
-
-        public void copyStructuredNameFieldsFrom(ValuesDelta name) {
-            copyStringFrom(name, StructuredName.DISPLAY_NAME);
-
-            copyStringFrom(name, StructuredName.GIVEN_NAME);
-            copyStringFrom(name, StructuredName.FAMILY_NAME);
-            copyStringFrom(name, StructuredName.PREFIX);
-            copyStringFrom(name, StructuredName.MIDDLE_NAME);
-            copyStringFrom(name, StructuredName.SUFFIX);
-
-            copyStringFrom(name, StructuredName.PHONETIC_GIVEN_NAME);
-            copyStringFrom(name, StructuredName.PHONETIC_MIDDLE_NAME);
-            copyStringFrom(name, StructuredName.PHONETIC_FAMILY_NAME);
-
-            copyStringFrom(name, StructuredName.FULL_NAME_STYLE);
-            copyStringFrom(name, StructuredName.PHONETIC_NAME_STYLE);
-        }
-
-        public String getPhoneNumber() {
-            return getAsString(Phone.NUMBER);
-        }
-
-        public String getPhoneNormalizedNumber() {
-            return getAsString(Phone.NORMALIZED_NUMBER);
-        }
-
-        public boolean phoneHasType() {
-            return containsKey(Phone.TYPE);
-        }
-
-        public int getPhoneType() {
-            return getAsInteger(Phone.TYPE);
-        }
-
-        public String getPhoneLabel() {
-            return getAsString(Phone.LABEL);
-        }
-
-        public String getEmailData() {
-            return getAsString(Email.DATA);
-        }
-
-        public boolean emailHasType() {
-            return containsKey(Email.TYPE);
-        }
-
-        public int getEmailType() {
-            return getAsInteger(Email.TYPE);
-        }
-
-        public String getEmailLabel() {
-            return getAsString(Email.LABEL);
-        }
-    }
 }
diff --git a/src/com/android/contacts/model/RawContactDeltaList.java b/src/com/android/contacts/model/RawContactDeltaList.java
index 82dd494..600a751 100644
--- a/src/com/android/contacts/model/RawContactDeltaList.java
+++ b/src/com/android/contacts/model/RawContactDeltaList.java
@@ -30,7 +30,7 @@
 import android.provider.ContactsContract.RawContacts;
 import android.util.Log;
 
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
diff --git a/src/com/android/contacts/model/RawContactModifier.java b/src/com/android/contacts/model/RawContactModifier.java
index 1b8d0fe..f1f5697 100644
--- a/src/com/android/contacts/model/RawContactModifier.java
+++ b/src/com/android/contacts/model/RawContactModifier.java
@@ -47,10 +47,11 @@
 import android.util.SparseIntArray;
 
 import com.android.contacts.ContactsUtils;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.util.CommonDateUtils;
 import com.android.contacts.editor.EventFieldEditorView;
 import com.android.contacts.editor.PhoneticNameEditorView;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountType.EditField;
 import com.android.contacts.common.model.account.AccountType.EditType;
diff --git a/src/com/android/contacts/model/dataitem/DataItem.java b/src/com/android/contacts/model/dataitem/DataItem.java
index 38d0c03..f1b2ccc 100644
--- a/src/com/android/contacts/model/dataitem/DataItem.java
+++ b/src/com/android/contacts/model/dataitem/DataItem.java
@@ -154,4 +154,15 @@
         CharSequence actionBody = kind.actionBody.inflateUsing(context, mContentValues);
         return actionBody == null ? null : actionBody.toString();
     }
+
+    /**
+     * This builds the data string(intended for display) depending on the type of data item. It
+     * returns the same value as {@link #buildDataString} by default, but certain data items can
+     * override it to provide their version of formatted data strings.
+     *
+     * @return Data string representing the data item, possibly formatted for display
+     */
+    public String buildDataStringForDisplay(Context context, DataKind kind) {
+        return buildDataString(context, kind);
+    }
 }
diff --git a/src/com/android/contacts/model/dataitem/PhoneDataItem.java b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
index 66b9018..c69bee1 100644
--- a/src/com/android/contacts/model/dataitem/PhoneDataItem.java
+++ b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
@@ -17,10 +17,13 @@
 package com.android.contacts.model.dataitem;
 
 import android.content.ContentValues;
+import android.content.Context;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.telephony.PhoneNumberUtils;
 
+import com.android.contacts.common.model.dataitem.DataKind;
+
 /**
  * Represents a phone data item, wrapping the columns in
  * {@link ContactsContract.CommonDataKinds.Phone}.
@@ -68,4 +71,17 @@
         }
     }
 
+    /**
+     * Returns the formatted phone number (if already computed using {@link
+     * #computeFormattedPhoneNumber}). Otherwise this method returns the unformatted phone number.
+     */
+    @Override
+    public String buildDataStringForDisplay(Context context, DataKind kind) {
+        final String formatted = getFormattedPhoneNumber();
+        if (formatted != null) {
+            return formatted;
+        } else {
+            return getNumber();
+        }
+    }
 }
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 90a97de..1bf332e 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -96,7 +96,7 @@
         }
 
         mIsPrimary = item.isSuperPrimary();
-        mBody = item.buildDataString(context, kind);
+        mBody = item.buildDataStringForDisplay(context, kind);
 
         mDataId = item.getId();
         mDataUri = ContentUris.withAppendedId(Data.CONTENT_URI, mDataId);
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index a585dbe..00ac7ba 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -58,7 +58,7 @@
 
 import com.android.contacts.common.Collapser;
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.Contact;
 import com.android.contacts.model.ContactLoader;
 import com.android.contacts.model.RawContact;
@@ -551,7 +551,10 @@
             if (mLookupUri == null) {
                 Log.wtf(TAG, "Lookup uri wasn't initialized. Loader was started too early");
             }
-            return new ContactLoader(getApplicationContext(), mLookupUri, false);
+            return new ContactLoader(getApplicationContext(), mLookupUri,
+                    false /*loadGroupMetaData*/, false /*loadStreamItems*/,
+                    false /*loadInvitableAccountTypes*/, false /*postViewNotification*/,
+                    true /*computeFormattedPhoneNumber*/);
         }
     };
 
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index 5c584b4..40c29b9 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -38,7 +38,7 @@
 import android.widget.RemoteViews;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.Contact;
 import com.android.contacts.model.ContactLoader;
 import com.android.contacts.common.model.account.AccountType;
diff --git a/src/com/android/contacts/util/AccountFilterUtil.java b/src/com/android/contacts/util/AccountFilterUtil.java
deleted file mode 100644
index a6df994..0000000
--- a/src/com/android/contacts/util/AccountFilterUtil.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.contacts.R;
-import com.android.contacts.list.AccountFilterActivity;
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.list.ContactListFilterController;
-
-/**
- * Utility class for account filter manipulation.
- */
-public class AccountFilterUtil {
-    private static final String TAG = AccountFilterUtil.class.getSimpleName();
-
-    /**
-     * Find TextView with the id "account_filter_header" and set correct text for the account
-     * filter header.
-     *
-     * @param filterContainer View containing TextView with id "account_filter_header"
-     * @return true when header text is set in the call. You may use this for conditionally
-     * showing or hiding this entire view.
-     */
-    public static boolean updateAccountFilterTitleForPeople(View filterContainer,
-            ContactListFilter filter, boolean showTitleForAllAccounts) {
-        return updateAccountFilterTitle(filterContainer, filter, showTitleForAllAccounts, false);
-    }
-
-    /**
-     * Similar to {@link #updateAccountFilterTitleForPeople(View, ContactListFilter, boolean,
-     * boolean)}, but for Phone UI.
-     */
-    public static boolean updateAccountFilterTitleForPhone(View filterContainer,
-            ContactListFilter filter, boolean showTitleForAllAccounts) {
-        return updateAccountFilterTitle(
-                filterContainer, filter, showTitleForAllAccounts, true);
-    }
-
-    private static boolean updateAccountFilterTitle(View filterContainer,
-            ContactListFilter filter, boolean showTitleForAllAccounts,
-            boolean forPhone) {
-        final Context context = filterContainer.getContext();
-        final TextView headerTextView = (TextView)
-                filterContainer.findViewById(R.id.account_filter_header);
-
-        boolean textWasSet = false;
-        if (filter != null) {
-            if (forPhone) {
-                if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
-                    if (showTitleForAllAccounts) {
-                        headerTextView.setText(R.string.list_filter_phones);
-                        textWasSet = true;
-                    }
-                } else if (filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
-                    headerTextView.setText(context.getString(
-                            R.string.listAllContactsInAccount, filter.accountName));
-                    textWasSet = true;
-                } else if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
-                    headerTextView.setText(R.string.listCustomView);
-                    textWasSet = true;
-                } else {
-                    Log.w(TAG, "Filter type \"" + filter.filterType + "\" isn't expected.");
-                }
-            } else {
-                if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
-                    if (showTitleForAllAccounts) {
-                        headerTextView.setText(R.string.list_filter_all_accounts);
-                        textWasSet = true;
-                    }
-                } else if (filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
-                    headerTextView.setText(context.getString(
-                            R.string.listAllContactsInAccount, filter.accountName));
-                    textWasSet = true;
-                } else if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
-                    headerTextView.setText(R.string.listCustomView);
-                    textWasSet = true;
-                } else if (filter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
-                    headerTextView.setText(R.string.listSingleContact);
-                    textWasSet = true;
-                } else {
-                    Log.w(TAG, "Filter type \"" + filter.filterType + "\" isn't expected.");
-                }
-            }
-        } else {
-            Log.w(TAG, "Filter is null.");
-        }
-        return textWasSet;
-    }
-
-    /**
-     * Launches account filter setting Activity using
-     * {@link Activity#startActivityForResult(Intent, int)}.
-     *
-     * @param activity
-     * @param requestCode requestCode for {@link Activity#startActivityForResult(Intent, int)}
-     * @param currentFilter currently-selected filter, so that it can be displayed as activated.
-     */
-    public static void startAccountFilterActivityForResult(
-            Activity activity, int requestCode, ContactListFilter currentFilter) {
-        final Intent intent = new Intent(activity, AccountFilterActivity.class);
-        intent.putExtra(AccountFilterActivity.KEY_EXTRA_CURRENT_FILTER, currentFilter);
-        activity.startActivityForResult(intent, requestCode);
-    }
-
-    /**
-     * Very similar to
-     * {@link #startAccountFilterActivityForResult(Activity, int, ContactListFilter)}
-     * but uses Fragment instead.
-     */
-    public static void startAccountFilterActivityForResult(
-            Fragment fragment, int requestCode, ContactListFilter currentFilter) {
-        final Activity activity = fragment.getActivity();
-        if (activity != null) {
-            final Intent intent = new Intent(activity, AccountFilterActivity.class);
-            intent.putExtra(AccountFilterActivity.KEY_EXTRA_CURRENT_FILTER, currentFilter);
-            fragment.startActivityForResult(intent, requestCode);
-        } else {
-            Log.w(TAG, "getActivity() returned null. Ignored");
-        }
-    }
-
-    /**
-     * Useful method to handle onActivityResult() for
-     * {@link #startAccountFilterActivityForResult(Activity, int)} or
-     * {@link #startAccountFilterActivityForResult(Fragment, int)}.
-     *
-     * This will update filter via a given ContactListFilterController.
-     */
-    public static void handleAccountFilterResult(
-            ContactListFilterController filterController, int resultCode, Intent data) {
-        if (resultCode == Activity.RESULT_OK) {
-            final ContactListFilter filter = (ContactListFilter)
-                    data.getParcelableExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER);
-            if (filter == null) {
-                return;
-            }
-            if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
-                filterController.selectCustomFilter();
-            } else {
-                filterController.setContactListFilter(filter, true);
-            }
-        }
-    }
-}
diff --git a/src/com/android/contacts/util/AccountSelectionUtil.java b/src/com/android/contacts/util/AccountSelectionUtil.java
index d3c9d14..1d456b3 100644
--- a/src/com/android/contacts/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/util/AccountSelectionUtil.java
@@ -31,7 +31,7 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 
diff --git a/src/com/android/contacts/util/AccountsListAdapter.java b/src/com/android/contacts/util/AccountsListAdapter.java
index 2740049..a2891a8 100644
--- a/src/com/android/contacts/util/AccountsListAdapter.java
+++ b/src/com/android/contacts/util/AccountsListAdapter.java
@@ -26,7 +26,7 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 
diff --git a/src/com/android/contacts/util/EmptyService.java b/src/com/android/contacts/util/EmptyService.java
deleted file mode 100644
index 2e6a159..0000000
--- a/src/com/android/contacts/util/EmptyService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Background {@link Service} that is used to keep our process alive long enough
- * for background threads to finish. Started and stopped directly by specific
- * background tasks when needed.
- */
-public class EmptyService extends Service {
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-}
diff --git a/src/com/android/contacts/util/LocalizedNameResolver.java b/src/com/android/contacts/util/LocalizedNameResolver.java
deleted file mode 100644
index ec0b812..0000000
--- a/src/com/android/contacts/util/LocalizedNameResolver.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.util;
-
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorDescription;
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Xml;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-
-/**
- * Retrieves localized names per account type. This allows customizing texts like
- * "All Contacts" for certain account types, but e.g. "All Friends" or "All Connections" for others.
- */
-public class LocalizedNameResolver  {
-    private static final String TAG = "LocalizedNameResolver";
-
-    /**
-     * Meta-data key for the contacts configuration associated with a sync service.
-     */
-    private static final String METADATA_CONTACTS = "android.provider.CONTACTS_STRUCTURE";
-
-    private static final String CONTACTS_DATA_KIND = "ContactsDataKind";
-
-    /**
-     * Returns the name for All Contacts for the specified account type.
-     */
-    public static String getAllContactsName(Context context, String accountType) {
-        if (context == null) throw new IllegalArgumentException("Context must not be null");
-        if (accountType == null) return null;
-
-        return resolveAllContactsName(context, accountType);
-     }
-
-    /**
-     * Finds "All Contacts"-Name for the specified account type.
-     */
-    private static String resolveAllContactsName(Context context, String accountType) {
-        final AccountManager am = AccountManager.get(context);
-
-        for (AuthenticatorDescription auth : am.getAuthenticatorTypes()) {
-            if (accountType.equals(auth.type)) {
-                return resolveAllContactsNameFromMetaData(context, auth.packageName);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Finds the meta-data XML containing the contacts configuration and
-     * reads the picture priority from that file.
-     */
-    private static String resolveAllContactsNameFromMetaData(Context context, String packageName) {
-        final PackageManager pm = context.getPackageManager();
-        try {
-            PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_SERVICES
-                    | PackageManager.GET_META_DATA);
-            if (pi != null && pi.services != null) {
-                for (ServiceInfo si : pi.services) {
-                    final XmlResourceParser parser = si.loadXmlMetaData(pm, METADATA_CONTACTS);
-                    if (parser != null) {
-                        return loadAllContactsNameFromXml(context, parser, packageName);
-                    }
-                }
-            }
-        } catch (NameNotFoundException e) {
-            Log.w(TAG, "Problem loading \"All Contacts\"-name: " + e.toString());
-        }
-        return null;
-    }
-
-    private static String loadAllContactsNameFromXml(Context context, XmlPullParser parser,
-            String packageName) {
-        try {
-            final AttributeSet attrs = Xml.asAttributeSet(parser);
-            int type;
-            while ((type = parser.next()) != XmlPullParser.START_TAG
-                    && type != XmlPullParser.END_DOCUMENT) {
-                // Drain comments and whitespace
-            }
-
-            if (type != XmlPullParser.START_TAG) {
-                throw new IllegalStateException("No start tag found");
-            }
-
-            final int depth = parser.getDepth();
-            while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
-                    && type != XmlPullParser.END_DOCUMENT) {
-                String name = parser.getName();
-                if (type == XmlPullParser.START_TAG && CONTACTS_DATA_KIND.equals(name)) {
-                    final TypedArray typedArray = context.obtainStyledAttributes(attrs,
-                            android.R.styleable.ContactsDataKind);
-                    try {
-                        // See if a string has been hardcoded directly into the xml
-                        final String nonResourceString = typedArray.getNonResourceString(
-                                android.R.styleable.ContactsDataKind_allContactsName);
-                        if (nonResourceString != null) {
-                            return nonResourceString;
-                        }
-
-                        // See if a resource is referenced. We can't rely on getString
-                        // to automatically resolve it as the resource lives in a different package
-                        int id = typedArray.getResourceId(
-                                android.R.styleable.ContactsDataKind_allContactsName, 0);
-                        if (id == 0) return null;
-
-                        // Resolve the resource Id
-                        final PackageManager packageManager = context.getPackageManager();
-                        final Resources resources;
-                        try {
-                            resources = packageManager.getResourcesForApplication(packageName);
-                        } catch (NameNotFoundException e) {
-                            return null;
-                        }
-                        try {
-                            return resources.getString(id);
-                        } catch (NotFoundException e) {
-                            return null;
-                        }
-                    } finally {
-                        typedArray.recycle();
-                    }
-                }
-            }
-            return null;
-        } catch (XmlPullParserException e) {
-            throw new IllegalStateException("Problem reading XML", e);
-        } catch (IOException e) {
-            throw new IllegalStateException("Problem reading XML", e);
-        }
-    }
-}
diff --git a/src/com/android/contacts/util/WeakAsyncTask.java b/src/com/android/contacts/util/WeakAsyncTask.java
deleted file mode 100644
index f60cfd7..0000000
--- a/src/com/android/contacts/util/WeakAsyncTask.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.os.AsyncTask;
-
-import java.lang.ref.WeakReference;
-
-public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget> extends
-        AsyncTask<Params, Progress, Result> {
-    protected WeakReference<WeakTarget> mTarget;
-
-    public WeakAsyncTask(WeakTarget target) {
-        mTarget = new WeakReference<WeakTarget>(target);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected final void onPreExecute() {
-        final WeakTarget target = mTarget.get();
-        if (target != null) {
-            this.onPreExecute(target);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected final Result doInBackground(Params... params) {
-        final WeakTarget target = mTarget.get();
-        if (target != null) {
-            return this.doInBackground(target, params);
-        } else {
-            return null;
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected final void onPostExecute(Result result) {
-        final WeakTarget target = mTarget.get();
-        if (target != null) {
-            this.onPostExecute(target, result);
-        }
-    }
-
-    protected void onPreExecute(WeakTarget target) {
-        // No default action
-    }
-
-    protected abstract Result doInBackground(WeakTarget target, Params... params);
-
-    protected void onPostExecute(WeakTarget target, Result result) {
-        // No default action
-    }
-}
diff --git a/src/com/android/contacts/vcard/ExportProcessor.java b/src/com/android/contacts/vcard/ExportProcessor.java
index 12f9e24..6063629 100644
--- a/src/com/android/contacts/vcard/ExportProcessor.java
+++ b/src/com/android/contacts/vcard/ExportProcessor.java
@@ -28,7 +28,6 @@
 import android.util.Log;
 
 import com.android.contacts.R;
-import com.android.contacts.activities.PeopleActivity;
 import com.android.vcard.VCardComposer;
 import com.android.vcard.VCardConfig;
 
@@ -52,17 +51,21 @@
     private final NotificationManager mNotificationManager;
     private final ExportRequest mExportRequest;
     private final int mJobId;
+    private final String mCallingActivity;
+
 
     private volatile boolean mCanceled;
     private volatile boolean mDone;
 
-    public ExportProcessor(VCardService service, ExportRequest exportRequest, int jobId) {
+    public ExportProcessor(VCardService service, ExportRequest exportRequest, int jobId,
+            String callingActivity) {
         mService = service;
         mResolver = service.getContentResolver();
         mNotificationManager =
                 (NotificationManager)mService.getSystemService(Context.NOTIFICATION_SERVICE);
         mExportRequest = exportRequest;
         mJobId = jobId;
+        mCallingActivity = callingActivity;
     }
 
     @Override
@@ -254,7 +257,8 @@
 
     private void doFinishNotification(final String title, final String description) {
         if (DEBUG) Log.d(LOG_TAG, "send finish notification: " + title + ", " + description);
-        final Intent intent = new Intent(mService, PeopleActivity.class);
+        final Intent intent = new Intent();
+        intent.setClassName(mService, mCallingActivity);
         final Notification notification =
                 NotificationImportExportListener.constructFinishNotification(mService, title,
                         description, intent);
diff --git a/src/com/android/contacts/vcard/ExportVCardActivity.java b/src/com/android/contacts/vcard/ExportVCardActivity.java
index 6bed577..29ffc4c 100644
--- a/src/com/android/contacts/vcard/ExportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ExportVCardActivity.java
@@ -165,7 +165,10 @@
             return;
         }
 
+        final String callingActivity = getIntent().getExtras()
+                .getString(VCardCommonArguments.ARG_CALLING_ACTIVITY);
         Intent intent = new Intent(this, VCardService.class);
+        intent.putExtra(VCardCommonArguments.ARG_CALLING_ACTIVITY, callingActivity);
 
         if (startService(intent) == null) {
             Log.e(LOG_TAG, "Failed to start vCard service");
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index a741ba3..d6cad88 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -48,7 +48,7 @@
 
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.util.AccountSelectionUtil;
 import com.android.vcard.VCardEntryCounter;
@@ -998,14 +998,6 @@
         }
     }
 
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        // This Activity should finish itself on orientation change, and give the main screen back
-        // to the caller Activity.
-        finish();
-    }
-
     /**
      * Scans vCard in external storage (typically SDCard) and tries to import it.
      * - When there's no SDCard available, an error dialog is shown.
diff --git a/src/com/android/contacts/vcard/NfcImportVCardActivity.java b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
index c181dfa..3c099cb 100644
--- a/src/com/android/contacts/vcard/NfcImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
@@ -32,7 +32,7 @@
 import android.util.Log;
 
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.vcard.VCardEntry;
 import com.android.vcard.VCardEntryCounter;
diff --git a/src/com/android/contacts/vcard/SelectAccountActivity.java b/src/com/android/contacts/vcard/SelectAccountActivity.java
index 9185244..f74cc8c 100644
--- a/src/com/android/contacts/vcard/SelectAccountActivity.java
+++ b/src/com/android/contacts/vcard/SelectAccountActivity.java
@@ -23,7 +23,7 @@
 
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.util.AccountSelectionUtil;
 
diff --git a/src/com/android/contacts/vcard/VCardCommonArguments.java b/src/com/android/contacts/vcard/VCardCommonArguments.java
new file mode 100644
index 0000000..06b49a2
--- /dev/null
+++ b/src/com/android/contacts/vcard/VCardCommonArguments.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.vcard;
+
+/**
+ * Argument constants used by many activities and services.
+ */
+public class VCardCommonArguments {
+
+    // Argument used to pass calling activities to the target activity or service.
+    // The value should be a string class name (e.g. com.android.contacts.vcard.VCardCommonArgs)
+    public static final String ARG_CALLING_ACTIVITY = "CALLING_ACTIVITY";
+}
diff --git a/src/com/android/contacts/vcard/VCardService.java b/src/com/android/contacts/vcard/VCardService.java
index 74ce69c..056f89a 100644
--- a/src/com/android/contacts/vcard/VCardService.java
+++ b/src/com/android/contacts/vcard/VCardService.java
@@ -128,6 +128,8 @@
     private String mErrorReason;
     private MyBinder mBinder;
 
+    private String mCallingActivity;
+
     // File names currently reserved by some export job.
     private final Set<String> mReservedDestination = new HashSet<String>();
     /* ** end of vCard exporter params ** */
@@ -173,6 +175,8 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int id) {
+        mCallingActivity = intent.getExtras().getString(
+                VCardCommonArguments.ARG_CALLING_ACTIVITY);
         return START_STICKY;
     }
 
@@ -223,7 +227,7 @@
 
     public synchronized void handleExportRequest(ExportRequest request,
             VCardImportExportListener listener) {
-        if (tryExecute(new ExportProcessor(this, request, mCurrentJobId))) {
+        if (tryExecute(new ExportProcessor(this, request, mCurrentJobId, mCallingActivity))) {
             final String path = request.destUri.getEncodedPath();
             if (DEBUG) Log.d(LOG_TAG, "Reserve the path " + path);
             if (!mReservedDestination.add(path)) {
diff --git a/tests/src/com/android/contacts/RawContactDeltaListTests.java b/tests/src/com/android/contacts/RawContactDeltaListTests.java
index ef7667b..a8c445b 100644
--- a/tests/src/com/android/contacts/RawContactDeltaListTests.java
+++ b/tests/src/com/android/contacts/RawContactDeltaListTests.java
@@ -37,7 +37,7 @@
 import com.android.contacts.RawContactModifierTests.MockContactsSource;
 import com.android.contacts.model.RawContact;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
diff --git a/tests/src/com/android/contacts/RawContactDeltaTests.java b/tests/src/com/android/contacts/RawContactDeltaTests.java
index 751d41c..dc4eb53 100644
--- a/tests/src/com/android/contacts/RawContactDeltaTests.java
+++ b/tests/src/com/android/contacts/RawContactDeltaTests.java
@@ -34,7 +34,7 @@
 
 import com.android.contacts.model.RawContact;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
@@ -143,49 +143,6 @@
         assertEquals("Unexpected change when merging", source, merged);
     }
 
-    /**
-     * Test that {@link ValuesDelta#buildDiff(android.net.Uri)} is correctly
-     * built for insert, update, and delete cases. Note this only tests behavior
-     * for individual {@link Data} rows.
-     */
-    public void testValuesDiffNone() {
-        final ContentValues before = new ContentValues();
-        before.put(Data._ID, TEST_PHONE_ID);
-        before.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
-
-        final ValuesDelta values = ValuesDelta.fromBefore(before);
-
-        // None action shouldn't produce a builder
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        assertNull("None action produced a builder", builder);
-    }
-
-    public void testValuesDiffInsert() {
-        final ContentValues after = new ContentValues();
-        after.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-
-        final ValuesDelta values = ValuesDelta.fromAfter(after);
-
-        // Should produce an insert action
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        final int type = builder.build().getType();
-        assertEquals("Didn't produce insert action", TYPE_INSERT, type);
-    }
-
-    public void testValuesDiffUpdate() {
-        final ContentValues before = new ContentValues();
-        before.put(Data._ID, TEST_PHONE_ID);
-        before.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
-
-        final ValuesDelta values = ValuesDelta.fromBefore(before);
-        values.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-
-        // Should produce an update action
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        final int type = builder.build().getType();
-        assertEquals("Didn't produce update action", TYPE_UPDATE, type);
-    }
-
     public void testValuesDiffDelete() {
         final ContentValues before = new ContentValues();
         before.put(Data._ID, TEST_PHONE_ID);
diff --git a/tests/src/com/android/contacts/RawContactModifierTests.java b/tests/src/com/android/contacts/RawContactModifierTests.java
index bb0945b..8008cd0 100644
--- a/tests/src/com/android/contacts/RawContactModifierTests.java
+++ b/tests/src/com/android/contacts/RawContactModifierTests.java
@@ -38,10 +38,10 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.model.RawContact;
 import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.model.RawContactDeltaList;
 import com.android.contacts.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index 2fb1040..4ede006 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -41,7 +41,7 @@
 import com.android.contacts.detail.ContactDetailFragment;
 import com.android.contacts.interactions.TestLoaderManager;
 import com.android.contacts.list.ContactBrowseListFragment;
-import com.android.contacts.model.AccountTypeManager;
+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.model.account.BaseAccountType;
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index a89ddc9..34f1e4b 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -31,7 +31,7 @@
 import com.android.contacts.common.test.mocks.ContactsMockContext;
 import com.android.contacts.common.test.mocks.MockContentProvider;
 import com.android.contacts.common.test.mocks.MockContentProvider.Query;
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.BaseAccountType;
 import com.android.contacts.test.InjectedServices;
diff --git a/tests/src/com/android/contacts/model/AccountTypeManagerTest.java b/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
deleted file mode 100644
index 8cc4e12..0000000
--- a/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.model;
-
-import android.content.Context;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountTypeWithDataSet;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Test case for {@link AccountTypeManager}.
- *
- * adb shell am instrument -w -e class com.android.contacts.model.AccountTypeManagerTest \
-       com.android.contacts.tests/android.test.InstrumentationTestRunner
- */
-@SmallTest
-public class AccountTypeManagerTest extends AndroidTestCase {
-    public void testFindAllInvitableAccountTypes() {
-        final Context c = getContext();
-
-        // Define account types.
-        final AccountType typeA = new MockAccountType("type1", null, null);
-        final AccountType typeB = new MockAccountType("type1", "minus", null);
-        final AccountType typeC = new MockAccountType("type2", null, "c");
-        final AccountType typeD = new MockAccountType("type2", "minus", "d");
-
-        // Define users
-        final AccountWithDataSet accountA1 = createAccountWithDataSet("a1", typeA);
-        final AccountWithDataSet accountC1 = createAccountWithDataSet("c1", typeC);
-        final AccountWithDataSet accountC2 = createAccountWithDataSet("c2", typeC);
-        final AccountWithDataSet accountD1 = createAccountWithDataSet("d1", typeD);
-
-        // empty - empty
-        Map<AccountTypeWithDataSet, AccountType> types =
-                AccountTypeManagerImpl.findAllInvitableAccountTypes(c,
-                        buildAccounts(), buildAccountTypes());
-        assertEquals(0, types.size());
-        try {
-            types.clear();
-            fail("Returned Map should be unmodifiable.");
-        } catch (UnsupportedOperationException ok) {
-        }
-
-        // No invite support, no accounts
-        verifyAccountTypes(
-                buildAccounts(),
-                buildAccountTypes(typeA, typeB)
-                /* empty */
-                );
-
-        // No invite support, with accounts
-        verifyAccountTypes(
-                buildAccounts(accountA1),
-                buildAccountTypes(typeA)
-                /* empty */
-                );
-
-        // With invite support, no accounts
-        verifyAccountTypes(
-                buildAccounts(),
-                buildAccountTypes(typeC)
-                /* empty */
-                );
-
-        // With invite support, 1 account
-        verifyAccountTypes(
-                buildAccounts(accountC1),
-                buildAccountTypes(typeC),
-                typeC
-                );
-
-        // With invite support, 2 account
-        verifyAccountTypes(
-                buildAccounts(accountC1, accountC2),
-                buildAccountTypes(typeC),
-                typeC
-                );
-
-        // Combinations...
-        verifyAccountTypes(
-                buildAccounts(accountA1),
-                buildAccountTypes(typeA, typeC)
-                /* empty */
-                );
-
-        verifyAccountTypes(
-                buildAccounts(accountC1, accountA1),
-                buildAccountTypes(typeA, typeC),
-                typeC
-                );
-
-        verifyAccountTypes(
-                buildAccounts(accountC1, accountA1),
-                buildAccountTypes(typeD, typeA, typeC),
-                typeC
-                );
-
-        verifyAccountTypes(
-                buildAccounts(accountC1, accountA1, accountD1),
-                buildAccountTypes(typeD, typeA, typeC, typeB),
-                typeC, typeD
-                );
-    }
-
-    private static AccountWithDataSet createAccountWithDataSet(String name, AccountType type) {
-        return new AccountWithDataSet(name, type.accountType, type.dataSet);
-    }
-
-    /**
-     * Array of {@link AccountType} -> {@link Map}
-     */
-    private static Map<AccountTypeWithDataSet, AccountType> buildAccountTypes(AccountType... types) {
-        final HashMap<AccountTypeWithDataSet, AccountType> result = Maps.newHashMap();
-        for (AccountType type : types) {
-            result.put(type.getAccountTypeAndDataSet(), type);
-        }
-        return result;
-    }
-
-    /**
-     * Array of {@link AccountWithDataSet} -> {@link Collection}
-     */
-    private static Collection<AccountWithDataSet> buildAccounts(AccountWithDataSet... accounts) {
-        final List<AccountWithDataSet> result = Lists.newArrayList();
-        for (AccountWithDataSet account : accounts) {
-            result.add(account);
-        }
-        return result;
-    }
-
-    /**
-     * Executes {@link AccountTypeManagerImpl#findInvitableAccountTypes} and verifies the
-     * result.
-     */
-    private void verifyAccountTypes(
-            Collection<AccountWithDataSet> accounts,
-            Map<AccountTypeWithDataSet, AccountType> types,
-            AccountType... expectedInvitableTypes
-            ) {
-        Map<AccountTypeWithDataSet, AccountType> result =
-                AccountTypeManagerImpl.findAllInvitableAccountTypes(getContext(), accounts, types);
-        for (AccountType type : expectedInvitableTypes) {
-            assertTrue("Result doesn't contain type=" + type.getAccountTypeAndDataSet(),
-                    result.containsKey(type.getAccountTypeAndDataSet()));
-        }
-        final int numExcessTypes = result.size() - expectedInvitableTypes.length;
-        assertEquals("Result contains " + numExcessTypes + " excess type(s)", 0, numExcessTypes);
-    }
-
-    private static class MockAccountType extends AccountType {
-        private final String mInviteContactActivityClassName;
-
-        public MockAccountType(String type, String dataSet, String inviteContactActivityClassName) {
-            accountType = type;
-            this.dataSet = dataSet;
-            mInviteContactActivityClassName = inviteContactActivityClassName;
-        }
-
-        @Override
-        public String getInviteContactActivityClassName() {
-            return mInviteContactActivityClassName;
-        }
-
-        @Override
-        public boolean isGroupMembershipEditable() {
-            return false;
-        }
-
-        @Override
-        public boolean areContactsWritable() {
-            return false;
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/model/ContactLoaderTest.java b/tests/src/com/android/contacts/model/ContactLoaderTest.java
index c87ede8..60d6930 100644
--- a/tests/src/com/android/contacts/model/ContactLoaderTest.java
+++ b/tests/src/com/android/contacts/model/ContactLoaderTest.java
@@ -28,6 +28,7 @@
 import android.test.LoaderTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.test.mocks.ContactsMockContext;
 import com.android.contacts.common.test.mocks.MockContentProvider;
 import com.android.contacts.common.model.account.AccountType;
diff --git a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
index 31eff52..3357af3 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
@@ -15,7 +15,7 @@
  */
 package com.android.contacts.tests.mocks;
 
-import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountTypeWithDataSet;
 import com.android.contacts.common.model.account.AccountWithDataSet;