Merge "Added phone number and phone number type to frequent phone contacts."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6856452..4c5b19f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -532,16 +532,6 @@
             android:name=".ContactSaveService"
             android:exported="false" />
 
-        <!-- Views the details of a single contact -->
-        <activity android:name="ContactOptionsActivity"
-            android:label="@string/contactOptionsTitle"
-        >
-            <intent-filter>
-                <action android:name="android.intent.action.EDIT" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
         <!-- Attaches a photo to a contact. Started from external applications -->
         <activity android:name=".activities.AttachPhotoActivity"
             android:label="@string/attach_photo_dialog_title"
diff --git a/res/layout-sw580dp-w1000dp/contact_detail_fragment.xml b/res/layout-sw580dp-w1000dp/contact_detail_fragment.xml
index 9dd3690..f4c95f8 100644
--- a/res/layout-sw580dp-w1000dp/contact_detail_fragment.xml
+++ b/res/layout-sw580dp-w1000dp/contact_detail_fragment.xml
@@ -32,8 +32,9 @@
     <!-- Real list -->
     <LinearLayout
         android:orientation="horizontal"
+        android:layout_weight="1"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="0dip">
 
         <ImageView android:id="@+id/photo"
             android:scaleType="centerCrop"
diff --git a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
index 2de488d..22f0412 100644
--- a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
+++ b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
@@ -47,9 +47,24 @@
                     android:layout_height="wrap_content"
                     android:visibility="gone" />
 
-                <TextView
-                    android:id="@+id/type"
-                    style="@style/ContactDetailItemType" />
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:orientation="horizontal">
+
+                    <TextView
+                        android:id="@+id/type"
+                        style="@style/ContactDetailItemType" />
+
+                    <View
+                        android:id="@+id/primary_indicator"
+                        android:layout_width="16dip"
+                        android:layout_height="16dip"
+                        android:visibility="gone"
+                        android:layout_gravity="center_vertical"
+                        android:background="@drawable/ic_menu_mark" />
+
+                </LinearLayout>
 
             </FrameLayout>
 
diff --git a/res/layout-sw580dp/external_group_editor_view.xml b/res/layout-sw580dp/external_group_editor_view.xml
new file mode 100644
index 0000000..39e0c56
--- /dev/null
+++ b/res/layout-sw580dp/external_group_editor_view.xml
@@ -0,0 +1,67 @@
+<?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:paddingTop="50dip"
+    android:paddingLeft="50dip"
+    android:paddingRight="100dip"
+    android:orientation="horizontal"
+    android:background="@color/background_primary">
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="3"
+        android:layout_marginRight="30dip"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/read_only_warning"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="10dip"
+            android:paddingLeft="10dip"
+            android:paddingRight="10dip"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorTertiary"
+            android:text="@string/group_read_only" />
+
+        <include
+            android:id="@+id/account_header"
+            layout="@layout/editor_account_header"/>
+
+        <TextView
+            android:id="@+id/group_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorTertiary"
+            android:textStyle="bold"
+            android:padding="10dip"/>
+
+    </LinearLayout>
+
+    <include
+        layout="@layout/group_editor_existing_member_list"
+        android:id="@android:id/list"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="2"/>
+
+</LinearLayout>
diff --git a/res/layout-sw580dp/group_editor_fragment.xml b/res/layout-sw580dp/group_editor_view.xml
similarity index 64%
rename from res/layout-sw580dp/group_editor_fragment.xml
rename to res/layout-sw580dp/group_editor_view.xml
index bc41710..7874c8c 100644
--- a/res/layout-sw580dp/group_editor_fragment.xml
+++ b/res/layout-sw580dp/group_editor_view.xml
@@ -25,10 +25,33 @@
     android:background="@color/background_primary">
 
     <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="3"
+        android:layout_marginRight="30dip"
+        android:orientation="vertical">
+
+        <include
+            android:id="@+id/account_header"
+            layout="@layout/editor_account_header"/>
+
+        <EditText
+            android:id="@+id/group_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold"
+            android:inputType="textCapWords"
+            android:hint="@string/group_name_hint"
+            android:layout_marginBottom="5dip"/>
+
+    </LinearLayout>
+
+    <LinearLayout
         android:id="@+id/group_members"
         android:layout_width="0dip"
         android:layout_height="match_parent"
-        android:layout_weight="1"
+        android:layout_weight="2"
         android:orientation="vertical">
 
         <include
@@ -41,8 +64,4 @@
 
     </LinearLayout>
 
-    <include
-        layout="@layout/group_editor_header"
-        android:id="@+id/header"/>
-
 </LinearLayout>
diff --git a/res/layout-w470dp/contact_detail_fragment.xml b/res/layout-w470dp/contact_detail_fragment.xml
index 42266d5..17cbc2d 100644
--- a/res/layout-w470dp/contact_detail_fragment.xml
+++ b/res/layout-w470dp/contact_detail_fragment.xml
@@ -14,15 +14,17 @@
      limitations under the License.
 -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contact_detail"
+    android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
     <LinearLayout
         android:orientation="horizontal"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="0px"
+        android:layout_weight="1" >
 
         <ImageView android:id="@+id/photo"
             android:scaleType="centerCrop"
@@ -87,5 +89,5 @@
         android:layout_alignParentTop="true"
         android:background="@android:color/transparent"
         android:visibility="gone"/>
-</RelativeLayout>
+</LinearLayout>
 
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index 2d0b9b5..ff7dd4b 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -18,7 +18,8 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
->
+    android:paddingBottom="?android:attr/actionBarSize">
+
     <FrameLayout
         android:id="@+id/voicemail_status"
         android:layout_width="match_parent"
diff --git a/res/layout/contact_detail_list_item.xml b/res/layout/contact_detail_list_item.xml
index 4fcd881..e96b7f0 100644
--- a/res/layout/contact_detail_list_item.xml
+++ b/res/layout/contact_detail_list_item.xml
@@ -45,9 +45,24 @@
             android:layout_gravity="center_vertical"
             android:textAppearance="?android:attr/textAppearanceMedium" />
 
-        <TextView
-            android:id="@+id/type"
-            style="@style/ContactDetailItemType" />
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/type"
+                style="@style/ContactDetailItemType" />
+
+            <View
+                android:id="@+id/primary_indicator"
+                android:layout_width="16dip"
+                android:layout_height="16dip"
+                android:visibility="gone"
+                android:layout_gravity="center_vertical"
+                android:background="@drawable/ic_menu_mark" />
+
+        </LinearLayout>
 
         <TextView
             android:id="@+id/footer"
diff --git a/res/layout/contact_options.xml b/res/layout/contact_options.xml
deleted file mode 100644
index 5bd8836..0000000
--- a/res/layout/contact_options.xml
+++ /dev/null
@@ -1,31 +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="match_parent"
-    android:orientation="vertical"
->
-
-    <include layout="@layout/preference_with_more_button" android:id="@+id/ringtone" />
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:background="?android:attr/listDivider"
-    />
-    <include layout="@layout/edit_contact_entry_voicemail" android:id="@+id/voicemail"/>
-
-</LinearLayout>
diff --git a/res/layout/contact_tile_list.xml b/res/layout/contact_tile_list.xml
index 69ae1cc..2047b13 100644
--- a/res/layout/contact_tile_list.xml
+++ b/res/layout/contact_tile_list.xml
@@ -17,7 +17,8 @@
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:paddingBottom="?attr/favorites_padding_bottom">
 
     <ListView
         android:id="@+id/contact_tile_list"
@@ -30,6 +31,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center_horizontal"
-        android:textAppearance="?android:attr/textAppearanceLarge"/>
+        android:layout_marginTop="@dimen/empty_message_top_margin"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
 
 </FrameLayout>
