Merge "Handle the case of a null cursor being returned."
diff --git a/res/layout/account_filter_header.xml b/res/layout/account_filter_header.xml
index ef0a9c2..0ffb7e1 100644
--- a/res/layout/account_filter_header.xml
+++ b/res/layout/account_filter_header.xml
@@ -23,7 +23,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:paddingTop="@dimen/account_filter_header_top_padding"
+    android:paddingTop="@dimen/list_header_extra_top_padding"
     android:layout_marginLeft="@dimen/contact_browser_list_header_left_margin"
     android:layout_marginRight="@dimen/contact_browser_list_header_right_margin"
     android:background="?android:attr/selectableItemBackground"
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
index 13124f2..7498f5a 100644
--- a/res/layout/call_detail.xml
+++ b/res/layout/call_detail.xml
@@ -162,16 +162,22 @@
                     <TextView android:id="@+id/call_and_sms_text"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
+                        android:paddingRight="@dimen/call_log_icon_margin"
                         android:textAppearance="?android:attr/textAppearanceMedium"
                         android:textColor="?attr/call_log_primary_text_color"
+                        android:singleLine="true"
+                        android:ellipsize="end"
                     />
 
                     <TextView android:id="@+id/call_and_sms_label"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
+                        android:paddingRight="@dimen/call_log_icon_margin"
                         android:textAppearance="?android:attr/textAppearanceSmall"
                         android:textColor="?attr/call_log_primary_text_color"
                         android:textAllCaps="true"
+                        android:singleLine="true"
+                        android:ellipsize="end"
                     />
 
                 </LinearLayout>
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index 777c7af..4040c28 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -69,18 +69,38 @@
                     android:id="@+id/name"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_marginRight="@dimen/call_log_icon_margin"
                     android:textColor="?attr/call_log_primary_text_color"
                     android:textSize="18sp"
                     android:singleLine="true"
                 />
-                <TextView
-                    android:id="@+id/number"
+                <LinearLayout
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:textColor="?attr/call_log_secondary_text_color"
-                    android:textSize="14sp"
-                    android:singleLine="true"
-                />
+                    android:orientation="horizontal"
+                >
+                    <TextView
+                        android:id="@+id/number"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginRight="@dimen/call_log_icon_margin"
+                        android:textColor="?attr/call_log_secondary_text_color"
+                        android:textSize="14sp"
+                        android:singleLine="true"
+                        android:ellipsize="marquee"
+                        />
+                    <TextView
+                        android:id="@+id/label"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginRight="@dimen/call_log_icon_margin"
+                        android:textColor="?attr/call_log_secondary_text_color"
+                        android:textStyle="bold"
+                        android:textSize="14sp"
+                        android:singleLine="true"
+                        android:ellipsize="marquee"
+                        />
+                    </LinearLayout>
                 <LinearLayout
                     android:id="@+id/call_type"
                     android:layout_width="wrap_content"
@@ -99,6 +119,7 @@
                         android:id="@+id/call_count_and_date"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
+                        android:layout_marginRight="@dimen/call_log_icon_margin"
                         android:layout_gravity="center_vertical"
                         android:textColor="?attr/call_log_secondary_text_color"
                         android:textSize="14sp"
diff --git a/res/layout/group_browse_list_account_header.xml b/res/layout/group_browse_list_account_header.xml
index 709c276..78e0639 100644
--- a/res/layout/group_browse_list_account_header.xml
+++ b/res/layout/group_browse_list_account_header.xml
@@ -24,7 +24,7 @@
     <View
         android:id="@+id/header_extra_top_padding"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/contact_browser_list_top_margin" />
+        android:layout_height="@dimen/list_header_extra_top_padding" />
 
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/res/menu/dialtacts_options.xml b/res/menu/dialtacts_options.xml
index fb1987c..a35f2ea 100644
--- a/res/menu/dialtacts_options.xml
+++ b/res/menu/dialtacts_options.xml
@@ -34,6 +34,7 @@
 
     <item
         android:id="@+id/add_contact"
+        android:icon="@drawable/ic_add_contact_holo_dark"
         android:title="@string/menu_newContact"
-        android:showAsAction="withText" />
+        android:showAsAction="ifRoom" />
 </menu>
diff --git a/res/menu/phone_favorite_options.xml b/res/menu/phone_favorite_options.xml
new file mode 100644
index 0000000..ac67d6e
--- /dev/null
+++ b/res/menu/phone_favorite_options.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/menu_import_export"
+        android:title="@string/menu_import_export" />
+
+    <item
+        android:id="@+id/menu_accounts"
+        android:title="@string/menu_accounts" />
+</menu>
diff --git a/res/values-sw580dp/dimens.xml b/res/values-sw580dp/dimens.xml
index 3d3cb17..264565f 100644
--- a/res/values-sw580dp/dimens.xml
+++ b/res/values-sw580dp/dimens.xml
@@ -38,7 +38,7 @@
     <dimen name="contact_browser_list_header_left_margin">@dimen/list_visible_scrollbar_padding</dimen>
     <dimen name="contact_browser_list_header_right_margin">24dip</dimen>
     <dimen name="list_visible_scrollbar_padding">48dip</dimen>
-    <dimen name="account_filter_header_top_padding">@dimen/contact_browser_list_top_margin</dimen>
+    <dimen name="list_header_extra_top_padding">@dimen/contact_browser_list_top_margin</dimen>
 
     <!-- Because the "join" screen has the vertical scroll bar on right,
       we cannot use @dimen/contact_browser_list_header_left_margin as is. -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e856d67..e1d611d 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -178,7 +178,9 @@
     <dimen name="join_header_top_margin">16dip</dimen>
     <dimen name="join_header_bottom_margin">0dip</dimen>
 
