diff --git a/draggableviews.module b/draggableviews.module
index f6f056d..ea04282 100644
--- a/draggableviews.module
+++ b/draggableviews.module
@@ -25,7 +25,6 @@ function draggableviews_form_alter(&$form, &$form_state, $form_id) {
     $view = $form_state['build_info']['args'][0];
     $options = $view->field['draggableviews']->options['draggableviews'];
     $form['actions']['submit']['#value'] = t($options['save_button_label']);
-    $form['actions']['submit']['#submit'] = array('draggableviews_views_submit');
 
     if ($options['ajax']) {
       $form['actions']['submit']['#ajax'] = array(
@@ -47,28 +46,6 @@ function draggableviews_form_alter(&$form, &$form_state, $form_id) {
 }
 
 /**
- * Save weight records after form submit.
- */
-function draggableviews_views_submit($form, &$form_state) {
-  $view = $form_state['build_info']['args'][0];
-
-  // Use 'input' instead of mapped 'values' here. This is done because if in
-  // table display we sort by header then set weights and save, we got
-  // totally wrong results ($form_state['values']['draggableviews'] mapped
-  // wrong from $form_state['input']['draggableviews'])
-  $form_state['values']['draggableviews'] = $form_state['input']['draggableviews'];
-
-  // Set the weight.
-  $handler_object = draggableviews_get_handler_class($view->field['draggableviews']->options['draggableviews']['handler']);
-  $handler_object->set($form_state);
-
-  // Trigger the event "A view has been sorted"
-  if (module_exists('rules')) {
-    rules_invoke_event('draggableviews_rules_event_sorted', $view->name, $view->current_display);
-  }
-}
-
-/**
  * Implementes hook_preprocess_views_view_table().
  */
 function draggableviews_preprocess_views_view_table(&$vars) {
@@ -272,6 +249,32 @@ function draggableviews_views_post_execute(&$view) {
     $draggable_field = $view->field['draggableviews'];
     unset($view->field['draggableviews']);
     $view->field['draggableviews'] = $draggable_field;
+
+    // Clean-up dropout entities.
+    if (!empty($view->field['draggableviews']->options['draggableviews']['cleanup'])) {
+      $handler = draggableviews_get_handler_class($view->field['draggableviews']->options['draggableviews']['handler']);
+      // Here we get back an array where the first key (0) is the entity type
+      // and the second key (1) is an array of entity objects from the result.
+      $result = $view->query->get_result_entities($view->result);
+      $entity_type = $result[0];
+
+      $entity_ids_to_keep = array();
+      foreach ($result[1] as $entity) {
+        list($entity_id, $entity_vid, $bundle) = entity_extract_ids($entity_type, $entity);
+        $entity_ids_to_keep[] = $entity_id;
+      }
+
+      if (!empty($entity_ids_to_keep)) {
+        // We pass on the entity IDs that *should not* be cleaned up and we will
+        // get back the entity IDs that was cleaned up.
+        $entity_ids_to_cleanup = $handler->cleanup($view->name, $view->current_display, $entity_ids_to_keep);
+        // We pass on all the cleaned up entities for others to react on.
+        if (!empty($entity_ids_to_cleanup) && module_exists('rules')) {
+          $entities_to_cleanup = entity_load($entity_type, $entity_ids_to_cleanup);
+          rules_invoke_event("draggableviews_rules_event_cleanup_$entity_type", $view->name, $view->current_display, $entities_to_cleanup);
+        }
+      }
+    }
   }
 }
 
diff --git a/draggableviews.rules.inc b/draggableviews.rules.inc
index 2719f74..d1a2f9a 100644
--- a/draggableviews.rules.inc
+++ b/draggableviews.rules.inc
@@ -17,14 +17,80 @@ function draggableviews_rules_event_info() {
     'variables' => array(
       'view_name' => array(
         'type' => 'text',
-        'label' => t('view name'),
+        'label' => t('View name'),
       ),
       'display_name' => array(
         'type' => 'text',
-        'label' => t('view current display name'),
+        'label' => t('View display name'),
       ),
     ),
   );
 
+  foreach (entity_get_info() as $entity_type => $entity_info) {
+    // We don't want entity types that are considered configuration here, since
+    // those generally aren't rendered in Views.
+    if (empty($entity_info['configuration'])) {
+      $events["draggableviews_rules_event_cleanup_$entity_type"] = array(
+        'label' => t('A @label dropped out of a draggable view', array('@label' => drupal_strtolower($entity_info['label']))),
+        'group' => $entity_info['label'],
+        'variables' => array(
+          'view_name' => array(
+            'type' => 'text',
+            'label' => t('View name'),
+          ),
+          'display_name' => array(
+            'type' => 'text',
+            'label' => t('View display name'),
+          ),
+          'entities' => array(
+            'type' => "list<$entity_type>",
+            'label' => t('@label list', array('@label' => $entity_info['label'])),
+          ),
+        ),
+      );
+    }
+  }
+
   return $events;
 }
+
+/**
+ * Implements hook_rules_action_info().
+ */
+function draggableviews_rules_action_info() {
+  $actions = array();
+
+  $actions['draggableviews_rules_action_rebuild'] = array(
+    'label' => t('Rebuild the order structure of a view.'),
+    'group' => t('DraggableViews'),
+    'parameter' => array(
+      'view_name' => array(
+        'type' => 'text',
+        'label' => t('View name')
+      ),
+      'view_display' => array(
+        'type' => 'text',
+        'label' => t('View display name')
+      ),
+    ),
+  );
+
+  return $actions;
+}
+
+/**
+ * Action callback.
+ */
+function draggableviews_rules_action_rebuild($view_name, $view_display) {
+  // Load and execute the display.
+  $view = views_get_view($view_name);
+  $view->execute($view_display);
+  // Only render the style plugin to pass its output to the form builder,
+  // exactly like template_preprocess_views_view() does it.
+  $output = $view->style_plugin->render($view->result);
+
+  // The form state will be populated during build.
+  $form_state = array();
+  // Submit the form programatically to effectively rebuild the order structure.
+  drupal_form_submit(views_form_id($view), $form_state, $view, $output);
+}
diff --git a/handlers/draggableviews_handler.inc b/handlers/draggableviews_handler.inc
index 1fbef16..89a6409 100644
--- a/handlers/draggableviews_handler.inc
+++ b/handlers/draggableviews_handler.inc
@@ -51,4 +51,20 @@ class draggableviews_handler {
    *   Array with default values.
    */
   public function option_definition() {}
-}
\ No newline at end of file
+
+  /**
+   * Cleanup method.
+   *
+   * @param string $view_name
+   *
+   * @param string $view_display
+   *
+   * @param array $entity_ids_to_keep
+   *   Array of entity IDs that *should not* be removed from the order structure.
+   *
+   * @return array
+   *   Array of entity IDs that was cleaned up. This will be passed on for
+   *   other modules to react on.
+   */
+  public function cleanup($view_name, $view_display, $entity_ids_to_keep) {}
+}
diff --git a/handlers/draggableviews_handler_native.inc b/handlers/draggableviews_handler_native.inc
index b398530..8a612d7 100644
--- a/handlers/draggableviews_handler_native.inc
+++ b/handlers/draggableviews_handler_native.inc
@@ -68,4 +68,27 @@ class draggableviews_handler_native extends draggableviews_handler {
       $weight++;
     }
   }