diff --git a/res/layout/contacts_unavailable_fragment.xml b/res/layout/contacts_unavailable_fragment.xml
index 44c51b5..5566589 100644
--- a/res/layout/contacts_unavailable_fragment.xml
+++ b/res/layout/contacts_unavailable_fragment.xml
@@ -35,7 +35,7 @@
             android:id="@+id/message"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textAppearance="?android:attr/textAppearanceMedium"
             android:layout_marginBottom="20dip" />
 
         <Button
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
index 14fb137..6484d87 100644
--- a/res/layout/dialtacts_activity.xml
+++ b/res/layout/dialtacts_activity.xml
@@ -16,7 +16,8 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginTop="?android:attr/actionBarSize">
 
     <android.support.v4.view.ViewPager
         android:id="@+id/pager"
diff --git a/res/layout/group_browse_list_fragment.xml b/res/layout/group_browse_list_fragment.xml
index 66059fe..9e6bd27 100644
--- a/res/layout/group_browse_list_fragment.xml
+++ b/res/layout/group_browse_list_fragment.xml
@@ -31,12 +31,40 @@
       android:cacheColorHint="@android:color/transparent"
       android:divider="@null" />
 
-   <TextView
-     android:id="@+id/empty"
-     android:layout_width="match_parent"
-     android:layout_height="match_parent"
-     android:gravity="center"
-     android:text="@string/noGroups"
-     android:visibility="gone"/>
+    <TextView
+      android:id="@+id/empty"
+      android:layout_marginTop="@dimen/empty_message_top_margin"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_horizontal"
+      android:textAppearance="?android:attr/textAppearanceMedium"
+      android:text="@string/noGroups" />
 
+    <LinearLayout
+      android:id="@+id/add_accounts"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical">
+
+      <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:layout_marginTop="@dimen/no_accounts_message_margin"
+        android:layout_marginBottom="@dimen/no_accounts_message_margin"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="@string/noAccounts" />
+
+      <Button
+        android:id="@+id/add_account_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@dimen/add_account_button_left_margin"
+        android:layout_marginRight="@dimen/add_account_button_right_margin"
+        android:gravity="center"
+        android:layout_gravity="center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/contacts_unavailable_add_account" />
+
+    </LinearLayout>
 </LinearLayout>
diff --git a/res/layout/group_editor_header.xml b/res/layout/group_editor_header.xml
deleted file mode 100644
index 9b8bf88..0000000
--- a/res/layout/group_editor_header.xml
+++ /dev/null
@@ -1,45 +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.
--->
-
-<!--
-  Header for group editor that contains the account name, type, icon, as well
-  as the group name field.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="0dip"
-    android:layout_height="wrap_content"
-    android:layout_weight="1"
-    android:layout_marginLeft="80dip"
-    android:orientation="vertical">
-
-    <include
-        layout="@layout/group_editor_account_header"
-        android:id="@+id/account_header"/>
-
-    <include
-        layout="@layout/edit_divider"
-        android:id="@+id/divider"/>
-
-    <EditText
-        android:id="@+id/group_name"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:hint="@string/group_name_hint"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:inputType="textCapWords"/>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/res/menu-sw580dp-w720dp/actions.xml b/res/menu-sw580dp-w720dp/actions.xml
index 604813e..534332c 100644
--- a/res/menu-sw580dp-w720dp/actions.xml
+++ b/res/menu-sw580dp-w720dp/actions.xml
@@ -35,21 +35,25 @@
     <item
         android:id="@+id/menu_contacts_filter"
         android:icon="@drawable/ic_menu_settings_holo_light"
+        android:orderInCategory="1"
         android:title="@string/menu_contacts_filter" />
 
     <item
         android:id="@+id/menu_settings"
         android:icon="@drawable/ic_menu_settings_holo_light"
+        android:orderInCategory="2"
         android:title="@string/menu_settings" />
 
     <item
-        android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
-        android:title="@string/menu_accounts" />
-
-    <item
         android:id="@+id/menu_import_export"
         android:icon="@drawable/ic_menu_import_export_holo_light"
+        android:orderInCategory="3"
         android:title="@string/menu_import_export" />
 
+    <item
+        android:id="@+id/menu_accounts"
+        android:icon="@drawable/ic_menu_accounts_holo_light"
+        android:orderInCategory="4"
+        android:title="@string/menu_accounts" />
+
 </menu>
diff --git a/res/menu-sw580dp-w720dp/view_contact.xml b/res/menu-sw580dp-w720dp/view_contact.xml
index 733ab25..0fc918b 100644
--- a/res/menu-sw580dp-w720dp/view_contact.xml
+++ b/res/menu-sw580dp-w720dp/view_contact.xml
@@ -23,18 +23,14 @@
         android:showAsAction="always" />
 
     <item
+        android:id="@+id/menu_delete"
+        android:icon="@drawable/ic_menu_trash_holo_light"
+        android:title="@string/menu_deleteContact" />
+
+    <item
         android:id="@+id/menu_share"
         android:icon="@drawable/ic_menu_share_holo_light"
         android:title="@string/menu_share"
         android:alphabeticShortcut="s" />
 
-    <item
-        android:id="@+id/menu_options"
-        android:icon="@drawable/ic_menu_mark"
-        android:title="@string/menu_contactOptions" />
-
-    <item
-        android:id="@+id/menu_delete"
-        android:icon="@drawable/ic_menu_trash_holo_light"
-        android:title="@string/menu_deleteContact" />
 </menu>
diff --git a/res/menu-sw580dp/actions.xml b/res/menu-sw580dp/actions.xml
index ebe4193..593d693 100644
--- a/res/menu-sw580dp/actions.xml
+++ b/res/menu-sw580dp/actions.xml
@@ -32,24 +32,33 @@
         android:title="@string/menu_new_group_action_bar"
         android:showAsAction="withText" />
 
+    <!-- Added orderInCategory to keep the following buttons at the end of the menu
+         Buttons will be added in the order added/inflated. Ordered buttons will be added
+         at the end according to the orderInCategory. This setup insures that the buttons below
+         will be the last buttons in the menu regardless of how many buttons are added
+    -->
     <item
         android:id="@+id/menu_contacts_filter"
         android:icon="@drawable/ic_menu_settings_holo_light"
+        android:orderInCategory="1"
         android:title="@string/menu_contacts_filter" />
 
     <item
         android:id="@+id/menu_settings"
         android:icon="@drawable/ic_menu_settings_holo_light"
+        android:orderInCategory="2"
         android:title="@string/menu_settings" />
 
     <item
-        android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
-        android:title="@string/menu_accounts" />
-
-    <item
         android:id="@+id/menu_import_export"
         android:icon="@drawable/ic_menu_import_export_holo_light"
+        android:orderInCategory="3"
         android:title="@string/menu_import_export" />
 
+    <item
+        android:id="@+id/menu_accounts"
+        android:icon="@drawable/ic_menu_accounts_holo_light"
+        android:orderInCategory="4"
+        android:title="@string/menu_accounts" />
+
 </menu>
diff --git a/res/menu-sw580dp/view_contact.xml b/res/menu-sw580dp/view_contact.xml
index 542cfe3..e4b4b37 100644
--- a/res/menu-sw580dp/view_contact.xml
+++ b/res/menu-sw580dp/view_contact.xml
@@ -22,18 +22,14 @@
         android:alphabeticShortcut="e" />
 
     <item
+        android:id="@+id/menu_delete"
+        android:icon="@drawable/ic_menu_trash_holo_light"
+        android:title="@string/menu_deleteContact" />
+
+    <item
         android:id="@+id/menu_share"
         android:icon="@drawable/ic_menu_share_holo_light"
         android:title="@string/menu_share"
         android:alphabeticShortcut="s" />
 
-    <item
-        android:id="@+id/menu_options"
-        android:icon="@drawable/ic_menu_mark"
-        android:title="@string/menu_contactOptions" />
-
-    <item
-        android:id="@+id/menu_delete"
-        android:icon="@drawable/ic_menu_trash_holo_light"
-        android:title="@string/menu_deleteContact" />
 </menu>
diff --git a/res/menu/actions.xml b/res/menu/actions.xml
index fd2b967..346875b 100644
--- a/res/menu/actions.xml
+++ b/res/menu/actions.xml
@@ -43,13 +43,13 @@
         android:title="@string/menu_settings" />
 
     <item
