diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index fd4fac9..cb76abc 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -262,103 +262,6 @@ function book_entity_info_alter(&$info) {
 }
 
 /**
- * Implements hook_block_info().
- */
-function book_block_info() {
-  $block = array();
-  $block['navigation']['info'] = t('Book navigation');
-  $block['navigation']['cache'] = DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE;
-
-  return $block;
-}
-
-/**
- * Implements hook_block_view().
- *
- * Displays the book table of contents in a block when the current page is a
- * single-node view of a book node.
- */
-function book_block_view($delta = '') {
-  $block = array();
-  $current_bid = 0;
-  if ($node = menu_get_object()) {
-    $current_bid = empty($node->book['bid']) ? 0 : $node->book['bid'];
-  }
-
-  if (config('book.settings')->get('block.navigation.mode') == 'all pages') {
-    $block['subject'] = t('Book navigation');
-    $book_menus = array();
-    $pseudo_tree = array(0 => array('below' => FALSE));
-    foreach (book_get_books() as $book_id => $book) {
-      if ($book['bid'] == $current_bid) {
-        // If the current page is a node associated with a book, the menu
-        // needs to be retrieved.
-        $book_menus[$book_id] = menu_tree_output(menu_tree_all_data($node->book['menu_name'], $node->book));
-      }
-      else {
-        // Since we know we will only display a link to the top node, there
-        // is no reason to run an additional menu tree query for each book.
-        $book['in_active_trail'] = FALSE;
-        // Check whether user can access the book link.
-        $book_node = node_load($book['nid']);
-        $book['access'] = node_access('view', $book_node);
-        $pseudo_tree[0]['link'] = $book;
-        $book_menus[$book_id] = menu_tree_output($pseudo_tree);
-      }
-    }
-    if ($block['content'] = $book_menus) {
-      $book_menus['#theme'] = 'book_all_books_block';
-    }
-  }
-  elseif ($current_bid) {
-    // Only display this block when the user is browsing a book.
-  $select = db_select('node', 'n')
-    ->fields('n', array('title'))
-    ->condition('n.nid', $node->book['bid'])
-    ->addTag('node_access');
-    $title = $select->execute()->fetchField();
-    // Only show the block if the user has view access for the top-level node.
-    if ($title) {
-      $tree = menu_tree_all_data($node->book['menu_name'], $node->book);
-      // There should only be one element at the top level.
-      $data = array_shift($tree);
-      $block['subject'] = theme('book_title_link', array('link' => $data['link']));
-      $block['content'] = ($data['below']) ? menu_tree_output($data['below']) : '';
-    }
-  }
-
-  return $block;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function book_block_configure($delta = '') {
-  $block = array();
-  $options = array(
-    'all pages' => t('Show block on all pages'),
-    'book pages' => t('Show block only on book pages'),
-  );
-  $form['book_block_mode'] = array(
-    '#type' => 'radios',
-    '#title' => t('Book navigation block display'),
-    '#options' => $options,
-    '#default_value' => config('book.settings')->get('block.navigation.mode'),
-    '#description' => t("If <em>Show block on all pages</em> is selected, the block will contain the automatically generated menus for all of the site's books. If <em>Show block only on book pages</em> is selected, the block will contain only the one menu corresponding to the current page's book. In this case, if the current page is not in a book, no block will be displayed. The <em>Page specific visibility settings</em> or other visibility settings can be used in addition to selectively display this block."),
-    );
-
-  return $form;
-}
-
-/**
- * Implements hook_block_save().
- */
-function book_block_save($delta = '', $edit = array()) {
-  $block = array();
-  config('book.settings')->set('block.navigation.mode', $edit['book_block_mode'])->save();
-}
-
-/**
  * Returns HTML for a link to a book title when used as a block title.
  *
  * @param $variables
diff --git a/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
new file mode 100644
index 0000000..13066b4
--- /dev/null
+++ b/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace Drupal\book\Plugin\block\block;
+
+use Drupal\block\BlockBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * @Plugin(
+ *   id = "book_navigation",
+ *   subject = @Translation("Book navigation"),
+ *   module = "book"
+ * )
+ */
+class BookNavigationBlock extends BlockBase {
+
+  /**
+   * Implements BlockInterface::settings().
+   */
+  public function settings() {
+    return array(
+      'cache' => DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE,
+      'block_mode' => "all pages",
+    );
+  }
+
+  /**
+   * Implements BlockInterface::configure()
+   */
+  function configure($form, &$form_state) {
+    $options = array(
+      'all pages' => t('Show block on all pages'),
+      'book pages' => t('Show block only on book pages'),
+    );
+    $form['book_block_mode'] = array(
+      '#type' => 'radios',
+      '#title' => t('Book navigation block display'),
+      '#options' => $options,
+      '#default_value' => $this->configuration['block_mode'],
+      '#description' => t("If <em>Show block on all pages</em> is selected, the block will contain the automatically generated menus for all of the site's books. If <em>Show block only on book pages</em> is selected, the block will contain only the one menu corresponding to the current page's book. In this case, if the current page is not in a book, no block will be displayed. The <em>Page specific visibility settings</em> or other visibility settings can be used in addition to selectively display this block."),
+      );
+
+    return $form;
+  }
+
+  /**
+   * Implements BlockInterface::configureSubmit().
+   */
+  public function configureSubmit($form, &$form_state) {
+    $this->configuration['block_mode'] = $form_state['values']['book_block_mode'];
+  }
+
+  /**
+   * Implements BlockInterface::build().
+   */
+  public function build() {
+    $block = array();
+    $current_bid = 0;
+    if ($node = menu_get_object()) {
+      $current_bid = empty($node->book['bid']) ? 0 : $node->book['bid'];
+    }
+
+    if ($this->configuration['block_mode'] == 'all pages') {
+      $book_menus = array();
+      $pseudo_tree = array(0 => array('below' => FALSE));
+      foreach (book_get_books() as $book_id => $book) {
+        if ($book['bid'] == $current_bid) {
+          // If the current page is a node associated with a book, the menu
+          // needs to be retrieved.
+          $book_menus[$book_id] = menu_tree_output(menu_tree_all_data($node->book['menu_name'], $node->book));
+        }
+        else {
+          // Since we know we will only display a link to the top node, there
+          // is no reason to run an additional menu tree query for each book.
+          $book['in_active_trail'] = FALSE;
+          // Check whether user can access the book link.
+          $book_node = node_load($book['nid']);
+          $book['access'] = node_access('view', $book_node);
+          $pseudo_tree[0]['link'] = $book;
+          $book_menus[$book_id] = menu_tree_output($pseudo_tree);
+        }
+      }
+      if ($book_menus) {
+        return array(
+          '#theme' => 'book_all_books_block',
+          $book_menus
+        );
+      }
+    }
+    elseif ($current_bid) {
+      // Only display this block when the user is browsing a book.
+      $select = db_select('node', 'n')
+        ->fields('n', array('title'))
+        ->condition('n.nid', $node->book['bid'])
+        ->addTag('node_access');
+      $title = $select->execute()->fetchField();
+      // Only show the block if the user has view access for the top-level node.
+      if ($title) {
+        $tree = menu_tree_all_data($node->book['menu_name'], $node->book);
+        // There should only be one element at the top level.
+        $data = array_shift($tree);
+        return array(
+          '#title' => theme('book_title_link', array('link' => $data['link'])),
+          ($data['below']) ? menu_tree_output($data['below']) : '',
+        );
+      }
+    }
+    return array();
+  }
+}
