diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 1668521..cf36edf 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -109,9 +109,9 @@
     public static final String EXTRA_DATA_ID = "dataId";
 
     public static final String ACTION_JOIN_CONTACTS = "joinContacts";
+    public static final String ACTION_JOIN_SEVERAL_CONTACTS = "joinSeveralContacts";
     public static final String EXTRA_CONTACT_ID1 = "contactId1";
     public static final String EXTRA_CONTACT_ID2 = "contactId2";
-    public static final String EXTRA_CONTACT_WRITABLE = "contactWritable";
 
     public static final String ACTION_SET_SEND_TO_VOICEMAIL = "sendToVoicemail";
     public static final String EXTRA_SEND_TO_VOICEMAIL_FLAG = "sendToVoicemailFlag";
@@ -211,6 +211,8 @@
             deleteContact(intent);
         } else if (ACTION_JOIN_CONTACTS.equals(action)) {
             joinContacts(intent);
+        } else if (ACTION_JOIN_SEVERAL_CONTACTS.equals(action)) {
+            joinSeveralContacts(intent);
         } else if (ACTION_SET_SEND_TO_VOICEMAIL.equals(action)) {
             setSendToVoicemail(intent);
         } else if (ACTION_SET_RINGTONE.equals(action)) {
@@ -985,15 +987,14 @@
 
     /**
      * Creates an intent that can be sent to this service to join two contacts.
+     * The resulting contact uses the name from {@param contactId1} if possible.
      */
     public static Intent createJoinContactsIntent(Context context, long contactId1,
-            long contactId2, boolean contactWritable,
-            Class<? extends Activity> callbackActivity, String callbackAction) {
+            long contactId2, Class<? extends Activity> callbackActivity, String callbackAction) {
         Intent serviceIntent = new Intent(context, ContactSaveService.class);
         serviceIntent.setAction(ContactSaveService.ACTION_JOIN_CONTACTS);
         serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_ID1, contactId1);
         serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_ID2, contactId2);
-        serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_WRITABLE, contactWritable);
 
         // Callback intent will be invoked by the service once the contacts are joined.
         Intent callbackIntent = new Intent(context, callbackActivity);
@@ -1003,6 +1004,17 @@
         return serviceIntent;
     }
 
+    /**
+     * Creates an intent to join all raw contacts inside {@param contactIds}'s contacts.
+     * No special attention is paid to where the resulting contact's name is taken from.
+     */
+    public static Intent createJoinSeveralContactsIntent(Context context, long[] contactIds) {
+        Intent serviceIntent = new Intent(context, ContactSaveService.class);
+        serviceIntent.setAction(ContactSaveService.ACTION_JOIN_SEVERAL_CONTACTS);
+        serviceIntent.putExtra(ContactSaveService.EXTRA_CONTACT_IDS, contactIds);
+        return serviceIntent;
+    }
+
 
     private interface JoinContactQuery {
         String[] PROJECTION = {
@@ -1011,8 +1023,6 @@
                 RawContacts.DISPLAY_NAME_SOURCE,
         };
 
-        String SELECTION = RawContacts.CONTACT_ID + "=? OR " + RawContacts.CONTACT_ID + "=?";
-
         int _ID = 0;
         int CONTACT_ID = 1;
         int DISPLAY_NAME_SOURCE = 2;
@@ -1034,22 +1044,48 @@
         int IS_SUPER_PRIMARY = 2;
     }
 
