diff --git a/core/modules/forum/forum.views.inc b/core/modules/forum/forum.views.inc
new file mode 100644
index 0000000..54cb9a7
--- /dev/null
+++ b/core/modules/forum/forum.views.inc
@@ -0,0 +1,238 @@
+<?php
+
+/**
+ * @file
+ * Provide views data and handlers for forum.module.
+ *
+ * @ingroup views_module_handlers
+ */
+
+/**
+ * Implements hook_views_data().
+ */
+function forum_views_data() {
+
+  $data['forum']['table']['group'] = t('Forum');
+  $data['forum']['table']['base'] = array(
+    'field' => 'nid',
+    'title' => t('Forum content'),
+    'access query tag' => 'node_access',
+  );
+
+  $data['forum_index']['nid'] = array(
+    'title' => t('NID'),
+    'help' => t('The NID of the forum index entry.'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric',
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+    'relationship' => array(
+      'base' => 'node',
+      'base field' => 'nid',
+      'label' => t('Node'),
+    ),
+  );
+
+  $data['forum_index']['vid'] = array(j 
+    'title' => t('VID'),
+    'help' => t('The VID of the forum index entry.'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric',
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+    'relationship' => array(
+      'base' => 'node_revision',
+      'base field' => 'vid',
+      'label' => t('Node revision'),
+    ),
+  );
+
+  $data['forum_index']['tid'] = array(
+    'title' => t('Has taxonomy term ID'),
+    'help' => t('Display content if it has the selected taxonomy terms.'),
+    'argument' => array(
+      'id' => 'taxonomy_index_tid',
+      'name table' => 'taxonomy_term_data',
+      'name field' => 'name',
+      'empty field name' => t('Uncategorized'),
+      'numeric' => TRUE,
+      'skip base' => 'taxonomy_term_data',
+    ),
+    'filter' => array(
+      'title' => t('Has taxonomy term'),
+      'id' => 'taxonomy_index_tid',
+      'hierarchy table' => 'taxonomy_term_hierarchy',
+      'numeric' => TRUE,
+      'skip base' => 'taxonomy_term_data',
+      'allow empty' => TRUE,
+    ),
+    'relationship' => array(
+      'base' => 'taxonomy_term',
+      'base field' => 'tid',
+      'label' => t('Term'),
+    ),
+  );
+
+
+  $data['forum_index']['table']['group'] = t('Forum');
+  $data['forum_index']['table']['base'] = array(
+    'field' => 'nid',
+    'title' => t('Forum content'),
+    'access query tag' => 'node_access',
+  );
+
+  $data['forum_index']['nid'] = array(
+    'title' => t('NID'),
+    'help' => t('The NID of the forum index entry.'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric',
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+    'relationship' => array(
+      'base' => 'node',
+      'base field' => 'nid',
+      'label' => t('Node'),
+    ),
+  );
+
+  $data['forum_index']['title'] = array(
+    'title' => t('Title'),
+    'help' => t('The content title.'),
+    'field' => array(
+      'id' => 'node',
+      'click sortable' => TRUE,
+      'link_to_node default' => TRUE,
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+    'filter' => array(
+      'id' => 'string',
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+  );
+
+  $data['forum_index']['tid'] = array(
+    'title' => t('Has taxonomy term ID'),
+    'help' => t('Display content if it has the selected taxonomy terms.'),
+    'argument' => array(
+      'id' => 'taxonomy_index_tid',
+      'name table' => 'taxonomy_term_data',
+      'name field' => 'name',
+      'empty field name' => t('Uncategorized'),
+      'numeric' => TRUE,
+      'skip base' => 'taxonomy_term_data',
+    ),
+    'filter' => array(
+      'title' => t('Has taxonomy term'),
+      'id' => 'taxonomy_index_tid',
+      'hierarchy table' => 'taxonomy_term_hierarchy',
+      'numeric' => TRUE,
+      'skip base' => 'taxonomy_term_data',
+      'allow empty' => TRUE,
+    ),
+    'relationship' => array(
+      'base' => 'taxonomy_term',
+      'base field' => 'tid',
+      'label' => t('Term'),
+    ),
+  );
+
+
+  $data['forum_index']['created'] = array(
+    'title' => t('Post date'),
+    'help' => t('The date the content was posted.'),
+    'field' => array(
+      'id' => 'date',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'id' => 'date'
+    ),
+    'filter' => array(
+      'id' => 'date',
+    ),
+  );
+
+  $data['forum_index']['sticky'] = array(
+    'title' => t('Sticky'),
+    'help' => t('Whether or not the content is sticky.'),
+    'field' => array(
+      'id' => 'boolean',
+      'click sortable' => TRUE,
+      'output formats' => array(
+        'sticky' => array(t('Sticky'), t('Not sticky')),
+      ),
+    ),
+    'filter' => array(
+      'id' => 'boolean',
+      'label' => t('Sticky'),
+      'type' => 'yes-no',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+      'help' => t('Whether or not the content is sticky. To list sticky content first, set this to descending.'),
+    ),
+  );
+
+  $data['forum_index']['last_comment_timestamp'] = array(
+    'title' => t('Last comment time'),
+    'help' => t('Date and time of when the last comment was posted.'),
+    'field' => array(
+      'id' => 'comment_last_timestamp',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'id' => 'date',
+    ),
+    'filter' => array(
+      'id' => 'date',
+    ),
+  );
+
+  $data['forum_index']['comment_count'] = array(
+    'title' => t('Comment count'),
+    'help' => t('The number of comments a node has.'),
+    'field' => array(
+      'id' => 'numeric',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+    'argument' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  return $data;
+}
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php
index 2455b10..2c89ac7 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php
@@ -73,14 +73,16 @@ function testAdministratorRole() {
     $edit['user_admin_role'] = $this->rid;
     $this->drupalPost('admin/config/people/accounts', $edit, t('Save configuration'));
 
-    // Enable aggregator module and ensure the 'administer news feeds'
+    // Enable book and aggregator module and ensure the 'administer news feeds'/'edit own book content'
     // permission is assigned by default.
     $edit = array();
     $edit['modules[Core][aggregator][enable]'] = TRUE;
+    $edit['modules[Core][book][enable]'] = TRUE;
     // Aggregator depends on file module, enable that as well.
     $edit['modules[Core][file][enable]'] = TRUE;
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
     $this->assertTrue(user_access('administer news feeds', $this->admin_user), 'The permission was automatically assigned to the administrator role');
+    $this->assertTrue(user_access('edit own book content', $this->admin_user), 'The permission for node access was assigned to the administrator role.');
   }
 
   /**
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index dcd76d7..9b9f750 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -326,7 +326,7 @@ function user_admin_settings($form, &$form_state) {
     '#title' => t('Administrator role'),
     '#default_value' => $config->get('admin_role'),
     '#options' => $roles,
-    '#description' => t('This role will be automatically assigned new permissions whenever a module is enabled. Changing this setting will not affect existing permissions.'),
+    '#description' => t('This role will be automatically assigned new permissions whenever a module is installed. Changing this setting will not affect existing permissions.'),
   );
 
   // @todo Remove this check once language settings are generalized.
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index b5bbbf7..bd7a795 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -472,5 +472,27 @@ function hook_user_role_delete($role) {
 }
 
 /**
+ * Allows you act when a permission is enabled for a user.
+ *
+ * Allows you act when a user role has been deleted. If your module stores
+ * references to roles, it's recommended that you implement this hook and delete
+ * existing instances of the deleted role in your module database tables.
+ *
+ * @param $permissions
+ *   An array of permissions.
+ */
+function hook_user_permissions_insert($permissions) {
+}
+
+/**
+ * Allows you act when a permission is enabled for a user.
+ *
+ * @param array $permissions
+ *   An array of permissions.
+ */
+function hook_user_permissions_delete($permissions) {
+}
+
+/**
  * @} End of "addtogroup hooks".
  */
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 7bb9f4d..d5eef30 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2211,6 +2211,51 @@ function user_role_revoke_permissions($rid, array $permissions = array()) {
 }
 
 /**
+ * Adds new user permissions to the site.
+ *
+ * Modules should call this function when the list of permissions that the
+ * module provides has changed (for example, a dynamic permission has
+ * appeared).
+ *
+ * @todo: Change documentation since modules don't always have to call it.
+ *
+ * @param $permissions
+ *   A list of permission names to add.
+ */
+function user_permissions_insert(array $permissions = array()) {
+  // Allow modules to react on new permissions.
+  module_invoke_all('user_permissions_insert', $permissions);
+
+  // Grant any new permissions to the administration role.
+  $rid = variable_get('user_admin_role', 0);
+  if ($rid && !empty($permissions)) {
+    user_role_grant_permissions($rid, $permissions);
+  }
+}
+
+/**
+ * Removes user permissions that are no longer available.
+ *
+ * Modules should call this function when the list of permissions that the
+ * module provides has changed (for example, a dynamic permission has
+ * disappeared).
+ *
+ * @todo: Change documentation, or make all core modules actually call it.
+ *
+ * @param $permissions
+ *   A list of permission names to delete.
+ */
+function user_permissions_delete(array $permissions = array()) {
+  // Allow modules to act on the deleted permissions before they are removed.
+  module_invoke_all('user_permissions_delete', $permissions);
+
+  // Delete all records that currently reference the permissions.
+  db_delete('role_permission')
+    ->condition('permission', $permissions, 'IN')
+    ->execute();
+}
+
+/**
  * Implements hook_user_operations().
  */
 function user_user_operations($form = array(), $form_state = array()) {
