diff --git modules/menu/menu.module modules/menu/menu.module
index d72fbdd..bd1389e 100644
--- modules/menu/menu.module
+++ modules/menu/menu.module
@@ -596,7 +596,6 @@ function menu_form_alter(&$form, $form_state, $form_id) {
       return;
     }
     $link = $form['#node']->menu;
-    $form['#submit'][] = 'menu_node_form_submit';
 
     $form['menu'] = array(
       '#type' => 'fieldset',
@@ -661,15 +660,15 @@ function menu_form_alter(&$form, $form_state, $form_id) {
 }
 
 /**
- * Submit handler for node form.
+ * Implements hook_node_submit().
  *
  * @see menu_form_alter()
  */
-function menu_node_form_submit($form, &$form_state) {
+function menu_node_submit($node, $form, &$form_state) {
   // Decompose the selected menu parent option into 'menu_name' and 'plid', if
   // the form used the default parent selection widget.
   if (!empty($form_state['values']['menu']['parent'])) {
-    list($form_state['values']['menu']['menu_name'], $form_state['values']['menu']['plid']) = explode(':', $form_state['values']['menu']['parent']);
+    list($node->menu['menu_name'], $node->menu['plid']) = explode(':', $form_state['values']['menu']['parent']);
   }
 }
 
diff --git modules/node/node.pages.inc modules/node/node.pages.inc
index fce7bfd..94ccd8e 100644
--- modules/node/node.pages.inc
+++ modules/node/node.pages.inc
@@ -91,7 +91,8 @@ function node_form($form, &$form_state, $node) {
   }
 
   if (isset($form_state['node'])) {
-    $node = (object)($form_state['node'] + (array)$node);
+    // Does PHP not have a nicer way to merge two stdClasses?
+    $node = (object) ((array)$form_state['node'] + (array)$node);
   }
   if (isset($form_state['node_preview'])) {
     $form['#prefix'] = $form_state['node_preview'];
@@ -246,7 +247,6 @@ function node_form($form, &$form_state, $node) {
     '#access' => variable_get('node_preview_' . $node->type, DRUPAL_OPTIONAL) != DRUPAL_REQUIRED || (!form_get_errors() && isset($form_state['node_preview'])),
     '#value' => t('Save'),
     '#weight' => 5,
-    '#submit' => array('node_form_submit'),
   );
   $form['actions']['preview'] = array(
     '#access' => variable_get('node_preview_' . $node->type, DRUPAL_OPTIONAL) != DRUPAL_DISABLED,
@@ -263,6 +263,8 @@ function node_form($form, &$form_state, $node) {
       '#submit' => array('node_form_delete_submit'),
     );
   }
+
+  $form['#submit'][] = 'node_form_submit';
   $form['#validate'][] = 'node_form_validate';
   $form['#theme'] = array($node->type . '_node_form', 'node_form');
 
@@ -419,15 +421,14 @@ function node_form_submit($form, &$form_state) {
  * Build a node by processing submitted form values and prepare for a form rebuild.
  */
 function node_form_submit_build_node($form, &$form_state) {
-  // Unset any button-level handlers, execute all the form-level submit
-  // functions to process the form values into an updated node.
-  unset($form_state['submit_handlers']);
-  form_execute_handlers('submit', $form, $form_state);
   $node = node_submit((object)$form_state['values']);
 
+  // Invoke the various submit hooks.
+  module_invoke_all('node_submit', $node, $form, $form_state);
+  entity_invoke('submit', 'node', $node, $form, $form_state);
   field_attach_submit('node', $node, $form, $form_state);
 
-  $form_state['node'] = (array)$node;
+  $form_state['node'] = $node;
   $form_state['rebuild'] = TRUE;
   return $node;
 }
diff --git modules/poll/poll.module modules/poll/poll.module
index eab52b2..8e9ac11 100644
--- modules/poll/poll.module
+++ modules/poll/poll.module
@@ -419,12 +419,18 @@ function poll_choice_js($form, $form_state) {
 }
 
 /**
+ * Implements of hook_node_submit().
+ *
  * Renumber fields and create a teaser when a poll node is submitted.
  */
-function poll_node_form_submit(&$form, &$form_state) {
+function poll_node_submit($node, &$form, &$form_state) {
+  if ($node->type != 'poll') {
+    return;
+  }
   // Renumber fields
-  $form_state['values']['choice'] = array_values($form_state['values']['choice']);
-  $form_state['values']['teaser'] = poll_teaser((object)$form_state['values']);
+  $node->choice = array_values($form_state['values']['choice']);
+  // @todo: I think this is not used anywhere.
+  $node->teaser = poll_teaser((object)$form_state['values']);
 }
 
 /**
