Merge "Dedup NANPA numbers"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 18bc0d4..d407da3 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -75,4 +75,10 @@
     <!-- contact browser list margins -->
     <dimen name="contact_browser_list_item_photo_size">64dip</dimen>
     <dimen name="contact_browser_list_top_margin">8dip</dimen>
+
+    <!-- Dimensions for "No contacts" string in PhoneFavoriteFragment for the All contacts
+         with phone numbers section
+    -->
+    <dimen name="contact_phone_list_empty_description_size">20sp</dimen>
+    <dimen name="contact_phone_list_empty_description_padding">10dip</dimen>
 </resources>
diff --git a/src/com/android/contacts/common/util/SearchUtil.java b/src/com/android/contacts/common/util/SearchUtil.java
index b3428ff..ed41d6c 100644
--- a/src/com/android/contacts/common/util/SearchUtil.java
+++ b/src/com/android/contacts/common/util/SearchUtil.java
@@ -106,28 +106,19 @@
             i += Character.charCount(codePoint);
         }
 
-        int valueCodePoint = 0;
         for (int i = 0; i < value.length(); i = findNextTokenStart(value, i)) {
-            valueCodePoint = value.codePointAt(i);
-
             int numMatch = 0;
-
-            // As an optimization, we lower here instead of making the parent do it.
-            //int substringCodePoint = substring.codePointAt(numMatch);
-            int valueCpIndex = 0;
-            int cp = Character.toLowerCase(valueCodePoint);
-            while (numMatch < substringLength && cp == substringCodePoints[numMatch]) {
-                numMatch++;
-                if (numMatch == substringLength) {
-                    // Must exit loop here otherwise code below may cause IndexOutOfBoundsException.
-                    // When query string matches content exactly.
-                    return i;
+            for (int j = i; j < value.length() && numMatch < substringLength; ++numMatch) {
+                int valueCp = Character.toLowerCase(value.codePointAt(j));
+                int substringCp = substringCodePoints[numMatch];
+                if (valueCp != substringCp) {
+                    break;
                 }
-                valueCpIndex += Character.charCount(cp);
-                cp = Character.toLowerCase(value.codePointAt(i + valueCpIndex));
-
+                j += Character.charCount(valueCp);
             }
-
+            if (numMatch == substringLength) {
+                return i;
+            }
         }
         return -1;
     }
diff --git a/src/com/android/contacts/common/vcard/VCardService.java b/src/com/android/contacts/common/vcard/VCardService.java
index 07c2a3c..e2adbbd 100644
--- a/src/com/android/contacts/common/vcard/VCardService.java
+++ b/src/com/android/contacts/common/vcard/VCardService.java
@@ -175,8 +175,12 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int id) {
-        mCallingActivity = intent.getExtras().getString(
-                VCardCommonArguments.ARG_CALLING_ACTIVITY);
+        if (intent != null && intent.getExtras() != null) {
+            mCallingActivity = intent.getExtras().getString(
+                    VCardCommonArguments.ARG_CALLING_ACTIVITY);
+        } else {
+            mCallingActivity = null;
+        }
         return START_STICKY;
     }
 
diff --git a/tests/src/com/android/contacts/common/util/SearchUtilTest.java b/tests/src/com/android/contacts/common/util/SearchUtilTest.java
index e03e871..3176a3c 100644
--- a/tests/src/com/android/contacts/common/util/SearchUtilTest.java
+++ b/tests/src/com/android/contacts/common/util/SearchUtilTest.java
@@ -73,6 +73,9 @@
         assertEquals(-1, SearchUtil.contains(actual, "thisx"));
         assertEquals(-1, SearchUtil.contains(actual, "manyx"));
         assertEquals(-1, SearchUtil.contains(actual, "hellox"));
+
+        // Test for partial match of start of query to end of line
+        assertEquals(-1, SearchUtil.contains(actual, "punctual"));
     }
 
     public void testFindNextTokenStart() {