-    private void joinContacts(Intent intent) {
-        long contactId1 = intent.getLongExtra(EXTRA_CONTACT_ID1, -1);
-        long contactId2 = intent.getLongExtra(EXTRA_CONTACT_ID2, -1);
+    private void joinSeveralContacts(Intent intent) {
+        final long[] contactIds = intent.getLongArrayExtra(EXTRA_CONTACT_IDS);
 
-        if (contactId1 == -1 || contactId2 == -1) {
-            Log.e(TAG, "Invalid arguments for joinContacts request");
+        // Load raw contact IDs for all contacts involved.
+        long rawContactIds[] = getRawContactIdsForAggregation(contactIds);
+        if (rawContactIds == null) {
+            Log.e(TAG, "Invalid arguments for joinSeveralContacts request");
             return;
         }
 
+        // For each pair of raw contacts, insert an aggregation exception
         final ContentResolver resolver = getContentResolver();
+        final ArrayList<ContentProviderOperation> operations
+                = new ArrayList<ContentProviderOperation>();
+        for (int i = 0; i < rawContactIds.length; i++) {
+            for (int j = 0; j < rawContactIds.length; j++) {
+                if (i != j) {
+                    buildJoinContactDiff(operations, rawContactIds[i], rawContactIds[j]);
+                }
+            }
+        }
+
+        // Apply all aggregation exceptions as one batch
+        try {
+            resolver.applyBatch(ContactsContract.AUTHORITY, operations);
+            showToast(R.string.contactsJoinedMessage);
+        } catch (RemoteException | OperationApplicationException e) {
+            Log.e(TAG, "Failed to apply aggregation exception batch", e);
+            showToast(R.string.contactSavedErrorToast);
+        }
+    }
+
+
+    private void joinContacts(Intent intent) {
+        long contactId1 = intent.getLongExtra(EXTRA_CONTACT_ID1, -1);
+        long contactId2 = intent.getLongExtra(EXTRA_CONTACT_ID2, -1);
 
         // Load raw contact IDs for all raw contacts involved - currently edited and selected
         // in the join UIs.
         long rawContactIds[] = getRawContactIdsForAggregation(contactId1, contactId2);
         if (rawContactIds == null) {
-            // Error.
+            Log.e(TAG, "Invalid arguments for joinContacts request");
             return;
         }
 
@@ -1064,6 +1100,8 @@
             }
         }
 
+        final ContentResolver resolver = getContentResolver();
+
         // Use the name for contactId1 as the name for the newly aggregated contact.
         final Uri contactId1Uri = ContentUris.withAppendedId(
                 Contacts.CONTENT_URI, contactId1);
@@ -1101,10 +1139,7 @@
             resolver.applyBatch(ContactsContract.AUTHORITY, operations);
             showToast(R.string.contactsJoinedMessage);
             success = true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to apply aggregation exception batch", e);
-            showToast(R.string.contactSavedErrorToast);
-        } catch (OperationApplicationException e) {
+        } catch (RemoteException | OperationApplicationException e) {
             Log.e(TAG, "Failed to apply aggregation exception batch", e);
             showToast(R.string.contactSavedErrorToast);
         }
@@ -1118,13 +1153,32 @@
         deliverCallback(callbackIntent);
     }
 
