Remove full editor (1/2)

Test: Tested the following editor scenarios:
  1) new contact
  2) edit other contact
  3) edit writable raw contact
  4) edit read-only raw contact (joins a new writable raw contact to it)
  5) edit aggregate w/ 1 writable and 1 read-only raw contact
  6) edit aggregate w/ 2 writable raw contacts
  7) edit local me raw contact
  8) edit local me raw contact joined with a read-only raw contact

Bug: 31088704
Change-Id: I1fce2873facefa39d7b468f1deda02acc674e3e1
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index b34f384..d9d0231 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -743,7 +743,8 @@
 
         ContentValues values = new ContentValues();
         // TODO: Move this into the contact editor where it belongs. This needs to be integrated
-        // with the way other intent extras that are passed to the {@link ContactEditorActivity}.
+        // with the way other intent extras that are passed to the
+        // {@link CompactContactEditorActivity}.
         values.clear();
         values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
         values.put(GroupMembership.GROUP_ROW_ID, ContentUris.parseId(groupUri));
diff --git a/src/com/android/contacts/ContactsDrawerActivity.java b/src/com/android/contacts/ContactsDrawerActivity.java
index 047046b..8f2a7b8 100644
--- a/src/com/android/contacts/ContactsDrawerActivity.java
+++ b/src/com/android/contacts/ContactsDrawerActivity.java
@@ -62,7 +62,7 @@
 import com.android.contacts.common.util.DeviceAccountPresentationValues;
 import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.common.util.ViewUtil;
-import com.android.contacts.editor.ContactEditorFragment;
+import com.android.contacts.editor.ContactEditorBaseFragment;
 import com.android.contacts.group.GroupListItem;
 import com.android.contacts.group.GroupMetadata;
 import com.android.contacts.group.GroupNameEditDialogFragment;