-        android:id="@+id/menu_accounts"
-        android:icon="@drawable/ic_menu_accounts_holo_light"
-        android:title="@string/menu_accounts" />
-
-    <item
         android:id="@+id/menu_import_export"
         android:icon="@drawable/ic_menu_import_export_holo_light"
         android:title="@string/menu_import_export" />
 
+    <item
+        android:id="@+id/menu_accounts"
+        android:icon="@drawable/ic_menu_accounts_holo_light"
+        android:title="@string/menu_accounts" />
+
 </menu>
diff --git a/res/menu/view_contact.xml b/res/menu/view_contact.xml
index 7cf17d6..17ed7c6 100644
--- a/res/menu/view_contact.xml
+++ b/res/menu/view_contact.xml
@@ -28,12 +28,17 @@
         android:alphabeticShortcut="s" />
 
     <item
-        android:id="@+id/menu_options"
-        android:icon="@drawable/ic_menu_mark"
-        android:title="@string/menu_contactOptions" />
-
-    <item
         android:id="@+id/menu_delete"
         android:icon="@drawable/ic_menu_trash_holo_light"
         android:title="@string/menu_deleteContact" />
+
+    <item
+        android:id="@+id/menu_set_ringtone"
+        android:icon="@drawable/ic_menu_mark"
+        android:title="@string/menu_set_ring_tone" />
+
+    <item
+        android:id="@+id/menu_send_to_voicemail"
+        android:checkable="true"
+        android:title="@string/menu_redirect_calls_to_vm" />
 </menu>
diff --git a/res/values-sw580dp-w720dp/styles.xml b/res/values-sw580dp-w720dp/styles.xml
index 4efaa09..045aeab 100644
--- a/res/values-sw580dp-w720dp/styles.xml
+++ b/res/values-sw580dp-w720dp/styles.xml
@@ -14,11 +14,11 @@
      limitations under the License.
 -->
 <resources>
-    <style name="PeopleTheme" parent="@android:Theme.Holo.Light">
+    <style name="PeopleTheme" parent="@android:style/Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
         <item name="list_item_height">66dip</item>
         <item name="activated_background">@drawable/list_item_activated_background</item>
         <item name="android:windowContentOverlay">@null</item>
-        <item name="android:actionBarStyle">@style/TransparentActionBarStyle</item>
         <item name="section_header_background">@drawable/list_title_holo</item>
         <item name="list_item_divider">?android:attr/listDivider</item>
         <item name="list_item_padding_top">0dip</item>
diff --git a/res/values-sw580dp/styles.xml b/res/values-sw580dp/styles.xml
index 2838c81..df77fc6 100644
--- a/res/values-sw580dp/styles.xml
+++ b/res/values-sw580dp/styles.xml
@@ -14,11 +14,11 @@
      limitations under the License.
 -->
 <resources>
-    <style name="PeopleTheme" parent="@android:Theme.Holo.Light">
+    <style name="PeopleTheme" parent="@android:style/Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
         <item name="list_item_height">66dip</item>
         <item name="activated_background">@drawable/list_item_activated_background</item>
         <item name="android:windowContentOverlay">@null</item>
-        <item name="android:actionBarStyle">@style/TransparentActionBarStyle</item>
         <item name="section_header_background">@drawable/list_title_holo</item>
         <item name="list_item_divider">?android:attr/listDivider</item>
         <item name="list_item_padding_top">0dip</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a878fc3..2b71c84 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -225,4 +225,10 @@
     <dimen name="call_detail_contact_background_overlay_height">42dip</dimen>
     <dimen name="call_detail_contact_name_margin">24dip</dimen>
     <dimen name="call_detail_action_bar_height">60dip</dimen>
+
+    <!-- Empty message margins -->
+    <dimen name="empty_message_top_margin">43dip</dimen>
+    <dimen name="no_accounts_message_margin">15dip</dimen>
+    <dimen name="add_account_button_left_margin">50dip</dimen>
+    <dimen name="add_account_button_right_margin">50dip</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d2c2536..ebf26d7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -176,15 +176,18 @@
     <!-- Toast shown after two contacts have been joined by a user action -->
     <string name="contactsJoinedMessage">Contacts joined</string>
 
-    <!-- Menu item that opens the Options activity for a given contact -->
-    <string name="menu_contactOptions">Options</string>
-
     <!-- Title for the Options activity for a given contact -->
     <string name="contactOptionsTitle">Options</string>
 
     <!-- Confirmation dialog title after users selects to delete a contact. -->
     <string name="deleteConfirmation_title">Delete</string>
 
+    <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=15] -->
+    <string name="menu_set_ring_tone">Set ringtone</string>
+
+    <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=30] -->
+    <string name="menu_redirect_calls_to_vm">Redirect calls to voicemail</string>
+
     <!-- Warning dialog contents after users selects to delete a ReadOnly contact. -->
     <string name="readOnlyContactWarning">You cannot delete contacts from read-only accounts, but you can hide them in your contacts lists.</string>
 
@@ -287,11 +290,14 @@
     <!-- The menu item that allows you to remove a photo from a contact [CHAR LIMIT=50] -->
     <string name="removePhoto">Remove photo</string>
 
-    <!-- The text displayed when the contacts list is empty while displaying all contacts -->
-    <string name="noContacts">No contacts.</string>
+    <!-- The text displayed when the contacts list is empty while displaying all contacts [CHAR LIMIT=NONE] -->
+    <string name="noContacts">No contacts</string>
 
     <!-- The text displayed when the groups list is empty while displaying all groups [CHAR LIMIT=NONE] -->
-    <string name="noGroups">No groups.</string>
+    <string name="noGroups">No groups</string>
+
+    <!-- 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>
@@ -358,7 +364,7 @@
     <string name="listTotalAllContactsZeroCustom">No visible contacts</string>
 
     <!-- Displayed at the top of the contacts showing the zero total number of contacts visible when starred contact list is selected  [CHAR LIMIT=64]-->
-    <string name="listTotalAllContactsZeroStarred">No starred contacts</string>
+    <string name="listTotalAllContactsZeroStarred">No Favorites</string>
 
     <!-- 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>
@@ -1575,6 +1581,15 @@
     <!-- Joined contact indicator displayed in the contact detail [CHAR LIMIT=64] -->
     <string name="indicator_joined_contact">Joined contact</string>
 
+    <!-- Option displayed in context menu to copy long pressed item to clipboard [CHAR LIMIT=64] -->
+    <string name="copy_text">Copy to clipboard</string>
+
+    <!-- Option displayed in context menu to set long pressed item as default contact method [CHAR LIMIT=64] -->
+    <string name="set_default">Set default</string>
+
+    <!-- Option displayed in context menu to clear long pressed item as default contact method [CHAR LIMIT=64] -->
+    <string name="clear_default">Clear default</string>
+
     <!-- Toast shown when text is copied to the clipboard [CHAR LIMIT=64] -->
     <string name="toast_text_copied">Text copied</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d26affc..e98175d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -14,7 +14,9 @@
      limitations under the License.
 -->
 <resources>
-    <style name="DialtactsTheme" parent="android:Theme.Holo.SplitActionBarWhenNarrow">
+    <style name="DialtactsTheme"
+           parent="android:Theme.Holo.SolidActionBar.SplitActionBarWhenNarrow">
+        <item name="android:windowActionBarOverlay">true</item>
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowBackground">@android:color/black</item>
         <item name="activated_background">@drawable/list_item_activated_background</item>
@@ -51,6 +53,8 @@
         <item name="call_log_voicemail_status_height">40dip</item>
         <item name="call_log_voicemail_status_background_color">#FFFFE0</item>
         <item name="call_log_voicemail_status_text_color">#000000</item>
+        <!-- Favorites -->
+        <item name="favorites_padding_bottom">?android:attr/actionBarSize</item>
     </style>
 
     <style name="CallDetailActivityTheme" parent="android:Theme.Holo.SplitActionBarWhenNarrow">
@@ -69,10 +73,12 @@
         <item name="call_log_voicemail_status_text_color">#000000</item>
     </style>
 
-    <style name="ContactDetailActivityTheme" parent="android:Theme.Holo.Light">
+    <style name="ContactDetailActivityTheme" parent="@android:style/Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
         <item name="android:windowContentOverlay">@null</item>
     </style>
