Merge 'goog/jb-ub-mail-ur8' into master

Change-Id: I7d1e9583bca936a770334252dc0046417b642298
diff --git a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
index 00f1ff4..49e2d5c 100644
--- a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
+++ b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
@@ -41,6 +41,8 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * RecipientAlternatesAdapter backs the RecipientEditTextView for managing contacts
@@ -63,7 +65,11 @@
     private Query mQuery;
 
     public interface RecipientMatchCallback {
-        public void matchesFound(HashMap<String, RecipientEntry> results);
+        public void matchesFound(Map<String, RecipientEntry> results);
+        /**
+         * Called with all addresses that could not be resolved to valid recipients.
+         */
+        public void matchesNotFound(Set<String> addresses);
     }
 
     public static void getMatchingRecipients(Context context, ArrayList<String> inAddresses,
@@ -126,6 +132,7 @@
         }
         // See if any entries did not resolve; if so, we need to check other
         // directories
+        final Set<String> matchesNotFound = new HashSet<String>();
         if (recipientEntries.size() < addresses.size()) {
             final List<DirectorySearchParams> paramsList;
             Cursor directoryCursor = context.getContentResolver().query(DirectoryListQuery.URI,
@@ -139,6 +146,9 @@
                     unresolvedAddresses.add(address);
                 }
             }
+
+            matchesNotFound.addAll(unresolvedAddresses);
+
             Cursor directoryContactsCursor = null;
             for (String unresolvedAddress : unresolvedAddresses) {
                 for (int i = 0; i < paramsList.size(); i++) {
@@ -158,13 +168,22 @@
                 }
                 if (directoryContactsCursor != null) {
                     try {
-                        callback.matchesFound(processContactEntries(directoryContactsCursor));
+                        final Map<String, RecipientEntry> entries =
+                                processContactEntries(directoryContactsCursor);
+
+                        for (final String address : entries.keySet()) {
+                            matchesNotFound.remove(address);
+                        }
+
+                        callback.matchesFound(entries);
                     } finally {
                         directoryContactsCursor.close();
                     }
                 }
             }
         }
+
+        callback.matchesNotFound(matchesNotFound);
     }
 
     private static HashMap<String, RecipientEntry> processContactEntries(Cursor c) {
diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java
index c786126..5400833 100644
--- a/chips/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java
@@ -86,9 +86,9 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -2454,7 +2454,7 @@
                     new RecipientMatchCallback() {
 
                         @Override
-                        public void matchesFound(HashMap<String, RecipientEntry> entries) {
+                        public void matchesFound(Map<String, RecipientEntry> entries) {
                             final ArrayList<RecipientChip> replacements =
                                     new ArrayList<RecipientChip>();
                             for (final RecipientChip temp : originalRecipients) {
@@ -2473,6 +2473,10 @@
                                     replacements.add(null);
                                 }
                             }
+                            processReplacements(replacements);
+                        }
+
+                        private void processReplacements(final List<RecipientChip> replacements) {
                             if (replacements != null && replacements.size() > 0) {
                                 mHandler.post(new Runnable() {
                                     @Override
@@ -2522,6 +2526,28 @@
                                 });
                             }
                         }
+
+                        @Override
+                        public void matchesNotFound(final Set<String> addresses) {
+                            final List<RecipientChip> replacements =
+                                    new ArrayList<RecipientChip>(addresses.size());
+
+                            for (final RecipientChip temp : originalRecipients) {
+                                if (RecipientEntry.isCreatedRecipient(temp.getEntry()
+                                        .getContactId())
+                                        && getSpannable().getSpanStart(temp) != -1) {
+                                    if (addresses.contains(temp.getEntry().getDestination())) {
+                                        replacements.add(createFreeChip(temp.getEntry()));
+                                    } else {
+                                        replacements.add(null);
+                                    }
+                                } else {
+                                    replacements.add(null);
+                                }
+                            }
+
+                            processReplacements(replacements);
+                        }
                     });
             return null;
         }
@@ -2549,7 +2575,7 @@
                     new RecipientMatchCallback() {
 
                         @Override
-                        public void matchesFound(HashMap<String, RecipientEntry> entries) {
+                        public void matchesFound(Map<String, RecipientEntry> entries) {
                             for (final RecipientChip temp : originalRecipients) {
                                 if (RecipientEntry.isCreatedRecipient(temp.getEntry()
                                         .getContactId())
@@ -2577,6 +2603,10 @@
                             }
                         }
 
+                        @Override
+                        public void matchesNotFound(final Set<String> addresses) {
+                            // No action required
+                        }
                     });
             return null;
         }
diff --git a/chips/src/com/android/ex/chips/RecipientEntry.java b/chips/src/com/android/ex/chips/RecipientEntry.java
index 98a35e6..1a79f32 100644
--- a/chips/src/com/android/ex/chips/RecipientEntry.java
+++ b/chips/src/com/android/ex/chips/RecipientEntry.java
@@ -214,4 +214,9 @@
     public boolean isSelectable() {
         return mEntryType == ENTRY_TYPE_PERSON;
     }
+
+    @Override
+    public String toString() {
+        return mDisplayName + " <" + mDestination + ">, isValid=" + mIsValid;
+    }
 }
\ No newline at end of file