-    private long[] getRawContactIdsForAggregation(long contactId1, long contactId2) {
+    private long[] getRawContactIdsForAggregation(long[] contactIds) {
+        if (contactIds == null) {
+            return null;
+        }
+
         final ContentResolver resolver = getContentResolver();
         long rawContactIds[];
+
+        final StringBuilder queryBuilder = new StringBuilder();
+        final String stringContactIds[] = new String[contactIds.length];
+        for (int i = 0; i < contactIds.length; i++) {
+            queryBuilder.append(RawContacts.CONTACT_ID + "=?");
+            stringContactIds[i] = String.valueOf(contactIds[i]);
+            if (contactIds[i] == -1) {
+                return null;
+            }
+            if (i == contactIds.length -1) {
+                break;
+            }
+            queryBuilder.append(" OR ");
+        }
+
         final Cursor c = resolver.query(RawContacts.CONTENT_URI,
                 JoinContactQuery.PROJECTION,
-                JoinContactQuery.SELECTION,
-                new String[]{String.valueOf(contactId1), String.valueOf(contactId2)}, null);
+                queryBuilder.toString(),
+                stringContactIds, null);
         if (c == null) {
             Log.e(TAG, "Unable to open Contacts DB cursor");
             showToast(R.string.contactSavedErrorToast);
@@ -1132,7 +1186,7 @@
         }
         try {
             if (c.getCount() < 2) {
-                Log.e(TAG, "Not enough raw contacts to aggregate toghether.");
+                Log.e(TAG, "Not enough raw contacts to aggregate together.");
                 return null;
             }
             rawContactIds = new long[c.getCount()];
@@ -1147,6 +1201,10 @@
         return rawContactIds;
     }
 
+    private long[] getRawContactIdsForAggregation(long contactId1, long contactId2) {
+        return getRawContactIdsForAggregation(new long[] {contactId1, contactId2});
+    }
+
     /**
      * Construct a {@link AggregationExceptions#TYPE_KEEP_TOGETHER} ContentProviderOperation.
      */
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 577bf57..d660f4f 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -64,6 +64,8 @@
 import com.android.contacts.common.list.ContactTileAdapter.DisplayType;
 import com.android.contacts.interactions.ContactMultiDeletionInteraction;
 import com.android.contacts.interactions.ContactMultiDeletionInteraction.MultiContactDeleteListener;
+import com.android.contacts.interactions.JoinContactsDialogFragment;
+import com.android.contacts.interactions.JoinContactsDialogFragment.JoinContactsListener;
 import com.android.contacts.list.MultiSelectContactsListFragment;
 import com.android.contacts.list.MultiSelectContactsListFragment.OnCheckBoxListActionListener;
 import com.android.contacts.list.ContactTileListFragment;
@@ -100,7 +102,8 @@
         DialogManager.DialogShowingViewActivity,
         ContactListFilterController.ContactListFilterListener,
         ProviderStatusListener,
-        MultiContactDeleteListener {
+        MultiContactDeleteListener,
+        JoinContactsListener {
 
     private static final String TAG = "PeopleActivity";
 
@@ -1065,6 +1068,8 @@
                 && mAllFragment.getSelectedContactIds().size() != 0;
         makeMenuItemVisible(menu, R.id.menu_share, showSelectedContactOptions);
         makeMenuItemVisible(menu, R.id.menu_delete, showSelectedContactOptions);
+        makeMenuItemVisible(menu, R.id.menu_join, showSelectedContactOptions);
+        makeMenuItemEnabled(menu, R.id.menu_join, mAllFragment.getSelectedContactIds().size() > 1);
 
         // Debug options need to be visible even in search mode.
         makeMenuItemVisible(menu, R.id.export_database, mEnableDebugMenuOptions);
@@ -1081,12 +1086,19 @@
     }
 
     private void makeMenuItemVisible(Menu menu, int itemId, boolean visible) {
-        MenuItem item =menu.findItem(itemId);
+        final MenuItem item = menu.findItem(itemId);
         if (item != null) {
             item.setVisible(visible);
         }
     }
 
+    private void makeMenuItemEnabled(Menu menu, int itemId, boolean visible) {
+        final MenuItem item = menu.findItem(itemId);
+        if (item != null) {
+            item.setEnabled(visible);
+        }
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if (mDisableOptionItemSelected) {
@@ -1130,6 +1142,9 @@
             case R.id.menu_share:
                 shareSelectedContacts();
                 return true;
+            case R.id.menu_join:
+                joinSelectedContacts();
+                return true;
             case R.id.menu_delete:
                 deleteSelectedContacts();
                 return true;
@@ -1197,6 +1212,15 @@
         ImplicitIntentsUtil.startActivityOutsideApp(this, intent);
     }
 
+    private void joinSelectedContacts() {
+        JoinContactsDialogFragment.start(this, mAllFragment.getSelectedContactIds());
+    }
+
+    @Override
+    public void onContactsJoined() {
+        mAllFragment.clearCheckBoxes();
+    }
+
     private void deleteSelectedContacts() {
         ContactMultiDeletionInteraction.start(PeopleActivity.this,
                 mAllFragment.getSelectedContactIds());
diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java
index f25d01a..94e2263 100644
--- a/src/com/android/contacts/editor/CompactContactEditorFragment.java
+++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java
@@ -304,8 +304,7 @@
     @Override
     protected void joinAggregate(final long contactId) {
         final Intent intent = ContactSaveService.createJoinContactsIntent(
-                mContext, mContactIdForJoin, contactId, mContactWritableForJoin,
-                CompactContactEditorActivity.class,
+                mContext, mContactIdForJoin, contactId, CompactContactEditorActivity.class,
                 CompactContactEditorActivity.ACTION_JOIN_COMPLETED);
         mContext.startService(intent);
     }
diff --git a/src/com/android/contacts/editor/ContactEditorBaseFragment.java b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
index 57905d1..d8c20fb 100644
--- a/src/com/android/contacts/editor/ContactEditorBaseFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
@@ -139,7 +139,6 @@
 
     // Join Activity
     private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin";
-    private static final String KEY_CONTACT_WRITABLE_FOR_JOIN = "contactwritableforjoin";
 
     protected static final int REQUEST_CODE_JOIN = 0;
     protected static final int REQUEST_CODE_ACCOUNTS_CHANGED = 1;
@@ -332,7 +331,6 @@
 
     // Join Activity
     protected long mContactIdForJoin;
-    protected boolean mContactWritableForJoin;
 
     //
     // Editor state for {@link ContactEditorView}.
@@ -465,7 +463,6 @@
 
             // Join Activity
             mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN);
-            mContactWritableForJoin = savedState.getBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN);
         }
 
         // mState can still be null because it may not have have finished loading before
@@ -582,7 +579,6 @@
 
         // Join Activity
         outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin);