-    <style name="ContactEditorActivityTheme" parent="android:Theme.Holo.Light">
+    <style name="ContactEditorActivityTheme" parent="@android:style/Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
         <item name="android:windowContentOverlay">@null</item>
     </style>
 
@@ -159,7 +165,12 @@
         <attr name="call_log_voicemail_status_text_color" format="color" />
     </declare-styleable>
 
-    <style name="PeopleTheme" parent="android:Theme.Holo.Light.SplitActionBarWhenNarrow">
+    <declare-styleable name="Favorites">
+        <attr name="favorites_padding_bottom" format="dimension" />
+    </declare-styleable>
+
+    <style name="PeopleTheme" parent="@android:style/Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
         <item name="list_item_height">?android:attr/listPreferredItemHeight</item>
         <item name="activated_background">@drawable/list_item_activated_background</item>
         <item name="section_header_background">@drawable/list_title_holo</item>
@@ -185,10 +196,18 @@
         <item name="list_item_header_underline_height">1px</item>
         <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
         <item name="contact_filter_popup_width">320dip</item>
+        <!-- Favorites -->
+        <item name="favorites_padding_bottom">0dip</item>
+    </style>
+
+    <style name="ContactsActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
+        <item name="android:background">@color/people_app_theme_color</item>
+        <item name="android:backgroundStacked">@color/people_app_theme_color</item>
     </style>
 
     <!-- TODO: Clean up this file so themes aren't copied. -->
-    <style name="GroupDetailTheme" parent="android:Theme.Holo.Light">
+    <style name="GroupDetailTheme" parent="@android:style/Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+        <item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
         <item name="list_item_height">?android:attr/listPreferredItemHeight</item>
         <item name="activated_background">@drawable/list_item_activated_background</item>
         <item name="section_header_background">@drawable/list_title_holo</item>
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index 3463d3c..f2a9d13 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -126,6 +126,8 @@
 
         private boolean mLoadingPhoto;
         private byte[] mPhotoBinaryData;
