diff --git modules/book/book.admin.inc modules/book/book.admin.inc
index 386dfcc..82d82db 100644
--- modules/book/book.admin.inc
+++ modules/book/book.admin.inc
@@ -16,7 +16,7 @@ function book_admin_overview() {
 
   // Add any recognized books to the table list.
   foreach (book_get_books() as $book) {
-    $rows[] = array(l($book['title'], $book['href'], $book['options']), l(t('edit order and titles'), 'admin/content/book/' . $book['nid']));
+    $rows[] = array(l($book['title'], $book['href'], $book['options']), l(t('edit order and titles'), 'node/' . $book['nid'] . '/reorder'));
   }
 
   return theme('table', array('header' => $headers, 'rows' => $rows, 'empty' => t('No books available.')));
@@ -74,11 +74,22 @@ function book_admin_settings_validate($form, &$form_state) {
 function book_admin_edit($form, $form_state, $node) {
   drupal_set_title($node->title);
   $form['#node'] = $node;
-  _book_admin_table($node, $form);
-  $form['save'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save book pages'),
-  );
+  if (!empty($node->book)) {
+    $toc = menu_tree_all_data(book_menu_name($node->nid));
+    if (!empty($toc)) {
+      _book_admin_table($node, $form);
+      $form['save'] = array(
+        '#type' => 'submit',
+        '#value' => t('Save book pages'),
+      );
+    }
+    else {
+      $form['reorder'] = array(
+        '#type' => 'item',
+        '#description' => t('No child pages.'),
+      );
+    }
+  }
 
   return $form;
 }
@@ -235,7 +246,9 @@ function theme_book_admin_table($variables) {
 
   $rows = array();
   $destination = drupal_get_destination();
+
   $access = user_access('administer nodes');
+
   foreach (element_children($form) as $key) {
     $nid = $form[$key]['nid']['#value'];
     $href = $form[$key]['href']['#value'];
@@ -245,13 +258,18 @@ function theme_book_admin_table($variables) {
     $form[$key]['mlid']['#attributes']['class'] = array('book-mlid');
     $form[$key]['weight']['#attributes']['class'] = array('book-weight');
 
+    // Check node access for specified node and current user.
+    $node = node_load($nid);
+    $update_access = $access || node_access("update", $node);
+    $delete_access = $access || node_access("delete", $node);
+
     $data = array(
       theme('indentation', array('size' => $form[$key]['depth']['#value'] - 2)) . drupal_render($form[$key]['title']),
       drupal_render($form[$key]['weight']),
       drupal_render($form[$key]['plid']) . drupal_render($form[$key]['mlid']),
       l(t('view'), $href),
-      $access ? l(t('edit'), 'node/' . $nid . '/edit', array('query' => $destination)) : '&nbsp;',
-      $access ? l(t('delete'), 'node/' . $nid . '/delete', array('query' => $destination) )  : '&nbsp;',
+      $update_access ? l(t('edit'), 'node/' . $nid . '/edit', array('query' => $destination)) : '&nbsp;',
+      $delete_access ? l(t('delete'), 'node/' . $nid . '/delete', array('query' => $destination) )  : '&nbsp;',
     );
     $row = array('data' => $data);
     if (isset($form[$key]['#attributes'])) {
@@ -263,3 +281,11 @@ function theme_book_admin_table($variables) {
 
   return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'book-outline')));
 }
+
+/**
+ * Menu callback; show the reorder form for a single node.
+ */
+function book_reorder($node) {
+  return drupal_get_form('book_admin_edit', $node);
+}
+
diff --git modules/book/book.info modules/book/book.info
index 1bb72d3..5807680 100644
--- modules/book/book.info
+++ modules/book/book.info
@@ -2,8 +2,9 @@
 name = Book
 description = Allows users to create and organize related content in an outline.
 package = Core
-version = VERSION
+version = VERSIOa
 core = 7.x
 files[] = book.test
 configure = admin/content/book/settings
 stylesheets[all][] = book.css
+
diff --git modules/book/book.module modules/book/book.module
index 4252f3e..3b5cc00 100644
--- modules/book/book.module
+++ modules/book/book.module
@@ -29,7 +29,7 @@ function book_help($path, $arg) {
     case 'admin/content/book':
       return '<p>' . t('The book module offers a means to organize a collection of related content pages, collectively known as a book. When viewed, this content automatically displays links to adjacent book pages, providing a simple navigation system for creating and reviewing structured content.') . '</p>';
     case 'node/%/outline':
-      return '<p>' . t('The outline feature allows you to include pages in the <a href="@book">Book hierarchy</a>, as well as move them within the hierarchy or to <a href="@book-admin">reorder an entire book</a>.', array('@book' => url('book'), '@book-admin' => url('admin/content/book'))) . '</p>';
+      return '<p>' . t('The outline feature allows you to include pages in the <a href="@book">Book hierarchy</a>, as well as move them within the hierarchy or to <a href="@book-admin">reorder an entire book</a>.', array('@book' => url('book'), '@book-admin' => url('node/' . arg(1) . '/reorder'))) . '</p>';
   }
 }
 
@@ -69,13 +69,22 @@ function book_theme() {
 function book_permission() {
   return array(
     'administer book outlines' => array(
-      'title' => t('Administer book outlines'),
+      'title' => t('Administer all book outlines'),
+    ),
+    'administer own book outlines' => array(
+      'title' => t('Administer own book outlines'),
     ),
     'create new books' => array(
       'title' => t('Create new books'),
     ),
+    'add content to own books' => array(
+      'title' => t('Add content and child pages to own books'),
+    ),
     'add content to books' => array(
-      'title' => t('Add content and child pages to books'),
+      'title' => t('Add content and child pages to all books'),
+    ),
+    'choose only own books in outline' => array(
+      'title' => t('Choose only own books in the book outline'),
     ),
     'access printer-friendly version' => array(
       'title' => t('View printer-friendly books'),
@@ -85,6 +94,65 @@ function book_permission() {
 }
 
 /**
+ * Helper for access check for given user.
+ */
+function _book_user_access($node, $user) {
+  $access = user_access('add content to books') || user_access('administer book outlines');
+  if ($user->uid == $node->uid && user_access('add content to own books')) {
+    $access = TRUE;
+  }
+  return $access;
+}
+
+/**
+ * Implements hook_menu_local_tasks_alter().
+ */
+function book_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+  if ($root_path == 'node/%/reorder') {
+    $node = node_load(arg(1));
+    $child_link = _book_add_child_link($node);
+    $child_node_type = $child_link['book_add_child']['href'];
+    $parent = $child_link['book_add_child']['query']['parent'];
+
+    $item = menu_get_item($child_link['book_add_child']['href']);
+    $item['title'] = $child_link['book_add_child']['title'];
+    $item['href'] = $child_node_type;
+
+    // This will pass our parent link
+    $item['localized_options'] = array(
+      'title' => $item['title'],
+      'href' => $item['href'],
+      'query' => array(
+        'parent' => $parent,
+      ),
+    );
+
+    if ($item['access']) {
+      $data['actions']['output'][] = array(
+        '#theme' => 'menu_local_action',
+        '#link' => $item,
+      );
+    }
+  }
+}
+
+/**
+ * Helper: return child link for given book.
+ */
+function _book_add_child_link($node) {
+  global $user;
+  $child_type = variable_get('book_child_type', 'book');
+  if (_book_user_access($node, $user) && node_access('create', $child_type) && $node->status == 1 && $node->book['depth'] < MENU_MAX_DEPTH) {
+    $link['book_add_child'] = array(
+      'title' => t('Add child page'),
+      'href' => 'node/add/' . str_replace('_', '-', $child_type),
+      'query' => array('parent' => $node->book['mlid']),
+    );
+    return $link;  
+  }
+}
+
+/**
  * Inject links into $node as needed.
  */
 function book_node_view_link($node, $view_mode) {
@@ -92,15 +160,7 @@ function book_node_view_link($node, $view_mode) {
 
   if (isset($node->book['depth'])) {
     if ($view_mode == 'full' && node_is_page($node)) {
-      $child_type = variable_get('book_child_type', 'book');
-      if ((user_access('add content to books') || user_access('administer book outlines')) && node_access('create', $child_type) && $node->status == 1 && $node->book['depth'] < MENU_MAX_DEPTH) {
-        $links['book_add_child'] = array(
-          'title' => t('Add child page'),
-          'href' => 'node/add/' . str_replace('_', '-', $child_type),
-          'query' => array('parent' => $node->book['mlid']),
-        );
-      }
-
+      $links = _book_add_child_link($node);
       if (user_access('access printer-friendly version')) {
         $links['book_printer'] = array(
           'title' => t('Printer-friendly version'),
@@ -145,15 +205,6 @@ function book_menu() {
     'weight' => 8,
     'file' => 'book.admin.inc',
   );
-  $items['admin/content/book/%node'] = array(
-    'title' => 'Re-order book pages and change titles',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('book_admin_edit', 3),
-    'access callback' => '_book_outline_access',
-    'access arguments' => array(3),
-    'type' => MENU_CALLBACK,
-    'file' => 'book.admin.inc',
-  );
   $items['book'] = array(
     'title' => 'Books',
     'page callback' => 'book_render',
@@ -178,6 +229,17 @@ function book_menu() {
     'weight' => 2,
     'file' => 'book.pages.inc',
   );
+  $items['node/%node/reorder'] = array(
+    'title' => 'Reorder',
+    'description' => "Manage your book's outline.",
+    'page callback' => 'book_reorder',
+    'page arguments' => array(1),
+    'access callback' => '_book_outline_access',
+    'access arguments' => array(1),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 2,
+    'file' => 'book.admin.inc',
+  );
   $items['node/%node/outline/remove'] = array(
     'title' => 'Remove from outline',
     'page callback' => 'drupal_get_form',
@@ -194,7 +256,8 @@ function book_menu() {
  * Menu item access callback - determine if the outline tab is accessible.
  */
 function _book_outline_access($node) {
-  return user_access('administer book outlines') && node_access('view', $node);
+  global $user;
+  return _book_user_access($node, $user) && node_access('update', $node);
 }
 
 /**
@@ -212,6 +275,7 @@ function book_admin_paths() {
     $paths = array(
       'node/*/outline' => TRUE,
       'node/*/outline/remove' => TRUE,
+      'node/*/reorder' => TRUE,
     );
     return $paths;
   }
@@ -282,7 +346,7 @@ function book_block_view($delta = '') {
     // Only display this block when the user is browsing a book.
     $select = db_select('node');
     $select->addField('node', 'title');
-    $select->condition('nid', $node->book['bid']);
+    $select->condition('node.nid', $node->book['bid']);
     $select->addTag('node_access');
     $title = $select->execute()->fetchField();
     // Only show the block if the user has view access for the top-level node.
@@ -350,6 +414,7 @@ function theme_book_title_link($variables) {
  * the options for a form select.
  */
 function book_get_books() {
+  global $user;
   $all_books = &drupal_static(__FUNCTION__);
 
   if (!isset($all_books)) {
@@ -366,6 +431,9 @@ function book_get_books() {
       $query->fields('ml');
       $query->condition('n.nid', $nids, 'IN');
       $query->condition('n.status', 1);
+      if (user_access('administer own book outlines') && !user_access('administer book outlines')) {
+        $query->condition('n.uid', $user->uid);
+      }
       $query->orderBy('ml.weight');
       $query->orderBy('ml.link_title');
       $query->addTag('node_access');
@@ -392,10 +460,9 @@ function book_form_node_form_alter(&$form, &$form_state, $form_id) {
   $node = $form['#node'];
   $access = user_access('administer book outlines');
   if (!$access) {
-    if (user_access('add content to books') && ((!empty($node->book['mlid']) && !empty($node->nid)) || book_type_is_allowed($node->type))) {
-      // Already in the book hierarchy, or this node type is allowed.
-      $access = TRUE;
-    }
+    $access = user_access('add content to books') || user_access('add content to own books');
+    // Already in the book hierarchy, or this node type is allowed.
+    $access = $access && ((!empty($node->book['mlid']) && !empty($node->nid)) || book_type_is_allowed($node->type));
   }
 
   if ($access) {
@@ -903,8 +970,10 @@ function book_node_delete($node) {
  * Implements hook_node_prepare().
  */
 function book_node_prepare($node) {
+  global $user;
+  $access = _book_user_access($node, $user);
   // Prepare defaults for the add/edit form.
-  if (empty($node->book) && (user_access('add content to books') || user_access('administer book outlines'))) {
+  if (empty($node->book) && $access) {
     $node->book = array();
 
     if (empty($node->nid) && isset($_GET['parent']) && is_numeric($_GET['parent'])) {
diff --git modules/book/book.pages.inc modules/book/book.pages.inc
index 6671ef5..14c8342 100644
--- modules/book/book.pages.inc
+++ modules/book/book.pages.inc
@@ -1,5 +1,5 @@
 <?php
-// $Id: book.pages.inc,v 1.28 2011/01/28 08:04:59 webchick Exp $
+// $Id: book.pages.inc,v 1.27 2010/07/07 01:07:33 dries Exp $
 
 /**
  * @file
@@ -77,11 +77,9 @@ function book_export_html($nid) {
     if (isset($node->book)) {
       $tree = book_menu_subtree_data($node->book);
       $contents = book_export_traverse($tree, 'book_node_export');
-      return theme('book_export_html', array('title' => $node->title, 'contents' => $contents, 'depth' => $node->book['depth']));
-    }
-    else {
-      drupal_not_found();
     }
+
+    return theme('book_export_html', array('title' => $node->title, 'contents' => $contents, 'depth' => $node->book['depth']));
   }
   else {
     drupal_access_denied();
diff --git modules/book/book.test modules/book/book.test
index cc43a86..7f8c816 100644
--- modules/book/book.test
+++ modules/book/book.test
@@ -1,10 +1,5 @@
 <?php
-// $Id: book.test,v 1.30 2011/02/04 18:42:20 dries Exp $
-
-/**
- * @file
- * Tests for book.module.
- */
+// $Id: book.test,v 1.28 2010/10/18 05:53:34 webchick Exp $
 
 class BookTestCase extends DrupalWebTestCase {
   protected $book;
@@ -242,10 +237,6 @@ class BookTestCase extends DrupalWebTestCase {
     $this->drupalGet('book/export/foobar/' . $this->book->nid);
     $this->assertResponse('404', t('Unsupported export format returned "not found".'));
 
-    // Make sure we get a 404 on a not existing book node.
-    $this->drupalGet('book/export/html/123');
-    $this->assertResponse('404', t('Not existing book node returned "not found".'));
-
     // Make sure an anonymous user cannot view printer-friendly version.
     $this->drupalLogout();
 
