diff --git a/workbench_moderation.module b/workbench_moderation.module
index f510e2e..a5c0fc5 100644
--- a/workbench_moderation.module
+++ b/workbench_moderation.module
@@ -675,13 +675,28 @@ function workbench_moderation_node_update($node) {
     return;
   }
 
-  // Set default moderation state values.
+  // Set moderation state values.
   if (!isset($node->workbench_moderation_state_current)) {
-    $node->workbench_moderation_state_current = ($node->status ? workbench_moderation_state_published() : workbench_moderation_state_none());
-  };
+    $node->workbench_moderation_state_current = !empty($node->original->workbench_moderation['current']->state) ? $node->original->workbench_moderation['current']->state : workbench_moderation_state_none();
+  }
   if (!isset($node->workbench_moderation_state_new)) {
-    $node->workbench_moderation_state_new = variable_get('workbench_moderation_default_state_' . $node->type, workbench_moderation_state_none());
-  };
+    // Moving from published to unpublished.
+    if ($node->status == NODE_NOT_PUBLISHED && isset($node->original->status) && $node->original->status == NODE_PUBLISHED) {
+      $node->workbench_moderation_state_new = variable_get('workbench_moderation_default_state_' . $node->type, workbench_moderation_state_none());
+    }
+    // Moving from unpublished to published.
+    elseif ($node->status == NODE_PUBLISHED && isset($node->original->status) && $node->original->status == NODE_NOT_PUBLISHED) {
+      $node->workbench_moderation_state_new = workbench_moderation_state_published();
+    }
+    else {
+      if (!empty($node->original->workbench_moderation['current']->state)) {
+        $node->workbench_moderation_state_new = $node->original->workbench_moderation['current']->state;
+      }
+      else {
+        $node->workbench_moderation_state_new = variable_get('workbench_moderation_default_state_' . $node->type, workbench_moderation_state_none());
+      }
+    }
+  }
 
   // If this is a new node, give it some information about 'my revision'.
   if (!isset($node->workbench_moderation)) {
@@ -1526,8 +1541,11 @@ function workbench_moderation_moderate($node, $state) {
     // If we're moderating the published revision to a non-published state,
     // remove the workbench moderation 'published' property.
     unset($node->workbench_moderation['published']);
+    drupal_register_shutdown_function('workbench_moderation_store_unpublish', $node);
+
   }
 
+
   // If we're moderating an unpublished revision and there is an existing
   // published revision, make sure that the published revision is live.
   // We do this in a shutdown function to avoid race conditions when
@@ -1536,7 +1554,6 @@ function workbench_moderation_moderate($node, $state) {
     drupal_register_shutdown_function('workbench_moderation_store', $node);
   }
 
-
   // Notify other modules that the state was changed.
   module_invoke_all('workbench_moderation_transition', $node, $old_revision->state, $state);
 }
@@ -1580,6 +1597,44 @@ function workbench_moderation_store($node) {
 }
 
 /**
+ * Shutdown callback for unpublishing a node revision.
+ *
+ * This function is called by drupal_register_shutdown_function().
+ * The purpose is to delay a node_save() call so that a live revision
+ * is not called during hook_node_update().
+ *
+ * Instead, we delay the update until the new revision is saved. This way,
+ * we can more safely call the revision and pick up changes to items
+ * that are not revisioned (such as menu and path assignments).
+ *
+ * @see workbench_moderation_moderate()
+ *
+ * @param $node
+ *   The node being saved.
+ */
+function workbench_moderation_store_unpublish($node) {
+  if (!isset($node->nid)) {
+    watchdog('Workbench moderation', 'Failed to save node revision: node not passed to shutdown function.', array(), WATCHDOG_NOTICE);
+    return;
+  }
+  watchdog('Workbench moderation', 'Saved node revision: %node as live version for node %live.', array('%node' => $node->vid, '%live' => $node->nid), WATCHDOG_NOTICE, l($node->title, 'node/' . $node->nid));
+
+  // Remove the moderation record's "published" flag.
+  $query = db_update('workbench_moderation_node_history')
+    ->condition('hid', $node->workbench_moderation['published']->hid)
+    ->fields(array('published' => 0))
+    ->execute();
+
+  // Make sure the 'current' revision is the 'live' revision -- ie, the revision
+  // in {node}.
+  $live_revision = workbench_moderation_node_current_load($node);
+  $live_revision->status = 0;
+  $live_revision->revision = 0;
+  $live_revision->workbench_moderation['updating_live_revision'] = TRUE;
+  node_save($live_revision);
+}
+
+/**
  * Helper function to redirect after a state change submission.
  *
  * @param $node
diff --git a/workbench_moderation.node.inc b/workbench_moderation.node.inc
index 5baaf59..c5ede9b 100644
--- a/workbench_moderation.node.inc
+++ b/workbench_moderation.node.inc
@@ -284,24 +284,9 @@ function workbench_moderation_node_unpublish_form_submit($form, &$form_state) {
   global $user;
   $node = $form['node']['#value'];
 
-  // Remove the moderation record's "published" flag.
-  $query = db_update('workbench_moderation_node_history')
-    ->condition('hid', $node->workbench_moderation['published']->hid)
-    ->fields(array('published' => 0))
-    ->execute();
-
-  // Moderate the revision.
+  // Moderate the revision. This will do the heavy lifting
   workbench_moderation_moderate($node, $form_state['values']['state']);
 
-  // Make sure the 'current' revision is the 'live' revision -- ie, the revision
-  // in {node}.
-  $live_revision = workbench_moderation_node_current_load($node);
-  $live_revision->status = 0;
-  $live_revision->revision = 0;
-  $live_revision->workbench_moderation['updating_live_revision'] = TRUE;
-  // @TODO: do we trust node_save() here?
-  node_save($live_revision);
-
   drupal_set_message(t('The live revision of this content has been unpublished.'));
   $form_state['redirect'] ="node/{$node->nid}/moderation";
 }