+        private boolean mSendToVoicemail;
+        private String mCustomRingtone;
 
         /**
          * Constructor for case "no contact found". This must only be used for the
@@ -150,6 +152,8 @@
             mStarred = false;
             mPresence = null;
             mInvitableAccountTypes = null;
+            mSendToVoicemail = false;
+            mCustomRingtone = null;
         }
 
         /**
@@ -158,7 +162,7 @@
         private Result(Uri uri, Uri lookupUri, long directoryId, String lookupKey, long id,
                 long nameRawContactId, int displayNameSource, long photoId, String photoUri,
                 String displayName, String altDisplayName, String phoneticName, boolean starred,
-                Integer presence) {
+                Integer presence, boolean sendToVoicemail, String customRingtone) {
             mLookupUri = lookupUri;
             mUri = uri;
             mDirectoryId = directoryId;
@@ -177,6 +181,8 @@
             mStarred = starred;
             mPresence = presence;
             mInvitableAccountTypes = Lists.newArrayList();
+            mSendToVoicemail = sendToVoicemail;
+            mCustomRingtone = customRingtone;
         }
 
         private Result(Result from) {
@@ -209,6 +215,8 @@
 
             mLoadingPhoto = from.mLoadingPhoto;
             mPhotoBinaryData = from.mPhotoBinaryData;
+            mSendToVoicemail = from.mSendToVoicemail;
+            mCustomRingtone = from.mCustomRingtone;
         }
 
         /**
@@ -378,6 +386,14 @@
         public List<GroupMetaData> getGroupMetaData() {
             return mGroups;
         }
+
+        public boolean isSendToVoicemail() {
+            return mSendToVoicemail;
+        }
+
+        public String getCustomRingtone() {
+            return mCustomRingtone;
+        }
     }
 
     /**
@@ -451,6 +467,8 @@
                 Data.STATUS_TIMESTAMP,
 
                 Contacts.PHOTO_URI,
+                Contacts.SEND_TO_VOICEMAIL,
+                Contacts.CUSTOM_RINGTONE,
         };
 
         public final static int NAME_RAW_CONTACT_ID = 0;
@@ -518,6 +536,8 @@
         public final static int STATUS_TIMESTAMP = 58;
 
         public final static int PHOTO_URI = 59;
+        public final static int SEND_TO_VOICEMAIL = 60;
+        public final static int CUSTOM_RINGTONE = 61;
     }
 
     /**
@@ -778,6 +798,8 @@
             final Integer presence = cursor.isNull(ContactQuery.CONTACT_PRESENCE)
                     ? null
                     : cursor.getInt(ContactQuery.CONTACT_PRESENCE);
+            final boolean sendToVoicemail = cursor.getInt(ContactQuery.SEND_TO_VOICEMAIL) == 1;
+            final String customRingtone = cursor.getString(ContactQuery.CUSTOM_RINGTONE);
 
             Uri lookupUri;
             if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
@@ -789,7 +811,8 @@
 
             return new Result(contactUri, lookupUri, directoryId, lookupKey, contactId,
                     nameRawContactId, displayNameSource, photoId, photoUri, displayName,
-                    altDisplayName, phoneticName, starred, presence);
+                    altDisplayName, phoneticName, starred, presence, sendToVoicemail,
+                    customRingtone);
         }
 
         /**
diff --git a/src/com/android/contacts/ContactOptionsActivity.java b/src/com/android/contacts/ContactOptionsActivity.java
deleted file mode 100644
index dd7387f..0000000
--- a/src/com/android/contacts/ContactOptionsActivity.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import com.android.contacts.activities.PeopleActivity;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.database.Cursor;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract.Contacts;
-import android.util.Log;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.TextView;
-
-/**
- * An activity for selecting options for a given contact: custom ringtone and send-to-voicemail.
- */
-public class ContactOptionsActivity extends Activity implements View.OnClickListener {
-
-    private static final String TAG = "ContactOptionsActivity";
-
-    private static final String[] AGGREGATES_PROJECTION = new String[] {
-            Contacts.CUSTOM_RINGTONE, Contacts.SEND_TO_VOICEMAIL
-    };
-
-    private static final int COL_CUSTOM_RINGTONE = 0;
-    private static final int COL_SEND_TO_VOICEMAIL = 1;
-
-    /** The launch code when picking a ringtone */
-    private static final int RINGTONE_PICKED = 3023;
-
-    private String mCustomRingtone;
-    private boolean mSendToVoicemail;
-    private TextView mRingtoneTitle;
-    private CheckBox mSendToVoicemailCheckbox;
-
-    private Uri mLookupUri;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mLookupUri = getIntent().getData();
-
-        setContentView(R.layout.contact_options);
-
-        View ringtoneLayout = findViewById(R.id.ringtone);
-        ringtoneLayout.setFocusable(true);
-        ringtoneLayout.setOnClickListener(this);
-        TextView label = (TextView)findViewById(R.id.label);
-        label.setText(getString(R.string.label_ringtone));
-
-        mRingtoneTitle = (TextView)ringtoneLayout.findViewById(R.id.data);
-
-        View sendToVoicemailLayout = findViewById(R.id.voicemail);
-        sendToVoicemailLayout.setOnClickListener(this);
-        label = (TextView)sendToVoicemailLayout.findViewById(R.id.label);
-        label.setText(getString(R.string.actionIncomingCall));
-
-        ActionBar actionBar =  getActionBar();
-        if (actionBar != null) {
-            actionBar.setDisplayHomeAsUpEnabled(true);
-        }
-
-        mSendToVoicemailCheckbox = (CheckBox)sendToVoicemailLayout.findViewById(R.id.checkbox);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        if (!loadData()) {
-            finish();
-        }
-
-        updateView();
-    }
-
-    private void updateView() {
-        if (mCustomRingtone == null) {
-            mRingtoneTitle.setText(getString(R.string.default_ringtone));
-        } else {
-            Uri ringtoneUri = Uri.parse(mCustomRingtone);
-            Ringtone ringtone = RingtoneManager.getRingtone(this, ringtoneUri);
-            if (ringtone == null) {
-                Log.w(TAG, "ringtone's URI doesn't resolve to a Ringtone");
-                return;
-            }
-            mRingtoneTitle.setText(ringtone.getTitle(this));
-        }
-
-        mSendToVoicemailCheckbox.setChecked(mSendToVoicemail);
-    }
-
-    public void onClick(View v) {
-        switch (v.getId()) {
-            case R.id.ringtone: {
-                doPickRingtone();
-                break;
-            }
-            case R.id.voicemail: {
-                doToggleSendToVoicemail();
-                break;
-            }
-        }
-    }
-
-    private void doPickRingtone() {
-
-        Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
-        // Allow user to pick 'Default'
-        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
-        // Show only ringtones
-        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
-        // Don't show 'Silent'
-        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
-
-        Uri ringtoneUri;
-        if (mCustomRingtone != null) {
-            ringtoneUri = Uri.parse(mCustomRingtone);
-        } else {
-            // Otherwise pick default ringtone Uri so that something is selected.
-            ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
-        }
-
-        // Put checkmark next to the current ringtone for this contact
-        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, ringtoneUri);
-
-        // Launch!
-        startActivityForResult(intent, RINGTONE_PICKED);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (resultCode != RESULT_OK) {
-            return;
-        }
-
-        switch (requestCode) {
-            case RINGTONE_PICKED: {
-                Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
-                handleRingtonePicked(pickedUri);
-                break;
-            }
-        }
-    }
-
-    private void handleRingtonePicked(Uri pickedUri) {
-        if (pickedUri == null || RingtoneManager.isDefault(pickedUri)) {
-            mCustomRingtone = null;
-        } else {
-            mCustomRingtone = pickedUri.toString();
-        }
-        saveData();
-        updateView();
-    }
-
-    private void doToggleSendToVoicemail() {
-        mSendToVoicemailCheckbox.toggle();
-        mSendToVoicemail = mSendToVoicemailCheckbox.isChecked();
-        saveData();
-        updateView();
-    }
-
-    private boolean loadData() {
-        Cursor c =
-                getContentResolver().query(mLookupUri, AGGREGATES_PROJECTION, null, null, null);
-        try {
-            if (!c.moveToFirst()) {
-                return false;
-            }
-
-            mCustomRingtone = c.getString(COL_CUSTOM_RINGTONE);
-            mSendToVoicemail = c.getInt(COL_SEND_TO_VOICEMAIL) != 0;
-
-        } finally {
-            c.close();
-        }
-        return true;
-    }
-
-    private void saveData() {
-        ContentValues values = new ContentValues(2);
-        values.put(Contacts.CUSTOM_RINGTONE, mCustomRingtone);
-        values.put(Contacts.SEND_TO_VOICEMAIL, mSendToVoicemail);
-        getContentResolver().update(mLookupUri, values, null, null);
-    }
-
-    @Override
-    public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
-            boolean globalSearch) {
-        if (globalSearch) {
-            super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
-        } else {
-            ContactsSearchManager.startSearch(this, initialQuery);
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                Intent intent = new Intent(this, PeopleActivity.class);
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                startActivity(intent);
-                finish();
-                return true;
-            default:
-                break;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
-
-
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 775009e..e2ab6b0 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -98,6 +98,12 @@
     public static final String EXTRA_CONTACT_ID2 = "contactId2";
     public static final String EXTRA_CONTACT_WRITABLE = "contactWritable";
 
+    public static final String ACTION_SET_SEND_TO_VOICEMAIL = "sendToVoicemail";
+    public static final String EXTRA_SEND_TO_VOICEMAIL_FLAG = "sendToVoicemailFlag";
+
+    public static final String ACTION_SET_RINGTONE = "setRingtone";
+    public static final String EXTRA_CUSTOM_RINGTONE = "customRingtone";
+
     private static final HashSet<String> ALLOWED_DATA_COLUMNS = Sets.newHashSet(
         Data.MIMETYPE,
         Data.IS_PRIMARY,
@@ -185,6 +191,10 @@
             deleteContact(intent);
         } else if (ACTION_JOIN_CONTACTS.equals(action)) {
             joinContacts(intent);
+        } else if (ACTION_SET_SEND_TO_VOICEMAIL.equals(action)) {
+            setSendToVoicemail(intent);
+        } else if (ACTION_SET_RINGTONE.equals(action)) {
+            setRingtone(intent);
         }
     }
 
@@ -382,6 +392,7 @@
      * @param callbackActivity is the activity to send the callback intent to
      * @param callbackAction is the intent action for the callback intent
      */
+
     public static Intent createNewGroupIntent(Context context, Account account,
             String label, long[] rawContactsToAdd, Class<?> callbackActivity,
             String callbackAction) {
@@ -657,6 +668,57 @@
     }
 
     /**
+     * Creates an intent that can be sent to this service to set the redirect to voicemail.
+     */
+    public static Intent createSetSendToVoicemail(Context context, Uri contactUri,
+            boolean value) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_SET_SEND_TO_VOICEMAIL);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_URI, contactUri);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_SEND_TO_VOICEMAIL_FLAG, value);
+
+        return serviceIntent;
+    }
+
+    private void setSendToVoicemail(Intent intent) {
+        Uri contactUri = intent.getParcelableExtra(EXTRA_CONTACT_URI);
+        boolean value = intent.getBooleanExtra(EXTRA_SEND_TO_VOICEMAIL_FLAG, false);
+        if (contactUri == null) {
+            Log.e(TAG, "Invalid arguments for setRedirectToVoicemail");
+            return;
+        }
+
+        final ContentValues values = new ContentValues(1);
+        values.put(Contacts.SEND_TO_VOICEMAIL, value);
+        getContentResolver().update(contactUri, values, null, null);
+    }
+
+    /**
+     * Creates an intent that can be sent to this service to save the contact's ringtone.
+     */
+    public static Intent createSetRingtone(Context context, Uri contactUri,
+            String value) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_SET_RINGTONE);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_URI, contactUri);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_CUSTOM_RINGTONE, value);
+
+        return serviceIntent;
+    }
+
+    private void setRingtone(Intent intent) {
+        Uri contactUri = intent.getParcelableExtra(EXTRA_CONTACT_URI);
+        String value = intent.getStringExtra(EXTRA_CUSTOM_RINGTONE);
+        if (contactUri == null) {
+            Log.e(TAG, "Invalid arguments for setRingtone");
+            return;
+        }
+        ContentValues values = new ContentValues(1);
+        values.put(Contacts.CUSTOM_RINGTONE, value);
+        getContentResolver().update(contactUri, values, null, null);
+    }
+
+    /**
      * Creates an intent that sets the selected data item as super primary (default)
      */
     public static Intent createSetSuperPrimaryIntent(Context context, long dataId) {
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 7e41a5c..022a724 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -122,7 +122,12 @@
     }
 
     private class PageChangeListener implements OnPageChangeListener {
-        private int mPreviousPosition = -1;  // Invalid at first
+        private int mCurrentPosition = -1;
+        /**
+         * Used during page migration, to remember the next position {@link #onPageSelected(int)}
+         * specified.
+         */
+        private int mNextPosition = -1;
 
         @Override
         public void onPageScrolled(
@@ -132,34 +137,38 @@
         @Override
         public void onPageSelected(int position) {
             final ActionBar actionBar = getActionBar();
-            if (mPreviousPosition == position) {
+            if (mCurrentPosition == position) {
                 Log.w(TAG, "Previous position and next position became same (" + position + ")");
             }
 
-            if (mPreviousPosition >= 0) {
-                sendFragmentVisibilityChange(mPreviousPosition, false);
-            }
-            sendFragmentVisibilityChange(position, true);
-
             actionBar.selectTab(actionBar.getTabAt(position));
-
-            // Activity#onPrepareOptionsMenu() may not be called when Fragment has it's own
-            // options menu. We force this Activity to call it to hide/show bottom bar. Also
-            // we don't want to do so when it is unnecessary (buttons may flicker).
-            if (mPreviousPosition == TAB_INDEX_DIALER || position == TAB_INDEX_DIALER) {
-                // Force this Activity to prepare Menu again.
-                invalidateOptionsMenu();
-            }
-
-            mPreviousPosition = position;
+            mNextPosition = position;
         }
 
         public void setCurrentPosition(int position) {
-            mPreviousPosition = position;
+            mCurrentPosition = position;
         }
 
         @Override
         public void onPageScrollStateChanged(int state) {
+            switch (state) {
+                case ViewPager.SCROLL_STATE_IDLE: {
+                    if (mCurrentPosition >= 0) {
+                        sendFragmentVisibilityChange(mCurrentPosition, false);
+                    }
+                    if (mNextPosition >= 0) {
+                        sendFragmentVisibilityChange(mNextPosition, true);
+                    }
+                    invalidateOptionsMenu();
+
+                    mCurrentPosition = mNextPosition;
+                    break;
+                }
+                case ViewPager.SCROLL_STATE_DRAGGING:
+                case ViewPager.SCROLL_STATE_SETTLING:
+                default:
+                    break;
+            }
         }
     }
 
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 481b28e..6a0d7ad 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -602,6 +602,10 @@
                 }
             }
             invalidateOptionsMenu();
