Merge "Don't do the LIMIT as part of SORT_BY, but pass it into its own parameter"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a57ac3a..07de004 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1337,9 +1337,6 @@
     <!-- The editable field hint text to add a new website to a contact in the Raw Contact Editor [CHAR LIMIT=22] -->
     <string name="add_website">Add new website</string>
 
-    <!-- The editable field hint text to add a new internet call method to a contact in the Raw Contact Editor [CHAR LIMIT=22] -->
-    <string name="add_internet_call">Add new internet call</string>
-
     <!-- The editable field hint text to add a new event to a contact in the Raw Contact Editor [CHAR LIMIT=22] -->
     <string name="add_event">Add new event</string>
 
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index ab13a4b..a70bf3f 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -27,9 +27,7 @@
  * {@link ValuesDelta} object.
  */
 public interface Editor {
-    /**
-     * Listener for an {@link Editor}, usually to handle deleted items.
-     */
+
     public interface EditorListener {
         /**
          * Called when the given {@link Editor} has been deleted.
@@ -44,17 +42,18 @@
 
         public static final int REQUEST_PICK_PHOTO = 1;
         public static final int FIELD_CHANGED = 2;
+        public static final int FIELD_TURNED_EMPTY = 3;
+        public static final int FIELD_TURNED_NON_EMPTY = 4;
 
         // The editor has switched between different representations of the same
         // data, e.g. from full name to structured name
-        public static final int EDITOR_FORM_CHANGED = 3;
+        public static final int EDITOR_FORM_CHANGED = 5;
     }
 
     /**
-     * Returns whether or not there is at least one empty field (i.e. text
-     * fields) in this {@link Editor}.
+     * Returns whether or not all the fields are empty in this {@link Editor}.
      */
-    public boolean hasEmptyField();
+    public boolean isEmpty();
 
     /**
      * Prepares this editor for the given {@link ValuesDelta}, which
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index a83a9c8..dcce085 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -110,7 +110,8 @@
         mDateView.setText(data);
     }
 
-    public boolean hasEmptyField() {
+    @Override
+    public boolean isEmpty() {
         return TextUtils.isEmpty(mDateView.getText());
     }
 
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index e24acff..b472279 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -24,16 +24,6 @@
 import com.android.contacts.model.EntityModifier;
 
 import android.content.Context;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Event;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Note;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Relation;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Website;
-import android.provider.ContactsContract.Data;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
@@ -43,7 +33,6 @@
 import android.widget.TextView;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -67,31 +56,6 @@
 
     private LayoutInflater mInflater;
 
-    /**
-     * Map of data MIME types to the "add field" footer text resource ID
-     * (that for example, maps to "Add new phone number").
-     */
-    private static final HashMap<String, Integer> sAddFieldFooterTextResourceIds =
-            new HashMap<String, Integer>();
-
-    static {
-        final HashMap<String, Integer> hashMap = sAddFieldFooterTextResourceIds;
-        hashMap.put(Phone.CONTENT_ITEM_TYPE, R.string.add_phone);
-        hashMap.put(Email.CONTENT_ITEM_TYPE, R.string.add_email);
-        hashMap.put(Im.CONTENT_ITEM_TYPE, R.string.add_im);
-        hashMap.put(StructuredPostal.CONTENT_ITEM_TYPE, R.string.add_address);
-        hashMap.put(Note.CONTENT_ITEM_TYPE, R.string.add_note);
-        hashMap.put(Website.CONTENT_ITEM_TYPE, R.string.add_website);
-        hashMap.put(SipAddress.CONTENT_ITEM_TYPE, R.string.add_internet_call);
-        hashMap.put(Event.CONTENT_ITEM_TYPE, R.string.add_event);
-        hashMap.put(Relation.CONTENT_ITEM_TYPE, R.string.add_relationship);
-    }
-
-    /**
-     * List of the empty editor views.
-     */
-    private List<View> mEmptyEditorViews = new ArrayList<View>();
-
     public KindSectionView(Context context) {
         this(context, null);
     }
@@ -152,8 +116,9 @@
     /** {@inheritDoc} */
     @Override
     public void onRequest(int request) {
-        // If a field has changed, then check if another row can be added dynamically.
-        if (request == FIELD_CHANGED) {
+        // If a field has become empty or non-empty, then check if another row
+        // can be added dynamically.
+        if (request == FIELD_TURNED_EMPTY || request == FIELD_TURNED_NON_EMPTY) {
             updateAddFooterVisible();
         }
     }
@@ -172,11 +137,10 @@
                 : getResources().getString(kind.titleRes);
 
         // Set "add field" footer message according to MIME type. Some MIME types
-        // can only have max 1 field, so the map will return null if these sections
+        // can only have max 1 field, so the resource ID will be -1 if these sections
         // should not have an "Add field" option.
-        Integer textResourceId = sAddFieldFooterTextResourceIds.get(kind.mimeType);
-        if (textResourceId != null) {
-            mAddFieldText.setText(textResourceId);
+        if (kind.addNewFieldTextResourceId != -1) {
+            mAddFieldText.setText(getResources().getString(kind.addNewFieldTextResourceId));
         }
 
         rebuildFromState();
@@ -222,7 +186,8 @@
         } catch (Exception e) {
             throw new RuntimeException(
                     "Cannot allocate editor with layout resource ID " +
-                    mKind.editorLayoutResourceId);
+                    mKind.editorLayoutResourceId + " for MIME type " + mKind.mimeType +
+                    " with error " + e.toString());
         }
 
         view.setEnabled(isEnabled());
@@ -270,24 +235,15 @@
     }
 
     /**
-     * Determines a list of {@link Editor} {@link View}s that have an empty
-     * field in them and removes extra ones, so there is max 1 empty
-     * {@link Editor} {@link View} at a time.
+     * Updates the editors being displayed to the user removing extra empty
+     * {@link Editor}s, so there is only max 1 empty {@link Editor} view at a time.
      */
     private void updateEmptyEditors() {
-        mEmptyEditorViews.clear();
-
-        // Construct a list of editors that have an empty field in them.
-        for (int i = 0; i < mEditors.getChildCount(); i++) {
-            View v = mEditors.getChildAt(i);
-            if (((Editor) v).hasEmptyField()) {
-                mEmptyEditorViews.add(v);
-            }
-        }
+        List<View> emptyEditors = getEmptyEditors();
 
         // If there is more than 1 empty editor, then remove it from the list of editors.
-        if (mEmptyEditorViews.size() > 1) {
-            for (View emptyEditorView : mEmptyEditorViews) {
+        if (emptyEditors.size() > 1) {
+            for (View emptyEditorView : emptyEditors) {
                 // If no child {@link View}s are being focused on within
                 // this {@link View}, then remove this empty editor.
                 if (emptyEditorView.findFocus() == null) {
@@ -298,16 +254,30 @@
     }
 
     /**
-     * Returns true if one of the editors has an empty field, or false
+     * Returns a list of empty editor views in this section.
+     */
+    private List<View> getEmptyEditors() {
+        List<View> emptyEditorViews = new ArrayList<View>();
+        for (int i = 0; i < mEditors.getChildCount(); i++) {
+            View view = mEditors.getChildAt(i);
+            if (((Editor) view).isEmpty()) {
+                emptyEditorViews.add(view);
+            }
+        }
+        return emptyEditorViews;
+    }
+
+    /**
+     * Returns true if one of the editors has all of its fields empty, or false
      * otherwise.
      */
     private boolean hasEmptyEditor() {
-        return mEmptyEditorViews.size() > 0;
+        return getEmptyEditors().size() > 0;
     }
 
     public void addItem() {
         ValuesDelta values = null;
-        // if this is a list, we can freely add. if not, only allow adding the first
+        // If this is a list, we can freely add. If not, only allow adding the first.
         if (!mKind.isList) {
             if (getEditorCount() == 1) {
                 return;
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 9d418d0..db80580 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -72,6 +72,7 @@
     private ValuesDelta mEntry;
     private EntityDelta mState;
     private boolean mReadOnly;
+    private boolean mWasEmpty = true;
 
     private EditType mType;
 
@@ -258,6 +259,16 @@
         if (mListener != null) {
             mListener.onRequest(EditorListener.FIELD_CHANGED);
         }
+
+        boolean isEmpty = isEmpty();
+        if (mWasEmpty != isEmpty) {
+            if (isEmpty) {
+                mListener.onRequest(EditorListener.FIELD_TURNED_EMPTY);
+            } else {
+                mListener.onRequest(EditorListener.FIELD_TURNED_NON_EMPTY);
+            }
+            mWasEmpty = isEmpty;
+        }
     }
 
     protected boolean isFieldChanged(String column, String value) {
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 242e3b5..7b86291 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -179,7 +179,8 @@
         // Photo is not deletable
     }
 
-    public boolean hasEmptyField() {
-        return mHasSetPhoto;
+    @Override
+    public boolean isEmpty() {
+        return !mHasSetPhoto;
     }
 }
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 39bfa80..9b93700 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -234,14 +234,15 @@
         mExpansionButton.setEnabled(!readOnly && isEnabled());
     }
 
-    public boolean hasEmptyField() {
+    @Override
+    public boolean isEmpty() {
         for (int i = 0; i < mFields.getChildCount(); i++) {
             EditText editText = (EditText) mFields.getChildAt(i);
-            if (TextUtils.isEmpty(editText.getText())) {
-                return true;
+            if (!TextUtils.isEmpty(editText.getText())) {
+                return false;
             }
         }
-        return false;
+        return true;
     }
 
     /**
diff --git a/src/com/android/contacts/model/BaseAccountType.java b/src/com/android/contacts/model/BaseAccountType.java
index d4a7496..3196876 100644
--- a/src/com/android/contacts/model/BaseAccountType.java
+++ b/src/com/android/contacts/model/BaseAccountType.java
@@ -99,7 +99,7 @@
 
     protected DataKind addDataKindStructuredName(Context context) {
         DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
-                R.string.nameLabelsGroup, -1, -1, true));
+                R.string.nameLabelsGroup, -1, -1, true, R.layout.structured_name_editor_view, -1));
         kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
         kind.actionBody = new SimpleInflater(Nickname.NAME);
 
@@ -128,7 +128,7 @@
 
     protected DataKind addDataKindDisplayName(Context context) {
         DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME,
-                R.string.nameLabelsGroup, -1, -1, true));
+                R.string.nameLabelsGroup, -1, -1, true, R.layout.text_fields_editor_view, -1));
         kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
         kind.actionBody = new SimpleInflater(Nickname.NAME);
 
@@ -168,7 +168,7 @@
 
     protected DataKind addDataKindPhoneticName(Context context) {
         DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME,
-                R.string.name_phonetic, -1, -1, true));
+                R.string.name_phonetic, -1, -1, true, R.layout.phonetic_name_editor_view, -1));
         kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
         kind.actionBody = new SimpleInflater(Nickname.NAME);
 
@@ -187,8 +187,8 @@
 
     protected DataKind addDataKindNickname(Context context) {
         DataKind kind = addKind(new DataKind(Nickname.CONTENT_ITEM_TYPE,
-                    R.string.nicknameLabelsGroup, -1, 115, true));
-
+                    R.string.nicknameLabelsGroup, -1, 115, true,
+                    R.layout.text_fields_editor_view, -1));
         kind.isList = false;
         kind.actionHeader = new SimpleInflater(R.string.nicknameLabelsGroup);
         kind.actionBody = new SimpleInflater(Nickname.NAME);
@@ -204,7 +204,8 @@
 
     protected DataKind addDataKindPhone(Context context) {
         DataKind kind = addKind(new DataKind(Phone.CONTENT_ITEM_TYPE, R.string.phoneLabelsGroup,
-                android.R.drawable.sym_action_call, 10, true));
+                android.R.drawable.sym_action_call, 10, true,
+                R.layout.text_fields_editor_view, R.string.add_phone));
         kind.iconAltRes = R.drawable.sym_action_sms;
         kind.actionHeader = new PhoneActionInflater();
         kind.actionAltHeader = new PhoneActionAltInflater();
@@ -243,7 +244,8 @@
 
     protected DataKind addDataKindEmail(Context context) {
         DataKind kind = addKind(new DataKind(Email.CONTENT_ITEM_TYPE, R.string.emailLabelsGroup,
-                R.drawable.sym_action_email_holo_light, 15, true));
+                R.drawable.sym_action_email_holo_light, 15, true,
+                R.layout.text_fields_editor_view, R.string.add_email));
         kind.actionHeader = new EmailActionInflater();
         kind.actionBody = new SimpleInflater(Email.DATA);
         kind.typeColumn = Email.TYPE;
@@ -264,7 +266,7 @@
     protected DataKind addDataKindStructuredPostal(Context context) {
         DataKind kind = addKind(new DataKind(StructuredPostal.CONTENT_ITEM_TYPE,
                 R.string.postalLabelsGroup, R.drawable.sym_action_show_map_holo_light, 25,
-                true));
+                true, R.layout.text_fields_editor_view, R.string.add_address));
         kind.actionHeader = new PostalActionInflater();
         kind.actionBody = new SimpleInflater(StructuredPostal.FORMATTED_ADDRESS);
         kind.typeColumn = StructuredPostal.TYPE;
@@ -285,7 +287,8 @@
 
     protected DataKind addDataKindIm(Context context) {
         DataKind kind = addKind(new DataKind(Im.CONTENT_ITEM_TYPE, R.string.imLabelsGroup,
-                    R.drawable.sym_action_talk_holo_light, 20, true));
+                    R.drawable.sym_action_talk_holo_light, 20, true,
+                    R.layout.text_fields_editor_view, R.string.add_im));
         kind.actionHeader = new ImActionInflater();
         kind.actionBody = new SimpleInflater(Im.DATA);
 
@@ -316,7 +319,8 @@
 
     protected DataKind addDataKindOrganization(Context context) {
         DataKind kind = addKind(new DataKind(Organization.CONTENT_ITEM_TYPE,
-                    R.string.organizationLabelsGroup, -1, 5, true));
+                    R.string.organizationLabelsGroup, -1, 5, true,
+                    R.layout.text_fields_editor_view, -1));
         kind.actionHeader = new SimpleInflater(Organization.COMPANY);
         kind.actionBody = new SimpleInflater(Organization.TITLE);
         kind.isList = false;
@@ -331,7 +335,7 @@
     }
 
     protected DataKind addDataKindPhoto(Context context) {
-        DataKind kind = addKind(new DataKind(Photo.CONTENT_ITEM_TYPE, -1, -1, -1, true));
+        DataKind kind = addKind(new DataKind(Photo.CONTENT_ITEM_TYPE, -1, -1, -1, true, -1, -1));
         kind.fieldList = Lists.newArrayList();
         kind.fieldList.add(new EditField(Photo.PHOTO, -1, -1));
         return kind;
@@ -339,7 +343,8 @@
 
     protected DataKind addDataKindNote(Context context) {
         DataKind kind = addKind(new DataKind(Note.CONTENT_ITEM_TYPE,
-                    R.string.label_notes, -1, 110, true));
+                    R.string.label_notes, -1, 110, true,
+                    R.layout.text_fields_editor_view, R.string.add_note));
         kind.isList = false;
         kind.actionHeader = new SimpleInflater(R.string.label_notes);
         kind.actionBody = new SimpleInflater(Note.NOTE);
@@ -352,7 +357,7 @@
     protected DataKind addDataKindWebsite(Context context) {
         DataKind kind = addKind(new DataKind(Website.CONTENT_ITEM_TYPE,
                 R.string.websiteLabelsGroup, R.drawable.sym_action_goto_website_holo_light, 120,
-                true));
+                true, R.layout.text_fields_editor_view, R.string.add_website));
         kind.actionHeader = new SimpleInflater(R.string.websiteLabelsGroup);
         kind.actionBody = new SimpleInflater(Website.URL);
         kind.defaultValues = new ContentValues();
@@ -374,7 +379,8 @@
         // the android:icon attribute of the SIP-related
         // intent-filters in the Phone app's manifest.
         DataKind kind = addKind(new DataKind(SipAddress.CONTENT_ITEM_TYPE,
-                    R.string.label_sip_address, android.R.drawable.sym_action_call, 130, true));
+                    R.string.label_sip_address, android.R.drawable.sym_action_call, 130, true,
+                    R.layout.text_fields_editor_view, -1));
 
         kind.isList = false;
         kind.actionHeader = new SimpleInflater(R.string.label_sip_address);
@@ -389,7 +395,7 @@
     protected DataKind addDataKindGroupMembership(Context context) {
         DataKind kind = getKindForMimetype(GroupMembership.CONTENT_ITEM_TYPE);
         kind = addKind(new DataKind(GroupMembership.CONTENT_ITEM_TYPE,
-                R.string.groupsLabel, android.R.drawable.sym_contact_card, 999, true));
+                R.string.groupsLabel, android.R.drawable.sym_contact_card, 999, true, -1, -1));
 
         kind.isList = false;
         kind.fieldList = Lists.newArrayList();
diff --git a/src/com/android/contacts/model/DataKind.java b/src/com/android/contacts/model/DataKind.java
index f17bc5a..73c1e45 100644
--- a/src/com/android/contacts/model/DataKind.java
+++ b/src/com/android/contacts/model/DataKind.java
@@ -56,12 +56,15 @@
 
     public ContentValues defaultValues;
 
+    /** Layout resource id for an editor view to edit this {@link DataKind}. */
+    public final int editorLayoutResourceId;
+
     /**
-     * Layout resource id for an editor {@link View} to edit this
-     * {@link DataKind}. The default is a text editor, but this can be
-     * overridden when a more appropriate XML layout is available.
+     * String resource id for the "add field" footer. This is equal to -1 if it
+     * is not applicable to add a new field to this class (i.e. for a structured
+     * name because a user should only have one structured name).
      */
-    public int editorLayoutResourceId = R.layout.text_fields_editor_view;
+    public final int addNewFieldTextResourceId;
 
     /**
      * If this is a date field, this specifies the format of the date when saving. The
@@ -78,14 +81,12 @@
     public SimpleDateFormat dateFormatWithYear;
 
     public DataKind() {
-    }
-
-    public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable) {
-        this(mimeType, titleRes, iconRes, weight, editable, R.layout.text_fields_editor_view);
+        editorLayoutResourceId = R.layout.text_fields_editor_view;
+        addNewFieldTextResourceId = -1;
     }
 
     public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable,
-            int editorLayoutResourceId) {
+            int editorLayoutResourceId, int addNewFieldTextResourceId) {
         this.mimeType = mimeType;
         this.titleRes = titleRes;
         this.iconRes = iconRes;
@@ -94,5 +95,6 @@
         this.isList = true;
         this.typeOverallMax = -1;
         this.editorLayoutResourceId = editorLayoutResourceId;
+        this.addNewFieldTextResourceId = addNewFieldTextResourceId;
     }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/model/ExchangeAccountType.java b/src/com/android/contacts/model/ExchangeAccountType.java
index b81eb50..2f6d781 100644
--- a/src/com/android/contacts/model/ExchangeAccountType.java
+++ b/src/com/android/contacts/model/ExchangeAccountType.java
@@ -17,7 +17,6 @@
 package com.android.contacts.model;
 
 import com.android.contacts.R;
-import com.android.contacts.editor.EventFieldEditorView;
 import com.android.contacts.util.DateUtils;
 import com.google.android.collect.Lists;
 
@@ -65,7 +64,8 @@
     @Override
     protected DataKind addDataKindStructuredName(Context context) {
         DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
-                R.string.nameLabelsGroup, -1, -1, true));
+                R.string.nameLabelsGroup, -1, -1, true,
+                R.layout.structured_name_editor_view, -1));
         kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
         kind.actionBody = new SimpleInflater(Nickname.NAME);
 
@@ -94,7 +94,8 @@
     @Override
     protected DataKind addDataKindDisplayName(Context context) {
         DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME,
-                R.string.nameLabelsGroup, -1, -1, true));
+                R.string.nameLabelsGroup, -1, -1, true,
+                R.layout.text_fields_editor_view, -1));
 
         boolean displayOrderPrimary =
                 context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
@@ -127,7 +128,8 @@
     @Override
     protected DataKind addDataKindPhoneticName(Context context) {
         DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME,
-                R.string.name_phonetic, -1, -1, true));
+                R.string.name_phonetic, -1, -1, true,
+                R.layout.phonetic_name_editor_view, -1));
         kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
         kind.actionBody = new SimpleInflater(Nickname.NAME);
 
@@ -292,7 +294,8 @@
 
     protected DataKind addDataKindEvent(Context context) {
         DataKind kind = addKind(
-                new DataKind(Event.CONTENT_ITEM_TYPE, R.string.eventLabelsGroup, -1, 150, true));
+                new DataKind(Event.CONTENT_ITEM_TYPE, R.string.eventLabelsGroup, -1, 150, true,
+                R.layout.event_field_editor_view, R.string.add_event));
         kind.actionHeader = new EventActionInflater();
         kind.actionBody = new SimpleInflater(Event.START_DATE);
 
@@ -303,7 +306,6 @@
         kind.typeList.add(buildEventType(Event.TYPE_BIRTHDAY, false).setSpecificMax(1));
 
         kind.dateFormatWithYear = DateUtils.DATE_AND_TIME_FORMAT;
-        kind.editorLayoutResourceId = R.layout.event_field_editor_view;
 
         kind.fieldList = Lists.newArrayList();
         kind.fieldList.add(new EditField(Event.DATA, R.string.eventLabelsGroup, FLAGS_EVENT));
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/GoogleAccountType.java
index 699f679..3d437cb 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/GoogleAccountType.java
@@ -17,7 +17,6 @@
 package com.android.contacts.model;
 
 import com.android.contacts.R;
-import com.android.contacts.editor.EventFieldEditorView;
 import com.android.contacts.util.DateUtils;
 import com.google.android.collect.Lists;
 
@@ -100,7 +99,8 @@
 
     private DataKind addDataKindRelation(Context context) {
         DataKind kind = addKind(new DataKind(Relation.CONTENT_ITEM_TYPE,
-                R.string.relationLabelsGroup, -1, 160, true));
+                R.string.relationLabelsGroup, -1, 160, true,
+                R.layout.text_fields_editor_view, R.string.add_relationship));
         kind.actionHeader = new RelationActionInflater();
         kind.actionBody = new SimpleInflater(Relation.NAME);
 
@@ -135,10 +135,10 @@
 
     private DataKind addDataKindEvent(Context context) {
         DataKind kind = addKind(new DataKind(Event.CONTENT_ITEM_TYPE,
-                    R.string.eventLabelsGroup, -1, 150, true));
+                    R.string.eventLabelsGroup, -1, 150, true,
+                    R.layout.event_field_editor_view, R.string.add_event));
         kind.actionHeader = new EventActionInflater();
         kind.actionBody = new SimpleInflater(Event.START_DATE);
-        kind.editorLayoutResourceId = R.layout.event_field_editor_view;
 
         kind.typeColumn = Event.TYPE;
         kind.typeList = Lists.newArrayList();
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
index 389041a..52a6cdf 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -82,13 +82,14 @@
             this.accountType = TEST_ACCOUNT_TYPE;
 
             final DataKind nameKind = new DataKind(StructuredName.CONTENT_ITEM_TYPE,
-                    R.string.nameLabelsGroup, -1, -1, true);
+                    R.string.nameLabelsGroup, -1, -1, true, -1, -1);
             nameKind.typeOverallMax = 1;
             addKind(nameKind);
 
             // Phone allows maximum 2 home, 1 work, and unlimited other, with
             // constraint of 5 numbers maximum.
-            final DataKind phoneKind = new DataKind(Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+            final DataKind phoneKind = new DataKind(
+                    Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1);
 
             phoneKind.typeOverallMax = 5;
             phoneKind.typeColumn = Phone.TYPE;
@@ -105,21 +106,23 @@
             addKind(phoneKind);
 
             // Email is unlimited
-            final DataKind emailKind = new DataKind(Email.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+            final DataKind emailKind = new DataKind(
+                    Email.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1);
             emailKind.typeOverallMax = -1;
             emailKind.fieldList = Lists.newArrayList();
             emailKind.fieldList.add(new EditField(Email.DATA, -1, -1));
             addKind(emailKind);
 
             // IM is only one
-            final DataKind imKind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+            final DataKind imKind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1);
             imKind.typeOverallMax = 1;
             imKind.fieldList = Lists.newArrayList();
             imKind.fieldList.add(new EditField(Im.DATA, -1, -1));
             addKind(imKind);
 
             // Organization is only one
-            final DataKind orgKind = new DataKind(Organization.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+            final DataKind orgKind = new DataKind(
+                    Organization.CONTENT_ITEM_TYPE, -1, -1, 10, true, -1, -1);
             orgKind.typeOverallMax = 1;
             orgKind.fieldList = Lists.newArrayList();
             orgKind.fieldList.add(new EditField(Organization.COMPANY, -1, -1));