diff --git a/taxonomy_menu.module b/taxonomy_menu.module
index 1dfe363..4024147 100644
--- a/taxonomy_menu.module
+++ b/taxonomy_menu.module
@@ -94,6 +94,12 @@ function taxonomy_menu_form_alter(&$form, &$form_state, $form_id) {
     $form['#submit'][] = 'taxonomy_menu_vocab_submit';
 
   }
+  elseif ($form_id == "taxonomy_overview_terms") {
+    // add an extra submit handler to sync the rearranged terms with menu
+    // @ TODO: using hook_taxonomy_vocabulary_update is nicer then callback,
+    // but gives less info and does not always fire.
+    $form['#submit'][] = 'taxonomy_menu_overview_submit';
+  }
 }
 
 /**
@@ -185,6 +191,55 @@ function taxonomy_menu_vocab_submit($form, &$form_state) {
 }
 
 /**
+ * Submit handler, reacting on form ID: taxonomy_overview_terms
+ */
+function taxonomy_menu_overview_submit(&$form, &$form_state) {
+  // Only sync if taxonomy_menu is enabled for this vocab and the 'sync'
+  // option has been checked.
+
+  // This form has the following flow of buttons:
+  // 1. [Save] --> rebuild taxonomy_menu
+  // 2. [Reset to alphabetical] --> no rebuild yet
+  // 3. [Reset to alphabetical][Reset to alphabetical] --> rebuild
+  // 4. [Reset to alphabetical][Cancel] --> no rebuild
+  // The code below avoids rebuilding after situation 2.
+
+  if ($form_state['rebuild'] == FALSE && isset($form['#vocabulary']->vid) ) {
+    // Try to catch the 'Save' button.
+    $vid = $form['#vocabulary']->vid;
+  }
+  elseif ($form_state['rebuild'] == TRUE && isset($form['#vocabulary']->vid) ) {
+    // Try to catch the 'Reset to alphabetical' button
+    $vid = NULL;
+  }
+  elseif ($form_state['rebuild'] == FALSE && isset($form['vid']['#value']) ) {
+    // Try to catch the second (confirming) 'Reset to alphabetical' button.
+    $vid = $form['vid']['#value'];
+  }
+  else {
+    // The button [Reset to alphabetical] [Cancel] does not call this page.
+    $vid = NULL;
+  }
+
+  if (isset($vid)) {
+    $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $vid), 0);
+    $sync = variable_get(_taxonomy_menu_build_variable('sync', $vid), 0);
+    if ($menu_name && $sync) {
+      // Update all menu items (do not rebuild the menu).
+      $message = _taxonomy_menu_update_link_items($vid);
+
+      // Report status.
+      if (isset($message)) {
+        drupal_set_message($message, 'status');
+      }
+
+      // Rebuild the menu.
+      menu_cache_clear($menu_name);
+    }
+  }
+}
+
+/**
  * rebuilds a menu
  *
  * @param $vid
@@ -194,6 +249,7 @@ function taxonomy_menu_vocab_submit($form, &$form_state) {
 function _taxonomy_menu_rebuild($vid) {
   // Remove all of the menu items for this vocabulary
   _taxonomy_menu_delete_all($vid);
+
   // Only insert the links if a menu is set
   if (variable_get(_taxonomy_menu_build_variable('vocab_menu', $vid), FALSE)) {
     _taxonomy_menu_insert_link_items($vid);
@@ -229,24 +285,24 @@ function _taxonomy_menu_check_variable($variable, $new_value) {
 function _taxonomy_menu_update_link_items($vid) {
   $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $vid), FALSE);
 
-  //get a list of the current menu links
+  // Get a list of the current tid - menu_link combinations
   $menu_links = _taxonomy_menu_get_menu_items($vid);
 
-  //cycle through the
+  // Cycle through the menu links
   foreach ($menu_links as $tid => $mlid) {
+    // $args must be reset each time through.
+     $args = array(
+       'menu_name' => $menu_name,
+       'mlid' => $mlid,
+     );
+
     if ($tid == 0) {
       $args['vid'] = $vid;
     }
     else {
       $args['term'] = taxonomy_term_load($tid);
-      //since taxonomy_get_term does not return the parents, fetch them now
-      $args['term']->parents = _taxonomy_menu_get_parents($tid);
     }
 
-    //set the menu name
-    $args['menu_name'] = $menu_name;
-    $args['mlid'] = $mlid;
-
     //update the menu link
     taxonomy_menu_handler('update', $args);
   }
@@ -286,84 +342,21 @@ function taxonomy_menu_taxonomy_vocabulary_delete($vocabulary) {
 /**
  * Implementation of hook_taxonomy_term_insert($term).
  */
