diff --git a/workbench_moderation.api.php b/workbench_moderation.api.php
index 7dc8b9c..8267d8e 100644
--- a/workbench_moderation.api.php
+++ b/workbench_moderation.api.php
@@ -26,3 +26,28 @@ function hook_workbench_moderation_access_alter(&$access, $op, $node) {
     $access = FALSE;
   }
 }
+
+/**
+ * Allows modules to alter the list of possible next states for a node.
+ *
+ * @param &$states
+ *   An array of possible state changes, or FALSE if none were found before
+ *   invoking this hook. Passed by reference.
+ * @param $current_state
+ *   The current moderation state.
+ * @param $context
+ *   An associative array containing:
+ *   - 'account': The user object being checked.
+ *   - 'node': The node object being acted upon, or a node type string if the
+ *     caller could not provide a full object (i.e. on node creation).
+ *
+ * @see workbench_moderation_states_next()
+ */
+function hook_workbench_moderation_states_next_alter(&$states, $current_state, $context) {
+  // Do not permit users to give final approval to their own nodes, even if
+  // they would otherwise have rights to do so.
+  $published = workbench_moderation_state_published();
+  if (isset($states[$published]) && (is_string($context['node']) || $context['account']->uid == $context['node']->uid)) {
+    unset($states[$published]);
+  }
+}
diff --git a/workbench_moderation.module b/workbench_moderation.module
index 1d3846d..28817ba 100644
--- a/workbench_moderation.module
+++ b/workbench_moderation.module
@@ -410,7 +410,7 @@ function _workbench_moderation_access($op, $node) {
 
   if ($op == 'unpublish') {
     // workbench_moderation_states_next() checks transition permissions.
-    $next_states = workbench_moderation_states_next(workbench_moderation_state_published(), $user, $node->type);
+    $next_states = workbench_moderation_states_next(workbench_moderation_state_published(), $user, $node);
     $access &= !empty($next_states);
   }
 
@@ -477,7 +477,7 @@ function _workbench_moderation_moderate_access($node, $state) {
   global $user;
 
   $my_revision = $node->workbench_moderation['my_revision'];
-  $next_states = workbench_moderation_states_next($my_revision->state, $user, $node->type);
+  $next_states = workbench_moderation_states_next($my_revision->state, $user, $node);
   $access = node_access('update', $node, $user)       // the user can edit the node
           && $my_revision->current                    // this is the current revision (no branching the revision history)
           && (!empty($next_states))                   // there are next states the user may transition to
@@ -771,7 +771,7 @@ function workbench_moderation_form_node_form_alter(&$form, $form_state) {
   }
   // Get all the states *this* user can access. If states is false, this user
   // can not change the moderation state
-  if ($states = workbench_moderation_states_next($moderation_state, $user, $form['type']['#value'])) {
+  if ($states = workbench_moderation_states_next($moderation_state, $user, $form['#node'])) {
     $current = array($moderation_state => t('Current: @state', array('@state' => workbench_moderation_state_label($moderation_state))));
     $states = array_merge($current, $states);
     $form['options']['workbench_moderation_state_new'] = array(
@@ -1332,14 +1332,16 @@ function workbench_moderation_transition_delete($transition) {
  *   The current moderation state.
  * @param $account
  *   The user object being checked.
- * @param $node_type
- *   The node type being acted upon.
+ * @param $node
+ *   The node object being acted upon.
  *
  * @return
  *   If the user may moderate a change, return an array of possible state
  *   changes. Otherwise, return FALSE.
  */
-function workbench_moderation_states_next($current_state, $account = NULL, $node_type) {
+function workbench_moderation_states_next($current_state, $account = NULL, $node) {
+  $states = FALSE;
+
   // Make sure we have a current state.
   if (!$current_state) {
     $current_state = workbench_moderation_state_none();
@@ -1353,7 +1355,6 @@ function workbench_moderation_states_next($current_state, $account = NULL, $node
     // Some functions expect an array of $state => $state pairs.
     $states = workbench_moderation_state_labels();
     unset($states[$current_state]);
-    return $states;
   }
   else {
     // Get a list of possible transitions.
@@ -1370,15 +1371,16 @@ function workbench_moderation_states_next($current_state, $account = NULL, $node
     // workbench_moderation_state_allowed().
     if ($states) {
       foreach ($states as $machine_name => $label) {
-        if (!workbench_moderation_state_allowed($account, $current_state, $machine_name, $node_type)) {
+        if (!workbench_moderation_state_allowed($account, $current_state, $machine_name, $node->type)) {
           unset($states[$machine_name]);
         }
       }
-      return $states;
     }
   }
 
-  return FALSE;
+  $context = array('account' => $account, 'node' => $node);
+  drupal_alter('workbench_moderation_states_next', $states, $current_state, $context);
+  return $states;
 }
 
 /**
@@ -1543,7 +1545,7 @@ function workbench_moderation_moderate_callback($node, $state) {
  */
 function workbench_moderation_get_moderation_links($node, $url_options = array()) {
   // Make sure that this node type is moderated.
-  if (!workbench_moderation_node_type_moderated($node->type)) {
+  if (!workbench_moderation_node_type_moderated($node)) {
     return;
   }
 
@@ -1551,7 +1553,7 @@ function workbench_moderation_get_moderation_links($node, $url_options = array()
   $links = array();
   $my_revision = $node->workbench_moderation['my_revision'];
   if ($my_revision->vid == $node->workbench_moderation['current']->vid
-      && $next_states = workbench_moderation_states_next($my_revision->state, NULL, $node->type)) {
+      && $next_states = workbench_moderation_states_next($my_revision->state, NULL, $node)) {
     foreach ($next_states as $state => $label) {
       $link = array_merge($url_options, array(
         'title' => workbench_moderation_state_label($state),
@@ -1584,7 +1586,7 @@ function workbench_moderation_moderate_form($form, &$form_state, $node, $destina
   $links = array();
   $my_revision = $node->workbench_moderation['my_revision'];
   if ($my_revision->vid == $node->workbench_moderation['current']->vid
-      && $next_states = workbench_moderation_states_next($my_revision->state, $user, $node->type)) {
+      && $next_states = workbench_moderation_states_next($my_revision->state, $user, $node)) {
     $form['#destination'] = $destination;
     $form['node'] = array(
       '#type' => 'value',
@@ -1724,7 +1726,7 @@ function workbench_moderation_messages($context, $node = NULL) {
     }
 
     // Add an unpublish link.
-    $next_states = workbench_moderation_states_next(workbench_moderation_state_published(), $user, $node->type);
+    $next_states = workbench_moderation_states_next(workbench_moderation_state_published(), $user, $node);
     if ($revision_published && !empty($next_states) && $link = workbench_moderation_access_link(t('Unpublish this revision'), "node/{$node->nid}/moderation/{$node->vid}/unpublish")) {
       $info_block_messages[] = array(
         'label' => t('Actions'),
diff --git a/workbench_moderation.node.inc b/workbench_moderation.node.inc
index 3ca0d27..a42c740 100644
--- a/workbench_moderation.node.inc
+++ b/workbench_moderation.node.inc
@@ -172,7 +172,7 @@ function workbench_moderation_node_history_view($node) {
     if (!empty($node->workbench_moderation['published']) && $revision->vid == $node->workbench_moderation['published']->vid) {
       $row['data']['moderation'] = '<div class="moderation-state"><strong>' . t('This is the published revision.') . '</strong></div>';
       // Provide an unpublish link.
-      $next_states = workbench_moderation_states_next(workbench_moderation_state_published(), $user, $node->type);
+      $next_states = workbench_moderation_states_next(workbench_moderation_state_published(), $user, $node);
       if (!empty($next_states)) {
         $row['data']['moderation'] .= '<div class="moderation-actions">' . l(t('Unpublish'), "node/{$revision->nid}/moderation/{$revision->live_revision}/unpublish") . '</div>';
       }
@@ -258,7 +258,7 @@ function workbench_moderation_node_unpublish_form($form, &$form_state, $node) {
   );
 
   $current_state = $node->workbench_moderation['my_revision']->state;
-  if ($next_states = workbench_moderation_states_next($current_state, $user, $node->type)) {
+  if ($next_states = workbench_moderation_states_next($current_state, $user, $node)) {
     $form['state'] = array(
       '#title' => t('Set moderation state:'),
       '#type' => 'select',