@@ -587,7 +587,7 @@
     private Intent createPreferenceIntent() {
         final Intent intent = new Intent(this, ContactsPreferenceActivity.class);
         intent.putExtra(ContactsPreferenceActivity.EXTRA_NEW_LOCAL_PROFILE,
-                ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE);
+                ContactEditorBaseFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE);
         intent.putExtra(ContactsPreferenceActivity.EXTRA_MODE_FULLY_EXPANDED,
                 QuickContactActivity.MODE_FULLY_EXPANDED);
         intent.putExtra(ContactsPreferenceActivity.EXTRA_PREVIOUS_SCREEN_TYPE,
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
deleted file mode 100644
index 293e8c0..0000000
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2010 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.activities;
-
-import com.android.contacts.R;
-import com.android.contacts.common.activity.RequestPermissionsActivity;
-import com.android.contacts.editor.ContactEditorFragment;
-import com.android.contacts.util.DialogManager;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * Contact editor with all fields displayed.
- */
-public class ContactEditorActivity extends ContactEditorBaseActivity
-        implements DialogManager.DialogShowingViewActivity {
-
-    @Override
-    public void onCreate(Bundle savedState) {
-        super.onCreate(savedState);
-
-        if (RequestPermissionsActivity.startPermissionActivity(this)) {
-            return;
-        }
-
-        setContentView(R.layout.contact_editor_activity);
-
-        mFragment = (ContactEditorFragment) getFragmentManager().findFragmentById(
-                R.id.contact_editor_fragment);
-        mFragment.setListener(mFragmentListener);
-
-        final String action = getIntent().getAction();
-        final Uri uri = ContactEditorBaseActivity.ACTION_EDIT.equals(action)
-                || Intent.ACTION_EDIT.equals(action) ? getIntent().getData() : null;
-        mFragment.load(action, uri, getIntent().getExtras());
-    }
-}
diff --git a/src/com/android/contacts/activities/ContactEditorBaseActivity.java b/src/com/android/contacts/activities/ContactEditorBaseActivity.java
index 8a8ce1d..5b3d3a3 100644
--- a/src/com/android/contacts/activities/ContactEditorBaseActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorBaseActivity.java
@@ -36,7 +36,6 @@
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.editor.ContactEditorBaseFragment;
-import com.android.contacts.editor.ContactEditorFragment;
 import com.android.contacts.editor.EditorIntents;
 import com.android.contacts.interactions.ContactDeletionInteraction;
 import com.android.contacts.util.DialogManager;
@@ -50,20 +49,6 @@
         implements DialogManager.DialogShowingViewActivity {
     protected static final String TAG = "ContactEditorActivity";
 
-    /**
-     * Intent action to edit a contact with all available field inputs displayed.
-     *
-     * Only used to open the "fully expanded" editor -- {@link ContactEditorActivity}.
-     */
-    public static final String ACTION_EDIT = "com.android.contacts.action.FULL_EDIT";
-
-    /**
-     * Intent action to insert a new contact with all available field inputs displayed.
-     *
-     * Only used to open the "fully expanded" editor -- {@link ContactEditorActivity}.
-     */
-    public static final String ACTION_INSERT = "com.android.contacts.action.FULL_INSERT";
-
     public static final String ACTION_JOIN_COMPLETED = "joinCompleted";
     public static final String ACTION_SAVE_COMPLETED = "saveCompleted";
 
@@ -223,7 +208,7 @@
 
         ActionBar actionBar = getActionBar();
         if (actionBar != null) {
-            if (Intent.ACTION_EDIT.equals(action) || ACTION_EDIT.equals(action)) {
+            if (Intent.ACTION_EDIT.equals(action)) {
                 mActionBarTitleResId = R.string.contact_editor_title_existing_contact;
             } else {
                 mActionBarTitleResId = R.string.contact_editor_title_new_contact;
@@ -254,15 +239,15 @@
         }
 
         String action = intent.getAction();
-        if (Intent.ACTION_EDIT.equals(action) || ACTION_EDIT.equals(action)) {
+        if (Intent.ACTION_EDIT.equals(action)) {
             mFragment.setIntentExtras(intent.getExtras());
         } else if (ACTION_SAVE_COMPLETED.equals(action)) {
             mFragment.onSaveCompleted(true,
-                    intent.getIntExtra(ContactEditorFragment.SAVE_MODE_EXTRA_KEY,
+                    intent.getIntExtra(ContactEditorBaseFragment.SAVE_MODE_EXTRA_KEY,
                             ContactEditor.SaveMode.CLOSE),
                     intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false),
                     intent.getData(),
-                    intent.getLongExtra(ContactEditorFragment.JOIN_CONTACT_ID_EXTRA_KEY, -1));
+                    intent.getLongExtra(ContactEditorBaseFragment.JOIN_CONTACT_ID_EXTRA_KEY, -1));
         } else if (ACTION_JOIN_COMPLETED.equals(action)) {
             mFragment.onJoinCompleted(intent.getData());
         }
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index 57c460a..f36b046 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -488,7 +488,7 @@
 
         @Override
         public void onEditContactAction(Uri contactLookupUri) {
-            startActivityAndForwardResult(EditorIntents.createEditContactIntent(
+            startActivityAndForwardResult(EditorIntents.createCompactEditContactIntent(
                     ContactSelectionActivity.this, contactLookupUri, /* materialPalette =*/ null,
                     /* photoId =*/ -1));
         }
@@ -658,7 +658,8 @@
 
     private void startCreateNewContactActivity() {
         Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
-        intent.putExtra(ContactEditorActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
+        intent.putExtra(
+                ContactEditorBaseActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
         startActivityAndForwardResult(intent);
     }
 
diff --git a/src/com/android/contacts/common/model/RawContactModifier.java b/src/com/android/contacts/common/model/RawContactModifier.java
index fd028e3..4d62bb3 100644
--- a/src/com/android/contacts/common/model/RawContactModifier.java
+++ b/src/com/android/contacts/common/model/RawContactModifier.java
@@ -694,7 +694,7 @@
                 final Integer type = values.getAsInteger(Phone.TYPE);
                 // If the provided phone number provides a custom phone type but not a label,
                 // replace it with mobile (by default) to avoid the "Enter custom label" from
-                // popping up immediately upon entering the ContactEditorFragment
+                // popping up immediately upon entering the ContactEditorBaseFragment
                 if (type != null && type == Phone.TYPE_CUSTOM &&
                         TextUtils.isEmpty(values.getAsString(Phone.LABEL))) {
                     values.put(Phone.TYPE, Phone.TYPE_MOBILE);
diff --git a/src/com/android/contacts/editor/ContactEditorBaseFragment.java b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
index 2d363bd..0c0b205 100644
--- a/src/com/android/contacts/editor/ContactEditorBaseFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
@@ -111,8 +111,6 @@
     private static final List<String> VALID_INTENT_ACTIONS = new ArrayList<String>() {{
         add(Intent.ACTION_EDIT);
         add(Intent.ACTION_INSERT);
-        add(ContactEditorBaseActivity.ACTION_EDIT);
-        add(ContactEditorBaseActivity.ACTION_INSERT);
         add(ContactEditorBaseActivity.ACTION_SAVE_COMPLETED);
     }};
 
@@ -358,7 +356,7 @@
     // Loaded data
     //
     // Used to store existing contact data so it can be re-applied during a rebind call,
-    // i.e. account switch.  Only used in {@link ContactEditorFragment}.
+    // i.e. account switch.
     protected ImmutableList<RawContact> mRawContacts;
     protected Cursor mGroupMetaData;
 
@@ -553,8 +551,7 @@
             // The delta list may not have finished loading before orientation change happens.
             // In this case, there will be a saved state but deltas will be missing.  Reload from
             // database.
-            if (Intent.ACTION_EDIT.equals(mAction) ||
-                    ContactEditorBaseActivity.ACTION_EDIT.equals(mAction)) {
+            if (Intent.ACTION_EDIT.equals(mAction)) {
                 // Either
                 // 1) orientation change but load never finished.
                 // 2) not an orientation change so data needs to be loaded for first time.
@@ -576,11 +573,9 @@
                 mAccountWithDataSet = new AccountWithDataSet(account.name, account.type, dataSet);
             }
 
-            if (Intent.ACTION_EDIT.equals(mAction) ||
-                    ContactEditorBaseActivity.ACTION_EDIT.equals(mAction)) {
+            if (Intent.ACTION_EDIT.equals(mAction)) {
                 mIsEdit = true;
-            } else if (Intent.ACTION_INSERT.equals(mAction) ||
-                    ContactEditorBaseActivity.ACTION_INSERT.equals(mAction)) {
+            } else if (Intent.ACTION_INSERT.equals(mAction)) {
                 mHasNewContact = true;
                 if (mAccountWithDataSet != null) {
                     createContact(mAccountWithDataSet);
@@ -780,12 +775,12 @@
         // Set visibility of menus
 
         // help menu depending on whether this is inserting or editing
-        if (isInsert(mAction) || mRawContactIdToDisplayAlone != -1) {
+        if (Intent.ACTION_INSERT.equals(mAction) || mRawContactIdToDisplayAlone != -1) {
             HelpUtils.prepareHelpMenuItem(mContext, helpMenu, R.string.help_url_people_add);
             splitMenu.setVisible(false);
             joinMenu.setVisible(false);
             deleteMenu.setVisible(false);
-        } else if (isEdit(mAction)) {
+        } else if (Intent.ACTION_EDIT.equals(mAction)) {
             HelpUtils.prepareHelpMenuItem(mContext, helpMenu, R.string.help_url_people_edit);
             splitMenu.setVisible(canUnlinkRawContacts());
             // Cannot join a user profile
@@ -1743,21 +1738,4 @@
         // Otherwise pass back a lookup-style Uri
         return contactLookupUri;
     }
-
-    /**
-     * Whether the argument Intent requested a contact insert action or not.
-     */
-    protected static boolean isInsert(Intent intent) {
-        return intent == null ? false : isInsert(intent.getAction());
-    }
-
-    protected static boolean isInsert(String action) {
-        return Intent.ACTION_INSERT.equals(action)
-                || ContactEditorBaseActivity.ACTION_INSERT.equals(action);
-    }
-
-    protected static boolean isEdit(String action) {
-        return Intent.ACTION_EDIT.equals(action)
-                || ContactEditorBaseActivity.ACTION_EDIT.equals(action);
-    }
 }
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
deleted file mode 100644
index 146bc4c..0000000
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2010 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.editor;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.LinearLayout;
-import android.widget.ListPopupWindow;
-
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-import com.android.contacts.activities.ContactEditorActivity;
-import com.android.contacts.activities.ContactEditorBaseActivity.ContactEditor;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.RawContactDelta;
-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.account.AccountWithDataSet;
-import com.android.contacts.common.util.AccountsListAdapter;
-import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
-import com.android.contacts.detail.PhotoSelectionHandler;
-import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.util.ContactPhotoUtils;
-import com.android.contacts.util.UiClosables;
-
-import java.io.FileNotFoundException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Contact editor with all fields displayed.
- */
-public class ContactEditorFragment extends ContactEditorBaseFragment implements
-        RawContactReadOnlyEditorView.Listener {
-
-    private static final String KEY_EXPANDED_EDITORS = "expandedEditors";
-
-    private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester";
-    private static final String KEY_CURRENT_PHOTO_URI = "currentphotouri";
-    private static final String KEY_UPDATED_PHOTOS = "updatedPhotos";
-
-    // Used to store which raw contact editors have been expanded. Keyed on raw contact ids.
-    private HashMap<Long, Boolean> mExpandedEditors = new HashMap<Long, Boolean>();
-
-    /**
-     * The raw contact for which we started "take photo" or "choose photo from gallery" most
-     * recently.  Used to restore {@link #mCurrentPhotoHandler} after orientation change.
-     */
-    private long mRawContactIdRequestingPhoto;
-
-    /**
-     * The {@link PhotoHandler} for the photo editor for the {@link #mRawContactIdRequestingPhoto}
-     * raw contact.
-     *
-     * A {@link PhotoHandler} is created for each photo editor in {@link #bindPhotoHandler}, but
-     * the only "active" one should get the activity result.  This member represents the active
-     * one.
-     */
-    private PhotoHandler mCurrentPhotoHandler;
-    private Uri mCurrentPhotoUri;
-    private Bundle mUpdatedPhotos = new Bundle();
-
-    public ContactEditorFragment() {
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        final View view = inflater.inflate(R.layout.contact_editor_fragment, container, false);
-
-        mContent = (LinearLayout) view.findViewById(R.id.editors);
-
-        setHasOptionsMenu(true);
-
-        return view;
-    }
-
-    @Override
-    public void onCreate(Bundle savedState) {
-        super.onCreate(savedState);
-
-        if (savedState != null) {
-            mExpandedEditors = (HashMap<Long, Boolean>)
-                    savedState.getSerializable(KEY_EXPANDED_EDITORS);
-            mRawContactIdRequestingPhoto = savedState.getLong(
-                    KEY_RAW_CONTACT_ID_REQUESTING_PHOTO);
-            mCurrentPhotoUri = savedState.getParcelable(KEY_CURRENT_PHOTO_URI);
-            mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS);
-            mRawContactIdToDisplayAlone = savedState.getLong(
-                    ContactEditorBaseFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE, -1);
-        }
-    }
-
-    @Override
-    public void load(String action, Uri lookupUri, Bundle intentExtras) {
-        super.load(action, lookupUri, intentExtras);
-        if (intentExtras != null) {
-            mRawContactIdToDisplayAlone = intentExtras.getLong(
-                    ContactEditorBaseFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE, -1);
-        }
-    }
-
-    @Override
-    public void onStart() {
-        getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupsLoaderListener);
-        super.onStart();
-    }
-
-    @Override
-    public void onExternalEditorRequest(AccountWithDataSet account, Uri uri) {
-        if (mListener != null) {
-            mListener.onCustomEditContactActivityRequested(account, uri, null, false);
-        }
-    }
-
-    @Override
-    public void onEditorExpansionChanged() {
-        updatedExpandedEditorsMap();
-    }
-
-    @Override
-    protected void setGroupMetaData() {
-        if (mGroupMetaData == null) {
-            return;
-        }
-        int editorCount = mContent.getChildCount();
-        for (int i = 0; i < editorCount; i++) {
-            BaseRawContactEditorView editor = (BaseRawContactEditorView) mContent.getChildAt(i);
-            editor.setGroupMetaData(mGroupMetaData);
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (item.getItemId() == android.R.id.home) {
-            return revert();
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    @Override
-    protected void bindEditors() {
-        // bindEditors() can only bind views if there is data in mState, so immediately return
-        // if mState is null
-        if (mState.isEmpty()) {
-            return;
-        }
-
-        // Check if delta list is ready.  Delta list is populated from existing data and when
-        // editing an read-only contact, it's also populated with newly created data for the
-        // blank form.  When the data is not ready, skip. This method will be called multiple times.
-        if ((mIsEdit && !mExistingContactDataReady) || (mHasNewContact && !mNewContactDataReady)) {
-            return;
-        }
-
-        // Sort the editors
-        Collections.sort(mState, mComparator);
-
-        // Remove any existing editors and rebuild any visible
-        mContent.removeAllViews();
-
-        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
-        int numRawContacts = mState.size();
-
-        for (int i = 0; i < numRawContacts; i++) {
-            // TODO ensure proper ordering of entities in the list
-            final RawContactDelta rawContactDelta = mState.get(i);
-            if (!rawContactDelta.isVisible()) continue;
-
-            final AccountType type = rawContactDelta.getAccountType(accountTypes);
-            final long rawContactId = rawContactDelta.getRawContactId();
-
-            if (mRawContactIdToDisplayAlone != -1 && mRawContactIdToDisplayAlone != rawContactId) {
-                continue;
-            }
-
-            final BaseRawContactEditorView editor;
-            if (!type.areContactsWritable()) {
-                editor = (BaseRawContactEditorView) inflater.inflate(
-                        R.layout.raw_contact_readonly_editor_view, mContent, false);
-            } else {
-                editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view,
-                        mContent, false);
-            }
-            editor.setListener(this);
-            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(mContext)
-                    .getAccounts(true);
-            if (mHasNewContact && !mNewLocalProfile && accounts.size() > 1) {
-                addAccountSwitcher(mState.get(0), editor);
-            }
-
-            editor.setEnabled(isEnabled());
-
-            if (mRawContactIdToDisplayAlone != -1) {
-                editor.setCollapsed(false);
-            } else if (mExpandedEditors.containsKey(rawContactId)) {
-                editor.setCollapsed(mExpandedEditors.get(rawContactId));
-            } else {
-                // By default, only the first editor will be expanded.
-                editor.setCollapsed(i != 0);
-            }
-
-            mContent.addView(editor);
-
-            editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile());
-            if (mRawContactIdToDisplayAlone != -1) {
-                editor.setCollapsible(false);
-            } else {
-                editor.setCollapsible(numRawContacts > 1);
-            }
-
-            // Set up the photo handler.
-            bindPhotoHandler(editor, type, mState);
-
-            // If a new photo was chosen but not yet saved, we need to update the UI to
-            // reflect this.
-            final Uri photoUri = updatedPhotoUriForRawContact(rawContactId);
-            if (photoUri != null) editor.setFullSizedPhoto(photoUri);
-
-            if (editor instanceof RawContactEditorView) {
-                final Activity activity = getActivity();
-                final RawContactEditorView rawContactEditor = (RawContactEditorView) editor;
-                final ValuesDelta nameValuesDelta = rawContactEditor.getNameEditor().getValues();
-                final EditorListener structuredNameListener = new EditorListener() {
-
-                    @Override
-                    public void onRequest(int request) {
-                        // Make sure the activity is running
-                        if (activity.isFinishing()) {
-                            return;
-                        }
-                        if (!isEditingUserProfile()) {
-                            if (request == EditorListener.FIELD_CHANGED) {
-                                if (!nameValuesDelta.isSuperPrimary()) {
-                                    unsetSuperPrimaryForAllNameEditors();
-                                    nameValuesDelta.setSuperPrimary(true);
-                                }
-                                acquireAggregationSuggestions(activity,
-                                        rawContactEditor.getNameEditor().getRawContactId(),
-                                        rawContactEditor.getNameEditor().getValues());
-                            } else if (request == EditorListener.FIELD_TURNED_EMPTY) {
-                                if (nameValuesDelta.isSuperPrimary()) {
-                                    nameValuesDelta.setSuperPrimary(false);
-                                }
-                            }
-                        }
-                    }
-
-                    @Override
-                    public void onDeleteRequested(Editor removedEditor) {
-                    }
-                };
-
-                final StructuredNameEditorView nameEditor = rawContactEditor.getNameEditor();
-                nameEditor.setEditorListener(structuredNameListener);
-
-                rawContactEditor.setAutoAddToDefaultGroup(mAutoAddToDefaultGroup);
-
-                if (!isEditingUserProfile() && isAggregationSuggestionRawContactId(rawContactId)) {
-                    acquireAggregationSuggestions(activity,
-                            rawContactEditor.getNameEditor().getRawContactId(),
-                            rawContactEditor.getNameEditor().getValues());
-                }
-            }
-        }
-
-        setGroupMetaData();
-
-        // Show editor now that we've loaded state
-        mContent.setVisibility(View.VISIBLE);
-
-        // Refresh Action Bar as the visibility of the join command
-        // Activity can be null if we have been detached from the Activity
-        invalidateOptionsMenu();
-
-        updatedExpandedEditorsMap();
-    }
-
-    private void unsetSuperPrimaryForAllNameEditors() {
-        for (int i = 0; i < mContent.getChildCount(); i++) {
-            final View view = mContent.getChildAt(i);
-            if (view instanceof RawContactEditorView) {
-                final RawContactEditorView rawContactEditorView = (RawContactEditorView) view;
-                final StructuredNameEditorView nameEditorView =
-                        rawContactEditorView.getNameEditor();
-                if (nameEditorView != null) {
-                    final ValuesDelta valuesDelta = nameEditorView.getValues();
-                    if (valuesDelta != null) {
-                        valuesDelta.setSuperPrimary(false);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Update the values in {@link #mExpandedEditors}.
-     */
-    private void updatedExpandedEditorsMap() {
-        for (int i = 0; i < mContent.getChildCount(); i++) {
-            final View childView = mContent.getChildAt(i);
-            if (childView instanceof BaseRawContactEditorView) {
-                BaseRawContactEditorView childEditor = (BaseRawContactEditorView) childView;
-                mExpandedEditors.put(childEditor.getRawContactId(), childEditor.isCollapsed());
-            }
-        }
-    }
-
-    /**
-     * If we've stashed a temporary file containing a contact's new photo, return its URI.
-     * @param rawContactId identifies the raw-contact whose Bitmap we'll try to return.
-     * @return Uru of photo for specified raw-contact, or null
-     */
-    private Uri updatedPhotoUriForRawContact(long rawContactId) {
-        return (Uri) mUpdatedPhotos.get(String.valueOf(rawContactId));
-    }
-
-    private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
-            RawContactDeltaList state) {
-        final int mode;
-        boolean showIsPrimaryOption;
-        if (type.areContactsWritable()) {
-            if (editor.hasSetPhoto()) {
-                mode = PhotoActionPopup.Modes.WRITE_ABLE_PHOTO;
-                showIsPrimaryOption = hasMoreThanOnePhoto();
-            } else {
-                mode = PhotoActionPopup.Modes.NO_PHOTO;
-                showIsPrimaryOption = false;
-            }
-        } else if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) {
-            mode = PhotoActionPopup.Modes.READ_ONLY_PHOTO;
-            showIsPrimaryOption = true;
-        } else {
-            // Read-only and either no photo or the only photo ==> no options
-            editor.getPhotoEditor().setEditorListener(null);
-            editor.getPhotoEditor().setShowPrimary(false);
-            return;
-        }
-        if (mRawContactIdToDisplayAlone != -1) {
-            showIsPrimaryOption = false;
-        }
-        final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state);
-        editor.getPhotoEditor().setEditorListener(
-                (PhotoHandler.PhotoEditorListener) photoHandler.getListener());
-        editor.getPhotoEditor().setShowPrimary(showIsPrimaryOption);
-
-        // Note a newly created raw contact gets some random negative ID, so any value is valid
-        // here. (i.e. don't check against -1 or anything.)
-        if (mRawContactIdRequestingPhoto == editor.getRawContactId()) {
-            mCurrentPhotoHandler = photoHandler;
-        }
-    }
-
-    private void addAccountSwitcher(
-            final RawContactDelta currentState, BaseRawContactEditorView editor) {
-        final AccountWithDataSet currentAccount = new AccountWithDataSet(
-                currentState.getAccountName(),
-                currentState.getAccountType(),
-                currentState.getDataSet());
-        final View accountView = editor.findViewById(R.id.account);
-        final View anchorView = editor.findViewById(R.id.account_selector_container);
-        if (accountView == null) {
-            return;
-        }
-        anchorView.setVisibility(View.VISIBLE);
-        accountView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                final ListPopupWindow popup = new ListPopupWindow(mContext, null);
-                final AccountsListAdapter adapter =
-                        new AccountsListAdapter(mContext,
-                        AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, currentAccount);
-                popup.setWidth(anchorView.getWidth());
-                popup.setAnchorView(anchorView);
-                popup.setAdapter(adapter);
-                popup.setModal(true);
-                popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
-                popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-                    @Override
-                    public void onItemClick(AdapterView<?> parent, View view, int position,
-                            long id) {
-                        UiClosables.closeQuietly(popup);
-                        AccountWithDataSet newAccount = adapter.getItem(position);
-                        if (!newAccount.equals(currentAccount)) {
-                            rebindEditorsForNewContact(currentState, currentAccount, newAccount);
-                        }
-                    }
-                });
-                popup.show();
-            }
-        });
-    }
-
-    @Override
-    protected boolean doSaveAction(int saveMode, Long joinContactId) {
-        final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
-                SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
-                ((Activity) mContext).getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED,
-                mUpdatedPhotos, JOIN_CONTACT_ID_EXTRA_KEY, joinContactId);
-        return startSaveService(mContext, intent, saveMode);
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        outState.putSerializable(KEY_EXPANDED_EDITORS, mExpandedEditors);
-        outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto);
-        outState.putParcelable(KEY_CURRENT_PHOTO_URI, mCurrentPhotoUri);
-        outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos);
-        outState.putLong(ContactEditorBaseFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE,
-                mRawContactIdToDisplayAlone);
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (mStatus == Status.SUB_ACTIVITY) {
-            mStatus = Status.EDITING;
-        }
-
-        // See if the photo selection handler handles this result.
-        if (mCurrentPhotoHandler != null && mCurrentPhotoHandler.handlePhotoActivityResult(
-                requestCode, resultCode, data)) {
-            return;
-        }
-
-        super.onActivityResult(requestCode, resultCode, data);
-    }
-
-    @Override
-    protected void joinAggregate(final long contactId) {
-        final Intent intent = ContactSaveService.createJoinContactsIntent(
-                mContext, mContactIdForJoin, contactId, ContactEditorActivity.class,
-                ContactEditorActivity.ACTION_JOIN_COMPLETED);
-        mContext.startService(intent);
-    }
-
-    /**
-     * Sets the photo stored in mPhoto and writes it to the RawContact with the given id
-     */
-    private void setPhoto(long rawContact, Bitmap photo, Uri photoUri) {
-        BaseRawContactEditorView requestingEditor = getRawContactEditorView(rawContact);
-
-        if (photo == null || photo.getHeight() <= 0 || photo.getWidth() <= 0) {
-            // This is unexpected.
-            Log.w(TAG, "Invalid bitmap passed to setPhoto()");
-        }
-
-        if (requestingEditor != null) {
-            requestingEditor.setPhotoEntry(photo);
-            // Immediately set all other photos as non-primary. Otherwise the UI can display
-            // multiple photos as "Primary photo".
-            for (int i = 0; i < mContent.getChildCount(); i++) {
-                final View childView = mContent.getChildAt(i);
-                if (childView instanceof BaseRawContactEditorView
-                        && childView != requestingEditor) {
-                    final BaseRawContactEditorView rawContactEditor
-                            = (BaseRawContactEditorView) childView;
-                    rawContactEditor.getPhotoEditor().setSuperPrimary(false);
-                }
-            }
-        } else {
-            Log.w(TAG, "The contact that requested the photo is no longer present.");
-        }
-
-        mUpdatedPhotos.putParcelable(String.valueOf(rawContact), photoUri);
-    }
-
-    /**
-     * Finds raw contact editor view for the given rawContactId.
-     */
-    @Override
-    protected View getAggregationAnchorView(long rawContactId) {
-        BaseRawContactEditorView editorView = getRawContactEditorView(rawContactId);
-        return editorView == null ? null : editorView.findViewById(R.id.anchor_view);
-    }
-
-    public BaseRawContactEditorView getRawContactEditorView(long rawContactId) {
-        for (int i = 0; i < mContent.getChildCount(); i++) {
-            final View childView = mContent.getChildAt(i);
-            if (childView instanceof BaseRawContactEditorView) {
-                final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
-                if (editor.getRawContactId() == rawContactId) {
-                    return editor;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if there is currently more than one photo on screen.
-     */
-    private boolean hasMoreThanOnePhoto() {
-        int countWithPicture = 0;
-        final int numEntities = mState.size();
-        for (int i = 0; i < numEntities; i++) {
-            final RawContactDelta entity = mState.get(i);
-            if (entity.isVisible()) {
-                final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
-                if (primary != null && primary.getPhoto() != null) {
-                    countWithPicture++;
-                } else {
-                    final long rawContactId = entity.getRawContactId();
-                    final Uri uri = mUpdatedPhotos.getParcelable(String.valueOf(rawContactId));
-                    if (uri != null) {
-                        try {
-                            mContext.getContentResolver().openInputStream(uri);
-                            countWithPicture++;
-                        } catch (FileNotFoundException e) {
-                        }
-                    }
-                }
-
-                if (countWithPicture > 1) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Custom photo handler for the editor.  The inner listener that this creates also has a
-     * reference to the editor and acts as an {@link EditorListener}, and uses that editor to hold
-     * state information in several of the listener methods.
-     */
-    private final class PhotoHandler extends PhotoSelectionHandler {
-
-        final long mRawContactId;
-        private final BaseRawContactEditorView mEditor;
-        private final PhotoActionListener mPhotoEditorListener;
-
-        public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
-                RawContactDeltaList state) {
-            super(context, editor.getPhotoEditor().getChangeAnchorView(), photoMode, false, state);
-            mEditor = editor;
-            mRawContactId = editor.getRawContactId();
-            mPhotoEditorListener = new PhotoEditorListener();
-        }
-
-        @Override
-        public PhotoActionListener getListener() {
-            return mPhotoEditorListener;
-        }
-
-        @Override
-        public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) {
-            mRawContactIdRequestingPhoto = mEditor.getRawContactId();
-            mCurrentPhotoHandler = this;
-            mStatus = Status.SUB_ACTIVITY;
-            mCurrentPhotoUri = photoUri;
-            ContactEditorFragment.this.startActivityForResult(intent, requestCode);
-        }
-
-        private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
-                implements EditorListener {
-
-            @Override
-            public void onRequest(int request) {
-                if (!hasValidState()) return;
-
-                if (request == EditorListener.REQUEST_PICK_PHOTO) {
-                    onClick(mEditor.getPhotoEditor());
-                }
-                if (request == EditorListener.REQUEST_PICK_PRIMARY_PHOTO) {
-                    useAsPrimaryChosen();
-                }
-            }
-
-            @Override
-            public void onDeleteRequested(Editor removedEditor) {
-                // The picture cannot be deleted, it can only be removed, which is handled by
-                // onRemovePictureChosen()
-            }
-
-            /**
-             * User has chosen to set the selected photo as the (super) primary photo
-             */
-            public void useAsPrimaryChosen() {
-                // Set the IsSuperPrimary for each editor
-                int count = mContent.getChildCount();
-                for (int i = 0; i < count; i++) {
-                    final View childView = mContent.getChildAt(i);
-                    if (childView instanceof BaseRawContactEditorView) {
-                        final BaseRawContactEditorView editor =
-                                (BaseRawContactEditorView) childView;
-                        final PhotoEditorView photoEditor = editor.getPhotoEditor();
-                        photoEditor.setSuperPrimary(editor == mEditor);
-                    }
-                }
-                bindEditors();
-            }
-
-            /**
-             * User has chosen to remove a picture
-             */
-            @Override
-            public void onRemovePictureChosen() {
-                mEditor.setPhotoEntry(null);
-
-                // Prevent bitmap from being restored if rotate the device.
-                // (only if we first chose a new photo before removing it)
-                mUpdatedPhotos.remove(String.valueOf(mRawContactId));
-                bindEditors();
-            }
-
-            @Override
-            public void onPhotoSelected(Uri uri) throws FileNotFoundException {
-                final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(mContext, uri);
-                setPhoto(mRawContactId, bitmap, uri);
-                mCurrentPhotoHandler = null;
-                bindEditors();
-            }
-
-            @Override
-            public Uri getCurrentPhotoUri() {
-                return mCurrentPhotoUri;
-            }
-
-            @Override
-            public void onPhotoSelectionDismissed() {
-                // Nothing to do.
-            }
-        }
-    }
-}
diff --git a/src/com/android/contacts/editor/EditorIntents.java b/src/com/android/contacts/editor/EditorIntents.java
index badc697..74120e6 100644
--- a/src/com/android/contacts/editor/EditorIntents.java
+++ b/src/com/android/contacts/editor/EditorIntents.java
@@ -24,8 +24,6 @@
 import android.text.TextUtils;
 
 import com.android.contacts.activities.CompactContactEditorActivity;
-import com.android.contacts.activities.ContactEditorActivity;
-import com.android.contacts.activities.ContactEditorBaseActivity;
 import com.android.contacts.common.model.RawContactDeltaList;
 import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
 
@@ -70,7 +68,8 @@
             /* Bundle updatedPhotos, */ boolean isNewLocalProfile) {
         final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI,
                 context, CompactContactEditorActivity.class);
-        intent.putExtra(ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE, isNewLocalProfile);
+        intent.putExtra(
+                ContactEditorBaseFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE, isNewLocalProfile);
         if (rawContactDeltaList != null || displayName != null || phoneticName != null) {
             putRawContactDeltaValues(intent, rawContactDeltaList, displayName, phoneticName);
         }
@@ -78,16 +77,16 @@
     }
 
     /**
-     * Returns an Intent to edit a different contact (in the fully expaned editor) with whatever
+     * Returns an Intent to edit a different contact in the compact editor with whatever
      * values were already entered on the currently displayed contact editor.
      */
     public static Intent createEditOtherContactIntent(Context context, Uri contactLookupUri,
             ArrayList<ContentValues> contentValues) {
         final Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri, context,
-                ContactEditorActivity.class);
+                CompactContactEditorActivity.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(ContactEditorBaseFragment.INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY, "");
 
         // Pass on all the data that has been entered so far
         if (contentValues != null && contentValues.size() != 0) {
@@ -97,42 +96,13 @@
     }
 
     /**
-     * Returns an Intent to start the fully expanded {@link ContactEditorActivity} for an
-     * existing contact.
-     */
-    public static Intent createEditContactIntent(Context context, Uri contactLookupUri,
-            MaterialPalette materialPalette, long photoId) {
-        final Intent intent = new Intent(ContactEditorBaseActivity.ACTION_EDIT, contactLookupUri,
-                context, ContactEditorActivity.class);
-        addContactIntentFlags(intent);
-        putMaterialPalette(intent, materialPalette);
-        putPhotoId(intent, photoId);
-        return intent;
-    }
-
-    /**
-     * Returns an Intent to start the fully expanded {@link ContactEditorActivity} for a
-     * new contact.
-     */
-    public static Intent createInsertContactIntent(Context context,
-            RawContactDeltaList rawContactDeltaList, String displayName, String phoneticName,
-            boolean isNewLocalProfile) {
-        final Intent intent = new Intent(ContactEditorBaseActivity.ACTION_INSERT,
-                Contacts.CONTENT_URI, context, ContactEditorActivity.class);
-        intent.putExtra(ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE, isNewLocalProfile);
-        addContactIntentFlags(intent);
-        putRawContactDeltaValues(intent, rawContactDeltaList, displayName, phoneticName);
-        return intent;
-    }
-
-    /**
      * Returns an Intent to start the compact editor for the given raw contact.
      */
     public static Intent createEditContactIntentForRawContact(Context context,
             Uri contactLookupUri, long rawContactId, boolean isReadOnly) {
         final Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri, context,
                 CompactContactEditorActivity.class);
-        intent.putExtra(ContactEditorFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE,
+        intent.putExtra(ContactEditorBaseFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE,
                 rawContactId);
         intent.putExtra(
                 ContactEditorBaseFragment.INTENT_EXTRA_RAW_CONTACT_DISPLAY_ALONE_IS_READ_ONLY,
@@ -140,11 +110,6 @@
         return intent;
     }
 
-    private static void addContactIntentFlags(Intent intent) {
-        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-    }
-
     private static void putMaterialPalette(Intent intent, MaterialPalette materialPalette) {
         if (materialPalette != null) {
             intent.putExtra(ContactEditorBaseFragment.INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR,
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
deleted file mode 100644
index 5a4c9db..0000000
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2009 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.editor;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.contacts.GroupMetaDataLoader;
-import com.android.contacts.R;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountType.EditType;
-import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.common.model.RawContactDelta;
-import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.common.model.RawContactModifier;
-
-import com.google.common.base.Objects;
-
-import java.util.ArrayList;
-
-/**
- * Custom view that provides all the editor interaction for a specific
- * {@link Contacts} represented through an {@link RawContactDelta}. Callers can
- * reuse this view and quickly rebuild its contents through
- * {@link #setState(RawContactDelta, AccountType, ViewIdGenerator)}.
- * <p>
- * Internal updates are performed against {@link ValuesDelta} so that the
- * source {@link RawContact} can be swapped out. Any state-based changes, such as
- * adding {@link Data} rows or changing {@link EditType}, are performed through
- * {@link RawContactModifier} to ensure that {@link AccountType} are enforced.
- */
-public class RawContactEditorView extends BaseRawContactEditorView {
-    private static final String KEY_SUPER_INSTANCE_STATE = "superInstanceState";
-
-    private LayoutInflater mInflater;
-
-    private StructuredNameEditorView mName;
-    private PhoneticNameEditorView mPhoneticName;
-    private TextFieldsEditorView mNickName;
-
-    private GroupMembershipView mGroupMembershipView;
-
-    private ViewGroup mFields;
-
-    private View mAccountSelector;
-    private TextView mAccountSelectorTypeTextView;
-    private TextView mAccountSelectorNameTextView;
-
-    private View mAccountHeader;
-    private TextView mAccountHeaderTypeTextView;
-    private TextView mAccountHeaderNameTextView;
-    private ImageView mAccountIconImageView;
-
-    private long mRawContactId = -1;
-    private boolean mAutoAddToDefaultGroup = true;
-    private Cursor mGroupMetaData;
-    private DataKind mGroupMembershipKind;
-    private RawContactDelta mState;
-
-    public RawContactEditorView(Context context) {
-        super(context);
-    }
-
-    public RawContactEditorView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        super.setEnabled(enabled);
-
-        View view = getPhotoEditor();
-        if (view != null) {
-            view.setEnabled(enabled);
-        }
-
-        if (mName != null) {
-            mName.setEnabled(enabled);
-        }
-
-        if (mPhoneticName != null) {
-            mPhoneticName.setEnabled(enabled);
-        }
-
-        if (mFields != null) {
-            int count = mFields.getChildCount();
-            for (int i = 0; i < count; i++) {
-                mFields.getChildAt(i).setEnabled(enabled);
-            }
-        }
-
-        if (mGroupMembershipView != null) {
-            mGroupMembershipView.setEnabled(enabled);
-        }
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        mInflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        mName = (StructuredNameEditorView)findViewById(R.id.edit_name);
-        mName.setDeletable(false);
-
-        mPhoneticName = (PhoneticNameEditorView)findViewById(R.id.edit_phonetic_name);
-        mPhoneticName.setDeletable(false);
-
-        mNickName = (TextFieldsEditorView)findViewById(R.id.edit_nick_name);
-
-        mFields = (ViewGroup)findViewById(R.id.sect_fields);
-
-        mAccountHeader = findViewById(R.id.account_header_container);
-        mAccountHeaderTypeTextView = (TextView) findViewById(R.id.account_type);
-        mAccountHeaderNameTextView = (TextView) findViewById(R.id.account_name);
-        mAccountIconImageView = (ImageView) findViewById(android.R.id.icon);
-
-        // The same header is used by both full editor and read-only editor view. The header is
-        // left-aligned with read-only editor view but is not aligned well with full editor. So we
-        // need to shift the text in the header a little bit for full editor.
-        LinearLayout accountInfoView = (LinearLayout) findViewById(R.id.account_info);
-        final int topBottomPaddingDp = (int) getResources().getDimension(R.dimen
-                .editor_account_header_expandable_top_bottom_padding);
-        final int leftPaddingDp = (int) getResources().getDimension(R.dimen
-                .editor_account_header_expandable_left_padding);
-        accountInfoView.setPadding(leftPaddingDp, topBottomPaddingDp, 0, topBottomPaddingDp);
-
-        mAccountSelector = findViewById(R.id.account_selector_container);
-        mAccountSelectorTypeTextView = (TextView) findViewById(R.id.account_type_selector);
-        mAccountSelectorNameTextView = (TextView) findViewById(R.id.account_name_selector);
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Bundle bundle = new Bundle();
-        // super implementation of onSaveInstanceState returns null
-        bundle.putParcelable(KEY_SUPER_INSTANCE_STATE, super.onSaveInstanceState());
-        return bundle;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        if (state instanceof Bundle) {
-            Bundle bundle = (Bundle) state;
-            super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPER_INSTANCE_STATE));
-            return;
-        }
-        super.onRestoreInstanceState(state);
-    }
-
-    /**
-     * Set the internal state for this view, given a current
-     * {@link RawContactDelta} state and the {@link AccountType} that
-     * apply to that state.
-     */
-    @Override
-    public void setState(RawContactDelta state, AccountType type, ViewIdGenerator vig,
-            boolean isProfile) {
-
-        mState = state;
-
-        // Remove any existing sections
-        mFields.removeAllViews();
-
-        // Bail if invalid state or account type
-        if (state == null || type == null) return;
-
-        setId(vig.getId(state, null, null, ViewIdGenerator.NO_VIEW_INDEX));
-
-        // Make sure we have a StructuredName
-        RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
-
-        mRawContactId = state.getRawContactId();
-
-        // Fill in the account info
-        final Pair<String,String> accountInfo = isProfile
-                ? EditorUiUtils.getLocalAccountInfo(getContext(), state.getAccountName(), type)
-                : EditorUiUtils.getAccountInfo(getContext(), state.getAccountName(), type);
-        if (accountInfo.first == null) {
-            // Hide this view so the other text view will be centered vertically
-            mAccountHeaderNameTextView.setVisibility(View.GONE);
-        } else {
-            mAccountHeaderNameTextView.setVisibility(View.VISIBLE);
-            mAccountHeaderNameTextView.setText(accountInfo.first);
-        }
-        mAccountHeaderTypeTextView.setText(accountInfo.second);
-        updateAccountHeaderContentDescription();
-
-        // The account selector and header are both used to display the same information.
-        mAccountSelectorTypeTextView.setText(mAccountHeaderTypeTextView.getText());
-        mAccountSelectorTypeTextView.setVisibility(mAccountHeaderTypeTextView.getVisibility());
-        mAccountSelectorNameTextView.setText(mAccountHeaderNameTextView.getText());
-        mAccountSelectorNameTextView.setVisibility(mAccountHeaderNameTextView.getVisibility());
-        // Showing the account header at the same time as the account selector drop down is
-        // confusing. They should be mutually exclusive.
-        mAccountHeader.setVisibility(mAccountSelector.getVisibility() == View.GONE
-                ? View.VISIBLE : View.GONE);
-
-        mAccountIconImageView.setImageDrawable(state.getRawContactAccountType(getContext())
-                .getDisplayIcon(getContext()));
-
-        // Show photo editor when supported
-        RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
-        setHasPhotoEditor((type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null));
-        getPhotoEditor().setEnabled(isEnabled());
-        mName.setEnabled(isEnabled());
-
-        mPhoneticName.setEnabled(isEnabled());
-
-        // Show and hide the appropriate views
-        mFields.setVisibility(View.VISIBLE);
-        mName.setVisibility(View.VISIBLE);
-        mPhoneticName.setVisibility(View.VISIBLE);
-
-        mGroupMembershipKind = type.getKindForMimetype(GroupMembership.CONTENT_ITEM_TYPE);
-        if (mGroupMembershipKind != null) {
-            mGroupMembershipView = (GroupMembershipView)mInflater.inflate(
-                    R.layout.item_group_membership, mFields, false);
-            mGroupMembershipView.setKind(mGroupMembershipKind);
-            mGroupMembershipView.setEnabled(isEnabled());
-        }
-
-        // Create editor sections for each possible data kind
-        for (DataKind kind : type.getSortedDataKinds()) {
-            // Skip kind of not editable
-            if (!kind.editable) continue;
-
-            final String mimeType = kind.mimeType;
-            if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                // Handle special case editor for structured name
-                final ValuesDelta primary = state.getPrimaryEntry(mimeType);
-                mName.setValues(
-                        type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME),
-                        primary, state, false, vig);
-                mPhoneticName.setValues(
-                        type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME),
-                        primary, state, false, vig);
-                // It is useful to use Nickname outside of a KindSectionView so that we can treat it
-                // as a part of StructuredName's fake KindSectionView, even though it uses a
-                // different CP2 mime-type. We do a bit of extra work below to make this possible.
-                final DataKind nickNameKind = type.getKindForMimetype(Nickname.CONTENT_ITEM_TYPE);
-                if (nickNameKind != null) {
-                    ValuesDelta primaryNickNameEntry = state.getPrimaryEntry(nickNameKind.mimeType);
-                    if (primaryNickNameEntry == null) {
-                        primaryNickNameEntry = RawContactModifier.insertChild(state, nickNameKind);
-                    }
-                    mNickName.setValues(nickNameKind, primaryNickNameEntry, state, false, vig);
-                    mNickName.setDeletable(false);
-                } else {
-                    mPhoneticName.setPadding(0, 0, 0, (int) getResources().getDimension(
-                            R.dimen.editor_padding_between_editor_views));
-                    mNickName.setVisibility(View.GONE);
-                }
-            } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                // Handle special case editor for photos
-                final ValuesDelta primary = state.getPrimaryEntry(mimeType);
-                getPhotoEditor().setValues(kind, primary, state, false, vig);
-            } else if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                if (mGroupMembershipView != null) {
-                    mGroupMembershipView.setState(state);
-                    mFields.addView(mGroupMembershipView);
-                }
-            } else if (DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME.equals(mimeType)
-                    || DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)
-                    || Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                // Don't create fields for each of these mime-types. They are handled specially.
-                continue;
-            } else {
-                // Otherwise use generic section-based editors
-                if (kind.fieldList == null) continue;
-                final KindSectionView section = (KindSectionView)mInflater.inflate(
-                        R.layout.item_kind_section, mFields, false);
-                section.setEnabled(isEnabled());
-                section.setState(kind, state, /* readOnly =*/ false, vig);
-                mFields.addView(section);
-            }
-        }
-
-        addToDefaultGroupIfNeeded();
-    }
-
-    @Override
-    public void setGroupMetaData(Cursor groupMetaData) {
-        mGroupMetaData = groupMetaData;
-        addToDefaultGroupIfNeeded();
-        if (mGroupMembershipView != null) {
-            mGroupMembershipView.setGroupMetaData(groupMetaData);
-        }
-    }
-
-    public void setAutoAddToDefaultGroup(boolean flag) {
-        this.mAutoAddToDefaultGroup = flag;
-    }
-
-    /**
-     * If automatic addition to the default group was requested (see
-     * {@link #setAutoAddToDefaultGroup}, checks if the raw contact is in any
-     * group and if it is not adds it to the default group (in case of Google
-     * contacts that's "My Contacts").
-     */
-    private void addToDefaultGroupIfNeeded() {
-        if (!mAutoAddToDefaultGroup || mGroupMetaData == null || mGroupMetaData.isClosed()
-                || mState == null) {
-            return;
-        }
-
-        boolean hasGroupMembership = false;
-        ArrayList<ValuesDelta> entries = mState.getMimeEntries(GroupMembership.CONTENT_ITEM_TYPE);
-        if (entries != null) {
-            for (ValuesDelta values : entries) {
-                Long id = values.getGroupRowId();
-                if (id != null && id.longValue() != 0) {
-                    hasGroupMembership = true;
-                    break;
-                }
-            }
-        }
-
-        if (!hasGroupMembership) {
-            long defaultGroupId = getDefaultGroupId();
-            if (defaultGroupId != -1) {
-                ValuesDelta entry = RawContactModifier.insertChild(mState, mGroupMembershipKind);
-                if (entry != null) {
-                    entry.setGroupRowId(defaultGroupId);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the default group (e.g. "My Contacts") for the current raw contact's
-     * account.  Returns -1 if there is no such group.
-     */
-    private long getDefaultGroupId() {
-        String accountType = mState.getAccountType();
-        String accountName = mState.getAccountName();
-        String accountDataSet = mState.getDataSet();
-        mGroupMetaData.moveToPosition(-1);
-        while (mGroupMetaData.moveToNext()) {
-            String name = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_NAME);
-            String type = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
-            String dataSet = mGroupMetaData.getString(GroupMetaDataLoader.DATA_SET);
-            if (name.equals(accountName) && type.equals(accountType)
-                    && Objects.equal(dataSet, accountDataSet)) {
-                long groupId = mGroupMetaData.getLong(GroupMetaDataLoader.GROUP_ID);
-                if (!mGroupMetaData.isNull(GroupMetaDataLoader.AUTO_ADD)
-                            && mGroupMetaData.getInt(GroupMetaDataLoader.AUTO_ADD) != 0) {
-                    return groupId;
-                }
-            }
-        }
-        return -1;
-    }
-
-    public StructuredNameEditorView getNameEditor() {
-        return mName;
-    }
-
-    public TextFieldsEditorView getPhoneticNameEditor() {
-        return mPhoneticName;
-    }
-
-    public TextFieldsEditorView getNickNameEditor() {
-        return mNickName;
-    }
-
-    @Override
-    public long getRawContactId() {
-        return mRawContactId;
-    }
-}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 376fa22..35b86b2 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -63,9 +63,9 @@
 import android.provider.ContactsContract.CommonDataKinds.Website;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.DataUsageFeedback;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.DataUsageFeedback;
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.RawContacts;
@@ -129,8 +129,10 @@
 import com.android.contacts.common.model.Contact;
 import com.android.contacts.common.model.ContactLoader;
 import com.android.contacts.common.model.RawContact;
+import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.model.dataitem.CustomDataItem;
 import com.android.contacts.common.model.dataitem.DataItem;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.common.model.dataitem.EmailDataItem;
@@ -145,10 +147,8 @@
 import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
 import com.android.contacts.common.model.dataitem.StructuredPostalDataItem;
 import com.android.contacts.common.model.dataitem.WebsiteDataItem;
-import com.android.contacts.common.model.dataitem.CustomDataItem;
-import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.common.util.DateUtils;
+import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.common.util.MaterialColorMapUtils;
 import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
 import com.android.contacts.common.util.PermissionsUtil;
@@ -157,7 +157,7 @@
 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.ContactEditorBaseFragment;
 import com.android.contacts.editor.EditorIntents;
 import com.android.contacts.interactions.CalendarInteractionsLoader;
 import com.android.contacts.interactions.CallLogInteractionsLoader;
@@ -178,10 +178,8 @@
 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.lang.SecurityException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -2996,7 +2994,7 @@
                     intent.putExtra(Intents.Insert.DATA, values);
 
                     // If the contact can only export to the same account, add it to the intent.
-                    // Otherwise the ContactEditorFragment will show a dialog for selecting an
+                    // Otherwise the ContactEditorBaseFragment will show a dialog for selecting an
                     // account.
                     if (mContactData.getDirectoryExportSupport() ==
                             Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY) {
@@ -3009,7 +3007,8 @@
 
                     // Add this flag to disable the delete menu option on directory contact joins
                     // with local contacts. The delete option is ambiguous when joining contacts.
-                    intent.putExtra(ContactEditorFragment.INTENT_EXTRA_DISABLE_DELETE_MENU_OPTION,
+                    intent.putExtra(
+                            ContactEditorBaseFragment.INTENT_EXTRA_DISABLE_DELETE_MENU_OPTION,
                             true);
 
                     intent.setPackage(getPackageName());