diff --git a/commerce.info b/commerce.info
index 7799c71..34851cb 100644
--- a/commerce.info
+++ b/commerce.info
@@ -1,6 +1,7 @@
 name = Commerce
 description = Defines features and functions common to the Commerce modules. Must be enabled to uninstall other Commerce modules.
 package = Commerce
+dependencies[] = system (>=7.4)
 dependencies[] = entity
 dependencies[] = rules
 core = 7.x
diff --git a/commerce.install b/commerce.install
index 85fb9b0..03f4dbc 100644
--- a/commerce.install
+++ b/commerce.install
@@ -6,6 +6,23 @@
 
 
 /**
+ * Implements hook_install().
+ */
+function commerce_install() {
+  // Give commerce.module a higher weight than field.module so we can use
+  // hook_system_info_alter() to override the dependencies it adds.
+  $weight = db_select('system', 's')
+              ->fields('s', array('weight'))
+              ->condition('name', 'field', '=')
+              ->execute()
+              ->fetchField();
+  db_update('system')
+    ->fields(array('weight' => $weight + 1))
+    ->condition('name', 'commerce', '=')
+    ->execute();
+}
+
+/**
  * Implements hook_uninstall().
  */
 function commerce_uninstall() {
@@ -289,3 +306,20 @@ function commerce_update_7101() {
   cache_clear_all('commerce_currencies:', 'cache', TRUE);
   return t('Cached currency data has been deleted and will be rebuilt to include new formatting parameters.');
 }
+
+/**
+ * Give commerce.module a higher weight than field.module so we can use
+ * hook_system_info_alter() to remove the dependencies it adds.
+ */
+function commerce_update_7102() {
+  $weight = db_select('system', 's')
+              ->fields('s', array('weight'))
+              ->condition('name', 'field', '=')
+              ->execute()
+              ->fetchField();
+  db_update('system')
+    ->fields(array('weight' => $weight + 1))
+    ->condition('name', 'commerce', '=')
+    ->execute();
+  return t('The module weight for Commerce has been increased.');
+}
diff --git a/commerce.module b/commerce.module
index ce69fa6..a1a1b3d 100644
--- a/commerce.module
+++ b/commerce.module
@@ -54,6 +54,33 @@ function commerce_hook_info() {
 }
 
 /**
+ * Implements hook_system_info_alter().
+ *
+ * Drupal's Field module doesn't allow field type providing modules to be
+ * disabled while fields and instances of those types exist in the system.
+ * See http://drupal.org/node/943772 for further explanation.
+ * That approach doesn't work for Commerce, creating circular dependencies
+ * and making uninstall impossible.
+ * This function removes the requirement, allowing Commerce to implement its
+ * own workaround.
+ *
+ * @see commerce_delete_field()
+ */
+function commerce_system_info_alter(&$info, $file, $type) {
+  $modules = array(
+    'commerce_product_reference',
+    'commerce_price',
+    'commerce_customer',
+    'commerce_line_item',
+  );
+
+  if ($type == 'module' && in_array($file->name, $modules)) {
+    unset($info['required']);
+    unset($info['explanation']);
+  }
+}
+
+/**
  * Finds all fields of a particular field type.
  *
  * @param $field_type
@@ -178,6 +205,11 @@ function commerce_delete_fields($type) {
  * work on disabled fields. As a workaround, this function first activates the
  * fields of the specified type and then deletes them.
  *
+ * Deleting reactivated fields doesn't call the hook_field_delete()
+ * implementations of their parent modules (since they are already disabled),
+ * making this approach infeasible for core, but perfect for Commerce,
+ * since it doesn't implement that hook for any of its field types.
+ *
  * @param $field_name
  *   The name of the field to enable and delete.
  */
@@ -204,7 +236,6 @@ function commerce_delete_instances($entity_type, $bundle = NULL) {
   $params = array(
     'entity_type' => $entity_type,
   );
-
   if (!empty($bundle)) {
     $params['bundle'] = $bundle;
   }
@@ -213,6 +244,19 @@ function commerce_delete_instances($entity_type, $bundle = NULL) {
   foreach (field_read_instances($params, array('include_inactive' => TRUE)) as $instance) {
     commerce_delete_instance($instance);
   }
+
+  // Since this is a function called on uninstall, now is a good time
+  // to clear bundle display settings.
+  $settings = variable_get('field_bundle_settings', array());
+  if (isset($settings[$entity_type])) {
+    if (isset($bundle)) {
+      unset($settings[$entity_type][$bundle]);
+    }
+    else {
+      unset($settings[$entity_type]);
+    }
+    variable_set('field_bundle_settings', $settings);
+  }
 }
 
 /**
diff --git a/modules/product_reference/commerce_product_reference.install b/modules/product_reference/commerce_product_reference.install
index d0132d9..a590bb7 100644
--- a/modules/product_reference/commerce_product_reference.install
+++ b/modules/product_reference/commerce_product_reference.install
@@ -30,6 +30,6 @@ function commerce_product_reference_field_schema($field) {
  * Implements hook_uninstall().
  */
 function commerce_product_reference_uninstall() {
-  // Delete any product referencefields.
+  // Delete any product reference fields.
   commerce_delete_fields('commerce_product_reference');
 }