-    <dimen name="account_filter_header_top_padding">0dip</dimen>
+    <!-- Padding between the action bar's bottom edge and the first header
+         in contacts/group lists. -->
+    <dimen name="list_header_extra_top_padding">0dip</dimen>
 
     <!-- ContactTile Layouts -->
     <!--
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 30ba696..225c9fe 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -163,9 +163,6 @@
     <!-- Toast shown after two contacts have been joined by a user action -->
     <string name="contactsJoinedMessage">Contacts joined</string>
 
-    <!-- Confirmation dialog title after users selects to delete a contact. [CHAR LIMIT=25]-->
-    <string name="deleteConfirmation_title">Delete contact?</string>
-
     <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=15] -->
     <string name="menu_set_ring_tone">Set ringtone</string>
 
@@ -585,8 +582,6 @@
     <!-- The text displayed on the divider for the Favorites tab in Phone app indicating that items below it are frequently called as opposed to starred contacts [CHAR LIMIT = 39] -->
     <string name="favoritesFrequentCalled">Frequently called</string>
 
-    <!-- Dialog title when prompting before creating a contact -->
-    <string name="add_contact_dlg_title">Add contact</string>
     <!-- Dialog message when prompting before creating a contact. Includes
          the email address, e.g. "Add xyz@foo.com to contacts?" -->
     <string name="add_contact_dlg_message_fmt">Add \"<xliff:g id="email">%s</xliff:g>\" to contacts?</string>
@@ -732,19 +727,11 @@
       -->
     <string name="description_view_contact_detail" msgid="2795575601596468581">View contact</string>
 
-    <!-- Dialog title shown when (USB) storage does not exist [CHAR LIMIT=25] -->
-    <string name="no_sdcard_title" product="nosdcard">Storage unavailable</string>
-    <!-- Dialog title shown when SD Card does not exist -->
-    <string name="no_sdcard_title" product="default">No SD card</string>
-
     <!-- Dialog message shown when (USB) storage does not exist [CHAR LIMIT=30] -->
     <string name="no_sdcard_message" product="nosdcard">No storage was found.</string>
     <!-- Dialog message shown when SDcard does not exist. [CHAR LIMIT=30] -->
     <string name="no_sdcard_message" product="default">No SD card was found.</string>
 
-    <!-- Dialog title shown when searching vCard data from SD Card -->
-    <string name="searching_vcard_title">Searching for vCard</string>
-
     <!-- Action string for selecting SIM for importing contacts -->
     <string name="import_from_sim">Import from SIM card</string>
 
@@ -777,11 +764,6 @@
     <!-- Dialog message shown when searching VCard data from SD Card. [CHAR LIMIT=NONE] -->
     <string name="searching_vcard_message" product="default">Searching for vCard data on SD card\u2026</string>
 
-    <!-- Dialog title shown when scanning VCard data failed. [CHAR LIMIT=NONE] -->
-    <string name="scanning_sdcard_failed_title" product="nosdcard">Couldn\'t scan storage</string>
-    <!-- Dialog title shown when scanning VCard data failed. -->
-    <string name="scanning_sdcard_failed_title" product="default">Couldn\'t scan SD card</string>
-
     <!-- Dialog message shown when searching VCard data failed.
          An exact reason for the failure should [CHAR LIMIT=NONE] -->
     <string name="scanning_sdcard_failed_message" product="nosdcard">The storage couldn\'t be scanned. (Reason: \"<xliff:g id="fail_reason">%s</xliff:g>\")</string>
@@ -969,17 +951,11 @@
     <!-- Message in progress bar while exporting contact list to a file "(current number) of (total number) contacts" The order of "current number" and "total number" cannot be changed (like "total: (total number), current: (current number)")-->
     <string name="exporting_contact_list_progress"><xliff:g id="current_number">%s</xliff:g> of <xliff:g id="total_number">%s</xliff:g> contacts</string>
 
-    <!-- Title shown in a Dialog confirming a user's cancel request toward existing vCard import. [CHAR LIMIT=40] -->
-    <string name="cancel_import_confirmation_title">Canceling vCard import</string>
-
     <!-- Message shown in a Dialog confirming a user's cancel request toward existing vCard import.
          The argument is file name for the vCard import the user wants to cancel.
          [CHAR LIMIT=128] -->
     <string name="cancel_import_confirmation_message">Cancel import of <xliff:g id="filename" example="import.vcf">%s</xliff:g>?</string>
 
-    <!-- Title shown in a Dialog confirming a user's cancel request toward existing vCard export. [CHAR LIMIT=128] -->
-    <string name="cancel_export_confirmation_title">Canceling vCard export</string>
-
     <!-- Message shown in a Dialog confirming a user's cancel request toward existing vCard export.
          The argument is file name for the vCard export the user wants to cancel.
          [CHAR LIMIT=128] -->
@@ -1394,19 +1370,11 @@
     <!-- The name of the invisible local contact directory -->
     <string name="local_invisible_directory">Other</string>
 
-    <!-- The title of a confirmation dialog shown when the user selects a
-        contact aggregation suggestion in Contact editor. [CHAR LIMIT=128]-->
-    <string name="aggregation_suggestion_join_dialog_title">Join contacts</string>
-
     <!-- The message in a confirmation dialog shown when the user selects a
         contact aggregation suggestion in Contact editor. [CHAR LIMIT=512]-->
     <string name="aggregation_suggestion_join_dialog_message">Join
         the current contact with the selected contact?</string>
 
-    <!-- The title of a confirmation dialog shown when the user selects a
-        contact aggregation suggestion in Contact editor. [CHAR LIMIT=128]-->
-    <string name="aggregation_suggestion_edit_dialog_title">Edit selected contacts</string>
-
     <!-- The message in a confirmation dialog shown when the user selects a
         contact aggregation suggestion in Contact editor. [CHAR LIMIT=512]-->
     <string name="aggregation_suggestion_edit_dialog_message">Switch to editing
@@ -1518,9 +1486,6 @@
     <!-- An item in the popup list of groups that triggers creation of a contact group [CHAR LIMIT=128] -->
     <string name="create_group_item_label">[Create new group]</string>
 
