diff --git a/src/com/android/contacts/model/AugmentedEntity.java b/src/com/android/contacts/model/AugmentedEntity.java
index 2cded4e..24264db 100644
--- a/src/com/android/contacts/model/AugmentedEntity.java
+++ b/src/com/android/contacts/model/AugmentedEntity.java
@@ -76,7 +76,7 @@
     public static AugmentedEntity fromBefore(Entity before) {
         final AugmentedEntity entity = new AugmentedEntity();
         entity.mValues = AugmentedValues.fromBefore(before.getEntityValues());
-        entity.mValues.setIdColumn(RawContacts._ID);
+        entity.mValues.setIdColumn("raw_contacts", RawContacts._ID);
         for (NamedContentValues namedValues : before.getSubValues()) {
             entity.addEntry(AugmentedValues.fromBefore(namedValues.values));
         }
@@ -150,6 +150,21 @@
         return null;
     }
 
+    /**
+     * Return the total number of {@link AugmentedValues} contained.
+     */
+    public int getEntryCount(boolean onlyVisible) {
+        int count = 0;
+        for (ArrayList<AugmentedValues> mimeEntries : mEntries.values()) {
+            for (AugmentedValues child : mimeEntries) {
+                // Skip deleted items when requesting only visible
+                if (onlyVisible && child.isVisible()) continue;
+                count++;
+            }
+        }
+        return count;
+    }
+
     private static final int MODE_CONTINUE = 1;
     private static final int MODE_DONE = 2;
 
@@ -330,6 +345,7 @@
     public static class AugmentedValues {
         private ContentValues mBefore;
         private ContentValues mAfter;
+        private String mIdTable = "data";
         private String mIdColumn = BaseColumns._ID;
 
         private AugmentedValues() {
@@ -385,7 +401,9 @@
             return getAsLong(mIdColumn);
         }
 
-        public void setIdColumn(String idColumn) {
+        public void setIdColumn(String idTable, String idColumn) {
+            // TODO: remove idTable when we've fixed contentprovider
+            mIdTable = idTable;
             mIdColumn = idColumn;
         }
 
@@ -393,19 +411,28 @@
             return (getAsLong(Data.IS_PRIMARY) != 0);
         }
 
+        public boolean beforeExists() {
+            return (mBefore != null && mBefore.containsKey(mIdColumn));
+        }
+
+        public boolean isVisible() {
+            // When "after" is present, then visible
+            return (mAfter != null);
+        }
+
         public boolean isDelete() {
             // When "after" is wiped, action is "delete"
-            return (mAfter == null);
+            return beforeExists() && (mAfter == null);
         }
 
         public boolean isUpdate() {
             // When "after" has some changes, action is "update"
-            return (mAfter.size() > 0);
+            return beforeExists() && (mAfter.size() > 0);
         }
 
         public boolean isInsert() {
-            // When no "before" id, action is "insert"
-            return mBefore == null || getId() == null;
+            // When no "before" id, and has "after", action is "insert"
+            return !beforeExists() && (mAfter != null);
         }
 
         public void markDeleted() {
@@ -518,11 +545,11 @@
             } else if (isDelete()) {
                 // When marked for deletion and "before" exists, then "delete"
                 builder = ContentProviderOperation.newDelete(targetUri);
-                builder.withSelection(mIdColumn + "=" + getId(), null);
+                builder.withSelection(mIdTable + "." + mIdColumn + "=" + getId(), null);
             } else if (isUpdate()) {
                 // When has changes and "before" exists, then "update"
                 builder = ContentProviderOperation.newUpdate(targetUri);
-                builder.withSelection(mIdColumn + "=" + getId(), null);
+                builder.withSelection(mIdTable + "." + mIdColumn + "=" + getId(), null);
                 builder.withValues(mAfter);
             }
             return builder;
diff --git a/src/com/android/contacts/model/ContactsSource.java b/src/com/android/contacts/model/ContactsSource.java
index c344711..b778f2a 100644
--- a/src/com/android/contacts/model/ContactsSource.java
+++ b/src/com/android/contacts/model/ContactsSource.java
@@ -150,6 +150,7 @@
             this.iconRes = iconRes;
             this.weight = weight;
             this.editable = editable;
+            this.typeOverallMax = -1;
         }
     }
 
@@ -169,6 +170,7 @@
         public EditType(int rawValue, int labelRes) {
             this.rawValue = rawValue;
             this.labelRes = labelRes;
+            this.specificMax = -1;
         }
 
         public EditType(int rawValue, int labelRes, boolean secondary) {
@@ -185,6 +187,20 @@
             this(rawValue, labelRes, secondary, specificMax);
             this.customColumn = customColumn;
         }
