diff --git a/features.admin.inc b/features.admin.inc
index e23c7fb..524e393 100644
--- a/features.admin.inc
+++ b/features.admin.inc
@@ -48,6 +48,18 @@ function features_settings_form($form, $form_state) {
       );
     }
   }
+  $form['advanced'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Advanced'),
+    '#collapsed' => TRUE,
+    '#collapsible' => TRUE,
+  );
+  $form['advanced']['features_modules_uninstall_cleanup'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('features_modules_uninstall_cleanup', FALSE),
+    '#title' => t('Cleanup features on uninstall'),
+    '#description' => t('Delete configuration on uninstall of a feature module. If you choice to use this option, you are responsible for any data loose caused by it. The current components that implement this cleanup are @components.', array('@components' => implode(', ', array_keys(features_implement_hooks('features_delete'))))),
+  );
   return system_settings_form($form);
 }
 
diff --git a/features.api.php b/features.api.php
index 7c24024..c545d8e 100644
--- a/features.api.php
+++ b/features.api.php
@@ -198,6 +198,26 @@ function hook_features_revert($module_name) {
  * component, not the module, eg. [component]_features_export() rather than
  * [module]_features_export().
  *
+ * Delete all component objects for a given feature module.
+ *
+ * @param string $module_name
+ *   The name of the feature module whose components should be reverted.
+ */
+function hook_features_delete($module_name) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['mycomponent'])) {
+    foreach ($feature->info['features']['mycomponent'] as $name) {
+      mycomponent_delete($mycomponent);
+    }
+  }
+}
+
+
+/**
+ * Component hook. The hook should be implemented using the name ot the
+ * component, not the module, eg. [component]_features_export() rather than
+ * [module]_features_export().
+ *
  * Rebuild all component objects for a given feature module. Should only be
  * implemented for 'faux-exportable' components.
  *
diff --git a/features.module b/features.module
index 59952b3..b5a8ddb 100644
--- a/features.module
+++ b/features.module
@@ -330,6 +330,29 @@ function features_modules_enabled($modules) {
   }
 }
 
+
+
+/**
+ * Implements hook_modules_uninstalled().
+ */
+function features_modules_uninstalled($modules) {
+  if (variable_get('features_modules_uninstall_cleanup', FALSE)) {
+    // Go through all modules and gather features that can be enabled.
+    $items = array();
+    foreach ($modules as $module) {
+      if ($feature = features_load_feature($module)) {
+        $items[$module] = array_keys($feature->info['features']);
+      }
+    }
+  
+    if (!empty($items)) {
+      _features_restore('delete', $items);
+      // Rebuild the list of features includes.
+      features_include(TRUE);
+    }
+  }
+}
+
 /**
  * Load includes for any modules that implement the features API and
  * load includes for those provided by features.
@@ -553,6 +576,27 @@ function features_hook($component, $hook, $reset = FALSE) {
   return function_exists($base . '_' . $hook) ? $base . '_' . $hook : FALSE;
 }
 
+
+/**
+ * Returns components that implement a features_hook.
+ *
+ * @param $hook
+ *   A features hook to look for.
+ *
+ * @return
+ *   An array of components that implement said hook in form component to hook.
+ */
+function features_implement_hooks($hook) {
+  features_include();
+  $components = array();
+  foreach (array_keys(features_get_components()) as $component) {
+    if ($component_hook = features_hook($component, $hook)) {
+      $components[$component] = $component_hook;
+    }
+  }
+  return $components;
+}
+
 /**
  * Enables and installs an array of modules, ignoring those
  * already enabled & installed. Consider this a helper or
@@ -865,6 +909,10 @@ function _features_restore($op, $items = array()) {
       $restore_hook = 'features_enable_feature';
       $log_action = 'Enable';
       break;
+    case 'delete':
+      $restore_hook = 'features_delete';
+      $log_action = 'Delete';
+      break;
   }
 
   if (empty($items)) {
diff --git a/includes/features.field.inc b/includes/features.field.inc
index cdfe692..8acb14d 100644
--- a/includes/features.field.inc
+++ b/includes/features.field.inc
@@ -309,7 +309,6 @@ function field_instance_features_rebuild($module) {
     }
   }
 }
-
 /**
  * Load a field base configuration by a field_name identifier.
  */
@@ -336,6 +335,32 @@ function features_field_instance_load($identifier) {
   return FALSE;
 }
 