-    <!-- Title of the dialog that allows deletion of a contact group [CHAR LIMIT=128] -->
-    <string name="delete_group_dialog_title">Delete group</string>
-
     <!-- Shows how many groups are from the specified account [CHAR LIMIT=15] -->
     <plurals name="num_groups_in_account">
         <item quantity="one">1 group</item>
@@ -1563,9 +1528,6 @@
     <!-- Toast shown when text is copied to the clipboard [CHAR LIMIT=64] -->
     <string name="toast_text_copied">Text copied</string>
 
-    <!-- Title of the alert dialog when the user hits the Cancel button in the editor [CHAR LIMIT=64] -->
-    <string name="cancel_confirmation_dialog_title">Discard changes</string>
-
     <!-- Contents of the alert dialog when the user hits the Cancel button in the editor [CHAR LIMIT=128] -->
     <string name="cancel_confirmation_dialog_message">Discard your changes?</string>
 
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 2d75c26..60dfb7b 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -18,7 +18,6 @@
 
 import com.android.contacts.calllog.CallTypeHelper;
 import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.format.FormatUtils;
 
 import android.content.res.Resources;
 import android.graphics.Typeface;
@@ -103,6 +102,7 @@
 
         final CharSequence nameText;
         final CharSequence numberText;
+        final CharSequence labelText;
         final CharSequence displayNumber =
             mPhoneNumberHelper.getDisplayNumber(details.number, details.formattedNumber);
         if (TextUtils.isEmpty(details.name)) {
@@ -113,20 +113,17 @@
             } else {
                 numberText = details.geocode;
             }
+            labelText = null;
         } else {
             nameText = details.name;
-            if (numberFormattedLabel != null) {
-                numberText = FormatUtils.applyStyleToSpan(Typeface.BOLD,
-                        numberFormattedLabel + " " + displayNumber, 0,
-                        numberFormattedLabel.length(),
-                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            } else {
-                numberText = displayNumber;
-            }
+            numberText = displayNumber;
+            labelText = numberFormattedLabel;
         }
 
         views.nameView.setText(nameText);
         views.numberView.setText(numberText);
+        views.labelView.setText(labelText);
+        views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE);
     }
 
     /** Sets the text of the header view for the details page of a phone call. */
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
index fa06879..ea5a461 100644
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ b/src/com/android/contacts/PhoneCallDetailsViews.java
@@ -31,14 +31,17 @@
     public final CallTypeIconsView callTypeIcons;
     public final TextView callTypeAndDate;
     public final TextView numberView;