+
+        @Override
+        public boolean equals(Object object) {
+            if (object instanceof EditType) {
+                final EditType other = (EditType)object;
+                return other.rawValue == rawValue;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return rawValue;
+        }
     }
 
     /**
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/EntityModifier.java
index e68d0dc..33ccf6f 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/EntityModifier.java
@@ -22,7 +22,10 @@
 
 import android.content.ContentValues;
 import android.provider.ContactsContract.Data;
+import android.util.SparseIntArray;
 
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -30,16 +33,21 @@
  * new rows, or enforcing {@link ContactsSource}.
  */
 public class EntityModifier {
-    // TODO: provide helper to force an augmentedentity into sourceconstraints?
-
     /**
      * For the given {@link AugmentedEntity}, determine if the given
      * {@link DataKind} could be inserted under specific
      * {@link ContactsSource}.
      */
-    public static boolean canInsert(AugmentedEntity contact, DataKind kind) {
-        // TODO: compare against constraints to determine if insert is possible
-        return true;
+    public static boolean canInsert(AugmentedEntity state, DataKind kind) {
+        // Insert possible when have valid types and under overall maximum
+        final boolean validTypes = hasValidTypes(state, kind);
+        final boolean validOverall = (kind.typeOverallMax == -1)
+                || (state.getEntryCount(true) < kind.typeOverallMax);
+        return (validTypes && validOverall);
+    }
+
+    public static boolean hasValidTypes(AugmentedEntity state, DataKind kind) {
+        return (getValidTypes(state, kind).size() > 0);
     }
 
     /**
@@ -47,10 +55,95 @@
      * list possible {@link EditType} options available based on
      * {@link ContactsSource}.
      */
-    public static List<EditType> getValidTypes(AugmentedEntity entity, DataKind kind,
+    public static ArrayList<EditType> getValidTypes(AugmentedEntity state, DataKind kind) {
+        return getValidTypes(state, kind, null, true, null);
+    }
+
+    /**
+     * For the given {@link AugmentedEntity} and {@link DataKind}, return the
+     * list possible {@link EditType} options available based on
+     * {@link ContactsSource}.
+     *
+     * @param forceInclude Always include this {@link EditType} in the returned
+     *            list, even when an otherwise-invalid choice. This is useful
+     *            when showing a dialog that includes the current type.
+     */
+    public static ArrayList<EditType> getValidTypes(AugmentedEntity state, DataKind kind,
             EditType forceInclude) {
-        // TODO: enforce constraints and include any extra provided
-        return kind.typeList;
+        return getValidTypes(state, kind, forceInclude, true, null);
+    }
+
+    /**
+     * For the given {@link AugmentedEntity} and {@link DataKind}, return the
+     * list possible {@link EditType} options available based on
+     * {@link ContactsSource}.
+     *
+     * @param forceInclude Always include this {@link EditType} in the returned
+     *            list, even when an otherwise-invalid choice. This is useful
+     *            when showing a dialog that includes the current type.
+     * @param includeSecondary If true, include any valid types marked as
+     *            {@link EditType#secondary}.
+     * @param typeCount When provided, will be used for the frequency count of
+     *            each {@link EditType}, otherwise built using
+     *            {@link #getTypeFrequencies(AugmentedEntity, DataKind)}.
+     */
+    private static ArrayList<EditType> getValidTypes(AugmentedEntity state, DataKind kind,
+            EditType forceInclude, boolean includeSecondary, SparseIntArray typeCount) {
+        final ArrayList<EditType> validTypes = new ArrayList<EditType>();
+
+        // Bail early if no types provided
+        if (!hasEditTypes(kind)) return validTypes;
+
+        if (typeCount == null) {
+            // Build frequency counts if not provided
+            typeCount = getTypeFrequencies(state, kind);
+        }
+
+        // Build list of valid types
+        final int overallCount = typeCount.get(FREQUENCY_TOTAL);
+        for (EditType type : kind.typeList) {
+            final boolean validUnlimited = (type.specificMax == -1 && overallCount < kind.typeOverallMax);
+            final boolean validSpecific = (typeCount.get(type.rawValue) < type.specificMax);
+            final boolean validSecondary = (includeSecondary ? true : !type.secondary);
+            final boolean forcedInclude = type.equals(forceInclude);
+            if (forcedInclude || (validSecondary && (validUnlimited || validSpecific))) {
+                // Type is valid when no limit, under limit, or forced include
+                validTypes.add(type);
+            }
+        }
+
+        return validTypes;
+    }
+
+    private static final int FREQUENCY_TOTAL = Integer.MIN_VALUE;
+
+    /**
+     * Count up the frequency that each {@link EditType} appears in the given
+     * {@link AugmentedEntity}. The returned {@link SparseIntArray} maps from
+     * {@link EditType#rawValue} to counts, with the total overall count stored
+     * as {@link #FREQUENCY_TOTAL}.
+     */
+    private static SparseIntArray getTypeFrequencies(AugmentedEntity state, DataKind kind) {
+        final SparseIntArray typeCount = new SparseIntArray();
+
+        // Find all entries for this kind, bailing early if none found
+        final List<AugmentedValues> mimeEntries = state.getMimeEntries(kind.mimeType);
+        if (mimeEntries == null) return typeCount;
+
+        int totalCount = 0;
+        for (AugmentedValues entry : mimeEntries) {
+            // Only count visible entries
+            if (!entry.isVisible()) continue;
+            totalCount++;
+
+            final EditType type = getCurrentType(entry, kind);
+            if (type != null) {
+                final int count = typeCount.get(type.rawValue);
+                typeCount.put(type.rawValue, count + 1);
+            }
+        }
+        typeCount.put(FREQUENCY_TOTAL, totalCount);
+        return typeCount;
     }
 
     /**
@@ -67,7 +160,15 @@
      * the possible types.
      */
     public static EditType getCurrentType(AugmentedValues entry, DataKind kind) {
-        final long rawValue = entry.getAsLong(kind.typeColumn);
+        final Long rawValue = entry.getAsLong(kind.typeColumn);
+        if (rawValue == null) return null;
+        return getType(kind, rawValue.intValue());
+    }
+
+    /**
+     * Find the {@link EditType} with the given {@link EditType#rawValue}.
+     */
+    public static EditType getType(DataKind kind, int rawValue) {
         for (EditType type : kind.typeList) {
             if (type.rawValue == rawValue) {
                 return type;
@@ -77,11 +178,64 @@
     }
 
     /**
+     * Find the best {@link EditType} for a potential insert. The "best" is the
+     * first primary type that doesn't already exist. When all valid types
+     * exist, we pick the last valid option.
+     */
+    public static EditType getBestValidType(AugmentedEntity state, DataKind kind,
+            boolean includeSecondary) {
+        // Shortcut when no types
+        if (kind.typeColumn == null) return null;
+
+        // Find type counts and valid primary types, bail if none
+        final SparseIntArray typeCount = getTypeFrequencies(state, kind);
+        final ArrayList<EditType> validTypes = getValidTypes(state, kind, null, includeSecondary,
+                typeCount);
+        if (validTypes.size() == 0) return null;
+
+        // Keep track of the last valid type
+        final EditType lastType = validTypes.get(validTypes.size() - 1);
+
+        // Remove any types that already exist
+        Iterator<EditType> iterator = validTypes.iterator();
+        while (iterator.hasNext()) {
+            final EditType type = iterator.next();
+            final int count = typeCount.get(type.rawValue);
+
+            if (count > 0) {
+                // Type already appears, so don't consider
+                iterator.remove();
+            }
+        }
+
+        // Use the best remaining, otherwise the last valid
+        if (validTypes.size() > 0) {
+            return validTypes.get(0);
+        } else {
+            return lastType;
+        }
+    }
+
+    /**
      * Insert a new child of kind {@link DataKind} into the given
-     * {@link AugmentedEntity}. Assumes the caller has already checked
-     * {@link #canInsert(AugmentedEntity, DataKind)}.
+     * {@link AugmentedEntity}. Tries using the best {@link EditType} found
+     * using {@link #getBestValidType(AugmentedEntity, DataKind, boolean)}.
      */
     public static void insertChild(AugmentedEntity state, DataKind kind) {
+        // First try finding a valid primary
+        EditType bestType = getBestValidType(state, kind, false);
+        if (bestType == null) {
+            // No valid primary found, so expand search to secondary
+            bestType = getBestValidType(state, kind, true);
+        }
+        insertChild(state, kind, bestType);
+    }
+
+    /**
+     * Insert a new child of kind {@link DataKind} into the given
+     * {@link AugmentedEntity}, marked with the given {@link EditType}.
+     */
+    public static void insertChild(AugmentedEntity state, DataKind kind, EditType type) {
         final ContentValues after = new ContentValues();
 
         // Our parent CONTACT_ID is provided later
@@ -92,10 +246,9 @@
             after.putAll(kind.defaultValues);
         }
 
-        if (kind.typeColumn != null) {
-            // TODO: add the best-kind of entry based on current state machine
-            final EditType firstType = kind.typeList.get(0);
-            after.put(kind.typeColumn, firstType.rawValue);
+        if (kind.typeColumn != null && type != null) {
+            // Set type, if provided
+            after.put(kind.typeColumn, type.rawValue);
         }
 
         state.addEntry(AugmentedValues.fromAfter(after));
diff --git a/src/com/android/contacts/ui/widget/ContactEditorView.java b/src/com/android/contacts/ui/widget/ContactEditorView.java
index 924241f..058c040 100644
--- a/src/com/android/contacts/ui/widget/ContactEditorView.java
+++ b/src/com/android/contacts/ui/widget/ContactEditorView.java
@@ -120,7 +120,7 @@
      * {@link DataKind} around a {@link Data#MIMETYPE}. This view shows a
      * section header and a trigger for adding new {@link Data} rows.
      */
-    public static class KindSection extends ViewHolder implements OnClickListener {
+    protected static class KindSection extends ViewHolder implements OnClickListener, EditorListener {
         private static final int RES_SECTION = R.layout.item_edit_kind;
 
         private ViewGroup mEditors;
@@ -144,7 +144,12 @@
             mTitle = (TextView)mContent.findViewById(R.id.kind_title);
             mTitle.setText(kind.titleRes);
 
-            rebuildFromState();
+            this.rebuildFromState();
+            this.updateAddEnabled();
+        }
+
+        public void onDeleted(Editor editor) {
+            this.updateAddEnabled();
         }
 
         /**
@@ -152,7 +157,6 @@
          */
         public void rebuildFromState() {
             // TODO: build special "stub" entries to help enter first-phone or first-email
-            // TODO: set the add-enabled state based on entitymodifier
 
             // Remove any existing editors
             mEditors.removeAllViews();
@@ -160,16 +164,27 @@
             // Build individual editors for each entry
             if (!mState.hasMimeEntries(mKind.mimeType)) return;
             for (AugmentedValues entry : mState.getMimeEntries(mKind.mimeType)) {
+                // Skip entries that aren't visible
+                if (!entry.isVisible()) continue;
+
                 final GenericEditor editor = new GenericEditor(mContext);
                 editor.setValues(mKind, entry, mState);
+                editor.setEditorListener(this);
                 mEditors.addView(editor.getView());
             }
         }
 
+        protected void updateAddEnabled() {
+            // Set enabled state on the "add" view
+            final boolean canInsert = EntityModifier.canInsert(mState, mKind);
+            mAdd.setEnabled(canInsert);
+        }
+
         public void onClick(View v) {
             // Insert a new child and rebuild
             EntityModifier.insertChild(mState, mKind);
-            rebuildFromState();
+            this.rebuildFromState();
+            this.updateAddEnabled();
         }
     }
 
@@ -177,13 +192,28 @@
      * Generic definition of something that edits a {@link Data} row through an
      * {@link AugmentedValues} object.
      */
-    public interface Editor {
+    protected interface Editor {
         /**
          * Prepare this editor for the given {@link AugmentedValues}, which
          * builds any needed views. Any changes performed by the user will be
          * written back to that same object.
          */
         public void setValues(DataKind kind, AugmentedValues values, AugmentedEntity state);
+
+        /**
+         * Add a specific {@link EditorListener} to this {@link Editor}.
+         */
+        public void setEditorListener(EditorListener listener);
+    }
+
+    /**
+     * Listener for an {@link Editor}, usually to handle deleted items.
+     */
+    protected interface EditorListener {
+        /**
+         * Called when the given {@link Editor} has been deleted.
+         */
+        public void onDeleted(Editor editor);
     }
 
     /**
@@ -191,7 +221,7 @@
      * the entry. Uses {@link AugmentedValues} to read any existing
      * {@link Entity} values, and to correctly write any changes values.
      */
-    public static class GenericEditor extends ViewHolder implements Editor, OnClickListener {
+    protected static class GenericEditor extends ViewHolder implements Editor, OnClickListener {
         private static final int RES_EDITOR = R.layout.item_editor;
         private static final int RES_FIELD = R.layout.item_editor_field;
         private static final int RES_LABEL_ITEM = android.R.layout.simple_list_item_1;
@@ -218,6 +248,12 @@
             mDelete.setOnClickListener(this);
         }
 
+        private EditorListener mListener;
+
+        public void setEditorListener(EditorListener listener) {
+            mListener = listener;
+        }
+
         /**
          * Build the current label state based on selected {@link EditType} and
          * possible custom label string.
@@ -247,7 +283,7 @@
             mEntry = entry;
             mState = state;
 
-            if (entry.isDelete()) {
+            if (!entry.isVisible()) {
                 // Hide ourselves entirely if deleted
                 mContent.setVisibility(View.GONE);
                 return;
@@ -386,6 +422,11 @@
                     // Mark as deleted and hide this editor
                     mEntry.markDeleted();
                     mContent.setVisibility(View.GONE);
+
+                    if (mListener != null) {
+                        // Notify listener when present
+                        mListener.onDeleted(this);
+                    }
                     break;
                 }
             }
@@ -395,7 +436,7 @@
     /**
      * Simple editor for {@link Photo}.
      */
-    public static class PhotoEditor extends ViewHolder implements Editor {
+    protected static class PhotoEditor extends ViewHolder implements Editor {
         private static final int RES_PHOTO = R.layout.item_editor_photo;
 
         public PhotoEditor(Context context) {
@@ -454,12 +495,15 @@
 
         public void setValues(DataKind kind, AugmentedValues values, AugmentedEntity state) {
         }
+
+        public void setEditorListener(EditorListener listener) {
+        }
     }
 
     /**
      * Simple editor for {@link StructuredName}.
      */
-    public static class DisplayNameEditor extends ViewHolder implements Editor {
+    protected static class DisplayNameEditor extends ViewHolder implements Editor {
         private static final int RES_DISPLAY_NAME = R.layout.item_editor_displayname;
 
         public DisplayNameEditor(Context context) {
@@ -468,6 +512,9 @@
 
         public void setValues(DataKind kind, AugmentedValues values, AugmentedEntity state) {
         }
+
+        public void setEditorListener(EditorListener listener) {
+        }
     }
 
 }
diff --git a/tests/src/com/android/contacts/AugmentedEntityTests.java b/tests/src/com/android/contacts/AugmentedEntityTests.java
index e9498e1..aeab4f9 100644
--- a/tests/src/com/android/contacts/AugmentedEntityTests.java
+++ b/tests/src/com/android/contacts/AugmentedEntityTests.java
@@ -63,7 +63,7 @@
         mContext = getContext();
     }
 
-    public Entity getEntity(long contactId, long phoneId) {
+    protected Entity getEntity(long contactId, long phoneId) {
         // Build an existing contact read from database
         final ContentValues contact = new ContentValues();
         contact.put(RawContacts.VERSION, 43);
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
new file mode 100644
index 0000000..4db9d0b
--- /dev/null
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -0,0 +1,213 @@
+/*
+ * 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;
+
+import com.android.contacts.model.AugmentedEntity;
+import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.ContactsSource.DataKind;
+import com.android.contacts.model.ContactsSource.EditType;
+
+import android.content.ContentValues;
+import android.content.Entity;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link EntityModifier} to verify that {@link ContactsSource}
+ * constraints are being enforced correctly.
+ */
+@LargeTest
+public class EntityModifierTests extends AndroidTestCase {
+    public static final String TAG = "EntityModifierTests";
+
+    public EntityModifierTests() {
+        super();
+    }
+
+    @Override
+    public void setUp() {
+        mContext = getContext();
+    }
+
+    /**
+     * Build a {@link ContactsSource} that has various odd constraints for
+     * testing purposes.
+     */
+    protected ContactsSource getSource() {
+        final ContactsSource list = new ContactsSource();
+
+        {
+            // Phone allows maximum 2 home, 1 work, and unlimited other, with
+            // constraint of 5 numbers maximum.
+            DataKind kind = new DataKind(Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+
+            kind.typeOverallMax = 5;
+            kind.typeColumn = Phone.TYPE;
+            kind.typeList = new ArrayList<EditType>();
+            kind.typeList.add(new EditType(Phone.TYPE_HOME, -1, false, 2));
+            kind.typeList.add(new EditType(Phone.TYPE_WORK, -1, false, 1));
+            kind.typeList.add(new EditType(Phone.TYPE_FAX_WORK, -1, true, -1));
+            kind.typeList.add(new EditType(Phone.TYPE_OTHER, -1));
+
+            list.add(kind);
+        }
+
+        return list;
+    }
+
+    /**
+     * Build an {@link Entity} with the requested set of phone numbers.
+     */
+    protected AugmentedEntity getEntity() {
+        final ContentValues contact = new ContentValues();
+        final Entity before = new Entity(contact);
+        return AugmentedEntity.fromBefore(before);
+    }
+
+    /**
+     * Assert this {@link List} contains the given {@link Object}.
+     */
+    protected void assertContains(List<?> list, Object object) {
+        assertTrue("Missing expected value", list.contains(object));
+    }
+
+    /**
+     * Assert this {@link List} does not contain the given {@link Object}.
+     */
+    protected void assertNotContains(List<?> list, Object object) {
+        assertFalse("Contained unexpected value", list.contains(object));
+    }
+
+    /**
+     * Insert various rows to test
+     * {@link EntityModifier#getValidTypes(AugmentedEntity, DataKind, EditType)}
+     */
+    public void testValidTypes() {
+        // Build a source and pull specific types
+        final ContactsSource source = getSource();
+        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
+        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+        final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
+        final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
+
+        List<EditType> validTypes;
+
+        // Add first home, first work
+        final AugmentedEntity state = getEntity();
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+        EntityModifier.insertChild(state, kindPhone, typeWork);
+
+        // Expecting home, other
+        validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
+        assertContains(validTypes, typeHome);
+        assertNotContains(validTypes, typeWork);
+        assertContains(validTypes, typeOther);
+
+        // Add second home
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+
+        // Expecting other
+        validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
+        assertNotContains(validTypes, typeHome);
+        assertNotContains(validTypes, typeWork);
+        assertContains(validTypes, typeOther);
+
+        // Add third and fourth home (invalid, but possible)
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+
+        // Expecting none
+        validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
+        assertNotContains(validTypes, typeHome);
+        assertNotContains(validTypes, typeWork);
+        assertNotContains(validTypes, typeOther);
+    }
+
+    /**
+     * Test {@link EntityModifier#canInsert(AugmentedEntity, DataKind)} by
+     * inserting various rows.
+     */
+    public void testCanInsert() {
+        // Build a source and pull specific types
+        final ContactsSource source = getSource();
+        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
+        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+        final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
+        final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
+
+        // Add first home, first work
+        final AugmentedEntity state = getEntity();
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+        EntityModifier.insertChild(state, kindPhone, typeWork);
+        assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone));
+
+        // Add two other, which puts us just under "5" overall limit
+        EntityModifier.insertChild(state, kindPhone, typeOther);
+        EntityModifier.insertChild(state, kindPhone, typeOther);
+        assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone));
+
+        // Add second home, which should push to snug limit
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+        assertFalse("Able to insert", EntityModifier.canInsert(state, kindPhone));
+    }
+
+    /**
+     * Test {@link EntityModifier#getBestValidType(AugmentedEntity, DataKind)}
+     * by asserting expected best options in various states.
+     */
+    public void testBestValidType() {
+        // Build a source and pull specific types
+        final ContactsSource source = getSource();
+        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
+        final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+        final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
+        final EditType typeFaxWork = EntityModifier.getType(kindPhone, Phone.TYPE_FAX_WORK);
+        final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
+
+        EditType suggested;
+
+        // Default suggestion should be home
+        final AugmentedEntity state = getEntity();
+        suggested = EntityModifier.getBestValidType(state, kindPhone, false);
+        assertEquals("Unexpected suggestion", typeHome, suggested);
+
+        // Add first home, should now suggest work
+        EntityModifier.insertChild(state, kindPhone, typeHome);
+        suggested = EntityModifier.getBestValidType(state, kindPhone, false);
+        assertEquals("Unexpected suggestion", typeWork, suggested);
+
+        // Add work fax, should still suggest work
+        EntityModifier.insertChild(state, kindPhone, typeFaxWork);
+        suggested = EntityModifier.getBestValidType(state, kindPhone, false);
+        assertEquals("Unexpected suggestion", typeWork, suggested);
+
+        // Add other, should still suggest work
+        EntityModifier.insertChild(state, kindPhone, typeOther);
+        suggested = EntityModifier.getBestValidType(state, kindPhone, false);
+        assertEquals("Unexpected suggestion", typeWork, suggested);
+
+        // Add work, now should suggest other
+        EntityModifier.insertChild(state, kindPhone, typeWork);
+        suggested = EntityModifier.getBestValidType(state, kindPhone, false);
+        assertEquals("Unexpected suggestion", typeOther, suggested);
+    }
+}