+/**
+ * Implements of hook_features_delete().
+ */
+function field_base_features_delete($module) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['field_base'])) {
+    foreach ($feature->info['features']['field_base'] as $field_name) {
+      field_delete_field($field_name);
+    }
+  }
+}
+
+/**
+ * Implements of hook_features_delete().
+ */
+function field_instance_features_delete($module) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['field_instance'])) {
+    foreach ($feature->info['features']['field_instance'] as $identifier) {
+      if ($instance = features_field_instance_load($identifier)) {
+        field_delete_instance($instance, FALSE);
+      }
+    }
+  }
+}
+
 /* ----- DEPRECATED FIELD EXPORT -----
  * keep this code for backward compatibility with older exports
  * until v3.x
diff --git a/includes/features.filter.inc b/includes/features.filter.inc
index a52927d..cf3907a 100644
--- a/includes/features.filter.inc
+++ b/includes/features.filter.inc
@@ -96,6 +96,21 @@ function filter_features_rebuild($module) {
 }
 
 /**
+ * Implements hook_features_delete().
+ */
+function filter_features_delete($module) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['filter'])) {
+    foreach ($feature->info['features']['filter'] as $name) {
+      if ($object = filter_format_load($name)) {
+        // Cannot delete due to security issues.
+        filter_format_disable($object);
+      }
+    }
+  }
+}
+
+/**
  * Load a filter format by its name.
  */
 function features_filter_format_load($name) {
diff --git a/includes/features.menu.inc b/includes/features.menu.inc
index 23888e1..3123639 100644
--- a/includes/features.menu.inc
+++ b/includes/features.menu.inc
@@ -128,6 +128,21 @@ function menu_custom_features_rebuild($module) {
 }
 
 /**
+ * Implements hook_features_delete().
+ */
+function menu_custom_features_delete($module) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['menu_custom'])) {
+    foreach ($feature->info['features']['menu_custom'] as $name) {
+      trigger_error('here ' . $name);
+      if ($menu = menu_load($name)) {
+        menu_delete($menu);
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_features_export_options().
  */
 function menu_links_features_export_options() {
diff --git a/includes/features.node.inc b/includes/features.node.inc
index 7beb55f..889481d 100644
--- a/includes/features.node.inc
+++ b/includes/features.node.inc
@@ -115,6 +115,23 @@ function node_features_revert($module = NULL) {
 }
 
 /**
+ * Implements hook_features_revert().
+ *
+ * @param $module
+ * name of module to revert content for
+ */
+function node_features_delete($module = NULL) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['node'])) {
+    foreach ($feature->info['features']['node'] as $type_name) {
+      if (node_type_get_type($type_name)) {
+        node_type_delete($type_name);
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_features_disable().
  *
  * When a features module is disabled, modify any node types it provides so
diff --git a/includes/features.taxonomy.inc b/includes/features.taxonomy.inc
index a7c85cd..a796ff2 100644
--- a/includes/features.taxonomy.inc
+++ b/includes/features.taxonomy.inc
@@ -103,3 +103,17 @@ function taxonomy_features_rebuild($module) {
     }
   }
 }
+
+/**
+ * Implements hook_features_delete().
+ */
+function taxonomy_features_delete($module) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['taxonomy'])) {
+    foreach ($feature->info['features']['taxonomy'] as $vocab_name) {
+      if ($vocab = taxonomy_vocabulary_machine_name_load($vocab_name)) {
+        taxonomy_vocabulary_delete($vocab->vid);
+      }
+    }
+  }
+}
diff --git a/includes/features.user.inc b/includes/features.user.inc
index 77f025b..b7830ee 100644
--- a/includes/features.user.inc
+++ b/includes/features.user.inc
@@ -217,6 +217,20 @@ function user_role_features_rebuild($module) {
 }
 
 /**
+ * Implements hook_features_delete().
+ */
+function user_role_features_delete($module) {
+  $feature = features_load_feature($module);
+  if (!empty($feature->info['features']['user_role'])) {
+    foreach ($feature->info['features']['user_role'] as $name) {
+      if ($object = user_role_load_by_name($name)) {
+        user_role_delete($name);
+      }
+    }
+  }
+}
+
+/**
  * Generate $rid => $role with role names untranslated.
  */
 function _user_features_get_roles($builtin = TRUE) {
diff --git a/tests/features.test b/tests/features.test
index e38bab5..4acfa10 100644
--- a/tests/features.test
+++ b/tests/features.test
@@ -217,6 +217,88 @@ class FeaturesEnableTestCase extends DrupalWebTestCase {
 }
 
 
+
+/**
+ * Tests enabling of feature modules.
+ */
+class FeaturesDeleteTestCase extends DrupalWebTestCase {
+  protected $profile = 'testing';
+
+  /**
+   * Test info.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('Features delete tests'),
+      'description' => t('Run tests for uninstall of features and deleting items.') ,
+      'group' => t('Features'),
+    );
+  }
+
+
+  /**
+   * Set up test.
+   */
+  public function setUp() {
+    parent::setUp(array(
+      'features',
+      'ctools',
+      'features_test',
+    ));
+  }
+
+
+  /**
+   * Run test for features_get_components on enable.
+   */
+  public function testFeaturesDelete() {
+    variable_set('features_modules_uninstall_cleanup', TRUE);
+    $this->assertTrue((bool)node_type_get_type('features_test'), 'features_test node type exists before delete.');
+    $this->assertTrue((bool)field_info_field('field_features_test'), 'field_features_test exists before delete.');
+    $this->assertTrue((bool)field_info_instance('node', 'field_features_test', 'features_test'), 'field_features_test for features_test exists before delete.');
+    $this->assertTrue((bool)taxonomy_vocabulary_machine_name_load('taxonomy_features_test'), 'taxonomy_features_test exists before delete.');
+    $this->assertTrue((bool)user_role_load_by_name('role_features_test'), 'role_features_test exists before delete.');
+    $this->assertTrue((bool)filter_format_load('features_test'), 'features_test exists before delete.');
+    $this->assertTrue((bool)menu_load('menu-menu-features-test'), 'menu-menu-features-test exists before delete.');
+
+    module_disable(array('features_test'));
+    drupal_uninstall_modules(array('features_test'));
+
+    $this->assertFalse(node_type_get_type('features_test'), 'features_test deleted after uninstall.');
+    $this->assertFalse((bool)field_info_instance('node', 'field_features_test', 'features_test'), 'field_features_test for features_test deleted after uninstall.');
+    $this->assertFalse((bool)field_info_field('field_features_test'), 'field_features_test deleted after uninstall.');
+    $this->assertFalse((bool)taxonomy_vocabulary_machine_name_load('taxonomy_features_test'), 'taxonomy_features_test deleted after uninstall.');
+    $this->assertFalse((bool)user_role_load_by_name('role_features_test'), 'role_features_test deleted after uninstall.');
+    $this->assertFalse((bool)filter_format_load('features_test'), 'features_test exists deleted after uninstall.');
+    $this->assertFalse((bool)menu_load('menu-menu-features-test'), 'menu-menu-features-test deleted after uninstall..');
+  }
+
+  /**
+   * Run test for features_get_components on enable.
+   */
+  public function testFeaturesNotDelete() {
+    variable_set('features_modules_uninstall_cleanup', FALSE);
+    $this->assertTrue((bool)node_type_get_type('features_test'), 'features_test node type exists before delete.');
+    $this->assertTrue((bool)field_info_field('field_features_test'), 'field_features_test exists before delete.');
+    $this->assertTrue((bool)field_info_instance('node', 'field_features_test', 'features_test'), 'field_features_test for features_test exists before delete.');
+    $this->assertTrue((bool)taxonomy_vocabulary_machine_name_load('taxonomy_features_test'), 'taxonomy_features_test exists before delete.');
+    $this->assertTrue((bool)user_role_load_by_name('role_features_test'), 'role_features_test exists before delete.');
+    $this->assertTrue((bool)filter_format_load('features_test'), 'features_test exists before delete.');
+    $this->assertTrue((bool)menu_load('menu-menu-features-test'), 'menu-menu-features-test exists before delete.');
+
+    module_disable(array('features_test'));
+    drupal_uninstall_modules(array('features_test'));
+
+    $this->assertTrue(node_type_get_type('features_test'), 'features_test not deleted after uninstall.');
+    $this->assertTrue((bool)field_info_instance('node', 'field_features_test', 'features_test'), 'field_features_test for features_test not deleted after uninstall.');
+    $this->assertTrue((bool)field_info_field('field_features_test'), 'field_features_test not deleted after uninstall.');
+    $this->assertTrue((bool)taxonomy_vocabulary_machine_name_load('taxonomy_features_test'), 'taxonomy_features_test not deleted after uninstall.');
+    $this->assertTrue((bool)user_role_load_by_name('role_features_test'), 'role_features_test not deleted after uninstall.');
+    $this->assertTrue((bool)filter_format_load('features_test'), 'features_test not deleted after uninstall.');
+    $this->assertTrue((bool)menu_load('menu-menu-features-test'), 'menu-menu-features-test not deleted after uninstall.');
+  }
+}
+
 /**
  * Tests intergration of ctools for features.
  */
diff --git a/tests/features_test/features_test.info b/tests/features_test/features_test.info
index 2dc49c1..7aee71c 100644
--- a/tests/features_test/features_test.info
+++ b/tests/features_test/features_test.info
@@ -3,10 +3,15 @@ description = Test module for Features testing.
 core = 7.x
 package = Testing
 php = 5.2.0
+dependencies[] = ctools
 dependencies[] = features
+dependencies[] = filter
 dependencies[] = image
+dependencies[] = menu
+dependencies[] = node
 dependencies[] = strongarm
 dependencies[] = taxonomy
+dependencies[] = text
 dependencies[] = views
 features[ctools][] = strongarm:strongarm:1
 features[ctools][] = views:views_default:3.0
@@ -15,8 +20,10 @@ features[field_base][] = field_features_test
 features[field_instance][] = node-features_test-field_features_test
 features[filter][] = features_test
 features[image][] = features_test
+features[menu_custom][] = menu-menu-features-test
 features[node][] = features_test
 features[taxonomy][] = taxonomy_features_test
 features[user_permission][] = create features_test content
+features[user_role][] = role_features_test
 features[views_view][] = features_test
 hidden = 1
