Change aggregation suggestions to be raw contacts

Each suggestion is a raw contact that belongs to the same account
of the currently edited raw contact.
Surfaced data is the raw contact's data.
Pass the current changes to the newly selected raw contact.
Remove a few unneeded methods.
Removed the join option for tapping on a suggestion since all raw
contacts selected from here will be editable.

Since QuickContact depends on the aggregation suggestion engine to
return contact level suggestions also removed everything related to
it there since it's currently disabled.
b/29216287 tracks plans bring it back but it probably won't be in the
form of using the suggestion engine to populate the card, so it felt
okay to remove the code. Layouts were left in case they can be reused
 later.

Test:
Opened QuickContact
Tested the suggestions for a contact with multiple raw contacts both
in and out of the current account and made sure only ones in the
current accountwere shown.
Checked contact with raw contacts which have different names, made
sure those displayed correctly. CP2 doesn't store the alternative
versions of raw contact names so the primary one is always shown
which is a non-regression.

Bug: 32277025
Bug: 32278866
Bug: 31088704
Bug: 31704115
Change-Id: Ibd4bdaaf100ffd5524eebac300d23763bbe6a22d
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index 3052a24..7cbae7a 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -304,10 +304,10 @@
                 }
 
                 @Override
-                public void onEditOtherContactRequested(
-                        Uri contactLookupUri, ArrayList<ContentValues> values) {
-                    final Intent intent = EditorIntents.createEditOtherContactIntent(
-                            ContactEditorActivity.this, contactLookupUri, values);
+                public void onEditOtherRawContactRequested(
+                        Uri contactLookupUri, long rawContactId, ArrayList<ContentValues> values) {
+                    final Intent intent = EditorIntents.createEditOtherRawContactIntent(
+                            ContactEditorActivity.this, contactLookupUri, rawContactId, values);
                     ImplicitIntentsUtil.startActivityInApp(
                             ContactEditorActivity.this, intent);
                     finish();
diff --git a/src/com/android/contacts/editor/AggregationSuggestionEngine.java b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
index 8ababa8..62e55e5 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionEngine.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
@@ -29,7 +29,6 @@
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Nickname;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Contacts.AggregationSuggestions;
@@ -41,6 +40,8 @@
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.compat.AggregationSuggestionsCompat;
+
+import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
@@ -57,36 +58,26 @@
         void onAggregationSuggestionChange();
     }
 
-    public static final class RawContact {
-        public long rawContactId;
-        public String accountType;
-        public String accountName;
-        public String dataSet;
-
-        @Override
-        public String toString() {
-            return "ID: " + rawContactId + " account: " + accountType + "/" + accountName
-                    + " dataSet: " + dataSet;
-        }
-    }
-
     public static final class Suggestion {
-
         public long contactId;
-        public long photoId;
-        public String lookupKey;
+        public String contactLookupKey;
+        public long rawContactId;
         public String name;
         public String phoneNumber;
         public String emailAddress;
         public String nickname;
-        public byte[] photo;
-        public List<RawContact> rawContacts;
 
         @Override
         public String toString() {
-            return "ID: " + contactId + " rawContacts: " + rawContacts + " name: " + name
-            + " phone: " + phoneNumber + " email: " + emailAddress + " nickname: "
-            + nickname + (photo != null ? " [has photo]" : "");
+            return Objects.toStringHelper(Suggestion.class)
+                    .add("contactId", contactId)
+                    .add("contactLookupKey", contactLookupKey)
+                    .add("rawContactId", rawContactId)
+                    .add("name", name)
+                    .add("phoneNumber", phoneNumber)
+                    .add("emailAddress", emailAddress)
+                    .add("nickname", nickname)
+                    .toString();
         }
     }
 
@@ -107,10 +98,11 @@
 
     private static final long SUGGESTION_LOOKUP_DELAY_MILLIS = 300;
 
+    private static final int SUGGESTIONS_LIMIT = 3;
+
     private final Context mContext;
 
     private long[] mSuggestedContactIds = new long[0];
-
     private Handler mMainHandler;
     private Handler mHandler;
     private long mContactId;
@@ -119,8 +111,6 @@
     private Cursor mDataCursor;
     private ContentObserver mContentObserver;
     private Uri mSuggestionsUri;
-    private int mSuggestionsLimit = 3;
-    private boolean mPruneInvisibleContacts = false;
 
     public AggregationSuggestionEngine(Context context) {
         super("AggregationSuggestions", Process.THREAD_PRIORITY_BACKGROUND);
@@ -156,14 +146,6 @@
         mAccountFilter = account;
     }
 
-    public void setSuggestionsLimit(int suggestionsLimit) {
-        mSuggestionsLimit = suggestionsLimit;
-    }
-
-    public void setPruneInvisibleContacts (boolean pruneInvisibleContacts) {
-        mPruneInvisibleContacts = pruneInvisibleContacts;
-    }
-
     public void setListener(Listener listener) {
         mListener = listener;
     }
@@ -238,7 +220,7 @@
         // AggregationSuggestions.Builder() became visible in API level 23, so use it if applicable.
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             final Builder uriBuilder = new AggregationSuggestions.Builder()
-                    .setLimit(mSuggestionsLimit)
+                    .setLimit(SUGGESTIONS_LIMIT)
                     .setContactId(mContactId);
             if (nameSb.length() != 0) {
                 uriBuilder.addNameParameter(nameSb.toString());
@@ -252,7 +234,7 @@
         // For previous SDKs, use the backup plan.
         final AggregationSuggestionsCompat.Builder uriBuilder =
                 new AggregationSuggestionsCompat.Builder()
-                .setLimit(mSuggestionsLimit)
+                .setLimit(SUGGESTIONS_LIMIT)
                 .setContactId(mContactId);
         if (nameSb.length() != 0) {
             uriBuilder.addNameParameter(nameSb.toString());
@@ -288,42 +270,33 @@
 
         public static final String SELECTION_PREFIX =
                 Data.MIMETYPE + " IN ('"
-                    + Phone.CONTENT_ITEM_TYPE + "','"
-                    + Email.CONTENT_ITEM_TYPE + "','"
-                    + StructuredName.CONTENT_ITEM_TYPE + "','"
-                    + Nickname.CONTENT_ITEM_TYPE + "','"
-                    + Photo.CONTENT_ITEM_TYPE + "')"
-                + " AND " + Data.CONTACT_ID + " IN (";
+                        + Phone.CONTENT_ITEM_TYPE + "','"
+                        + Email.CONTENT_ITEM_TYPE + "','"
+                        + StructuredName.CONTENT_ITEM_TYPE + "','"
+                        + Nickname.CONTENT_ITEM_TYPE + "')"
+                        + " AND " + Data.CONTACT_ID + " IN (";
 
         public static final String[] COLUMNS = {
-            Data._ID,
-            Data.CONTACT_ID,
-            Data.LOOKUP_KEY,
-            Data.PHOTO_ID,
-            Data.DISPLAY_NAME,
-            Data.RAW_CONTACT_ID,
-            Data.MIMETYPE,
-            Data.DATA1,
-            Data.IS_SUPER_PRIMARY,
-            Photo.PHOTO,
-            RawContacts.ACCOUNT_TYPE,
-            RawContacts.ACCOUNT_NAME,
-            RawContacts.DATA_SET
+                Data.CONTACT_ID,
+                Data.LOOKUP_KEY,
+                Data.RAW_CONTACT_ID,
+                Data.MIMETYPE,
+                Data.DATA1,
+                Data.IS_SUPER_PRIMARY,
+                RawContacts.ACCOUNT_TYPE,
+                RawContacts.ACCOUNT_NAME,
+                RawContacts.DATA_SET
         };
 
-        public static final int ID = 0;
-        public static final int CONTACT_ID = 1;
-        public static final int LOOKUP_KEY = 2;
-        public static final int PHOTO_ID = 3;
-        public static final int DISPLAY_NAME = 4;
-        public static final int RAW_CONTACT_ID = 5;
-        public static final int MIMETYPE = 6;
-        public static final int DATA1 = 7;
-        public static final int IS_SUPERPRIMARY = 8;
-        public static final int PHOTO = 9;
-        public static final int ACCOUNT_TYPE = 10;
-        public static final int ACCOUNT_NAME = 11;
-        public static final int DATA_SET = 12;
+        public static final int CONTACT_ID = 0;
+        public static final int LOOKUP_KEY = 1;
+        public static final int RAW_CONTACT_ID = 2;
+        public static final int MIMETYPE = 3;
+        public static final int DATA1 = 4;
+        public static final int IS_SUPERPRIMARY = 5;
+        public static final int ACCOUNT_TYPE = 6;
+        public static final int ACCOUNT_NAME = 7;
+        public static final int DATA_SET = 8;
     }
 
     private void loadAggregationSuggestions(Uri uri) {
@@ -352,12 +325,12 @@
                 sb.append(mSuggestedContactIds[i]);
             }
             sb.append(')');
-            sb.toString();
 
             Cursor dataCursor = contentResolver.query(Data.CONTENT_URI,
                     DataQuery.COLUMNS, sb.toString(), null, Data.CONTACT_ID);
             if (dataCursor != null) {
-                mMainHandler.sendMessage(mMainHandler.obtainMessage(MESSAGE_DATA_CURSOR, dataCursor));
+                mMainHandler.sendMessage(
+                        mMainHandler.obtainMessage(MESSAGE_DATA_CURSOR, dataCursor));
             }
         } finally {
             cursor.close();
@@ -370,8 +343,7 @@
         final ArrayList<Long> newIds = new ArrayList<Long>(count);
         while (cursor.moveToNext()) {
             final long contactId = cursor.getLong(0);
-            if (!changed &&
-                    Arrays.binarySearch(mSuggestedContactIds, contactId) < 0) {
+            if (!changed && Arrays.binarySearch(mSuggestedContactIds, contactId) < 0) {
                 changed = true;
             }
             newIds.add(contactId);
@@ -404,110 +376,59 @@
     }
 
     public List<Suggestion> getSuggestions() {
-        final ArrayList<Long> visibleContacts = new ArrayList<>();
-        if (mPruneInvisibleContacts) {
-            final Uri contactFilterUri = Data.CONTENT_URI.buildUpon()
-                    .appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true")
-                    .build();
-            final ContentResolver contentResolver = mContext.getContentResolver();
-            final Cursor contactCursor = contentResolver.query(contactFilterUri,
-                    new String[]{Data.CONTACT_ID}, null, null, null);
-            try {
-                if (contactCursor != null) {
-                    while (contactCursor.moveToNext()) {
-                        final long contactId = contactCursor.getLong(0);
-                        visibleContacts.add(contactId);
-                    }
-                }
-            } finally {
-                contactCursor.close();
-            }
+        final ArrayList<Suggestion> list = Lists.newArrayList();
 
-        }
-
-        ArrayList<Suggestion> list = Lists.newArrayList();
-        if (mDataCursor != null) {
+        if (mDataCursor != null && mAccountFilter != null) {
             Suggestion suggestion = null;
-            long currentContactId = -1;
+            long currentRawContactId = -1;
             mDataCursor.moveToPosition(-1);
             while (mDataCursor.moveToNext()) {
-                long contactId = mDataCursor.getLong(DataQuery.CONTACT_ID);
-                if (mPruneInvisibleContacts && !visibleContacts.contains(contactId)) {
-                    continue;
-                }
-                if (contactId != currentContactId) {
+                final long rawContactId = mDataCursor.getLong(DataQuery.RAW_CONTACT_ID);
+                if (rawContactId != currentRawContactId) {
                     suggestion = new Suggestion();
-                    suggestion.contactId = contactId;
-                    suggestion.name = mDataCursor.getString(DataQuery.DISPLAY_NAME);
-                    suggestion.lookupKey = mDataCursor.getString(DataQuery.LOOKUP_KEY);
-                    suggestion.rawContacts = Lists.newArrayList();
-                    // No restriction, add all suggestions.
-                    if (mAccountFilter == null) {
-                        list.add(suggestion);
-                    }
-                    currentContactId = contactId;
-                }
-
-                long rawContactId = mDataCursor.getLong(DataQuery.RAW_CONTACT_ID);
-                if (!containsRawContact(suggestion, rawContactId)) {
-                    RawContact rawContact = new RawContact();
-                    rawContact.rawContactId = rawContactId;
-                    rawContact.accountName = mDataCursor.getString(DataQuery.ACCOUNT_NAME);
-                    rawContact.accountType = mDataCursor.getString(DataQuery.ACCOUNT_TYPE);
-                    rawContact.dataSet = mDataCursor.getString(DataQuery.DATA_SET);
+                    suggestion.rawContactId = rawContactId;
+                    suggestion.contactId = mDataCursor.getLong(DataQuery.CONTACT_ID);
+                    suggestion.contactLookupKey = mDataCursor.getString(DataQuery.LOOKUP_KEY);
+                    final String accountName = mDataCursor.getString(DataQuery.ACCOUNT_NAME);
+                    final String accountType = mDataCursor.getString(DataQuery.ACCOUNT_TYPE);
+                    final String dataSet = mDataCursor.getString(DataQuery.DATA_SET);
                     final AccountWithDataSet account = new AccountWithDataSet(
-                            rawContact.accountName, rawContact.accountType, rawContact.dataSet);
-                    // If we're restricting to a certain account, only add the suggestion if
-                    // it has a raw contact from that account.
-                    if (mAccountFilter != null && mAccountFilter.equals(account)
-                            && !list.contains(suggestion)) {
+                            accountName, accountType, dataSet);
+                    if (mAccountFilter.equals(account)) {
                         list.add(suggestion);
                     }
-                    suggestion.rawContacts.add(rawContact);
+                    currentRawContactId = rawContactId;
                 }
 
-                String mimetype = mDataCursor.getString(DataQuery.MIMETYPE);
+                final String mimetype = mDataCursor.getString(DataQuery.MIMETYPE);
                 if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                    String data = mDataCursor.getString(DataQuery.DATA1);
+                    final String data = mDataCursor.getString(DataQuery.DATA1);
                     int superprimary = mDataCursor.getInt(DataQuery.IS_SUPERPRIMARY);
                     if (!TextUtils.isEmpty(data)
                             && (superprimary != 0 || suggestion.phoneNumber == null)) {
                         suggestion.phoneNumber = data;
                     }
                 } else if (Email.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                    String data = mDataCursor.getString(DataQuery.DATA1);
+                    final String data = mDataCursor.getString(DataQuery.DATA1);
                     int superprimary = mDataCursor.getInt(DataQuery.IS_SUPERPRIMARY);
                     if (!TextUtils.isEmpty(data)
                             && (superprimary != 0 || suggestion.emailAddress == null)) {
                         suggestion.emailAddress = data;
                     }
                 } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                    String data = mDataCursor.getString(DataQuery.DATA1);
+                    final String data = mDataCursor.getString(DataQuery.DATA1);
                     if (!TextUtils.isEmpty(data)) {
                         suggestion.nickname = data;
                     }
-                } else if (Photo.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                    long dataId = mDataCursor.getLong(DataQuery.ID);
-                    long photoId = mDataCursor.getLong(DataQuery.PHOTO_ID);
-                    if (dataId == photoId && !mDataCursor.isNull(DataQuery.PHOTO)) {
-                        suggestion.photo = mDataCursor.getBlob(DataQuery.PHOTO);
-                        suggestion.photoId = photoId;
+                } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
+                    // DATA1 stores the display name for the raw contact.
+                    final String data = mDataCursor.getString(DataQuery.DATA1);
+                    if (!TextUtils.isEmpty(data) && suggestion.name == null) {
+                        suggestion.name = data;
                     }
                 }
             }
         }
         return list;
     }
-
-    public boolean containsRawContact(Suggestion suggestion, long rawContactId) {
-        if (suggestion.rawContacts != null) {
-            int count = suggestion.rawContacts.size();
-            for (int i = 0; i < count; i++) {
-                if (suggestion.rawContacts.get(i).rawContactId == rawContactId) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
 }
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index 5a3da00..b89f06a 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -16,9 +16,10 @@
 
 package com.android.contacts.editor;
 
+import android.content.ContentUris;
 import android.content.Context;
-import android.graphics.BitmapFactory;
 import android.net.Uri;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -28,16 +29,8 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
-import com.android.contacts.editor.AggregationSuggestionEngine.RawContact;
-import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
 import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
 
 /**
  * A view that contains a name, picture and other data for a contact aggregation suggestion.
@@ -45,25 +38,15 @@
 public class AggregationSuggestionView extends LinearLayout {
 
     public interface Listener {
-
         /**
-         * Callback that passes the contact ID to join with and, for convenience,
-         * also the list of constituent raw contact IDs to avoid a separate query
-         * for those.
+         * Callback that passes the contact URI and raw contact ID to edit instead of the
+         * current contact.
          */
-        public void onJoinAction(long contactId, List<Long> rawContacIds);
-
-        /**
-         * Callback that passes the contact ID to edit instead of the current contact.
-         */
-        public void onEditAction(Uri contactLookupUri);
+        void onEditAction(Uri contactLookupUri, long rawContactId);
     }
 
     private Listener mListener;
-    private long mContactId;
-    private String mLookupKey;
-    private List<RawContact> mRawContacts = Lists.newArrayList();
-    private boolean mNewContact;
+    private Suggestion mSuggestion;
 
     public AggregationSuggestionView(Context context) {
         super(context);
@@ -77,22 +60,21 @@
         super(context, attrs, defStyle);
     }
 
-    public void setNewContact(boolean flag) {
-        mNewContact = flag;
-    }
-
     public void bindSuggestion(Suggestion suggestion) {
-        mContactId = suggestion.contactId;
-        mLookupKey = suggestion.lookupKey;
-        mRawContacts = suggestion.rawContacts;
-        ImageView photo = (ImageView) findViewById(R.id.aggregation_suggestion_photo);
-        if (suggestion.photo != null) {
-            photo.setImageBitmap(BitmapFactory.decodeByteArray(
-                    suggestion.photo, 0, suggestion.photo.length));
-        } else {
-            photo.setImageDrawable(ContactPhotoManager.getDefaultAvatarDrawableForContact(
-                    getResources(), false, null));
-        }
+        mSuggestion = suggestion;
+        final ContactPhotoManager.DefaultImageRequest
+                request = new ContactPhotoManager.DefaultImageRequest(
+                suggestion.name, String.valueOf(suggestion.rawContactId), /* isCircular = */ false);
+        final Uri photoUri = Uri.withAppendedPath(ContentUris.withAppendedId(
+                ContactsContract.RawContacts.CONTENT_URI, suggestion.rawContactId),
+                ContactsContract.RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
+        final ImageView photoView = (ImageView) findViewById(
+                R.id.aggregation_suggestion_photo);
+        ContactPhotoManager.getInstance(getContext()).loadDirectoryPhoto(photoView,
+                photoUri,
+                /* darkTheme = */ false,
+                /* isCircular = */ false,
+                request);
 
         TextView name = (TextView) findViewById(R.id.aggregation_suggestion_name);
         name.setText(suggestion.name);
@@ -111,48 +93,18 @@
         data.setText(dataText);
     }
 
-    /**
-     * Returns true if the suggested contact can be edited.
-     */
-    private boolean canEditSuggestedContact() {
-        if (!mNewContact) {
-            return false;
-        }
-
-        AccountTypeManager accountTypes = AccountTypeManager.getInstance(getContext());
-        for (RawContact rawContact : mRawContacts) {
-            String accountType = rawContact.accountType;
-            String dataSet = rawContact.dataSet;
-            if (accountType == null) {
-                return true;
-            }
-            AccountType type = accountTypes.getAccountType(accountType, dataSet);
-            if (type.areContactsWritable()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
     public void setListener(Listener listener) {
         mListener = listener;
     }
 
     public boolean handleItemClickEvent() {
         if (mListener != null && isEnabled()) {
-            if (canEditSuggestedContact()) {
-                if (TextUtils.isEmpty(mLookupKey)) {
-                    return false;
-                }
-                mListener.onEditAction(Contacts.getLookupUri(mContactId, mLookupKey));
-            } else {
-                ArrayList<Long> rawContactIds = Lists.newArrayList();
-                for (RawContact rawContact : mRawContacts) {
-                    rawContactIds.add(rawContact.rawContactId);
-                }
-                mListener.onJoinAction(mContactId, rawContactIds);
+            if (TextUtils.isEmpty(mSuggestion.contactLookupKey)) {
+                return false;
             }
+            mListener.onEditAction(
+                    Contacts.getLookupUri(mSuggestion.contactId, mSuggestion.contactLookupKey),
+                    mSuggestion.rawContactId);
             return true;
         }
         return false;
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 0f1ff8e..65c30e8 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -241,10 +241,10 @@
         void onSaveFinished(Intent resultIntent);
 
         /**
-         * User switched to editing a different contact (a suggestion from the
+         * User switched to editing a different raw contact (a suggestion from the
          * aggregation engine).
          */
-        void onEditOtherContactRequested(Uri contactLookupUri,
+        void onEditOtherRawContactRequested(Uri contactLookupUri, long rawContactId,
                 ArrayList<ContentValues> contentValues);
 
         /**
@@ -259,14 +259,12 @@
      */
     private static final class AggregationSuggestionAdapter extends BaseAdapter {
         private final LayoutInflater mLayoutInflater;
-        private final boolean mSetNewContact;
         private final AggregationSuggestionView.Listener mListener;
         private final List<AggregationSuggestionEngine.Suggestion> mSuggestions;
 
-        public AggregationSuggestionAdapter(Activity activity, boolean setNewContact,
+        public AggregationSuggestionAdapter(Activity activity,
                 AggregationSuggestionView.Listener listener, List<Suggestion> suggestions) {
             mLayoutInflater = activity.getLayoutInflater();
-            mSetNewContact = setNewContact;
             mListener = listener;
             mSuggestions = suggestions;
         }
@@ -277,7 +275,6 @@
             final AggregationSuggestionView suggestionView =
                     (AggregationSuggestionView) mLayoutInflater.inflate(
                             R.layout.aggregation_suggestions_item, null);
-            suggestionView.setNewContact(mSetNewContact);
             suggestionView.setListener(mListener);
             suggestionView.bindSuggestion(suggestion);
             return suggestionView;
@@ -969,20 +966,6 @@
         return false;
     }
 
-    /**
-     * Whether editor inputs and the options menu should be enabled.
-     */
-    private boolean isEnabled() {
-        return mEnabled;
-    }
-
-    /**
-     * Returns the palette extra that was passed in.
-     */
-    private MaterialColorMapUtils.MaterialPalette getMaterialPalette() {
-        return mMaterialPalette;
-    }
-
     //
     // Account creation
     //
@@ -1251,7 +1234,7 @@
         if (mCopyReadOnlyName) {
             copyReadOnlyName();
         }
-        editorView.setState(mState, getMaterialPalette(), mViewIdGenerator,
+        editorView.setState(mState, mMaterialPalette, mViewIdGenerator,
                 mHasNewContact, mIsUserProfile, mAccountWithDataSet,
                 mRawContactIdToDisplayAlone);
 
@@ -1266,7 +1249,7 @@
         }
 
         // The editor is ready now so make it visible
-        editorView.setEnabled(isEnabled());
+        editorView.setEnabled(mEnabled);
         editorView.setVisibility(View.VISIBLE);
 
         // Refresh the ActionBar as the visibility of the join command
@@ -1567,7 +1550,6 @@
         mAggregationSuggestionPopup.setAdapter(
                 new AggregationSuggestionAdapter(
                         getActivity(),
-                        mState.size() == 1 && mState.get(0).isContactInsert(),
                         /* listener =*/ this,
                         mAggregationSuggestionEngine.getSuggestions()));
         mAggregationSuggestionPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -1589,19 +1571,6 @@
         return getContent().getAggregationAnchorView();
     }
 
-    @Override
-    public void onJoinAction(long contactId, List<Long> rawContactIdList) {
-        final long rawContactIds[] = new long[rawContactIdList.size()];
-        for (int i = 0; i < rawContactIds.length; i++) {
-            rawContactIds[i] = rawContactIdList.get(i);
-        }
-        try {
-            JoinSuggestedContactDialogFragment.show(this, rawContactIds);
-        } catch (Exception ignored) {
-            // No problem - the activity is no longer available to display the dialog
-        }
-    }
-
     /**
      * Joins the suggested contact (specified by the id's of constituent raw
      * contacts), save all changes, and stay in the editor.
@@ -1616,20 +1585,20 @@
     }
 
     @Override
-    public void onEditAction(Uri contactLookupUri) {
-        SuggestionEditConfirmationDialogFragment.show(this, contactLookupUri);
+    public void onEditAction(Uri contactLookupUri, long rawContactId) {
+        SuggestionEditConfirmationDialogFragment.show(this, contactLookupUri, rawContactId);
     }
 
     /**
-     * Abandons the currently edited contact and switches to editing the suggested
-     * one, transferring all the data there
+     * Abandons the currently edited contact and switches to editing the selected raw contact,
+     * transferring all the data there
      */
-    public void doEditSuggestedContact(Uri contactUri) {
+    public void doEditSuggestedContact(Uri contactUri, long rawContactId) {
         if (mListener != null) {
             // make sure we don't save this contact when closing down
             mStatus = Status.CLOSING;
-            mListener.onEditOtherContactRequested(
-                    contactUri, mState.get(0).getContentValues());
+            mListener.onEditOtherRawContactRequested(contactUri, rawContactId,
+                    getContent().getCurrentRawContactDelta().getContentValues());
         }
     }
 
diff --git a/src/com/android/contacts/editor/EditorIntents.java b/src/com/android/contacts/editor/EditorIntents.java
index 2d05eb2..015e75b 100644
--- a/src/com/android/contacts/editor/EditorIntents.java
+++ b/src/com/android/contacts/editor/EditorIntents.java
@@ -81,17 +81,18 @@
     }
 
     /**
-     * Returns an Intent to edit a different contact in the editor with whatever
+     * Returns an Intent to edit a different raw contact in the editor with whatever
      * values were already entered on the current editor.
      */
-    public static Intent createEditOtherContactIntent(Context context, Uri uri,
-            ArrayList<ContentValues> contentValues) {
+    public static Intent createEditOtherRawContactIntent(Context context, Uri uri,
+            long rawContactId, ArrayList<ContentValues> contentValues) {
         final Intent intent = new Intent(Intent.ACTION_EDIT, uri, context,
                 ContactEditorActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                 | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
         intent.putExtra(ContactEditorFragment.INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY, "");
-
+        intent.putExtra(ContactEditorFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE,
+                rawContactId);
         // Pass on all the data that has been entered so far
         if (contentValues != null && contentValues.size() != 0) {
             intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contentValues);
diff --git a/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java b/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java
index 9408c7e..f94d5dc 100644
--- a/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java
+++ b/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java
@@ -16,8 +16,6 @@
 
 package com.android.contacts.editor;
 
-import com.android.contacts.R;
-
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
@@ -25,13 +23,17 @@
 import android.net.Uri;
 import android.os.Bundle;
 
+import com.android.contacts.R;
+
 public class SuggestionEditConfirmationDialogFragment extends DialogFragment {
 
     private static final String ARG_CONTACT_URI = "contactUri";
+    private static final String ARG_RAW_CONTACT_ID = "rawContactId";
 
-    public static void show(ContactEditorFragment fragment, Uri contactUri) {
+    public static void show(ContactEditorFragment fragment, Uri contactUri, long rawContactId) {
         final Bundle args = new Bundle();
         args.putParcelable(ARG_CONTACT_URI, contactUri);
+        args.putLong(ARG_RAW_CONTACT_ID, rawContactId);
 
         final SuggestionEditConfirmationDialogFragment dialog = new
                 SuggestionEditConfirmationDialogFragment();
@@ -53,7 +55,9 @@
                                         (ContactEditorFragment) getTargetFragment();
                                 final Uri contactUri =
                                         getArguments().getParcelable(ARG_CONTACT_URI);
-                                targetFragment.doEditSuggestedContact(contactUri);
+                                final long rawContactId =
+                                        getArguments().getLong(ARG_RAW_CONTACT_ID);
+                                targetFragment.doEditSuggestedContact(contactUri, rawContactId);
                             }
                         }
                 )
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index f69f2ec..3597607 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -32,7 +32,6 @@
 import android.content.Loader;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -48,7 +47,6 @@
 import android.os.Bundle;
 import android.os.Trace;
 import android.provider.CalendarContract;
-import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Event;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -72,9 +70,7 @@
 import android.provider.ContactsContract.RawContacts;
 import android.support.graphics.drawable.VectorDrawableCompat;
 import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
 import android.support.v7.graphics.Palette;
-import android.support.v7.widget.CardView;
 import android.telecom.PhoneAccount;
 import android.telecom.TelecomManager;
 import android.text.BidiFormatter;
@@ -85,7 +81,6 @@
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -94,12 +89,6 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnCreateContextMenuListener;
 import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
 import android.widget.Toast;
 import android.widget.Toolbar;
 
@@ -113,7 +102,6 @@
 import com.android.contacts.common.CallUtil;
 import com.android.contacts.common.ClipboardUtils;
 import com.android.contacts.common.Collapser;
-import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.activity.RequestDesiredPermissionsActivity;
 import com.android.contacts.common.activity.RequestPermissionsActivity;
@@ -135,7 +123,6 @@
 import com.android.contacts.common.model.ContactLoader;
 import com.android.contacts.common.model.RawContact;
 import com.android.contacts.common.model.RawContactDeltaList;
-import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.dataitem.CustomDataItem;
 import com.android.contacts.common.model.dataitem.DataItem;
@@ -160,8 +147,6 @@
 import com.android.contacts.common.util.UriUtils;
 import com.android.contacts.common.util.ViewUtil;
 import com.android.contacts.detail.ContactDisplayUtils;
-import com.android.contacts.editor.AggregationSuggestionEngine;
-import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
 import com.android.contacts.editor.ContactEditorFragment;
 import com.android.contacts.editor.EditorIntents;
 import com.android.contacts.editor.EditorUiUtils;
@@ -186,6 +171,7 @@
 import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;
 import com.android.contacts.widget.QuickContactImageView;
 import com.android.contactsbind.HelpUtils;
+
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
@@ -195,11 +181,8 @@
 import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -208,7 +191,7 @@
  * {@link Intent#getSourceBounds()}.
  */
 public class QuickContactActivity extends ContactsActivity implements
-        AggregationSuggestionEngine.Listener, SplitContactConfirmationDialogFragment.Listener {
+        SplitContactConfirmationDialogFragment.Listener {
 
     /**
      * QuickContacts immediately takes up the full screen. All possible information is shown.
@@ -230,10 +213,7 @@
     private static final String TAG = "QuickContact";
 
     private static final String KEY_THEME_COLOR = "theme_color";
-    private static final String KEY_IS_SUGGESTION_LIST_COLLAPSED = "is_suggestion_list_collapsed";
-    private static final String KEY_SELECTED_SUGGESTION_CONTACTS = "selected_suggestion_contacts";
     private static final String KEY_PREVIOUS_CONTACT_ID = "previous_contact_id";
-    private static final String KEY_SUGGESTIONS_AUTO_SELECTED = "suggestions_auto_seleted";
 
     private static final String KEY_SEND_TO_VOICE_MAIL_STATE = "sendToVoicemailState";
     private static final String KEY_ARE_PHONE_OPTIONS_CHANGEABLE = "arePhoneOptionsChangable";
@@ -303,23 +283,7 @@
     private ExpandingEntryCardView mAboutCard;
     private ExpandingEntryCardView mPermissionExplanationCard;
 
-    // Suggestion card.
-    private boolean mShouldShowSuggestions = false;
-    private CardView mCollapsedSuggestionCardView;
-    private CardView mExpandSuggestionCardView;
-    private View mCollapsedSuggestionHeader;
-    private TextView mCollapsedSuggestionCardTitle;
-    private TextView mExpandSuggestionCardTitle;
-    private ImageView mSuggestionSummaryPhoto;
-    private TextView mSuggestionForName;
-    private TextView mSuggestionContactsNumber;
-    private LinearLayout mSuggestionList;
-    private Button mSuggestionsCancelButton;
-    private Button mSuggestionsLinkButton;
-    private boolean mIsSuggestionListCollapsed;
-    private boolean mSuggestionsShouldAutoSelected = true;
     private long mPreviousContactId = 0;
-
     // Permission explanation card.
     private boolean mShouldShowPermissionExplanation = false;
     private String mPermissionExplanationCardSubHeader = "";
@@ -328,10 +292,6 @@
     private AsyncTask<Void, Void, Cp2DataCardModel> mEntriesAndActionsTask;
     private AsyncTask<Void, Void, Void> mRecentDataTask;
 
-    private AggregationSuggestionEngine mAggregationSuggestionEngine;
-    private List<Suggestion> mSuggestions;
-
-    private TreeSet<Long> mSelectedAggregationIds = new TreeSet<>();
     /**
      * The last copy of Cp2DataCardModel that was passed to {@link #populateContactAndAboutCard}.
      */
@@ -535,211 +495,6 @@
         }
     };
 
-    @Override
-    public void onAggregationSuggestionChange() {
-        if (!mShouldShowSuggestions) {
-            return;
-        }
-        if (mAggregationSuggestionEngine == null) {
-            return;
-        }
-        mSuggestions = mAggregationSuggestionEngine.getSuggestions();
-        mCollapsedSuggestionCardView.setVisibility(View.GONE);
-        mExpandSuggestionCardView.setVisibility(View.GONE);
-        mSuggestionList.removeAllViews();
-
-        if (mContactData == null) {
-            return;
-        }
-
-        final String suggestionForName = mContactData.getDisplayName();
-        final int suggestionNumber = mSuggestions.size();
-
-        if (suggestionNumber <= 0) {
-            mSelectedAggregationIds.clear();
-            return;
-        }
-
-        ContactPhotoManager.DefaultImageRequest
-                request = new ContactPhotoManager.DefaultImageRequest(
-                suggestionForName, mContactData.getLookupKey(), ContactPhotoManager.TYPE_DEFAULT,
-                /* isCircular */ true );
-        final long photoId = mContactData.getPhotoId();
-        final byte[] photoBytes = mContactData.getThumbnailPhotoBinaryData();
-        if (photoBytes != null) {
-            ContactPhotoManager.getInstance(this).loadThumbnail(mSuggestionSummaryPhoto, photoId,
-                /* darkTheme */ false , /* isCircular */ true , request);
-        } else {
-            ContactPhotoManager.DEFAULT_AVATAR.applyDefaultImage(mSuggestionSummaryPhoto,
-                    -1, false, request);
-        }
-
-        final String suggestionTitle = getResources().getQuantityString(
-                R.plurals.quickcontact_suggestion_card_title, suggestionNumber, suggestionNumber);
-        mCollapsedSuggestionCardTitle.setText(suggestionTitle);
-        mExpandSuggestionCardTitle.setText(suggestionTitle);
-
-        mSuggestionForName.setText(suggestionForName);
-        final int linkedContactsNumber = mContactData.getRawContacts().size();
-        final String contactsInfo;
-        final String accountName = mContactData.getRawContacts().get(0).getAccountName();
-        if (linkedContactsNumber == 1 && accountName == null) {
-            mSuggestionContactsNumber.setVisibility(View.INVISIBLE);
-        }
-        if (linkedContactsNumber == 1 && accountName != null) {
-            contactsInfo = getResources().getString(R.string.contact_from_account_name,
-                    accountName);
-        } else {
-            contactsInfo = getResources().getString(
-                    R.string.quickcontact_contacts_number, linkedContactsNumber);
-        }
-        mSuggestionContactsNumber.setText(contactsInfo);
-
-        final Set<Long> suggestionContactIds = new HashSet<>();
-        for (Suggestion suggestion : mSuggestions) {
-            mSuggestionList.addView(inflateSuggestionListView(suggestion));
-            suggestionContactIds.add(suggestion.contactId);
-        }
-
-        if (mIsSuggestionListCollapsed) {
-            collapseSuggestionList();
-        } else {
-            expandSuggestionList();
-        }
-
-        // Remove contact Ids that are not suggestions.
-        final Set<Long> selectedSuggestionIds = com.google.common.collect.Sets.intersection(
-                mSelectedAggregationIds, suggestionContactIds);
-        mSelectedAggregationIds = new TreeSet<>(selectedSuggestionIds);
-        if (!mSelectedAggregationIds.isEmpty()) {
-            enableLinkButton();
-        }
-    }
-
-    private void collapseSuggestionList() {
-        mCollapsedSuggestionCardView.setVisibility(View.VISIBLE);
-        mExpandSuggestionCardView.setVisibility(View.GONE);
-        mIsSuggestionListCollapsed = true;
-    }
-
-    private void expandSuggestionList() {
-        mCollapsedSuggestionCardView.setVisibility(View.GONE);
-        mExpandSuggestionCardView.setVisibility(View.VISIBLE);
-        mIsSuggestionListCollapsed = false;
-    }
-
-    private View inflateSuggestionListView(final Suggestion suggestion) {
-        final LayoutInflater layoutInflater = LayoutInflater.from(this);
-        final View suggestionView = layoutInflater.inflate(
-                R.layout.quickcontact_suggestion_contact_item, null);
-
-        ContactPhotoManager.DefaultImageRequest
-                request = new ContactPhotoManager.DefaultImageRequest(
-                suggestion.name, suggestion.lookupKey, ContactPhotoManager.TYPE_DEFAULT, /*
-                isCircular */ true);
-        final ImageView photo = (ImageView) suggestionView.findViewById(
-                R.id.aggregation_suggestion_photo);
-        if (suggestion.photo != null) {
-            ContactPhotoManager.getInstance(this).loadThumbnail(photo, suggestion.photoId,
-                   /* darkTheme */ false, /* isCircular */ true, request);
-        } else {
-            ContactPhotoManager.DEFAULT_AVATAR.applyDefaultImage(photo, -1, false, request);
-        }
-
-        final TextView name = (TextView) suggestionView.findViewById(R.id.aggregation_suggestion_name);
-        name.setText(suggestion.name);
-
-        final TextView accountNameView = (TextView) suggestionView.findViewById(
-                R.id.aggregation_suggestion_account_name);
-        final String accountName = suggestion.rawContacts.get(0).accountName;
-        if (!TextUtils.isEmpty(accountName)) {
-            accountNameView.setText(
-                    getResources().getString(R.string.contact_from_account_name, accountName));
-        } else {
-            accountNameView.setVisibility(View.INVISIBLE);
-        }
-
-        final CheckBox checkbox = (CheckBox) suggestionView.findViewById(R.id.suggestion_checkbox);
-        final int[][] stateSet = new int[][] {
-                new int[] { android.R.attr.state_checked },
-                new int[] { -android.R.attr.state_checked }
-        };
-        final int[] colors = new int[] { mColorFilterColor, mColorFilterColor };
-        if (suggestion != null && suggestion.name != null) {
-            checkbox.setContentDescription(suggestion.name + " " +
-                    getResources().getString(R.string.contact_from_account_name, accountName));
-        }
-        checkbox.setButtonTintList(new ColorStateList(stateSet, colors));
-        checkbox.setChecked(mSuggestionsShouldAutoSelected ||
-                mSelectedAggregationIds.contains(suggestion.contactId));
-        if (checkbox.isChecked()) {
-            mSelectedAggregationIds.add(suggestion.contactId);
-        }
-        checkbox.setTag(suggestion.contactId);
-        checkbox.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                final CheckBox checkBox = (CheckBox) v;
-                final Long contactId = (Long) checkBox.getTag();
-                if (mSelectedAggregationIds.contains(mContactData.getId())) {
-                    mSelectedAggregationIds.remove(mContactData.getId());
-                }
-                if (checkBox.isChecked()) {
-                    mSelectedAggregationIds.add(contactId);
-                    if (mSelectedAggregationIds.size() >= 1) {
-                        enableLinkButton();
-                    }
-                } else {
-                    mSelectedAggregationIds.remove(contactId);
-                    mSuggestionsShouldAutoSelected = false;
-                    if (mSelectedAggregationIds.isEmpty()) {
-                        disableLinkButton();
-                    }
-                }
-            }
-        });
-
-        return suggestionView;
-    }
-
-    private void enableLinkButton() {
-        mSuggestionsLinkButton.setClickable(true);
-        mSuggestionsLinkButton.getBackground().setColorFilter(mColorFilter);
-        mSuggestionsLinkButton.setTextColor(
-                ContextCompat.getColor(this, android.R.color.white));
-        mSuggestionsLinkButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                // Join selected contacts.
-                if (!mSelectedAggregationIds.contains(mContactData.getId())) {
-                    mSelectedAggregationIds.add(mContactData.getId());
-                }
-
-                final Long[] contactIdsArray = mSelectedAggregationIds.toArray(
-                        new Long[mSelectedAggregationIds.size()]);
-                final long[] contactIdsArray2 = new long[contactIdsArray.length];
-                for (int i = 0; i < contactIdsArray.length; i++) {
-                    contactIdsArray2[i] = contactIdsArray[i];
-                }
-
-                final Intent intent = ContactSaveService.createJoinSeveralContactsIntent(
-                        QuickContactActivity.this, contactIdsArray2);
-                QuickContactActivity.this.startService(intent);
-
-                disableLinkButton();
-            }
-        });
-    }
-
-    private void disableLinkButton() {
-        mSuggestionsLinkButton.setClickable(false);
-        mSuggestionsLinkButton.getBackground().setColorFilter(
-                ContextCompat.getColor(this, R.color.disabled_button_background),
-                PorterDuff.Mode.SRC_ATOP);
-        mSuggestionsLinkButton.setTextColor(
-                ContextCompat.getColor(this, R.color.disabled_button_text));
-    }
-
     private interface ContextMenuIds {
         static final int COPY_TEXT = 0;
         static final int CLEAR_DEFAULT = 1;
@@ -1046,59 +801,6 @@
         mPermissionExplanationCard =
                 (ExpandingEntryCardView) findViewById(R.id.permission_explanation_card);
 
-        if (mShouldShowSuggestions) {
-            mCollapsedSuggestionCardView = (CardView) findViewById(R.id.collapsed_suggestion_card);
-            mExpandSuggestionCardView = (CardView) findViewById(R.id.expand_suggestion_card);
-            mCollapsedSuggestionHeader = findViewById(R.id.collapsed_suggestion_header);
-            mCollapsedSuggestionCardTitle = (TextView) findViewById(
-                    R.id.collapsed_suggestion_card_title);
-            mExpandSuggestionCardTitle = (TextView) findViewById(R.id.expand_suggestion_card_title);
-            mSuggestionSummaryPhoto = (ImageView) findViewById(R.id.suggestion_icon);
-            mSuggestionForName = (TextView) findViewById(R.id.suggestion_for_name);
-            mSuggestionContactsNumber = (TextView) findViewById(
-                    R.id.suggestion_for_contacts_number);
-            mSuggestionList = (LinearLayout) findViewById(R.id.suggestion_list);
-            mSuggestionsCancelButton = (Button) findViewById(R.id.cancel_button);
-            mSuggestionsLinkButton = (Button) findViewById(R.id.link_button);
-            if (savedInstanceState != null) {
-                mIsSuggestionListCollapsed = savedInstanceState.getBoolean(
-                        KEY_IS_SUGGESTION_LIST_COLLAPSED, true);
-                mPreviousContactId = savedInstanceState.getLong(KEY_PREVIOUS_CONTACT_ID);
-                mSuggestionsShouldAutoSelected = savedInstanceState.getBoolean(
-                        KEY_SUGGESTIONS_AUTO_SELECTED, true);
-                mSelectedAggregationIds = (TreeSet<Long>)
-                        savedInstanceState.getSerializable(KEY_SELECTED_SUGGESTION_CONTACTS);
-            } else {
-                mIsSuggestionListCollapsed = true;
-                mSelectedAggregationIds.clear();
-            }
-            if (mSelectedAggregationIds.isEmpty()) {
-                disableLinkButton();
-            } else {
-                enableLinkButton();
-            }
-            mCollapsedSuggestionHeader.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View view) {
-                    mCollapsedSuggestionCardView.setVisibility(View.GONE);
-                    mExpandSuggestionCardView.setVisibility(View.VISIBLE);
-                    mIsSuggestionListCollapsed = false;
-                    mExpandSuggestionCardTitle.requestFocus();
-                    mExpandSuggestionCardTitle.sendAccessibilityEvent(
-                            AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-                }
-            });
-
-            mSuggestionsCancelButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View view) {
-                    mCollapsedSuggestionCardView.setVisibility(View.VISIBLE);
-                    mExpandSuggestionCardView.setVisibility(View.GONE);
-                    mIsSuggestionListCollapsed = true;
-                }
-            });
-        }
-
         mPermissionExplanationCard.setOnClickListener(mEntryClickHandler);
         mNoContactDetailsCard.setOnClickListener(mEntryClickHandler);
         mContactCard.setOnClickListener(mEntryClickHandler);
@@ -1240,12 +942,7 @@
         if (mColorFilter != null) {
             savedInstanceState.putInt(KEY_THEME_COLOR, mColorFilterColor);
         }
-        savedInstanceState.putBoolean(KEY_IS_SUGGESTION_LIST_COLLAPSED, mIsSuggestionListCollapsed);
         savedInstanceState.putLong(KEY_PREVIOUS_CONTACT_ID, mPreviousContactId);
-        savedInstanceState.putBoolean(
-                KEY_SUGGESTIONS_AUTO_SELECTED, mSuggestionsShouldAutoSelected);
-        savedInstanceState.putSerializable(
-                KEY_SELECTED_SUGGESTION_CONTACTS, mSelectedAggregationIds);
 
         // Phone specific options
         savedInstanceState.putBoolean(KEY_SEND_TO_VOICE_MAIL_STATE, mSendToVoicemailState);
@@ -1436,7 +1133,6 @@
     private void bindDataToCards(Cp2DataCardModel cp2DataCardModel) {
         startInteractionLoaders(cp2DataCardModel);
         populateContactAndAboutCard(cp2DataCardModel, /* shouldAddPhoneticName */ true);
-        populateSuggestionCard();
     }
 
     private void startInteractionLoaders(Cp2DataCardModel cp2DataCardModel) {
@@ -1549,53 +1245,6 @@
         }
     }
 
-    private void populateSuggestionCard() {
-        if (!mShouldShowSuggestions) {
-            return;
-        }
-        // Initialize suggestion related view and data.
-        if (mPreviousContactId != mContactData.getId()) {
-            mCollapsedSuggestionCardView.setVisibility(View.GONE);
-            mExpandSuggestionCardView.setVisibility(View.GONE);
-            mIsSuggestionListCollapsed = true;
-            mSuggestionsShouldAutoSelected = true;
-            mSuggestionList.removeAllViews();
-        }
-
-        // Do not show the card when it's directory contact or invisible.
-        if (DirectoryContactUtil.isDirectoryContact(mContactData)
-                || InvisibleContactUtil.isInvisibleAndAddable(mContactData, this)) {
-            return;
-        }
-
-        if (mAggregationSuggestionEngine == null) {
-            mAggregationSuggestionEngine = new AggregationSuggestionEngine(this);
-            mAggregationSuggestionEngine.setListener(this);
-            mAggregationSuggestionEngine.setSuggestionsLimit(getResources().getInteger(
-                    R.integer.quickcontact_suggestions_limit));
-            mAggregationSuggestionEngine.start();
-        }
-
-        mAggregationSuggestionEngine.setContactId(mContactData.getId());
-        if (mPreviousContactId != 0
-                && mPreviousContactId != mContactData.getId()) {
-            // Clear selected Ids when listing suggestions for new contact Id.
-            mSelectedAggregationIds.clear();
-        }
-        mPreviousContactId = mContactData.getId();
-
-        // Trigger suggestion engine to compute suggestions.
-        if (mContactData.getId() <= 0) {
-            return;
-        }
-        final ContentValues values = new ContentValues();
-        values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
-                mContactData.getDisplayName());
-        values.put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME,
-                mContactData.getPhoneticName());
-        mAggregationSuggestionEngine.onNameChange(ValuesDelta.fromBefore(values));
-    }
-
     private void populateContactAndAboutCard(Cp2DataCardModel cp2DataCardModel,
             boolean shouldAddPhoneticName) {
         mCachedCp2DataCardModel = cp2DataCardModel;
@@ -2515,8 +2164,6 @@
                 if (imageViewDrawable == mPhotoView.getDrawable()) {
                     mHasComputedThemeColor = true;
                     setThemeColor(palette);
-                    // update color and photo in suggestion card
-                    onAggregationSuggestionChange();
                 }
             }
         }.execute();
@@ -2534,9 +2181,6 @@
         mContactCard.setColorAndFilter(mColorFilterColor, mColorFilter);
         mRecentCard.setColorAndFilter(mColorFilterColor, mColorFilter);
         mAboutCard.setColorAndFilter(mColorFilterColor, mColorFilter);
-        if (mShouldShowSuggestions) {
-            mSuggestionsCancelButton.setTextColor(mColorFilterColor);
-        }
     }
 
     private void updateStatusBarColor() {
@@ -2892,9 +2536,6 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
-        if (mAggregationSuggestionEngine != null) {
-            mAggregationSuggestionEngine.quit();
-        }
     }
 
     /**