+
+  function cleanup($view_name, $view_display, $entity_ids_to_keep) {
+    // First we need to find out what entity ids that will be remove,
+    // because we need to return those back to the caller.
+    $entity_ids_to_cleanup = db_select('draggableviews_structure', 'ds')
+      ->fields('ds', array('entity_id'))
+      ->condition('view_name', $view_name)
+      ->condition('view_display', $view_display)
+      ->condition('entity_id', $entity_ids_to_keep, 'NOT IN')
+      ->execute()
+      ->fetchCol();
+
+    // Cleanup.
+    if (!empty($entity_ids_to_cleanup)) {
+      db_delete('draggableviews_structure')
+        ->condition('view_name', $view_name)
+        ->condition('view_display', $view_display)
+        ->condition('entity_id', $entity_ids_to_cleanup, 'IN')
+        ->execute();
+    }
+
+    return $entity_ids_to_cleanup;
+  }
 }
diff --git a/views/draggableviews_handler_field_draggable.inc b/views/draggableviews_handler_field_draggable.inc
index 9f4b130..8a8e284 100644
--- a/views/draggableviews_handler_field_draggable.inc
+++ b/views/draggableviews_handler_field_draggable.inc
@@ -22,6 +22,7 @@ class draggableviews_handler_field_draggable extends views_handler_field {
         'hierarchy_handler' => array('default' => ''),
         'save_button_label' => array('default' => 'Save'),
         'ajax' => array('default' => FALSE),
+        'cleanup' => array('default' => FALSE),
       ),
     );
 
@@ -135,6 +136,13 @@ class draggableviews_handler_field_draggable extends views_handler_field {
       '#description' => t('Use ajax in draggable form.'),
       '#default_value' => $this->options['draggableviews']['ajax'],
     );
+
+    $form['draggableviews']['cleanup'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Clean-up dropout entities'),
+      '#description' => t("Clean-up entites from the order structure that no longer are rendered in this view. Using this option wont work well with paginated views. Using this option can also have negative impact on the performance of this view."),
+      '#default_value' => $this->options['draggableviews']['cleanup'],
+    );
   }
 
   function render($values) {
@@ -196,4 +204,26 @@ class draggableviews_handler_field_draggable extends views_handler_field {
       }
     }
   }
-}
\ No newline at end of file
+
+  /**
+   * Form submit handler invoked by Views.
+   */
+  function views_form_submit($form, &$form_state) {
+    // Use 'input' instead of mapped 'values' here. This is done because if in
+    // table display we sort by header then set weights and save, we got
+    // totally wrong results ($form_state['values']['draggableviews'] mapped
+    // wrong from $form_state['input']['draggableviews'])
+    if (!$form_state['programmed']) {
+      $form_state['values']['draggableviews'] = $form_state['input']['draggableviews'];
+    }
+
+    // Set the weight.
+    $handler_object = draggableviews_get_handler_class($this->view->field['draggableviews']->options['draggableviews']['handler']);
+    $handler_object->set($form_state);
+
+    // Trigger the event "A view has been sorted"
+    if (module_exists('rules')) {
+      rules_invoke_event('draggableviews_rules_event_sorted', $this->view->name, $this->view->current_display);
+    }
+  }
+}
