diff --git a/entity_view_mode.info b/entity_view_mode.info
index 51cd2df..1d77cc5 100644
--- a/entity_view_mode.info
+++ b/entity_view_mode.info
@@ -3,3 +3,4 @@ description = Allows administrators to define custom view modes for entities via
 core = 7.x
 recommends[] = field_ui
 configure = admin/config/system/entity-view-modes
+files[] = entity_view_mode.test
diff --git a/entity_view_mode.module b/entity_view_mode.module
index 58548d4..8da92b1 100644
--- a/entity_view_mode.module
+++ b/entity_view_mode.module
@@ -106,7 +106,7 @@ function entity_view_mode_save($entity_type, $view_mode) {
 
   // Determine if we will be inserting a new view mode.
   if (!isset($view_mode['is_new'])) {
-    $view_mode['is_new'] = !empty($view_mode['original']);
+    $view_mode['is_new'] = empty($view_mode['original']);
   }
 
   // Let modules modify the view mode before it is saved.
@@ -124,6 +124,11 @@ function entity_view_mode_save($entity_type, $view_mode) {
     module_invoke_all('entity_view_mode_insert', $view_mode, $entity_type);
   }
   else {
+    // If the view mode's machine name has changed, invoke a separate hook
+    // before running the update hook.
+    if ($view_mode_name != $existing_view_mode) {
+      module_invoke_all('entity_view_mode_rename', $entity_type, $existing_view_mode, $view_mode_name);
+    }
     module_invoke_all('entity_view_mode_update', $view_mode, $entity_type);
   }
 
@@ -161,6 +166,42 @@ function field_entity_view_mode_insert($view_mode, $entity_type) {
 }
 
 /**
+ * Implements hook_entity_view_mode_rename() on behalf of core field module.
+ */
+function field_entity_view_mode_rename($entity_type, $view_mode_old, $view_mode_new) {
+  $entity_info = entity_get_info($entity_type);
+
+  foreach (array_keys($entity_info['bundles']) as $bundle) {
+    // Update all field bundle settings for the renamed view mode.
+    $settings = field_bundle_settings($entity_type, $bundle);
+    $changed = FALSE;
+    if (isset($settings['view_modes'][$view_mode_old])) {
+      $settings['view_modes'][$view_mode_new] = $settings['view_modes'][$view_mode_old];
+      unset($settings['view_modes'][$view_mode_old]);
+      $changed = TRUE;
+    }
+    if (isset($settings['extra_fields']['display'][$view_mode_old])) {
+      $settings['extra_fields']['display'][$view_mode_new] = $settings['extra_fields']['display'][$view_mode_old];
+      unset($settings['extra_fields']['display'][$view_mode_old]);
+      $changed = TRUE;
+    }
+    if ($changed) {
+      field_bundle_settings($entity_type, $bundle, $settings);
+    }
+
+    // Update all field instance display settings for the renamed view mode.
+    $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle));
+    foreach ($instances as $instance) {
+      // Remove the view mode settings from all configured field instances.
+      if (isset($instance['display'][$view_mode_old])) {
+        $instance['display'][$view_mode_new] = $instance['display'][$view_mode_old];
+        field_update_instance($instance);
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_entity_view_mode_update() on behalf of core field module.
  */
 function field_entity_view_mode_update($view_mode, $entity_type) {
@@ -182,13 +223,12 @@ function field_entity_view_mode_update($view_mode, $entity_type) {
       // settings.
       $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
       if (!empty($value) && empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
-        $view_mode_label = $entity_info['view modes'][$view_mode_name]['label'];
         $path = _field_ui_bundle_admin_path($entity_type, $bundle) . "/display/$view_mode_name";
-        drupal_set_message(t('The %view_mode @entity_type @bundle view mode now uses custom display settings. You might want to <a href="@url" target="_new">configure them</a>.', array(
-          '%view_mode' => $view_mode_label,
+        drupal_set_message(t('The %view_mode @entity_type @bundle view mode now uses custom display settings copied from the default view mode. You might want to <a href="@url">configure them</a>.', array(
+          '%view_mode' => $view_mode['label'],
           '@entity_type' => $entity_info['label'],
           '@bundle' => $entity_info['bundles'][$bundle]['label'],
-          '@url' => url($path),
+          '@url' => url($path, array('query' => drupal_get_destination())),
         )));
         // Initialize the newly customized view mode with the display settings
         // from the default view mode.
@@ -210,14 +250,23 @@ function field_entity_view_mode_delete($view_mode, $entity_type) {
   $view_mode_name = $view_mode['machine_name'];
 
   foreach (array_keys($entity_info['bundles']) as $bundle) {
-    // Remove bundle settings for the view mode.
-    $bundle_settings = field_bundle_settings($entity_type, $bundle);
-    if (isset($bundle_settings['view_modes'][$view_mode_name])) {
-      unset($bundles_settings['view_modes'][$view_mode_name]);
-      field_bundle_settings($entity_type, $bundle, $bundle_settings);
+    // Remove all field bundle settings for the deleted view mode.
+    $settings = field_bundle_settings($entity_type, $bundle);
+    if (isset($settings['view_modes'][$view_mode_name]) || isset($settings['extra_fields']['display'][$view_mode_name])) {
+      unset($settings['view_modes'][$view_mode_name]);
+      unset($settings['extra_fields']['display'][$view_mode_name]);
+      field_bundle_settings($entity_type, $bundle, $settings);
     }
 
-    // @todo Delete view mode settings in field instances?
+    // Remove all field instance display settings for the deleted view mode.
+    $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle));
+    foreach ($instances as $instance) {
+      // Remove the view mode settings from all configured field instances.
+      if (isset($instance['display'][$view_mode_name])) {
+        unset($instance['display'][$view_mode_name]);
+        field_update_instance($instance);
+      }
+    }
   }
 }
 
diff --git a/entity_view_mode.test b/entity_view_mode.test
new file mode 100644
index 0000000..71c80f3
--- /dev/null
+++ b/entity_view_mode.test
@@ -0,0 +1,159 @@
+<?php
+
+/**
+ * @file
+ * Test integration for the entity_view_mode module.
+ */
+
+class EntityViewModeTestHelper extends DrupalWebTestCase {
+
+  /**
+   * Overrides DrupalWebTestCase::setUp().
+   */
+  public function setUp() {
+    parent::setUp(array('entity_view_mode'));
+  }
+
+  /**
+   * Overrides DrupalWebTestCase::refreshVariables().
+   *
+   * Ensures that the entity and field view mode caches are cleared so they
+   * can be reliably checked in the test.
+   */
+  protected function refreshVariables() {
+    parent::refreshVariables();
+
+    // Clear the entity and display caches.
+    drupal_static_reset('field_view_mode_settings');
+    entity_info_cache_clear();
+  }
+
+  public function assertViewModeExists($entity_type, $view_mode) {
+    $info = entity_get_info($entity_type);
+    return $this->assertTrue(!empty($info['view modes'][$view_mode]), "View mode $view_mode found for entity type $entity_type.");
+  }
+
+  public function assertNoViewModeExists($entity_type, $view_mode) {
+    $info = entity_get_info($entity_type);
+    return $this->assertTrue(!isset($info['view modes'][$view_mode]), "View mode $view_mode not found for entity type $entity_type.");
+  }
+
+  public function getActualViewMode($entity_type, $bundle, $view_mode) {
+    $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+    return (!empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default');
+  }
+
+  public function assertActualViewMode($entity_type, $bundle, $view_mode, $expected_view_mode) {
+    $actual_view_mode = $this->getActualViewMode($entity_type, $bundle, $view_mode);
+    return $this->assertIdentical($expected_view_mode, $actual_view_mode, "View mode $view_mode for entity type $entity_type and bundle $bundle actually uses view mode $actual_view_mode, expected $expected_view_mode.");
+  }
+
+  public function assertViewModeDefaultDisplay($entity_type, $bundle, $view_mode) {
+    return $this->assertActualViewMode($entity_type, $bundle, $view_mode, 'default');
+  }
+
+  public function assertViewModeCustomDisplay($entity_type, $bundle, $view_mode) {
+    return $this->assertActualViewMode($entity_type, $bundle, $view_mode, $view_mode);
+  }
+}
+
+class EntityViewModeFunctionalTest extends EntityViewModeTestHelper {
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity view mode functionality',
+      'description' => 'Tests entity view mode module functionality.',
+      'group' => 'Entity view mode',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    // Create an administrative user.
+    $this->admin_user = $this->drupalCreateUser(array(
+      'administer entity view modes',
+      'administer content types',
+    ));
+  }
+
+  public function testEntityViewModes() {
+    $this->drupalLogin($this->admin_user);
+    $this->drupalGet('admin/config/system/entity-view-modes');
+    $this->assertLinkByHref('admin/config/system/entity-view-modes/add/node');
+    $this->drupalGet('admin/config/system/entity-view-modes/add/node');
+
+    // @todo Set some 'default' settings under a field instance display and
+    // view mode settings to test that the default settings are applied to
+    // custom view modes.
+    //$settings = field_bundle_settings('node', 'article');
+    //$settings['extra_fields']['display']['test']['default']['testing'] = TRUE;
+    //field_bundle_settings('node', 'article', $settings);
+    //$settings = field_bundle_settings('node', 'page');
+    //$settings['extra_fields']['display']['test']['default']['testing'] = TRUE;
+    //field_bundle_settings('node', 'page', $settings);
+
+    // Attempt to create a view mode that already is provided by core.
+    $edit = array(
+      'label' => 'Custom teaser',
+      'machine_name' => 'teaser',
+    );
+    $this->drupalPost(NULL, $edit, 'Save');
+    $this->assertText('The machine-readable name is already in use. It must be unique.');
+
+    // Save a new view mode for real.
+    $edit['label'] = 'Custom 1';
+    $edit['machine_name'] = 'custom_1';
+    $edit['enabled_bundles[article]'] = TRUE;
+    $edit['enabled_bundles[page]'] = FALSE;
+    $this->drupalPost(NULL, $edit, 'Save');
+    $this->assertViewModeExists('node', 'custom_1');
+    $this->assertViewModeCustomDisplay('node', 'article', 'custom_1');
+    $this->assertViewModeDefaultDisplay('node', 'page', 'custom_1');
+
+    // Switch the view mode from articles to pages.
+    $edit = array(
+      'enabled_bundles[article]' => FALSE,
+      'enabled_bundles[page]' => TRUE,
+    );
+    $this->drupalPost('admin/config/system/entity-view-modes/edit/node/custom_1', $edit, 'Save');
+    $this->assertText('Saved the Custom 1 node view mode.');
+    $this->assertViewModeExists('node', 'custom_1');
+    $this->assertViewModeDefaultDisplay('node', 'article', 'custom_1');
+    $this->assertViewModeCustomDisplay('node', 'page', 'custom_1');
+
+    // Save a custom value into the view mode settings to check that when a
+    // view mode's machine name is changed, that the display settings are
+    // changed as well.
+    //$settings = field_bundle_settings('node', 'page');
+    //$settings['view_modes']['custom_1']['testing'] = TRUE;
+    //$settings['extra_fields']['display']['testing']['custom_1']['custom_1']['testing'] = TRUE;
+    //field_bundle_settings('node', 'page', $settings);
+
+    // Rename the view mode's label and machine name.
+    $edit = array(
+      'label' => 'Custom 2',
+      'machine_name' => 'custom_2',
+    );
+    $this->drupalPost('admin/config/system/entity-view-modes/edit/node/custom_1', $edit, 'Save');
+    $this->assertText('Saved the Custom 2 node view mode.');
+    $this->assertNoViewModeExists('node', 'custom_1');
+    $this->assertViewModeDefaultDisplay('node', 'article', 'custom_1');
+    $this->assertViewModeDefaultDisplay('node', 'page', 'custom_1');
+    $this->assertViewModeExists('node', 'custom_2');
+    $this->assertViewModeDefaultDisplay('node', 'article', 'custom_2');
+    $this->assertViewModeCustomDisplay('node', 'page', 'custom_2');
+
+    // Check that our custom value was transferred to the new view mode
+    // settings.
+    //$settings = field_bundle_settings('node', 'page');
+    //$this->assertTrue(!isset($settings['view_modes']['custom_1']) && !isset($settings['extra_fields']['display']['custom_1']));
+    //$this->assertTrue(!empty($settings['view_modes']['custom_2']['testing']) && !empty($settings['extra_fields']['display']['custom_2']['testing']));
+
+    // Delete the view mode.
+    $this->drupalPost('admin/config/system/entity-view-modes/delete/node/custom_2', array(), 'Delete');
+    $this->assertText('Deleted the Custom 2 node view mode.');
+    $this->assertNoViewModeExists('node', 'custom_2');
+    $this->assertViewModeDefaultDisplay('node', 'article', 'custom_2');
+    $this->assertViewModeDefaultDisplay('node', 'page', 'custom_2');
+  }
+}