+            showEmptyStateForTab(tab);
+            if (tab == TabState.GROUPS) {
+                mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+            }
             return;
         }
 
@@ -618,6 +622,11 @@
                 mDetailsView.setVisibility(View.GONE);
                 break;
             case GROUPS:
+                mFavoritesView.setVisibility(View.GONE);
+                mBrowserView.setVisibility(View.VISIBLE);
+                mDetailsView.setVisibility(View.VISIBLE);
+                mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+                break;
             case ALL:
                 mFavoritesView.setVisibility(View.GONE);
                 mBrowserView.setVisibility(View.VISIBLE);
@@ -665,6 +674,24 @@
             // fragment transaction does it implicitly.  We don't have to call invalidateOptionsMenu
             // manually.
         }
+        showEmptyStateForTab(tab);
+    }
+
+    private void showEmptyStateForTab(TabState tab) {
+        if (mContactsUnavailableFragment != null) {
+            switch (tab) {
+                case FAVORITES:
+                    mContactsUnavailableFragment.setMessageText(
+                            R.string.listTotalAllContactsZeroStarred);
+                    break;
+                case GROUPS:
+                    mContactsUnavailableFragment.setMessageText(R.string.noGroups);
+                    break;
+                case ALL:
+                    mContactsUnavailableFragment.setMessageText(R.string.noContacts);
+                    break;
+            }
+        }
     }
 
     private class TabPagerListener implements ViewPager.OnPageChangeListener {
@@ -680,7 +707,12 @@
         public void onPageSelected(int position) {
             // Make sure not in the search mode, in which case position != TabState.ordinal().
             if (!mTabPagerAdapter.isSearchMode()) {
-                mActionBarAdapter.setCurrentTab(TabState.fromInt(position), false);
+                TabState selectedTab = TabState.fromInt(position);
+                mActionBarAdapter.setCurrentTab(selectedTab, false);
+                showEmptyStateForTab(selectedTab);
+                if (selectedTab == TabState.GROUPS) {
+                    mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+                }
                 invalidateOptionsMenu();
             }
         }
@@ -904,6 +936,11 @@
             if (mainView != null) {
                 mainView.setVisibility(View.INVISIBLE);
             }
+
+            TabState tab = mActionBarAdapter.getCurrentTab();
+            if (tab == TabState.GROUPS) {
+                mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+            }
         }
 
         invalidateOptionsMenuIfNeeded();
@@ -1246,14 +1283,18 @@
         if (mActionBarAdapter.isSearchMode()) {
             addContactMenu.setVisible(false);
             addGroupMenu.setVisible(false);
+            contactsFilterMenu.setVisible(false);
         } else {
             switch (mActionBarAdapter.getCurrentTab()) {
                 case FAVORITES:
-                    // TODO: Fall through until we determine what the menu items should be for
-                    // this tab
+                    addContactMenu.setVisible(false);
+                    addGroupMenu.setVisible(false);
+                    contactsFilterMenu.setVisible(false);
+                    break;
                 case ALL:
                     addContactMenu.setVisible(true);
                     addGroupMenu.setVisible(false);
+                    contactsFilterMenu.setVisible(true);
                     break;
                 case GROUPS:
                     // Do not display the "new group" button if no accounts are available
@@ -1263,6 +1304,7 @@
                         addGroupMenu.setVisible(false);
                     }
                     addContactMenu.setVisible(false);
+                    contactsFilterMenu.setVisible(false);
                     break;
             }
         }
@@ -1272,9 +1314,6 @@
             searchMenu.setVisible(!mActionBarAdapter.isSearchMode());
         }
 
-        if (contactsFilterMenu != null) {
-            contactsFilterMenu.setVisible(!mActionBarAdapter.isSearchMode());
-        }
 
         MenuItem settings = menu.findItem(R.id.menu_settings);
         if (settings != null) {
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 8f7cfa8..abc9adf 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -989,19 +989,16 @@
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
-        inflater.inflate(R.menu.call_log_options, menu);
+        if (mShowOptionsMenu) {
+            inflater.inflate(R.menu.call_log_options, menu);
+        }
     }
 
     @Override
     public void onPrepareOptionsMenu(Menu menu) {
-        menu.findItem(R.id.delete_all).setVisible(mShowOptionsMenu);
-        menu.findItem(R.id.show_voicemails_only).setVisible(mShowOptionsMenu);
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings_call_log);
         if (mShowOptionsMenu) {
-            callSettingsMenuItem.setVisible(true);
-            callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
-        } else {
-            callSettingsMenuItem.setVisible(false);
+            menu.findItem(R.id.menu_call_settings_call_log)
+                .setIntent(DialtactsActivity.getCallSettingsIntent());
         }
     }
 
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index a6ba6b0..1dae19f 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -47,6 +47,7 @@
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.SearchManager;
+import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -87,15 +88,18 @@
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.AbsListView.OnScrollListener;
 import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.BaseAdapter;
 import android.widget.Button;
 import android.widget.CheckBox;
@@ -113,12 +117,18 @@
 import java.util.Map;
 
 public class ContactDetailFragment extends Fragment implements FragmentKeyListener, FragmentOverlay,