-        outState.putBoolean(KEY_CONTACT_WRITABLE_FOR_JOIN, mContactWritableForJoin);
 
         super.onSaveInstanceState(outState);
     }
@@ -1337,7 +1333,6 @@
         }
 
         mContactIdForJoin = ContentUris.parseId(contactLookupUri);
-        mContactWritableForJoin = isContactWritable();
         final Intent intent = new Intent(UiIntentActions.PICK_JOIN_CONTACT_ACTION);
         intent.putExtra(UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, mContactIdForJoin);
         startActivityForResult(intent, REQUEST_CODE_JOIN);
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 96aaecd..9e5148d 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -509,8 +509,8 @@
     @Override
     protected void joinAggregate(final long contactId) {
         final Intent intent = ContactSaveService.createJoinContactsIntent(
-                mContext, mContactIdForJoin, contactId, mContactWritableForJoin,
-                ContactEditorActivity.class, ContactEditorActivity.ACTION_JOIN_COMPLETED);
+                mContext, mContactIdForJoin, contactId, ContactEditorActivity.class,
+                ContactEditorActivity.ACTION_JOIN_COMPLETED);
         mContext.startService(intent);
     }
 
diff --git a/src/com/android/contacts/interactions/JoinContactsDialogFragment.java b/src/com/android/contacts/interactions/JoinContactsDialogFragment.java
new file mode 100644
index 0000000..a9a1aa9
--- /dev/null
+++ b/src/com/android/contacts/interactions/JoinContactsDialogFragment.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.interactions;
+
+
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentTransaction;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+
+import java.util.TreeSet;
+
+/**
+ * An interaction invoked to join multiple contacts together.
+ */
+public class JoinContactsDialogFragment extends DialogFragment {
+
+    private static final String FRAGMENT_TAG = "joinDialog";
+    private static final String KEY_CONTACT_IDS = "contactIds";
+
+    public interface JoinContactsListener {
+        void onContactsJoined();
+    }
+
+    public static void start(Activity activity, TreeSet<Long> contactIds) {
+        final FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
+        final JoinContactsDialogFragment newFragment
+                = JoinContactsDialogFragment.newInstance(contactIds);
+        newFragment.show(ft, FRAGMENT_TAG);
+    }
+
+    private static JoinContactsDialogFragment newInstance(TreeSet<Long> contactIds) {
+        final JoinContactsDialogFragment fragment = new JoinContactsDialogFragment();
+        Bundle arguments = new Bundle();
+        arguments.putSerializable(KEY_CONTACT_IDS, contactIds);
+        fragment.setArguments(arguments);
+        return fragment;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final TreeSet<Long> contactIds =
+                (TreeSet<Long>) getArguments().getSerializable(KEY_CONTACT_IDS);
+        if (contactIds.size() <= 1) {
+            return new AlertDialog.Builder(getActivity())
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setMessage(R.string.batch_merge_single_contact_warning)
+                    .setPositiveButton(android.R.string.ok, null)
+                    .create();
+        }
+        return new AlertDialog.Builder(getActivity())
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setMessage(R.string.batch_merge_confirmation)
+                .setNegativeButton(android.R.string.cancel, null)
+                .setPositiveButton(android.R.string.ok,
+                        new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                joinContacts(contactIds);
+                            }
+                        }
+                )
+                .create();
+    }
+
+    private void joinContacts(TreeSet<Long> contactIds) {
+        final Long[] contactIdsArray = contactIds.toArray(new Long[contactIds.size()]);
+        final long[] contactIdsArray2 = new long[contactIdsArray.length];
+        for (int i = 0; i < contactIds.size(); i++) {
+            contactIdsArray2[i] = contactIdsArray[i];
+        }
+
+        final Intent intent = ContactSaveService.createJoinSeveralContactsIntent(getActivity(),
+                contactIdsArray2);
+        getActivity().startService(intent);
+
+        notifyListener();
+    }
+
+    private void notifyListener() {
+        if (getActivity() instanceof JoinContactsListener) {
+            ((JoinContactsListener) getActivity()).onContactsJoined();
+        }
+    }
+
+}