+    public final TextView labelView;
 
     private PhoneCallDetailsViews(TextView nameView, View callTypeView,
-            CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView numberView) {
+            CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView numberView,
+            TextView labelView) {
         this.nameView = nameView;
         this.callTypeView = callTypeView;
         this.callTypeIcons = callTypeIcons;
         this.callTypeAndDate = callTypeAndDate;
         this.numberView = numberView;
+        this.labelView = labelView;
     }
 
     /**
@@ -53,7 +56,8 @@
                 view.findViewById(R.id.call_type),
                 (CallTypeIconsView) view.findViewById(R.id.call_type_icons),
                 (TextView) view.findViewById(R.id.call_count_and_date),
-                (TextView) view.findViewById(R.id.number));
+                (TextView) view.findViewById(R.id.number),
+                (TextView) view.findViewById(R.id.label));
     }
 
     public static PhoneCallDetailsViews createForTest(Context context) {
@@ -62,6 +66,7 @@
                 new View(context),
                 new CallTypeIconsView(context),
                 new TextView(context),
+                new TextView(context),
                 new TextView(context));
     }
 }
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index d6c0ab1..d4a96e1 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -165,6 +165,40 @@
 
             actionBar.selectTab(actionBar.getTabAt(position));
             mNextPosition = position;
+
+            // This method is called halfway between swiping between the two pages.
+            // When the next page is fully selected, the ViewPager will go back to IDLE state in
+            // onPageScrollStateChanged(). The order should be:
+            // (user's swipe) -> onPageSelected() -> IDLE in onPageScrollStateChanged()
+            //
+            // sendFragmentVisibilityChange() must be called from here or in the IDLE state to
+            // notify the visibility change events to two pages: the current page (pointed by
+            // mCurrentPosition) should receive sendFragmentVisibilityChange() with the second
+            // argument false, meaning "the page is now invisible", while the next page (pointed by
+            // mNextPosition) should receive the method with the second argument true, meaning
+            // "the page becomes visible".
+            //
+            // To make transition animation smooth enough, we need to delay the event in some cases:
+            // - We should delay both method calls when the dialpad screen is involved.
+            //   The screen does not have the bottom action bar, requiring different layout to
+            //   fill the screen. The layout refresh takes some time and thus should be done after
+            //   the page migration being completed.
+            // - We should delay the method for the call log screen. The screen will update
+            //   its internal state and may query full call log. which is too costly to do when
+            //   onVisibilityChanged() is called, making the animation slower.
+            // - We should *not* delay the method for the phone favorite screen. The screen has
+            //   another icon the call log screen doesn't have. We want to show/hide it immediately
+            //   after user's choosing pages.
+            if (mCurrentPosition == TAB_INDEX_CALL_LOG && mNextPosition == TAB_INDEX_FAVORITES) {
+                sendFragmentVisibilityChange(mNextPosition, true /* visible */ );
+                invalidateOptionsMenu();
+            } else if (mCurrentPosition == TAB_INDEX_FAVORITES
+                    && mNextPosition == TAB_INDEX_CALL_LOG) {
+                sendFragmentVisibilityChange(mCurrentPosition, false /* not visible */ );
+                invalidateOptionsMenu();
+            } else {
+                // Delay sendFragmentVisibilityChange() for both positions.
+            }
         }
 
         public void setCurrentPosition(int position) {
@@ -175,11 +209,17 @@
         public void onPageScrollStateChanged(int state) {
             switch (state) {
                 case ViewPager.SCROLL_STATE_IDLE: {
-                    if (mCurrentPosition >= 0) {
-                        sendFragmentVisibilityChange(mCurrentPosition, false);
-                    }
-                    if (mNextPosition >= 0) {
-                        sendFragmentVisibilityChange(mNextPosition, true);
+                    // Call delayed sendFragmentVisibilityChange() call(s).
+                    // See comments in onPageSelected() for more details.
+                    if (mCurrentPosition == TAB_INDEX_CALL_LOG
+                            && mNextPosition == TAB_INDEX_FAVORITES) {
+                        sendFragmentVisibilityChange(mCurrentPosition, false /* not visible */ );
+                    } else if (mCurrentPosition == TAB_INDEX_FAVORITES
+                            && mNextPosition == TAB_INDEX_CALL_LOG) {
+                        sendFragmentVisibilityChange(mNextPosition, true /* visible */ );
+                    } else {
+                        sendFragmentVisibilityChange(mCurrentPosition, false /* not visible */ );
+                        sendFragmentVisibilityChange(mNextPosition, true /* visible */ );
                     }
                     invalidateOptionsMenu();
 
@@ -526,6 +566,9 @@
                     && mContactListFilterController.getFilter() != null) {
                 mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
             }
+            if (currentPosition == TAB_INDEX_FAVORITES) {
+                mPhoneFavoriteFragment.onVisibilityChanged(true);
+            }
         } else if (fragment instanceof PhoneNumberPickerFragment) {
             mSearchFragment = (PhoneNumberPickerFragment) fragment;
             mSearchFragment.setOnPhoneNumberPickerActionListener(mPhoneNumberPickerActionListener);
@@ -653,10 +696,10 @@
         final int previousItemIndex = mViewPager.getCurrentItem();
         mViewPager.setCurrentItem(tabIndex, false /* smoothScroll */);
         if (previousItemIndex != tabIndex) {
-            sendFragmentVisibilityChange(previousItemIndex, false);
+            sendFragmentVisibilityChange(previousItemIndex, false /* not visible */ );
         }
         mPageChangeListener.setCurrentPosition(tabIndex);
-        sendFragmentVisibilityChange(tabIndex, true);
+        sendFragmentVisibilityChange(tabIndex, true /* visible */ );
 
         // Restore to the previous manual selection
         mLastManuallySelectedFragment = savedTabIndex;
@@ -777,21 +820,18 @@
         final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
         final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
         final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        Tab tab = getActionBar().getSelectedTab();
+        final Tab tab = getActionBar().getSelectedTab();
         if (mInSearchUi) {
             searchMenuItem.setVisible(false);
             if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
                 filterOptionMenuItem.setVisible(true);
                 filterOptionMenuItem.setOnMenuItemClickListener(
                         mFilterOptionsMenuItemClickListener);
-                addContactOptionMenuItem.setVisible(true);
-                addContactOptionMenuItem.setIntent(
-                        new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
             } else {
                 // Filter option menu should be not be shown as a overflow menu.
                 filterOptionMenuItem.setVisible(false);
-                addContactOptionMenuItem.setVisible(false);
             }
+            addContactOptionMenuItem.setVisible(false);
             callSettingsMenuItem.setVisible(false);
         } else {
             final boolean showCallSettingsMenu;
@@ -879,7 +919,7 @@
         actionBar.setDisplayShowHomeEnabled(true);
         actionBar.setDisplayHomeAsUpEnabled(true);
 
-        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), false);
+        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), false /* not visible */ );
 
         // Show the search fragment and hide everything else.
         mSearchFragment.setUserVisibleHint(true);
@@ -931,7 +971,7 @@
         actionBar.setDisplayShowHomeEnabled(false);
         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 
-        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), true);
+        sendFragmentVisibilityChange(mViewPager.getCurrentItem(), true /* visible */ );
 
         mViewPager.setVisibility(View.VISIBLE);
 
@@ -959,9 +999,12 @@
     }
 
     private void sendFragmentVisibilityChange(int position, boolean visibility) {
-        final Fragment fragment = getFragmentAt(position);
-        if (fragment instanceof ViewPagerVisibilityListener) {
-            ((ViewPagerVisibilityListener) fragment).onVisibilityChanged(visibility);
+        // Position can be -1 initially. See PageChangeListener.
+        if (position >= 0) {
+            final Fragment fragment = getFragmentAt(position);
+            if (fragment instanceof ViewPagerVisibilityListener) {
+                ((ViewPagerVisibilityListener) fragment).onVisibilityChanged(visibility);
+            }
         }
     }
 
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index ba1e257..6bc959d 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -968,7 +968,12 @@
         View mainView = findViewById(R.id.main_view);
 
         if (mProviderStatus == ProviderStatus.STATUS_NORMAL) {
+            // Ensure that the mTabPager is visible; we may have made it invisible below.
             contactsUnavailableView.setVisibility(View.GONE);
+            if (mTabPager != null) {
+                mTabPager.setVisibility(View.VISIBLE);
+            }
+
             if (mainView != null) {
                 mainView.setVisibility(View.VISIBLE);
             }
@@ -1001,7 +1006,14 @@
             } else {
                 mContactsUnavailableFragment.update();
             }
+
+            // Show the contactsUnavailableView, and hide the mTabPager so that we don't
+            // see it sliding in underneath the contactsUnavailableView at the edges.
             contactsUnavailableView.setVisibility(View.VISIBLE);
+            if (mTabPager != null) {
+                mTabPager.setVisibility(View.GONE);
+            }
+
             if (mainView != null) {
                 mainView.setVisibility(View.INVISIBLE);
             }
diff --git a/src/com/android/contacts/activities/ShowOrCreateActivity.java b/src/com/android/contacts/activities/ShowOrCreateActivity.java
index c60d0fb..50658c3 100755
--- a/src/com/android/contacts/activities/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/activities/ShowOrCreateActivity.java
@@ -216,7 +216,6 @@
                         R.string.add_contact_dlg_message_fmt, mCreateDescrip);
 
                 return new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT)
