diff --git a/src/Controller/HmMenuController.php b/src/Controller/HmMenuController.php
index 9f2793a10c27ac5d47bd0821be594fe44998b812..d101c2eda3ccdffbc96430cdea0f4416a5ab246b 100644
--- a/src/Controller/HmMenuController.php
+++ b/src/Controller/HmMenuController.php
@@ -168,6 +168,8 @@ class HmMenuController extends ControllerBase {
     $updated_links = $request->get('keys');
     //$after = $request->get('after');
     $before = $request->get('before');
+    $all_siblings = [];
+    $insert_after = TRUE;
     
     if (is_array($updated_links) && !empty($updated_links)) {
       if (empty($parent)) {
@@ -186,48 +188,39 @@ class HmMenuController extends ControllerBase {
           // The parent menu doesn't exist.
           return new JsonResponse(['result' => 'fail']);
       }
-      else {
-        if (empty($children)) {
-          $parent_link = reset($parent_links);
-          $children = $parent_link->subtree;
-        }
 
-        if ($children) {
-          // The parent menu has children.
-          $target_position = intval($target_position);
-          $all_siblings = [];
-          $insert_after = TRUE;
-          $position = 0;
-          foreach ($children as $child) {
-            $link = $child->link;
-            $link_id = $link->getPLuginId();
-            // Figure out if the new links are inserted
-            // after the target position.
-            if ($position++ == $target_position && $link_id !== $before) {
-              $insert_after = FALSE;
-            }
-            
-            $all_siblings[$link_id] = (int) $link->getWeight();
+      if (empty($children)) {
+        $parent_link = reset($parent_links);
+        $children = $parent_link->subtree;
+      }
+
+      if ($children) {
+        // The parent menu has children.
+        $target_position = intval($target_position);
+
+        $position = 0;
+        foreach ($children as $child) {
+          $link = $child->link;
+          $link_id = $link->getPLuginId();
+          // Figure out if the new links are inserted
+          // after the target position.
+          if ($position++ == $target_position && $link_id !== $before) {
+            $insert_after = FALSE;
           }
           
-          $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_links, $insert_after);
-          $weight = $new_hierarchy['start_weight'];
-          $moving_siblings = $new_hierarchy['moving_siblings'];
-          
-          // Update all sibling links needed to update.
-          foreach ($moving_siblings as $link_id => $link_weight) {
-            $this->menuLinkManager->updateDefinition($link_id, ['weight' => $link_weight]);
-          }
-        }
-        else {
-          // The parent link doesn't have children.
-          $weight = 0;
-        }
-        // Move all links updated.
-        foreach ($updated_links as $link_id) {
-          $this->menuLinkManager->updateDefinition($link_id, ['weight' => $weight++, 'parent' => $parent]);
+          $all_siblings[$link_id] = (int) $link->getWeight();
         }
       }
+      else {
+        // The parent link doesn't have children.
+        
+      }
+      
+      $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_links, $insert_after);
+      // Update all links need to update.
+      foreach ($new_hierarchy as $link_id => $link_weight) {
+        $this->menuLinkManager->updateDefinition($link_id, ['weight' => $link_weight, 'parent' => $parent]);
+      }
       
       return new JsonResponse(['result' => 'success']);
     }
diff --git a/src/Controller/HmTaxonomyController.php b/src/Controller/HmTaxonomyController.php
index 68cc884c34e87b50a28be4fdf4fdd4d5d809e0f2..536b1f4c9fa2792d9958d49922763cb131e000f2 100644
--- a/src/Controller/HmTaxonomyController.php
+++ b/src/Controller/HmTaxonomyController.php
@@ -146,6 +146,8 @@ class HmTaxonomyController extends ControllerBase {
     //$after = $request->get('after');
     $before = $request->get('before');
     $success = FALSE;
+    $insert_after = TRUE;
+    $all_siblings = [];
 
     if (is_array($updated_terms) && !empty($updated_terms)) {
       // Taxonomy access control.
@@ -156,7 +158,6 @@ class HmTaxonomyController extends ControllerBase {
       if (empty($children)) {
         if (Term::load($parent_id)) {
           // The parent term hasn't had any children.
-          $weight = 0;
         }
         else {
           // The parent term doesn't exist.
@@ -166,8 +167,6 @@ class HmTaxonomyController extends ControllerBase {
       else {
         // The parent term has children.
         $target_position = intval($target_position);       
-        $all_siblings = [];
-        $insert_after = TRUE;
         $position = 0;
         
         foreach ($children as $child) {
@@ -179,30 +178,18 @@ class HmTaxonomyController extends ControllerBase {
           
           $all_siblings[$child->tid] = (int) $child->weight;
         }
-        
-        $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_terms, $insert_after);
-        $weight = $new_hierarchy['start_weight'];
-        $moving_siblings = $new_hierarchy['moving_siblings'];
-        $tids = array_keys($moving_siblings);
-        
-        if (!empty($tids)) {
-          // Update siblings.
-          $term_siblings = Term::loadMultiple($tids);
-          foreach ($term_siblings as $term) {
-            $term->setWeight($moving_siblings[$term->id()]);
-            $success = $term->save();
-          }
-        }
       }
       
+      $new_hierarchy = $this->hmPluginTypeManager->updateHierarchy($target_position, $all_siblings, $updated_terms, $insert_after);
+      $tids = array_keys($new_hierarchy);
+      
       // Load all terms needed to update.
-      $terms = Term::loadMultiple($updated_terms);
-      // Update all terms, the weight will be increased by 1,
-      // after inserting.
+      $terms = Term::loadMultiple($tids);
+      // Update all terms.
       foreach ($terms as $term) {
         if ($access_control_handler->access($term, 'update')) {
           $term->set('parent', ['target_id' => $parent_id]);
-          $term->setWeight($weight++);
+          $term->setWeight($new_hierarchy[$term->id()]);
           $success = $term->save();
         }
       }
diff --git a/src/PluginTypeManager.php b/src/PluginTypeManager.php
index a6a5a8b3d0f6b5fe23a6b0430ff17ea10f72ca8b..315d523f0cea7cb1aebf038c28534a7d1ba5de3e 100644
--- a/src/PluginTypeManager.php
+++ b/src/PluginTypeManager.php
@@ -97,107 +97,115 @@ class PluginTypeManager {
    *   IDs of new items inserted.
    * @param int|bool $after
    *   Indicator if new items are inserted after target position.
+   * @param int $weight
+   *   The initial weight.
    *   
    * @return array
    *   All siblings needed to move and their new weights.
    */
-  public function updateHierarchy(int $target_position, array $all_siblings, array $updated_items, $after) {
-    $filtered_moving_siblings = [];
+  public function updateHierarchy(int $target_position, array $all_siblings, array $updated_items, $after, int $weight = 0) {
+    $new_hierarchy = [];
     $first_half = TRUE;
-
-    $total = count($all_siblings);
-    if ($target_position === 0) {
-      // The insert postion is the first position.
-      // we don't need to move any siblings.
-      $weight = (int) reset($all_siblings) - 1;
-    }   
-    elseif ($target_position >= $total - 1) {
-      // The insert postion is the end,
-      // we don't need to move any siblings.
-      $last_item= array_slice($all_siblings, -1, 1, TRUE);
-      $weight = (int) reset($last_item) + 1;
-    }
-    else {
-      $target_item = array_slice($all_siblings, $target_position, 1, TRUE);
-      $weight = (int) reset($target_item);
-      // If the target position is in the second half,
-      // we will move all siblings
-      // after the target position forward.
-      // Otherwise, we will move siblings
-      // before the target position backwards.
-      if ($target_position >= $total / 2) {
-        $first_half = FALSE;
-        
-        if ($after) {
-          // Insert after the target position.
-          // The target stay where it is.
-          $weight += 1;
-          $moving_siblings = array_slice($all_siblings, $target_position + 1, NULL, TRUE);
-        }
-        else {
-          // Insert before the target position.
-          // The target need to move forwards.
-          $moving_siblings = array_slice($all_siblings, $target_position, NULL, TRUE);
-        }
-        $step = $weight + count($updated_items);
+    
+    if (!empty($all_siblings)) {
+      $total = count($all_siblings);
+      if ($target_position === 0) {
+        // The insert postion is the first position.
+        // we don't need to move any siblings.
+        $weight = (int) reset($all_siblings) - 1;
+      }
+      elseif ($target_position >= $total - 1) {
+        // The insert postion is the end,
+        // we don't need to move any siblings.
+        $last_item= array_slice($all_siblings, -1, 1, TRUE);
+        $weight = (int) reset($last_item) + 1;
       }
       else {
-        if ($after) {
-          // Insert after the target position.
-          // The target need to move backwards.
-          $moving_siblings = array_slice($all_siblings, 0, $target_position + 1, TRUE);
+        $target_item = array_slice($all_siblings, $target_position, 1, TRUE);
+        $weight = (int) reset($target_item);
+        // If the target position is in the second half,
+        // we will move all siblings
+        // after the target position forward.
+        // Otherwise, we will move siblings
+        // before the target position backwards.
+        if ($target_position >= $total / 2) {
+          $first_half = FALSE;
+          
+          if ($after) {
+            // Insert after the target position.
+            // The target stay where it is.
+            $weight += 1;
+            $moving_siblings = array_slice($all_siblings, $target_position + 1, NULL, TRUE);
+          }
+          else {
+            // Insert before the target position.
+            // The target need to move forwards.
+            $moving_siblings = array_slice($all_siblings, $target_position, NULL, TRUE);
+          }
+          $step = $weight + count($updated_items);
         }
         else {
-          // Insert before the target position.
-          // The target stay where it is.
-          $weight -= 1;
-          $moving_siblings = array_slice($all_siblings, 0, $target_position, TRUE);
-        }
-        $weight = $step = $weight - count($updated_items);
-        // Reverse the siblings_moved array
-        // as we will decrease the weight
-        // starting from the first element
-        // and the new weight should be in
-        // an opposite order.
-        $moving_siblings = array_reverse($moving_siblings, TRUE);
-      }
-      
-      // Move all siblings that need to move.
-      foreach($moving_siblings as $item_id => $item_weight) {
-        // Skip all links in the updated array. They will be moved later.
-        if (in_array($item_id, $updated_items)) {
-          continue;
-        }
-        if ($first_half) {
-          // While moving the first half of the siblings,
-          // all moving siblings' weight are decreased,
-          // if they are greater than the step.
-          if ((int)$item_weight < --$step) {
-            // There is planty room, no need to move anymore.
-            break;
+          if ($after) {
+            // Insert after the target position.
+            // The target need to move backwards.
+            $moving_siblings = array_slice($all_siblings, 0, $target_position + 1, TRUE);
           }
           else {
-            // Update the weight.
-            $filtered_moving_siblings[$item_id] = $step;
+            // Insert before the target position.
+            // The target stay where it is.
+            $weight -= 1;
+            $moving_siblings = array_slice($all_siblings, 0, $target_position, TRUE);
           }
+          $weight = $step = $weight - count($updated_items);
+          // Reverse the siblings_moved array
+          // as we will decrease the weight
+          // starting from the first element
+          // and the new weight should be in
+          // an opposite order.
+          $moving_siblings = array_reverse($moving_siblings, TRUE);
         }
-        else {
-          // While moving the second half of the siblings,
-          // all moving siblings' weight are increased,
-          // if they are less than the step.
-          if ((int)$item_weight < ++$step) {
-            // Update the weight.
-            $filtered_moving_siblings[$item_id] = $step;
+        
+        // Move all siblings that need to move.
+        foreach($moving_siblings as $item_id => $item_weight) {
+          // Skip all links in the updated array. They will be moved later.
+          if (in_array($item_id, $updated_items)) {
+            continue;
+          }
+          if ($first_half) {
+            // While moving the first half of the siblings,
+            // all moving siblings' weight are decreased,
+            // if they are greater than the step.
+            if ((int)$item_weight < --$step) {
+              // There is planty room, no need to move anymore.
+              break;
+            }
+            else {
+              // Update the weight.
+              $new_hierarchy[$item_id] = $step;
+            }
           }
           else {
-            // There is planty room, no need to move anymore.
-            break;
+            // While moving the second half of the siblings,
+            // all moving siblings' weight are increased,
+            // if they are less than the step.
+            if ((int)$item_weight < ++$step) {
+              // Update the weight.
+              $new_hierarchy[$item_id] = $step;
+            }
+            else {
+              // There is planty room, no need to move anymore.
+              break;
+            }
           }
         }
       }
     }
     
-    return ['start_weight' => $weight, 'moving_siblings' => $filtered_moving_siblings];
+    foreach ($updated_items as $item) {
+      $new_hierarchy[$item] = $weight++;
+    }
+    
+    return $new_hierarchy;
   }
 }