diff --git a/features.export.inc b/features.export.inc
index 7d7a5f8..0d45caf 100644
--- a/features.export.inc
+++ b/features.export.inc
@@ -45,17 +45,33 @@ function _features_populate($pipe, &$export, $module_name = '') {
   foreach ($pipe as $component => $data) {
     static $processed = array();
     // Convert already defined items to dependencies.
-    _features_resolve_dependencies($data, $export, $module_name, $component);
+    _features_resolve_component_conflicts($data, $export, $module_name, $component);
     if (!empty($data) && $function = features_hook($component, 'features_export')) {
       // Pass module-specific data and export array.
       // We don't use features_invoke() here since we need to pass $export by reference.
       $more = $function($data, $export, $module_name, $component);
       // Add the context information.
       $export['component'] = $component;
+
+      // Gather any suggestions for items to add to feature if not already provided.
+      if ($function = features_hook($component, 'features_pipe_suggestions')) {
+        $suggestions = $function($data, $export, $module_name, $component);
+        drupal_alter(array('features_pipe_suggestions', 'features_pipe_suggestions_' . $component), $suggestions, $data, $export);
+        foreach ($suggestions as $component_type => $suggestion) {
+          _features_resolve_component_conflicts($suggestion, $export, $module_name, $component_type, FALSE);
+          if ($suggestion) {
+            $more[$component_type] = isset($more[$component_type]) ? $more[$component_type] : array();
+            $more[$component_type] = array_merge($more[$component_type], $suggestion);
+          }
+        }
+      }
+
       // Allow other modules to manipulate the pipe to add in additional modules.
       drupal_alter(array('features_pipe', 'features_pipe_' . $component), $more, $data, $export);
+
       // Remove the component information.
       unset($export['component']);
+
       // Allow for export functions to request additional exports, but avoid
       // circular references on already processed components.
       $processed[$component] = isset($processed[$component]) ? array_merge($processed[$component], $data) : $data;
@@ -79,12 +95,17 @@ function _features_populate($pipe, &$export, $module_name = '') {
 /**
  * Iterates over data and convert to dependencies if already defined elsewhere.
  */
-function _features_resolve_dependencies(&$data, &$export, $module_name, $component) {
+function _features_resolve_component_conflicts(&$data, &$export, $module_name, $component, $add_dependency = TRUE) {
+  // Clean out any invalid options.
+  $options = features_export_options($component);
+  $data = array_intersect($data, array_keys($options));
   if ($map = features_get_default_map($component)) {
     foreach ($data as $key => $item) {
       // If this node type is provided by a different module, add it as a dependency
-      if (isset($map[$item]) && $map[$item] != $module_name) {
-        $export['dependencies'][$map[$item]] = $map[$item];
+      if (isset($map[$item]) && $map[$item] != $module_name && module_exists($module_name)) {
+        if ($add_dependency) {
+          $export['dependencies'][$map[$item]] = $map[$item];
+        }
         unset($data[$key]);
       }
     }
@@ -879,3 +900,17 @@ function _features_sanitize(&$array) {
 function _features_is_assoc($array) {
   return (is_array($array) && (0 !== count(array_diff_key($array, array_keys(array_keys($array)))) || count($array)==0));
 }
+
+/**
+ * Returns options for a given component.
+ */
+function features_export_options($component) {
+  $options = &drupal_static(__FUNCTION__, array());
+  if (!isset($options[$component])) {
+    $options[$component] = features_invoke($component, 'features_export_options');
+    if (!isset($options[$component])) {
+      $options[$component] = array();
+    }
+  }
+  return $options[$component];
+}
diff --git a/includes/features.context.inc b/includes/features.context.inc
index 2da59a7..5e7e445 100644
--- a/includes/features.context.inc
+++ b/includes/features.context.inc
@@ -1,9 +1,9 @@
 <?php
 
 /**
- * Implements hook_features_export().
+ * Implements hook_features_pipe_suggestions().
  */
-function context_features_export($data, &$export, $module_name = '') {
+function context_features_pipe_suggestions($data, &$export, $module_name = '') {
   $pipe = ctools_component_features_export('context', $data, $export, $module_name);
 
   $contexts = context_load();
diff --git a/includes/features.field.inc b/includes/features.field.inc
index 96b22b4..0672569 100644
--- a/includes/features.field.inc
+++ b/includes/features.field.inc
@@ -37,7 +37,6 @@ function field_features_export_options() {
  */
 function field_features_export($data, &$export, $module_name = '') {
   $pipe = array();
-  $map = features_get_default_map('field');
 
   // The field_default_fields() hook integration is provided by the
   // features module so we need to add it as a dependency.
@@ -45,33 +44,21 @@ function field_features_export($data, &$export, $module_name = '') {
 
   foreach ($data as $identifier) {
     if ($field = features_field_load($identifier)) {
-      // If this field is already provided by another module, remove the field
-      // and add the other module as a dependency.
-      if (isset($map[$identifier]) && $map[$identifier] != $module_name) {
-        if (isset($export['features']['field'][$identifier])) {
-          unset($export['features']['field'][$identifier]);
+      $export['features']['field'][$identifier] = $identifier;
+      $export['dependencies'][$field['field_config']['module']] = $field['field_config']['module'];
+      $export['dependencies'][$field['field_config']['storage']['module']] = $field['field_config']['storage']['module'];
+      $export['dependencies'][$field['field_instance']['widget']['module']] = $field['field_instance']['widget']['module'];
+      foreach ($field['field_instance']['display'] as $key => $display) {
+        if (isset($display['module'])) {
+          $export['dependencies'][$display['module']] = $display['module'];
+          // @TODO: handle the pipe to image styles
         }
-        $module = $map[$identifier];
-        $export['dependencies'][$module] = $module;
       }
-      // If the field has not yet been exported, add it
-      else {
-        $export['features']['field'][$identifier] = $identifier;
-        $export['dependencies'][$field['field_config']['module']] = $field['field_config']['module'];
-        $export['dependencies'][$field['field_config']['storage']['module']] = $field['field_config']['storage']['module'];
-        $export['dependencies'][$field['field_instance']['widget']['module']] = $field['field_instance']['widget']['module'];
-        foreach ($field['field_instance']['display'] as $key => $display) {
-          if (isset($display['module'])) {
-            $export['dependencies'][$display['module']] = $display['module'];
-            // @TODO: handle the pipe to image styles
-          }
-        }
-        // If taxonomy field, add in the vocabulary
-        if ($field['field_config']['type'] == 'taxonomy_term_reference' && !empty($field['field_config']['settings']['allowed_values'])) {
-          foreach ($field['field_config']['settings']['allowed_values'] as $allowed_values) {
-            if (!empty($allowed_values['vocabulary'])) {
-              $pipe['taxonomy'][] = $allowed_values['vocabulary'];
-            }
+      // If taxonomy field, add in the vocabulary
+      if ($field['field_config']['type'] == 'taxonomy_term_reference' && !empty($field['field_config']['settings']['allowed_values'])) {
+        foreach ($field['field_config']['settings']['allowed_values'] as $allowed_values) {
+          if (!empty($allowed_values['vocabulary'])) {
+            $pipe['taxonomy'][] = $allowed_values['vocabulary'];
           }
         }
       }
diff --git a/includes/features.image.inc b/includes/features.image.inc
index 9eee8db..286b2a2 100644
--- a/includes/features.image.inc
+++ b/includes/features.image.inc
@@ -30,19 +30,9 @@ function image_features_export_options() {
  */
 function image_features_export($data, &$export, $module_name = '') {
   $pipe = array();
-  $map = features_get_default_map('image');
-  foreach ($data as $style) {
-    $export['dependencies']['image'] = 'image';
-    // If another module provides this style, add it as a dependency
-    if (isset($map[$style]) && $map[$style] != $module_name) {
-      $module = $map[$style];
-      $export['dependencies'][$module] = $module;
-    }
-    // Otherwise, export the style
-    elseif (image_style_load($style)) {
-      $export['features']['image'][$style] = $style;
-    }
-  }
+  $export['dependencies']['image'] = 'image';
+  $export['features']['image'] = isset($export['features']['image']) ? $export['features']['image'] : array();
+  $export['features']['image'] += array_combine($data, $data);
   return $pipe;
 }
 
diff --git a/includes/features.menu.inc b/includes/features.menu.inc
index 3060aa0..35d47ca 100644
--- a/includes/features.menu.inc
+++ b/includes/features.menu.inc
@@ -56,23 +56,16 @@ function menu_custom_features_export_options() {
  * Implements hook_features_export().
  */
 function menu_custom_features_export($data, &$export, $module_name = '') {
+  $pipe = array();
   // Default hooks are provided by the feature module so we need to add
   // it as a dependency.
   $export['dependencies']['features'] = 'features';
   $export['dependencies']['menu'] = 'menu';
+  $export['features']['menu_custom'] = isset($export['features']['menu_custom']) ? $export['features']['menu_custom'] : array();
+  $export['features']['menu_custom'] += array_combine($data, $data);
 
   // Collect a menu to module map
-  $pipe = array();
-  $map = features_get_default_map('menu_custom', 'menu_name');
-  foreach ($data as $menu_name) {
-    // If this menu is provided by a different module, add it as a dependency.
-    if (isset($map[$menu_name]) && $map[$menu_name] != $module_name) {
-      $export['dependencies'][$map[$menu_name]] = $map[$menu_name];
-    }
-    else {
-      $export['features']['menu_custom'][$menu_name] = $menu_name;
-    }
-  }
+
   return $pipe;
 }
 
@@ -160,29 +153,22 @@ function menu_links_features_identifier($link) {
  * Implements hook_features_export().
  */
 function menu_links_features_export($data, &$export, $module_name = '') {
+  $pipe = array();
   // Default hooks are provided by the feature module so we need to add
   // it as a dependency.
   $export['dependencies']['features'] = 'features';
   $export['dependencies']['menu'] = 'menu';
+  $export['features']['menu_links'] = isset($export['features']['menu_links']) ? $export['features']['menu_links'] : array();
+  $export['features']['menu_links'] += array_combine($data, $data);
 
   // Collect a link to module map
-  $pipe = array();
-  $map = features_get_default_map('menu_links', 'menu_links_features_identifier');
   foreach ($data as $identifier) {
-    if ($link = features_menu_link_load($identifier)) {
-      // If this link is provided by a different module, add it as a dependency.
-      if (isset($map[$identifier]) && $map[$identifier] != $module_name) {
-        $export['dependencies'][$map[$identifier]] = $map[$identifier];
-      }
-      else {
-        $export['features']['menu_links'][$identifier] = $identifier;
-      }
-      // For now, exclude a variety of common menus from automatic export.
-      // They may still be explicitly included in a Feature if the builder
-      // chooses to do so.
-      if (!in_array($link['menu_name'], array('features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel'))) {
-        $pipe['menu_custom'][] = $link['menu_name'];
-      }
+    $link = features_menu_link_load($identifier);
+    // For now, exclude a variety of common menus from automatic export.
+    // They may still be explicitly included in a Feature if the builder
+    // chooses to do so.
+    if ($link && !in_array($link['menu_name'], array('features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel'))) {
+      $pipe['menu_custom'][] = $link['menu_name'];
     }
   }
   return $pipe;
diff --git a/includes/features.node.inc b/includes/features.node.inc
index af35e25..e6223cb 100644
--- a/includes/features.node.inc
+++ b/includes/features.node.inc
@@ -23,28 +23,26 @@ function node_features_export_options() {
 /**
  * Implements hook_features_export.
  */
-function node_features_export($data, &$export, $module_name = '') {
+function node_features_export(&$data, &$export, $module_name = '') {
   $pipe = array();
-  $map = features_get_default_map('node');
 
-  foreach ($data as $type) {
-    // Poll node module to determine who provides the node type.
-    if ($info = node_type_get_type($type)) {
-      // If this node type is provided by a different module, add it as a dependency
-      if (isset($map[$type]) && $map[$type] != $module_name) {
-        $export['dependencies'][$map[$type]] = $map[$type];
-      }
-      // Otherwise export the node type.
-      elseif (in_array($info->base, array('node_content', 'features'))) {
-        $export['features']['node'][$type] = $type;
-        $export['dependencies']['node'] = 'node';
-        $export['dependencies']['features'] = 'features';
-      }
+  $export['dependencies']['node'] = 'node';
+  $export['dependencies']['features'] = 'features';
+  $export['features']['node'] = isset($export['features']['node']) ? $export['features']['node'] : array();
+  $export['features']['node'] += array_combine($data, $data);
 
-      $fields = field_info_instances('node', $type);
-      foreach ($fields as $name => $field) {
-        $pipe['field'][] = "node-{$field['bundle']}-{$field['field_name']}";
-      }
+  return $pipe;
+}
+
+/**
+ * Implements hook_features_pipe_suggestions().
+ */
+function node_features_pipe_suggestions($data, &$export, $module_name = '') {
+  $pipe = array();
+
+  foreach ($data as $type) {
+    foreach (field_info_instances('node', $type) as $name => $field) {
+      $pipe['field'][] = "node-{$field['bundle']}-{$field['field_name']}";
     }
   }
 
diff --git a/includes/features.taxonomy.inc b/includes/features.taxonomy.inc
index 5ac4ec5..6daccf3 100644
--- a/includes/features.taxonomy.inc
+++ b/includes/features.taxonomy.inc
@@ -36,20 +36,19 @@ function taxonomy_features_export($data, &$export, $module_name = '') {
   // taxonomy_default_vocabularies integration is provided by Features.
   $export['dependencies']['features'] = 'features';
   $export['dependencies']['taxonomy'] = 'taxonomy';
+  $export['features']['taxonomy'] = isset($export['features']['taxonomy']) ? $export['features']['taxonomy'] : array();
+  $export['features']['taxonomy'] += array_combine($data, $data);
+  return $pipe;
+}
 
-  // Add dependencies for each vocabulary.
-  $map = features_get_default_map('taxonomy');
+/**
+ * Implements hook_features_pipe_suggestions().
+ */
+function taxonomy_features_pipe_suggestions($data, &$export, $module_name = '') {
+  $pipe = array();
   foreach ($data as $machine_name) {
-    if (isset($map[$machine_name]) && $map[$machine_name] != $module_name) {
-      $export['dependencies'][$map[$machine_name]] = $map[$machine_name];
-    }
-    else {
-      $export['features']['taxonomy'][$machine_name] = $machine_name;
-
-      $fields = field_info_instances('taxonomy_term', $machine_name);
-      foreach ($fields as $name => $field) {
-        $pipe['field'][] = "taxonomy_term-{$field['bundle']}-{$field['field_name']}";
-      }
+    foreach (field_info_instances('taxonomy_term', $machine_name) as $name => $field) {
+      $pipe['field'][] = "taxonomy_term-{$field['bundle']}-{$field['field_name']}";
     }
   }
   return $pipe;
diff --git a/includes/features.user.inc b/includes/features.user.inc
index c76455d..c67874d 100644
--- a/includes/features.user.inc
+++ b/includes/features.user.inc
@@ -147,17 +147,8 @@ function user_permission_features_rebuild($module) {
  */
 function user_role_features_export($data, &$export, $module_name = '') {
   $export['dependencies']['features'] = 'features';
-  $map = features_get_default_map('user_role', 'name');
-  foreach ($data as $role) {
-    // Role is provided by another module. Add dependency.
-    if (isset($map[$role]) && $map[$role] != $module_name) {
-      $export['dependencies'][$map[$role]] = $map[$role];
-    }
-    // Export.
-    elseif(user_role_load_by_name($role)) {
-      $export['features']['user_role'][$role] = $role;
-    }
-  }
+  $export['features']['user_role'] = isset($export['features']['user_role']) ? $export['features']['user_role'] : array();
+  $export['features']['user_role'] += array_combine($data, $data);
   return array();
 }
 