-                        .setTitle(R.string.add_contact_dlg_title)
                         .setMessage(message)
                         .setPositiveButton(android.R.string.ok,
                                 new IntentClickListener(this, createIntent))
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
index b38430b..99ba8e8 100644
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ b/src/com/android/contacts/calllog/CallLogAdapter.java
@@ -54,6 +54,37 @@
         public void fetchCalls();
     }
 
+    /**
+     * Stores a phone number of a call with the country code where it originally occurred.
+     * <p>
+     * Note the country does not necessarily specifies the country of the phone number itself, but
+     * it is the country in which the user was in when the call was placed or received.
+     */
+    private static final class NumberWithCountryIso {
+        public final String number;
+        public final String countryIso;
+
+        public NumberWithCountryIso(String number, String countryIso) {
+            this.number = number;
+            this.countryIso = countryIso;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) return false;
+            if (!(o instanceof NumberWithCountryIso)) return false;
+            NumberWithCountryIso other = (NumberWithCountryIso) o;
+            return TextUtils.equals(number, other.number)
+                    && TextUtils.equals(countryIso, other.countryIso);
+        }
+
+        @Override
+        public int hashCode() {
+            return (number == null ? 0 : number.hashCode())
+                    ^ (countryIso == null ? 0 : countryIso.hashCode());
+        }
+    }
+
     /** The time in millis to delay starting the thread processing requests. */
     private static final int START_PROCESSING_REQUESTS_DELAY_MILLIS = 1000;
 
@@ -69,8 +100,10 @@
      * <p>
      * The content of the cache is expired (but not purged) whenever the application comes to
      * the foreground.
+     * <p>
+     * The key is number with the country in which the call was placed or received.
      */
-    private ExpirableCache<String, ContactInfo> mContactInfoCache;
+    private ExpirableCache<NumberWithCountryIso, ContactInfo> mContactInfoCache;
 
     /**
      * A request for contact details for the given number.
@@ -317,14 +350,15 @@
 
         // Check the existing entry in the cache: only if it has changed we should update the
         // view.
-        ContactInfo existingInfo = mContactInfoCache.getPossiblyExpired(number);
+        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
+        ContactInfo existingInfo = mContactInfoCache.getPossiblyExpired(numberCountryIso);
         boolean updated = !info.equals(existingInfo);
         // Store the data in the cache so that the UI thread can use to display it. Store it
         // even if it has not changed so that it is marked as not expired.
-        mContactInfoCache.put(number, info);
+        mContactInfoCache.put(numberCountryIso, info);
         // Update the call log even if the cache it is up-to-date: it is possible that the cache
         // contains the value from a different call log entry.
-        updateCallLogContactInfoCache(number, info, callLogInfo);
+        updateCallLogContactInfoCache(number, countryIso, info, callLogInfo);
         return updated;
     }
     /*
@@ -471,8 +505,9 @@
         }
 
         // Lookup contacts with this number
+        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
         ExpirableCache.CachedValue<ContactInfo> cachedInfo =
-                mContactInfoCache.getCachedValue(number);
+                mContactInfoCache.getCachedValue(numberCountryIso);
         ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue();
         if (!mPhoneNumberHelper.canPlaceCallsTo(number)
                 || mPhoneNumberHelper.isVoicemailNumber(number)) {
@@ -480,7 +515,7 @@
             // for it.
             info = ContactInfo.EMPTY;
         } else if (cachedInfo == null) {
-            mContactInfoCache.put(number, ContactInfo.EMPTY);
+            mContactInfoCache.put(numberCountryIso, ContactInfo.EMPTY);
             // Use the cached contact info from the call log.
             info = cachedContactInfo;
             // The db request should happen on a non-UI thread.
@@ -558,8 +593,8 @@
     }
 
     /** Stores the updated contact info in the call log if it is different from the current one. */
-    private void updateCallLogContactInfoCache(String number, ContactInfo updatedInfo,
-            ContactInfo callLogInfo) {
+    private void updateCallLogContactInfoCache(String number, String countryIso,
+            ContactInfo updatedInfo, ContactInfo callLogInfo) {
         final ContentValues values = new ContentValues();
         boolean needsUpdate = false;
 
@@ -615,12 +650,15 @@
             return;
         }
 
-        StringBuilder where = new StringBuilder();
-        where.append(Calls.NUMBER);
-        where.append(" = ?");
-
-        mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
-                where.toString(), new String[]{ number });
+        if (countryIso == null) {
+            mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
+                    Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
+                    new String[]{ number });
+        } else {
+            mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
+                    Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
+                    new String[]{ number, countryIso });
+        }
     }
 
     /** Returns the contact information as stored in the call log. */
@@ -674,8 +712,9 @@
     }
 
     @VisibleForTesting