-function taxonomy_menu_taxonomy_term_insert($term) {
-  // only sync if taxonomy_menu is enabled for this vocab and the 'sync'
-  // option has been checked.
-  $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $term->vid), 0);
-  $sync = variable_get(_taxonomy_menu_build_variable('sync', $term->vid), 0);
-
-  if ($menu_name && $sync) {
-    //we have to pull from the args because using a taxonomy function pulls from the cache
-    $item = array(
-      'term' => $term,
-      'menu_name' => $menu_name,
-    );
-    $message = t('Term %term has been added to taxonomy menu %menu_name.', array('%term' => $term->name, '%menu_name' => $menu_name));
-
-    // Run function.
-    taxonomy_menu_handler('insert', $item);
-    // Report status.
-    drupal_set_message($message, 'status');
-
-    // Rebuild the menu.
-    menu_cache_clear($menu_name);
-  }
+function taxonomy_menu_taxonomy_term_insert($term) {_taxonomy_menu_taxonomy_termapi_helper($term, 'insert');
 }
 
 /**
  * Implementation of hook_taxonomy_term_update().
  */
 function taxonomy_menu_taxonomy_term_update($term) {
-  // Only sync if taxonomy_menu is enabled for this vocab and the 'sync'
-  // option has been checked.
-  $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $term->vid), 0);
-  $sync = variable_get(_taxonomy_menu_build_variable('sync', $term->vid), 0);
-
-  if ($menu_name && $sync) {
-    $item = array(
-      'term' => $term,
-      'menu_name' => $menu_name,
-      'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
-    );
-    $message = t('Term %term has been updated in taxonomy menu %menu_name.', array('%term' => $term->name, '%menu_name' => $menu_name));
-
-    // run function
-    taxonomy_menu_handler('update', $item);
-    // report status
-    drupal_set_message($message, 'status');
-
-    // rebuild the menu
-    menu_cache_clear($menu_name);
-  }
+  _taxonomy_menu_taxonomy_termapi_helper($term, 'update');
 }
 
 /**
  * Implementation of hook_taxonomy_term_delete()
  */
 function taxonomy_menu_taxonomy_term_delete($term) {
-      // only sync if taxonomy_menu is enabled for this vocab and the 'sync'
-  // option has been checked.
-  $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $term->vid), 0);
-  $sync = variable_get(_taxonomy_menu_build_variable('sync', $term->vid), 0);
-
-  if ($menu_name && $sync) {
-    $item = array(
-      'tid' => $term->tid,
-      'vid' => $term->vid,
-      'menu_name' => $menu_name,
-      'term' => $term,
-      'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
-    );
-    $message = t('Term %term has been deleted from taxonomy menu %menu_name.', array('%term' => $term->name, '%menu_name' => $menu_name));
-
-      // run function
-    taxonomy_menu_handler('delete', $item);
-    // report status
-    drupal_set_message($message, 'status');
-
-    // rebuild the menu
-    menu_cache_clear($menu_name);
-  }
+  _taxonomy_menu_taxonomy_termapi_helper($term, 'delete');
 }
 
 /**
@@ -417,8 +410,50 @@ function taxonomy_menu_node_delete($node) {
   _taxonomy_menu_nodeapi_helper('delete', $terms, $node);
 }
 
+ /**
+ * Abstraction of hook_taxonomy_term_<operation>()
+ */
+function _taxonomy_menu_taxonomy_termapi_helper($term, $operation) {
+  // Only sync if taxonomy_menu is enabled for this vocab and the 'sync'
+  // option has been checked.
+  $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $term->vid), 0);
+  $sync = variable_get(_taxonomy_menu_build_variable('sync', $term->vid), 0);
+
+  if ($menu_name && $sync) {
+    $item = array(
+      'tid' => $term->tid,
+      'vid' => $term->vid,
+      'term' => $term,
+      'menu_name' => $menu_name,
+      'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
+    );
+
+    switch ($operation) {
+      case 'insert':
+        $text = 'Added term %term to taxonomy menu %menu_name.';
+        break;
+      case 'update':
+        $text = 'Updated term %term in taxonomy menu %menu_name.';
+        break;
+      case 'delete':
+        $text = 'Deleted term %term from taxonomy menu %menu_name.';
+        break;
+    }
+    $message = t($text, array('%term' => $term->name, '%menu_name' => $menu_name));
+
+      // run function
+    taxonomy_menu_handler($operation, $item);
+
+    // report status
+    drupal_set_message($message, 'status');
+
+    // rebuild the menu
+    menu_cache_clear($menu_name);
+  }
+}
+
 /**
- * Helper function to
+ * Helper function for hook_node_insert/update/delete
  * @param $tids
  * @param $node
  * @return unknown_type
@@ -426,58 +461,30 @@ function taxonomy_menu_node_delete($node) {
 function _taxonomy_menu_nodeapi_helper($op, $terms = array(), $node) {
   foreach ($terms as $key => $tid) {
     $term = taxonomy_term_load($tid);
-    $term->parents = array_keys(taxonomy_get_parents($tid));
-    //$parents = taxonomy_get_parents($tid);
-    //foreach ($parents as $term_id => $term_obj) {
-    //  $term->parents[] = $term_id;
-    //}
+
     //update the menu for each term if necessary
     $menu_name = variable_get(_taxonomy_menu_build_variable('vocab_menu', $term->vid), FALSE);
     $vocb_sync = variable_get(_taxonomy_menu_build_variable('sync', $term->vid), TRUE);
     $menu_num = variable_get(_taxonomy_menu_build_variable('display_num', $term->vid), TRUE);
     $hide_empty = variable_get(_taxonomy_menu_build_variable('hide_empty_terms', $term->vid), FALSE);
     if ($menu_name && $vocb_sync && ($menu_num || $hide_empty)) {
-      switch ($op) {
-        case 'update':
-          //build argument array to save menu_item
-          $args = array(
-            'tid' => $term->tid,
-            'vid' => $term->vid,
-            'term' => $term,
-            'menu_name' => $menu_name,
-            'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
-          );
-          //since taxonomy_get_term does not return the parents, fetch them now
-          $args['term']->parents = _taxonomy_menu_get_parents($term->tid);
-          break;
-
-        case 'insert':
-          //build argument array to save menu_item
-          $args = array(
-            'tid' => $term->tid,
-            'vid' => $term->vid,
-            'term' => $term,
-            'menu_name' => $menu_name,
-            'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
-          );
-          //since taxonomy_get_term does not return the parents, fetch them now
-          $args['term']->parents = _taxonomy_menu_get_parents($term->tid);
-          break;
-
-        case 'delete':
-          $args = array(
-            'term' => $term,
-            'tid' => $term->tid,
-            'vid' => $term->vid,
-            'menu_name' => $menu_name,
-            'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
-          );
-          /* Turn the op to 'update' here since we really do want to update the item
-           * and not delete/recreate it, since the latter will break hierarchy and
-           * customizations.
-           */
-          $op = 'update';
+      //build argument array to save menu_item
+      $args = array(
+        'tid' => $term->tid,
+        'vid' => $term->vid,
+        'term' => $term,
+        'menu_name' => $menu_name,
+        'mlid' => _taxonomy_menu_get_mlid($term->tid, $term->vid),
+      );
+
+      if ($op == 'delete') {
+        /* Turn the op to 'update' here since we really do want to update the item
+        * and not delete/recreate it, since the latter will break hierarchy and
+        * customizations.
+        */
+        $op = 'update';
       }
