diff --git a/taxonomy_access.module b/taxonomy_access.module
index a7b94b0..962cd53 100644
--- a/taxonomy_access.module
+++ b/taxonomy_access.module
@@ -300,6 +300,7 @@ function taxonomy_access_field_info_alter(&$info) {
        $entity->uid = $account->uid;
      }
    }
+
    list($entity_id, , $bundle) = entity_extract_ids($entity_type, $entity);
    if ($entity_id) {
      // Load the entity.
@@ -482,35 +483,127 @@ function taxonomy_access_field_widget_taxonomy_autocomplete_form_alter(&$element
 }
 
 /**
- * Implements hook_field_widget_WIDGET_TYPE_form_alter().
+ * Implements hook_field_widget_form_alter().
  *
- * This implements the create grant for select widgets.
+ * This implements the create grant for options widgets:
+ * 1. Denies access if the user cannot alter the field values.
+ * 2. Attaches jQuery to disable values disallowed by create.
+ * 3. Adds the disallowed values from (2) to the element so they are available
+ *    to the custom validator.
+ * 4. Adds the custom validator.
  *
+ * We use JQuery to disable the options because of FAPI limitations:
  * @see
- *   _taxonomy_access_configure_options_widget()
+ *   http://drupal.org/node/284917
+ * @see
+ *   http://drupal.org/node/342316
+ * @see
+ *   http://drupal.org/node/12089
  */
-function taxonomy_access_field_widget_options_select_form_alter(&$element, &$form_state, $context) {
+function taxonomy_access_field_widget_form_alter(&$element, &$form_state, $context) {
   // Only act on taxonomy fields.
   if ($context['field']['type'] != 'taxonomy_term_reference') {
     return;
   }
-  _taxonomy_access_configure_options_widget($element, $context['field']['cardinality']);
-}
-
-/**
- * Implements hook_field_widget_WIDGET_TYPE_form_alter().
- *
- * This implements the create grant for checkbox/radio widgets.
- *
- * @see
- *   _taxonomy_access_configure_options_widget()
- */
-function taxonomy_access_field_widget_options_buttons_form_alter(&$element, &$form_state, $context) {
-  // Only act on taxonomy fields.
-  if ($context['field']['type'] != 'taxonomy_term_reference') {
+  // Only act on options widgets.
+  $widget = $context['instance']['widget']['type'];
+  if (!in_array($widget, array('options_buttons', 'options_select'))) {
     return;
   }
-  _taxonomy_access_configure_options_widget($element, $context['field']['cardinality']);
+
+  // Check for an existing entity ID.
+  $entity_id = 0;
+  if (!empty($form_state['build_info']['args'][0])) {
+    $info = entity_get_info($context['instance']['entity_type']);
+    $pseudo_entity = (object) $form_state['build_info']['args'][0];
+    if (isset($pseudo_entity->{$info['entity keys']['id']})) {
+      $entity_id = $pseudo_entity->{$info['entity keys']['id']};
+    }
+  }
+  // Enforce that list grants do not filter our queries.
+  taxonomy_access_disable_list();
+
+  // Collect a list of terms and determine which are allowed
+  $tids = array_keys($element['#options']);
+
+  // Ignore the "none" option if present.
+  $key = array_search('_none', $tids);
+  if ($key !== FALSE) {
+    unset($tids[$key]);
+  }
+
+  $allowed_tids = taxonomy_access_create_allowed($tids);
+  $disallowed_tids = taxonomy_access_create_disallowed($tids);
+
+  // If no options are allowed, deny access to the field.
+  if (empty($allowed_tids)) {
+    $element['#access'] = FALSE;
+  }
+
+  // On node creation, simply remove disallowed default values.
+  if (!$entity_id) {
+    $disallowed_defaults = array();
+    if (is_array($element['#default_value'])) {
+      foreach ($element['#default_value'] as $key => $value) {
+        if (in_array($value, $disallowed_tids)) {
+          unset($element['#default_value'][0]);
+        }
+      }
+    }
+    elseif (in_array($element['#default_value'], $disallowed_tids)) {
+      unset($element['#default_value']);
+    }
+  }
+  // If the node already exists, check:
+  // 1. Whether the field already has the maximum number of values
+  // 2. Whether all of these values are disallowed.
+  // If both these things are true, then the user cannot edit the field's
+  // value, so disallow access.
+  else {
+    $defaults =
+      is_array($element['#default_value'])
+      ? $element['#default_value']
+      : array($element['#default_value'])
+      ;
+
+    $disallowed_defaults =
+      array_intersect($defaults, $disallowed_tids);
+
+    if ($context['field']['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
+      if (sizeof($disallowed_defaults) >= $context['field']['cardinality']) {
+        $element['#access'] = FALSE;
+      }
+    }
+  }
+
+  // If there are disallowed, terms, add CSS and JS for jQuery.
+  // We use jQuery because FAPI does not currently support attributes
+  // for individual options.
+  if (!empty($disallowed_tids)) {
+
+    // Add a css class to the field that we can use in jQuery.
+    $class_name = 'tac_' . $element['#field_name'];
+    $element['#attributes']['class'][] = $class_name;
+
+    // Add js for disabling create options.
+    $settings[] = array(
+      'field' => $class_name,
+      'disallowed_tids' => $disallowed_tids,
+      'disallowed_defaults' => $disallowed_defaults,
+    );
+    $element['#attached']['js'][] =
+      drupal_get_path('module', 'taxonomy_access') . '/tac_create.js';
+    $element['#attached']['js'][] = array(
+      'data' => array('taxonomy_access' => $settings),
+      'type' => 'setting',
+    );
+  }
+
+  $element['#disallowed_defaults'] = $disallowed_defaults;
+  $element['#element_validate'] = array('taxonomy_access_options_validate');
+
+  // Re-enable list grants.
+  taxonomy_access_enable_list();
 }
 
 
@@ -1705,93 +1798,6 @@ function _taxonomy_access_term_options($field) {
   return $options;
 }
 
-
-/**
- * Helper function for hook_field_widget_form_alter() on options widgets.
- *
- * This implements the create grant for options widgets:
- * 1. Denies access if the user cannot alter the field values.
- * 2. Attaches jQuery to disable values disallowed by create.
- * 3. Adds the disallowed values from (2) to the element so they are available
- *    to the custom validator.
- * 4. Adds the custom validator.
- *
- * We use JQuery to disable the options because of FAPI limitations:
- * @see
- *   http://drupal.org/node/284917
- * @see
- *   http://drupal.org/node/342316
- * @see
- *   http://drupal.org/node/12089
- */
-function _taxonomy_access_configure_options_widget(&$element, $field_size) {
-  // Enforce that list grants do not filter our queries.
-  taxonomy_access_disable_list();
-
-  // Collect a list of terms and determine which are allowed
-  $tids = array_keys($element['#options']);
-
-  // Ignore the "none" option if present.
-  $key = array_search('_none', $tids);
-  if ($key !== FALSE) {
-    unset($tids[$key]);
-  }
-
-  $allowed_tids = taxonomy_access_create_allowed($tids);
-  $disallowed_tids = taxonomy_access_create_disallowed($tids);
-
-  // If no options are allowed, deny access to the field.
-  if (empty($allowed_tids)) {
-    $element['#access'] = FALSE;
-  }
-
-  // If the field already has the maximum number of values, and all of these
-  // values are disallowed, deny access to the field.
-  $defaults =
-    is_array($element['#default_value'])
-    ? $element['#default_value']
-    : array($element['#default_value'])
-    ;
-
-  $disallowed_defaults =
-    array_intersect($defaults, $disallowed_tids);
-  if ($field_size != FIELD_CARDINALITY_UNLIMITED) {
-    if (sizeof($disallowed_defaults) >= $field_size) {
-      $element['#access'] = FALSE;
-    }
-  }
-
-  // If there are disallowed, terms, add CSS and JS for jQuery.
-  // We use jQuery because FAPI does not currently support attributes
-  // for individual options.
-  if (!empty($disallowed_tids)) {
-
-    // Add a css class to the field that we can use in jQuery.
-    $class_name = 'tac_' . $element['#field_name'];
-    $element['#attributes']['class'][] = $class_name;
-
-    // Add js for disabling create options.
-    $settings[] = array(
-      'field' => $class_name,
-      'disallowed_tids' => $disallowed_tids,
-      'disallowed_defaults' => $disallowed_defaults,
-    );
-    $element['#attached']['js'][] =
-      drupal_get_path('module', 'taxonomy_access') . '/tac_create.js';
-    $element['#attached']['js'][] = array(
-      'data' => array('taxonomy_access' => $settings),
-      'type' => 'setting',
-    );
-  }
-
-  $element['#disallowed_defaults'] = $disallowed_defaults;
-  $element['#element_validate'] = array('taxonomy_access_options_validate');
-
-  // Re-enable list grants.
-  taxonomy_access_enable_list();
-
-}
-
 /**
  * Validation to process option sets, which may have some terms disabled.
  *