-    void injectContactInfoForTest(String number, ContactInfo contactInfo) {
-        mContactInfoCache.put(number, contactInfo);
+    void injectContactInfoForTest(String number, String countryIso, ContactInfo contactInfo) {
+        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
+        mContactInfoCache.put(numberCountryIso, contactInfo);
     }
 
     @Override
@@ -692,10 +731,11 @@
      *         Else if the number in the contacts starts with a "+", use that one
      *         Else if the number in the contacts is longer, use that one
      */
-    public String getBetterNumberFromContacts(String number) {
+    public String getBetterNumberFromContacts(String number, String countryIso) {
         String matchingNumber = null;
         // Look in the cache first. If it's not found then query the Phones db
-        ContactInfo ci = mContactInfoCache.getPossiblyExpired(number);
+        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
+        ContactInfo ci = mContactInfoCache.getPossiblyExpired(numberCountryIso);
         if (ci != null && ci != ContactInfo.EMPTY) {
             matchingNumber = ci.number;
         } else {
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 88aab4d..2033d25 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -334,7 +334,8 @@
                        (callType == Calls.INCOMING_TYPE
                                 || callType == Calls.MISSED_TYPE)) {
                     // If the caller-id matches a contact with a better qualified number, use it
-                    number = mAdapter.getBetterNumberFromContacts(number);
+                    String countryIso = cursor.getString(CallLogQuery.COUNTRY_ISO);
+                    number = mAdapter.getBetterNumberFromContacts(number, countryIso);
                 }
                 intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
                                     Uri.fromParts("tel", number, null));
@@ -354,11 +355,6 @@
     public void onVisibilityChanged(boolean visible) {
         if (mShowOptionsMenu != visible) {
             mShowOptionsMenu = visible;
-            // Invalidate the options menu since we are changing the list of options shown in it.
-            Activity activity = getActivity();
-            if (activity != null) {
-                activity.invalidateOptionsMenu();
-            }
         }
 
         if (visible && isResumed()) {
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
index dc31bb2..59dfcd4 100644
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
@@ -96,7 +96,7 @@
         }
 
         if (newCalls.length == 0) {
-            Log.e(TAG, "No voicemails to notify about: clear the notification.");
+            // No voicemails to notify about: clear the notification.
             clearNotification();
             return;
         }
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 844f892..da5237f 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -1062,7 +1062,6 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             AlertDialog dialog = new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.cancel_confirmation_dialog_title)
                     .setMessage(R.string.cancel_confirmation_dialog_message)
                     .setPositiveButton(android.R.string.ok,
                         new DialogInterface.OnClickListener() {
@@ -1456,7 +1455,6 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.aggregation_suggestion_join_dialog_title)
                     .setMessage(R.string.aggregation_suggestion_join_dialog_message)
                     .setPositiveButton(android.R.string.yes,
                         new DialogInterface.OnClickListener() {
@@ -1504,7 +1502,6 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             return new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.aggregation_suggestion_edit_dialog_title)
                     .setMessage(R.string.aggregation_suggestion_edit_dialog_message)
                     .setPositiveButton(android.R.string.yes,
                         new DialogInterface.OnClickListener() {
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index ff0af6f..2a1ec5e 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -364,14 +364,15 @@
      * no empty text is allowed in any custom label.
      */
     private Dialog createCustomDialog() {
-        final EditText customType = new EditText(mContext);
+        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+        builder.setTitle(R.string.customLabelPickerTitle);
+
+        final EditText customType = new EditText(builder.getContext());
         customType.setId(R.id.custom_dialog_content);
         customType.setInputType(INPUT_TYPE_CUSTOM);
         customType.setSaveEnabled(true);
         customType.requestFocus();
 
-        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
-        builder.setTitle(R.string.customLabelPickerTitle);
         builder.setView(customType);
 
         builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index a3ebeb0..9d056f4 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -550,7 +550,6 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             AlertDialog dialog = new AlertDialog.Builder(getActivity())
                     .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setTitle(R.string.cancel_confirmation_dialog_title)
                     .setMessage(R.string.cancel_confirmation_dialog_message)
                     .setPositiveButton(android.R.string.ok,
                         new DialogInterface.OnClickListener() {
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 7e880a4..4aa4030 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -274,7 +274,6 @@
 
     private void showDialog(int messageId, final Uri contactUri) {
         mDialog = new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.deleteConfirmation_title)
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setMessage(messageId)
                 .setNegativeButton(android.R.string.cancel, null)
diff --git a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
index c1f3bd7..09306f2 100644
--- a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
@@ -52,7 +52,6 @@
 
         return new AlertDialog.Builder(getActivity())
                 .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setTitle(R.string.delete_group_dialog_title)
                 .setMessage(message)
                 .setPositiveButton(android.R.string.ok,
                     new DialogInterface.OnClickListener() {
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index 9c36f05..cf86dc9 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -54,13 +54,8 @@
      */
     private static final boolean LOCAL_INVISIBLE_DIRECTORY_ENABLED = false;
 
-    /**
-     * The animation is used here to allocate animated name text views.
-     */
-    private TextWithHighlightingFactory mTextWithHighlightingFactory;
     private int mDisplayOrder;
     private int mSortOrder;
-    private boolean mNameHighlightingEnabled;
 
     private boolean mDisplayPhotos;
     private boolean mQuickContactEnabled;
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index af06995..b512bf1 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -18,6 +18,8 @@
 import com.android.contacts.ContactPhotoManager;
 import com.android.contacts.ContactTileLoaderFactory;
 import com.android.contacts.R;
+import com.android.contacts.activities.DialtactsActivity.ViewPagerVisibilityListener;
+import com.android.contacts.interactions.ImportExportDialogFragment;
 import com.android.contacts.preference.ContactsPreferences;
 import com.android.contacts.util.AccountFilterUtil;
 
@@ -32,9 +34,15 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Directory;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
@@ -53,7 +61,8 @@
  * {@link PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}.
  * A contact filter header is also inserted between those adapters' results.
  */
-public class PhoneFavoriteFragment extends Fragment implements OnItemClickListener {
+public class PhoneFavoriteFragment extends Fragment implements OnItemClickListener,
+        ViewPagerVisibilityListener{
     private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
     private static final boolean DEBUG = false;
 
@@ -215,12 +224,15 @@
             new ContactsPreferenceChangeListener();
     private final ScrollListener mScrollListener = new ScrollListener();
 
+    private boolean mShowOptionsMenu;
+
     @Override
     public void onCreate(Bundle savedState) {
         super.onCreate(savedState);
         if (savedState != null) {
             mFilter = savedState.getParcelable(KEY_FILTER);
         }
+        setHasOptionsMenu(true);
     }
 
     @Override
@@ -319,6 +331,32 @@
     }
 
     @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        if (mShowOptionsMenu) {
+            inflater.inflate(R.menu.phone_favorite_options, menu);
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.menu_import_export:
+                ImportExportDialogFragment.show(getFragmentManager());
+                return true;
+            case R.id.menu_accounts:
+                final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
+                intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
+                    ContactsContract.AUTHORITY
+                });
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                startActivity(intent);
+                return true;
+        }
+        return false;
+    }
+
+    @Override
     public void onStart() {
         super.onStart();
 
@@ -453,4 +491,9 @@
     public void setListener(Listener listener) {
         mListener = listener;
     }
+
+    @Override
+    public void onVisibilityChanged(boolean visible) {
+        mShowOptionsMenu = visible;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/vcard/CancelActivity.java b/src/com/android/contacts/vcard/CancelActivity.java
index c890607..5dafa53 100644
--- a/src/com/android/contacts/vcard/CancelActivity.java
+++ b/src/com/android/contacts/vcard/CancelActivity.java
@@ -87,17 +87,13 @@
     protected Dialog onCreateDialog(int id, Bundle bundle) {
         switch (id) {
         case R.id.dialog_cancel_confirmation: {
-            final String title;
             final String message;
             if (mType == VCardService.TYPE_IMPORT) {
-                title = getString(R.string.cancel_import_confirmation_title);
                 message = getString(R.string.cancel_import_confirmation_message, mDisplayName);
             } else {
-                title = getString(R.string.cancel_export_confirmation_title);
                 message = getString(R.string.cancel_export_confirmation_message, mDisplayName);
             }
             final AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(title)
                     .setMessage(message)
                     .setPositiveButton(android.R.string.ok, new RequestCancelListener())
                     .setOnCancelListener(mCancelListener)
diff --git a/src/com/android/contacts/vcard/ExportVCardActivity.java b/src/com/android/contacts/vcard/ExportVCardActivity.java
index c36cc38..f38c9df 100644
--- a/src/com/android/contacts/vcard/ExportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ExportVCardActivity.java
@@ -235,7 +235,6 @@
             case R.id.dialog_sdcard_not_found: {
                 mProcessOngoing = false;
                 return new AlertDialog.Builder(this)
-                        .setTitle(R.string.no_sdcard_title)
                         .setIconAttribute(android.R.attr.alertDialogIcon)
                         .setMessage(R.string.no_sdcard_message)
                         .setPositiveButton(android.R.string.ok, this).create();
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index 18b9cc1..2dc92af 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -901,10 +901,9 @@
             }
             case R.id.dialog_searching_vcard: {
                 if (mProgressDialogForScanVCard == null) {
-                    String title = getString(R.string.searching_vcard_title);
                     String message = getString(R.string.searching_vcard_message);
                     mProgressDialogForScanVCard =
-                        ProgressDialog.show(this, title, message, true, false);
+                        ProgressDialog.show(this, "", message, true, false);
                     mProgressDialogForScanVCard.setOnCancelListener(mVCardScanThread);
                     mVCardScanThread.start();
                 }
@@ -912,7 +911,6 @@
             }
             case R.id.dialog_sdcard_not_found: {
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(R.string.no_sdcard_title)
                     .setIconAttribute(android.R.attr.alertDialogIcon)
                     .setMessage(R.string.no_sdcard_message)
                     .setOnCancelListener(mCancelListener)
@@ -922,7 +920,6 @@
             case R.id.dialog_vcard_not_found: {
                 final String message = getString(R.string.import_failure_no_vcard_file);
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                        .setTitle(R.string.scanning_sdcard_failed_title)
                         .setMessage(message)
                         .setOnCancelListener(mCancelListener)
                         .setPositiveButton(android.R.string.ok, mCancelListener);
@@ -954,7 +951,6 @@
                 String message = (getString(R.string.scanning_sdcard_failed_message,
                         getString(R.string.fail_reason_io_error)));
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                    .setTitle(R.string.scanning_sdcard_failed_title)
                     .setIconAttribute(android.R.attr.alertDialogIcon)
                     .setMessage(message)
                     .setOnCancelListener(mCancelListener)
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index 66c2c5a..ea7c3dc 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -48,7 +48,7 @@
 import android.provider.ContactsContract.ProviderStatus;
 import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.TextView;
 
 /**
@@ -64,7 +64,7 @@
  *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
  *
  */
-@Smoke
+@SmallTest
 public class PeopleActivityTest
         extends ActivityInstrumentationTestCase2<PeopleActivity>
 {
diff --git a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java b/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
index 600a589..8a98018 100644
--- a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
@@ -117,7 +117,7 @@
 
     public void testBindView_NoCallLogButMemoryCache_EnqueueRequest() {
         mCursor.addRow(createCallLogEntry());
-        mAdapter.injectContactInfoForTest(TEST_NUMBER, createContactInfo());
+        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
 
         // Bind the views of a single row.
         mAdapter.bindStandAloneView(mView, getContext(), mCursor);
@@ -132,7 +132,7 @@
 
     public void testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest() {
         mCursor.addRow(createCallLogEntryWithCachedValues());
-        mAdapter.injectContactInfoForTest(TEST_NUMBER, createContactInfo());
+        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
 
         // Bind the views of a single row.
         mAdapter.bindStandAloneView(mView, getContext(), mCursor);
@@ -147,7 +147,7 @@
         // Contact info contains a different name.
         ContactInfo info = createContactInfo();
         info.name = "new name";
-        mAdapter.injectContactInfoForTest(TEST_NUMBER, info);
+        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, info);
 
         // Bind the views of a single row.
         mAdapter.bindStandAloneView(mView, getContext(), mCursor);
diff --git a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
index 09fe463..9cac8fe 100644
--- a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
@@ -482,7 +482,7 @@
         contactInfo.formattedNumber = formattedNumber;
         contactInfo.normalizedNumber = number;
         contactInfo.photoId = 0;
-        mAdapter.injectContactInfoForTest(number, contactInfo);
+        mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo);
     }
 
     /**
diff --git a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
index 19b14d9..131af96 100644
--- a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
+++ b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
@@ -21,6 +21,7 @@
 import com.google.common.collect.Lists;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 
 import java.util.ArrayList;
@@ -33,6 +34,7 @@
 /**
  * Unit tests for {@link StreamItemAdapter}.
  */
+@SmallTest
 public class StreamItemAdapterTest extends AndroidTestCase {
     private StreamItemAdapter mAdapter;
     private FakeOnClickListener mListener;
diff --git a/tests/src/com/android/contacts/format/PrefixHighligherTest.java b/tests/src/com/android/contacts/format/PrefixHighligherTest.java
index a0c0ff3..668330b 100644
--- a/tests/src/com/android/contacts/format/PrefixHighligherTest.java
+++ b/tests/src/com/android/contacts/format/PrefixHighligherTest.java
@@ -17,11 +17,13 @@
 package com.android.contacts.format;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.TextView;
 
 /**
  * Unit tests for {@link PrefixHighlighter}.
  */
+@SmallTest
 public class PrefixHighligherTest extends AndroidTestCase {
     private static final int TEST_PREFIX_HIGHLIGHT_COLOR = 0xFF0000;
     /** The HTML code used to mark the start of the highlighted part. */
diff --git a/tests/src/com/android/contacts/format/SpannedTestUtils.java b/tests/src/com/android/contacts/format/SpannedTestUtils.java
index 625c6aa..646a7ec 100644
--- a/tests/src/com/android/contacts/format/SpannedTestUtils.java
+++ b/tests/src/com/android/contacts/format/SpannedTestUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.format;
 
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Html;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -26,6 +27,7 @@
 /**
  * Utility class to check the value of spanned text in text views.
  */
+@SmallTest
 public class SpannedTestUtils {
     /**
      * Checks that the text contained in the text view matches the given HTML text.
diff --git a/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java b/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
index f2848d0..2deaef3 100644
--- a/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
+++ b/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
@@ -21,10 +21,12 @@
 
 import android.database.CharArrayBuffer;
 import android.graphics.Typeface;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableStringBuilder;
 import android.text.style.StyleSpan;
 
 /** A factory for {@link TextWithHighlighting} that wraps its parts in italics. */
+@SmallTest
 public final class TestTextWithHighlightingFactory implements TextWithHighlightingFactory {
     /** A {@link TextWithHighlighting} implementation that wraps its parts in italics. */
     private final static class TestTextWithHighlighting extends SpannableStringBuilder
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index 2c4b74c..b37d24f 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -35,7 +35,7 @@
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Contacts.Entity;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Tests for {@link ContactDeletionInteraction}.
@@ -47,7 +47,7 @@
  *   adb shell am instrument \
  *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
  */
-@Smoke
+@SmallTest
 public class ContactDeletionInteractionTest
         extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
 
diff --git a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
index e0b443a..9490b1b 100644
--- a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
@@ -29,11 +29,12 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -48,7 +49,7 @@
  *   adb shell am instrument \
  *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
  */
-@Smoke
+@SmallTest
 public class PhoneNumberInteractionTest extends InstrumentationTestCase {
 
     static {
@@ -89,7 +90,8 @@
     public void testSendSmsWhenOnlyOneNumberAvailable() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null);
+                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.SMS, null);
@@ -107,7 +109,8 @@
     public void testSendSmsWhenDataIdIsProvided() {
         Uri dataUri = ContentUris.withAppendedId(Data.CONTENT_URI, 1);
         expectQuery(dataUri, true /* isDataUri */ )
-                .returnRow(1, "987", 0, null, null, Phone.TYPE_HOME, null);
+                .returnRow(1, "987", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.SMS, null);
@@ -125,8 +128,10 @@
     public void testSendSmsWhenThereIsPrimaryNumber() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null)
-                .returnRow(2, "456", 1, null, null, Phone.TYPE_HOME, null);
+                .returnRow(
+                        1, "123", 0, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE)
+                .returnRow(
+                        2, "456", 1, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.SMS, null);
@@ -164,8 +169,10 @@
     public void testCallNumberWhenThereAreDuplicates() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null)
-                .returnRow(2, "123", 0, null, null, Phone.TYPE_WORK, null);
+                .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null,
+                        Phone.CONTENT_ITEM_TYPE)
+                .returnRow(2, "123", 0, null, null, Phone.TYPE_WORK, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.PHONE_CALL, null);
@@ -180,11 +187,31 @@
         assertEquals("tel:123", intent.getDataString());
     }
 
+    public void testCallWithSip() {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
+        expectQuery(contactUri)
+                .returnRow(1, "example@example.com", 0, null, null, Phone.TYPE_HOME, null,
+                        SipAddress.CONTENT_ITEM_TYPE);
+        TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
+                mContext, InteractionType.PHONE_CALL, null);
+
+        interaction.startInteraction(contactUri);
+        interaction.getLoader().waitForLoader();
+
+        Intent intent = mContext.getIntentForStartActivity();
+        assertNotNull(intent);
+
+        assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
+        assertEquals("tel:example%40example.com", intent.getDataString());
+    }
+
     public void testShowDisambigDialogForCalling() {
         Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
         expectQuery(contactUri)
-                .returnRow(1, "123", 0, "account", null, Phone.TYPE_HOME, "label")
-                .returnRow(2, "456", 0, null, null, Phone.TYPE_WORK, null);
+                .returnRow(1, "123", 0, "account", null, Phone.TYPE_HOME, "label",
+                        Phone.CONTENT_ITEM_TYPE)
+                .returnRow(2, "456", 0, null, null, Phone.TYPE_WORK, null,
+                        Phone.CONTENT_ITEM_TYPE);
 
         TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
                 mContext, InteractionType.PHONE_CALL, null);
@@ -224,7 +251,9 @@
                         RawContacts.ACCOUNT_TYPE,
                         RawContacts.DATA_SET,
                         Phone.TYPE,
-                        Phone.LABEL)
-                .withSelection("mimetype='vnd.android.cursor.item/phone_v2' AND data1 NOT NULL");
+                        Phone.LABEL,
+                        Phone.MIMETYPE)
+                .withSelection("mimetype IN ('vnd.android.cursor.item/phone_v2',"
+                        + " 'vnd.android.cursor.item/sip_address') AND data1 NOT NULL");
     }
 }