-        OnItemClickListener, OnItemLongClickListener, SelectAccountDialogFragment.Listener {
+        OnItemClickListener, SelectAccountDialogFragment.Listener {
 
     private static final String TAG = "ContactDetailFragment";
 
     private static final int LOADER_DETAILS = 1;
 
+    private interface ContextMenuIds {
+        static final int COPY_TEXT = 0;
+        static final int CLEAR_DEFAULT = 1;
+        static final int SET_DEFAULT = 2;
+    }
+
     private static final String KEY_CONTACT_URI = "contactUri";
     private static final String LOADER_ARG_CONTACT_URI = "contactUri";
 
@@ -255,7 +265,7 @@
         mListView = (ListView) mView.findViewById(android.R.id.list);
         mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
         mListView.setOnItemClickListener(this);
-        mListView.setOnItemLongClickListener(this);
+        registerForContextMenu(mListView);
         mListView.setOnScrollListener(mVerticalScrollListener);
 
         // Don't set it to mListView yet.  We do so later when we bind the adapter.
@@ -1328,12 +1338,14 @@
         public ImageView secondaryActionButton;
         public View secondaryActionButtonContainer;
         public View secondaryActionDivider;
+        public View primaryIndicator;
 
         public DetailViewCache(View view, OnClickListener secondaryActionClickListener) {
             kind = (TextView) view.findViewById(R.id.kind);
             type = (TextView) view.findViewById(R.id.type);
             data = (TextView) view.findViewById(R.id.data);
             footer = (TextView) view.findViewById(R.id.footer);
+            primaryIndicator = view.findViewById(R.id.primary_indicator);
             presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
             secondaryActionButton = (ImageView) view.findViewById(
                     R.id.secondary_action_button);
@@ -1511,6 +1523,9 @@
                 views.footer.setVisibility(View.GONE);
             }
 
+            // Set the default contact method
+            views.primaryIndicator.setVisibility(entry.isPrimary ? View.VISIBLE : View.GONE);
+
             // Set the presence icon
             final Drawable presenceIcon = ContactPresenceIconUtil.getPresenceIcon(
                     mContext, entry.presence);
@@ -1642,18 +1657,105 @@
     }
 
     @Override
-    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
-        if (mListener == null) return false;
-        final DetailViewCache cache = (DetailViewCache) view.getTag();
-        if (cache == null) return false;
-        CharSequence text = cache.data.getText();
-        if (TextUtils.isEmpty(text)) return false;
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+        super.onCreateContextMenu(menu, view, menuInfo);
 
-        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
+        AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
+        DetailViewEntry selectedEntry = (DetailViewEntry) mAllEntries.get(info.position);
+
+        menu.setHeaderTitle(selectedEntry.data);
+        menu.add(ContextMenu.NONE, ContextMenuIds.COPY_TEXT,
+                ContextMenu.NONE, getString(R.string.copy_text));
+
+        String selectedMimeType = selectedEntry.mimetype;
+
+        // Only allow primary support for Phone and Email content types
+        if (Phone.CONTENT_ITEM_TYPE.equals(selectedMimeType) ||
+                Email.CONTENT_ITEM_TYPE.equals(selectedMimeType)) {
+
+            // Used to determine if entry is the only mime type of its kind
+            boolean isUniqueMimeType = true;
+
+            // Checking for unique mime type
+            for (int positionCounter = 0; positionCounter < mAllEntries.size(); positionCounter++) {
+                final ViewEntry entry = mAllEntries.get(positionCounter);
+
+                // Ignoring cases where entry is not a detail entry
+                if (entry.getViewType() != ViewAdapter.VIEW_TYPE_DETAIL_ENTRY) continue;
+
+                final DetailViewEntry checkEntry = (DetailViewEntry) entry;
+                if (positionCounter != info.position &&
+                        checkEntry.mimetype.equalsIgnoreCase(selectedMimeType)) {
+                    isUniqueMimeType = false;
+                    break;
+                }
+            }
+
+            // Checking for previously set default
+            if (selectedEntry.isPrimary) {
+                menu.add(ContextMenu.NONE, ContextMenuIds.CLEAR_DEFAULT,
+                        ContextMenu.NONE, getString(R.string.clear_default));
+            } else if (!isUniqueMimeType) {
+                menu.add(ContextMenu.NONE, ContextMenuIds.SET_DEFAULT,
+                        ContextMenu.NONE, getString(R.string.set_default));
+            }
+        }
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterView.AdapterContextMenuInfo menuInfo;
+        try {
+            menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return false;
+        }
+
+        switch (item.getItemId()) {
+            case ContextMenuIds.COPY_TEXT:
+                copyToClipboard(menuInfo.position);
+                return true;
+            case ContextMenuIds.SET_DEFAULT:
+                setDefaultContactMethod(mListView.getItemIdAtPosition(menuInfo.position));
+                return true;
+            case ContextMenuIds.CLEAR_DEFAULT:
+                clearDefaultContactMethod(mListView.getItemIdAtPosition(menuInfo.position));
+                return true;
+            default:
+                throw new IllegalArgumentException("Unknown menu option " + item.getItemId());
+        }
+    }
+
+    private void setDefaultContactMethod(long id) {
+        Intent setIntent = ContactSaveService.createSetSuperPrimaryIntent(mContext, id);
+        mContext.startService(setIntent);
+    }
+
+    private void clearDefaultContactMethod(long id) {
+        Intent clearIntent = ContactSaveService.createClearPrimaryIntent(mContext, id);
+        mContext.startService(clearIntent);
+    }
+
+    private void copyToClipboard(int viewEntryPosition) {
+        // Getting the text to copied
+        DetailViewEntry detailViewEntry = (DetailViewEntry) mAllEntries.get(viewEntryPosition);
+        CharSequence textToCopy = detailViewEntry.data;
+
+        // Checking for empty string
+        if (TextUtils.isEmpty(textToCopy)) return;
+
+        // Adding item to clipboard
+        ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(
                 Context.CLIPBOARD_SERVICE);
-        cm.setText(text);
-        Toast.makeText(getActivity(), R.string.toast_text_copied, Toast.LENGTH_SHORT).show();
-        return true;
+        String[] mimeTypes = new String[]{detailViewEntry.mimetype};
+        ClipData.Item clipDataItem = new ClipData.Item(textToCopy);
+        ClipData cd = new ClipData(detailViewEntry.typeString, mimeTypes, clipDataItem);
+        clipboardManager.setPrimaryClip(cd);
+
+        // Display Confirmation Toast
+        String toastText = getString(R.string.toast_text_copied);
+        Toast.makeText(getActivity(), toastText, Toast.LENGTH_SHORT).show();
     }
 
     @Override
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index 9085670..8d3cd75 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -17,8 +17,9 @@
 package com.android.contacts.detail;
 
 import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactOptionsActivity;
+import com.android.contacts.ContactSaveService;
 import com.android.contacts.R;
+import com.android.contacts.activities.ContactDetailActivity;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.internal.util.Objects;
@@ -28,9 +29,11 @@
 import android.app.LoaderManager;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.ActivityNotFoundException;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.Loader;
+import android.media.RingtoneManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
@@ -52,9 +55,15 @@
 
     private static final String TAG = ContactLoaderFragment.class.getSimpleName();
 
+    /** The launch code when picking a ringtone */
+    private static final int REQUEST_CODE_PICK_RINGTONE = 1;
+
+
     private boolean mOptionsMenuOptions;
     private boolean mOptionsMenuEditable;
     private boolean mOptionsMenuShareable;
