Index: modules/book/book.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.admin.inc,v
retrieving revision 1.31
diff -u -p -r1.31 book.admin.inc
--- modules/book/book.admin.inc	9 Jan 2010 21:54:00 -0000	1.31
+++ modules/book/book.admin.inc	26 Feb 2010 17:12:16 -0000
@@ -84,6 +84,20 @@ function book_admin_edit($form, $form_st
 }
 
 /**
+ * Project an array of arrays to one of its columns.
+ *
+ * @see book_admin_edit_validate()
+ *
+ * @param array $link
+ * @param string $key
+ * @param mixed $column
+ * @return void
+ */
+function _book_admin_gather_links(&$link, $key, $column) {
+  $link = $link[$column];
+}
+
+/**
  * Check that the book has not been changed while using the form.
  *
  * @see book_admin_edit()
@@ -93,6 +107,25 @@ function book_admin_edit_validate($form,
     form_set_error('', t('This book has been modified by another user, the changes could not be saved.'));
     $form_state['rebuild'] = TRUE;
   }
+
+  $mlids = $form_state['values']['table'];
+  array_walk($mlids, '_book_admin_gather_links', 'mlid');
+
+  $plids = $form_state['values']['table'];
+  array_walk($plids, '_book_admin_gather_links', 'plid');
+
+  $diff = array_diff($plids, $mlids);
+  $book_mlid = $form_state['build_info']['args'][0]->book['mlid'];
+  if (!in_array($book_mlid, $diff)) {
+    form_set_error('', t('There is no node right below the book root in this reordering, the changes could not be saved.'));
+  }
+
+  $diff = array_diff($diff, array($book_mlid));
+  if (!empty($diff)) {
+    form_set_error('', t('Some nodes have parents outside the book structure: @plids; the changes could not be saved.', array(
+      '@plids' => implode(t(', '), $diff),
+    )));
+  }
 }
 
 /**