+
       taxonomy_menu_handler($op, $args, $node);
       if (variable_get(_taxonomy_menu_build_variable('hide_empty_terms', $term->vid), FALSE)) {
         _taxonomy_menu_update_all_parents($term, $menu_name);
@@ -779,8 +786,7 @@ function taxonomy_menu_taxonomy_menu_delete(&$item) {
  */
 function _taxonomy_menu_create_item($args = array(), $node) {
 
-  //if tid = 0 then we are creating a vocab item
-
+  // If tid = 0 then we are creating a vocab item
   if (isset($args['tid']) && isset($args['vid']) && $args['tid'] == 0 && variable_get(_taxonomy_menu_build_variable('voc_item', $args['vid']), 0)) {
     $vocab = taxonomy_vocabulary_load($args['vid']);
     $item = array(
@@ -794,56 +800,51 @@ function _taxonomy_menu_create_item($args = array(), $node) {
       'menu_name' => $args['menu_name'],
       'language' => $vocab->language,
     );
-
-    return $item;
   }
   else {
+    // If tid <> 0 then we are creating a term item.
     $term = $args['term'];
-  }
 
-  // get the first parent
-  if(is_object($term) && isset($term->parents)) {
-    if (is_array($term->parents)) {
-      foreach ($term->parents as $key => $val) {
-        $ptid = $val;
-        break;
+    // Sometimes $term->parents is not set so we find it.
+    if (!isset($term->parents)) {
+      $term->parents = _taxonomy_menu_get_parents($term->tid);
+      if (empty($term->parents)) {
+        // even without parents, create one with $ptid = 0
+        $term->parents = array ( 0 => '0');
       }
     }
+
+    // Find the weight of the root taxonomy term; we'll need it in case we want
+    // a flat taxonomy menu.
+    if (is_object($term)) {
+      $term_parents = taxonomy_get_parents_all($term->tid);
+      $root_term_weight = $term_parents[count($term_parents) - 1]->weight;
+    }
     else {
-      $ptid = $term->parents;
+      $root_term_weight = 0;
     }
-  }
-
-  //if ptid is empty, then set it to 0
-  if (empty($ptid)) {
-    $ptid = 0;
-  }
-
-  // Find the weight of the root taxonomy term; we'll need it in case we want
-  // a flat taxonomy menu.
-  if (is_object($term)) {
-    $term_parents = taxonomy_get_parents_all($term->tid);
-    $root_term_weight = $term_parents[count($term_parents) - 1]->weight;
-  }
-  else {
-    $root_term_weight = 0;
-  }
-
-  // turn the term into the correct $item array form
-  $item = array(
-    'tid' => $term->tid,
-    'name' => $term->name,
-    'description' => $term->description,
-    'weight' => $term->weight,
-    'vid' => $term->vid,
-    'ptid' => $ptid,
-    'root_term_weight' => $root_term_weight,
-    'menu_name' => $args['menu_name'],
-    'language' => isset($term->language) ? $term->language : ($node ? $node->language : $GLOBALS['language']->language),
-  );
 
-  if (isset($args['mlid'])) {
-    $item['mlid'] = $args['mlid'];
+    foreach ($term->parents as $parent) {
+      $ptid = $parent;
+      // turn the term into the correct $item array form
+      $item = array(
+        'tid' => $term->tid,
+        'name' => $term->name,
+        'description' => $term->description,
+        'weight' => $term->weight,
+        'vid' => $term->vid,
+        'ptid' => $ptid,
+        'root_term_weight' => $root_term_weight,
+        'menu_name' => $args['menu_name'],
+        'language' => isset($term->language) ? $term->language : ($node ? $node->language : $GLOBALS['language']->language),
+      );
+      if (isset($args['mlid'])) {
+        $item['mlid'] = $args['mlid'];
+      }
+      // Mutiple parents are not supported yet, hence this break.
+      // without the break, the item is inserted multiple under one parent, instead once under each parent.
+      break;
+    }
   }
 
   return $item;