+    private boolean mSendToVoicemailState;
+    private String mCustomRingtone;
 
     /**
      * This is a listener to the {@link ContactLoaderFragment} and will be notified when the
@@ -194,6 +203,8 @@
                     mListener.onDetailsLoaded(mContactData);
                 }
             }
+            // Make sure the options menu is setup correctly with the loaded data.
+            getActivity().invalidateOptionsMenu();
         }
 
         @Override
@@ -222,11 +233,22 @@
         mOptionsMenuOptions = isContactOptionsChangeEnabled();
         mOptionsMenuEditable = isContactEditable();
         mOptionsMenuShareable = isContactShareable();
+        if (mContactData != null) {
+            mSendToVoicemailState = mContactData.isSendToVoicemail();
+            mCustomRingtone = mContactData.getCustomRingtone();
+        }
 
-        // Options only shows telephony-related settings (ringtone, send to voicemail).
-        // ==> Hide if we don't have a telephone
-        final MenuItem optionsMenu = menu.findItem(R.id.menu_options);
-        optionsMenu.setVisible(mOptionsMenuOptions);
+        // Hide telephony-related settings (ringtone, send to voicemail)
+        // if we don't have a telephone
+        final MenuItem optionsSendToVoicemail = menu.findItem(R.id.menu_send_to_voicemail);
+        if (optionsSendToVoicemail != null) {
+            optionsSendToVoicemail.setChecked(mSendToVoicemailState);
+            optionsSendToVoicemail.setVisible(mOptionsMenuOptions);
+        }
+        final MenuItem optionsRingtone = menu.findItem(R.id.menu_set_ringtone);
+        if (optionsRingtone != null) {
+            optionsRingtone.setVisible(mOptionsMenuOptions);
+        }
 
         final MenuItem editMenu = menu.findItem(R.id.menu_edit);
         editMenu.setVisible(mOptionsMenuEditable);
@@ -262,11 +284,9 @@
                 if (mListener != null) mListener.onDeleteRequested(mLookupUri);
                 return true;
             }
-            case R.id.menu_options: {
+            case R.id.menu_set_ringtone: {
                 if (mContactData == null) return false;
-                final Intent intent = new Intent(mContext, ContactOptionsActivity.class);
-                intent.setData(mContactData.getLookupUri());
-                mContext.startActivity(intent);
+                doPickRingtone();
                 return true;
             }
             case R.id.menu_share: {
@@ -290,6 +310,15 @@
                 }
                 return true;
             }
+            case R.id.menu_send_to_voicemail: {
+                // Update state and save
+                mSendToVoicemailState = !mSendToVoicemailState;
+                item.setChecked(mSendToVoicemailState);
+                Intent intent = ContactSaveService.createSetSendToVoicemail(
+                        mContext, mLookupUri, mSendToVoicemailState);
+                mContext.startService(intent);
+                return true;
+            }
         }
         return false;
     }
@@ -304,4 +333,55 @@
         }
         return false;
     }
+
+    private void doPickRingtone() {
+
+        Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+        // Allow user to pick 'Default'
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
+        // Show only ringtones
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
+        // Don't show 'Silent'
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
+
+        Uri ringtoneUri;
+        if (mCustomRingtone != null) {
+            ringtoneUri = Uri.parse(mCustomRingtone);
+        } else {
+            // Otherwise pick default ringtone Uri so that something is selected.
+            ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
+        }
+
+        // Put checkmark next to the current ringtone for this contact
+        intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, ringtoneUri);
+
+        // Launch!
+        startActivityForResult(intent, REQUEST_CODE_PICK_RINGTONE);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode != Activity.RESULT_OK) {
+            return;
+        }
+
+        switch (requestCode) {
+            case REQUEST_CODE_PICK_RINGTONE: {
+                Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
+                handleRingtonePicked(pickedUri);
+                break;
+            }
+        }
+    }
+
+    private void handleRingtonePicked(Uri pickedUri) {
+        if (pickedUri == null || RingtoneManager.isDefault(pickedUri)) {
+            mCustomRingtone = null;
+        } else {
+            mCustomRingtone = pickedUri.toString();
+        }
+        Intent intent = ContactSaveService.createSetRingtone(
+                mContext, mLookupUri, mCustomRingtone);
+        mContext.startService(intent);
+    }
 }
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index 6acbc85..add6b80 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -538,10 +538,8 @@
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
-
-        // If the hardware doesn't have a hardware menu key, we'll show soft menu button on the
-        // right side of digits EditText.
-        if (ViewConfiguration.get(getActivity()).hasPermanentMenuKey()) {
+        if (mShowOptionsMenu && ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
+                mDialpadChooser != null && mDigits != null) {
             inflater.inflate(R.menu.dialpad_options, menu);
         }
     }
@@ -549,16 +547,9 @@
     @Override
     public void onPrepareOptionsMenu(Menu menu) {
         // Hardware menu key should be available and Views should already be ready.
-        if (ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
+        if (mShowOptionsMenu && ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
                 mDialpadChooser != null && mDigits != null) {
-            if (mShowOptionsMenu) {
-                setupMenuItems(menu);
-            } else {
-                menu.findItem(R.id.menu_call_settings_dialpad).setVisible(false);
-                menu.findItem(R.id.menu_add_contacts).setVisible(false);
-                menu.findItem(R.id.menu_2s_pause).setVisible(false);
-                menu.findItem(R.id.menu_add_wait).setVisible(false);
-            }
+             setupMenuItems(menu);
         }
     }
 
diff --git a/src/com/android/contacts/group/GroupBrowseListFragment.java b/src/com/android/contacts/group/GroupBrowseListFragment.java
index d0d370e..a1544cf 100644
--- a/src/com/android/contacts/group/GroupBrowseListFragment.java
+++ b/src/com/android/contacts/group/GroupBrowseListFragment.java
@@ -27,15 +27,19 @@
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.Context;
 import android.content.CursorLoader;
+import android.content.Intent;
 import android.content.Loader;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.provider.ContactsContract;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
@@ -61,6 +65,7 @@
          * @param groupUri for the group that the user wishes to view.
          */
         void onViewGroupAction(Uri groupUri);
+
     }
 
     private static final String TAG = "GroupBrowseListFragment";
@@ -77,6 +82,8 @@
     private View mRootView;
     private AutoScrollListView mListView;
     private View mEmptyView;
+    private View mAddAccountsView;
+    private View mAddAccountButton;
 
     private GroupBrowseListAdapter mAdapter;
     private boolean mSelectionVisible;
@@ -113,6 +120,21 @@
             }
         });
 
+        mEmptyView = mRootView.findViewById(R.id.empty);
+        mAddAccountsView = mRootView.findViewById(R.id.add_accounts);
+        mAddAccountButton = mRootView.findViewById(R.id.add_account_button);
+        mAddAccountButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                intent.putExtra(Settings.EXTRA_AUTHORITIES,
+                        new String[] { ContactsContract.AUTHORITY });
+                startActivity(intent);
+            }
+        });
+        setAddAccountsVisibility(false);
+
         if (savedInstanceState != null) {
             String groupUriString = savedInstanceState.getString(EXTRA_KEY_GROUP_URI);
             if (groupUriString != null) {
@@ -281,4 +303,10 @@
             }
         }
     }
+
+    public void setAddAccountsVisibility(boolean visible) {
+        if (mAddAccountsView != null) {
+            mAddAccountsView.setVisibility(visible ? View.VISIBLE : View.GONE);
+        }
+    }
 }
diff --git a/src/com/android/contacts/list/ContactsUnavailableFragment.java b/src/com/android/contacts/list/ContactsUnavailableFragment.java
index e93687f..3bab3fd 100644
--- a/src/com/android/contacts/list/ContactsUnavailableFragment.java
+++ b/src/com/android/contacts/list/ContactsUnavailableFragment.java
@@ -45,6 +45,7 @@
     private Button mUninstallAppsButton;
     private Button mRetryUpgradeButton;
     private ProgressBar mProgress;
+    private int mNoContactsMsgResId = -1;
 
     private OnContactsUnavailableActionListener mListener;
 
@@ -81,8 +82,14 @@
         int providerStatus = mProviderStatusLoader.getProviderStatus();
         switch (providerStatus) {
             case ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS:
-                mMessageView.setGravity(Gravity.LEFT);
-                mMessageView.setVisibility(View.GONE);
+                if (mNoContactsMsgResId != -1) {
+                    mMessageView.setText(mNoContactsMsgResId);
+                    mMessageView.setGravity(Gravity.CENTER_HORIZONTAL);
+                    mMessageView.setVisibility(View.VISIBLE);
+                } else {
+                    mMessageView.setGravity(Gravity.LEFT);
+                    mMessageView.setVisibility(View.GONE);
+                }
                 mCreateContactButton.setVisibility(View.VISIBLE);
                 mAddAccountButton.setVisibility(View.VISIBLE);
                 mImportContactsButton.setVisibility(View.VISIBLE);
@@ -154,4 +161,19 @@
                 break;
         }
     }
+    /**
+     * Set the message to be shown if data is available for the selected tab
+     *
+     * @param resId - String resource ID of the message
+     */
+    public void setMessageText(int resId) {
+        mNoContactsMsgResId = resId;
+        if (mMessageView != null &&
+                mProviderStatusLoader.getProviderStatus() ==
+                    ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS) {
+            mMessageView.setText(mNoContactsMsgResId);
+            mMessageView.setGravity(Gravity.CENTER_HORIZONTAL);
+            mMessageView.setVisibility(View.VISIBLE);
+        }
+    }
 }
diff --git a/tests/src/com/android/contacts/ContactLoaderTest.java b/tests/src/com/android/contacts/ContactLoaderTest.java
index 1d3fb20..3d0ddb4 100644
--- a/tests/src/com/android/contacts/ContactLoaderTest.java
+++ b/tests/src/com/android/contacts/ContactLoaderTest.java
@@ -297,6 +297,9 @@
                         Data.STATUS_LABEL, Data.STATUS_TIMESTAMP,
 
                         Contacts.PHOTO_URI,
+
+                        Contacts.SEND_TO_VOICEMAIL,
+                        Contacts.CUSTOM_RINGTONE,
                     })
                     .withSortOrder(Contacts.Entity.RAW_CONTACT_ID)
                     .returnRow(
@@ -330,7 +333,10 @@
                         "Having dinner", "mockPkg3", 0,
                         20, 0,
 
-                        "content:some.photo.uri"
+                        "content:some.photo.uri",
+
+                        0,
+                        null
                     );
         }