From 0e619c6d5e8d75e96f1173a52f32b31780dcc59f Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Sun, 21 Aug 2011 18:21:51 +0200
Subject: [PATCH] Removed obvious cruft in core.

---
 modules/aggregator/aggregator-feed-source.tpl.php  |   34 -
 modules/aggregator/aggregator-item.tpl.php         |   45 -
 modules/aggregator/aggregator-rtl.css              |    4 -
 modules/aggregator/aggregator-summary-item.tpl.php |   23 -
 .../aggregator/aggregator-summary-items.tpl.php    |   23 -
 modules/aggregator/aggregator-wrapper.tpl.php      |   18 -
 modules/aggregator/aggregator.admin.inc            |  597 ---------
 modules/aggregator/aggregator.api.php              |  231 ----
 modules/aggregator/aggregator.css                  |   38 -
 modules/aggregator/aggregator.fetcher.inc          |   61 -
 modules/aggregator/aggregator.info                 |    8 -
 modules/aggregator/aggregator.install              |  280 -----
 modules/aggregator/aggregator.module               |  763 ------------
 modules/aggregator/aggregator.pages.inc            |  524 --------
 modules/aggregator/aggregator.parser.inc           |  328 -----
 modules/aggregator/aggregator.processor.inc        |  200 ---
 modules/aggregator/aggregator.test                 |  859 -------------
 modules/aggregator/tests/aggregator_test.info      |    6 -
 modules/aggregator/tests/aggregator_test.module    |   58 -
 modules/aggregator/tests/aggregator_test_atom.xml  |   20 -
 .../aggregator/tests/aggregator_test_rss091.xml    |   30 -
 modules/blog/blog.info                             |    7 -
 modules/blog/blog.install                          |   23 -
 modules/blog/blog.module                           |  272 ----
 modules/blog/blog.pages.inc                        |  127 --
 modules/blog/blog.test                             |  213 ----
 modules/book/book-all-books-block.tpl.php          |   18 -
 modules/book/book-export-html.tpl.php              |   50 -
 modules/book/book-navigation.tpl.php               |   51 -
 modules/book/book-node-export-html.tpl.php         |   24 -
 modules/book/book-rtl.css                          |   11 -
 modules/book/book.admin.inc                        |  264 ----
 modules/book/book.css                              |   54 -
 modules/book/book.info                             |    9 -
 modules/book/book.install                          |   92 --
 modules/book/book.js                               |   22 -
 modules/book/book.module                           | 1315 --------------------
 modules/book/book.pages.inc                        |  220 ----
 modules/book/book.test                             |  284 -----
 modules/color/color-rtl.css                        |   44 -
 modules/color/color.css                            |   81 --
 modules/color/color.info                           |    6 -
 modules/color/color.install                        |   42 -
 modules/color/color.js                             |  243 ----
 modules/color/color.module                         |  740 -----------
 modules/color/color.test                           |  133 --
 modules/color/images/hook-rtl.png                  |  Bin 116 -> 0 bytes
 modules/color/images/hook.png                      |  Bin 116 -> 0 bytes
 modules/color/images/lock.png                      |  Bin 230 -> 0 bytes
 modules/color/preview.html                         |    7 -
 modules/color/preview.js                           |   34 -
 modules/contact/contact.admin.inc                  |  206 ---
 modules/contact/contact.info                       |    7 -
 modules/contact/contact.install                    |   89 --
 modules/contact/contact.module                     |  257 ----
 modules/contact/contact.pages.inc                  |  291 -----
 modules/contact/contact.test                       |  416 -------
 modules/dashboard/dashboard-rtl.css                |   25 -
 modules/dashboard/dashboard.api.php                |   42 -
 modules/dashboard/dashboard.css                    |  130 --
 modules/dashboard/dashboard.info                   |    8 -
 modules/dashboard/dashboard.install                |   78 --
 modules/dashboard/dashboard.js                     |  218 ----
 modules/dashboard/dashboard.module                 |  677 ----------
 modules/dashboard/dashboard.test                   |  140 ---
 modules/forum/forum-icon.tpl.php                   |   24 -
 modules/forum/forum-list.tpl.php                   |   71 --
 modules/forum/forum-rtl.css                        |   17 -
 modules/forum/forum-submitted.tpl.php              |   28 -
 modules/forum/forum-topic-list.tpl.php             |   68 -
 modules/forum/forum.admin.inc                      |  313 -----
 modules/forum/forum.css                            |   46 -
 modules/forum/forum.info                           |   11 -
 modules/forum/forum.install                        |  241 ----
 modules/forum/forum.module                         | 1291 -------------------
 modules/forum/forum.pages.inc                      |   28 -
 modules/forum/forum.test                           |  525 --------
 modules/forum/forums.tpl.php                       |   22 -
 modules/overlay/images/background.png              |  Bin 76 -> 0 bytes
 modules/overlay/images/close.png                   |  Bin 344 -> 0 bytes
 modules/overlay/overlay-child.css                  |  166 ---
 modules/overlay/overlay-child.js                   |  192 ---
 modules/overlay/overlay-parent.css                 |   50 -
 modules/overlay/overlay-parent.js                  |  961 --------------
 modules/overlay/overlay.api.php                    |   40 -
 modules/overlay/overlay.info                       |    5 -
 modules/overlay/overlay.install                    |   19 -
 modules/overlay/overlay.module                     |  975 ---------------
 modules/overlay/overlay.tpl.php                    |   37 -
 modules/poll/poll-bar--block.tpl.php               |   26 -
 modules/poll/poll-bar.tpl.php                      |   26 -
 modules/poll/poll-results--block.tpl.php           |   28 -
 modules/poll/poll-results.tpl.php                  |   28 -
 modules/poll/poll-rtl.css                          |   10 -
 modules/poll/poll-vote.tpl.php                     |   29 -
 modules/poll/poll.css                              |   51 -
 modules/poll/poll.info                             |    8 -
 modules/poll/poll.install                          |  149 ---
 modules/poll/poll.module                           | 1005 ---------------
 modules/poll/poll.pages.inc                        |   97 --
 modules/poll/poll.test                             |  729 -----------
 modules/poll/poll.tokens.inc                       |  107 --
 modules/profile/profile-block.tpl.php              |   41 -
 modules/profile/profile-listing.tpl.php            |   52 -
 modules/profile/profile-wrapper.tpl.php            |   24 -
 modules/profile/profile.admin.inc                  |  446 -------
 modules/profile/profile.css                        |   10 -
 modules/profile/profile.info                       |   12 -
 modules/profile/profile.install                    |  152 ---
 modules/profile/profile.js                         |   58 -
 modules/profile/profile.module                     |  628 ----------
 modules/profile/profile.pages.inc                  |  139 --
 modules/profile/profile.test                       |  490 --------
 modules/shortcut/shortcut-rtl.css                  |   47 -
 modules/shortcut/shortcut.admin.css                |    8 -
 modules/shortcut/shortcut.admin.inc                |  770 ------------
 modules/shortcut/shortcut.admin.js                 |   99 --
 modules/shortcut/shortcut.api.php                  |   42 -
 modules/shortcut/shortcut.css                      |  106 --
 modules/shortcut/shortcut.info                     |    7 -
 modules/shortcut/shortcut.install                  |  116 --
 modules/shortcut/shortcut.module                   |  745 -----------
 modules/shortcut/shortcut.png                      |  Bin 558 -> 0 bytes
 modules/shortcut/shortcut.test                     |  346 -----
 modules/statistics/statistics.admin.inc            |  274 ----
 modules/statistics/statistics.info                 |    7 -
 modules/statistics/statistics.install              |  136 --
 modules/statistics/statistics.module               |  427 -------
 modules/statistics/statistics.pages.inc            |   91 --
 modules/statistics/statistics.test                 |  444 -------
 modules/statistics/statistics.tokens.inc           |   63 -
 modules/toolbar/toolbar-rtl.css                    |   41 -
 modules/toolbar/toolbar.css                        |  150 ---
 modules/toolbar/toolbar.info                       |    5 -
 modules/toolbar/toolbar.js                         |  106 --
 modules/toolbar/toolbar.module                     |  350 ------
 modules/toolbar/toolbar.png                        |  Bin 558 -> 0 bytes
 modules/toolbar/toolbar.tpl.php                    |   37 -
 modules/tracker/tracker.css                        |    7 -
 modules/tracker/tracker.info                       |    7 -
 modules/tracker/tracker.install                    |  113 --
 modules/tracker/tracker.module                     |  370 ------
 modules/tracker/tracker.pages.inc                  |  126 --
 modules/tracker/tracker.test                       |  254 ----
 profiles/standard/standard.info                    |    5 -
 profiles/standard/standard.install                 |   30 -
 146 files changed, 0 insertions(+), 25924 deletions(-)
 delete mode 100644 modules/aggregator/aggregator-feed-source.tpl.php
 delete mode 100644 modules/aggregator/aggregator-item.tpl.php
 delete mode 100644 modules/aggregator/aggregator-rtl.css
 delete mode 100644 modules/aggregator/aggregator-summary-item.tpl.php
 delete mode 100644 modules/aggregator/aggregator-summary-items.tpl.php
 delete mode 100644 modules/aggregator/aggregator-wrapper.tpl.php
 delete mode 100644 modules/aggregator/aggregator.admin.inc
 delete mode 100644 modules/aggregator/aggregator.api.php
 delete mode 100644 modules/aggregator/aggregator.css
 delete mode 100644 modules/aggregator/aggregator.fetcher.inc
 delete mode 100644 modules/aggregator/aggregator.info
 delete mode 100644 modules/aggregator/aggregator.install
 delete mode 100644 modules/aggregator/aggregator.module
 delete mode 100644 modules/aggregator/aggregator.pages.inc
 delete mode 100644 modules/aggregator/aggregator.parser.inc
 delete mode 100644 modules/aggregator/aggregator.processor.inc
 delete mode 100644 modules/aggregator/aggregator.test
 delete mode 100644 modules/aggregator/tests/aggregator_test.info
 delete mode 100644 modules/aggregator/tests/aggregator_test.module
 delete mode 100644 modules/aggregator/tests/aggregator_test_atom.xml
 delete mode 100644 modules/aggregator/tests/aggregator_test_rss091.xml
 delete mode 100644 modules/blog/blog.info
 delete mode 100644 modules/blog/blog.install
 delete mode 100644 modules/blog/blog.module
 delete mode 100644 modules/blog/blog.pages.inc
 delete mode 100644 modules/blog/blog.test
 delete mode 100644 modules/book/book-all-books-block.tpl.php
 delete mode 100644 modules/book/book-export-html.tpl.php
 delete mode 100644 modules/book/book-navigation.tpl.php
 delete mode 100644 modules/book/book-node-export-html.tpl.php
 delete mode 100644 modules/book/book-rtl.css
 delete mode 100644 modules/book/book.admin.inc
 delete mode 100644 modules/book/book.css
 delete mode 100644 modules/book/book.info
 delete mode 100644 modules/book/book.install
 delete mode 100644 modules/book/book.js
 delete mode 100644 modules/book/book.module
 delete mode 100644 modules/book/book.pages.inc
 delete mode 100644 modules/book/book.test
 delete mode 100644 modules/color/color-rtl.css
 delete mode 100644 modules/color/color.css
 delete mode 100644 modules/color/color.info
 delete mode 100644 modules/color/color.install
 delete mode 100644 modules/color/color.js
 delete mode 100644 modules/color/color.module
 delete mode 100644 modules/color/color.test
 delete mode 100644 modules/color/images/hook-rtl.png
 delete mode 100644 modules/color/images/hook.png
 delete mode 100644 modules/color/images/lock.png
 delete mode 100644 modules/color/preview.html
 delete mode 100644 modules/color/preview.js
 delete mode 100644 modules/contact/contact.admin.inc
 delete mode 100644 modules/contact/contact.info
 delete mode 100644 modules/contact/contact.install
 delete mode 100644 modules/contact/contact.module
 delete mode 100644 modules/contact/contact.pages.inc
 delete mode 100644 modules/contact/contact.test
 delete mode 100644 modules/dashboard/dashboard-rtl.css
 delete mode 100644 modules/dashboard/dashboard.api.php
 delete mode 100644 modules/dashboard/dashboard.css
 delete mode 100644 modules/dashboard/dashboard.info
 delete mode 100644 modules/dashboard/dashboard.install
 delete mode 100644 modules/dashboard/dashboard.js
 delete mode 100644 modules/dashboard/dashboard.module
 delete mode 100644 modules/dashboard/dashboard.test
 delete mode 100644 modules/forum/forum-icon.tpl.php
 delete mode 100644 modules/forum/forum-list.tpl.php
 delete mode 100644 modules/forum/forum-rtl.css
 delete mode 100644 modules/forum/forum-submitted.tpl.php
 delete mode 100644 modules/forum/forum-topic-list.tpl.php
 delete mode 100644 modules/forum/forum.admin.inc
 delete mode 100644 modules/forum/forum.css
 delete mode 100644 modules/forum/forum.info
 delete mode 100644 modules/forum/forum.install
 delete mode 100644 modules/forum/forum.module
 delete mode 100644 modules/forum/forum.pages.inc
 delete mode 100644 modules/forum/forum.test
 delete mode 100644 modules/forum/forums.tpl.php
 delete mode 100644 modules/overlay/images/background.png
 delete mode 100644 modules/overlay/images/close.png
 delete mode 100644 modules/overlay/overlay-child.css
 delete mode 100644 modules/overlay/overlay-child.js
 delete mode 100644 modules/overlay/overlay-parent.css
 delete mode 100644 modules/overlay/overlay-parent.js
 delete mode 100644 modules/overlay/overlay.api.php
 delete mode 100644 modules/overlay/overlay.info
 delete mode 100644 modules/overlay/overlay.install
 delete mode 100644 modules/overlay/overlay.module
 delete mode 100644 modules/overlay/overlay.tpl.php
 delete mode 100644 modules/poll/poll-bar--block.tpl.php
 delete mode 100644 modules/poll/poll-bar.tpl.php
 delete mode 100644 modules/poll/poll-results--block.tpl.php
 delete mode 100644 modules/poll/poll-results.tpl.php
 delete mode 100644 modules/poll/poll-rtl.css
 delete mode 100644 modules/poll/poll-vote.tpl.php
 delete mode 100644 modules/poll/poll.css
 delete mode 100644 modules/poll/poll.info
 delete mode 100644 modules/poll/poll.install
 delete mode 100644 modules/poll/poll.module
 delete mode 100644 modules/poll/poll.pages.inc
 delete mode 100644 modules/poll/poll.test
 delete mode 100644 modules/poll/poll.tokens.inc
 delete mode 100644 modules/profile/profile-block.tpl.php
 delete mode 100644 modules/profile/profile-listing.tpl.php
 delete mode 100644 modules/profile/profile-wrapper.tpl.php
 delete mode 100644 modules/profile/profile.admin.inc
 delete mode 100644 modules/profile/profile.css
 delete mode 100644 modules/profile/profile.info
 delete mode 100644 modules/profile/profile.install
 delete mode 100644 modules/profile/profile.js
 delete mode 100644 modules/profile/profile.module
 delete mode 100644 modules/profile/profile.pages.inc
 delete mode 100644 modules/profile/profile.test
 delete mode 100644 modules/shortcut/shortcut-rtl.css
 delete mode 100644 modules/shortcut/shortcut.admin.css
 delete mode 100644 modules/shortcut/shortcut.admin.inc
 delete mode 100644 modules/shortcut/shortcut.admin.js
 delete mode 100644 modules/shortcut/shortcut.api.php
 delete mode 100644 modules/shortcut/shortcut.css
 delete mode 100644 modules/shortcut/shortcut.info
 delete mode 100644 modules/shortcut/shortcut.install
 delete mode 100644 modules/shortcut/shortcut.module
 delete mode 100644 modules/shortcut/shortcut.png
 delete mode 100644 modules/shortcut/shortcut.test
 delete mode 100644 modules/statistics/statistics.admin.inc
 delete mode 100644 modules/statistics/statistics.info
 delete mode 100644 modules/statistics/statistics.install
 delete mode 100644 modules/statistics/statistics.module
 delete mode 100644 modules/statistics/statistics.pages.inc
 delete mode 100644 modules/statistics/statistics.test
 delete mode 100644 modules/statistics/statistics.tokens.inc
 delete mode 100644 modules/toolbar/toolbar-rtl.css
 delete mode 100644 modules/toolbar/toolbar.css
 delete mode 100644 modules/toolbar/toolbar.info
 delete mode 100644 modules/toolbar/toolbar.js
 delete mode 100644 modules/toolbar/toolbar.module
 delete mode 100644 modules/toolbar/toolbar.png
 delete mode 100644 modules/toolbar/toolbar.tpl.php
 delete mode 100644 modules/tracker/tracker.css
 delete mode 100644 modules/tracker/tracker.info
 delete mode 100644 modules/tracker/tracker.install
 delete mode 100644 modules/tracker/tracker.module
 delete mode 100644 modules/tracker/tracker.pages.inc
 delete mode 100644 modules/tracker/tracker.test

diff --git a/modules/aggregator/aggregator-feed-source.tpl.php b/modules/aggregator/aggregator-feed-source.tpl.php
deleted file mode 100644
index 6a684bd..0000000
--- a/modules/aggregator/aggregator-feed-source.tpl.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to present the source of the feed.
- *
- * The contents are rendered above feed listings when browsing source feeds.
- * For example, "example.com/aggregator/sources/1".
- *
- * Available variables:
- * - $source_icon: Feed icon linked to the source. Rendered through
- *   theme_feed_icon().
- * - $source_image: Image set by the feed source.
- * - $source_description: Description set by the feed source.
- * - $source_url: URL to the feed source.
- * - $last_checked: How long ago the feed was checked locally.
- *
- * @see template_preprocess()
- * @see template_preprocess_aggregator_feed_source()
- */
-?>
-<div class="feed-source">
-  <?php print $source_icon; ?>
-  <?php print $source_image; ?>
-  <div class="feed-description">
-    <?php print $source_description; ?>
-  </div>
-  <div class="feed-url">
-    <em><?php print t('URL:'); ?></em> <a href="<?php print $source_url; ?>"><?php print $source_url; ?></a>
-  </div>
-  <div class="feed-updated">
-    <em><?php print t('Updated:'); ?></em> <?php print $last_checked; ?>
-  </div>
-</div>
diff --git a/modules/aggregator/aggregator-item.tpl.php b/modules/aggregator/aggregator-item.tpl.php
deleted file mode 100644
index c5dd70c..0000000
--- a/modules/aggregator/aggregator-item.tpl.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to format an individual feed item for display
- * on the aggregator page.
- *
- * Available variables:
- * - $feed_url: URL to the originating feed item.
- * - $feed_title: Title of the feed item.
- * - $source_url: Link to the local source section.
- * - $source_title: Title of the remote source.
- * - $source_date: Date the feed was posted on the remote source.
- * - $content: Feed item content.
- * - $categories: Linked categories assigned to the feed.
- *
- * @see template_preprocess()
- * @see template_preprocess_aggregator_item()
- */
-?>
-<div class="feed-item">
-  <h3 class="feed-item-title">
-    <a href="<?php print $feed_url; ?>"><?php print $feed_title; ?></a>
-  </h3>
-
-  <div class="feed-item-meta">
-  <?php if ($source_url) : ?>
-    <a href="<?php print $source_url; ?>" class="feed-item-source"><?php print $source_title; ?></a> -
-  <?php endif; ?>
-    <span class="feed-item-date"><?php print $source_date; ?></span>
-  </div>
-
-<?php if ($content) : ?>
-  <div class="feed-item-body">
-    <?php print $content; ?>
-  </div>
-<?php endif; ?>
-
-<?php if ($categories) : ?>
-  <div class="feed-item-categories">
-    <?php print t('Categories'); ?>: <?php print implode(', ', $categories); ?>
-  </div>
-<?php endif ;?>
-
-</div>
diff --git a/modules/aggregator/aggregator-rtl.css b/modules/aggregator/aggregator-rtl.css
deleted file mode 100644
index ea59ca3..0000000
--- a/modules/aggregator/aggregator-rtl.css
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#aggregator .feed-source .feed-icon {
-  float: left;
-}
diff --git a/modules/aggregator/aggregator-summary-item.tpl.php b/modules/aggregator/aggregator-summary-item.tpl.php
deleted file mode 100644
index 1c82999..0000000
--- a/modules/aggregator/aggregator-summary-item.tpl.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to present a linked feed item for summaries.
- *
- * Available variables:
- * - $feed_url: Link to originating feed.
- * - $feed_title: Title of feed.
- * - $feed_age: Age of remote feed.
- * - $source_url: Link to remote source.
- * - $source_title: Locally set title for the source.
- *
- * @see template_preprocess()
- * @see template_preprocess_aggregator_summary_item()
- */
-?>
-<a href="<?php print $feed_url; ?>"><?php print $feed_title; ?></a>
-<span class="age"><?php print $feed_age; ?></span>
-
-<?php if ($source_url) : ?>,
-<span class="source"><a href="<?php print $source_url; ?>"><?php print $source_title; ?></a></span>
-<?php endif; ?>
diff --git a/modules/aggregator/aggregator-summary-items.tpl.php b/modules/aggregator/aggregator-summary-items.tpl.php
deleted file mode 100644
index 0e2133a..0000000
--- a/modules/aggregator/aggregator-summary-items.tpl.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to present feeds as list items.
- *
- * Each iteration generates a single feed source or category.
- *
- * Available variables:
- * - $title: Title of the feed or category.
- * - $summary_list: Unordered list of linked feed items generated through
- *   theme_item_list().
- * - $source_url: URL to the local source or category.
- *
- * @see template_preprocess()
- * @see template_preprocess_aggregator_summary_items()
- */
-?>
-<h3><?php print $title; ?></h3>
-<?php print $summary_list; ?>
-<div class="links">
-  <a href="<?php print $source_url; ?>"><?php print t('More'); ?></a>
-</div>
diff --git a/modules/aggregator/aggregator-wrapper.tpl.php b/modules/aggregator/aggregator-wrapper.tpl.php
deleted file mode 100644
index 80b9032..0000000
--- a/modules/aggregator/aggregator-wrapper.tpl.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to wrap aggregator content.
- *
- * Available variables:
- * - $content: All aggregator content.
- * - $page: Pager links rendered through theme_pager().
- *
- * @see template_preprocess()
- * @see template_preprocess_aggregator_wrapper()
- */
-?>
-<div id="aggregator">
-  <?php print $content; ?>
-  <?php print $pager; ?>
-</div>
diff --git a/modules/aggregator/aggregator.admin.inc b/modules/aggregator/aggregator.admin.inc
deleted file mode 100644
index 08087af..0000000
--- a/modules/aggregator/aggregator.admin.inc
+++ /dev/null
@@ -1,597 +0,0 @@
-<?php
-
-/**
- * @file
- * Admin page callbacks for the aggregator module.
- */
-
-/**
- * Menu callback; displays the aggregator administration page.
- */
-function aggregator_admin_overview() {
-  return aggregator_view();
-}
-
-/**
- * Displays the aggregator administration page.
- *
- * @return
- *   The page HTML.
- */
-function aggregator_view() {
-  $result = db_query('SELECT f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.hash, f.etag, f.modified, f.image, f.block, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.hash, f.etag, f.modified, f.image, f.block ORDER BY f.title');
-
-  $output = '<h3>' . t('Feed overview') . '</h3>';
-
-  $header = array(t('Title'), t('Items'), t('Last update'), t('Next update'), array('data' => t('Operations'), 'colspan' => '3'));
-  $rows = array();
-  foreach ($result as $feed) {
-    $rows[] = array(
-      l($feed->title, "aggregator/sources/$feed->fid"),
-      format_plural($feed->items, '1 item', '@count items'),
-      ($feed->checked ? t('@time ago', array('@time' => format_interval(REQUEST_TIME - $feed->checked))) : t('never')),
-      ($feed->checked && $feed->refresh ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - REQUEST_TIME))) : t('never')),
-      l(t('edit'), "admin/config/services/aggregator/edit/feed/$feed->fid"),
-      l(t('remove items'), "admin/config/services/aggregator/remove/$feed->fid"),
-      l(t('update items'), "admin/config/services/aggregator/update/$feed->fid"),
-    );
-  }
-  $output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => url('admin/config/services/aggregator/add/feed')))));
-
-  $result = db_query('SELECT c.cid, c.title, COUNT(ci.iid) as items FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid GROUP BY c.cid, c.title ORDER BY title');
-
-  $output .= '<h3>' . t('Category overview') . '</h3>';
-
-  $header = array(t('Title'), t('Items'), t('Operations'));
-  $rows = array();
-  foreach ($result as $category) {
-    $rows[] = array(l($category->title, "aggregator/categories/$category->cid"), format_plural($category->items, '1 item', '@count items'), l(t('edit'), "admin/config/services/aggregator/edit/category/$category->cid"));
-  }
-  $output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No categories available. <a href="@link">Add category</a>.', array('@link' => url('admin/config/services/aggregator/add/category')))));
-
-  return $output;
-}
-
-/**
- * Form builder; Generate a form to add/edit feed sources.
- *
- * @ingroup forms
- * @see aggregator_form_feed_validate()
- * @see aggregator_form_feed_submit()
- */
-function aggregator_form_feed($form, &$form_state, stdClass $feed = NULL) {
-  $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval');
-  $period[AGGREGATOR_CLEAR_NEVER] = t('Never');
-
-  $form['title'] = array('#type' => 'textfield',
-    '#title' => t('Title'),
-    '#default_value' => isset($feed->title) ? $feed->title : '',
-    '#maxlength' => 255,
-    '#description' => t('The name of the feed (or the name of the website providing the feed).'),
-    '#required' => TRUE,
-  );
-  $form['url'] = array('#type' => 'textfield',
-    '#title' => t('URL'),
-    '#default_value' => isset($feed->url) ? $feed->url : '',
-    '#maxlength' => 255,
-    '#description' => t('The fully-qualified URL of the feed.'),
-    '#required' => TRUE,
-  );
-  $form['refresh'] = array('#type' => 'select',
-    '#title' => t('Update interval'),
-    '#default_value' => isset($feed->refresh) ? $feed->refresh : 3600,
-    '#options' => $period,
-    '#description' => t('The length of time between feed updates. Requires a correctly configured <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status'))),
-  );
-  $form['block'] = array('#type' => 'select',
-    '#title' => t('News items in block'),
-    '#default_value' => isset($feed->block) ? $feed->block : 5,
-    '#options' => drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)),
-    '#description' => t("Drupal can make a block with the most recent news items of this feed. You can <a href=\"@block-admin\">configure blocks</a> to be displayed in the sidebar of your page. This setting lets you configure the number of news items to show in this feed's block. If you choose '0' this feed's block will be disabled.", array('@block-admin' => url('admin/structure/block'))),
-  );
-
-  // Handling of categories.
-  $options = array();
-  $values = array();
-  $categories = db_query('SELECT c.cid, c.title, f.fid FROM {aggregator_category} c LEFT JOIN {aggregator_category_feed} f ON c.cid = f.cid AND f.fid = :fid ORDER BY title', array(':fid' => isset($feed->fid) ? $feed->fid : NULL));
-  foreach ($categories as $category) {
-    $options[$category->cid] = check_plain($category->title);
-    if ($category->fid) $values[] = $category->cid;
-  }
-
-  if ($options) {
-    $form['category'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Categorize news items'),
-      '#default_value' => $values,
-      '#options' => $options,
-      '#description' => t('New feed items are automatically filed in the checked categories.'),
-    );
-  }
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
-  if (!empty($feed->fid)) {
-    $form['actions']['delete'] = array(
-      '#type' => 'submit',
-      '#value' => t('Delete'),
-    );
-    $form['fid'] = array(
-      '#type' => 'hidden',
-      '#value' => $feed->fid,
-    );
-  }
-
-  return $form;
-}
-
-/**
- * Validate aggregator_form_feed() form submissions.
- */
-function aggregator_form_feed_validate($form, &$form_state) {
-  if ($form_state['values']['op'] == t('Save')) {
-    // Ensure URL is valid.
-    if (!valid_url($form_state['values']['url'], TRUE)) {
-      form_set_error('url', t('The URL %url is invalid. Enter a fully-qualified URL, such as http://www.example.com/feed.xml.', array('%url' => $form_state['values']['url'])));
-    }
-    // Check for duplicate titles.
-    if (isset($form_state['values']['fid'])) {
-      $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE (title = :title OR url = :url) AND fid <> :fid", array(':title' => $form_state['values']['title'], ':url' => $form_state['values']['url'], ':fid' => $form_state['values']['fid']));
-    }
-    else {
-      $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = :title OR url = :url", array(':title' => $form_state['values']['title'], ':url' => $form_state['values']['url']));
-    }
-    foreach ($result as $feed) {
-      if (strcasecmp($feed->title, $form_state['values']['title']) == 0) {
-        form_set_error('title', t('A feed named %feed already exists. Enter a unique title.', array('%feed' => $form_state['values']['title'])));
-      }
-      if (strcasecmp($feed->url, $form_state['values']['url']) == 0) {
-        form_set_error('url', t('A feed with this URL %url already exists. Enter a unique URL.', array('%url' => $form_state['values']['url'])));
-      }
-    }
-  }
-}
-
-/**
- * Process aggregator_form_feed() form submissions.
- *
- * @todo Add delete confirmation dialog.
- */
-function aggregator_form_feed_submit($form, &$form_state) {
-  if ($form_state['values']['op'] == t('Delete')) {
-    $title = $form_state['values']['title'];
-    // Unset the title.
-    unset($form_state['values']['title']);
-  }
-  aggregator_save_feed($form_state['values']);
-  if (isset($form_state['values']['fid'])) {
-    if (isset($form_state['values']['title'])) {
-      drupal_set_message(t('The feed %feed has been updated.', array('%feed' => $form_state['values']['title'])));
-      if (arg(0) == 'admin') {
-        $form_state['redirect'] = 'admin/config/services/aggregator/';
-        return;
-      }
-      else {
-        $form_state['redirect'] = 'aggregator/sources/' . $form_state['values']['fid'];
-        return;
-      }
-    }
-    else {
-      watchdog('aggregator', 'Feed %feed deleted.', array('%feed' => $title));
-      drupal_set_message(t('The feed %feed has been deleted.', array('%feed' => $title)));
-      if (arg(0) == 'admin') {
-        $form_state['redirect'] = 'admin/config/services/aggregator/';
-        return;
-      }
-      else {
-        $form_state['redirect'] = 'aggregator/sources/';
-        return;
-      }
-    }
-  }
-  else {
-    watchdog('aggregator', 'Feed %feed added.', array('%feed' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/services/aggregator'));
-    drupal_set_message(t('The feed %feed has been added.', array('%feed' => $form_state['values']['title'])));
-  }
-}
-
-function aggregator_admin_remove_feed($form, $form_state, $feed) {
-  return confirm_form(
-    array(
-      'feed' => array(
-        '#type' => 'value',
-        '#value' => $feed,
-      ),
-    ),
-    t('Are you sure you want to remove all items from the feed %feed?', array('%feed' => $feed->title)),
-    'admin/config/services/aggregator',
-    t('This action cannot be undone.'),
-    t('Remove items'),
-    t('Cancel')
-  );
-}
-
-/**
- * Remove all items from a feed and redirect to the overview page.
- *
- * @param $feed
- *   An associative array describing the feed to be cleared.
- */
-function aggregator_admin_remove_feed_submit($form, &$form_state) {
-  aggregator_remove($form_state['values']['feed']);
-  $form_state['redirect'] = 'admin/config/services/aggregator';
-}
-
-/**
- * Form builder; Generate a form to import feeds from OPML.
- *
- * @ingroup forms
- * @see aggregator_form_opml_validate()
- * @see aggregator_form_opml_submit()
- */
-function aggregator_form_opml($form, &$form_state) {
-  $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval');
-
-  $form['upload'] = array(
-    '#type' => 'file',
-    '#title' => t('OPML File'),
-    '#description' => t('Upload an OPML file containing a list of feeds to be imported.'),
-  );
-  $form['remote'] = array(
-    '#type' => 'textfield',
-    '#title' => t('OPML Remote URL'),
-    '#maxlength' => 1024,
-    '#description' => t('Enter the URL of an OPML file. This file will be downloaded and processed only once on submission of the form.'),
-  );
-  $form['refresh'] = array(
-    '#type' => 'select',
-    '#title' => t('Update interval'),
-    '#default_value' => 3600,
-    '#options' => $period,
-    '#description' => t('The length of time between feed updates. Requires a correctly configured <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status'))),
-  );
-  $form['block'] = array('#type' => 'select',
-    '#title' => t('News items in block'),
-    '#default_value' => 5,
-    '#options' => drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)),
-    '#description' => t("Drupal can make a block with the most recent news items of a feed. You can <a href=\"@block-admin\">configure blocks</a> to be displayed in the sidebar of your page. This setting lets you configure the number of news items to show in a feed's block. If you choose '0' these feeds' blocks will be disabled.", array('@block-admin' => url('admin/structure/block'))),
-  );
-
-  // Handling of categories.
-  $options = array_map('check_plain', db_query("SELECT cid, title FROM {aggregator_category} ORDER BY title")->fetchAllKeyed());
-  if ($options) {
-    $form['category'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Categorize news items'),
-      '#options' => $options,
-      '#description' => t('New feed items are automatically filed in the checked categories.'),
-    );
-  }
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Import')
-  );
-
-  return $form;
-}
-
-/**
- * Validate aggregator_form_opml form submissions.
- */
-function aggregator_form_opml_validate($form, &$form_state) {
-  // If both fields are empty or filled, cancel.
-  if (empty($form_state['values']['remote']) == empty($_FILES['files']['name']['upload'])) {
-    form_set_error('remote', t('You must <em>either</em> upload a file or enter a URL.'));
-  }
-
-  // Validate the URL, if one was entered.
-  if (!empty($form_state['values']['remote']) && !valid_url($form_state['values']['remote'], TRUE)) {
-    form_set_error('remote', t('This URL is not valid.'));
-  }
-}
-
-/**
- * Process aggregator_form_opml form submissions.
- */
-function aggregator_form_opml_submit($form, &$form_state) {
-  $data = '';
-  $validators = array('file_validate_extensions' => array('opml xml'));
-  if ($file = file_save_upload('upload', $validators)) {
-    $data = file_get_contents($file->uri);
-  }
-  else {
-    $response = drupal_http_request($form_state['values']['remote']);
-    if (!isset($response->error)) {
-      $data = $response->data;
-    }
-  }
-
-  $feeds = _aggregator_parse_opml($data);
-  if (empty($feeds)) {
-    drupal_set_message(t('No new feed has been added.'));
-    return;
-  }
-
-  $form_state['values']['op'] = t('Save');
-
-  foreach ($feeds as $feed) {
-    // Ensure URL is valid.
-    if (!valid_url($feed['url'], TRUE)) {
-      drupal_set_message(t('The URL %url is invalid.', array('%url' => $feed['url'])), 'warning');
-      continue;
-    }
-
-    // Check for duplicate titles or URLs.
-    $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = :title OR url = :url", array(':title' => $feed['title'], ':url' => $feed['url']));
-    foreach ($result as $old) {
-      if (strcasecmp($old->title, $feed['title']) == 0) {
-        drupal_set_message(t('A feed named %title already exists.', array('%title' => $old->title)), 'warning');
-        continue 2;
-      }
-      if (strcasecmp($old->url, $feed['url']) == 0) {
-        drupal_set_message(t('A feed with the URL %url already exists.', array('%url' => $old->url)), 'warning');
-        continue 2;
-      }
-    }
-
-    $form_state['values']['title'] = $feed['title'];
-    $form_state['values']['url'] = $feed['url'];
-    drupal_form_submit('aggregator_form_feed', $form_state);
-  }
-
-  $form_state['redirect'] = 'admin/config/services/aggregator';
-}
-
-/**
- * Parse an OPML file.
- *
- * Feeds are recognized as <outline> elements with the attributes "text" and
- * "xmlurl" set.
- *
- * @param $opml
- *   The complete contents of an OPML document.
- *
- * @return
- *   An array of feeds, each an associative array with a "title" and a "url"
- *   element, or NULL if the OPML document failed to be parsed. An empty
- *   array will be returned if the document is valid but contains no feeds, as
- *   some OPML documents do.
- */
-function _aggregator_parse_opml($opml) {
-  $feeds = array();
-  $xml_parser = drupal_xml_parser_create($opml);
-  if (xml_parse_into_struct($xml_parser, $opml, $values)) {
-    foreach ($values as $entry) {
-      if ($entry['tag'] == 'OUTLINE' && isset($entry['attributes'])) {
-        $item = $entry['attributes'];
-        if (!empty($item['XMLURL']) && !empty($item['TEXT'])) {
-          $feeds[] = array('title' => $item['TEXT'], 'url' => $item['XMLURL']);
-        }
-      }
-    }
-  }
-  xml_parser_free($xml_parser);
-
-  return $feeds;
-}
-
-/**
- * Menu callback; refreshes a feed, then redirects to the overview page.
- *
- * @param $feed
- *   An object describing the feed to be refreshed.
- */
-function aggregator_admin_refresh_feed($feed) {
-  aggregator_refresh($feed);
-  drupal_goto('admin/config/services/aggregator');
-}
-
-/**
- * Form builder; Configure the aggregator system.
- *
- * @ingroup forms
- */
-function aggregator_admin_form($form, $form_state) {
-  // Global aggregator settings.
-  $form['aggregator_allowed_html_tags'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Allowed HTML tags'),
-    '#size' => 80,
-    '#maxlength' => 255,
-    '#default_value' => variable_get('aggregator_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'),
-    '#description' => t('A space-separated list of HTML tags allowed in the content of feed items. Disallowed tags are stripped from the content.'),
-  );
-
-  // Make sure configuration is sane.
-  aggregator_sanitize_configuration();
-
-  // Get all available fetchers.
-  $fetchers = module_implements('aggregator_fetch');
-  foreach ($fetchers as $k => $module) {
-    if ($info = module_invoke($module, 'aggregator_fetch_info')) {
-      $label = $info['title'] . ' <span class="description">' . $info['description'] . '</span>';
-    }
-    else {
-      $label = $module;
-    }
-    unset($fetchers[$k]);
-    $fetchers[$module] = $label;
-  }
-
-  // Get all available parsers.
-  $parsers = module_implements('aggregator_parse');
-  foreach ($parsers as $k => $module) {
-    if ($info = module_invoke($module, 'aggregator_parse_info')) {
-      $label = $info['title'] . ' <span class="description">' . $info['description'] . '</span>';
-    }
-    else {
-      $label = $module;
-    }
-    unset($parsers[$k]);
-    $parsers[$module] = $label;
-  }
-
-  // Get all available processors.
-  $processors = module_implements('aggregator_process');
-  foreach ($processors as $k => $module) {
-    if ($info = module_invoke($module, 'aggregator_process_info')) {
-      $label = $info['title'] . ' <span class="description">' . $info['description'] . '</span>';
-    }
-    else {
-      $label = $module;
-    }
-    unset($processors[$k]);
-    $processors[$module] = $label;
-  }
-
-  // Only show basic configuration if there are actually options.
-  $basic_conf = array();
-  if (count($fetchers) > 1) {
-    $basic_conf['aggregator_fetcher'] = array(
-      '#type' => 'radios',
-      '#title' => t('Fetcher'),
-      '#description' => t('Fetchers download data from an external source. Choose a fetcher suitable for the external source you would like to download from.'),
-      '#options' => $fetchers,
-      '#default_value' => variable_get('aggregator_fetcher', 'aggregator'),
-    );
-  }
-  if (count($parsers) > 1) {
-    $basic_conf['aggregator_parser'] = array(
-      '#type' => 'radios',
-      '#title' => t('Parser'),
-      '#description' => t('Parsers transform downloaded data into standard structures. Choose a parser suitable for the type of feeds you would like to aggregate.'),
-      '#options' => $parsers,
-      '#default_value' => variable_get('aggregator_parser', 'aggregator'),
-    );
-  }
-  if (count($processors) > 1) {
-    $basic_conf['aggregator_processors'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Processors'),
-      '#description' => t('Processors act on parsed feed data, for example they store feed items. Choose the processors suitable for your task.'),
-      '#options' => $processors,
-      '#default_value' => variable_get('aggregator_processors', array('aggregator')),
-    );
-  }
-  if (count($basic_conf)) {
-    $form['basic_conf'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Basic configuration'),
-      '#description' => t('For most aggregation tasks, the default settings are fine.'),
-      '#collapsible' => TRUE,
-      '#collapsed' => FALSE,
-      );
-    $form['basic_conf'] += $basic_conf;
-  }
-
-  // Implementing modules will expect an array at $form['modules'].
-  $form['modules'] = array();
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save configuration'),
-  );
-
-  return $form;
-}
-
-function aggregator_admin_form_submit($form, &$form_state) {
-  if (isset($form_state['values']['aggregator_processors'])) {
-    $form_state['values']['aggregator_processors'] = array_filter($form_state['values']['aggregator_processors']);
-  }
-  system_settings_form_submit($form, $form_state);
-}
-
-/**
- * Form builder; Generate a form to add/edit/delete aggregator categories.
- *
- * @ingroup forms
- * @see aggregator_form_category_validate()
- * @see aggregator_form_category_submit()
- */
-function aggregator_form_category($form, &$form_state, $edit = array('title' => '', 'description' => '', 'cid' => NULL)) {
-  $form['title'] = array('#type' => 'textfield',
-    '#title' => t('Title'),
-    '#default_value' => $edit['title'],
-    '#maxlength' => 64,
-    '#required' => TRUE,
-  );
-  $form['description'] = array('#type' => 'textarea',
-    '#title' => t('Description'),
-    '#default_value' => $edit['description'],
-  );
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save'));
-  if ($edit['cid']) {
-    $form['actions']['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
-    $form['cid'] = array('#type' => 'hidden', '#value' => $edit['cid']);
-  }
-
-  return $form;
-}
-
-/**
- * Validate aggregator_form_feed form submissions.
- */
-function aggregator_form_category_validate($form, &$form_state) {
-  if ($form_state['values']['op'] == t('Save')) {
-    // Check for duplicate titles
-    if (isset($form_state['values']['cid'])) {
-      $category = db_query("SELECT cid FROM {aggregator_category} WHERE title = :title AND cid <> :cid", array(':title' => $form_state['values']['title'], ':cid' => $form_state['values']['cid']))->fetchObject();
-    }
-    else {
-      $category = db_query("SELECT cid FROM {aggregator_category} WHERE title = :title", array(':title' => $form_state['values']['title']))->fetchObject();
-    }
-    if ($category) {
-      form_set_error('title', t('A category named %category already exists. Enter a unique title.', array('%category' => $form_state['values']['title'])));
-    }
-  }
-}
-
-/**
- * Process aggregator_form_category form submissions.
- *
- * @todo Add delete confirmation dialog.
- */
-function aggregator_form_category_submit($form, &$form_state) {
-  if ($form_state['values']['op'] == t('Delete')) {
-    $title = $form_state['values']['title'];
-    // Unset the title.
-    unset($form_state['values']['title']);
-  }
-  aggregator_save_category($form_state['values']);
-  if (isset($form_state['values']['cid'])) {
-    if (isset($form_state['values']['title'])) {
-      drupal_set_message(t('The category %category has been updated.', array('%category' => $form_state['values']['title'])));
-      if (arg(0) == 'admin') {
-        $form_state['redirect'] = 'admin/config/services/aggregator/';
-        return;
-      }
-      else {
-        $form_state['redirect'] = 'aggregator/categories/' . $form_state['values']['cid'];
-        return;
-      }
-    }
-    else {
-      watchdog('aggregator', 'Category %category deleted.', array('%category' => $title));
-      drupal_set_message(t('The category %category has been deleted.', array('%category' => $title)));
-      if (arg(0) == 'admin') {
-        $form_state['redirect'] = 'admin/config/services/aggregator/';
-        return;
-      }
-      else {
-        $form_state['redirect'] = 'aggregator/categories/';
-        return;
-      }
-    }
-  }
-  else {
-    watchdog('aggregator', 'Category %category added.', array('%category' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/services/aggregator'));
-    drupal_set_message(t('The category %category has been added.', array('%category' => $form_state['values']['title'])));
-  }
-}
diff --git a/modules/aggregator/aggregator.api.php b/modules/aggregator/aggregator.api.php
deleted file mode 100644
index f31413c..0000000
--- a/modules/aggregator/aggregator.api.php
+++ /dev/null
@@ -1,231 +0,0 @@
-<?php
-
-/**
- * @file
- * Documentation for aggregator API.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Implement this hook to create an alternative fetcher for aggregator module.
- *
- * A fetcher downloads feed data to a Drupal site. The fetcher is called
- * at the first of the three aggregation stages: data is downloaded by the
- * active fetcher, it is converted to a common format by the active parser and
- * finally, it is passed to all active processors which manipulate or store the
- * data.
- *
- * Modules that define this hook can be set as active fetcher on
- * admin/config/services/aggregator. Only one fetcher can be active at a time.
- *
- * @param $feed
- *   The $feed object that describes the resource to be downloaded.
- *   $feed->url contains the link to the feed. Download the data at the URL
- *   and expose it to other modules by attaching it to $feed->source_string.
- *
- * @return
- *   TRUE if fetching was successful, FALSE otherwise.
- *
- * @see hook_aggregator_fetch_info()
- * @see hook_aggregator_parse()
- * @see hook_aggregator_process()
- *
- * @ingroup aggregator
- */
-function hook_aggregator_fetch($feed) {
-  $feed->source_string = mymodule_fetch($feed->url);
-}
-
-/**
- * Implement this hook to expose the title and a short description of your
- * fetcher.
- *
- * The title and the description provided are shown on
- * admin/config/services/aggregator among other places. Use as title the human
- * readable name of the fetcher and as description a brief (40 to 80 characters)
- * explanation of the fetcher's functionality.
- *
- * This hook is only called if your module implements hook_aggregator_fetch().
- * If this hook is not implemented aggregator will use your module's file name
- * as title and there will be no description.
- *
- * @return
- *   An associative array defining a title and a description string.
- *
- * @see hook_aggregator_fetch()
- *
- * @ingroup aggregator
- */
-function hook_aggregator_fetch_info() {
-  return array(
-    'title' => t('Default fetcher'),
-    'description' => t('Default fetcher for resources available by URL.'),
-  );
-}
-
-/**
- * Implement this hook to create an alternative parser for aggregator module.
- *
- * A parser converts feed item data to a common format. The parser is called
- * at the second of the three aggregation stages: data is downloaded by the
- * active fetcher, it is converted to a common format by the active parser and
- * finally, it is passed to all active processors which manipulate or store the
- * data.
- *
- * Modules that define this hook can be set as active parser on
- * admin/config/services/aggregator. Only one parser can be active at a time.
- *
- * @param $feed
- *   The $feed object that describes the resource to be parsed.
- *   $feed->source_string contains the raw feed data as a string. Parse data
- *   from $feed->source_string and expose it to other modules as an array of
- *   data items on $feed->items.
- *
- *   Feed format:
- *   - $feed->description (string) - description of the feed
- *   - $feed->image (string) - image for the feed
- *   - $feed->etag (string) - value of feed's entity tag header field
- *   - $feed->modified (UNIX timestamp) - value of feed's last modified header
- *     field
- *   - $feed->items (Array) - array of feed items.
- *
- *   By convention, the common format for a single feed item is:
- *   $item[key-name] = value;
- *
- *   Recognized keys:
- *   TITLE (string) - the title of a feed item
- *   DESCRIPTION (string) - the description (body text) of a feed item
- *   TIMESTAMP (UNIX timestamp) - the feed item's published time as UNIX timestamp
- *   AUTHOR (string) - the feed item's author
- *   GUID (string) - RSS/Atom global unique identifier
- *   LINK (string) - the feed item's URL
- *
- * @return
- *   TRUE if parsing was successful, FALSE otherwise.
- *
- * @see hook_aggregator_parse_info()
- * @see hook_aggregator_fetch()
- * @see hook_aggregator_process()
- *
- * @ingroup aggregator
- */
-function hook_aggregator_parse($feed) {
-  if ($items = mymodule_parse($feed->source_string)) {
-    $feed->items = $items;
-    return TRUE;
-  }
-  return FALSE;
-}
-
-/**
- * Implement this hook to expose the title and a short description of your
- * parser.
- *
- * The title and the description provided are shown on
- * admin/config/services/aggregator among other places. Use as title the human
- * readable name of the parser and as description a brief (40 to 80 characters)
- * explanation of the parser's functionality.
- *
- * This hook is only called if your module implements hook_aggregator_parse().
- * If this hook is not implemented aggregator will use your module's file name
- * as title and there will be no description.
- *
- * @return
- *   An associative array defining a title and a description string.
- *
- * @see hook_aggregator_parse()
- *
- * @ingroup aggregator
- */
-function hook_aggregator_parse_info() {
-  return array(
-    'title' => t('Default parser'),
-    'description' => t('Default parser for RSS, Atom and RDF feeds.'),
-  );
-}
-
-/**
- * Implement this hook to create a processor for aggregator module.
- *
- * A processor acts on parsed feed data. Active processors are called at the
- * third and last of the aggregation stages: data is downloaded by the active
- * fetcher, it is converted to a common format by the active parser and
- * finally, it is passed to all active processors which manipulate or store the
- * data.
- *
- * Modules that define this hook can be activated as processor on
- * admin/config/services/aggregator.
- *
- * @param $feed
- *   The $feed object that describes the resource to be processed. $feed->items
- *   contains an array of feed items downloaded and parsed at the parsing
- *   stage. See hook_aggregator_parse() for the basic format of a single item
- *   in the $feed->items array. For the exact format refer to the particular
- *   parser in use.
- *
- * @see hook_aggregator_process_info()
- * @see hook_aggregator_fetch()
- * @see hook_aggregator_parse()
- *
- * @ingroup aggregator
- */
-function hook_aggregator_process($feed) {
-  foreach ($feed->items as $item) {
-    mymodule_save($item);
-  }
-}
-
-/**
- * Implement this hook to expose the title and a short description of your
- * processor.
- *
- * The title and the description provided are shown most importantly on
- * admin/config/services/aggregator. Use as title the natural name of the
- * processor and as description a brief (40 to 80 characters) explanation of
- * the functionality.
- *
- * This hook is only called if your module implements
- * hook_aggregator_process(). If this hook is not implemented aggregator
- * will use your module's file name as title and there will be no description.
- *
- * @return
- *   An associative array defining a title and a description string.
- *
- * @see hook_aggregator_process()
- *
- * @ingroup aggregator
- */
-function hook_aggregator_process_info($feed) {
-  return array(
-    'title' => t('Default processor'),
-    'description' => t('Creates lightweight records of feed items.'),
-  );
-}
-
-/**
- * Implement this hook to remove stored data if a feed is being deleted or a
- * feed's items are being removed.
- *
- * Aggregator calls this hook if either a feed is deleted or a user clicks on
- * "remove items".
- *
- * If your module stores feed items for example on hook_aggregator_process() it
- * is recommended to implement this hook and to remove data related to $feed
- * when called.
- *
- * @param $feed
- *   The $feed object whose items are being removed.
- *
- * @ingroup aggregator
- */
-function hook_aggregator_remove($feed) {
-  mymodule_remove_items($feed->fid);
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/modules/aggregator/aggregator.css b/modules/aggregator/aggregator.css
deleted file mode 100644
index 13c58ff..0000000
--- a/modules/aggregator/aggregator.css
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#aggregator .feed-source .feed-title {
-  margin-top: 0;
-}
-#aggregator .feed-source .feed-image img {
-  margin-bottom: 0.75em;
-}
-#aggregator .feed-source .feed-icon {
-  float: right; /* LTR */
-  display: block;
-}
-#aggregator .feed-item {
-  margin-bottom: 1.5em;
-}
-#aggregator .feed-item-title {
-  margin-bottom: 0;
-  font-size: 1.3em;
-}
-#aggregator .feed-item-meta,
-#aggregator .feed-item-body {
-  margin-bottom: 0.5em;
-}
-#aggregator .feed-item-categories {
-  font-size: 0.9em;
-}
-#aggregator td {
-  vertical-align: bottom;
-}
-#aggregator td.categorize-item {
-  white-space: nowrap;
-}
-#aggregator .categorize-item .news-item .body {
-  margin-top: 0;
-}
-#aggregator .categorize-item h3 {
-  margin-bottom: 1em;
-  margin-top: 0;
-}
diff --git a/modules/aggregator/aggregator.fetcher.inc b/modules/aggregator/aggregator.fetcher.inc
deleted file mode 100644
index 0f72877..0000000
--- a/modules/aggregator/aggregator.fetcher.inc
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-/**
- * @file
- * Fetcher functions for the aggregator module.
- */
-
-/**
- * Implements hook_aggregator_fetch_info().
- */
-function aggregator_aggregator_fetch_info() {
-  return array(
-    'title' => t('Default fetcher'),
-    'description' => t('Downloads data from a URL using Drupal\'s HTTP request handler.'),
-  );
-}
-
-/**
- * Implements hook_aggregator_fetch().
- */
-function aggregator_aggregator_fetch($feed) {
-  $feed->source_string = FALSE;
-
-  // Generate conditional GET headers.
-  $headers = array();
-  if ($feed->etag) {
-    $headers['If-None-Match'] = $feed->etag;
-  }
-  if ($feed->modified) {
-    $headers['If-Modified-Since'] = gmdate(DATE_RFC1123, $feed->modified);
-  }
-
-  // Request feed.
-  $result = drupal_http_request($feed->url, array('headers' => $headers));
-
-  // Process HTTP response code.
-  switch ($result->code) {
-    case 304:
-      break;
-    case 301:
-      $feed->url = $result->redirect_url;
-      // Do not break here.
-    case 200:
-    case 302:
-    case 307:
-      if (!isset($result->data)) {
-        $result->data = '';
-      }
-      if (!isset($result->headers)) {
-        $result->headers = array();
-      }
-      $feed->source_string = $result->data;
-      $feed->http_headers = $result->headers;
-      break;
-    default:
-      watchdog('aggregator', 'The feed from %site seems to be broken, due to "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error), WATCHDOG_WARNING);
-      drupal_set_message(t('The feed from %site seems to be broken, because of error "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error)));
-  }
-
-  return $feed->source_string === FALSE ? FALSE : TRUE;
-}
diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info
deleted file mode 100644
index f147740..0000000
--- a/modules/aggregator/aggregator.info
+++ /dev/null
@@ -1,8 +0,0 @@
-name = Aggregator
-description = "Aggregates syndicated content (RSS, RDF, and Atom feeds)."
-package = Core
-version = VERSION
-core = 8.x
-files[] = aggregator.test
-configure = admin/config/services/aggregator/settings
-stylesheets[all][] = aggregator.css
diff --git a/modules/aggregator/aggregator.install b/modules/aggregator/aggregator.install
deleted file mode 100644
index eecd14f..0000000
--- a/modules/aggregator/aggregator.install
+++ /dev/null
@@ -1,280 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the aggregator module.
- */
-
-/**
- * Implements hook_uninstall().
- */
-function aggregator_uninstall() {
-  variable_del('aggregator_allowed_html_tags');
-  variable_del('aggregator_summary_items');
-  variable_del('aggregator_clear');
-  variable_del('aggregator_category_selector');
-  variable_del('aggregator_fetcher');
-  variable_del('aggregator_parser');
-  variable_del('aggregator_processors');
-  variable_del('aggregator_teaser_length');
-}
-
-/**
- * Implements hook_schema().
- */
-function aggregator_schema() {
-  $schema['aggregator_category'] = array(
-    'description' => 'Stores categories for aggregator feeds and feed items.',
-    'fields' => array(
-      'cid'  => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique aggregator category ID.',
-      ),
-      'title' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Title of the category.',
-      ),
-      'description' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-        'description' => 'Description of the category',
-      ),
-      'block' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'The number of recent items to show within the category block.',
-      )
-    ),
-    'primary key' => array('cid'),
-    'unique keys' => array(
-      'title' => array('title'),
-    ),
-  );
-
-  $schema['aggregator_category_feed'] = array(
-    'description' => 'Bridge table; maps feeds to categories.',
-    'fields' => array(
-      'fid' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The feed's {aggregator_feed}.fid.",
-      ),
-      'cid' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {aggregator_category}.cid to which the feed is being assigned.',
-      )
-    ),
-    'primary key' => array('cid', 'fid'),
-    'indexes' => array(
-      'fid' => array('fid'),
-    ),
-    'foreign keys' => array(
-      'aggregator_category' => array(
-        'table' => 'aggregator_category',
-        'columns' => array('cid' => 'cid'),
-      ),
-    ),
-  );
-
-  $schema['aggregator_category_item'] = array(
-    'description' => 'Bridge table; maps feed items to categories.',
-    'fields' => array(
-      'iid' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The feed item's {aggregator_item}.iid.",
-      ),
-      'cid' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {aggregator_category}.cid to which the feed item is being assigned.',
-      )
-    ),
-    'primary key' => array('cid', 'iid'),
-    'indexes' => array(
-      'iid' => array('iid'),
-    ),
-    'foreign keys' => array(
-      'aggregator_category' => array(
-        'table' => 'aggregator_category',
-        'columns' => array('cid' => 'cid'),
-      ),
-    ),
-  );
-
-  $schema['aggregator_feed'] = array(
-    'description' => 'Stores feeds to be parsed by the aggregator.',
-    'fields' => array(
-      'fid' => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique feed ID.',
-      ),
-      'title' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Title of the feed.',
-      ),
-      'url' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'URL to the feed.',
-      ),
-      'refresh' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'How often to check for new feed items, in seconds.',
-      ),
-      'checked' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Last time feed was checked for new items, as Unix timestamp.',
-      ),
-      'queued' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Time when this feed was queued for refresh, 0 if not queued.',
-      ),
-      'link' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The parent website of the feed; comes from the <link> element in the feed.',
-      ),
-      'description' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-        'description' => "The parent website's description; comes from the <description> element in the feed.",
-      ),
-      'image' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-        'description' => 'An image representing the feed.',
-      ),
-      'hash' => array(
-        'type' => 'varchar',
-        'length' => 64,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Calculated hash of the feed data, used for validating cache.',
-      ),
-      'etag' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Entity tag HTTP response header, used for validating cache.',
-      ),
-      'modified' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'When the feed was last modified, as a Unix timestamp.',
-      ),
-      'block' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => "Number of items to display in the feed's block.",
-      )
-    ),
-    'primary key' => array('fid'),
-    'unique keys' => array(
-      'url'  => array('url'),
-      'title' => array('title'),
-    ),
-    'indexes' => array(
-      'queued' => array('queued'),
-    ),
-  );
-
-  $schema['aggregator_item'] = array(
-    'description' => 'Stores the individual items imported from feeds.',
-    'fields' => array(
-      'iid'  => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique ID for feed item.',
-      ),
-      'fid' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {aggregator_feed}.fid to which this item belongs.',
-      ),
-      'title' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Title of the feed item.',
-      ),
-      'link' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Link to the feed item.',
-      ),
-      'author' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Author of the feed item.',
-      ),
-      'description' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-        'description' => 'Body of the feed item.',
-      ),
-      'timestamp' => array(
-        'type' => 'int',
-        'not null' => FALSE,
-        'description' => 'Posted date of the feed item, as a Unix timestamp.',
-      ),
-      'guid' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-        'description' => 'Unique identifier for the feed item.',
-      )
-    ),
-    'primary key' => array('iid'),
-    'indexes' => array(
-      'fid' => array('fid'),
-    ),
-    'foreign keys' => array(
-      'aggregator_feed' => array(
-        'table' => 'aggregator_feed',
-        'columns' => array('fid' => 'fid'),
-      ),
-    ),
-  );
-
-  return $schema;
-}
diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module
deleted file mode 100644
index 1e1686a..0000000
--- a/modules/aggregator/aggregator.module
+++ /dev/null
@@ -1,763 +0,0 @@
-<?php
-
-/**
- * @file
- * Used to aggregate syndicated content (RSS, RDF, and Atom).
- */
-
-/**
- * Denotes that a feed's items should never expire.
- */
-define('AGGREGATOR_CLEAR_NEVER', 0);
-
-/**
- * Implements hook_help().
- */
-function aggregator_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#aggregator':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Aggregator module is an on-site syndicator and news reader that gathers and displays fresh content from RSS-, RDF-, and Atom-based feeds made available across the web. Thousands of sites (particularly news sites and blogs) publish their latest headlines in feeds, using a number of standardized XML-based formats. For more information, see the online handbook entry for <a href="@aggregator-module">Aggregator module</a>.', array('@aggregator-module' => 'http://drupal.org/handbook/modules/aggregator', '@aggregator' => url('aggregator'))) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Viewing feeds') . '</dt>';
-      $output .= '<dd>' . t('Feeds contain published content, and may be grouped in categories, generally by topic. Users view feed content in the <a href="@aggregator">main aggregator display</a>, or by <a href="@aggregator-sources">their source</a> (usually via an RSS feed reader). The most recent content in a feed or category can be displayed as a block through the <a href="@admin-block">Blocks administration page</a>.', array('@aggregator' => url('aggregator'), '@aggregator-sources' => url('aggregator/sources'), '@admin-block' => url('admin/structure/block'))) . '</a></dd>';
-      $output .= '<dt>' . t('Adding, editing, and deleting feeds') . '</dt>';
-      $output .= '<dd>' . t('Administrators can add, edit, and delete feeds, and choose how often to check each feed for newly updated items on the <a href="@feededit">Feed aggregator administration page</a>.', array('@feededit' => url('admin/config/services/aggregator'))) . '</dd>';
-      $output .= '<dt>' . t('OPML integration') . '</dt>';
-      $output .= '<dd>' . t('A <a href="@aggregator-opml">machine-readable OPML file</a> of all feeds is available. OPML is an XML-based file format used to share outline-structured information such as a list of RSS feeds. Feeds can also be <a href="@import-opml">imported via an OPML file</a>.', array('@aggregator-opml' => url('aggregator/opml'), '@import-opml' => url('admin/config/services/aggregator'))) . '</dd>';
-      $output .= '<dt>' . t('Configuring cron') . '</dt>';
-      $output .= '<dd>' . t('A correctly configured <a href="@cron">cron maintenance task</a> is required to update feeds automatically.', array('@cron' => 'http://drupal.org/cron')) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-    case 'admin/config/services/aggregator':
-      $output = '<p>' . t('Thousands of sites (particularly news sites and blogs) publish their latest headlines and posts in feeds, using a number of standardized XML-based formats. Formats supported by the aggregator include <a href="@rss">RSS</a>, <a href="@rdf">RDF</a>, and <a href="@atom">Atom</a>.', array('@rss' => 'http://cyber.law.harvard.edu/rss/', '@rdf' => 'http://www.w3.org/RDF/', '@atom' => 'http://www.atomenabled.org')) . '</p>';
-      $output .= '<p>' . t('Current feeds are listed below, and <a href="@addfeed">new feeds may be added</a>. For each feed or feed category, the <em>latest items</em> block may be enabled at the <a href="@block">blocks administration page</a>.', array('@addfeed' => url('admin/config/services/aggregator/add/feed'), '@block' => url('admin/structure/block'))) . '</p>';
-      return $output;
-    case 'admin/config/services/aggregator/add/feed':
-      return '<p>' . t('Add a feed in RSS, RDF or Atom format. A feed may only have one entry.') . '</p>';
-    case 'admin/config/services/aggregator/add/category':
-      return '<p>' . t('Categories allow feed items from different feeds to be grouped together. For example, several sport-related feeds may belong to a category named <em>Sports</em>. Feed items may be grouped automatically (by selecting a category when creating or editing a feed) or manually (via the <em>Categorize</em> page available from feed item listings). Each category provides its own feed page and block.') . '</p>';
-    case 'admin/config/services/aggregator/add/opml':
-      return '<p>' . t('<acronym title="Outline Processor Markup Language">OPML</acronym> is an XML format used to exchange multiple feeds between aggregators. A single OPML document may contain a collection of many feeds. Drupal can parse such a file and import all feeds at once, saving you the effort of adding them manually. You may either upload a local file from your computer or enter a URL where Drupal can download it.') . '</p>';
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function aggregator_theme() {
-  return array(
-    'aggregator_wrapper' => array(
-      'variables' => array('content' => NULL),
-      'file' => 'aggregator.pages.inc',
-      'template' => 'aggregator-wrapper',
-    ),
-    'aggregator_categorize_items' => array(
-      'render element' => 'form',
-      'file' => 'aggregator.pages.inc',
-    ),
-    'aggregator_feed_source' => array(
-      'variables' => array('feed' => NULL),
-      'file' => 'aggregator.pages.inc',
-      'template' => 'aggregator-feed-source',
-    ),
-    'aggregator_block_item' => array(
-      'variables' => array('item' => NULL, 'feed' => 0),
-    ),
-    'aggregator_summary_items' => array(
-      'variables' => array('summary_items' => NULL, 'source' => NULL),
-      'file' => 'aggregator.pages.inc',
-      'template' => 'aggregator-summary-items',
-    ),
-    'aggregator_summary_item' => array(
-      'variables' => array('item' => NULL),
-      'file' => 'aggregator.pages.inc',
-      'template' => 'aggregator-summary-item',
-    ),
-    'aggregator_item' => array(
-      'variables' => array('item' => NULL),
-      'file' => 'aggregator.pages.inc',
-      'template' => 'aggregator-item',
-    ),
-    'aggregator_page_opml' => array(
-      'variables' => array('feeds' => NULL),
-      'file' => 'aggregator.pages.inc',
-    ),
-    'aggregator_page_rss' => array(
-      'variables' => array('feeds' => NULL, 'category' => NULL),
-      'file' => 'aggregator.pages.inc',
-    ),
-  );
-}
-
-/**
- * Implements hook_menu().
- */
-function aggregator_menu() {
-  $items['admin/config/services/aggregator'] = array(
-    'title' => 'Feed aggregator',
-    'description' => "Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized.",
-    'page callback' => 'aggregator_admin_overview',
-    'access arguments' => array('administer news feeds'),
-    'weight' => 10,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/add/feed'] = array(
-    'title' => 'Add feed',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_feed'),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_ACTION,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/add/category'] = array(
-    'title' => 'Add category',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_category'),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_ACTION,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/add/opml'] = array(
-    'title' => 'Import OPML',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_opml'),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_ACTION,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/remove/%aggregator_feed'] = array(
-    'title' => 'Remove items',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_admin_remove_feed', 5),
-    'access arguments' => array('administer news feeds'),
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/update/%aggregator_feed'] = array(
-    'title' => 'Update items',
-    'page callback' => 'aggregator_admin_refresh_feed',
-    'page arguments' => array(5),
-    'access arguments' => array('administer news feeds'),
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/list'] = array(
-    'title' => 'List',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
-  $items['admin/config/services/aggregator/settings'] = array(
-    'title' => 'Settings',
-    'description' => 'Configure the behavior of the feed aggregator, including when to discard feed items and how to present feed items and categories.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_admin_form'),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['aggregator'] = array(
-    'title' => 'Feed aggregator',
-    'page callback' => 'aggregator_page_last',
-    'access arguments' => array('access news feeds'),
-    'weight' => 5,
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/sources'] = array(
-    'title' => 'Sources',
-    'page callback' => 'aggregator_page_sources',
-    'access arguments' => array('access news feeds'),
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/categories'] = array(
-    'title' => 'Categories',
-    'page callback' => 'aggregator_page_categories',
-    'access callback' => '_aggregator_has_categories',
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/rss'] = array(
-    'title' => 'RSS feed',
-    'page callback' => 'aggregator_page_rss',
-    'access arguments' => array('access news feeds'),
-    'type' => MENU_CALLBACK,
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/opml'] = array(
-    'title' => 'OPML feed',
-    'page callback' => 'aggregator_page_opml',
-    'access arguments' => array('access news feeds'),
-    'type' => MENU_CALLBACK,
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/categories/%aggregator_category'] = array(
-    'title callback' => '_aggregator_category_title',
-    'title arguments' => array(2),
-    'page callback' => 'aggregator_page_category',
-    'page arguments' => array(2),
-    'access arguments' => array('access news feeds'),
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/categories/%aggregator_category/view'] = array(
-    'title' => 'View',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
-  $items['aggregator/categories/%aggregator_category/categorize'] = array(
-    'title' => 'Categorize',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_page_category_form', 2),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/categories/%aggregator_category/configure'] = array(
-    'title' => 'Configure',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_category', 2),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 1,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['aggregator/sources/%aggregator_feed'] = array(
-    'page callback' => 'aggregator_page_source',
-    'page arguments' => array(2),
-    'access arguments' => array('access news feeds'),
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/sources/%aggregator_feed/view'] = array(
-    'title' => 'View',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
-  $items['aggregator/sources/%aggregator_feed/categorize'] = array(
-    'title' => 'Categorize',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_page_source_form', 2),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'aggregator.pages.inc',
-  );
-  $items['aggregator/sources/%aggregator_feed/configure'] = array(
-    'title' => 'Configure',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_feed', 2),
-    'access arguments' => array('administer news feeds'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 1,
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/edit/feed/%aggregator_feed'] = array(
-    'title' => 'Edit feed',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_feed', 6),
-    'access arguments' => array('administer news feeds'),
-    'file' => 'aggregator.admin.inc',
-  );
-  $items['admin/config/services/aggregator/edit/category/%aggregator_category'] = array(
-    'title' => 'Edit category',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('aggregator_form_category', 6),
-    'access arguments' => array('administer news feeds'),
-    'file' => 'aggregator.admin.inc',
-  );
-
-  return $items;
-}
-
-/**
- * Title callback for aggregatory category pages.
- *
- * @return
- *   An aggregator category title.
- */
-function _aggregator_category_title($category) {
-  return $category['title'];
-}
-
-/**
- * Find out whether there are any aggregator categories.
- *
- * @return
- *   TRUE if there is at least one category and the user has access to them, FALSE
- *   otherwise.
- */
-function _aggregator_has_categories() {
-  return user_access('access news feeds') && db_query('SELECT COUNT(*) FROM {aggregator_category}')->fetchField();
-}
-
-/**
- * Implements hook_permission().
- */
-function aggregator_permission() {
-  return array(
-    'administer news feeds' => array(
-      'title' => t('Administer news feeds'),
-    ),
-    'access news feeds' => array(
-      'title' => t('View news feeds'),
-    ),
-  );
-}
-
-/**
- * Implements hook_cron().
- *
- * Queues news feeds for updates once their refresh interval has elapsed.
- */
-function aggregator_cron() {
-  $result = db_query('SELECT * FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', array(
-    ':time' => REQUEST_TIME,
-    ':never' => AGGREGATOR_CLEAR_NEVER
-  ));
-  $queue = DrupalQueue::get('aggregator_feeds');
-  foreach ($result as $feed) {
-    if ($queue->createItem($feed)) {
-      // Add timestamp to avoid queueing item more than once.
-      db_update('aggregator_feed')
-        ->fields(array('queued' => REQUEST_TIME))
-        ->condition('fid', $feed->fid)
-        ->execute();
-    }
-  }
-
-  // Remove queued timestamp after 6 hours assuming the update has failed.
-  db_update('aggregator_feed')
-    ->fields(array('queued' => 0))
-    ->condition('queued', REQUEST_TIME - (3600 * 6), '<')
-    ->execute();
-}
-
-/**
- * Implements hook_cron_queue_info().
- */
-function aggregator_cron_queue_info() {
-  $queues['aggregator_feeds'] = array(
-    'worker callback' => 'aggregator_refresh',
-    'time' => 60,
-  );
-  return $queues;
-}
-
-/**
- * Implements hook_block_info().
- */
-function aggregator_block_info() {
-  $blocks = array();
-  $result = db_query('SELECT cid, title FROM {aggregator_category} ORDER BY title');
-  foreach ($result as $category) {
-    $blocks['category-' . $category->cid]['info'] = t('!title category latest items', array('!title' => $category->title));
-  }
-  $result = db_query('SELECT fid, title FROM {aggregator_feed} WHERE block <> 0 ORDER BY fid');
-  foreach ($result as $feed) {
-    $blocks['feed-' . $feed->fid]['info'] = t('!title feed latest items', array('!title' => $feed->title));
-  }
-  return $blocks;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function aggregator_block_configure($delta = '') {
-  list($type, $id) = explode('-', $delta);
-  if ($type == 'category') {
-    $value = db_query('SELECT block FROM {aggregator_category} WHERE cid = :cid', array(':cid' => $id))->fetchField();
-    $form['block'] = array(
-      '#type' => 'select',
-      '#title' => t('Number of news items in block'),
-      '#default_value' => $value,
-      '#options' => drupal_map_assoc(range(2, 20)),
-    );
-    return $form;
-  }
-}
-
-/**
- * Implements hook_block_save().
- */
-function aggregator_block_save($delta = '', $edit = array()) {
-  list($type, $id) = explode('-', $delta);
-  if ($type == 'category') {
-    db_update('aggregator_category')
-      ->fields(array('block' => $edit['block']))
-      ->condition('cid', $id)
-      ->execute();
-  }
-}
-
-/**
- * Implements hook_block_view().
- *
- * Generates blocks for the latest news items in each category and feed.
- */
-function aggregator_block_view($delta = '') {
-  if (user_access('access news feeds')) {
-    $block = array();
-    list($type, $id) = explode('-', $delta);
-    switch ($type) {
-      case 'feed':
-        if ($feed = db_query('SELECT fid, title, block FROM {aggregator_feed} WHERE block <> 0 AND fid = :fid', array(':fid' => $id))->fetchObject()) {
-          $block['subject'] = check_plain($feed->title);
-          $result = db_query_range("SELECT * FROM {aggregator_item} WHERE fid = :fid ORDER BY timestamp DESC, iid DESC", 0, $feed->block, array(':fid' => $id));
-          $read_more = theme('more_link', array('url' => 'aggregator/sources/' . $feed->fid, 'title' => t("View this feed's recent news.")));
-        }
-        break;
-
-      case 'category':
-        if ($category = db_query('SELECT cid, title, block FROM {aggregator_category} WHERE cid = :cid', array(':cid' => $id))->fetchObject()) {
-          $block['subject'] = check_plain($category->title);
-          $result = db_query_range('SELECT i.* FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON ci.iid = i.iid WHERE ci.cid = :cid ORDER BY i.timestamp DESC, i.iid DESC', 0, $category->block, array(':cid' => $category->cid));
-          $read_more = theme('more_link', array('url' => 'aggregator/categories/' . $category->cid, 'title' => t("View this category's recent news.")));
-        }
-        break;
-    }
-    $items = array();
-    foreach ($result as $item) {
-      $items[] = theme('aggregator_block_item', array('item' => $item));
-    }
-
-    // Only display the block if there are items to show.
-    if (count($items) > 0) {
-      $block['content'] = theme('item_list', array('items' => $items)) . $read_more;
-    }
-    return $block;
-  }
-}
-
-/**
- * Add/edit/delete aggregator categories.
- *
- * @param $edit
- *   An associative array describing the category to be added/edited/deleted.
- */
-function aggregator_save_category($edit) {
-  $link_path = 'aggregator/categories/';
-  if (!empty($edit['cid'])) {
-    $link_path .= $edit['cid'];
-    if (!empty($edit['title'])) {
-      db_merge('aggregator_category')
-        ->key(array('cid' => $edit['cid']))
-        ->fields(array(
-          'title' => $edit['title'],
-          'description' => $edit['description'],
-        ))
-        ->execute();
-      $op = 'update';
-    }
-    else {
-      db_delete('aggregator_category')
-        ->condition('cid', $edit['cid'])
-        ->execute();
-      // Make sure there is no active block for this category.
-      db_delete('block')
-        ->condition('module', 'aggregator')
-        ->condition('delta', 'category-' . $edit['cid'])
-        ->execute();
-      $edit['title'] = '';
-      $op = 'delete';
-    }
-  }
-  elseif (!empty($edit['title'])) {
-    // A single unique id for bundles and feeds, to use in blocks.
-    $link_path .= db_insert('aggregator_category')
-      ->fields(array(
-        'title' => $edit['title'],
-        'description' => $edit['description'],
-        'block' => 5,
-      ))
-      ->execute();
-    $op = 'insert';
-  }
-  if (isset($op)) {
-    menu_link_maintain('aggregator', $op, $link_path, $edit['title']);
-  }
-}
-
-/**
- * Add/edit/delete an aggregator feed.
- *
- * @param $edit
- *   An associative array describing the feed to be added/edited/deleted.
- */
-function aggregator_save_feed($edit) {
-  if (!empty($edit['fid'])) {
-    // An existing feed is being modified, delete the category listings.
-    db_delete('aggregator_category_feed')
-      ->condition('fid', $edit['fid'])
-      ->execute();
-  }
-  if (!empty($edit['fid']) && !empty($edit['title'])) {
-    db_update('aggregator_feed')
-      ->condition('fid', $edit['fid'])
-      ->fields(array(
-        'title' => $edit['title'],
-        'url' => $edit['url'],
-        'refresh' => $edit['refresh'],
-        'block' => $edit['block'],
-      ))
-      ->execute();
-  }
-  elseif (!empty($edit['fid'])) {
-    $iids = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $edit['fid']))->fetchCol();
-    if ($iids) {
-      db_delete('aggregator_category_item')
-        ->condition('iid', $iids, 'IN')
-        ->execute();
-    }
-    db_delete('aggregator_feed')->
-      condition('fid', $edit['fid'])
-      ->execute();
-    db_delete('aggregator_item')
-      ->condition('fid', $edit['fid'])
-      ->execute();
-    // Make sure there is no active block for this feed.
-    db_delete('block')
-      ->condition('module', 'aggregator')
-      ->condition('delta', 'feed-' . $edit['fid'])
-      ->execute();
-  }
-  elseif (!empty($edit['title'])) {
-    $edit['fid'] = db_insert('aggregator_feed')
-      ->fields(array(
-        'title' => $edit['title'],
-        'url' => $edit['url'],
-        'refresh' => $edit['refresh'],
-        'block' => $edit['block'],
-        'description' => '',
-        'image' => '',
-      ))
-      ->execute();
-
-  }
-  if (!empty($edit['title'])) {
-    // The feed is being saved, save the categories as well.
-    if (!empty($edit['category'])) {
-      foreach ($edit['category'] as $cid => $value) {
-        if ($value) {
-          db_insert('aggregator_category_feed')
-            ->fields(array(
-              'fid' => $edit['fid'],
-              'cid' => $cid,
-            ))
-            ->execute();
-        }
-      }
-    }
-  }
-}
-
-/**
- * Removes all items from a feed.
- *
- * @param $feed
- *   An object describing the feed to be cleared.
- */
-function aggregator_remove($feed) {
-  _aggregator_get_variables();
-  // Call hook_aggregator_remove() on all modules.
-  module_invoke_all('aggregator_remove', $feed);
-  // Reset feed.
-  db_merge('aggregator_feed')
-    ->key(array('fid' => $feed->fid))
-    ->fields(array(
-      'checked' => 0,
-      'hash' => '',
-      'etag' => '',
-      'modified' => 0,
-      'description' => $feed->description,
-      'image' => $feed->image,
-    ))
-    ->execute();
-}
-
-function _aggregator_get_variables() {
-  // Fetch the feed.
-  $fetcher = variable_get('aggregator_fetcher', 'aggregator');
-  if ($fetcher == 'aggregator') {
-    include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.fetcher.inc';
-  }
-  $parser = variable_get('aggregator_parser', 'aggregator');
-  if ($parser == 'aggregator') {
-    include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.parser.inc';
-  }
-  $processors = variable_get('aggregator_processors', array('aggregator'));
-  if (in_array('aggregator', $processors)) {
-    include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.processor.inc';
-  }
-  return array($fetcher, $parser, $processors);
-}
-
-/**
- * Checks a news feed for new items.
- *
- * @param $feed
- *   An object describing the feed to be refreshed.
- */
-function aggregator_refresh($feed) {
-  // Store feed URL to track changes.
-  $feed_url = $feed->url;
-
-  // Fetch the feed.
-  list($fetcher, $parser, $processors) = _aggregator_get_variables();
-  $success = module_invoke($fetcher, 'aggregator_fetch', $feed);
-
-  // We store the hash of feed data in the database. When refreshing a
-  // feed we compare stored hash and new hash calculated from downloaded
-  // data. If both are equal we say that feed is not updated.
-  $hash = hash('sha256', $feed->source_string);
-
-  if ($success && ($feed->hash != $hash)) {
-    // Parse the feed.
-    if (module_invoke($parser, 'aggregator_parse', $feed)) {
-      // Update feed with parsed data.
-      db_merge('aggregator_feed')
-        ->key(array('fid' => $feed->fid))
-        ->fields(array(
-          'url' => $feed->url,
-          'link' => empty($feed->link) ? $feed->url : $feed->link,
-          'description' => empty($feed->description) ? '' : $feed->description,
-          'image' => empty($feed->image) ? '' : $feed->image,
-          'hash' => $hash,
-          'etag' => empty($feed->etag) ? '' : $feed->etag,
-          'modified' => empty($feed->modified) ? 0 : $feed->modified,
-        ))
-        ->execute();
-
-      // Log if feed URL has changed.
-      if ($feed->url != $feed_url) {
-        watchdog('aggregator', 'Updated URL for feed %title to %url.', array('%title' => $feed->title, '%url' => $feed->url));
-      }
-
-      watchdog('aggregator', 'There is new syndicated content from %site.', array('%site' => $feed->title));
-      drupal_set_message(t('There is new syndicated content from %site.', array('%site' => $feed->title)));
-
-      // If there are items on the feed, let all enabled processors do their work on it.
-      if (@count($feed->items)) {
-        foreach ($processors as $processor) {
-          module_invoke($processor, 'aggregator_process', $feed);
-        }
-      }
-    }
-  }
-  else {
-    drupal_set_message(t('There is no new syndicated content from %site.', array('%site' => $feed->title)));
-  }
-
-  // Regardless of successful or not, indicate that this feed has been checked.
-  db_update('aggregator_feed')
-    ->fields(array('checked' => REQUEST_TIME, 'queued' => 0))
-    ->condition('fid', $feed->fid)
-    ->execute();
-
-  // Expire old feed items.
-  if (function_exists('aggregator_expire')) {
-    aggregator_expire($feed);
-  }
-}
-
-/**
- * Load an aggregator feed.
- *
- * @param $fid
- *   The feed id.
- * @return
- *   An object describing the feed.
- */
-function aggregator_feed_load($fid) {
-  $feeds = &drupal_static(__FUNCTION__);
-  if (!isset($feeds[$fid])) {
-    $feeds[$fid] = db_query('SELECT * FROM {aggregator_feed} WHERE fid = :fid', array(':fid' => $fid))->fetchObject();
-  }
-
-  return $feeds[$fid];
-}
-
-/**
- * Load an aggregator category.
- *
- * @param $cid
- *   The category id.
- * @return
- *   An associative array describing the category.
- */
-function aggregator_category_load($cid) {
-  $categories = &drupal_static(__FUNCTION__);
-  if (!isset($categories[$cid])) {
-    $categories[$cid] = db_query('SELECT * FROM {aggregator_category} WHERE cid = :cid', array(':cid' => $cid))->fetchAssoc();
-  }
-
-  return $categories[$cid];
-}
-
-/**
- * Returns HTML for an individual feed item for display in the block.
- *
- * @param $variables
- *   An associative array containing:
- *   - item: The item to be displayed.
- *   - feed: Not used.
- *
- * @ingroup themeable
- */
-function theme_aggregator_block_item($variables) {
-  // Display the external link to the item.
-  return '<a href="' . check_url($variables['item']->link) . '">' . check_plain($variables['item']->title) . "</a>\n";
-}
-
-/**
- * Safely render HTML content, as allowed.
- *
- * @param $value
- *   The content to be filtered.
- * @return
- *   The filtered content.
- */
-function aggregator_filter_xss($value) {
-  return filter_xss($value, preg_split('/\s+|<|>/', variable_get('aggregator_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'), -1, PREG_SPLIT_NO_EMPTY));
-}
-
-/**
- * Check and sanitize aggregator configuration.
- *
- * Goes through all fetchers, parsers and processors and checks whether they are
- * available.
- * If one is missing resets to standard configuration.
- *
- * @return
- *   TRUE if this function reset the configuration FALSE if not.
- */
-function aggregator_sanitize_configuration() {
-  $reset = FALSE;
-  list($fetcher, $parser, $processors) = _aggregator_get_variables();
-  if (!module_exists($fetcher)) {
-    $reset = TRUE;
-  }
-  if (!module_exists($parser)) {
-    $reset = TRUE;
-  }
-  foreach ($processors as $processor) {
-    if (!module_exists($processor)) {
-      $reset = TRUE;
-      break;
-    }
-  }
-  if ($reset) {
-    variable_del('aggregator_fetcher');
-    variable_del('aggregator_parser');
-    variable_del('aggregator_processors');
-    return TRUE;
-  }
-  return FALSE;
-}
-
-/**
- * Helper function for drupal_map_assoc.
- *
- * @param $count
- *   Items count.
- * @return
- *   Plural-formatted "@count items"
- */
-function _aggregator_items($count) {
-  return format_plural($count, '1 item', '@count items');
-}
diff --git a/modules/aggregator/aggregator.pages.inc b/modules/aggregator/aggregator.pages.inc
deleted file mode 100644
index 53ecb36..0000000
--- a/modules/aggregator/aggregator.pages.inc
+++ /dev/null
@@ -1,524 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the aggregator module.
- */
-
-/**
- * Menu callback; displays the most recent items gathered from any feed.
- *
- * @return
- *   The items HTML.
- */
-function aggregator_page_last() {
-  drupal_add_feed('aggregator/rss', variable_get('site_name', 'Drupal') . ' ' . t('aggregator'));
-
-  $items = aggregator_feed_items_load('sum');
-
-  return _aggregator_page_list($items, arg(1));
-}
-
-/**
- * Menu callback; displays all the items captured from a particular feed.
- *
- * @param $feed
- *   The feed for which to display all items.
- *
- * @return
- *   The rendered list of items for a feed.
- */
-function aggregator_page_source($feed) {
-  drupal_set_title($feed->title);
-  $feed_source = theme('aggregator_feed_source', array('feed' => $feed));
-
-  // It is safe to include the fid in the query because it's loaded from the
-  // database by aggregator_feed_load.
-  $items = aggregator_feed_items_load('source', $feed);
-
-  return _aggregator_page_list($items, arg(3), $feed_source);
-}
-
-/**
- * Menu callback; displays a form with all items captured from a feed.
- *
- * @param $feed
- *   The feed for which to list all the aggregated items.
- *
- * @return
- *   The rendered list of items for a feed.
- *
- * @see aggregator_page_source()
- */
-function aggregator_page_source_form($form, $form_state, $feed) {
-  return aggregator_page_source($feed);
-}
-
-/**
- * Menu callback; displays all the items aggregated in a particular category.
- *
- * @param $category
- *   The category for which to list all the aggregated items.
- *
- * @return
-*   The rendered list of items for a category.
- */
-function aggregator_page_category($category) {
-  drupal_add_feed('aggregator/rss/' . $category['cid'], variable_get('site_name', 'Drupal') . ' ' . t('aggregator - @title', array('@title' => $category['title'])));
-
-  // It is safe to include the cid in the query because it's loaded from the
-  // database by aggregator_category_load.
-  $items = aggregator_feed_items_load('category', $category);
-
-  return _aggregator_page_list($items, arg(3));
-}
-
-/**
- * Menu callback; displays a form containing items aggregated in a category.
- *
- * @param $category
- *   The category for which to list all the aggregated items.
- *
- * @return
-*   The rendered list of items for a category.
- *
- * @see aggregator_page_category()
- */
-function aggregator_page_category_form($form, $form_state, $category) {
-  return aggregator_page_category($category);
-}
-
-/**
- * Load feed items
- *
- * @param $type
- *   The filter for the items. Possible values: 'sum', 'source', 'category'
- * @param $data
- *   Feed or category data for filtering
- * @return
- *   An array of the feed items.
- */
-function aggregator_feed_items_load($type, $data = NULL) {
-  $items = array();
-  $range_limit = 20;
-  switch ($type) {
-    case 'sum':
-      $result = db_query_range('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.fid = f.fid ORDER BY i.timestamp DESC, i.iid DESC', 0, $range_limit);
-      break;
-    case 'source':
-      $result = db_query_range('SELECT * FROM {aggregator_item} WHERE fid = :fid ORDER BY timestamp DESC, iid DESC', 0, $range_limit, array(':fid' => $data->fid));
-      break;
-    case 'category':
-      $result = db_query_range('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = :cid ORDER BY timestamp DESC, i.iid DESC', 0, $range_limit, array(':cid' => $data['cid']));
-      break;
-  }
-
-  foreach ($result as $item) {
-    $item->categories = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = :iid ORDER BY c.title', array(':iid' => $item->iid))->fetchAll();
-    $items[] = $item;
-  }
-
-  return $items;
-}
-
-/**
- * Prints an aggregator page listing a number of feed items.
- *
- * Various menu callbacks use this function to print their feeds.
- *
- * @param $items
- *   The items to be listed.
- * @param $op
- *   Which form should be added to the items. Only 'categorize' is now recognized.
- * @param $feed_source
- *   The feed source URL.
- * @return
- *   The items HTML.
- */
-function _aggregator_page_list($items, $op, $feed_source = '') {
-  if (user_access('administer news feeds') && ($op == 'categorize')) {
-    // Get form data.
-    $output = aggregator_categorize_items($items, $feed_source);
-  }
-  else {
-    // Assemble themed output.
-    $output = $feed_source;
-    foreach ($items as $item) {
-      $output .= theme('aggregator_item', array('item' => $item));
-    }
-    $output = theme('aggregator_wrapper', array('content' => $output));
-  }
-
-  return $output;
-}
-
-/**
- * Form builder; build the page list form.
- *
- * @param $items
- *   An array of the feed items.
- * @param $feed_source
- *   The feed source URL.
- * @return
- *   The form structure.
- * @ingroup forms
- * @see aggregator_categorize_items_submit()
- */
-function aggregator_categorize_items($items, $feed_source = '') {
-  $form['#submit'][] = 'aggregator_categorize_items_submit';
-  $form['#theme'] = 'aggregator_categorize_items';
-  $form['feed_source'] = array(
-    '#value' => $feed_source,
-  );
-  $categories = array();
-  $done = FALSE;
-  $form['items'] = array();
-  $form['categories'] = array(
-    '#tree' => TRUE,
-  );
-  foreach ($items as $item) {
-    $form['items'][$item->iid] = array('#markup' => theme('aggregator_item', array('item' => $item)));
-    $form['categories'][$item->iid] = array();
-    $categories_result = db_query('SELECT c.cid, c.title, ci.iid FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid AND ci.iid = :iid', array(':iid' => $item->iid));
-    $selected = array();
-    foreach ($categories_result as $category) {
-      if (!$done) {
-        $categories[$category->cid] = check_plain($category->title);
-      }
-      if ($category->iid) {
-        $selected[] = $category->cid;
-      }
-    }
-    $done = TRUE;
-    $form['categories'][$item->iid] = array(
-      '#type' => variable_get('aggregator_category_selector', 'checkboxes'),
-      '#default_value' => $selected,
-      '#options' => $categories,
-      '#size' => 10,
-      '#multiple' => TRUE
-    );
-  }
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save categories'));
-
-  return $form;
-}
-
-/**
- * Process aggregator_categorize_items() form submissions.
- */
-function aggregator_categorize_items_submit($form, &$form_state) {
-  if (!empty($form_state['values']['categories'])) {
-    foreach ($form_state['values']['categories'] as $iid => $selection) {
-      db_delete('aggregator_category_item')
-        ->condition('iid', $iid)
-        ->execute();
-      $insert = db_insert('aggregator_category_item')->fields(array('iid', 'cid'));
-      $has_values = FALSE;
-      foreach ($selection as $cid) {
-        if ($cid && $iid) {
-          $has_values = TRUE;
-          $insert->values(array(
-            'iid' => $iid,
-            'cid' => $cid,
-          ));
-        }
-      }
-      if ($has_values) {
-        $insert->execute();
-      }
-    }
-  }
-  drupal_set_message(t('The categories have been saved.'));
-}
-
-/**
- * Returns HTML for the aggregator page list form for assigning categories.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_aggregator_categorize_items($variables) {
-  $form = $variables['form'];
-
-  $output = drupal_render($form['feed_source']);
-  $rows = array();
-  if (!empty($form['items'])) {
-    foreach (element_children($form['items']) as $key) {
-      $rows[] = array(
-        drupal_render($form['items'][$key]),
-        array('data' => drupal_render($form['categories'][$key]), 'class' => array('categorize-item')),
-      );
-    }
-  }
-  $output .= theme('table', array('header' => array('', t('Categorize')), 'rows' => $rows));
-  $output .= drupal_render($form['submit']);
-  $output .= drupal_render_children($form);
-
-  return theme('aggregator_wrapper', array('content' => $output));
-}
-
-/**
- * Process variables for aggregator-wrapper.tpl.php.
- *
- * @see aggregator-wrapper.tpl.php
- */
-function template_preprocess_aggregator_wrapper(&$variables) {
-  $variables['pager'] = theme('pager');
-}
-
-/**
- * Process variables for aggregator-item.tpl.php.
- *
- * @see aggregator-item.tpl.php
- */
-function template_preprocess_aggregator_item(&$variables) {
-  $item = $variables['item'];
-
-  $variables['feed_url'] = check_url($item->link);
-  $variables['feed_title'] = check_plain($item->title);
-  $variables['content'] = aggregator_filter_xss($item->description);
-
-  $variables['source_url'] = '';
-  $variables['source_title'] = '';
-  if (isset($item->ftitle) && isset($item->fid)) {
-    $variables['source_url'] = url("aggregator/sources/$item->fid");
-    $variables['source_title'] = check_plain($item->ftitle);
-  }
-  if (date('Ymd', $item->timestamp) == date('Ymd')) {
-    $variables['source_date'] = t('%ago ago', array('%ago' => format_interval(REQUEST_TIME - $item->timestamp)));
-  }
-  else {
-    $variables['source_date'] = format_date($item->timestamp, 'custom', variable_get('date_format_medium', 'D, m/d/Y - H:i'));
-  }
-
-  $variables['categories'] = array();
-  foreach ($item->categories as $category) {
-    $variables['categories'][$category->cid] = l($category->title, 'aggregator/categories/' . $category->cid);
-  }
-}
-
-/**
- * Menu callback; displays all the feeds used by the aggregator.
- */
-function aggregator_page_sources() {
-  $result = db_query('SELECT f.fid, f.title, f.description, f.image, MAX(i.timestamp) AS last FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.description, f.image ORDER BY last DESC, f.title');
-
-  $output = '';
-  foreach ($result as $feed) {
-    // Most recent items:
-    $summary_items = array();
-    if (variable_get('aggregator_summary_items', 3)) {
-      $items = db_query_range('SELECT i.title, i.timestamp, i.link FROM {aggregator_item} i WHERE i.fid = :fid ORDER BY i.timestamp DESC', 0, variable_get('aggregator_summary_items', 3), array(':fid' => $feed->fid));
-      foreach ($items as $item) {
-        $summary_items[] = theme('aggregator_summary_item', array('item' => $item));
-      }
-    }
-    $feed->url = url('aggregator/sources/' . $feed->fid);
-    $output .= theme('aggregator_summary_items', array('summary_items' => $summary_items, 'source' => $feed));
-  }
-  $output .= theme('feed_icon', array('url' => 'aggregator/opml', 'title' => t('OPML feed')));
-
-  return theme('aggregator_wrapper', array('content' => $output));
-}
-
-/**
- * Menu callback; displays all the categories used by the aggregator.
- */
-function aggregator_page_categories() {
-  $result = db_query('SELECT c.cid, c.title, c.description FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid LEFT JOIN {aggregator_item} i ON ci.iid = i.iid GROUP BY c.cid, c.title, c.description');
-
-  $output = '';
-  foreach ($result as $category) {
-    if (variable_get('aggregator_summary_items', 3)) {
-      $summary_items = array();
-      $items = db_query_range('SELECT i.title, i.timestamp, i.link, f.title as feed_title, f.link as feed_link FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON i.iid = ci.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE ci.cid = :cid ORDER BY i.timestamp DESC', 0, variable_get('aggregator_summary_items', 3), array(':cid' => $category->cid));
-      foreach ($items as $item) {
-        $summary_items[] = theme('aggregator_summary_item', array('item' => $item));
-      }
-    }
-    $category->url = url('aggregator/categories/' . $category->cid);
-    $output .= theme('aggregator_summary_items', array('summary_items' => $summary_items, 'source' => $category));
-  }
-
-  return theme('aggregator_wrapper', array('content' => $output));
-}
-
-/**
- * Menu callback; generate an RSS 0.92 feed of aggregator items or categories.
- */
-function aggregator_page_rss() {
-  $result = NULL;
-  // arg(2) is the passed cid, only select for that category.
-  if (arg(2)) {
-    $category = db_query('SELECT cid, title FROM {aggregator_category} WHERE cid = :cid', array(':cid' => arg(2)))->fetchObject();
-    $result = db_query_range('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = :cid ORDER BY timestamp DESC, i.iid DESC', 0, variable_get('feed_default_items', 10), array(':cid' => $category->cid));
-  }
-  // Or, get the default aggregator items.
-  else {
-    $category = NULL;
-    $result = db_query_range('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.fid = f.fid ORDER BY i.timestamp DESC, i.iid DESC', 0, variable_get('feed_default_items', 10));
-  }
-
-  $feeds = $result->fetchAll();
-  return theme('aggregator_page_rss', array('feeds' => $feeds, 'category' => $category));
-}
-
-/**
- * Prints the RSS page for a feed.
- *
- * @param $variables
- *   An associative array containing:
- *   - feeds: An array of the feeds to theme.
- *   - category: A common category, if any, for all the feeds.
- *
- * @return void
- *
- * @ingroup themeable
- */
-function theme_aggregator_page_rss($variables) {
-  $feeds = $variables['feeds'];
-  $category = $variables['category'];
-
-  drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
-
-  $items = '';
-  $feed_length = variable_get('feed_item_length', 'fulltext');
-  foreach ($feeds as $feed) {
-    switch ($feed_length) {
-      case 'teaser':
-        $summary = text_summary($feed->description, NULL, variable_get('aggregator_teaser_length', 600));
-        if ($summary != $feed->description) {
-          $summary .= '<p><a href="' . check_url($feed->link) . '">' . t('read more') . "</a></p>\n";
-        }
-        $feed->description = $summary;
-        break;
-      case 'title':
-        $feed->description = '';
-        break;
-    }
-    $items .= format_rss_item($feed->ftitle . ': ' . $feed->title, $feed->link, $feed->description, array('pubDate' => date('r', $feed->timestamp)));
-  }
-
-  $site_name = variable_get('site_name', 'Drupal');
-  $url = url((isset($category) ? 'aggregator/categories/' . $category->cid : 'aggregator'), array('absolute' => TRUE));
-  $description = isset($category) ? t('@site_name - aggregated feeds in category @title', array('@site_name' => $site_name, '@title' => $category->title)) : t('@site_name - aggregated feeds', array('@site_name' => $site_name));
-
-  $output  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
-  $output .= "<rss version=\"2.0\">\n";
-  $output .= format_rss_channel(t('@site_name aggregator', array('@site_name' => $site_name)), $url, $description, $items);
-  $output .= "</rss>\n";
-
-  print $output;
-}
-
-/**
- * Menu callback; generates an OPML representation of all feeds.
- *
- * @param $cid
- *   If set, feeds are exported only from a category with this ID. Otherwise, all feeds are exported.
- * @return
- *   The output XML.
- */
-function aggregator_page_opml($cid = NULL) {
-  if ($cid) {
-    $result = db_query('SELECT f.title, f.url FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} c on f.fid = c.fid WHERE c.cid = :cid ORDER BY title', array(':cid' => $cid));
-  }
-  else {
-    $result = db_query('SELECT * FROM {aggregator_feed} ORDER BY title');
-  }
-
-  $feeds = $result->fetchAll();
-  return theme('aggregator_page_opml', array('feeds' => $feeds));
-}
-
-/**
- * Prints the OPML page for a feed.
- *
- * @param $variables
- *   An associative array containing:
- *   - feeds: An array of the feeds to theme.
- *
- * @return void
- *
- * @ingroup themeable
- */
-function theme_aggregator_page_opml($variables) {
-  $feeds = $variables['feeds'];
-
-  drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8');
-
-  $output  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
-  $output .= "<opml version=\"1.1\">\n";
-  $output .= "<head>\n";
-  $output .= '<title>' . check_plain(variable_get('site_name', 'Drupal')) . "</title>\n";
-  $output .= '<dateModified>' . gmdate(DATE_RFC2822, REQUEST_TIME) . "</dateModified>\n";
-  $output .= "</head>\n";
-  $output .= "<body>\n";
-  foreach ($feeds as $feed) {
-    $output .= '<outline text="' . check_plain($feed->title) . '" xmlUrl="' . check_url($feed->url) . "\" />\n";
-  }
-  $output .= "</body>\n";
-  $output .= "</opml>\n";
-
-  print $output;
-}
-
-/**
- * Process variables for aggregator-summary-items.tpl.php.
- *
- * @see aggregator-summary-items.tpl.php
- */
-function template_preprocess_aggregator_summary_items(&$variables) {
-  $variables['title'] = check_plain($variables['source']->title);
-  $variables['summary_list'] = theme('item_list', array('items' => $variables['summary_items']));
-  $variables['source_url'] = $variables['source']->url;
-}
-
-/**
- * Process variables for aggregator-summary-item.tpl.php.
- *
- * @see aggregator-summary-item.tpl.php
- */
-function template_preprocess_aggregator_summary_item(&$variables) {
-  $item = $variables['item'];
-
-  $variables['feed_url'] = check_url($item->link);
-  $variables['feed_title'] = check_plain($item->title);
-  $variables['feed_age'] = t('%age old', array('%age' => format_interval(REQUEST_TIME - $item->timestamp)));
-
-  $variables['source_url'] = '';
-  $variables['source_title'] = '';
-  if (!empty($item->feed_link)) {
-    $variables['source_url'] = check_url($item->feed_link);
-    $variables['source_title'] = check_plain($item->feed_title);
-  }
-}
-
-/**
- * Process variables for aggregator-feed-source.tpl.php.
- *
- * @see aggregator-feed-source.tpl.php
- */
-function template_preprocess_aggregator_feed_source(&$variables) {
-  $feed = $variables['feed'];
-
-  $variables['source_icon'] = theme('feed_icon', array('url' => $feed->url, 'title' => t('!title feed', array('!title' => $feed->title))));
-  $variables['source_image'] = $feed->image;
-  $variables['source_description'] = aggregator_filter_xss($feed->description);
-  $variables['source_url'] = check_url(url($feed->link, array('absolute' => TRUE)));
-
-  if ($feed->checked) {
-    $variables['last_checked'] = t('@time ago', array('@time' => format_interval(REQUEST_TIME - $feed->checked)));
-  }
-  else {
-    $variables['last_checked'] = t('never');
-  }
-
-  if (user_access('administer news feeds')) {
-    $variables['last_checked'] = l($variables['last_checked'], 'admin/config/services/aggregator');
-  }
-}
diff --git a/modules/aggregator/aggregator.parser.inc b/modules/aggregator/aggregator.parser.inc
deleted file mode 100644
index cffd1c3..0000000
--- a/modules/aggregator/aggregator.parser.inc
+++ /dev/null
@@ -1,328 +0,0 @@
-<?php
-
-/**
- * @file
- * Parser functions for the aggregator module.
- */
-
-/**
- * Implements hook_aggregator_parse_info().
- */
-function aggregator_aggregator_parse_info() {
-  return array(
-    'title' => t('Default parser'),
-    'description' => t('Parses RSS, Atom and RDF feeds.'),
-  );
-}
-
-/**
- * Implements hook_aggregator_parse().
- */
-function aggregator_aggregator_parse($feed) {
-  global $channel, $image;
-
-  // Filter the input data.
-  if (aggregator_parse_feed($feed->source_string, $feed)) {
-    $modified = empty($feed->http_headers['last-modified']) ? 0 : strtotime($feed->http_headers['last-modified']);
-
-    // Prepare the channel data.
-    foreach ($channel as $key => $value) {
-      $channel[$key] = trim($value);
-    }
-
-    // Prepare the image data (if any).
-    foreach ($image as $key => $value) {
-      $image[$key] = trim($value);
-    }
-
-    if (!empty($image['link']) && !empty($image['url']) && !empty($image['title'])) {
-      $image = l(theme('image', array('path' => $image['url'], 'alt' => $image['title'])), $image['link'], array('html' => TRUE));
-    }
-    else {
-      $image = '';
-    }
-
-    $etag = empty($feed->http_headers['etag']) ? '' : $feed->http_headers['etag'];
-
-    // Add parsed data to the feed object.
-    $feed->link = !empty($channel['LINK']) ? $channel['LINK'] : '';
-    $feed->description = !empty($channel['DESCRIPTION']) ? $channel['DESCRIPTION'] : '';
-    $feed->image = $image;
-    $feed->etag = $etag;
-    $feed->modified = $modified;
-
-    // Clear the cache.
-    cache_clear_all();
-
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-/**
- * Parse a feed and store its items.
- *
- * @param $data
- *   The feed data.
- * @param $feed
- *   An object describing the feed to be parsed.
- * @return
- *   FALSE on error, TRUE otherwise.
- */
-function aggregator_parse_feed(&$data, $feed) {
-  global $items, $image, $channel;
-
-  // Unset the global variables before we use them.
-  unset($GLOBALS['element'], $GLOBALS['item'], $GLOBALS['tag']);
-  $items = array();
-  $image = array();
-  $channel = array();
-
-  // Parse the data.
-  $xml_parser = drupal_xml_parser_create($data);
-  xml_set_element_handler($xml_parser, 'aggregator_element_start', 'aggregator_element_end');
-  xml_set_character_data_handler($xml_parser, 'aggregator_element_data');
-
-  if (!xml_parse($xml_parser, $data, 1)) {
-    watchdog('aggregator', 'The feed from %site seems to be broken, due to an error "%error" on line %line.', array('%site' => $feed->title, '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser)), WATCHDOG_WARNING);
-    drupal_set_message(t('The feed from %site seems to be broken, because of error "%error" on line %line.', array('%site' => $feed->title, '%error' => xml_error_string(xml_get_error_code($xml_parser)), '%line' => xml_get_current_line_number($xml_parser))), 'error');
-    return FALSE;
-  }
-  xml_parser_free($xml_parser);
-
-  // We reverse the array such that we store the first item last, and the last
-  // item first. In the database, the newest item should be at the top.
-  $items = array_reverse($items);
-
-  // Initialize items array.
-  $feed->items = array();
-  foreach ($items as $item) {
-
-    // Prepare the item:
-    foreach ($item as $key => $value) {
-      $item[$key] = trim($value);
-    }
-
-    // Resolve the item's title. If no title is found, we use up to 40
-    // characters of the description ending at a word boundary, but not
-    // splitting potential entities.
-    if (!empty($item['title'])) {
-      $item['title'] = $item['title'];
-    }
-    elseif (!empty($item['description'])) {
-      $item['title'] = preg_replace('/^(.*)[^\w;&].*?$/', "\\1", truncate_utf8($item['description'], 40));
-    }
-    else {
-      $item['title'] = '';
-    }
-
-    // Resolve the items link.
-    if (!empty($item['link'])) {
-      $item['link'] = $item['link'];
-    }
-    else {
-      $item['link'] = $feed->link;
-    }
-
-    // Atom feeds have an ID tag instead of a GUID tag.
-    if (!isset($item['guid'])) {
-      $item['guid'] = isset($item['id']) ? $item['id'] : '';
-    }
-
-    // Atom feeds have a content and/or summary tag instead of a description tag.
-    if (!empty($item['content:encoded'])) {
-      $item['description'] = $item['content:encoded'];
-    }
-    elseif (!empty($item['summary'])) {
-      $item['description'] = $item['summary'];
-    }
-    elseif (!empty($item['content'])) {
-      $item['description'] = $item['content'];
-    }
-
-    // Try to resolve and parse the item's publication date.
-    $date = '';
-    foreach (array('pubdate', 'dc:date', 'dcterms:issued', 'dcterms:created', 'dcterms:modified', 'issued', 'created', 'modified', 'published', 'updated') as $key) {
-      if (!empty($item[$key])) {
-        $date = $item[$key];
-        break;
-      }
-    }
-
-    $item['timestamp'] = strtotime($date);
-
-    if ($item['timestamp'] === FALSE) {
-      $item['timestamp'] = aggregator_parse_w3cdtf($date); // Aggregator_parse_w3cdtf() returns FALSE on failure.
-    }
-
-    // Resolve dc:creator tag as the item author if author tag is not set.
-    if (empty($item['author']) && !empty($item['dc:creator'])) {
-      $item['author'] = $item['dc:creator'];
-    }
-
-    $item += array('author' => '', 'description' => '');
-
-    // Store on $feed object. This is where processors will look for parsed items.
-    $feed->items[] = $item;
-  }
-
-  return TRUE;
-}
-
-/**
- * Callback function used by the XML parser.
- */
-function aggregator_element_start($parser, $name, $attributes) {
-  global $item, $element, $tag, $items, $channel;
-
-  $name = strtolower($name);
-  switch ($name) {
-    case 'image':
-    case 'textinput':
-    case 'summary':
-    case 'tagline':
-    case 'subtitle':
-    case 'logo':
-    case 'info':
-      $element = $name;
-      break;
-    case 'id':
-    case 'content':
-      if ($element != 'item') {
-        $element = $name;
-      }
-    case 'link':
-      // According to RFC 4287, link elements in Atom feeds without a 'rel'
-      // attribute should be interpreted as though the relation type is
-      // "alternate".
-      if (!empty($attributes['HREF']) && (empty($attributes['REL']) || $attributes['REL'] == 'alternate')) {
-        if ($element == 'item') {
-          $items[$item]['link'] = $attributes['HREF'];
-        }
-        else {
-          $channel['link'] = $attributes['HREF'];
-        }
-      }
-      break;
-    case 'item':
-      $element = $name;
-      $item += 1;
-      break;
-    case 'entry':
-      $element = 'item';
-      $item += 1;
-      break;
-  }
-
-  $tag = $name;
-}
-
-/**
- * Call-back function used by the XML parser.
- */
-function aggregator_element_end($parser, $name) {
-  global $element;
-
-  switch ($name) {
-    case 'image':
-    case 'textinput':
-    case 'item':
-    case 'entry':
-    case 'info':
-      $element = '';
-      break;
-    case 'id':
-    case 'content':
-      if ($element == $name) {
-        $element = '';
-      }
-  }
-}
-
-/**
- * Callback function used by the XML parser.
- */
-function aggregator_element_data($parser, $data) {
-  global $channel, $element, $items, $item, $image, $tag;
-  $items += array($item => array());
-  switch ($element) {
-    case 'item':
-      $items[$item] += array($tag => '');
-      $items[$item][$tag] .= $data;
-      break;
-    case 'image':
-    case 'logo':
-      $image += array($tag => '');
-      $image[$tag] .= $data;
-      break;
-    case 'link':
-      if ($data) {
-        $items[$item] += array($tag => '');
-        $items[$item][$tag] .= $data;
-      }
-      break;
-    case 'content':
-      $items[$item] += array('content' => '');
-      $items[$item]['content'] .= $data;
-      break;
-    case 'summary':
-      $items[$item] += array('summary' => '');
-      $items[$item]['summary'] .= $data;
-      break;
-    case 'tagline':
-    case 'subtitle':
-      $channel += array('description' => '');
-      $channel['description'] .= $data;
-      break;
-    case 'info':
-    case 'id':
-    case 'textinput':
-      // The sub-element is not supported. However, we must recognize
-      // it or its contents will end up in the item array.
-      break;
-    default:
-      $channel += array($tag => '');
-      $channel[$tag] .= $data;
-  }
-}
-
-/**
- * Parse the W3C date/time format, a subset of ISO 8601.
- *
- * PHP date parsing functions do not handle this format.
- * See http://www.w3.org/TR/NOTE-datetime for more information.
- * Originally from MagpieRSS (http://magpierss.sourceforge.net/).
- *
- * @param $date_str
- *   A string with a potentially W3C DTF date.
- * @return
- *   A timestamp if parsed successfully or FALSE if not.
- */
-function aggregator_parse_w3cdtf($date_str) {
-  if (preg_match('/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/', $date_str, $match)) {
-    list($year, $month, $day, $hours, $minutes, $seconds) = array($match[1], $match[2], $match[3], $match[4], $match[5], $match[6]);
-    // Calculate the epoch for current date assuming GMT.
-    $epoch = gmmktime($hours, $minutes, $seconds, $month, $day, $year);
-    if ($match[10] != 'Z') { // Z is zulu time, aka GMT
-      list($tz_mod, $tz_hour, $tz_min) = array($match[8], $match[9], $match[10]);
-      // Zero out the variables.
-      if (!$tz_hour) {
-        $tz_hour = 0;
-      }
-      if (!$tz_min) {
-        $tz_min = 0;
-      }
-      $offset_secs = (($tz_hour * 60) + $tz_min) * 60;
-      // Is timezone ahead of GMT?  If yes, subtract offset.
-      if ($tz_mod == '+') {
-        $offset_secs *= -1;
-      }
-      $epoch += $offset_secs;
-    }
-    return $epoch;
-  }
-  else {
-    return FALSE;
-  }
-}
diff --git a/modules/aggregator/aggregator.processor.inc b/modules/aggregator/aggregator.processor.inc
deleted file mode 100644
index 6eb2c66..0000000
--- a/modules/aggregator/aggregator.processor.inc
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-
-/**
- * @file
- * Processor functions for the aggregator module.
- */
-
-/**
- * Implements hook_aggregator_process_info().
- */
-function aggregator_aggregator_process_info() {
-  return array(
-    'title' => t('Default processor'),
-    'description' => t('Creates lightweight records from feed items.'),
-  );
-}
-
-/**
- * Implements hook_aggregator_process().
- */
-function aggregator_aggregator_process($feed) {
-  if (is_object($feed)) {
-    if (is_array($feed->items)) {
-      foreach ($feed->items as $item) {
-        // Save this item. Try to avoid duplicate entries as much as possible. If
-        // we find a duplicate entry, we resolve it and pass along its ID is such
-        // that we can update it if needed.
-        if (!empty($item['guid'])) {
-          $entry = db_query("SELECT iid, timestamp FROM {aggregator_item} WHERE fid = :fid AND guid = :guid", array(':fid' => $feed->fid, ':guid' => $item['guid']))->fetchObject();
-        }
-        elseif ($item['link'] && $item['link'] != $feed->link && $item['link'] != $feed->url) {
-          $entry = db_query("SELECT iid, timestamp FROM {aggregator_item} WHERE fid = :fid AND link = :link", array(':fid' => $feed->fid, ':link' => $item['link']))->fetchObject();
-        }
-        else {
-          $entry = db_query("SELECT iid, timestamp FROM {aggregator_item} WHERE fid = :fid AND title = :title", array(':fid' => $feed->fid, ':title' => $item['title']))->fetchObject();
-        }
-        if (!$item['timestamp']) {
-          $item['timestamp'] = isset($entry->timestamp) ? $entry->timestamp : REQUEST_TIME;
-        }
-        aggregator_save_item(array('iid' => (isset($entry->iid) ? $entry->iid : ''), 'fid' => $feed->fid, 'timestamp' => $item['timestamp'], 'title' => $item['title'], 'link' => $item['link'], 'author' => $item['author'], 'description' => $item['description'], 'guid' => $item['guid']));
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_aggregator_remove().
- */
-function aggregator_aggregator_remove($feed) {
-  $iids = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchCol();
-  if ($iids) {
-    db_delete('aggregator_category_item')
-      ->condition('iid', $iids, 'IN')
-      ->execute();
-  }
-  db_delete('aggregator_item')
-    ->condition('fid', $feed->fid)
-    ->execute();
-
-  drupal_set_message(t('The news items from %site have been removed.', array('%site' => $feed->title)));
-}
-
-/**
- * Implements hook_form_aggregator_admin_form_alter().
- *
- * Form alter aggregator module's own form to keep processor functionality
- * separate from aggregator API functionality.
- */
-function aggregator_form_aggregator_admin_form_alter(&$form, $form_state) {
-  if (in_array('aggregator', variable_get('aggregator_processors', array('aggregator')))) {
-    $info = module_invoke('aggregator', 'aggregator_process', 'info');
-    $items = drupal_map_assoc(array(3, 5, 10, 15, 20, 25), '_aggregator_items');
-    $period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
-    $period[AGGREGATOR_CLEAR_NEVER] = t('Never');
-
-    // Only wrap into a collapsible fieldset if there is a basic configuration.
-    if (isset($form['basic_conf'])) {
-      $form['modules']['aggregator'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Default processor settings'),
-        '#description' => $info['description'],
-        '#collapsible' => TRUE,
-        '#collapsed' => !in_array('aggregator', variable_get('aggregator_processors', array('aggregator'))),
-      );
-    }
-    else {
-      $form['modules']['aggregator'] = array();
-    }
-
-    $form['modules']['aggregator']['aggregator_summary_items'] = array(
-      '#type' => 'select',
-      '#title' => t('Number of items shown in listing pages'),
-      '#default_value' => variable_get('aggregator_summary_items', 3),
-      '#empty_value' => 0,
-      '#options' => $items,
-    );
-
-    $form['modules']['aggregator']['aggregator_clear'] = array(
-      '#type' => 'select',
-      '#title' => t('Discard items older than'),
-      '#default_value' => variable_get('aggregator_clear', 9676800),
-      '#options' => $period,
-      '#description' => t('Requires a correctly configured <a href="@cron">cron maintenance task</a>.', array('@cron' => url('admin/reports/status'))),
-    );
-
-    $form['modules']['aggregator']['aggregator_category_selector'] = array(
-      '#type' => 'radios',
-      '#title' => t('Select categories using'),
-      '#default_value' => variable_get('aggregator_category_selector', 'checkboxes'),
-      '#options' => array('checkboxes' => t('checkboxes'),
-      'select' => t('multiple selector')),
-      '#description' => t('For a small number of categories, checkboxes are easier to use, while a multiple selector works well with large numbers of categories.'),
-    );
-    $form['modules']['aggregator']['aggregator_teaser_length'] = array(
-      '#type' => 'select',
-      '#title' => t('Length of trimmed description'),
-      '#default_value' => 600,
-      '#options' => drupal_map_assoc(array(0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000), '_aggregator_characters'),
-      '#description' => t("The maximum number of characters used in the trimmed version of content.")
-    );
-
-  }
-}
-
-/**
- * Helper function for teaser length choices.
- */
-function _aggregator_characters($length) {
-  return ($length == 0) ? t('Unlimited') : format_plural($length, '1 character', '@count characters');
-}
-
-/**
- * Add/edit/delete an aggregator item.
- *
- * @param $edit
- *   An associative array describing the item to be added/edited/deleted.
- */
-function aggregator_save_item($edit) {
-  if ($edit['title'] && empty($edit['iid'])) {
-    $edit['iid'] = db_insert('aggregator_item')
-      ->fields(array(
-        'title' => $edit['title'],
-        'link' => $edit['link'],
-        'author' => $edit['author'],
-        'description' => $edit['description'],
-        'guid' => $edit['guid'],
-        'timestamp' => $edit['timestamp'],
-        'fid' => $edit['fid'],
-      ))
-      ->execute();
-  }
-  if ($edit['iid'] && !$edit['title']) {
-    db_delete('aggregator_item')
-      ->condition('iid', $edit['iid'])
-      ->execute();
-    db_delete('aggregator_category_item')
-      ->condition('iid', $edit['iid'])
-      ->execute();
-  }
-  elseif ($edit['title'] && $edit['link']) {
-    // file the items in the categories indicated by the feed
-    $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $edit['fid']));
-    foreach ($result as $category) {
-      db_merge('aggregator_category_item')
-        ->key(array(
-          'iid' => $edit['iid'],
-          'cid' => $category->cid,
-        ))
-        ->execute();
-    }
-  }
-}
-
-/**
- * Expire feed items on $feed that are older than aggregator_clear.
- *
- * @param $feed
- *   Object describing feed.
- */
-function aggregator_expire($feed) {
-  $aggregator_clear = variable_get('aggregator_clear', 9676800);
-
-  if ($aggregator_clear != AGGREGATOR_CLEAR_NEVER) {
-    // Remove all items that are older than flush item timer.
-    $age = REQUEST_TIME - $aggregator_clear;
-    $iids = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid AND timestamp < :timestamp', array(
-      ':fid' => $feed->fid,
-      ':timestamp' => $age,
-    ))
-    ->fetchCol();
-    if ($iids) {
-      db_delete('aggregator_category_item')
-        ->condition('iid', $iids, 'IN')
-        ->execute();
-      db_delete('aggregator_item')
-        ->condition('iid', $iids, 'IN')
-        ->execute();
-    }
-  }
-}
diff --git a/modules/aggregator/aggregator.test b/modules/aggregator/aggregator.test
deleted file mode 100644
index 1ab12dc..0000000
--- a/modules/aggregator/aggregator.test
+++ /dev/null
@@ -1,859 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for aggregator.module.
- */
-
-class AggregatorTestCase extends DrupalWebTestCase {
-  function setUp() {
-    parent::setUp('aggregator', 'aggregator_test');
-    $web_user = $this->drupalCreateUser(array('administer news feeds', 'access news feeds', 'create article content'));
-    $this->drupalLogin($web_user);
-  }
-
-  /**
-   * Create an aggregator feed (simulate form submission on admin/config/services/aggregator/add/feed).
-   *
-   * @param $feed_url
-   *   If given, feed will be created with this URL, otherwise /rss.xml will be used.
-   * @return $feed
-   *   Full feed object if possible.
-   *
-   * @see getFeedEditArray()
-   */
-  function createFeed($feed_url = NULL) {
-    $edit = $this->getFeedEditArray($feed_url);
-    $this->drupalPost('admin/config/services/aggregator/add/feed', $edit, t('Save'));
-    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));
-
-    $feed = db_query("SELECT *  FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $edit['title'], ':url' => $edit['url']))->fetch();
-    $this->assertTrue(!empty($feed), t('The feed found in database.'));
-    return $feed;
-  }
-
-  /**
-   * Delete an aggregator feed.
-   *
-   * @param $feed
-   *   Feed object representing the feed.
-   */
-  function deleteFeed($feed) {
-    $this->drupalPost('admin/config/services/aggregator/edit/feed/' . $feed->fid, array(), t('Delete'));
-    $this->assertRaw(t('The feed %title has been deleted.', array('%title' => $feed->title)), t('Feed deleted successfully.'));
-  }
-
-  /**
-   * Return a randomly generated feed edit array.
-   *
-   * @param $feed_url
-   *   If given, feed will be created with this URL, otherwise /rss.xml will be used.
-   * @return
-   *   A feed array.
-   */
-  function getFeedEditArray($feed_url = NULL) {
-    $feed_name = $this->randomName(10);
-    if (!$feed_url) {
-      $feed_url = url('rss.xml', array(
-        'query' => array('feed' => $feed_name),
-        'absolute' => TRUE,
-      ));
-    }
-    $edit = array(
-      'title' => $feed_name,
-      'url' => $feed_url,
-      'refresh' => '900',
-    );
-    return $edit;
-  }
-
-  /**
-   * Return the count of the randomly created feed array.
-   *
-   * @return
-   *   Number of feed items on default feed created by createFeed().
-   */
-  function getDefaultFeedItemCount() {
-    // Our tests are based off of rss.xml, so let's find out how many elements should be related.
-    $feed_count = db_query_range('SELECT COUNT(*) FROM {node} n WHERE n.promote = 1 AND n.status = 1', 0, variable_get('feed_default_items', 10))->fetchField();
-    return $feed_count > 10 ? 10 : $feed_count;
-  }
-
-  /**
-   * Update feed items (simulate click to admin/config/services/aggregator/update/$fid).
-   *
-   * @param $feed
-   *   Feed object representing the feed.
-   * @param $expected_count
-   *   Expected number of feed items.
-   */
-  function updateFeedItems(&$feed, $expected_count) {
-    // First, let's ensure we can get to the rss xml.
-    $this->drupalGet($feed->url);
-    $this->assertResponse(200, t('!url is reachable.', array('!url' => $feed->url)));
-
-    // Refresh the feed (simulated link click).
-    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
-
-    // Ensure we have the right number of items.
-    $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid));
-    $items = array();
-    $feed->items = array();
-    foreach ($result as $item) {
-      $feed->items[] = $item->iid;
-    }
-    $feed->item_count = count($feed->items);
-    $this->assertEqual($expected_count, $feed->item_count, t('Total items in feed equal to the total items in database (!val1 != !val2)', array('!val1' => $expected_count, '!val2' => $feed->item_count)));
-  }
-
-  /**
-   * Confirm item removal from a feed.
-   *
-   * @param $feed
-   *   Feed object representing the feed.
-   */
-  function removeFeedItems($feed) {
-    $this->drupalPost('admin/config/services/aggregator/remove/' . $feed->fid, array(), t('Remove items'));
-    $this->assertRaw(t('The news items from %title have been removed.', array('%title' => $feed->title)), t('Feed items removed.'));
-  }
-
-  /**
-   * Add and remove feed items and ensure that the count is zero.
-   *
-   * @param $feed
-   *   Feed object representing the feed.
-   * @param $expected_count
-   *   Expected number of feed items.
-   */
-  function updateAndRemove($feed, $expected_count) {
-    $this->updateFeedItems($feed, $expected_count);
-    $count = db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
-    $this->assertTrue($count);
-    $this->removeFeedItems($feed);
-    $count = db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
-    $this->assertTrue($count == 0);
-  }
-
-  /**
-   * Pull feed categories from aggregator_category_feed table.
-   *
-   * @param $feed
-   *   Feed object representing the feed.
-   */
-  function getFeedCategories($feed) {
-    // add the categories to the feed so we can use them
-    $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $feed->fid));
-    foreach ($result as $category) {
-      $feed->categories[] = $category->cid;
-    }
-  }
-
-  /**
-   * Pull categories from aggregator_category table.
-   */
-  function getCategories() {
-    $categories = array();
-    $result = db_query('SELECT * FROM {aggregator_category}');
-    foreach ($result as $category) {
-      $categories[$category->cid] = $category;
-    }
-    return $categories;
-  }
-
-
-  /**
-   * Check if the feed name and url is unique.
-   *
-   * @param $feed_name
-   *   String containing the feed name to check.
-   * @param $feed_url
-   *   String containing the feed url to check.
-   * @return
-   *   TRUE if feed is unique.
-   */
-  function uniqueFeed($feed_name, $feed_url) {
-    $result = db_query("SELECT COUNT(*) FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed_name, ':url' => $feed_url))->fetchField();
-    return (1 == $result);
-  }
-
-  /**
-   * Create a valid OPML file from an array of feeds.
-   *
-   * @param $feeds
-   *   An array of feeds.
-   * @return
-   *   Path to valid OPML file.
-   */
-  function getValidOpml($feeds) {
-    // Properly escape URLs so that XML parsers don't choke on them.
-    foreach ($feeds as &$feed) {
-      $feed['url'] = htmlspecialchars($feed['url']);
-    }
-    /**
-     * Does not have an XML declaration, must pass the parser.
-     */
-    $opml = <<<EOF
-<opml version="1.0">
-  <head></head>
-  <body>
-    <!-- First feed to be imported. -->
-    <outline text="{$feeds[0]['title']}" xmlurl="{$feeds[0]['url']}" />
-
-    <!-- Second feed. Test string delimitation and attribute order. -->
-    <outline xmlurl='{$feeds[1]['url']}' text='{$feeds[1]['title']}'/>
-
-    <!-- Test for duplicate URL and title. -->
-    <outline xmlurl="{$feeds[0]['url']}" text="Duplicate URL"/>
-    <outline xmlurl="http://duplicate.title" text="{$feeds[1]['title']}"/>
-
-    <!-- Test that feeds are only added with required attributes. -->
-    <outline text="{$feeds[2]['title']}" />
-    <outline xmlurl="{$feeds[2]['url']}" />
-  </body>
-</opml>
-EOF;
-
-    $path = 'public://valid-opml.xml';
-    return file_unmanaged_save_data($opml, $path);
-  }
-
-  /**
-   * Create an invalid OPML file.
-   *
-   * @return
-   *   Path to invalid OPML file.
-   */
-  function getInvalidOpml() {
-    $opml = <<<EOF
-<opml>
-  <invalid>
-</opml>
-EOF;
-
-    $path = 'public://invalid-opml.xml';
-    return file_unmanaged_save_data($opml, $path);
-  }
-
-  /**
-   * Create a valid but empty OPML file.
-   *
-   * @return
-   *   Path to empty OPML file.
-   */
-  function getEmptyOpml() {
-    $opml = <<<EOF
-<?xml version="1.0" encoding="utf-8"?>
-<opml version="1.0">
-  <head></head>
-  <body>
-    <outline text="Sample text" />
-    <outline text="Sample text" url="Sample URL" />
-  </body>
-</opml>
-EOF;
-
-    $path = 'public://empty-opml.xml';
-    return file_unmanaged_save_data($opml, $path);
-  }
-
-  function getRSS091Sample() {
-    return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_rss091.xml';
-  }
-
-  function getAtomSample() {
-    // The content of this sample ATOM feed is based directly off of the
-    // example provided in RFC 4287.
-    return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_atom.xml';
-  }
-
-  function createSampleNodes() {
-    $langcode = LANGUAGE_NONE;
-    // Post 5 articles.
-    for ($i = 0; $i < 5; $i++) {
-      $edit = array();
-      $edit['title'] = $this->randomName();
-      $edit["body[$langcode][0][value]"] = $this->randomName();
-      $this->drupalPost('node/add/article', $edit, t('Save'));
-    }
-  }
-}
-
-class AddFeedTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Add feed functionality',
-      'description' => 'Add feed test.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Create a feed, ensure that it is unique, check the source, and delete the feed.
-   */
-  function testAddFeed() {
-    $feed = $this->createFeed();
-
-    // Check feed data.
-    $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/add/feed', array('absolute' => TRUE)), t('Directed to correct url.'));
-    $this->assertTrue($this->uniqueFeed($feed->title, $feed->url), t('The feed is unique.'));
-
-    // Check feed source.
-    $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(200, t('Feed source exists.'));
-    $this->assertText($feed->title, t('Page title'));
-    $this->drupalGet('aggregator/sources/' . $feed->fid . '/categorize');
-    $this->assertResponse(200, t('Feed categorization page exists.'));
-
-    // Delete feed.
-    $this->deleteFeed($feed);
-  }
-}
-
-class CategorizeFeedTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Categorize feed functionality',
-      'description' => 'Categorize feed test.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Create a feed and make sure you can add more than one category to it.
-   */
-  function testCategorizeFeed() {
-
-    // Create 2 categories.
-    $category_1 = array('title' => $this->randomName(10), 'description' => '');
-    $this->drupalPost('admin/config/services/aggregator/add/category', $category_1, t('Save'));
-    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_1['title'])), t('The category %title has been added.', array('%title' => $category_1['title'])));
-
-    $category_2 = array('title' => $this->randomName(10), 'description' => '');
-    $this->drupalPost('admin/config/services/aggregator/add/category', $category_2, t('Save'));
-    $this->assertRaw(t('The category %title has been added.', array('%title' => $category_2['title'])), t('The category %title has been added.', array('%title' => $category_2['title'])));
-
-    // Get categories from database.
-    $categories = $this->getCategories();
-
-    // Create a feed and assign 2 categories to it.
-    $feed = $this->getFeedEditArray();
-    $feed['block'] = 5;
-    foreach ($categories as $cid => $category) {
-      $feed['category'][$cid] = $cid;
-    }
-
-    // Use aggregator_save_feed() function to save the feed.
-    aggregator_save_feed($feed);
-    $db_feed = db_query("SELECT *  FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed['title'], ':url' => $feed['url']))->fetch();
-
-    // Assert the feed has two categories.
-    $this->getFeedCategories($db_feed);
-    $this->assertEqual(count($db_feed->categories), 2, t('Feed has 2 categories'));
-  }
-}
-
-class UpdateFeedTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Update feed functionality',
-      'description' => 'Update feed test.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Create a feed and attempt to update it.
-   */
-  function testUpdateFeed() {
-    $remamining_fields = array('title', 'url', '');
-    foreach ($remamining_fields as $same_field) {
-      $feed = $this->createFeed();
-
-      // Get new feed data array and modify newly created feed.
-      $edit = $this->getFeedEditArray();
-      $edit['refresh'] =  1800; // Change refresh value.
-      if (isset($feed->{$same_field})) {
-        $edit[$same_field] = $feed->{$same_field};
-      }
-      $this->drupalPost('admin/config/services/aggregator/edit/feed/' . $feed->fid, $edit, t('Save'));
-      $this->assertRaw(t('The feed %name has been updated.', array('%name' => $edit['title'])), t('The feed %name has been updated.', array('%name' => $edit['title'])));
-
-      // Check feed data.
-      $this->assertEqual($this->getUrl(), url('admin/config/services/aggregator/', array('absolute' => TRUE)));
-      $this->assertTrue($this->uniqueFeed($edit['title'], $edit['url']), t('The feed is unique.'));
-
-      // Check feed source.
-      $this->drupalGet('aggregator/sources/' . $feed->fid);
-      $this->assertResponse(200, t('Feed source exists.'));
-      $this->assertText($edit['title'], t('Page title'));
-
-      // Delete feed.
-      $feed->title = $edit['title']; // Set correct title so deleteFeed() will work.
-      $this->deleteFeed($feed);
-    }
-  }
-}
-
-class RemoveFeedTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Remove feed functionality',
-      'description' => 'Remove feed test.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Remove a feed and ensure that all it services are removed.
-   */
-  function testRemoveFeed() {
-    $feed = $this->createFeed();
-
-    // Delete feed.
-    $this->deleteFeed($feed);
-
-    // Check feed source.
-    $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(404, t('Deleted feed source does not exists.'));
-
-    // Check database for feed.
-    $result = db_query("SELECT COUNT(*) FROM {aggregator_feed} WHERE title = :title AND url = :url", array(':title' => $feed->title, ':url' => $feed->url))->fetchField();
-    $this->assertFalse($result, t('Feed not found in database'));
-  }
-}
-
-class UpdateFeedItemTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Update feed item functionality',
-      'description' => 'Update feed items from a feed.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Test running "update items" from the 'admin/config/services/aggregator' page.
-   */
-  function testUpdateFeedItem() {
-    $this->createSampleNodes();
-
-    // Create a feed and test updating feed items if possible.
-    $feed = $this->createFeed();
-    if (!empty($feed)) {
-      $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
-      $this->removeFeedItems($feed);
-    }
-
-    // Delete feed.
-    $this->deleteFeed($feed);
-
-    // Test updating feed items without valid timestamp information.
-    $edit = array(
-      'title' => "Feed without publish timestamp",
-      'url' => $this->getRSS091Sample(),
-    );
-
-    $this->drupalGet($edit['url']);
-    $this->assertResponse(array(200), t('URL !url is accessible', array('!url' => $edit['url'])));
-
-    $this->drupalPost('admin/config/services/aggregator/add/feed', $edit, t('Save'));
-    $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));
-
-    $feed = db_query("SELECT * FROM {aggregator_feed} WHERE url = :url", array(':url' => $edit['url']))->fetchObject();
-    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
-
-    $before = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
-
-    // Sleep for 3 second.
-    sleep(3);
-    db_update('aggregator_feed')
-      ->condition('fid', $feed->fid)
-      ->fields(array(
-        'checked' => 0,
-        'hash' => '',
-        'etag' => '',
-        'modified' => 0,
-      ))
-      ->execute();
-    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
-
-    $after = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
-
-    $this->assertTrue($before === $after, t('Publish timestamp of feed item was not updated (!before === !after)', array('!before' => $before, '!after' => $after)));
-  }
-}
-
-class RemoveFeedItemTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Remove feed item functionality',
-      'description' => 'Remove feed items from a feed.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Test running "remove items" from the 'admin/config/services/aggregator' page.
-   */
-  function testRemoveFeedItem() {
-    // Create a bunch of test feeds.
-    $feed_urls = array();
-    // No last-modified, no etag.
-    $feed_urls[] = url('aggregator/test-feed', array('absolute' => TRUE));
-    // Last-modified, but no etag.
-    $feed_urls[] = url('aggregator/test-feed/1', array('absolute' => TRUE));
-    // No Last-modified, but etag.
-    $feed_urls[] = url('aggregator/test-feed/0/1', array('absolute' => TRUE));
-    // Last-modified and etag.
-    $feed_urls[] = url('aggregator/test-feed/1/1', array('absolute' => TRUE));
-
-    foreach ($feed_urls as $feed_url) {
-      $feed = $this->createFeed($feed_url);
-      // Update and remove items two times in a row to make sure that removal
-      // resets all 'modified' information (modified, etag, hash) and allows for
-      // immediate update.
-      $this->updateAndRemove($feed, 2);
-      $this->updateAndRemove($feed, 2);
-      $this->updateAndRemove($feed, 2);
-      // Delete feed.
-      $this->deleteFeed($feed);
-    }
-  }
-}
-
-class CategorizeFeedItemTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Categorize feed item functionality',
-      'description' => 'Test feed item categorization.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * If a feed has a category, make sure that the children inherit that
-   * categorization.
-   */
-  function testCategorizeFeedItem() {
-    $this->createSampleNodes();
-
-    // Simulate form submission on "admin/config/services/aggregator/add/category".
-    $edit = array('title' => $this->randomName(10), 'description' => '');
-    $this->drupalPost('admin/config/services/aggregator/add/category', $edit, t('Save'));
-    $this->assertRaw(t('The category %title has been added.', array('%title' => $edit['title'])), t('The category %title has been added.', array('%title' => $edit['title'])));
-
-    $category = db_query("SELECT * FROM {aggregator_category} WHERE title = :title", array(':title' => $edit['title']))->fetch();
-    $this->assertTrue(!empty($category), t('The category found in database.'));
-
-    $link_path = 'aggregator/categories/' . $category->cid;
-    $menu_link = db_query("SELECT * FROM {menu_links} WHERE link_path = :link_path", array(':link_path' => $link_path))->fetch();
-    $this->assertTrue(!empty($menu_link), t('The menu link associated with the category found in database.'));
-
-    $feed = $this->createFeed();
-    db_insert('aggregator_category_feed')
-      ->fields(array(
-        'cid' => $category->cid,
-        'fid' => $feed->fid,
-      ))
-      ->execute();
-    $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
-    $this->getFeedCategories($feed);
-    $this->assertTrue(!empty($feed->categories), t('The category found in the feed.'));
-
-    // For each category of a feed, ensure feed items have that category, too.
-    if (!empty($feed->categories) && !empty($feed->items)) {
-      foreach ($feed->categories as $category) {
-        $categorized_count = db_select('aggregator_category_item')
-          ->condition('iid', $feed->items, 'IN')
-          ->countQuery()
-          ->execute()
-          ->fetchField();
-
-        $this->assertEqual($feed->item_count, $categorized_count, t('Total items in feed equal to the total categorized feed items in database'));
-      }
-    }
-
-    // Delete feed.
-    $this->deleteFeed($feed);
-  }
-}
-
-class ImportOPMLTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Import feeds from OPML functionality',
-      'description' => 'Test OPML import.',
-      'group' => 'Aggregator',
-    );
-  }
-
-  /**
-   * Open OPML import form.
-   */
-  function openImportForm() {
-    db_delete('aggregator_category')->execute();
-
-    $category = $this->randomName(10);
-    $cid = db_insert('aggregator_category')
-      ->fields(array(
-        'title' => $category,
-        'description' => '',
-      ))
-      ->execute();
-
-    $this->drupalGet('admin/config/services/aggregator/add/opml');
-    $this->assertText('A single OPML document may contain a collection of many feeds.', t('Found OPML help text.'));
-    $this->assertField('files[upload]', t('Found file upload field.'));
-    $this->assertField('remote', t('Found Remote URL field.'));
-    $this->assertField('refresh', '', t('Found Refresh field.'));
-    $this->assertFieldByName("category[$cid]", $cid, t('Found category field.'));
-  }
-
-  /**
-   * Submit form filled with invalid fields.
-   */
-  function validateImportFormFields() {
-    $before = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-
-    $edit = array();
-    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), t('Error if no fields are filled.'));
-
-    $path = $this->getEmptyOpml();
-    $edit = array(
-      'files[upload]' => $path,
-      'remote' => file_create_url($path),
-    );
-    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertRaw(t('You must <em>either</em> upload a file or enter a URL.'), t('Error if both fields are filled.'));
-
-    $edit = array('remote' => 'invalidUrl://empty');
-    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertText(t('This URL is not valid.'), t('Error if the URL is invalid.'));
-
-    $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-    $this->assertEqual($before, $after, t('No feeds were added during the three last form submissions.'));
-  }
-
-  /**
-   * Submit form with invalid, empty and valid OPML files.
-   */
-  function submitImportForm() {
-    $before = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-
-    $form['files[upload]'] = $this->getInvalidOpml();
-    $this->drupalPost('admin/config/services/aggregator/add/opml', $form, t('Import'));
-    $this->assertText(t('No new feed has been added.'), t('Attempting to upload invalid XML.'));
-
-    $edit = array('remote' => file_create_url($this->getEmptyOpml()));
-    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertText(t('No new feed has been added.'), t('Attempting to load empty OPML from remote URL.'));
-
-    $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-    $this->assertEqual($before, $after, t('No feeds were added during the two last form submissions.'));
-
-    db_delete('aggregator_feed')->execute();
-    db_delete('aggregator_category')->execute();
-    db_delete('aggregator_category_feed')->execute();
-
-    $category = $this->randomName(10);
-    db_insert('aggregator_category')
-      ->fields(array(
-        'cid' => 1,
-        'title' => $category,
-        'description' => '',
-      ))
-      ->execute();
-
-    $feeds[0] = $this->getFeedEditArray();
-    $feeds[1] = $this->getFeedEditArray();
-    $feeds[2] = $this->getFeedEditArray();
-    $edit = array(
-      'files[upload]' => $this->getValidOpml($feeds),
-      'refresh'       => '900',
-      'category[1]'   => $category,
-    );
-    $this->drupalPost('admin/config/services/aggregator/add/opml', $edit, t('Import'));
-    $this->assertRaw(t('A feed with the URL %url already exists.', array('%url' => $feeds[0]['url'])), t('Verifying that a duplicate URL was identified'));
-    $this->assertRaw(t('A feed named %title already exists.', array('%title' => $feeds[1]['title'])), t('Verifying that a duplicate title was identified'));
-
-    $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
-    $this->assertEqual($after, 2, t('Verifying that two distinct feeds were added.'));
-
-    $feeds_from_db = db_query("SELECT f.title, f.url, f.refresh, cf.cid FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} cf ON f.fid = cf.fid");
-    $refresh = $category = TRUE;
-    foreach ($feeds_from_db as $feed) {
-      $title[$feed->url] = $feed->title;
-      $url[$feed->title] = $feed->url;
-      $category = $category && $feed->cid == 1;
-      $refresh = $refresh && $feed->refresh == 900;
-    }
-
-    $this->assertEqual($title[$feeds[0]['url']], $feeds[0]['title'], t('First feed was added correctly.'));
-    $this->assertEqual($url[$feeds[1]['title']], $feeds[1]['url'], t('Second feed was added correctly.'));
-    $this->assertTrue($refresh, t('Refresh times are correct.'));
-    $this->assertTrue($category, t('Categories are correct.'));
-  }
-
-  function testOPMLImport() {
-    $this->openImportForm();
-    $this->validateImportFormFields();
-    $this->submitImportForm();
-  }
-}
-
-class AggregatorCronTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Update on cron functionality',
-      'description' => 'Update feeds on cron.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Add feeds update them on cron.
-   */
-  public function testCron() {
-    // Create feed and test basic updating on cron.
-    global $base_url;
-    $key = variable_get('cron_key', 'drupal');
-    $this->createSampleNodes();
-    $feed = $this->createFeed();
-    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
-    $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
-    $this->removeFeedItems($feed);
-    $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
-    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
-    $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
-
-    // Test feed locking when queued for update.
-    $this->removeFeedItems($feed);
-    db_update('aggregator_feed')
-      ->condition('fid', $feed->fid)
-      ->fields(array(
-        'queued' => REQUEST_TIME,
-      ))
-      ->execute();
-    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
-    $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
-    db_update('aggregator_feed')
-      ->condition('fid', $feed->fid)
-      ->fields(array(
-        'queued' => 0,
-      ))
-      ->execute();
-    $this->drupalGet($base_url . '/cron.php', array('external' => TRUE, 'query' => array('cron_key' => $key)));
-    $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField(), 'Expected number of items in database.');
-  }
-}
-
-class AggregatorRenderingTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Checks display of aggregator items',
-      'description' => 'Checks display of aggregator items on the page.',
-      'group' => 'Aggregator'
-    );
-  }
-
-  /**
-   * Add a feed block to the page and checks its links.
-   *
-   * TODO: Test the category block as well.
-   */
-  public function testBlockLinks() {
-    // Create feed.
-    $this->createSampleNodes();
-    $feed = $this->createFeed();
-    $this->updateFeedItems($feed, $this->getDefaultFeedItemCount());
-
-    // Place block on page (@see block.test:moveBlockToRegion())
-    // Need admin user to be able to access block admin.
-    $this->admin_user = $this->drupalCreateUser(array(
-      'administer blocks',
-      'access administration pages',
-      'administer news feeds',
-      'access news feeds',
-    ));
-    $this->drupalLogin($this->admin_user);
-
-    // Prepare to use the block admin form.
-    $block = array(
-      'module' => 'aggregator',
-      'delta' => 'feed-' . $feed->fid,
-      'title' => $feed->title,
-    );
-    $region = 'footer';
-    $edit = array();
-    $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = $region;
-    // Check the feed block is available in the block list form.
-    $this->drupalGet('admin/structure/block');
-    $this->assertFieldByName('blocks[' . $block['module'] . '_' . $block['delta'] . '][region]', '', 'Aggregator feed block is available for positioning.');
-    // Position it.
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
-    // Confirm that the block is now being displayed on pages.
-    $this->drupalGet('node');
-    $this->assertText(t($block['title']), t('Feed block is displayed on the page.'));
-
-    // Find the expected read_more link.
-    $href = 'aggregator/sources/' . $feed->fid;
-    $links = $this->xpath('//a[@href = :href]', array(':href' => url($href)));
-    $this->assert(isset($links[0]), t('Link to href %href found.', array('%href' => $href)));
-
-    // Visit that page.
-    $this->drupalGet($href);
-    $correct_titles = $this->xpath('//h1[normalize-space(text())=:title]', array(':title' => $feed->title));
-    $this->assertFalse(empty($correct_titles), t('Aggregator feed page is available and has the correct title.'));
-  }
-}
-
-/**
- * Tests for feed parsing.
- */
-class FeedParserTestCase extends AggregatorTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Feed parser functionality',
-      'description' => 'Test the built-in feed parser with valid feed samples.',
-      'group' => 'Aggregator',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-    // Do not remove old aggregator items during these tests, since our sample
-    // feeds have hardcoded dates in them (which may be expired when this test
-    // is run).
-    variable_set('aggregator_clear', AGGREGATOR_CLEAR_NEVER);
-  }
-
-  /**
-   * Test a feed that uses the RSS 0.91 format.
-   */
-  function testRSS091Sample() {
-    $feed = $this->createFeed($this->getRSS091Sample());
-    aggregator_refresh($feed);
-    $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(200, t('Feed %name exists.', array('%name' => $feed->title)));
-    $this->assertText('First example feed item title');
-    $this->assertLinkByHref('http://example.com/example-turns-one');
-    $this->assertText('First example feed item description.');
-  }
-
-  /**
-   * Test a feed that uses the Atom format.
-   */
-  function testAtomSample() {
-    $feed = $this->createFeed($this->getAtomSample());
-    aggregator_refresh($feed);
-    $this->drupalGet('aggregator/sources/' . $feed->fid);
-    $this->assertResponse(200, t('Feed %name exists.', array('%name' => $feed->title)));
-    $this->assertText('Atom-Powered Robots Run Amok');
-    $this->assertLinkByHref('http://example.org/2003/12/13/atom03');
-    $this->assertText('Some text.');
-    $this->assertEqual('urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', db_query('SELECT guid FROM {aggregator_item} WHERE link = :link', array(':link' => 'http://example.org/2003/12/13/atom03'))->fetchField(), 'Atom entry id element is parsed correctly.');
-  }
-}
-
diff --git a/modules/aggregator/tests/aggregator_test.info b/modules/aggregator/tests/aggregator_test.info
deleted file mode 100644
index 583a7fc..0000000
--- a/modules/aggregator/tests/aggregator_test.info
+++ /dev/null
@@ -1,6 +0,0 @@
-name = "Aggregator module tests"
-description = "Support module for aggregator related testing."
-package = Testing
-version = VERSION
-core = 8.x
-hidden = TRUE
diff --git a/modules/aggregator/tests/aggregator_test.module b/modules/aggregator/tests/aggregator_test.module
deleted file mode 100644
index 2d26a5d..0000000
--- a/modules/aggregator/tests/aggregator_test.module
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-/**
- * Implements hook_menu().
- */
-function aggregator_test_menu() {
-  $items['aggregator/test-feed'] = array(
-    'title' => 'Test feed static last modified date',
-    'description' => "A cached test feed with a static last modified date.",
-    'page callback' => 'aggregator_test_feed',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
-  return $items;
-}
-
-/**
- * Page callback. Generates a test feed and simulates last-modified and etags.
- *
- * @param $use_last_modified
- *   Set TRUE to send a last modified header.
- * @param $use_etag
- *   Set TRUE to send an etag.
- */
-function aggregator_test_feed($use_last_modified = FALSE, $use_etag = FALSE) {
-  $last_modified = strtotime('Sun, 19 Nov 1978 05:00:00 GMT');
-  $etag = drupal_hash_base64($last_modified);
-
-  $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
-  $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
-
-  // Send appropriate response. We respond with a 304 not modified on either
-  // etag or on last modified.
-  if ($use_last_modified) {
-    drupal_add_http_header('Last-Modified', gmdate(DATE_RFC1123, $last_modified));
-  }
-  if ($use_etag) {
-    drupal_add_http_header('ETag', $etag);
-  }
-  // Return 304 not modified if either last modified or etag match.
-  if ($last_modified == $if_modified_since || $etag == $if_none_match) {
-    drupal_add_http_header('Status', '304 Not Modified');
-    return;
-  }
-
-  // The following headers force validation of cache:
-  drupal_add_http_header('Expires', 'Sun, 19 Nov 1978 05:00:00 GMT');
-  drupal_add_http_header('Cache-Control', 'must-revalidate');
-  drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
-
-  // Read actual feed from file.
-  $file_name = DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/tests/aggregator_test_rss091.xml';
-  $handle = fopen($file_name, 'r');
-  $feed = fread($handle, filesize($file_name));
-  fclose($handle);
-
-  print $feed;
-}
diff --git a/modules/aggregator/tests/aggregator_test_atom.xml b/modules/aggregator/tests/aggregator_test_atom.xml
deleted file mode 100644
index 357b2e5..0000000
--- a/modules/aggregator/tests/aggregator_test_atom.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-
-  <title>Example Feed</title>
-  <link href="http://example.org/" />
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-    <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03" />
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-
-</feed>
diff --git a/modules/aggregator/tests/aggregator_test_rss091.xml b/modules/aggregator/tests/aggregator_test_rss091.xml
deleted file mode 100644
index 1fd5320..0000000
--- a/modules/aggregator/tests/aggregator_test_rss091.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<rss version="0.91">
-  <channel>
-    <title>Example</title>
-    <link>http://example.com</link>
-    <description>Example updates</description>
-    <language>en-us</language>
-    <copyright>Copyright 2000, Example team.</copyright>
-    <managingEditor>editor@example.com</managingEditor>
-    <webMaster>webmaster@example.com</webMaster>
-    <image>
-      <title>Example</title>
-      <url>http://example.com/images/druplicon.png</url>
-      <link>http://example.com</link>
-      <width>88</width>
-      <height>100</height>
-      <description>Example updates</description>
-    </image>
-    <item>
-      <title>First example feed item title</title>
-      <link>http://example.com/example-turns-one</link>
-      <description>First example feed item description.</description>
-    </item>
-    <item>
-      <title>Second example feed item title</title>
-      <link>http://example.com/example-turns-two</link>
-      <description>Second example feed item description.</description>
-    </item>
-  </channel>
-</rss>
diff --git a/modules/blog/blog.info b/modules/blog/blog.info
deleted file mode 100644
index 944794f..0000000
--- a/modules/blog/blog.info
+++ /dev/null
@@ -1,7 +0,0 @@
-name = Blog
-description = Enables multi-user blogs.
-package = Core
-version = VERSION
-core = 8.x
-dependencies[] = node
-files[] = blog.test
diff --git a/modules/blog/blog.install b/modules/blog/blog.install
deleted file mode 100644
index fffb14b..0000000
--- a/modules/blog/blog.install
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the blog module.
- */
-
-/**
- * Implements hook_install().
- */
-function blog_install() {
-  // Ensure the blog node type is available.
-  node_types_rebuild();
-  $types = node_type_get_types();
-  node_add_body_field($types['blog']);
-}
-
-/**
- * Implements hook_uninstall().
- */
-function blog_uninstall() {
-  variable_del('blog_block_count');
-}
diff --git a/modules/blog/blog.module b/modules/blog/blog.module
deleted file mode 100644
index 731bd2f..0000000
--- a/modules/blog/blog.module
+++ /dev/null
@@ -1,272 +0,0 @@
-<?php
-
-/**
- * @file
- * Enables multi-user blogs.
- */
-
-/**
- * Implements hook_node_info().
- */
-function blog_node_info() {
-  return array(
-    'blog' => array(
-      'name' => t('Blog entry'),
-      'base' => 'blog',
-      'description' => t('Use for multi-user blogs. Every user gets a personal blog.'),
-    )
-  );
-}
-
-/**
- * Implements hook_user_view().
- */
-function blog_user_view($account) {
-  if (user_access('create blog content', $account)) {
-    $account->content['summary']['blog'] =  array(
-      '#type' => 'user_profile_item',
-      '#title' => t('Blog'),
-      // l() escapes the attributes, so we should not escape !username here.
-      '#markup' => l(t('View recent blog entries'), "blog/$account->uid", array('attributes' => array('title' => t("Read !username's latest blog entries.", array('!username' => format_username($account)))))),
-      '#attributes' => array('class' => array('blog')),
-    );
-  }
-}
-
-/**
- * Implements hook_help().
- */
-function blog_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#blog':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t("The Blog module allows registered users to maintain an online journal, or <em>blog</em>. Blogs are made up of individual <em>blog entries</em>. By default, the blog entries are displayed by creation time in descending order, with comments enabled, and are promoted to the site's front page. For more information, see the online handbook entry for <a href='@blog'>Blog module</a>.", array('@blog' => 'http://drupal.org/handbook/modules/blog/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Single-user blogs') . '</dt>';
-      $output .= '<dd>' . t("Each user's blog entries are automatically displayed with a link to the user's main blog page. You can create as many single-user blogs as you have site users with permission to create blog content.") . '</dd>';
-      $output .= '<dt>' . t('Multi-user blogs') . '</dt>';
-      $output .= '<dd>' . t("Blog entries from each single-user blog are also aggregated into one central multi-user blog, which displays the blog content of all users in a single listing.") . '</dd>';
-      $output .= '<dt>' . t('Navigation') . '</dt>';
-      $output .= '<dd>' . t("There is an optional <em>Blogs</em> menu item added to the Navigation menu, which displays all blogs available on your site, and a <em>My blog</em> item displaying the current user's blog entries.") . '</dd>';
-      $output .= '<dt>' . t('Blocks') . '</dt>';
-      $output .= '<dd>' . t('The Blog module also creates a default <em>Recent blog posts</em> block that may be enabled at the <a href="@blocks">blocks administration page</a>.', array('@blocks' => url('admin/structure/block'))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_form().
- */
-function blog_form($node, $form_state) {
-  return node_content_form($node, $form_state);
-}
-
-/**
- * Implements hook_view().
- */
-function blog_view($node, $view_mode) {
-  if ($view_mode == 'full' && node_is_page($node)) {
-    // Breadcrumb navigation.  l() escapes title, so we should not escape !name.
-    drupal_set_breadcrumb(array(l(t('Home'), NULL), l(t('Blogs'), 'blog'), l(t("!name's blog", array('!name' => format_username($node))), 'blog/' . $node->uid)));
-  }
-  return $node;
-}
-
-/**
- * Implements hook_node_view().
- */
-function blog_node_view($node, $view_mode) {
-  if ($view_mode != 'rss') {
-    if ($node->type == 'blog' && (arg(0) != 'blog' || arg(1) != $node->uid)) {
-      // This goes to l(), which escapes !username in both title and attributes.
-      $links['blog_usernames_blog'] = array(
-        'title' => t("!username's blog", array('!username' => format_username($node))),
-        'href' => "blog/$node->uid",
-        'attributes' => array('title' => t("Read !username's latest blog entries.", array('!username' => format_username($node)))),
-      );
-      $node->content['links']['blog'] = array(
-        '#theme' => 'links__node__blog',
-        '#links' => $links,
-        '#attributes' => array('class' => array('links', 'inline')),
-      );
-    }
-  }
-}
-
-/**
- * Implements hook_menu().
- */
-function blog_menu() {
-  $items['blog'] = array(
-    'title' => 'Blogs',
-    'page callback' => 'blog_page_last',
-    'access arguments' => array('access content'),
-    'type' => MENU_SUGGESTED_ITEM,
-    'file' => 'blog.pages.inc',
-  );
-  $items['blog/%user_uid_optional'] = array(
-    'title' => 'My blog',
-    'page callback' => 'blog_page_user',
-    'page arguments' => array(1),
-    'access callback' => 'blog_page_user_access',
-    'access arguments' => array(1),
-    'file' => 'blog.pages.inc',
-  );
-  $items['blog/%user/feed'] = array(
-    'title' => 'Blogs',
-    'page callback' => 'blog_feed_user',
-    'page arguments' => array(1),
-    'access callback' => 'blog_page_user_access',
-    'access arguments' => array(1),
-    'type' => MENU_CALLBACK,
-    'file' => 'blog.pages.inc',
-  );
-  $items['blog/feed'] = array(
-    'title' => 'Blogs',
-    'page callback' => 'blog_feed_last',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-    'file' => 'blog.pages.inc',
-  );
-
-  return $items;
-}
-
-/**
- * Implements hook_menu_local_tasks_alter().
- */
-function blog_menu_local_tasks_alter(&$data, $router_item, $root_path) {
-  global $user;
-
-  // Add action link to 'node/add/blog' on 'blog' page.
-  if ($root_path == 'blog') {
-    $item = menu_get_item('node/add/blog');
-    if ($item['access']) {
-      $item['title'] = t('Create new blog entry');
-      $data['actions']['output'][] = array(
-        '#theme' => 'menu_local_action',
-        '#link' => $item,
-      );
-    }
-  }
-  // Provide a helper action link to the author on the 'blog/%' page.
-  elseif ($root_path == 'blog/%' && $router_item['page_arguments'][0]->uid == $user->uid) {
-    $data['actions']['output']['blog'] = array(
-      '#theme' => 'menu_local_action',
-    );
-    if (user_access('create blog content')) {
-      $data['actions']['output']['blog']['#link']['title'] = t('Post new blog entry.');
-      $data['actions']['output']['blog']['#link']['href'] = 'node/add/blog';
-    }
-    else {
-      $data['actions']['output']['blog']['#link']['title'] = t('You are not allowed to post a new blog entry.');
-    }
-  }
-}
-
-/**
- * Access callback for user blog pages.
- */
-function blog_page_user_access($account) {
-  // The visitor must be able to access the site's content.
-  // For a blog to 'exist' the user must either be able to
-  // create new blog entries, or it must have existing posts.
-  return $account->uid && user_access('access content') && (user_access('create blog content', $account) || _blog_post_exists($account));
-}
-
-/**
- * Helper function to determine if a user has blog posts already.
- */
-function _blog_post_exists($account) {
-  return (bool)db_select('node', 'n')
-    ->fields('n', array('nid'))
-    ->condition('type', 'blog')
-    ->condition('uid', $account->uid)
-    ->condition('status', 1)
-    ->range(0, 1)
-    ->addTag('node_access')
-    ->execute()
-    ->fetchField();
-}
-
-/**
- * Implements hook_block_info().
- */
-function blog_block_info() {
-  $block['recent']['info'] = t('Recent blog posts');
-  $block['recent']['properties']['administrative'] = TRUE;
-  return $block;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function blog_block_configure($delta = '') {
-  if ($delta == 'recent') {
-    $form['blog_block_count'] = array(
-      '#type' => 'select',
-      '#title' => t('Number of recent blog posts to display'),
-      '#default_value' => variable_get('blog_block_count', 10),
-      '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
-    );
-    return $form;
-  }
-}
-
-/**
- * Implements hook_block_save().
- */
-function blog_block_save($delta = '', $edit = array()) {
-  if ($delta == 'recent') {
-    variable_set('blog_block_count', $edit['blog_block_count']);
-  }
-}
-
-/**
- * Implements hook_block_view().
- *
- * Displays the most recent 10 blog titles.
- */
-function blog_block_view($delta = '') {
-  global $user;
-
-  if (user_access('access content')) {
-    $result = db_select('node', 'n')
-      ->fields('n', array('nid', 'title', 'created'))
-      ->condition('type', 'blog')
-      ->condition('status', 1)
-      ->orderBy('created', 'DESC')
-      ->range(0, variable_get('blog_block_count', 10))
-      ->addTag('node_access')
-      ->execute();
-
-    if ($node_title_list = node_title_list($result)) {
-      $block['subject'] = t('Recent blog posts');
-      $block['content']['blog_list'] = $node_title_list;
-      $block['content']['blog_more'] = array(
-        '#theme' => 'more_link',
-        '#url' => 'blog',
-        '#title' => t('Read the latest blog entries.'),
-      );
-
-      return $block;
-    }
-  }
-}
-
-/**
- * Implements hook_rdf_mapping().
- */
-function blog_rdf_mapping() {
-  return array(
-    array(
-      'type' => 'node',
-      'bundle' => 'blog',
-      'mapping' => array(
-        'rdftype' => array('sioc:Post', 'sioct:BlogPost'),
-      ),
-    ),
-  );
-}
diff --git a/modules/blog/blog.pages.inc b/modules/blog/blog.pages.inc
deleted file mode 100644
index 3684028..0000000
--- a/modules/blog/blog.pages.inc
+++ /dev/null
@@ -1,127 +0,0 @@
-<?php
-
-/**
- * @file
- * Page callback file for the blog module.
- */
-
-/**
- * Menu callback; displays a Drupal page containing recent blog entries of a given user.
- */
-function blog_page_user($account) {
-  global $user;
-
-  drupal_set_title($title = t("@name's blog", array('@name' => format_username($account))), PASS_THROUGH);
-
-  $build = array();
-
-  $query = db_select('node', 'n')->extend('PagerDefault');
-  $nids = $query
-    ->fields('n', array('nid', 'sticky', 'created'))
-    ->condition('type', 'blog')
-    ->condition('uid', $account->uid)
-    ->condition('status', 1)
-    ->orderBy('sticky', 'DESC')
-    ->orderBy('created', 'DESC')
-    ->limit(variable_get('default_nodes_main', 10))
-    ->addTag('node_access')
-    ->execute()
-    ->fetchCol();
-
-  if (!empty($nids)) {
-    $nodes = node_load_multiple($nids);
-    $build += node_view_multiple($nodes);
-    $build['pager'] = array(
-      '#theme' => 'pager',
-      '#weight' => 5,
-    );
-  }
-  else {
-    if ($account->uid == $user->uid) {
-      drupal_set_message(t('You have not created any blog entries.'));
-    }
-    else {
-      drupal_set_message(t('!author has not created any blog entries.', array('!author' => theme('username', array('account' => $account)))));
-    }
-  }
-  drupal_add_feed('blog/' . $account->uid . '/feed', t('RSS - !title', array('!title' => $title)));
-
-  return $build;
-}
-
-/**
- * Menu callback; displays a Drupal page containing recent blog entries of all users.
- */
-function blog_page_last() {
-  global $user;
-  $build = array();
-
-  $query = db_select('node', 'n')->extend('PagerDefault');
-  $nids = $query
-    ->fields('n', array('nid', 'sticky', 'created'))
-    ->condition('type', 'blog')
-    ->condition('status', 1)
-    ->orderBy('sticky', 'DESC')
-    ->orderBy('created', 'DESC')
-    ->limit(variable_get('default_nodes_main', 10))
-    ->addTag('node_access')
-    ->execute()
-    ->fetchCol();
-
-  if (!empty($nids)) {
-    $nodes = node_load_multiple($nids);
-    $build += node_view_multiple($nodes);
-    $build['pager'] = array(
-      '#theme' => 'pager',
-      '#weight' => 5,
-    );
-  }
-  else {
-    drupal_set_message(t('No blog entries have been created.'));
-  }
-  drupal_add_feed('blog/feed', t('RSS - blogs'));
-
-  return $build;
-}
-
-/**
- * Menu callback; displays an RSS feed containing recent blog entries of a given user.
- */
-function blog_feed_user($account) {
-
-  $nids = db_select('node', 'n')
-    ->fields('n', array('nid', 'created'))
-    ->condition('type', 'blog')
-    ->condition('uid', $account->uid)
-    ->condition('status', 1)
-    ->orderBy('created', 'DESC')
-    ->range(0, variable_get('feed_default_items', 10))
-    ->addTag('node_access')
-    ->execute()
-    ->fetchCol();
-
-  $channel['title'] = t("!name's blog", array('!name' => format_username($account)));
-  $channel['link'] = url('blog/' . $account->uid, array('absolute' => TRUE));
-
-  node_feed($nids, $channel);
-}
-
-/**
- * Menu callback; displays an RSS feed containing recent blog entries of all users.
- */
-function blog_feed_last() {
-  $nids = db_select('node', 'n')
-    ->fields('n', array('nid', 'created'))
-    ->condition('type', 'blog')
-    ->condition('status', 1)
-    ->orderBy('created', 'DESC')
-    ->range(0, variable_get('feed_default_items', 10))
-    ->addTag('node_access')
-    ->execute()
-    ->fetchCol();
-
-  $channel['title'] = t('!site_name blogs', array('!site_name' => variable_get('site_name', 'Drupal')));
-  $channel['link'] = url('blog', array('absolute' => TRUE));
-
-  node_feed($nids, $channel);
-}
diff --git a/modules/blog/blog.test b/modules/blog/blog.test
deleted file mode 100644
index 6ff66a2..0000000
--- a/modules/blog/blog.test
+++ /dev/null
@@ -1,213 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for blog.module.
- */
-
-class BlogTestCase extends DrupalWebTestCase {
-  protected $big_user;
-  protected $own_user;
-  protected $any_user;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Blog functionality',
-      'description' => 'Create, view, edit, delete, and change blog entries and verify its consistency in the database.',
-      'group' => 'Blog',
-    );
-  }
-
-  /**
-   * Enable modules and create users with specific permissions.
-   */
-  function setUp() {
-    parent::setUp('blog');
-    // Create users.
-    $this->big_user = $this->drupalCreateUser(array('administer blocks'));
-    $this->own_user = $this->drupalCreateUser(array('create blog content', 'edit own blog content', 'delete own blog content'));
-    $this->any_user = $this->drupalCreateUser(array('create blog content', 'edit any blog content', 'delete any blog content', 'access administration pages'));
-  }
-
-  /**
-   * Confirm that the "You are not allowed to post a new blog entry." message
-   * shows up if a user submitted blog entries, has been denied that
-   * permission, and goes to the blog page.
-   */
-  function testUnprivilegedUser() {
-    // Create a blog node for a user with no blog permissions.
-    $this->drupalCreateNode(array('type' => 'blog', 'uid' => $this->big_user->uid));
-
-    $this->drupalLogin($this->big_user);
-
-    $this->drupalGet('blog/' . $this->big_user->uid);
-    $this->assertResponse(200);
-    $this->assertTitle(t("@name's blog", array('@name' => format_username($this->big_user))) . ' | Drupal', t('Blog title was displayed'));
-    $this->assertText(t('You are not allowed to post a new blog entry.'), t('No new entries can be posted without the right permission'));
-  }
-
-  /**
-   * View the blog of a user with no blog entries as another user.
-   */
-  function testBlogPageNoEntries() {
-    $this->drupalLogin($this->big_user);
-
-    $this->drupalGet('blog/' . $this->own_user->uid);
-    $this->assertResponse(200);
-    $this->assertTitle(t("@name's blog", array('@name' => format_username($this->own_user))) . ' | Drupal', t('Blog title was displayed'));
-    $this->assertText(t('@author has not created any blog entries.', array('@author' => format_username($this->own_user))), t('Users blog displayed with no entries'));
-  }
-
-  /**
-   * Login users, create blog nodes, and test blog functionality through the admin and user interfaces.
-   */
-  function testBlog() {
-    // Login the admin user.
-    $this->drupalLogin($this->big_user);
-    // Enable the recent blog block.
-    $edit = array();
-    $edit['blocks[blog_recent][region]'] = 'sidebar_second';
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertResponse(200);
-    // Verify ability to change number of recent blog posts in block.
-    $edit = array();
-    $edit['blog_block_count'] = 5;
-    $this->drupalPost('admin/structure/block/manage/blog/recent/configure', $edit, t('Save block'));
-    $this->assertEqual(variable_get('blog_block_count', 10), 5, t('Number of recent blog posts changed.'));
-
-    // Do basic tests for each user.
-    $this->doBasicTests($this->any_user, TRUE);
-    $this->doBasicTests($this->own_user, FALSE);
-
-    // Create another blog node for the any blog user.
-    $node = $this->drupalCreateNode(array('type' => 'blog', 'uid' => $this->any_user->uid));
-    // Verify the own blog user only has access to the blog view node.
-    $this->verifyBlogs($this->any_user, $node, FALSE, 403);
-
-    // Create another blog node for the own blog user.
-    $node = $this->drupalCreateNode(array('type' => 'blog', 'uid' => $this->own_user->uid));
-    // Login the any blog user.
-    $this->drupalLogin($this->any_user);
-    // Verify the any blog user has access to all the blog nodes.
-    $this->verifyBlogs($this->own_user, $node, TRUE);
-  }
-
-  /**
-   * Run basic tests on the indicated user.
-   *
-   * @param object $user
-   *   The logged in user.
-   * @param boolean $admin
-   *   User has 'access administration pages' privilege.
-   */
-  private function doBasicTests($user, $admin) {
-    // Login the user.
-    $this->drupalLogin($user);
-    // Create blog node.
-    $node = $this->drupalCreateNode(array('type' => 'blog'));
-    // Verify the user has access to all the blog nodes.
-    $this->verifyBlogs($user, $node, $admin);
-    // Create one more node to test the blog page with more than one node
-    $this->drupalCreateNode(array('type' => 'blog', 'uid' => $user->uid));
-    // Verify the blog links are displayed.
-    $this->verifyBlogLinks($user);
-  }
-
-  /**
-   * Verify the logged in user has the desired access to the various blog nodes.
-   *
-   * @param object $node_user
-   *   The user who creates the node.
-   * @param object $node
-   *   A node object.
-   * @param boolean $admin
-   *   User has 'access administration pages' privilege.
-   * @param integer $response
-   *   HTTP response code.
-   */
-  private function verifyBlogs($node_user, $node, $admin, $response = 200) {
-    $response2 = ($admin) ? 200 : 403;
-
-    // View blog help node.
-    $this->drupalGet('admin/help/blog');
-    $this->assertResponse($response2);
-    if ($response2 == 200) {
-      $this->assertTitle(t('Blog | Drupal'), t('Blog help node was displayed'));
-      $this->assertText(t('Blog'), t('Blog help node was displayed'));
-    }
-
-    // Verify the blog block was displayed.
-    $this->drupalGet('');
-    $this->assertResponse(200);
-    $this->assertText(t('Recent blog posts'), t('Blog block was displayed'));
-
-    // View blog node.
-    $this->drupalGet('node/' . $node->nid);
-    $this->assertResponse(200);
-    $this->assertTitle($node->title . ' | Drupal', t('Blog node was displayed'));
-    $breadcrumb = array(
-      l(t('Home'), NULL),
-      l(t('Blogs'), 'blog'),
-      l(t("!name's blog", array('!name' => format_username($node_user))), 'blog/' . $node_user->uid),
-    );
-    $this->assertRaw(theme('breadcrumb', array('breadcrumb' => $breadcrumb)), t('Breadcrumbs were displayed'));
-
-    // View blog edit node.
-    $this->drupalGet('node/' . $node->nid . '/edit');
-    $this->assertResponse($response);
-    if ($response == 200) {
-      $this->assertTitle('Edit Blog entry ' . $node->title . ' | Drupal', t('Blog edit node was displayed'));
-    }
-
-    if ($response == 200) {
-      // Edit blog node.
-      $edit = array();
-      $langcode = LANGUAGE_NONE;
-      $edit["title"] = 'node/' . $node->nid;
-      $edit["body[$langcode][0][value]"] = $this->randomName(256);
-      $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
-      $this->assertRaw(t('Blog entry %title has been updated.', array('%title' => $edit["title"])), t('Blog node was edited'));
-
-      // Delete blog node.
-      $this->drupalPost('node/' . $node->nid . '/delete', array(), t('Delete'));
-      $this->assertResponse($response);
-      $this->assertRaw(t('Blog entry %title has been deleted.', array('%title' => $edit["title"])), t('Blog node was deleted'));
-    }
-  }
-
-  /**
-   * Verify the blog links are displayed to the logged in user.
-   *
-   * @param object $user
-   *   The logged in user.
-   */
-  private function verifyBlogLinks($user) {
-    // Confirm blog entries link exists on the user page.
-    $this->drupalGet('user/' . $user->uid);
-    $this->assertResponse(200);
-    $this->assertText(t('View recent blog entries'), t('View recent blog entries link was displayed'));
-
-    // Confirm the recent blog entries link goes to the user's blog page.
-    $this->clickLink('View recent blog entries');
-    $this->assertTitle(t("@name's blog | Drupal", array('@name' => format_username($user))), t('View recent blog entries link target was correct'));
-
-    // Confirm a blog page was displayed.
-    $this->drupalGet('blog');
-    $this->assertResponse(200);
-    $this->assertTitle('Blogs | Drupal', t('Blog page was displayed'));
-    $this->assertText(t('Home'), t('Breadcrumbs were displayed'));
-    $this->assertLink(t('Create new blog entry'));
-
-    // Confirm a blog page was displayed per user.
-    $this->drupalGet('blog/' . $user->uid);
-    $this->assertTitle(t("@name's blog | Drupal", array('@name' => format_username($user))), t('User blog node was displayed'));
-
-    // Confirm a blog feed was displayed.
-    $this->drupalGet('blog/feed');
-    $this->assertTitle(t('Drupal blogs'), t('Blog feed was displayed'));
-
-    // Confirm a blog feed was displayed per user.
-    $this->drupalGet('blog/' . $user->uid . '/feed');
-    $this->assertTitle(t("@name's blog", array('@name' => format_username($user))), t('User blog feed was displayed'));
-  }
-}
diff --git a/modules/book/book-all-books-block.tpl.php b/modules/book/book-all-books-block.tpl.php
deleted file mode 100644
index d22ff2c..0000000
--- a/modules/book/book-all-books-block.tpl.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for rendering book outlines within a block.
- * This template is used only when the block is configured to "show block on
- * all pages" which presents Multiple independent books on all pages.
- *
- * Available variables:
- * - $book_menus: Array of book outlines keyed to the parent book ID. Call
- *   render() on each to print it as an unordered list.
- */
-?>
-<?php foreach ($book_menus as $book_id => $menu) : ?>
-<div id="book-block-menu-<?php print $book_id; ?>" class="book-block-menu">
-  <?php print render($menu); ?>
-</div>
-<?php endforeach; ?>
diff --git a/modules/book/book-export-html.tpl.php b/modules/book/book-export-html.tpl.php
deleted file mode 100644
index 180f3ae..0000000
--- a/modules/book/book-export-html.tpl.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for printed version of book outline.
- *
- * Available variables:
- * - $title: Top level node title.
- * - $head: Header tags.
- * - $language: Language code. e.g. "en" for english.
- * - $language_rtl: TRUE or FALSE depending on right to left language scripts.
- * - $base_url: URL to home page.
- * - $contents: Nodes within the current outline rendered through
- *   book-node-export-html.tpl.php.
- *
- * @see template_preprocess_book_export_html()
- */
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php print $language->language; ?>" xml:lang="<?php print $language->language; ?>">
-  <head>
-    <title><?php print $title; ?></title>
-    <?php print $head; ?>
-    <base href="<?php print $base_url; ?>" />
-    <link type="text/css" rel="stylesheet" href="misc/print.css" />
-    <?php if ($language_rtl): ?>
-      <link type="text/css" rel="stylesheet" href="misc/print-rtl.css" />
-    <?php endif; ?>
-  </head>
-  <body>
-    <?php
-    /**
-     * The given node is /embedded to its absolute depth in a top level
-     * section/. For example, a child node with depth 2 in the hierarchy is
-     * contained in (otherwise empty) &lt;div&gt; elements corresponding to
-     * depth 0 and depth 1. This is intended to support WYSIWYG output - e.g.,
-     * level 3 sections always look like level 3 sections, no matter their
-     * depth relative to the node selected to be exported as printer-friendly
-     * HTML.
-     */
-    $div_close = '';
-    ?>
-    <?php for ($i = 1; $i < $depth; $i++) : ?>
-      <div class="section-<?php print $i; ?>">
-      <?php $div_close .= '</div>'; ?>
-    <?php endfor; ?>
-    <?php print $contents; ?>
-    <?php print $div_close; ?>
-  </body>
-</html>
diff --git a/modules/book/book-navigation.tpl.php b/modules/book/book-navigation.tpl.php
deleted file mode 100644
index e5883dc..0000000
--- a/modules/book/book-navigation.tpl.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to navigate books. Presented under nodes that
- * are a part of book outlines.
- *
- * Available variables:
- * - $tree: The immediate children of the current node rendered as an
- *   unordered list.
- * - $current_depth: Depth of the current node within the book outline.
- *   Provided for context.
- * - $prev_url: URL to the previous node.
- * - $prev_title: Title of the previous node.
- * - $parent_url: URL to the parent node.
- * - $parent_title: Title of the parent node. Not printed by default. Provided
- *   as an option.
- * - $next_url: URL to the next node.
- * - $next_title: Title of the next node.
- * - $has_links: Flags TRUE whenever the previous, parent or next data has a
- *   value.
- * - $book_id: The book ID of the current outline being viewed. Same as the
- *   node ID containing the entire outline. Provided for context.
- * - $book_url: The book/node URL of the current outline being viewed.
- *   Provided as an option. Not used by default.
- * - $book_title: The book/node title of the current outline being viewed.
- *   Provided as an option. Not used by default.
- *
- * @see template_preprocess_book_navigation()
- */
-?>
-<?php if ($tree || $has_links): ?>
-  <div id="book-navigation-<?php print $book_id; ?>" class="book-navigation">
-    <?php print $tree; ?>
-
-    <?php if ($has_links): ?>
-    <div class="page-links clearfix">
-      <?php if ($prev_url) : ?>
-        <a href="<?php print $prev_url; ?>" class="page-previous" title="<?php print t('Go to previous page'); ?>"><?php print t('‹ ') . $prev_title; ?></a>
-      <?php endif; ?>
-      <?php if ($parent_url) : ?>
-        <a href="<?php print $parent_url; ?>" class="page-up" title="<?php print t('Go to parent page'); ?>"><?php print t('up'); ?></a>
-      <?php endif; ?>
-      <?php if ($next_url) : ?>
-        <a href="<?php print $next_url; ?>" class="page-next" title="<?php print t('Go to next page'); ?>"><?php print $next_title . t(' ›'); ?></a>
-      <?php endif; ?>
-    </div>
-    <?php endif; ?>
-
-  </div>
-<?php endif; ?>
diff --git a/modules/book/book-node-export-html.tpl.php b/modules/book/book-node-export-html.tpl.php
deleted file mode 100644
index ef6c322..0000000
--- a/modules/book/book-node-export-html.tpl.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for rendering a single node in a printer
- * friendly outline.
- *
- * @see book-node-export-html.tpl.php
- * Where it is collected and printed out.
- *
- * Available variables:
- * - $depth: Depth of the current node inside the outline.
- * - $title: Node title.
- * - $content: Node content.
- * - $children: All the child nodes recursively rendered through this file.
- *
- * @see template_preprocess_book_node_export_html()
- */
-?>
-<div id="node-<?php print $node->nid; ?>" class="section-<?php print $depth; ?>">
-  <h1 class="book-heading"><?php print $title; ?></h1>
-  <?php print $content; ?>
-  <?php print $children; ?>
-</div>
diff --git a/modules/book/book-rtl.css b/modules/book/book-rtl.css
deleted file mode 100644
index f3a84c2..0000000
--- a/modules/book/book-rtl.css
+++ /dev/null
@@ -1,11 +0,0 @@
-
-.book-navigation .menu {
-  padding: 1em 3em 0 0;
-}
-
-.book-navigation .page-previous {
-  float: right;
-}
-.book-navigation .page-up {
-  float: right;
-}
diff --git a/modules/book/book.admin.inc b/modules/book/book.admin.inc
deleted file mode 100644
index 7b9dea3..0000000
--- a/modules/book/book.admin.inc
+++ /dev/null
@@ -1,264 +0,0 @@
-<?php
-
-/**
- * @file
- * Admin page callbacks for the book module.
- */
-
-/**
- * Returns an administrative overview of all books.
- */
-function book_admin_overview() {
-  $rows = array();
-
-  $headers = array(t('Book'), t('Operations'));
-
-  // 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']));
-  }
-
-  return theme('table', array('header' => $headers, 'rows' => $rows, 'empty' => t('No books available.')));
-}
-
-/**
- * Builds and returns the book settings form.
- *
- * @see book_admin_settings_validate()
- *
- * @ingroup forms
- */
-function book_admin_settings() {
-  $types = node_type_get_names();
-  $form['book_allowed_types'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Content types allowed in book outlines'),
-    '#default_value' => variable_get('book_allowed_types', array('book')),
-    '#options' => $types,
-    '#description' => t('Users with the %outline-perm permission can add all content types.', array('%outline-perm' => t('Administer book outlines'))),
-    '#required' => TRUE,
-  );
-  $form['book_child_type'] = array(
-    '#type' => 'radios',
-    '#title' => t('Content type for child pages'),
-    '#default_value' => variable_get('book_child_type', 'book'),
-    '#options' => $types,
-    '#required' => TRUE,
-  );
-  $form['array_filter'] = array('#type' => 'value', '#value' => TRUE);
-  $form['#validate'][] = 'book_admin_settings_validate';
-
-  return system_settings_form($form);
-}
-
-/**
- * Validate the book settings form.
- *
- * @see book_admin_settings()
- */
-function book_admin_settings_validate($form, &$form_state) {
-  $child_type = $form_state['values']['book_child_type'];
-  if (empty($form_state['values']['book_allowed_types'][$child_type])) {
-    form_set_error('book_child_type', t('The content type for the %add-child link must be one of those selected as an allowed book outline type.', array('%add-child' => t('Add child page'))));
-  }
-}
-
-/**
- * Build the form to administrate the hierarchy of a single book.
- *
- * @see book_admin_edit_submit()
- *
- * @ingroup forms.
- */
-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'),
-  );
-
-  return $form;
-}
-
-/**
- * Check that the book has not been changed while using the form.
- *
- * @see book_admin_edit()
- */
-function book_admin_edit_validate($form, &$form_state) {
-  if ($form_state['values']['tree_hash'] != $form_state['values']['tree_current_hash']) {
-    form_set_error('', t('This book has been modified by another user, the changes could not be saved.'));
-  }
-}
-
-/**
- * Handle submission of the book administrative page form.
- *
- * This function takes care to save parent menu items before their children.
- * Saving menu items in the incorrect order can break the menu tree.
- *
- * @see book_admin_edit()
- * @see menu_overview_form_submit()
- */
-function book_admin_edit_submit($form, &$form_state) {
-  // Save elements in the same order as defined in post rather than the form.
-  // This ensures parents are updated before their children, preventing orphans.
-  $order = array_flip(array_keys($form_state['input']['table']));
-  $form['table'] = array_merge($order, $form['table']);
-
-  foreach (element_children($form['table']) as $key) {
-    if ($form['table'][$key]['#item']) {
-      $row = $form['table'][$key];
-      $values = $form_state['values']['table'][$key];
-
-      // Update menu item if moved.
-      if ($row['plid']['#default_value'] != $values['plid'] || $row['weight']['#default_value'] != $values['weight']) {
-        $row['#item']['plid'] = $values['plid'];
-        $row['#item']['weight'] = $values['weight'];
-        menu_link_save($row['#item']);
-      }
-
-      // Update the title if changed.
-      if ($row['title']['#default_value'] != $values['title']) {
-        $node = node_load($values['nid']);
-        $langcode = LANGUAGE_NONE;
-        $node->title = $values['title'];
-        $node->book['link_title'] = $values['title'];
-        $node->revision = 1;
-        $node->log = t('Title changed from %original to %current.', array('%original' => $node->title, '%current' => $values['title']));
-
-        node_save($node);
-        watchdog('content', 'book: updated %title.', array('%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid));
-      }
-    }
-  }
-
-  drupal_set_message(t('Updated book %title.', array('%title' => $form['#node']->title)));
-}
-
-/**
- * Build the table portion of the form for the book administration page.
- *
- * @see book_admin_edit()
- */
-function _book_admin_table($node, &$form) {
-  $form['table'] = array(
-    '#theme' => 'book_admin_table',
-    '#tree' => TRUE,
-  );
-
-  $tree = book_menu_subtree_data($node->book);
-  $tree = array_shift($tree); // Do not include the book item itself.
-  if ($tree['below']) {
-    $hash = drupal_hash_base64(serialize($tree['below']));
-    // Store the hash value as a hidden form element so that we can detect
-    // if another user changed the book hierarchy.
-    $form['tree_hash'] = array(
-      '#type' => 'hidden',
-      '#default_value' => $hash,
-    );
-    $form['tree_current_hash'] = array(
-      '#type' => 'value',
-      '#value' => $hash,
-    );
-    _book_admin_table_tree($tree['below'], $form['table']);
-  }
-
-}
-
-/**
- * Recursive helper to build the main table in the book administration page form.
- *
- * @see book_admin_edit()
- */
-function _book_admin_table_tree($tree, &$form) {
-  // The delta must be big enough to give each node a distinct value.
-  $count = count($tree);
-  $delta = ($count < 30) ? 15 : intval($count / 2) + 1;
-
-  foreach ($tree as $data) {
-    $form['book-admin-' . $data['link']['nid']] = array(
-      '#item' => $data['link'],
-      'nid' => array('#type' => 'value', '#value' => $data['link']['nid']),
-      'depth' => array('#type' => 'value', '#value' => $data['link']['depth']),
-      'href' => array('#type' => 'value', '#value' => $data['link']['href']),
-      'title' => array(
-        '#type' => 'textfield',
-        '#default_value' => $data['link']['link_title'],
-        '#maxlength' => 255,
-        '#size' => 40,
-      ),
-      'weight' => array(
-        '#type' => 'weight',
-        '#default_value' => $data['link']['weight'],
-        '#delta' => max($delta, abs($data['link']['weight'])),
-        '#title' => t('Weight for @title', array('@title' => $data['link']['title'])),
-        '#title_display' => 'invisible',
-      ),
-      'plid' => array(
-        '#type' => 'hidden',
-        '#default_value' => $data['link']['plid'],
-      ),
-      'mlid' => array(
-        '#type' => 'hidden',
-        '#default_value' => $data['link']['mlid'],
-      ),
-    );
-    if ($data['below']) {
-      _book_admin_table_tree($data['below'], $form);
-    }
-  }
-
-  return $form;
-}
-
-/**
- * Returns HTML for a book administration form.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @see book_admin_table()
- * @ingroup themeable
- */
-function theme_book_admin_table($variables) {
-  $form = $variables['form'];
-
-  drupal_add_tabledrag('book-outline', 'match', 'parent', 'book-plid', 'book-plid', 'book-mlid', TRUE, MENU_MAX_DEPTH - 2);
-  drupal_add_tabledrag('book-outline', 'order', 'sibling', 'book-weight');
-
-  $header = array(t('Title'), t('Weight'), t('Parent'), array('data' => t('Operations'), 'colspan' => '3'));
-
-  $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'];
-
-    // Add special classes to be used with tabledrag.js.
-    $form[$key]['plid']['#attributes']['class'] = array('book-plid');
-    $form[$key]['mlid']['#attributes']['class'] = array('book-mlid');
-    $form[$key]['weight']['#attributes']['class'] = array('book-weight');
-
-    $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;',
-    );
-    $row = array('data' => $data);
-    if (isset($form[$key]['#attributes'])) {
-      $row = array_merge($row, $form[$key]['#attributes']);
-    }
-    $row['class'][] = 'draggable';
-    $rows[] = $row;
-  }
-
-  return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'book-outline')));
-}
diff --git a/modules/book/book.css b/modules/book/book.css
deleted file mode 100644
index a8d2136..0000000
--- a/modules/book/book.css
+++ /dev/null
@@ -1,54 +0,0 @@
-
-.book-navigation .menu {
-  border-top: 1px solid #888;
-  padding: 1em 0 0 3em; /* LTR */
-}
-.book-navigation .page-links {
-  border-top: 1px solid #888;
-  border-bottom: 1px solid #888;
-  text-align: center;
-  padding: 0.5em;
-}
-.book-navigation .page-previous {
-  text-align: left;
-  width: 42%;
-  display: block;
-  float: left; /* LTR */
-}
-.book-navigation .page-up {
-  margin: 0 5%;
-  width: 4%;
-  display: block;
-  float: left; /* LTR */
-}
-.book-navigation .page-next {
-  text-align: right;
-  width: 42%;
-  display: block;
-  float: right;
-}
-#book-outline {
-  min-width: 56em;
-}
-.book-outline-form .form-item {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-html.js #edit-book-pick-book {
-  display: none;
-}
-.form-item-book-bid .description {
-  clear: both;
-}
-#book-admin-edit select {
-  margin-right: 24px;
-}
-#book-admin-edit select.progress-disabled {
-  margin-right: 0;
-}
-#book-admin-edit tr.ajax-new-content {
-  background-color: #ffd;
-}
-#book-admin-edit .form-item {
-  float: left;
-}
diff --git a/modules/book/book.info b/modules/book/book.info
deleted file mode 100644
index 114b212..0000000
--- a/modules/book/book.info
+++ /dev/null
@@ -1,9 +0,0 @@
-name = Book
-description = Allows users to create and organize related content in an outline.
-package = Core
-version = VERSION
-core = 8.x
-dependencies[] = node
-files[] = book.test
-configure = admin/content/book/settings
-stylesheets[all][] = book.css
diff --git a/modules/book/book.install b/modules/book/book.install
deleted file mode 100644
index e92aca6..0000000
--- a/modules/book/book.install
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the book module.
- */
-
-/**
- * Implements hook_install().
- */
-function book_install() {
-  // Add the node type.
-  _book_install_type_create();
-}
-
-/**
- * Implements hook_uninstall().
- */
-function book_uninstall() {
-  variable_del('book_allowed_types');
-  variable_del('book_child_type');
-  variable_del('book_block_mode');
-
-  // Delete menu links.
-  db_delete('menu_links')
-    ->condition('module', 'book')
-    ->execute();
-  menu_cache_clear_all();
-}
-
-function _book_install_type_create() {
-  // Create an additional node type.
-  $book_node_type = array(
-    'type' => 'book',
-    'name' => t('Book page'),
-    'base' => 'node_content',
-    'description' => t('<em>Books</em> have a built-in hierarchical navigation. Use for handbooks or tutorials.'),
-    'custom' => 1,
-    'modified' => 1,
-    'locked' => 0,
-  );
-
-  $book_node_type = node_type_set_defaults($book_node_type);
-  node_type_save($book_node_type);
-  node_add_body_field($book_node_type);
-  // Default to not promoted.
-  variable_set('node_options_book', array('status'));
-  // Use this default type for adding content to books.
-  variable_set('book_allowed_types', array('book'));
-  variable_set('book_child_type', 'book');
-}
-
-/**
- * Implements hook_schema().
- */
-function book_schema() {
-  $schema['book'] = array(
-  'description' => 'Stores book outline information. Uniquely connects each node in the outline to a link in {menu_links}',
-    'fields' => array(
-      'mlid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The book page's {menu_links}.mlid.",
-      ),
-      'nid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The book page's {node}.nid.",
-      ),
-      'bid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The book ID is the {book}.nid of the top-level page.",
-      ),
-    ),
-    'primary key' => array('mlid'),
-    'unique keys' => array(
-      'nid' => array('nid'),
-    ),
-    'indexes' => array(
-      'bid' => array('bid'),
-    ),
-  );
-
-  return $schema;
-}
diff --git a/modules/book/book.js b/modules/book/book.js
deleted file mode 100644
index 5b953f1..0000000
--- a/modules/book/book.js
+++ /dev/null
@@ -1,22 +0,0 @@
-
-(function ($) {
-
-Drupal.behaviors.bookFieldsetSummaries = {
-  attach: function (context) {
-    $('fieldset.book-form', context).drupalSetSummary(function (context) {
-      var val = $('.form-item-book-bid select').val();
-
-      if (val === '0') {
-        return Drupal.t('Not in book');
-      }
-      else if (val === 'new') {
-        return Drupal.t('New book');
-      }
-      else {
-        return Drupal.checkPlain($('.form-item-book-bid select :selected').text());
-      }
-    });
-  }
-};
-
-})(jQuery);
diff --git a/modules/book/book.module b/modules/book/book.module
deleted file mode 100644
index beb1721..0000000
--- a/modules/book/book.module
+++ /dev/null
@@ -1,1315 +0,0 @@
-<?php
-
-/**
- * @file
- * Allows users to create and organize related content in an outline.
- */
-
-/**
- * Implements hook_help().
- */
-function book_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#book':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Book module is used for creating structured, multi-page content, such as site resource guides, manuals, and wikis. It allows you to create content that has chapters, sections, subsections, or any similarly-tiered structure. For more information, see the online handbook entry for <a href="@book">Book module</a>.', array('@book' => 'http://drupal.org/handbook/modules/book/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Adding and managing book content') . '</dt>';
-      $output .= '<dd>' . t('You can assign separate permissions for <em>creating</em>, <em>editing</em>, and <em>deleting</em> book content, as well as <em>adding content to books</em>, and <em>creating new books</em>. Users with the <em>Administer book outlines</em> permission can add <em>any</em> type of content to a book by selecting the appropriate book outline while editing the content. They can also view a list of all books, and edit and rearrange section titles on the <a href="@admin-book">Book administration page</a>.', array('@admin-book' => url('admin/content/book'))) . '</dd>';
-      $output .= '<dt>' . t('Book navigation') . '</dt>';
-      $output .= '<dd>' . t("Book pages have a default book-specific navigation block. This navigation block contains links that lead to the previous and next pages in the book, and to the level above the current page in the book's structure. This block can be enabled on the <a href='@admin-block'>Blocks administration page</a>. For book pages to show up in the book navigation, they must be added to a book outline.", array('@admin-block' => url('admin/structure/block'))) . '</dd>';
-      $output .= '<dt>' . t('Collaboration') . '</dt>';
-      $output .= '<dd>' . t('Books can be created collaboratively, as they allow users with appropriate permissions to add pages into existing books, and add those pages to a custom table of contents menu.') . '</dd>';
-      $output .= '<dt>' . t('Printing books') . '</dt>';
-      $output .= '<dd>' . t("Users with the <em>View printer-friendly books</em> permission can select the <em>printer-friendly version</em> link visible at the bottom of a book page's content to generate a printer-friendly display of the page and all of its subsections.") . '</dd>';
-      $output .= '</dl>';
-      return $output;
-    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>';
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function book_theme() {
-  return array(
-    'book_navigation' => array(
-      'variables' => array('book_link' => NULL),
-      'template' => 'book-navigation',
-    ),
-    'book_export_html' => array(
-      'variables' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL),
-      'template' => 'book-export-html',
-    ),
-    'book_admin_table' => array(
-      'render element' => 'form',
-    ),
-    'book_title_link' => array(
-      'variables' => array('link' => NULL),
-    ),
-    'book_all_books_block' => array(
-      'render element' => 'book_menus',
-      'template' => 'book-all-books-block',
-    ),
-    'book_node_export_html' => array(
-      'variables' => array('node' => NULL, 'children' => NULL),
-      'template' => 'book-node-export-html',
-    ),
-  );
-}
-
-/**
- * Implements hook_permission().
- */
-function book_permission() {
-  return array(
-    'administer book outlines' => array(
-      'title' => t('Administer book outlines'),
-    ),
-    'create new books' => array(
-      'title' => t('Create new books'),
-    ),
-    'add content to books' => array(
-      'title' => t('Add content and child pages to books'),
-    ),
-    'access printer-friendly version' => array(
-      'title' => t('View printer-friendly books'),
-      'description' => t('View a book page and all of its sub-pages as a single document for ease of printing. Can be performance heavy.'),
-    ),
-  );
-}
-
-/**
- * Inject links into $node as needed.
- */
-function book_node_view_link($node, $view_mode) {
-  $links = array();
-
-  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']),
-        );
-      }
-
-      if (user_access('access printer-friendly version')) {
-        $links['book_printer'] = array(
-          'title' => t('Printer-friendly version'),
-          'href' => 'book/export/html/' . $node->nid,
-          'attributes' => array('title' => t('Show a printer-friendly version of this book page and its sub-pages.'))
-        );
-      }
-    }
-  }
-
-  if (!empty($links)) {
-    $node->content['links']['book'] = array(
-      '#theme' => 'links__node__book',
-      '#links' => $links,
-      '#attributes' => array('class' => array('links', 'inline')),
-    );
-  }
-}
-
-/**
- * Implements hook_menu().
- */
-function book_menu() {
-  $items['admin/content/book'] = array(
-    'title' => 'Books',
-    'description' => "Manage your site's book outlines.",
-    'page callback' => 'book_admin_overview',
-    'access arguments' => array('administer book outlines'),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'book.admin.inc',
-  );
-  $items['admin/content/book/list'] = array(
-    'title' => 'List',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-  );
-  $items['admin/content/book/settings'] = array(
-    'title' => 'Settings',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('book_admin_settings'),
-    'access arguments' => array('administer site configuration'),
-    'type' => MENU_LOCAL_TASK,
-    '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',
-    'access arguments' => array('access content'),
-    'type' => MENU_SUGGESTED_ITEM,
-    'file' => 'book.pages.inc',
-  );
-  $items['book/export/%/%'] = array(
-    'page callback' => 'book_export',
-    'page arguments' => array(2, 3),
-    'access arguments' => array('access printer-friendly version'),
-    'type' => MENU_CALLBACK,
-    'file' => 'book.pages.inc',
-  );
-  $items['node/%node/outline'] = array(
-    'title' => 'Outline',
-    'page callback' => 'book_outline',
-    'page arguments' => array(1),
-    'access callback' => '_book_outline_access',
-    'access arguments' => array(1),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 2,
-    'file' => 'book.pages.inc',
-  );
-  $items['node/%node/outline/remove'] = array(
-    'title' => 'Remove from outline',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('book_remove_form', 1),
-    'access callback' => '_book_outline_remove_access',
-    'access arguments' => array(1),
-    'file' => 'book.pages.inc',
-  );
-
-  return $items;
-}
-
-/**
- * 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);
-}
-
-/**
- * Menu item access callback - determine if the user can remove nodes from the outline.
- */
-function _book_outline_remove_access($node) {
-  return isset($node->book) && ($node->book['bid'] != $node->nid) && _book_outline_access($node);
-}
-
-/**
- * Implements hook_admin_paths().
- */
-function book_admin_paths() {
-  if (variable_get('node_admin_theme')) {
-    $paths = array(
-      'node/*/outline' => TRUE,
-      'node/*/outline/remove' => TRUE,
-    );
-    return $paths;
-  }
-}
-
-/**
- * Implements hook_entity_info_alter().
- */
-function book_entity_info_alter(&$info) {
-  // Add the 'Print' view mode for nodes.
-  $info['node']['view modes'] += array(
-    'print' => array(
-      'label' => t('Print'),
-      'custom settings' => FALSE,
-    ),
-  );
-}
-
-/**
- * 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 (variable_get('book_block_mode', 'all pages') == '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);
-      }
-    }
-    $book_menus['#theme'] = 'book_all_books_block';
-    $block['content'] = $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('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' => variable_get('book_block_mode', 'all pages'),
-    '#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();
-  variable_set('book_block_mode', $edit['book_block_mode']);
-}
-
-/**
- * Returns HTML for a link to a book title when used as a block title.
- *
- * @param $variables
- *   An associative array containing:
- *   - link: An array containing title, href and options for the link.
- *
- * @ingroup themeable
- */
-function theme_book_title_link($variables) {
-  $link = $variables['link'];
-
-  $link['options']['attributes']['class'] = array('book-title');
-
-  return l($link['title'], $link['href'], $link['options']);
-}
-
-/**
- * Returns an array of all books.
- *
- * This list may be used for generating a list of all the books, or for building
- * the options for a form select.
- */
-function book_get_books() {
-  $all_books = &drupal_static(__FUNCTION__);
-
-  if (!isset($all_books)) {
-    $all_books = array();
-    $nids = db_query("SELECT DISTINCT(bid) FROM {book}")->fetchCol();
-
-    if ($nids) {
-      $query = db_select('book', 'b', array('fetch' => PDO::FETCH_ASSOC));
-      $query->join('node', 'n', 'b.nid = n.nid');
-      $query->join('menu_links', 'ml', 'b.mlid = ml.mlid');
-      $query->addField('n', 'type', 'type');
-      $query->addField('n', 'title', 'title');
-      $query->fields('b');
-      $query->fields('ml');
-      $query->condition('n.nid', $nids, 'IN');
-      $query->condition('n.status', 1);
-      $query->orderBy('ml.weight');
-      $query->orderBy('ml.link_title');
-      $query->addTag('node_access');
-      $result2 = $query->execute();
-      foreach ($result2 as $link) {
-        $link['href'] = $link['link_path'];
-        $link['options'] = unserialize($link['options']);
-        $all_books[$link['bid']] = $link;
-      }
-    }
-  }
-
-  return $all_books;
-}
-
-/**
- * Implements hook_form_BASE_FORM_ID_alter().
- *
- * Adds the book fieldset to the node form.
- *
- * @see book_pick_book_nojs_submit()
- */
-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;
-    }
-  }
-
-  if ($access) {
-    _book_add_form_elements($form, $form_state, $node);
-    // Since the "Book" dropdown can't trigger a form submission when
-    // JavaScript is disabled, add a submit button to do that. book.css hides
-    // this button when JavaScript is enabled.
-    $form['book']['pick-book'] = array(
-      '#type' => 'submit',
-      '#value' => t('Change book (update list of parents)'),
-      '#submit' => array('book_pick_book_nojs_submit'),
-      '#weight' => 20,
-    );
-  }
-}
-
-/**
- * Submit handler to change a node's book.
- *
- * This handler is run when JavaScript is disabled. It triggers the form to
- * rebuild so that the "Parent item" options are changed to reflect the newly
- * selected book. When JavaScript is enabled, the submit button that triggers
- * this handler is hidden, and the "Book" dropdown directly triggers the
- * book_form_update() Ajax callback instead.
- *
- * @see book_form_update()
- */
-function book_pick_book_nojs_submit($form, &$form_state) {
-  $form_state['node']->book = $form_state['values']['book'];
-  $form_state['rebuild'] = TRUE;
-}
-
-/**
- * Build the parent selection form element for the node form or outline tab.
- *
- * This function is also called when generating a new set of options during the
- * Ajax callback, so an array is returned that can be used to replace an existing
- * form element.
- */
-function _book_parent_select($book_link) {
-  if (variable_get('menu_override_parent_selector', FALSE)) {
-    return array();
-  }
-  // Offer a message or a drop-down to choose a different parent page.
-  $form = array(
-    '#type' => 'hidden',
-    '#value' => -1,
-    '#prefix' => '<div id="edit-book-plid-wrapper">',
-    '#suffix' => '</div>',
-  );
-
-  if ($book_link['nid'] === $book_link['bid']) {
-    // This is a book - at the top level.
-    if ($book_link['original_bid'] === $book_link['bid']) {
-      $form['#prefix'] .= '<em>' . t('This is the top-level page in this book.') . '</em>';
-    }
-    else {
-      $form['#prefix'] .= '<em>' . t('This will be the top-level page in this book.') . '</em>';
-    }
-  }
-  elseif (!$book_link['bid']) {
-    $form['#prefix'] .= '<em>' . t('No book selected.') . '</em>';
-  }
-  else {
-    $form = array(
-      '#type' => 'select',
-      '#title' => t('Parent item'),
-      '#default_value' => $book_link['plid'],
-      '#description' => t('The parent page in the book. The maximum depth for a book and all child pages is !maxdepth. Some pages in the selected book may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)),
-      '#options' => book_toc($book_link['bid'], $book_link['parent_depth_limit'], array($book_link['mlid'])),
-      '#attributes' => array('class' => array('book-title-select')),
-      '#prefix' => '<div id="edit-book-plid-wrapper">',
-      '#suffix' => '</div>',
-    );
-  }
-
-  return $form;
-}
-
-/**
- * Build the common elements of the book form for the node and outline forms.
- */
-function _book_add_form_elements(&$form, &$form_state, $node) {
-  // If the form is being processed during the Ajax callback of our book bid
-  // dropdown, then $form_state will hold the value that was selected.
-  if (isset($form_state['values']['book'])) {
-    $node->book = $form_state['values']['book'];
-  }
-
-  $form['book'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Book outline'),
-    '#weight' => 10,
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#group' => 'additional_settings',
-    '#attributes' => array(
-      'class' => array('book-form'),
-    ),
-    '#attached' => array(
-      'js' => array(drupal_get_path('module', 'book') . '/book.js'),
-    ),
-    '#tree' => TRUE,
-    '#attributes' => array('class' => array('book-outline-form')),
-  );
-  foreach (array('menu_name', 'mlid', 'nid', 'router_path', 'has_children', 'options', 'module', 'original_bid', 'parent_depth_limit') as $key) {
-    $form['book'][$key] = array(
-      '#type' => 'value',
-      '#value' => $node->book[$key],
-    );
-  }
-
-  $form['book']['plid'] = _book_parent_select($node->book);
-
-  // @see _book_admin_table_tree(). The weight may be larger than 15.
-  $form['book']['weight'] = array(
-    '#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $node->book['weight'],
-    '#delta' => max(15, abs($node->book['weight'])),
-    '#weight' => 5,
-    '#description' => t('Pages at a given level are ordered first by weight and then by title.'),
-  );
-  $options = array();
-  $nid = isset($node->nid) ? $node->nid : 'new';
-
-  if (isset($node->nid) && ($nid == $node->book['original_bid']) && ($node->book['parent_depth_limit'] == 0)) {
-    // This is the top level node in a maximum depth book and thus cannot be moved.
-    $options[$node->nid] = $node->title;
-  }
-  else {
-    foreach (book_get_books() as $book) {
-      $options[$book['nid']] = $book['title'];
-    }
-  }
-
-  if (user_access('create new books') && ($nid == 'new' || ($nid != $node->book['original_bid']))) {
-    // The node can become a new book, if it is not one already.
-    $options = array($nid => '<' . t('create a new book') . '>') + $options;
-  }
-  if (!$node->book['mlid']) {
-    // The node is not currently in the hierarchy.
-    $options = array(0 => '<' . t('none') . '>') + $options;
-  }
-
-  // Add a drop-down to select the destination book.
-  $form['book']['bid'] = array(
-    '#type' => 'select',
-    '#title' => t('Book'),
-    '#default_value' => $node->book['bid'],
-    '#options' => $options,
-    '#access' => (bool) $options,
-    '#description' => t('Your page will be a part of the selected book.'),
-    '#weight' => -5,
-    '#attributes' => array('class' => array('book-title-select')),
-    '#ajax' => array(
-      'callback' => 'book_form_update',
-      'wrapper' => 'edit-book-plid-wrapper',
-      'effect' => 'fade',
-      'speed' => 'fast',
-    ),
-  );
-}
-
-/**
- * Renders a new parent page select element when the book selection changes.
- *
- * This function is called via Ajax when the selected book is changed on a node
- * or book outline form.
- *
- * @return
- *   The rendered parent page select element.
- */
-function book_form_update($form, $form_state) {
-  return $form['book']['plid'];
-}
-
-/**
- * Common helper function to handles additions and updates to the book outline.
- *
- * Performs all additions and updates to the book outline through node addition,
- * node editing, node deletion, or the outline tab.
- */
-function _book_update_outline($node) {
-  if (empty($node->book['bid'])) {
-    return FALSE;
-  }
-  $new = empty($node->book['mlid']);
-
-  $node->book['link_path'] = 'node/' . $node->nid;
-  $node->book['link_title'] = $node->title;
-  $node->book['parent_mismatch'] = FALSE; // The normal case.
-
-  if ($node->book['bid'] == $node->nid) {
-    $node->book['plid'] = 0;
-    $node->book['menu_name'] = book_menu_name($node->nid);
-  }
-  else {
-    // Check in case the parent is not is this book; the book takes precedence.
-    if (!empty($node->book['plid'])) {
-      $parent = db_query("SELECT * FROM {book} WHERE mlid = :mlid", array(
-        ':mlid' => $node->book['plid'],
-      ))->fetchAssoc();
-    }
-    if (empty($node->book['plid']) || !$parent || $parent['bid'] != $node->book['bid']) {
-      $node->book['plid'] = db_query("SELECT mlid FROM {book} WHERE nid = :nid", array(
-        ':nid' => $node->book['bid'],
-      ))->fetchField();
-      $node->book['parent_mismatch'] = TRUE; // Likely when JS is disabled.
-    }
-  }
-
-  if (menu_link_save($node->book)) {
-    if ($new) {
-      // Insert new.
-      db_insert('book')
-        ->fields(array(
-          'nid' => $node->nid,
-          'mlid' => $node->book['mlid'],
-          'bid' => $node->book['bid'],
-        ))
-        ->execute();
-      // Reset the cache of stored books.
-      drupal_static_reset('book_get_books');
-    }
-    else {
-      if ($node->book['bid'] != db_query("SELECT bid FROM {book} WHERE nid = :nid", array(
-          ':nid' => $node->nid,
-        ))->fetchField()) {
-        // Update the bid for this page and all children.
-        book_update_bid($node->book);
-        // Reset the cache of stored books.
-        drupal_static_reset('book_get_books');
-      }
-    }
-
-    return TRUE;
-  }
-
-  // Failed to save the menu link.
-  return FALSE;
-}
-
-/**
- * Update the bid for a page and its children when it is moved to a new book.
- *
- * @param $book_link
- *   A fully loaded menu link that is part of the book hierarchy.
- */
-function book_update_bid($book_link) {
-  $query = db_select('menu_links');
-  $query->addField('menu_links', 'mlid');
-  for ($i = 1; $i <= MENU_MAX_DEPTH && $book_link["p$i"]; $i++) {
-    $query->condition("p$i", $book_link["p$i"]);
-  }
-  $mlids = $query->execute()->fetchCol();
-
-  if ($mlids) {
-    db_update('book')
-      ->fields(array('bid' => $book_link['bid']))
-      ->condition('mlid', $mlids, 'IN')
-      ->execute();
-  }
-}
-
-/**
- * Get the book menu tree for a page, and return it as a linear array.
- *
- * @param $book_link
- *   A fully loaded menu link that is part of the book hierarchy.
- * @return
- *   A linear array of menu links in the order that the links are shown in the
- *   menu, so the previous and next pages are the elements before and after the
- *   element corresponding to $node. The children of $node (if any) will come
- *   immediately after it in the array, and links will only be fetched as deep
- *   as one level deeper than $book_link.
- */
-function book_get_flat_menu($book_link) {
-  $flat = &drupal_static(__FUNCTION__, array());
-
-  if (!isset($flat[$book_link['mlid']])) {
-    // Call menu_tree_all_data() to take advantage of the menu system's caching.
-    $tree = menu_tree_all_data($book_link['menu_name'], $book_link, $book_link['depth'] + 1);
-    $flat[$book_link['mlid']] = array();
-    _book_flatten_menu($tree, $flat[$book_link['mlid']]);
-  }
-
-  return $flat[$book_link['mlid']];
-}
-
-/**
- * Recursive helper function for book_get_flat_menu().
- */
-function _book_flatten_menu($tree, &$flat) {
-  foreach ($tree as $data) {
-    if (!$data['link']['hidden']) {
-      $flat[$data['link']['mlid']] = $data['link'];
-      if ($data['below']) {
-        _book_flatten_menu($data['below'], $flat);
-      }
-    }
-  }
-}
-
-/**
- * Fetches the menu link for the previous page of the book.
- */
-function book_prev($book_link) {
-  // If the parent is zero, we are at the start of a book.
-  if ($book_link['plid'] == 0) {
-    return NULL;
-  }
-  $flat = book_get_flat_menu($book_link);
-  // Assigning the array to $flat resets the array pointer for use with each().
-  $curr = NULL;
-  do {
-    $prev = $curr;
-    list($key, $curr) = each($flat);
-  } while ($key && $key != $book_link['mlid']);
-
-  if ($key == $book_link['mlid']) {
-    // The previous page in the book may be a child of the previous visible link.
-    if ($prev['depth'] == $book_link['depth'] && $prev['has_children']) {
-      // The subtree will have only one link at the top level - get its data.
-      $tree = book_menu_subtree_data($prev);
-      $data = array_shift($tree);
-      // The link of interest is the last child - iterate to find the deepest one.
-      while ($data['below']) {
-        $data = end($data['below']);
-      }
-
-      return $data['link'];
-    }
-    else {
-      return $prev;
-    }
-  }
-}
-
-/**
- * Fetches the menu link for the next page of the book.
- */
-function book_next($book_link) {
-  $flat = book_get_flat_menu($book_link);
-  // Assigning the array to $flat resets the array pointer for use with each().
-  do {
-    list($key, $curr) = each($flat);
-  }
-  while ($key && $key != $book_link['mlid']);
-
-  if ($key == $book_link['mlid']) {
-    return current($flat);
-  }
-}
-
-/**
- * Format the menu links for the child pages of the current page.
- */
-function book_children($book_link) {
-  $flat = book_get_flat_menu($book_link);
-
-  $children = array();
-
-  if ($book_link['has_children']) {
-    // Walk through the array until we find the current page.
-    do {
-      $link = array_shift($flat);
-    }
-    while ($link && ($link['mlid'] != $book_link['mlid']));
-    // Continue though the array and collect the links whose parent is this page.
-    while (($link = array_shift($flat)) && $link['plid'] == $book_link['mlid']) {
-      $data['link'] = $link;
-      $data['below'] = '';
-      $children[] = $data;
-    }
-  }
-
-  if ($children) {
-    $elements = menu_tree_output($children);
-    return drupal_render($elements);
-  }
-  return '';
-}
-
-/**
- * Generate the corresponding menu name from a book ID.
- */
-function book_menu_name($bid) {
-  return 'book-toc-' . $bid;
-}
-
-/**
- * Implements hook_node_load().
- */
-function book_node_load($nodes, $types) {
-  $result = db_query("SELECT * FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid IN (:nids)", array(':nids' =>  array_keys($nodes)), array('fetch' => PDO::FETCH_ASSOC));
-  foreach ($result as $record) {
-    $nodes[$record['nid']]->book = $record;
-    $nodes[$record['nid']]->book['href'] = $record['link_path'];
-    $nodes[$record['nid']]->book['title'] = $record['link_title'];
-    $nodes[$record['nid']]->book['options'] = unserialize($record['options']);
-  }
-}
-
-/**
- * Implements hook_node_view().
- */
-function book_node_view($node, $view_mode) {
-  if ($view_mode == 'full') {
-    if (!empty($node->book['bid']) && empty($node->in_preview)) {
-      $node->content['book_navigation'] = array(
-        '#markup' => theme('book_navigation', array('book_link' => $node->book)),
-        '#weight' => 100,
-      );
-    }
-  }
-
-  if ($view_mode != 'rss') {
-    book_node_view_link($node, $view_mode);
-  }
-}
-
-/**
- * Implements hook_page_alter().
- *
- * Add the book menu to the list of menus used to build the active trail when
- * viewing a book page.
- */
-function book_page_alter(&$page) {
-  if (($node = menu_get_object()) && !empty($node->book['bid'])) {
-    $active_menus = menu_get_active_menu_names();
-    $active_menus[] = $node->book['menu_name'];
-    menu_set_active_menu_names($active_menus);
-  }
-}
-
-/**
- * Implements hook_node_presave().
- */
-function book_node_presave($node) {
-  // Always save a revision for non-administrators.
-  if (!empty($node->book['bid']) && !user_access('administer nodes')) {
-    $node->revision = 1;
-    // The database schema requires a log message for every revision.
-    if (!isset($node->log)) {
-      $node->log = '';
-    }
-  }
-  // Make sure a new node gets a new menu link.
-  if (empty($node->nid)) {
-    $node->book['mlid'] = NULL;
-  }
-}
-
-/**
- * Implements hook_node_insert().
- */
-function book_node_insert($node) {
-  if (!empty($node->book['bid'])) {
-    if ($node->book['bid'] == 'new') {
-      // New nodes that are their own book.
-      $node->book['bid'] = $node->nid;
-    }
-    $node->book['nid'] = $node->nid;
-    $node->book['menu_name'] = book_menu_name($node->book['bid']);
-    _book_update_outline($node);
-  }
-}
-
-/**
- * Implements hook_node_update().
- */
-function book_node_update($node) {
-  if (!empty($node->book['bid'])) {
-    if ($node->book['bid'] == 'new') {
-      // New nodes that are their own book.
-      $node->book['bid'] = $node->nid;
-    }
-    $node->book['nid'] = $node->nid;
-    $node->book['menu_name'] = book_menu_name($node->book['bid']);
-    _book_update_outline($node);
-  }
-}
-
-/**
- * Implements hook_node_delete().
- */
-function book_node_delete($node) {
-  if (!empty($node->book['bid'])) {
-    if ($node->nid == $node->book['bid']) {
-      // Handle deletion of a top-level post.
-      $result = db_query("SELECT b.nid FROM {menu_links} ml INNER JOIN {book} b on b.mlid = ml.mlid WHERE ml.plid = :plid", array(
-        ':plid' => $node->book['mlid']
-      ));
-      foreach ($result as $child) {
-        $child_node = node_load($child->nid);
-        $child_node->book['bid'] = $child_node->nid;
-        _book_update_outline($child_node);
-      }
-    }
-    menu_link_delete($node->book['mlid']);
-    db_delete('book')
-      ->condition('mlid', $node->book['mlid'])
-      ->execute();
-    drupal_static_reset('book_get_books');
-  }
-}
-
-/**
- * Implements hook_node_prepare().
- */
-function book_node_prepare($node) {
-  // Prepare defaults for the add/edit form.
-  if (empty($node->book) && (user_access('add content to books') || user_access('administer book outlines'))) {
-    $node->book = array();
-
-    if (empty($node->nid) && isset($_GET['parent']) && is_numeric($_GET['parent'])) {
-      // Handle "Add child page" links:
-      $parent = book_link_load($_GET['parent']);
-
-      if ($parent && $parent['access']) {
-        $node->book['bid'] = $parent['bid'];
-        $node->book['plid'] = $parent['mlid'];
-        $node->book['menu_name'] = $parent['menu_name'];
-      }
-    }
-    // Set defaults.
-    $node->book += _book_link_defaults(!empty($node->nid) ? $node->nid : 'new');
-  }
-  else {
-    if (isset($node->book['bid']) && !isset($node->book['original_bid'])) {
-      $node->book['original_bid'] = $node->book['bid'];
-    }
-  }
-  // Find the depth limit for the parent select.
-  if (isset($node->book['bid']) && !isset($node->book['parent_depth_limit'])) {
-    $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
-  }
-}
-
-/**
- * Find the depth limit for items in the parent select.
- */
-function _book_parent_depth_limit($book_link) {
-  return MENU_MAX_DEPTH - 1 - (($book_link['mlid'] && $book_link['has_children']) ? menu_link_children_relative_depth($book_link) : 0);
-}
-
-/**
- * Form altering function for the confirm form for a single node deletion.
- */
-function book_form_node_delete_confirm_alter(&$form, $form_state) {
-  $node = node_load($form['nid']['#value']);
-
-  if (isset($node->book) && $node->book['has_children']) {
-    $form['book_warning'] = array(
-      '#markup' => '<p>' . t('%title is part of a book outline, and has associated child pages. If you proceed with deletion, the child pages will be relocated automatically.', array('%title' => $node->title)) . '</p>',
-      '#weight' => -10,
-    );
-  }
-}
-
-/**
- * Return an array with default values for a book link.
- */
-function _book_link_defaults($nid) {
-  return array('original_bid' => 0, 'menu_name' => '', 'nid' => $nid, 'bid' => 0, 'router_path' => 'node/%', 'plid' => 0, 'mlid' => 0, 'has_children' => 0, 'weight' => 0, 'module' => 'book', 'options' => array());
-}
-
-/**
- * Process variables for book-all-books-block.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $book_menus
- *
- * All non-renderable elements are removed so that the template has full
- * access to the structured data but can also simply iterate over all
- * elements and render them (as in the default template).
- *
- * @see book-navigation.tpl.php
- */
-function template_preprocess_book_all_books_block(&$variables) {
-  // Remove all non-renderable elements.
-  $elements = $variables['book_menus'];
-  $variables['book_menus'] = array();
-  foreach (element_children($elements) as $index) {
-    $variables['book_menus'][$index] = $elements[$index];
-  }
-}
-
-/**
- * Process variables for book-navigation.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $book_link
- *
- * @see book-navigation.tpl.php
- */
-function template_preprocess_book_navigation(&$variables) {
-  $book_link = $variables['book_link'];
-
-  // Provide extra variables for themers. Not needed by default.
-  $variables['book_id'] = $book_link['bid'];
-  $variables['book_title'] = check_plain($book_link['link_title']);
-  $variables['book_url'] = 'node/' . $book_link['bid'];
-  $variables['current_depth'] = $book_link['depth'];
-  $variables['tree'] = '';
-
-  if ($book_link['mlid']) {
-    $variables['tree'] = book_children($book_link);
-
-    if ($prev = book_prev($book_link)) {
-      $prev_href = url($prev['href']);
-      drupal_add_html_head_link(array('rel' => 'prev', 'href' => $prev_href));
-      $variables['prev_url'] = $prev_href;
-      $variables['prev_title'] = check_plain($prev['title']);
-    }
-
-    if ($book_link['plid'] && $parent = book_link_load($book_link['plid'])) {
-      $parent_href = url($parent['href']);
-      drupal_add_html_head_link(array('rel' => 'up', 'href' => $parent_href));
-      $variables['parent_url'] = $parent_href;
-      $variables['parent_title'] = check_plain($parent['title']);
-    }
-
-    if ($next = book_next($book_link)) {
-      $next_href = url($next['href']);
-      drupal_add_html_head_link(array('rel' => 'next', 'href' => $next_href));
-      $variables['next_url'] = $next_href;
-      $variables['next_title'] = check_plain($next['title']);
-    }
-  }
-
-  $variables['has_links'] = FALSE;
-  // Link variables to filter for values and set state of the flag variable.
-  $links = array('prev_url', 'prev_title', 'parent_url', 'parent_title', 'next_url', 'next_title');
-  foreach ($links as $link) {
-    if (isset($variables[$link])) {
-      // Flag when there is a value.
-      $variables['has_links'] = TRUE;
-    }
-    else {
-      // Set empty to prevent notices.
-      $variables[$link] = '';
-    }
-  }
-}
-
-/**
- * Recursively processes and formats menu items for book_toc().
- *
- * This helper function recursively modifies the $toc array for each item in
- * $tree, ignoring items in the exclude array or at a depth greater than the
- * limit.  Truncates titles over thirty characters and appends an indentation
- * string incremented by depth.
- *
- * @param $tree
- *   The data structure of the book's menu tree.  Includes hidden links.
- * @param $indent
- *   A string appended to each menu item title. Increments by '--' per depth
- *   level.
- * @param $toc
- *   Reference to the table of contents array. This is modified in place, so the
- *   function does not have a return value.
- * @param $exclude
- *   Optional array of mlid values. Any link whose mlid is in this array will be
- *   excluded (along with its children).
- * @param $depth_limit
- *   Any link deeper than this value will be excluded (along with its children).
- */
-function _book_toc_recurse($tree, $indent, &$toc, $exclude, $depth_limit) {
-  foreach ($tree as $data) {
-    if ($data['link']['depth'] > $depth_limit) {
-      // Don't iterate through any links on this level.
-      break;
-    }
-
-    if (!in_array($data['link']['mlid'], $exclude)) {
-      $toc[$data['link']['mlid']] = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, TRUE);
-      if ($data['below']) {
-        _book_toc_recurse($data['below'], $indent . '--', $toc, $exclude, $depth_limit);
-      }
-    }
-  }
-}
-
-/**
- * Returns an array of book pages in table of contents order.
- *
- * @param $bid
- *   The ID of the book whose pages are to be listed.
- * @param $depth_limit
- *   Any link deeper than this value will be excluded (along with its children).
- * @param $exclude
- *   Optional array of mlid values. Any link whose mlid is in this array
- *   will be excluded (along with its children).
- * @return
- *   An array of mlid, title pairs for use as options for selecting a book page.
- */
-function book_toc($bid, $depth_limit, $exclude = array()) {
-  $tree = menu_tree_all_data(book_menu_name($bid));
-  $toc = array();
-  _book_toc_recurse($tree, '', $toc, $exclude, $depth_limit);
-
-  return $toc;
-}
-
-/**
- * Process variables for book-export-html.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $title
- * - $contents
- * - $depth
- *
- * @see book-export-html.tpl.php
- */
-function template_preprocess_book_export_html(&$variables) {
-  global $base_url, $language;
-
-  $variables['title'] = check_plain($variables['title']);
-  $variables['base_url'] = $base_url;
-  $variables['language'] = $language;
-  $variables['language_rtl'] = ($language->direction == LANGUAGE_RTL);
-  $variables['head'] = drupal_get_html_head();
-}
-
-/**
- * Traverse the book tree to build printable or exportable output.
- *
- * During the traversal, the $visit_func() callback is applied to each
- * node, and is called recursively for each child of the node (in weight,
- * title order).
- *
- * @param $tree
- *   A subtree of the book menu hierarchy, rooted at the current page.
- * @param $visit_func
- *   A function callback to be called upon visiting a node in the tree.
- * @return
- *   The output generated in visiting each node.
- */
-function book_export_traverse($tree, $visit_func) {
-  $output = '';
-
-  foreach ($tree as $data) {
-    // Note- access checking is already performed when building the tree.
-    if ($node = node_load($data['link']['nid'], FALSE)) {
-      $children = '';
-
-      if ($data['below']) {
-        $children = book_export_traverse($data['below'], $visit_func);
-      }
-
-      if (function_exists($visit_func)) {
-        $output .= call_user_func($visit_func, $node, $children);
-      }
-      else {
-        // Use the default function.
-        $output .= book_node_export($node, $children);
-      }
-    }
-  }
-
-  return $output;
-}
-
-/**
- * Generates printer-friendly HTML for a node.
- *
- * @see book_export_traverse()
- *
- * @param $node
- *   The node that will be output.
- * @param $children
- *   All the rendered child nodes within the current node.
- * @return
- *   The HTML generated for the given node.
- */
-function book_node_export($node, $children = '') {
-  $build = node_view($node, 'print');
-  unset($build['#theme']);
-  // @todo Rendering should happen in the template using render().
-  $node->rendered = drupal_render($build);
-
-  return theme('book_node_export_html', array('node' => $node, 'children' => $children));
-}
-
-/**
- * Process variables for book-node-export-html.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $node
- * - $children
- *
- * @see book-node-export-html.tpl.php
- */
-function template_preprocess_book_node_export_html(&$variables) {
-  $variables['depth'] = $variables['node']->book['depth'];
-  $variables['title'] = check_plain($variables['node']->title);
-  $variables['content'] = $variables['node']->rendered;
-}
-
-/**
- * Determine if a given node type is in the list of types allowed for books.
- */
-function book_type_is_allowed($type) {
-  return in_array($type, variable_get('book_allowed_types', array('book')));
-}
-
-/**
- * Implements hook_node_type_update().
- *
- * Update book module's persistent variables if the machine-readable name of a
- * node type is changed.
- */
-function book_node_type_update($type) {
-  if (!empty($type->old_type) && $type->old_type != $type->type) {
-    // Update the list of node types that are allowed to be added to books.
-    $allowed_types = variable_get('book_allowed_types', array('book'));
-    $key = array_search($type->old_type, $allowed_types);
-
-    if ($key !== FALSE) {
-      $allowed_types[$type->type] = $allowed_types[$key] ? $type->type : 0;
-      unset($allowed_types[$key]);
-      variable_set('book_allowed_types', $allowed_types);
-    }
-
-    // Update the setting for the "Add child page" link.
-    if (variable_get('book_child_type', 'book') == $type->old_type) {
-      variable_set('book_child_type', $type->type);
-    }
-  }
-}
-
-/**
- * Like menu_link_load(), but adds additional data from the {book} table.
- *
- * Do not call when loading a node, since this function may call node_load().
- */
-function book_link_load($mlid) {
-  if ($item = db_query("SELECT * FROM {menu_links} ml INNER JOIN {book} b ON b.mlid = ml.mlid LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = :mlid", array(
-      ':mlid' => $mlid,
-    ))->fetchAssoc()) {
-    _menu_link_translate($item);
-    return $item;
-  }
-
-  return FALSE;
-}
-
-/**
- * Get the data representing a subtree of the book hierarchy.
- *
- * The root of the subtree will be the link passed as a parameter, so the
- * returned tree will contain this item and all its descendents in the menu tree.
- *
- * @param $link
- *   A fully loaded menu link.
- * @return
- *   An subtree of menu links in an array, in the order they should be rendered.
- */
-function book_menu_subtree_data($link) {
-  $tree = &drupal_static(__FUNCTION__, array());
-
-  // Generate a cache ID (cid) specific for this $menu_name and $link.
-  $cid = 'links:' . $link['menu_name'] . ':subtree-cid:' . $link['mlid'];
-
-  if (!isset($tree[$cid])) {
-    $cache = cache_get($cid, 'cache_menu');
-
-    if ($cache && isset($cache->data)) {
-      // If the cache entry exists, it will just be the cid for the actual data.
-      // This avoids duplication of large amounts of data.
-      $cache = cache_get($cache->data, 'cache_menu');
-
-      if ($cache && isset($cache->data)) {
-        $data = $cache->data;
-      }
-    }
-
-    // If the subtree data was not in the cache, $data will be NULL.
-    if (!isset($data)) {
-      $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
-      $query->join('menu_router', 'm', 'm.path = ml.router_path');
-      $query->join('book', 'b', 'ml.mlid = b.mlid');
-      $query->fields('b');
-      $query->fields('m', array('load_functions', 'to_arg_functions', 'access_callback', 'access_arguments', 'page_callback', 'page_arguments', 'delivery_callback', 'title', 'title_callback', 'title_arguments', 'type'));
-      $query->fields('ml');
-      $query->condition('menu_name', $link['menu_name']);
-      for ($i = 1; $i <= MENU_MAX_DEPTH && $link["p$i"]; ++$i) {
-        $query->condition("p$i", $link["p$i"]);
-      }
-      for ($i = 1; $i <= MENU_MAX_DEPTH; ++$i) {
-        $query->orderBy("p$i");
-      }
-      $links = array();
-      foreach ($query->execute() as $item) {
-        $links[] = $item;
-      }
-      $data['tree'] = menu_tree_data($links, array(), $link['depth']);
-      $data['node_links'] = array();
-      menu_tree_collect_node_links($data['tree'], $data['node_links']);
-      // Compute the real cid for book subtree data.
-      $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . hash('sha256', serialize($data));
-      // Cache the data, if it is not already in the cache.
-
-      if (!cache_get($tree_cid, 'cache_menu')) {
-        cache_set($tree_cid, $data, 'cache_menu');
-      }
-      // Cache the cid of the (shared) data using the menu and item-specific cid.
-      cache_set($cid, $tree_cid, 'cache_menu');
-    }
-    // Check access for the current user to each item in the tree.
-    menu_tree_check_access($data['tree'], $data['node_links']);
-    $tree[$cid] = $data['tree'];
-  }
-
-  return $tree[$cid];
-}
diff --git a/modules/book/book.pages.inc b/modules/book/book.pages.inc
deleted file mode 100644
index 1617f00..0000000
--- a/modules/book/book.pages.inc
+++ /dev/null
@@ -1,220 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the book module.
- */
-
-/**
- * Menu callback; prints a listing of all books.
- */
-function book_render() {
-  $book_list = array();
-  foreach (book_get_books() as $book) {
-    $book_list[] = l($book['title'], $book['href'], $book['options']);
-  }
-
-  return theme('item_list', array('items' => $book_list));
-}
-
-/**
- * Menu callback; Generates various representation of a book page and its children.
- *
- * The function delegates the generation of output to helper functions.
- * The function name is derived by prepending 'book_export_' to the
- * given output type. So, e.g., a type of 'html' results in a call to
- * the function book_export_html().
- *
- * @param $type
- *   A string encoding the type of output requested. The following
- *   types are currently supported in book module:
- *
- *   - html: HTML (printer friendly output)
- *
- *   Other types may be supported in contributed modules.
- * @param $nid
- *   An integer representing the node id (nid) of the node to export
- * @return
- *   A string representing the node and its children in the book hierarchy
- *   in a format determined by the $type parameter.
- */
-function book_export($type, $nid) {
-  $type = drupal_strtolower($type);
-
-  $export_function = 'book_export_' . $type;
-
-  if (function_exists($export_function)) {
-    print call_user_func($export_function, $nid);
-  }
-  else {
-    drupal_set_message(t('Unknown export format.'));
-    drupal_not_found();
-  }
-}
-
-/**
- * This function is called by book_export() to generate HTML for export.
- *
- * The given node is /embedded to its absolute depth in a top level
- * section/. For example, a child node with depth 2 in the hierarchy
- * is contained in (otherwise empty) &lt;div&gt; elements
- * corresponding to depth 0 and depth 1. This is intended to support
- * WYSIWYG output - e.g., level 3 sections always look like level 3
- * sections, no matter their depth relative to the node selected to be
- * exported as printer-friendly HTML.
- *
- * @param $nid
- *   An integer representing the node id (nid) of the node to export.
- * @return
- *   A string containing HTML representing the node and its children in
- *   the book hierarchy.
- */
-function book_export_html($nid) {
-  if (user_access('access printer-friendly version')) {
-    $export_data = array();
-    $node = node_load($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();
-    }
-  }
-  else {
-    drupal_access_denied();
-  }
-}
-
-/**
- * Menu callback; show the outline form for a single node.
- */
-function book_outline($node) {
-  drupal_set_title($node->title);
-  return drupal_get_form('book_outline_form', $node);
-}
-
-/**
- * Build the form to handle all book outline operations via the outline tab.
- *
- * @see book_outline_form_submit()
- * @see book_remove_button_submit()
- *
- * @ingroup forms
- */
-function book_outline_form($form, &$form_state, $node) {
-  if (!isset($node->book)) {
-    // The node is not part of any book yet - set default options.
-    $node->book = _book_link_defaults($node->nid);
-  }
-  else {
-    $node->book['original_bid'] = $node->book['bid'];
-  }
-
-  // Find the depth limit for the parent select.
-  if (!isset($node->book['parent_depth_limit'])) {
-    $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
-  }
-  $form['#node'] = $node;
-  $form['#id'] = 'book-outline';
-  _book_add_form_elements($form, $form_state, $node);
-
-  $form['book']['#collapsible'] = FALSE;
-
-  $form['update'] = array(
-    '#type' => 'submit',
-    '#value' => $node->book['original_bid'] ? t('Update book outline') : t('Add to book outline'),
-    '#weight' => 15,
-  );
-
-  $form['remove'] = array(
-    '#type' => 'submit',
-    '#value' => t('Remove from book outline'),
-    '#access' => $node->nid != $node->book['bid'] && $node->book['bid'],
-    '#weight' => 20,
-    '#submit' => array('book_remove_button_submit'),
-  );
-
-  return $form;
-}
-
-/**
- * Button submit function to redirect to removal confirm form.
- *
- * @see book_outline_form()
- */
-function book_remove_button_submit($form, &$form_state) {
-  $form_state['redirect'] = 'node/' . $form['#node']->nid . '/outline/remove';
-}
-
-/**
- * Handles book outline form submissions from the outline tab.
- *
- * @see book_outline_form()
- */
-function book_outline_form_submit($form, &$form_state) {
-  $node = $form['#node'];
-  $form_state['redirect'] = "node/" . $node->nid;
-  $book_link = $form_state['values']['book'];
-  if (!$book_link['bid']) {
-    drupal_set_message(t('No changes were made'));
-
-    return;
-  }
-
-  $book_link['menu_name'] = book_menu_name($book_link['bid']);
-  $node->book = $book_link;
-  if (_book_update_outline($node)) {
-    if ($node->book['parent_mismatch']) {
-      // This will usually only happen when JS is disabled.
-      drupal_set_message(t('The post has been added to the selected book. You may now position it relative to other pages.'));
-      $form_state['redirect'] = "node/" . $node->nid . "/outline";
-    }
-    else {
-      drupal_set_message(t('The book outline has been updated.'));
-    }
-  }
-  else {
-    drupal_set_message(t('There was an error adding the post to the book.'), 'error');
-  }
-}
-
-/**
- * Menu callback; builds a form to confirm removal of a node from the book.
- *
- * @see book_remove_form_submit()
- *
- * @ingroup forms
- */
-function book_remove_form($form, &$form_state, $node) {
-  $form['#node'] = $node;
-  $title = array('%title' => $node->title);
-
-  if ($node->book['has_children']) {
-    $description = t('%title has associated child pages, which will be relocated automatically to maintain their connection to the book. To recreate the hierarchy (as it was before removing this page), %title may be added again using the Outline tab, and each of its former child pages will need to be relocated manually.', $title);
-  }
-  else {
-    $description = t('%title may be added to hierarchy again using the Outline tab.', $title);
-  }
-
-  return confirm_form($form, t('Are you sure you want to remove %title from the book hierarchy?', $title), 'node/' . $node->nid, $description, t('Remove'));
-}
-
-/**
- * Confirm form submit function to remove a node from the book.
- *
- * @see book_remove_form()
- */
-function book_remove_form_submit($form, &$form_state) {
-  $node = $form['#node'];
-  if ($node->nid != $node->book['bid']) {
-    // Only allowed when this is not a book (top-level page).
-    menu_link_delete($node->book['mlid']);
-    db_delete('book')
-      ->condition('nid', $node->nid)
-      ->execute();
-    drupal_set_message(t('The post has been removed from the book.'));
-  }
-  $form_state['redirect'] = 'node/' . $node->nid;
-}
diff --git a/modules/book/book.test b/modules/book/book.test
deleted file mode 100644
index cc61778..0000000
--- a/modules/book/book.test
+++ /dev/null
@@ -1,284 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for book.module.
- */
-
-class BookTestCase extends DrupalWebTestCase {
-  protected $book;
-  // $book_author is a user with permission to create and edit books.
-  protected $book_author;
-  // $web_user is a user with permission to view a book
-  // and access the printer-friendly version.
-  protected $web_user;
-  // $admin_user is a user with permission to create and edit books and to administer blocks.
-  protected $admin_user;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Book functionality',
-      'description' => 'Create a book, add pages, and test book interface.',
-      'group' => 'Book',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('book');
-
-    // Create users.
-    $this->book_author = $this->drupalCreateUser(array('create new books', 'create book content', 'edit own book content', 'add content to books'));
-    $this->web_user = $this->drupalCreateUser(array('access printer-friendly version'));
-    $this->admin_user = $this->drupalCreateUser(array('create new books', 'create book content', 'edit own book content', 'add content to books', 'administer blocks'));
-  }
-
-  /**
-   * Create a new book with a page hierarchy.
-   */
-  function createBook() {
-    // Create new book.
-    $this->drupalLogin($this->book_author);
-
-    $this->book = $this->createBookNode('new');
-    $book = $this->book;
-
-    /*
-     * Add page hierarchy to book.
-     * Book
-     *  |- Node 0
-     *   |- Node 1
-     *   |- Node 2
-     *  |- Node 3
-     *  |- Node 4
-     */
-    $nodes = array();
-    $nodes[] = $this->createBookNode($book->nid); // Node 0.
-    $nodes[] = $this->createBookNode($book->nid, $nodes[0]->book['mlid']); // Node 1.
-    $nodes[] = $this->createBookNode($book->nid, $nodes[0]->book['mlid']); // Node 2.
-    $nodes[] = $this->createBookNode($book->nid); // Node 3.
-    $nodes[] = $this->createBookNode($book->nid); // Node 4.
-
-    $this->drupalLogout();
-
-    return $nodes;
-  }
-
-  /**
-   * Test book functionality through node interfaces.
-   */
-  function testBook() {
-    // Create new book.
-    $nodes = $this->createBook();
-    $book = $this->book;
-
-    $this->drupalLogin($this->web_user);
-
-    // Check that book pages display along with the correct outlines and
-    // previous/next links.
-    $this->checkBookNode($book, array($nodes[0], $nodes[3], $nodes[4]), FALSE, FALSE, $nodes[0], array());
-    $this->checkBookNode($nodes[0], array($nodes[1], $nodes[2]), $book, $book, $nodes[1], array($book));
-    $this->checkBookNode($nodes[1], NULL, $nodes[0], $nodes[0], $nodes[2], array($book, $nodes[0]));
-    $this->checkBookNode($nodes[2], NULL, $nodes[1], $nodes[0], $nodes[3], array($book, $nodes[0]));
-    $this->checkBookNode($nodes[3], NULL, $nodes[2], $book, $nodes[4], array($book));
-    $this->checkBookNode($nodes[4], NULL, $nodes[3], $book, FALSE, array($book));
-
-    $this->drupalLogout();
-
-    // Create a second book, and move an existing book page into it.
-    $this->drupalLogin($this->book_author);
-    $other_book = $this->createBookNode('new');
-    $node = $this->createBookNode($book->nid);
-    $edit = array('book[bid]' => $other_book->nid);
-    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
-
-    $this->drupalLogout();
-    $this->drupalLogin($this->web_user);
-
-    // Check that the nodes in the second book are displayed correctly.
-    // First we must set $this->book to the second book, so that the
-    // correct regex will be generated for testing the outline.
-    $this->book = $other_book;
-    $this->checkBookNode($other_book, array($node), FALSE, FALSE, $node, array());
-    $this->checkBookNode($node, NULL, $other_book, $other_book, FALSE, array($other_book));
-  }
-
-  /**
-   * Check the outline of sub-pages; previous, up, and next; and printer friendly version.
-   *
-   * @param $node
-   *   Node to check.
-   * @param $nodes
-   *   Nodes that should be in outline.
-   * @param $previous
-   *   Previous link node.
-   * @param $up
-   *   Up link node.
-   * @param $next
-   *   Next link node.
-   * @param $breadcrumb
-   *   The nodes that should be displayed in the breadcrumb.
-   */
-  function checkBookNode($node, $nodes, $previous = FALSE, $up = FALSE, $next = FALSE, array $breadcrumb) {
-    // $number does not use drupal_static as it should not be reset
-    // since it uniquely identifies each call to checkBookNode().
-    static $number = 0;
-    $this->drupalGet('node/' . $node->nid);
-
-    // Check outline structure.
-    if ($nodes !== NULL) {
-      $this->assertPattern($this->generateOutlinePattern($nodes), t('Node ' . $number . ' outline confirmed.'));
-    }
-    else {
-      $this->pass(t('Node ' . $number . ' doesn\'t have outline.'));
-    }
-
-    // Check previous, up, and next links.
-    if ($previous) {
-      $this->assertRaw(l('‹ ' . $previous->title, 'node/' . $previous->nid, array('attributes' => array('class' => array('page-previous'), 'title' => t('Go to previous page')))), t('Previous page link found.'));
-    }
-
-    if ($up) {
-      $this->assertRaw(l('up', 'node/' . $up->nid, array('attributes' => array('class' => array('page-up'), 'title' => t('Go to parent page')))), t('Up page link found.'));
-    }
-
-    if ($next) {
-      $this->assertRaw(l($next->title . ' ›', 'node/' . $next->nid, array('attributes' => array('class' => array('page-next'), 'title' => t('Go to next page')))), t('Next page link found.'));
-    }
-
-    // Compute the expected breadcrumb.
-    $expected_breadcrumb = array();
-    $expected_breadcrumb[] = url('');
-    foreach ($breadcrumb as $a_node) {
-      $expected_breadcrumb[] = url('node/' . $a_node->nid);
-    }
-
-    // Fetch links in the current breadcrumb.
-    $links = $this->xpath('//div[@class="breadcrumb"]/a');
-    $got_breadcrumb = array();
-    foreach ($links as $link) {
-      $got_breadcrumb[] = (string) $link['href'];
-    }
-
-    // Compare expected and got breadcrumbs.
-    $this->assertIdentical($expected_breadcrumb, $got_breadcrumb, t('The breadcrumb is correctly displayed on the page.'));
-
-    // Check printer friendly version.
-    $this->drupalGet('book/export/html/' . $node->nid);
-    $this->assertText($node->title, t('Printer friendly title found.'));
-    $this->assertRaw(check_markup($node->body[LANGUAGE_NONE][0]['value'], $node->body[LANGUAGE_NONE][0]['format']), t('Printer friendly body found.'));
-
-    $number++;
-  }
-
-  /**
-   * Create a regular expression to check for the sub-nodes in the outline.
-   *
-   * @param array $nodes Nodes to check in outline.
-   */
-  function generateOutlinePattern($nodes) {
-    $outline = '';
-    foreach ($nodes as $node) {
-      $outline .= '(node\/' . $node->nid . ')(.*?)(' . $node->title . ')(.*?)';
-    }
-
-    return '/<div id="book-navigation-' . $this->book->nid . '"(.*?)<ul(.*?)' . $outline . '<\/ul>/s';
-  }
-
-  /**
-   * Create book node.
-   *
-   * @param integer $book_nid Book node id or set to 'new' to create new book.
-   * @param integer $parent Parent book reference id.
-   */
-  function createBookNode($book_nid, $parent = NULL) {
-    // $number does not use drupal_static as it should not be reset
-    // since it uniquely identifies each call to createBookNode().
-    static $number = 0; // Used to ensure that when sorted nodes stay in same order.
-
-    $edit = array();
-    $langcode = LANGUAGE_NONE;
-    $edit["title"] = $number . ' - SimpleTest test node ' . $this->randomName(10);
-    $edit["body[$langcode][0][value]"] = 'SimpleTest test body ' . $this->randomName(32) . ' ' . $this->randomName(32);
-    $edit['book[bid]'] = $book_nid;
-
-    if ($parent !== NULL) {
-      $this->drupalPost('node/add/book', $edit, t('Change book (update list of parents)'));
-
-      $edit['book[plid]'] = $parent;
-      $this->drupalPost(NULL, $edit, t('Save'));
-    }
-    else {
-      $this->drupalPost('node/add/book', $edit, t('Save'));
-    }
-
-    // Check to make sure the book node was created.
-    $node = $this->drupalGetNodeByTitle($edit['title']);
-    $this->assertNotNull(($node === FALSE ? NULL : $node), t('Book node found in database.'));
-    $number++;
-
-    return $node;
-  }
-
-  /**
-   * Tests book export ("printer-friendly version") functionality.
-   */
-  function testBookExport() {
-    // Create a book.
-    $nodes = $this->createBook();
-
-    // Login as web user and view printer-friendly version.
-    $this->drupalLogin($this->web_user);
-    $this->drupalGet('node/' . $this->book->nid);
-    $this->clickLink(t('Printer-friendly version'));
-
-    // Make sure each part of the book is there.
-    foreach ($nodes as $node) {
-      $this->assertText($node->title, t('Node title found in printer friendly version.'));
-      $this->assertRaw(check_markup($node->body[LANGUAGE_NONE][0]['value'], $node->body[LANGUAGE_NONE][0]['format']), t('Node body found in printer friendly version.'));
-    }
-
-    // Make sure we can't export an unsupported format.
-    $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();
-
-    // Load the book and verify there is no printer-friendly version link.
-    $this->drupalGet('node/' . $this->book->nid);
-    $this->assertNoLink(t('Printer-friendly version'), t('Anonymous user is not shown link to printer-friendly version.'));
-
-    // Try getting the URL directly, and verify it fails.
-    $this->drupalGet('book/export/html/' . $this->book->nid);
-    $this->assertResponse('403', t('Anonymous user properly forbidden.'));
-  }
-
-  /**
-   * Tests the functionality of the book navigation block.
-   */
-  function testBookNavigationBlock() {
-    $this->drupalLogin($this->admin_user);
-
-    // Set block title to confirm that the interface is available.
-    $block_title = $this->randomName(16);
-    $this->drupalPost('admin/structure/block/manage/book/navigation/configure', array('title' => $block_title), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
-
-    // Set the block to a region to confirm block is available.
-    $edit = array();
-    $edit['blocks[book_navigation][region]'] = 'footer';
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.'));
-
-    // Test correct display of the block.
-    $nodes = $this->createBook();
-    $this->drupalGet('<front>');
-    $this->assertText($block_title, t('Book navigation block is displayed.'));
-    $this->assertText($this->book->title, t('Link to book root (@title) is displayed.', array('@title' => $nodes[0]->title)));
-    $this->assertNoText($nodes[0]->title, t('No links to individual book pages are displayed.'));
-  }
-}
diff --git a/modules/color/color-rtl.css b/modules/color/color-rtl.css
deleted file mode 100644
index bfbcd49..0000000
--- a/modules/color/color-rtl.css
+++ /dev/null
@@ -1,44 +0,0 @@
-
-#placeholder {
-  left: 0;
-  right: auto;
-}
-
-/* Palette */
-.color-form .form-item {
-  padding-left: 0;
-  padding-right: 1em;
-}
-.color-form label {
-  float: right;
-  clear: right;
-}
-.color-form .form-text,
-.color-form .form-select {
-  float: right;
-}
-.color-form .form-text {
-  margin-right: 0;
-  margin-left: 5px;
-}
-#palette .hook {
-  float: right;
-}
-#palette .down,
-#palette .up,
-#palette .both {
-  background: url(images/hook-rtl.png) no-repeat 0 0;
-}
-#palette .up {
-  background-position: 0 -27px;
-}
-#palette .both {
-  background-position: 0 -54px;
-}
-#palette .lock {
-  float: right;
-  right: -10px;
-}
-html.js #preview {
-  float: right;
-}
diff --git a/modules/color/color.css b/modules/color/color.css
deleted file mode 100644
index e513dad..0000000
--- a/modules/color/color.css
+++ /dev/null
@@ -1,81 +0,0 @@
-
-/* Farbtastic placement */
-.color-form {
-  max-width: 50em;
-  position: relative;
-}
-#placeholder {
-  position: absolute;
-  top: 0;
-  right: 0; /* LTR */
-}
-
-/* Palette */
-.color-form .form-item {
-  height: 2em;
-  line-height: 2em;
-  padding-left: 1em; /* LTR */
-  margin: 0.5em 0;
-}
-.color-form label {
-  float: left; /* LTR */
-  clear: left; /* LTR */
-  width: 10em;
-}
-.color-form .form-text,
-.color-form .form-select {
-  float: left; /* LTR */
-}
-.color-form .form-text {
-  text-align: center;
-  margin-right: 5px; /* LTR */
-  cursor: pointer;
-}
-
-#palette .hook {
-  float: left; /* LTR */
-  margin-top: 3px;
-  width: 16px;
-  height: 16px;
-}
-#palette .down,
-#palette .up,
-#palette .both {
-  background: url(images/hook.png) no-repeat 100% 0; /* LTR */
-}
-#palette .up {
-  background-position: 100% -27px; /* LTR */
-}
-#palette .both {
-  background-position: 100% -54px; /* LTR */
-}
-
-#palette .lock {
-  float: left; /* LTR */
-  position: relative;
-  top: -1.4em;
-  left: -10px; /* LTR */
-  width: 20px;
-  height: 25px;
-  background: url(images/lock.png) no-repeat 50% 2px;
-  cursor: pointer;
-}
-#palette .unlocked {
-  background-position: 50% -22px;
-}
-#palette .form-item {
-  width: 20em;
-}
-#palette .item-selected {
-  background: #eee;
-}
-
-/* Preview */
-#preview {
-  display: none;
-}
-html.js #preview {
-  display: block;
-  position: relative;
-  float: left; /* LTR */
-}
diff --git a/modules/color/color.info b/modules/color/color.info
deleted file mode 100644
index c25e123..0000000
--- a/modules/color/color.info
+++ /dev/null
@@ -1,6 +0,0 @@
-name = Color
-description = Allows administrators to change the color scheme of compatible themes.
-package = Core
-version = VERSION
-core = 8.x
-files[] = color.test
diff --git a/modules/color/color.install b/modules/color/color.install
deleted file mode 100644
index a1879f9..0000000
--- a/modules/color/color.install
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the color module.
- */
-
-/**
- * Implements hook_requirements().
- */
-function color_requirements($phase) {
-  $requirements = array();
-
-  if ($phase == 'runtime') {
-    // Check for the PHP GD library.
-    if (function_exists('imagegd2')) {
-      $info = gd_info();
-      $requirements['color_gd'] = array(
-        'value' => $info['GD Version'],
-      );
-
-      // Check for PNG support.
-      if (function_exists('imagecreatefrompng')) {
-        $requirements['color_gd']['severity'] = REQUIREMENT_OK;
-      }
-      else {
-        $requirements['color_gd']['severity'] = REQUIREMENT_WARNING;
-        $requirements['color_gd']['description'] = t('The GD library for PHP is enabled, but was compiled without PNG support. Check the <a href="@url">PHP image documentation</a> for information on how to correct this.', array('@url' => 'http://www.php.net/manual/ref.image.php'));
-      }
-    }
-    else {
-      $requirements['color_gd'] = array(
-        'value' => t('Not installed'),
-        'severity' => REQUIREMENT_ERROR,
-        'description' => t('The GD library for PHP is missing or outdated. Check the <a href="@url">PHP image documentation</a> for information on how to correct this.', array('@url' => 'http://www.php.net/manual/book.image.php')),
-      );
-    }
-    $requirements['color_gd']['title'] = t('GD library PNG support');
-  }
-
-  return $requirements;
-}
diff --git a/modules/color/color.js b/modules/color/color.js
deleted file mode 100644
index 43099ad..0000000
--- a/modules/color/color.js
+++ /dev/null
@@ -1,243 +0,0 @@
-(function ($) {
-
-Drupal.behaviors.color = {
-  attach: function (context, settings) {
-    var i, j, colors, field_name;
-    // This behavior attaches by ID, so is only valid once on a page.
-    var form = $('#system-theme-settings .color-form', context).once('color');
-    if (form.length == 0) {
-      return;
-    }
-    var inputs = [];
-    var hooks = [];
-    var locks = [];
-    var focused = null;
-
-    // Add Farbtastic.
-    $(form).prepend('<div id="placeholder"></div>').addClass('color-processed');
-    var farb = $.farbtastic('#placeholder');
-
-    // Decode reference colors to HSL.
-    var reference = settings.color.reference;
-    for (i in reference) {
-      reference[i] = farb.RGBToHSL(farb.unpack(reference[i]));
-    }
-
-    // Build a preview.
-    var height = [];
-    var width = [];
-    // Loop through all defined gradients.
-    for (i in settings.gradients) {
-      // Add element to display the gradient.
-      $('#preview').once('color').append('<div id="gradient-' + i + '"></div>');
-      var gradient = $('#preview #gradient-' + i);
-      // Add height of current gradient to the list (divided by 10).
-      height.push(parseInt(gradient.css('height'), 10) / 10);
-      // Add width of current gradient to the list (divided by 10).
-      width.push(parseInt(gradient.css('width'), 10) / 10);
-      // Add rows (or columns for horizontal gradients).
-      // Each gradient line should have a height (or width for horizontal
-      // gradients) of 10px (because we divided the height/width by 10 above).
-      for (j = 0; j < (settings.gradients[i]['direction'] == 'vertical' ? height[i] : width[i]); ++j) {
-        gradient.append('<div class="gradient-line"></div>');
-      }
-    }
-
-    // Fix preview background in IE6.
-    if (navigator.appVersion.match(/MSIE [0-6]\./)) {
-      var e = $('#preview #img')[0];
-      var image = e.currentStyle.backgroundImage;
-      e.style.backgroundImage = 'none';
-      e.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image.substring(5, image.length - 2) + "')";
-    }
-
-    // Set up colorScheme selector.
-    $('#edit-scheme', form).change(function () {
-      var schemes = settings.color.schemes, colorScheme = this.options[this.selectedIndex].value;
-      if (colorScheme != '' && schemes[colorScheme]) {
-        // Get colors of active scheme.
-        colors = schemes[colorScheme];
-        for (field_name in colors) {
-          callback($('#edit-palette-' + field_name), colors[field_name], false, true);
-        }
-        preview();
-      }
-    });
-
-    /**
-     * Render the preview.
-     */
-    function preview() {
-      Drupal.color.callback(context, settings, form, farb, height, width);
-    }
-
-    /**
-     * Shift a given color, using a reference pair (ref in HSL).
-     *
-     * This algorithm ensures relative ordering on the saturation and luminance
-     * axes is preserved, and performs a simple hue shift.
-     *
-     * It is also symmetrical. If: shift_color(c, a, b) == d,
-     *                        then shift_color(d, b, a) == c.
-     */
-    function shift_color(given, ref1, ref2) {
-      // Convert to HSL.
-      given = farb.RGBToHSL(farb.unpack(given));
-
-      // Hue: apply delta.
-      given[0] += ref2[0] - ref1[0];
-
-      // Saturation: interpolate.
-      if (ref1[1] == 0 || ref2[1] == 0) {
-        given[1] = ref2[1];
-      }
-      else {
-        var d = ref1[1] / ref2[1];
-        if (d > 1) {
-          given[1] /= d;
-        }
-        else {
-          given[1] = 1 - (1 - given[1]) * d;
-        }
-      }
-
-      // Luminance: interpolate.
-      if (ref1[2] == 0 || ref2[2] == 0) {
-        given[2] = ref2[2];
-      }
-      else {
-        var d = ref1[2] / ref2[2];
-        if (d > 1) {
-          given[2] /= d;
-        }
-        else {
-          given[2] = 1 - (1 - given[2]) * d;
-        }
-      }
-
-      return farb.pack(farb.HSLToRGB(given));
-    }
-
-    /**
-     * Callback for Farbtastic when a new color is chosen.
-     */
-    function callback(input, color, propagate, colorScheme) {
-      var matched;
-      // Set background/foreground colors.
-      $(input).css({
-        backgroundColor: color,
-        'color': farb.RGBToHSL(farb.unpack(color))[2] > 0.5 ? '#000' : '#fff'
-      });
-
-      // Change input value.
-      if ($(input).val() && $(input).val() != color) {
-        $(input).val(color);
-
-        // Update locked values.
-        if (propagate) {
-          i = input.i;
-          for (j = i + 1; ; ++j) {
-            if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break;
-            matched = shift_color(color, reference[input.key], reference[inputs[j].key]);
-            callback(inputs[j], matched, false);
-          }
-          for (j = i - 1; ; --j) {
-            if (!locks[j] || $(locks[j]).is('.unlocked')) break;
-            matched = shift_color(color, reference[input.key], reference[inputs[j].key]);
-            callback(inputs[j], matched, false);
-          }
-
-          // Update preview.
-          preview();
-        }
-
-        // Reset colorScheme selector.
-        if (!colorScheme) {
-          resetScheme();
-        }
-      }
-    }
-
-    /**
-     * Reset the color scheme selector.
-     */
-    function resetScheme() {
-      $('#edit-scheme', form).each(function () {
-        this.selectedIndex = this.options.length - 1;
-      });
-    }
-
-    // Focus the Farbtastic on a particular field.
-    function focus() {
-      var input = this;
-      // Remove old bindings.
-      focused && $(focused).unbind('keyup', farb.updateValue)
-          .unbind('keyup', preview).unbind('keyup', resetScheme)
-          .parent().removeClass('item-selected');
-
-      // Add new bindings.
-      focused = this;
-      farb.linkTo(function (color) { callback(input, color, true, false); });
-      farb.setColor(this.value);
-      $(focused).keyup(farb.updateValue).keyup(preview).keyup(resetScheme)
-        .parent().addClass('item-selected');
-    }
-
-    // Initialize color fields.
-    $('#palette input.form-text', form)
-    .each(function () {
-      // Extract palette field name
-      this.key = this.id.substring(13);
-
-      // Link to color picker temporarily to initialize.
-      farb.linkTo(function () {}).setColor('#000').linkTo(this);
-
-      // Add lock.
-      var i = inputs.length;
-      if (inputs.length) {
-        var lock = $('<div class="lock"></div>').toggle(
-          function () {
-            $(this).addClass('unlocked');
-            $(hooks[i - 1]).attr('class',
-              locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook up' : 'hook'
-            );
-            $(hooks[i]).attr('class',
-              locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook down' : 'hook'
-            );
-          },
-          function () {
-            $(this).removeClass('unlocked');
-            $(hooks[i - 1]).attr('class',
-              locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook both' : 'hook down'
-            );
-            $(hooks[i]).attr('class',
-              locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook both' : 'hook up'
-            );
-          }
-        );
-        $(this).after(lock);
-        locks.push(lock);
-      };
-
-      // Add hook.
-      var hook = $('<div class="hook"></div>');
-      $(this).after(hook);
-      hooks.push(hook);
-
-      $(this).parent().find('.lock').click();
-      this.i = i;
-      inputs.push(this);
-    })
-    .focus(focus);
-
-    $('#palette label', form);
-
-    // Focus first color.
-    focus.call(inputs[0]);
-
-    // Render preview.
-    preview();
-  }
-};
-
-})(jQuery);
diff --git a/modules/color/color.module b/modules/color/color.module
deleted file mode 100644
index 09eb82b..0000000
--- a/modules/color/color.module
+++ /dev/null
@@ -1,740 +0,0 @@
-<?php
-
-/**
- * Implements hook_help().
- */
-function color_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#color':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Color module allows users with the <em>Administer site configuration</em> permission to quickly and easily change the color scheme of themes that have been built to be compatible with it. For more information, see the online handbook entry for <a href="@color">Color module</a>.', array('@color' => 'http://drupal.org/handbook/modules/color')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Changing colors') . '</dt>';
-      $output .= '<dd>' . t("Using the Color module allows you to easily change the color of links, backgrounds, text, and other theme elements. To change the color settings for a compatible theme, select the <em>Settings</em> link for your theme on the <a href='@configure'>Themes administration page</a>. If you don't see a color picker on that page, then your theme is not compatible with the color module. If you are sure that the theme does indeed support the color module, but the color picker does not appear, then <a href='@troubleshoot'>follow these troubleshooting procedures</a>.", array('@configure' => url('admin/appearance'), '@troubleshoot' => 'http://drupal.org/node/109457')) . '</dd>';
-      $output .= '<dd>' . t("The Color module saves a modified copy of the theme's specified stylesheets in the files directory. This means that if you make any manual changes to your theme's stylesheet, <em>you must save your color settings again, even if they haven't changed</em>. This step is required because the module stylesheets (in the files directory) need to be recreated to include your changes.") . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function color_theme() {
-  return array(
-    'color_scheme_form' => array(
-      'render element' => 'form',
-    ),
-  );
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function color_form_system_theme_settings_alter(&$form, &$form_state) {
-  if (isset($form_state['build_info']['args'][0]) && ($theme = $form_state['build_info']['args'][0]) && color_get_info($theme) && function_exists('gd_info')) {
-    $form['color'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Color scheme'),
-      '#weight' => -1,
-      '#attributes' => array('id' => 'color_scheme_form'),
-      '#theme' => 'color_scheme_form',
-    );
-    $form['color'] += color_scheme_form($form, $form_state, $theme);
-    $form['#validate'][] = 'color_scheme_form_validate';
-    $form['#submit'][] = 'color_scheme_form_submit';
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function color_form_system_themes_alter(&$form, &$form_state) {
-  _color_theme_select_form_alter($form, $form_state);
-}
-
-/**
- * Helper for hook_form_FORM_ID_alter() implementations.
- */
-function _color_theme_select_form_alter(&$form, &$form_state) {
-  // Use the generated screenshot in the theme list.
-  $themes = list_themes();
-  foreach (element_children($form) as $theme) {
-    if ($screenshot = variable_get('color_' . $theme . '_screenshot')) {
-      if (isset($form[$theme]['screenshot'])) {
-        $form[$theme]['screenshot']['#markup'] = theme('image', array('path' => $screenshot, 'title' => '', 'attributes' => array('class' => array('screenshot'))));
-      }
-    }
-  }
-}
-
-/**
- * Callback for the theme to alter the resources used.
- */
-function _color_html_alter(&$vars) {
-  global $theme_key;
-  $themes = list_themes();
-
-  // Override stylesheets.
-  $color_paths = variable_get('color_' . $theme_key . '_stylesheets', array());
-  if (!empty($color_paths)) {
-
-    foreach ($themes[$theme_key]->stylesheets['all'] as $base_filename => $old_path) {
-      // Loop over the path array with recolored CSS files to find matching
-      // paths which could replace the non-recolored paths.
-      foreach ($color_paths as $color_path) {
-        // Color module currently requires unique file names to be used,
-        // which allows us to compare different file paths.
-        if (basename($old_path) == basename($color_path)) {
-          // Replace the path to the new css file.
-          // This keeps the order of the stylesheets intact.
-          $vars['css'][$old_path]['data'] = $color_path;
-        }
-      }
-    }
-
-    $vars['styles'] = drupal_get_css($vars['css']);
-  }
-}
-
-/**
- * Callback for the theme to alter the resources used.
- */
-function _color_page_alter(&$vars) {
-  global $theme_key;
-
-  // Override logo.
-  $logo = variable_get('color_' . $theme_key . '_logo');
-  if ($logo && $vars['logo'] && preg_match('!' . $theme_key . '/logo.png$!', $vars['logo'])) {
-    $vars['logo'] = file_create_url($logo);
-  }
-}
-
-/**
- * Retrieve the color.module info for a particular theme.
- */
-function color_get_info($theme) {
-  static $theme_info = array();
-
-  if (isset($theme_info[$theme])) {
-    return $theme_info[$theme];
-  }
-
-  $path = drupal_get_path('theme', $theme);
-  $file = DRUPAL_ROOT . '/' . $path . '/color/color.inc';
-  if ($path && file_exists($file)) {
-    include $file;
-    $theme_info[$theme] = $info;
-    return $info;
-  }
-}
-
-/**
- * Helper function to retrieve the color palette for a particular theme.
- */
-function color_get_palette($theme, $default = FALSE) {
-  // Fetch and expand default palette.
-  $info = color_get_info($theme);
-  $palette = $info['schemes']['default']['colors'];
-
-  // Load variable.
-  return $default ? $palette : variable_get('color_' . $theme . '_palette', $palette);
-}
-
-/**
- * Form callback. Returns the configuration form.
- */
-function color_scheme_form($complete_form, &$form_state, $theme) {
-  $base = drupal_get_path('module', 'color');
-  $info = color_get_info($theme);
-
-  $info['schemes'][''] = array('title' => t('Custom'), 'colors' => array());
-  $color_sets = array();
-  $schemes = array();
-  foreach ($info['schemes'] as $key => $scheme) {
-    $color_sets[$key] = $scheme['title'];
-    $schemes[$key] = $scheme['colors'];
-    $schemes[$key] += $info['schemes']['default']['colors'];
-  }
-
-  // See if we're using a predefined scheme.
-  // Note: we use the original theme when the default scheme is chosen.
-  $current_scheme = variable_get('color_' . $theme . '_palette', array());
-  foreach ($schemes as $key => $scheme) {
-    if ($current_scheme == $scheme) {
-      $scheme_name = $key;
-      break;
-    }
-  }
-  if (empty($scheme_name)) {
-    if (empty($current_scheme)) {
-      $scheme_name = 'default';
-    }
-    else {
-      $scheme_name = '';
-    }
-  }
-
-  // Add scheme selector.
-  $form['scheme'] = array(
-    '#type' => 'select',
-    '#title' => t('Color set'),
-    '#options' => $color_sets,
-    '#default_value' => $scheme_name,
-    '#attached' => array(
-      // Add Farbtastic color picker.
-      'library' => array(
-        array('system', 'farbtastic'),
-      ),
-      // Add custom CSS.
-      'css' => array(
-        $base . '/color.css' => array(),
-      ),
-      // Add custom JavaScript.
-      'js' => array(
-        $base . '/color.js',
-        array(
-          'data' => array(
-            'color' => array(
-              'reference' => color_get_palette($theme, TRUE),
-              'schemes' => $schemes,
-            ),
-            'gradients' => $info['gradients'],
-          ),
-          'type' => 'setting',
-        ),
-      ),
-    ),
-  );
-
-  // Add palette fields.
-  $palette = color_get_palette($theme);
-  $names = $info['fields'];
-  $form['palette']['#tree'] = TRUE;
-  foreach ($palette as $name => $value) {
-    if (isset($names[$name])) {
-      $form['palette'][$name] = array(
-        '#type' => 'textfield',
-        '#title' => check_plain($names[$name]),
-        '#default_value' => $value,
-        '#size' => 8,
-      );
-    }
-  }
-  $form['theme'] = array('#type' => 'value', '#value' => $theme);
-  $form['info'] = array('#type' => 'value', '#value' => $info);
-
-  return $form;
-}
-
-/**
- * Returns HTML for a theme's color form.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_color_scheme_form($variables) {
-  $form = $variables['form'];
-
-  $theme = $form['theme']['#value'];
-  $info = $form['info']['#value'];
-  $path = drupal_get_path('theme', $theme) . '/';
-  drupal_add_css($path . $info['preview_css']);
-  
-  $preview_js_path = isset($info['preview_js']) ? $path . $info['preview_js'] : drupal_get_path('module', 'color') . '/' . 'preview.js';
-  // Add the JS at a weight below color.js.
-  drupal_add_js($preview_js_path, array('weight' => -1));
-    
-  $output  = '';
-  $output .= '<div class="color-form clearfix">';
-  // Color schemes
-  $output .= drupal_render($form['scheme']);
-  // Palette
-  $output .= '<div id="palette" class="clearfix">';
-  foreach (element_children($form['palette']) as $name) {
-    $output .= drupal_render($form['palette'][$name]);
-  }
-  $output .= '</div>';
-  // Preview
-  $output .= drupal_render_children($form);
-  $output .= '<h2>' . t('Preview') . '</h2>';
-  // Attempt to load preview HTML if the theme provides it.
-  $preview_html_path = DRUPAL_ROOT . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html');
-  $output .= file_get_contents($preview_html_path);
-  // Close the wrapper div.
-  $output .= '</div>';
-
-  return $output;
-}
-
-/**
- * Validation handler for color change form.
- */
-function color_scheme_form_validate($form, &$form_state) {
-  // Only accept hexadecimal CSS color strings to avoid XSS upon use.
-  foreach ($form_state['values']['palette'] as $key => $color) {
-    if (!preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color)) {
-      form_set_error('palette][' . $key, t('You must enter a valid hexadecimal color value for %name.', array('%name' => $form['color']['palette'][$key]['#title'])));
-    }
-  }
-}
-
-/**
- * Submit handler for color change form.
- */
-function color_scheme_form_submit($form, &$form_state) {
-  // Get theme coloring info.
-  if (!isset($form_state['values']['info'])) {
-    return;
-  }
-  $theme = $form_state['values']['theme'];
-  $info = $form_state['values']['info'];
-
-  // Resolve palette.
-  $palette = $form_state['values']['palette'];
-  if ($form_state['values']['scheme'] != '') {
-    foreach ($palette as $key => $color) {
-      if (isset($info['schemes'][$form_state['values']['scheme']]['colors'][$key])) {
-        $palette[$key] = $info['schemes'][$form_state['values']['scheme']]['colors'][$key];
-      }
-    }
-    $palette += $info['schemes']['default']['colors'];
-  }
-
-  // Make sure enough memory is available, if PHP's memory limit is compiled in.
-  if (function_exists('memory_get_usage')) {
-    // Fetch source image dimensions.
-    $source = drupal_get_path('theme', $theme) . '/' . $info['base_image'];
-    list($width, $height) = getimagesize($source);
-
-    // We need at least a copy of the source and a target buffer of the same
-    // size (both at 32bpp).
-    $required = $width * $height * 8;
-    // We intend to prevent color scheme changes if there isn't enough memory
-    // available.  memory_get_usage(TRUE) returns a more accurate number than
-    // memory_get_usage(), therefore we won't inadvertently reject a color
-    // scheme change based on a faulty memory calculation.
-    $usage = memory_get_usage(TRUE);
-    $limit = parse_size(ini_get('memory_limit'));
-    if ($usage + $required > $limit) {
-      drupal_set_message(t('There is not enough memory available to PHP to change this theme\'s color scheme. You need at least %size more. Check the <a href="@url">PHP documentation</a> for more information.', array('%size' => format_size($usage + $required - $limit), '@url' => 'http://www.php.net/manual/ini.core.php#ini.sect.resource-limits')), 'error');
-      return;
-    }
-  }
-
-  // Delete old files.
-  foreach (variable_get('color_' . $theme . '_files', array()) as $file) {
-    @drupal_unlink($file);
-  }
-  if (isset($file) && $file = dirname($file)) {
-    @drupal_rmdir($file);
-  }
-
-  // Don't render the default colorscheme, use the standard theme instead.
-  if (implode(',', color_get_palette($theme, TRUE)) == implode(',', $palette)) {
-    variable_del('color_' . $theme . '_palette');
-    variable_del('color_' . $theme . '_stylesheets');
-    variable_del('color_' . $theme . '_logo');
-    variable_del('color_' . $theme . '_files');
-    variable_del('color_' . $theme . '_screenshot');
-    return;
-  }
-
-  // Prepare target locations for generated files.
-  $id = $theme . '-' . substr(hash('sha256', serialize($palette) . microtime()), 0, 8);
-  $paths['color'] = 'public://color';
-  $paths['target'] = $paths['color'] . '/' . $id;
-  foreach ($paths as $path) {
-    file_prepare_directory($path, FILE_CREATE_DIRECTORY);
-  }
-  $paths['target'] = $paths['target'] . '/';
-  $paths['id'] = $id;
-  $paths['source'] = drupal_get_path('theme', $theme) . '/';
-  $paths['files'] = $paths['map'] = array();
-
-  // Save palette and logo location.
-  variable_set('color_' . $theme . '_palette', $palette);
-  variable_set('color_' . $theme . '_logo', $paths['target'] . 'logo.png');
-
-  // Copy over neutral images.
-  foreach ($info['copy'] as $file) {
-    $base = basename($file);
-    $source = $paths['source'] . $file;
-    $filepath = file_unmanaged_copy($source, $paths['target'] . $base);
-    $paths['map'][$file] = $base;
-    $paths['files'][] = $filepath;
-  }
-
-  // Render new images, if image has been provided.
-  if ($info['base_image']) {
-    _color_render_images($theme, $info, $paths, $palette);
-  }
-
-  // Rewrite theme stylesheets.
-  $css = array();
-  foreach ($info['css'] as $stylesheet) {
-    // Build a temporary array with LTR and RTL files.
-    $files = array();
-    if (file_exists($paths['source'] . $stylesheet)) {
-      $files[] = $stylesheet;
-
-      $rtl_file = str_replace('.css', '-rtl.css', $stylesheet);
-      if (file_exists($paths['source'] . $rtl_file)) {
-        $files[] = $rtl_file;
-      }
-    }
-
-    foreach ($files as $file) {
-      // Aggregate @imports recursively for each configured top level CSS file
-      // without optimization. Aggregation and optimization will be
-      // handled by drupal_build_css_cache() only.
-      $style = drupal_load_stylesheet($paths['source'] . $file, FALSE);
-
-      // Return the path to where this CSS file originated from, stripping
-      // off the name of the file at the end of the path.
-      $base = base_path() . dirname($paths['source'] . $file) . '/';
-      _drupal_build_css_path(NULL, $base);
-
-      // Prefix all paths within this CSS file, ignoring absolute paths.
-      $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $style);
-
-      // Rewrite stylesheet with new colors.
-      $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
-      $base_file = basename($file);
-      $css[] = $paths['target'] . $base_file;
-      _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
-    }
-  }
-
-  // Maintain list of files.
-  variable_set('color_' . $theme . '_stylesheets', $css);
-  variable_set('color_' . $theme . '_files', $paths['files']);
-}
-
-/**
- * Rewrite the stylesheet to match the colors in the palette.
- */
-function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
-  $themes = list_themes();
-  // Prepare color conversion table.
-  $conversion = $palette;
-  foreach ($conversion as $k => $v) {
-    $conversion[$k] = drupal_strtolower($v);
-  }
-  $default = color_get_palette($theme, TRUE);
-
-  // Split off the "Don't touch" section of the stylesheet.
-  $split = "Color Module: Don't touch";
-  if (strpos($style, $split) !== FALSE) {
-    list($style, $fixed) = explode($split, $style);
-  }
-
-  // Find all colors in the stylesheet and the chunks in between.
-  $style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);
-  $is_color = FALSE;
-  $output = '';
-  $base = 'base';
-
-  // Iterate over all the parts.
-  foreach ($style as $chunk) {
-    if ($is_color) {
-      $chunk = drupal_strtolower($chunk);
-      // Check if this is one of the colors in the default palette.
-      if ($key = array_search($chunk, $default)) {
-        $chunk = $conversion[$key];
-      }
-      // Not a pre-set color. Extrapolate from the base.
-      else {
-        $chunk = _color_shift($palette[$base], $default[$base], $chunk, $info['blend_target']);
-      }
-    }
-    else {
-      // Determine the most suitable base color for the next color.
-
-      // 'a' declarations. Use link.
-      if (preg_match('@[^a-z0-9_-](a)[^a-z0-9_-][^/{]*{[^{]+$@i', $chunk)) {
-        $base = 'link';
-      }
-      // 'color:' styles. Use text.
-      elseif (preg_match('/(?<!-)color[^{:]*:[^{#]*$/i', $chunk)) {
-        $base = 'text';
-      }
-      // Reset back to base.
-      else {
-        $base = 'base';
-      }
-    }
-    $output .= $chunk;
-    $is_color = !$is_color;
-  }
-  // Append fixed colors segment.
-  if (isset($fixed)) {
-    $output .= $fixed;
-  }
-
-  // Replace paths to images.
-  foreach ($paths['map'] as $before => $after) {
-    $before = base_path() . $paths['source'] . $before;
-    $before = preg_replace('`(^|/)(?!../)([^/]+)/../`', '$1', $before);
-    $output = str_replace($before, $after, $output);
-  }
-
-  return $output;
-}
-
-/**
- * Save the rewritten stylesheet to disk.
- */
-function _color_save_stylesheet($file, $style, &$paths) {
-  $filepath = file_unmanaged_save_data($style, $file, FILE_EXISTS_REPLACE);
-  $paths['files'][] = $filepath;
-
-  // Set standard file permissions for webserver-generated files.
-  drupal_chmod($file);
-}
-
-/**
- * Render images that match a given palette.
- */
-function _color_render_images($theme, &$info, &$paths, $palette) {
-  // Prepare template image.
-  $source = $paths['source'] . '/' . $info['base_image'];
-  $source = imagecreatefrompng($source);
-  $width = imagesx($source);
-  $height = imagesy($source);
-
-  // Prepare target buffer.
-  $target = imagecreatetruecolor($width, $height);
-  imagealphablending($target, TRUE);
-
-  // Fill regions of solid color.
-  foreach ($info['fill'] as $color => $fill) {
-    imagefilledrectangle($target, $fill[0], $fill[1], $fill[0] + $fill[2], $fill[1] + $fill[3], _color_gd($target, $palette[$color]));
-  }
-
-  // Render gradients.
-  foreach ($info['gradients'] as $gradient) {
-    // Get direction of the gradient.
-    if (isset($gradient['direction']) && $gradient['direction'] == 'horizontal') {
-      // Horizontal gradient.
-      for ($x = 0; $x < $gradient['dimension'][2]; $x++) {
-        $color = _color_blend($target, $palette[$gradient['colors'][0]], $palette[$gradient['colors'][1]], $x / ($gradient['dimension'][2] - 1));
-        imagefilledrectangle($target, ($gradient['dimension'][0] + $x), $gradient['dimension'][1], ($gradient['dimension'][0] + $x + 1), ($gradient['dimension'][1] + $gradient['dimension'][3]), $color);
-      }
-    }
-    else {
-      // Vertical gradient.
-      for ($y = 0; $y < $gradient['dimension'][3]; $y++) {
-        $color = _color_blend($target, $palette[$gradient['colors'][0]], $palette[$gradient['colors'][1]], $y / ($gradient['dimension'][3] - 1));
-        imagefilledrectangle($target, $gradient['dimension'][0], $gradient['dimension'][1] + $y, $gradient['dimension'][0] + $gradient['dimension'][2], $gradient['dimension'][1] + $y + 1, $color);
-      }
-    }
-  }
-
-  // Blend over template.
-  imagecopy($target, $source, 0, 0, 0, 0, $width, $height);
-
-  // Clean up template image.
-  imagedestroy($source);
-
-  // Cut out slices.
-  foreach ($info['slices'] as $file => $coord) {
-    list($x, $y, $width, $height) = $coord;
-    $base = basename($file);
-    $image = drupal_realpath($paths['target'] . $base);
-
-    // Cut out slice.
-    if ($file == 'screenshot.png') {
-      $slice = imagecreatetruecolor(150, 90);
-      imagecopyresampled($slice, $target, 0, 0, $x, $y, 150, 90, $width, $height);
-      variable_set('color_' . $theme . '_screenshot', $image);
-    }
-    else {
-      $slice = imagecreatetruecolor($width, $height);
-      imagecopy($slice, $target, 0, 0, $x, $y, $width, $height);
-    }
-
-    // Save image.
-    imagepng($slice, $image);
-    imagedestroy($slice);
-    $paths['files'][] = $image;
-
-    // Set standard file permissions for webserver-generated files
-    drupal_chmod($image);
-
-    // Build before/after map of image paths.
-    $paths['map'][$file] = $base;
-  }
-
-  // Clean up target buffer.
-  imagedestroy($target);
-}
-
-/**
- * Shift a given color, using a reference pair and a target blend color.
- *
- * Note: this function is significantly different from the JS version, as it
- * is written to match the blended images perfectly.
- *
- * Constraint: if (ref2 == target + (ref1 - target) * delta) for some fraction delta
- *              then (return == target + (given - target) * delta)
- *
- * Loose constraint: Preserve relative positions in saturation and luminance
- *                   space.
- */
-function _color_shift($given, $ref1, $ref2, $target) {
-  // We assume that ref2 is a blend of ref1 and target and find
-  // delta based on the length of the difference vectors.
-
-  // delta = 1 - |ref2 - ref1| / |white - ref1|
-  $target = _color_unpack($target, TRUE);
-  $ref1 = _color_unpack($ref1, TRUE);
-  $ref2 = _color_unpack($ref2, TRUE);
-  $numerator = 0;
-  $denominator = 0;
-  for ($i = 0; $i < 3; ++$i) {
-    $numerator += ($ref2[$i] - $ref1[$i]) * ($ref2[$i] - $ref1[$i]);
-    $denominator += ($target[$i] - $ref1[$i]) * ($target[$i] - $ref1[$i]);
-  }
-  $delta = ($denominator > 0) ? (1 - sqrt($numerator / $denominator)) : 0;
-
-  // Calculate the color that ref2 would be if the assumption was true.
-  for ($i = 0; $i < 3; ++$i) {
-    $ref3[$i] = $target[$i] + ($ref1[$i] - $target[$i]) * $delta;
-  }
-
-  // If the assumption is not true, there is a difference between ref2 and ref3.
-  // We measure this in HSL space. Notation: x' = hsl(x).
-  $ref2 = _color_rgb2hsl($ref2);
-  $ref3 = _color_rgb2hsl($ref3);
-  for ($i = 0; $i < 3; ++$i) {
-    $shift[$i] = $ref2[$i] - $ref3[$i];
-  }
-
-  // Take the given color, and blend it towards the target.
-  $given = _color_unpack($given, TRUE);
-  for ($i = 0; $i < 3; ++$i) {
-    $result[$i] = $target[$i] + ($given[$i] - $target[$i]) * $delta;
-  }
-
-  // Finally, we apply the extra shift in HSL space.
-  // Note: if ref2 is a pure blend of ref1 and target, then |shift| = 0.
-  $result = _color_rgb2hsl($result);
-  for ($i = 0; $i < 3; ++$i) {
-    $result[$i] = min(1, max(0, $result[$i] + $shift[$i]));
-  }
-  $result = _color_hsl2rgb($result);
-
-  // Return hex color.
-  return _color_pack($result, TRUE);
-}
-
-/**
- * Convert a hex triplet into a GD color.
- */
-function _color_gd($img, $hex) {
-  $c = array_merge(array($img), _color_unpack($hex));
-  return call_user_func_array('imagecolorallocate', $c);
-}
-
-/**
- * Blend two hex colors and return the GD color.
- */
-function _color_blend($img, $hex1, $hex2, $alpha) {
-  $in1 = _color_unpack($hex1);
-  $in2 = _color_unpack($hex2);
-  $out = array($img);
-  for ($i = 0; $i < 3; ++$i) {
-    $out[] = $in1[$i] + ($in2[$i] - $in1[$i]) * $alpha;
-  }
-
-  return call_user_func_array('imagecolorallocate', $out);
-}
-
-/**
- * Convert a hex color into an RGB triplet.
- */
-function _color_unpack($hex, $normalize = FALSE) {
-  if (strlen($hex) == 4) {
-    $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3];
-  }
-  $c = hexdec($hex);
-  for ($i = 16; $i >= 0; $i -= 8) {
-    $out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1);
-  }
-
-  return $out;
-}
-
-/**
- * Convert an RGB triplet to a hex color.
- */
-function _color_pack($rgb, $normalize = FALSE) {
-  $out = 0;
-  foreach ($rgb as $k => $v) {
-    $out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8));
-  }
-
-  return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
-}
-
-/**
- * Convert a HSL triplet into RGB.
- */
-function _color_hsl2rgb($hsl) {
-  $h = $hsl[0];
-  $s = $hsl[1];
-  $l = $hsl[2];
-  $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s;
-  $m1 = $l * 2 - $m2;
-
-  return array(
-    _color_hue2rgb($m1, $m2, $h + 0.33333),
-    _color_hue2rgb($m1, $m2, $h),
-    _color_hue2rgb($m1, $m2, $h - 0.33333),
-  );
-}
-
-/**
- * Helper function for _color_hsl2rgb().
- */
-function _color_hue2rgb($m1, $m2, $h) {
-  $h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h);
-  if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6;
-  if ($h * 2 < 1) return $m2;
-  if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6;
-
-  return $m1;
-}
-
-/**
- * Convert an RGB triplet to HSL.
- */
-function _color_rgb2hsl($rgb) {
-  $r = $rgb[0];
-  $g = $rgb[1];
-  $b = $rgb[2];
-  $min = min($r, min($g, $b));
-  $max = max($r, max($g, $b));
-  $delta = $max - $min;
-  $l = ($min + $max) / 2;
-  $s = 0;
-
-  if ($l > 0 && $l < 1) {
-    $s = $delta / ($l < 0.5 ? (2 * $l) : (2 - 2 * $l));
-  }
-
-  $h = 0;
-  if ($delta > 0) {
-    if ($max == $r && $max != $g) $h += ($g - $b) / $delta;
-    if ($max == $g && $max != $b) $h += (2 + ($b - $r) / $delta);
-    if ($max == $b && $max != $r) $h += (4 + ($r - $g) / $delta);
-    $h /= 6;
-  }
-
-  return array($h, $s, $l);
-}
diff --git a/modules/color/color.test b/modules/color/color.test
deleted file mode 100644
index 897bd6c..0000000
--- a/modules/color/color.test
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for color module.
- */
-
-/**
- * Test color functionality.
- */
-class ColorTestCase extends DrupalWebTestCase {
-  protected $big_user;
-  protected $themes;
-  protected $colorTests;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Color functionality',
-      'description' => 'Modify the Bartik and Garland theme colors and make sure the changes are reflected on the frontend',
-      'group' => 'Color',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('color');
-
-    // Create users.
-    $this->big_user = $this->drupalCreateUser(array('administer themes'));
-
-    // This tests the color module in both Bartik and Garland.
-    $this->themes = array(
-      'bartik' => array(
-        'palette_input' => 'palette[bg]',
-        'scheme' => 'slate',
-        'scheme_color' => '#3b3b3b',
-      ),
-      'garland' => array(
-        'palette_input' => 'palette[link]',
-        'scheme' => 'greenbeam',
-        'scheme_color' => '#0c7a00',
-      ),
-    );
-    theme_enable(array_keys($this->themes));
-
-    // Array filled with valid and not valid color values
-    $this->colorTests = array(
-      '#000' => TRUE,
-      '#123456' => TRUE,
-      '#abcdef' => TRUE,
-      '#0' => FALSE,
-      '#00' => FALSE,
-      '#0000' => FALSE,
-      '#00000' => FALSE,
-      '123456' => FALSE,
-      '#00000g' => FALSE,
-    );
-  }
-
-  /**
-   * Test color module functionality.
-   */
-  function testColor() {
-    foreach ($this->themes as $theme => $test_values) {
-      $this->_testColor($theme, $test_values);
-    }
-  }
-
-  /**
-   * Tests color module functionality using the given theme.
-   */
-  function _testColor($theme, $test_values) {
-    variable_set('theme_default', $theme);
-    $settings_path = 'admin/appearance/settings/' . $theme;
-
-    $this->drupalLogin($this->big_user);
-    $this->drupalGet($settings_path);
-    $this->assertResponse(200);
-    $edit['scheme'] = '';
-    $edit[$test_values['palette_input']] = '#123456';
-    $this->drupalPost($settings_path, $edit, t('Save configuration'));
-
-    $this->drupalGet('<front>');
-    $stylesheets = variable_get('color_' . $theme . '_stylesheets', array());
-    $this->assertPattern('|' . file_create_url($stylesheets[0]) . '|', 'Make sure the color stylesheet is included in the content. (' . $theme . ')');
-
-    $stylesheet_content = join("\n", file($stylesheets[0]));
-    $this->assertTrue(strpos($stylesheet_content, 'color: #123456') !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')');
-
-    $this->drupalGet($settings_path);
-    $this->assertResponse(200);
-    $edit['scheme'] = $test_values['scheme'];
-    $this->drupalPost($settings_path, $edit, t('Save configuration'));
-
-    $this->drupalGet('<front>');
-    $stylesheets = variable_get('color_' . $theme . '_stylesheets', array());
-    $stylesheet_content = join("\n", file($stylesheets[0]));
-    $this->assertTrue(strpos($stylesheet_content, 'color: ' . $test_values['scheme_color']) !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')');
-
-    // Test with aggregated CSS turned on.
-    variable_set('preprocess_css', 1);
-    $this->drupalGet('<front>');
-    $stylesheets = variable_get('drupal_css_cache_files', array());
-    $stylesheet_content = '';
-    foreach ($stylesheets as $key => $uri) {
-      $stylesheet_content .= join("\n", file(drupal_realpath($uri)));
-    }
-    $this->assertTrue(strpos($stylesheet_content, 'public://') === FALSE, 'Make sure the color paths have been translated to local paths. (' . $theme . ')');
-    variable_set('preprocess_css', 0);
-  }
-
-  /**
-   * Test to see if the provided color is valid
-   */
-  function testValidColor() {
-    variable_set('theme_default', 'bartik');
-    $settings_path = 'admin/appearance/settings/bartik';
-
-    $this->drupalLogin($this->big_user);
-    $edit['scheme'] = '';
-
-    foreach ($this->colorTests as $color => $is_valid) {
-      $edit['palette[bg]'] = $color;
-      $this->drupalPost($settings_path, $edit, t('Save configuration'));
-
-      if($is_valid) {
-        $this->assertText('The configuration options have been saved.');
-      }
-      else {
-        $this->assertText('You must enter a valid hexadecimal color value for Main background.');
-      }
-    }
-  }
-}
diff --git a/modules/color/images/hook-rtl.png b/modules/color/images/hook-rtl.png
deleted file mode 100644
index a26b211e126c298b68a23bef312d8a6dd68f9f29..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 116
zcmeAS@N?(olHy`uVBq!ia0vp^96%h%$P6T}I+T6~QfvV}A+Age3@$D%RWpnNfFg_~
zL4Lsu4$p3+0XZ_BE{-7_Gm{e>82?L31t{n>ta@edSNfw=Fjbr(|C+$R=?YfIf$A7M
MUHx3vIVCg!0H}H$<p2Nx

diff --git a/modules/color/images/hook.png b/modules/color/images/hook.png
deleted file mode 100644
index dc1897370f928a8de70f257cc4786f9e79cf3c57..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 116
zcmeAS@N?(olHy`uVBq!ia0vp^96%h%$P6T}I+T6~QfvV}A+G=b|95e5IsWzME1(Et
zNswPKgTu2MX+VyQr;B3<$IRpe2gd)B5`hYO4Xa++`<4DE6-*UpkoRGhx^8b41ysl2
M>FVdQ&MBb@0PV6N4FCWD

diff --git a/modules/color/images/lock.png b/modules/color/images/lock.png
deleted file mode 100644
index 9e1e00e5efd11ffcf50d13257fd935b92804f840..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 230
zcmeAS@N?(olHy`uVBq!ia0vp@Ky1Xp3?w&5E;IvD>H$6>t}hukBqk>A+`04P$B%~&
z9s2wC@7=q1fsz$v>Hq)k`+uMD*RNk&w{C6I)wBhQGL{7S1v5B2yO9Ru<a)X|hE&`-
zdiEk;g91nELk`}J_x@KpAM3n&>(jdb$7)ZM{Pc1Y-?hq&k#F}a$H0#_yH$+eNWJyV
zS+9Izn}U6*lkVi>_5a-$bGOb6XENKZ<(Ty8=4y_vped4C?pNbf^*A=^p75V{Vb;aJ
c`|GV4`>omJ4i$SG16s`B>FVdQ&MBb@0I4ToN&o-=

diff --git a/modules/color/preview.html b/modules/color/preview.html
deleted file mode 100644
index e25b7ad..0000000
--- a/modules/color/preview.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<div id="preview">
-  <div id="text">
-    <h2>Lorem ipsum dolor</h2>
-    <p>Sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud <a href="#">exercitation ullamco</a> laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
-  </div>
-  <div id="img"></div>
-</div>
\ No newline at end of file
diff --git a/modules/color/preview.js b/modules/color/preview.js
deleted file mode 100644
index 88ae95f..0000000
--- a/modules/color/preview.js
+++ /dev/null
@@ -1,34 +0,0 @@
-
-(function ($) {
-  Drupal.color = {
-    callback: function(context, settings, form, farb, height, width) {
-      // Solid background.
-      $('#preview', form).css('backgroundColor', $('#palette input[name="palette[base]"]', form).val());
-
-      // Text preview
-      $('#text', form).css('color', $('#palette input[name="palette[text]"]', form).val());
-      $('#text a, #text h2', form).css('color', $('#palette input[name="palette[link]"]', form).val());
-
-      // Set up gradients if there are some.
-      var color_start, color_end;
-      for (i in settings.gradients) {
-        color_start = farb.unpack($('#palette input[name="palette[' + settings.gradients[i]['colors'][0] + ']"]', form).val());
-        color_end = farb.unpack($('#palette input[name="palette[' + settings.gradients[i]['colors'][1] + ']"]', form).val());
-        if (color_start && color_end) {
-          var delta = [];
-          for (j in color_start) {
-            delta[j] = (color_end[j] - color_start[j]) / (settings.gradients[i]['vertical'] ? height[i] : width[i]);
-          }
-          var accum = color_start;
-          // Render gradient lines.
-          $('#gradient-' + i + ' > div', form).each(function () {
-            for (j in accum) {
-              accum[j] += delta[j];
-            }
-            this.style.backgroundColor = farb.pack(accum);
-          });
-        }
-      }
-    }
-  };
-})(jQuery);
diff --git a/modules/contact/contact.admin.inc b/modules/contact/contact.admin.inc
deleted file mode 100644
index 9fde037..0000000
--- a/modules/contact/contact.admin.inc
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-
-/**
- * @file
- * Admin page callbacks for the contact module.
- */
-
-/**
- * Categories/list tab.
- */
-function contact_category_list() {
-  $header = array(
-    t('Category'),
-    t('Recipients'),
-    t('Selected'),
-    array('data' => t('Operations'), 'colspan' => 2),
-  );
-  $rows = array();
-
-  // Get all the contact categories from the database.
-  $categories = db_select('contact', 'c')
-    ->addTag('translatable')
-    ->fields('c', array('cid', 'category', 'recipients', 'selected'))
-    ->orderBy('weight')
-    ->orderBy('category')
-    ->execute()
-    ->fetchAll();
-
-  // Loop through the categories and add them to the table.
-  foreach ($categories as $category) {
-    $rows[] = array(
-      check_plain($category->category),
-      check_plain($category->recipients),
-      ($category->selected ? t('Yes') : t('No')),
-      l(t('Edit'), 'admin/structure/contact/edit/' . $category->cid),
-      l(t('Delete'), 'admin/structure/contact/delete/' . $category->cid),
-    );
-  }
-
-  if (!$rows) {
-    $rows[] = array(array(
-      'data' => t('No categories available.'),
-      'colspan' => 5,
-    ));
-  }
-
-  $build['category_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-  );
-  return $build;
-}
-
-/**
- * Category edit page.
- */
-function contact_category_edit_form($form, &$form_state, array $category = array()) {
-  // If this is a new category, add the default values.
-  $category += array(
-    'category' => '',
-    'recipients' => '',
-    'reply' => '',
-    'weight' => 0,
-    'selected' => 0,
-    'cid' => NULL,
-  );
-
-  $form['category'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Category'),
-    '#maxlength' => 255,
-    '#default_value' => $category['category'],
-    '#description' => t("Example: 'website feedback' or 'product information'."),
-    '#required' => TRUE,
-  );
-  $form['recipients'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Recipients'),
-    '#default_value' => $category['recipients'],
-    '#description' => t("Example: 'webmaster@example.com' or 'sales@example.com,support@example.com' . To specify multiple recipients, separate each e-mail address with a comma."),
-    '#required' => TRUE,
-  );
-  $form['reply'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Auto-reply'),
-    '#default_value' => $category['reply'],
-    '#description' => t('Optional auto-reply. Leave empty if you do not want to send the user an auto-reply message.'),
-  );
-  $form['weight'] = array(
-    '#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $category['weight'],
-    '#description' => t('When listing categories, those with lighter (smaller) weights get listed before categories with heavier (larger) weights. Categories with equal weights are sorted alphabetically.'),
-  );
-  $form['selected'] = array(
-    '#type' => 'select',
-    '#title' => t('Selected'),
-    '#options' => array(
-      0 => t('No'),
-      1 => t('Yes'),
-    ),
-    '#default_value' => $category['selected'],
-    '#description' => t('Set this to <em>Yes</em> if you would like this category to be selected by default.'),
-  );
-  $form['cid'] = array(
-    '#type' => 'value',
-    '#value' => $category['cid'],
-  );
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
-
-  return $form;
-}
-
-/**
- * Validate the contact category edit page form submission.
- */
-function contact_category_edit_form_validate($form, &$form_state) {
-  // Validate and each e-mail recipient.
-  $recipients = explode(',', $form_state['values']['recipients']);
-
-  // When creating a new contact form, or renaming the category on an existing
-  // contact form, make sure that the given category is unique.
-  $category = $form_state['values']['category'];
-  $query = db_select('contact', 'c')->condition('c.category', $category, '=');
-  if (!empty($form_state['values']['cid'])) {
-    $query->condition('c.cid', $form_state['values']['cid'], '<>');
-  }
-  if ($query->countQuery()->execute()->fetchField()) {
-    form_set_error('category', t('A contact form with category %category already exists.', array('%category' => $category)));
-  }
-
-  foreach ($recipients as &$recipient) {
-    $recipient = trim($recipient);
-    if (!valid_email_address($recipient)) {
-      form_set_error('recipients', t('%recipient is an invalid e-mail address.', array('%recipient' => $recipient)));
-    }
-  }
-  $form_state['values']['recipients'] = implode(',', $recipients);
-}
-
-/**
- * Process the contact category edit page form submission.
- */
-function contact_category_edit_form_submit($form, &$form_state) {
-  if ($form_state['values']['selected']) {
-    // Unselect all other contact categories.
-    db_update('contact')
-      ->fields(array('selected' => '0'))
-      ->execute();
-  }
-
-  if (empty($form_state['values']['cid'])) {
-    drupal_write_record('contact', $form_state['values']);
-  }
-  else {
-    drupal_write_record('contact', $form_state['values'], array('cid'));
-  }
-
-  drupal_set_message(t('Category %category has been saved.', array('%category' => $form_state['values']['category'])));
-  watchdog('contact', 'Category %category has been saved.', array('%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('Edit'), 'admin/structure/contact/edit/' . $form_state['values']['cid']));
-  $form_state['redirect'] = 'admin/structure/contact';
-}
-
-/**
- * Form builder for deleting a contact category.
- *
- * @see contact_category_delete_form_submit()
- */
-function contact_category_delete_form($form, &$form_state, array $contact) {
-  $form['contact'] = array(
-    '#type' => 'value',
-    '#value' => $contact,
-  );
-
-  return confirm_form(
-    $form,
-    t('Are you sure you want to delete %category?', array('%category' => $contact['category'])),
-    'admin/structure/contact',
-    t('This action cannot be undone.'),
-    t('Delete'),
-    t('Cancel')
-  );
-}
-
-/**
- * Submit handler for the confirm delete category form.
- *
- * @see contact_category_delete_form()
- */
-function contact_category_delete_form_submit($form, &$form_state) {
-  $contact = $form['contact']['#value'];
-
-  db_delete('contact')
-    ->condition('cid', $contact['cid'])
-    ->execute();
-
-  drupal_set_message(t('Category %category has been deleted.', array('%category' => $contact['category'])));
-  watchdog('contact', 'Category %category has been deleted.', array('%category' => $contact['category']), WATCHDOG_NOTICE);
-
-  $form_state['redirect'] = 'admin/structure/contact';
-}
diff --git a/modules/contact/contact.info b/modules/contact/contact.info
deleted file mode 100644
index dd2ac0f..0000000
--- a/modules/contact/contact.info
+++ /dev/null
@@ -1,7 +0,0 @@
-name = Contact
-description = Enables the use of both personal and site-wide contact forms.
-package = Core
-version = VERSION
-core = 8.x
-files[] = contact.test
-configure = admin/structure/contact
diff --git a/modules/contact/contact.install b/modules/contact/contact.install
deleted file mode 100644
index 7ddea45..0000000
--- a/modules/contact/contact.install
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the contact module.
- */
-
-/**
- * Implements hook_schema().
- */
-function contact_schema() {
-  $schema['contact'] = array(
-    'description' => 'Contact form category settings.',
-    'fields' => array(
-      'cid' => array(
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique category ID.',
-      ),
-      'category' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Category name.',
-        'translatable' => TRUE,
-      ),
-      'recipients' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-        'description' => 'Comma-separated list of recipient e-mail addresses.',
-      ),
-      'reply' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-        'description' => 'Text of the auto-reply message.',
-      ),
-      'weight' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The category's weight.",
-      ),
-      'selected' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Flag to indicate whether or not category is selected by default. (1 = Yes, 0 = No)',
-      ),
-    ),
-    'primary key' => array('cid'),
-    'unique keys' => array(
-      'category' => array('category'),
-    ),
-    'indexes' => array(
-      'list' => array('weight', 'category'),
-    ),
-  );
-
-  return $schema;
-}
-
-/**
- * Implements hook_install().
- */
-function contact_install() {
-  // Insert a default contact category.
-  db_insert('contact')
-    ->fields(array(
-      'category' => 'Website feedback',
-      'recipients' => variable_get('site_mail', ini_get('sendmail_from')),
-      'selected' => 1,
-      'reply' => '',
-    ))
-    ->execute();
-}
-
-/**
- * Implements hook_uninstall().
- */
-function contact_uninstall() {
-  variable_del('contact_default_status');
-  variable_del('contact_threshold_limit');
-  variable_del('contact_threshold_window');
-}
diff --git a/modules/contact/contact.module b/modules/contact/contact.module
deleted file mode 100644
index eaae9c6..0000000
--- a/modules/contact/contact.module
+++ /dev/null
@@ -1,257 +0,0 @@
-<?php
-
-/**
- * @file
- * Enables the use of personal and site-wide contact forms.
- */
-
-/**
- * Implements hook_help().
- */
-function contact_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#contact':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Contact module allows visitors to contact site administrators and other users. Users specify a subject, write their message, and can have a copy of their message sent to their own e-mail address. For more information, see the online handbook entry for <a href="@contact">Contact module</a>.', array('@contact' => 'http://drupal.org/handbook/modules/contact/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('User contact forms') . '</dt>';
-      $output .= '<dd>' . t('Site users can be contacted with a user contact form that keeps their e-mail address private. Users may enable or disable their personal contact forms by editing their <em>My account</em> page. If enabled, a <em>Contact</em> tab leads to a personal contact form displayed on their user profile. Site administrators are still able to use the contact form, even if has been disabled. The <em>Contact</em> tab is not shown when you view your own profile.') . '</dd>';
-      $output .= '<dt>' . t('Site-wide contact forms') . '</dt>';
-      $output .= '<dd>' . t('The <a href="@contact">Contact page</a> provides a simple form for users with the <em>Use the site-wide contact form</em> permission to send comments, feedback, or other requests. You can create categories for directing the contact form messages to a set of defined recipients. Common categories for a business site, for example, might include "Website feedback" (messages are forwarded to website administrators) and "Product information" (messages are forwarded to members of the sales department). E-mail addresses defined within a category are not displayed publicly.', array('@contact' => url('contact'))) . '</p>';
-      $output .= '<dt>' . t('Navigation') . '</dt>';
-      $output .= '<dd>' . t("When the site-wide contact form is enabled, a link in the main <em>Navigation</em> menu is created, but the link is disabled by default. This menu link can be enabled on the <a href='@menu'>Menus administration page</a>.", array('@contact' => url('contact'), '@menu' => url('admin/structure/menu'))) . '</dd>';
-      $output .= '<dt>' . t('Customization') . '</dt>';
-      $output .= '<dd>' . t('If you would like additional text to appear on the site-wide or personal contact page, use a block. You can create and edit blocks on the <a href="@blocks">Blocks administration page</a>.', array('@blocks' => url('admin/structure/block'))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-    case 'admin/structure/contact':
-      $output = '<p>' . t('Add one or more categories on this page to set up your site-wide <a href="@form">contact form</a>.', array('@form' => url('contact'))) . '</p>';
-      $output .= '<p>' . t('A <em>Contact</em> menu item (disabled by default) is added to the Navigation menu, which you can modify on the <a href="@menu-settings">Menus administration page</a>.', array('@menu-settings' => url('admin/structure/menu'))) . '</p>';
-      $output .= '<p>' . t('If you would like additional text to appear on the site-wide contact page, use a block. You can create and edit blocks on the <a href="@blocks">Blocks administration page</a>.', array('@blocks' => url('admin/structure/block'))) . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_permission().
- */
-function contact_permission() {
-  return array(
-    'administer contact forms' => array(
-      'title' => t('Administer contact forms and contact form settings'),
-    ),
-    'access site-wide contact form' => array(
-      'title' => t('Use the site-wide contact form'),
-    ),
-    'access user contact forms' => array(
-      'title' => t("Use users' personal contact forms"),
-    ),
-  );
-}
-
-/**
- * Implements hook_menu().
- */
-function contact_menu() {
-  $items['admin/structure/contact'] = array(
-    'title' => 'Contact form',
-    'description' => 'Create a system contact form and set up categories for the form to use.',
-    'page callback' => 'contact_category_list',
-    'access arguments' => array('administer contact forms'),
-    'file' => 'contact.admin.inc',
-  );
-  $items['admin/structure/contact/add'] = array(
-    'title' => 'Add category',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('contact_category_edit_form'),
-    'access arguments' => array('administer contact forms'),
-    'type' => MENU_LOCAL_ACTION,
-    'weight' => 1,
-    'file' => 'contact.admin.inc',
-  );
-  $items['admin/structure/contact/edit/%contact'] = array(
-    'title' => 'Edit contact category',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('contact_category_edit_form', 4),
-    'access arguments' => array('administer contact forms'),
-    'file' => 'contact.admin.inc',
-  );
-  $items['admin/structure/contact/delete/%contact'] = array(
-    'title' => 'Delete contact',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('contact_category_delete_form', 4),
-    'access arguments' => array('administer contact forms'),
-    'file' => 'contact.admin.inc',
-  );
-  $items['contact'] = array(
-    'title' => 'Contact',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('contact_site_form'),
-    'access arguments' => array('access site-wide contact form'),
-    'type' => MENU_SUGGESTED_ITEM,
-    'file' => 'contact.pages.inc',
-  );
-  $items['user/%user/contact'] = array(
-    'title' => 'Contact',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('contact_personal_form', 1),
-    'type' => MENU_LOCAL_TASK,
-    'access callback' => '_contact_personal_tab_access',
-    'access arguments' => array(1),
-    'weight' => 2,
-    'file' => 'contact.pages.inc',
-  );
-  return $items;
-}
-
-/**
- * Menu access callback for a user's personal contact form.
- *
- * @param $account
- *   A user account object.
- * @return
- *   TRUE if the current user has access to the requested user's contact form,
- *   or FALSE otherwise.
- */
-function _contact_personal_tab_access($account) {
-  global $user;
-
-  // Anonymous users cannot have contact forms.
-  if (!$account->uid) {
-    return FALSE;
-  }
-
-  // User administrators should always have access to personal contact forms.
-  if (user_access('administer users')) {
-    return TRUE;
-  }
-
-  // Users may not contact themselves.
-  if ($user->uid == $account->uid) {
-    return FALSE;
-  }
-
-  // If the requested user has disabled their contact form, or this preference
-  // has not yet been saved, do not allow users to contact them.
-  if (empty($account->data['contact'])) {
-    return FALSE;
-  }
-
-  // If requested user has been blocked, do not allow users to contact them.
-  if (empty($account->status)) {
-    return FALSE;
-  }
-
-  return user_access('access user contact forms');
-}
-
-/**
- * Load a contact category.
- *
- * @param $cid
- *   The contact category ID.
- * @return
- *   An array with the contact category's data.
- */
-function contact_load($cid) {
-  return db_select('contact', 'c')
-    ->addTag('translatable')
-    ->fields('c')
-    ->condition('cid', $cid)
-    ->execute()
-    ->fetchAssoc();
-}
-
-/**
- * Implements hook_mail().
- */
-function contact_mail($key, &$message, $params) {
-  $language = $message['language'];
-  $variables = array(
-    '!site-name' => variable_get('site_name', 'Drupal'),
-    '!subject' => $params['subject'],
-    '!category' => isset($params['category']['category']) ? $params['category']['category'] : '',
-    '!form-url' => url($_GET['q'], array('absolute' => TRUE, 'language' => $language)),
-    '!sender-name' => format_username($params['sender']),
-    '!sender-url' => $params['sender']->uid ? url('user/' . $params['sender']->uid, array('absolute' => TRUE, 'language' => $language)) : $params['sender']->mail,
-  );
-
-  switch ($key) {
-    case 'page_mail':
-    case 'page_copy':
-      $message['subject'] .= t('[!category] !subject', $variables, array('langcode' => $language->language));
-      $message['body'][] = t("!sender-name (!sender-url) sent a message using the contact form at !form-url.", $variables, array('langcode' => $language->language));
-      $message['body'][] = $params['message'];
-      break;
-
-    case 'page_autoreply':
-      $message['subject'] .= t('[!category] !subject', $variables, array('langcode' => $language->language));
-      $message['body'][] = $params['category']['reply'];
-      break;
-
-    case 'user_mail':
-    case 'user_copy':
-      $variables += array(
-        '!recipient-name' => format_username($params['recipient']),
-        '!recipient-edit-url' => url('user/' . $params['recipient']->uid . '/edit', array('absolute' => TRUE, 'language' => $language)),
-      );
-      $message['subject'] .= t('[!site-name] !subject', $variables, array('langcode' => $language->language));
-      $message['body'][] = t('Hello !recipient-name,', $variables, array('langcode' => $language->language));
-      $message['body'][] = t("!sender-name (!sender-url) has sent you a message via your contact form (!form-url) at !site-name.", $variables, array('langcode' => $language->language));
-      $message['body'][] = t("If you don't want to receive such e-mails, you can change your settings at !recipient-edit-url.", $variables, array('langcode' => $language->language));
-      $message['body'][] = t('Message:', array(), array('langcode' => $language->language));
-      $message['body'][] = $params['message'];
-      break;
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- *
- * Add the enable personal contact form to an individual user's account page.
- */
-function contact_form_user_profile_form_alter(&$form, &$form_state) {
-  if ($form['#user_category'] == 'account') {
-    $account = $form['#user'];
-    $form['contact'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Contact settings'),
-      '#weight' => 5,
-      '#collapsible' => TRUE,
-    );
-    $form['contact']['contact'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Personal contact form'),
-      '#default_value' => !empty($account->data['contact']) ? $account->data['contact'] : FALSE,
-      '#description' => t('Allow other users to contact you via a <a href="@url">personal contact form</a> which keeps your e-mail address hidden. Note that some privileged users such as site administrators are still able to contact you even if you choose to disable this feature.', array('@url' => url("user/$account->uid/contact"))),
-    );
-  }
-}
-
-/**
- * Implements hook_user_presave().
- */
-function contact_user_presave(&$edit, $account, $category) {
-  $edit['data']['contact'] = isset($edit['contact']) ? $edit['contact'] : variable_get('contact_default_status', 1);
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- *
- * Add the default personal contact setting on the user settings page.
- */
-function contact_form_user_admin_settings_alter(&$form, &$form_state) {
-  $form['contact'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Contact settings'),
-    '#weight' => 0,
-  );
-  $form['contact']['contact_default_status'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable the personal contact form by default for new users.'),
-    '#description' => t('Changing this setting will not affect existing users.'),
-    '#default_value' => variable_get('contact_default_status', 1),
-  );
-}
diff --git a/modules/contact/contact.pages.inc b/modules/contact/contact.pages.inc
deleted file mode 100644
index 30b2825..0000000
--- a/modules/contact/contact.pages.inc
+++ /dev/null
@@ -1,291 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the contact module.
- */
-
-/**
- * Form builder; the site-wide contact form.
- *
- * @see contact_site_form_validate()
- * @see contact_site_form_submit()
- */
-function contact_site_form($form, &$form_state) {
-  global $user;
-
-  // Check if flood control has been activated for sending e-mails.
-  $limit = variable_get('contact_threshold_limit', 5);
-  $window = variable_get('contact_threshold_window', 3600);
-  if (!flood_is_allowed('contact', $limit, $window) && !user_access('administer contact forms')) {
-    drupal_set_message(t("You cannot send more than %limit messages in @interval. Try again later.", array('%limit' => $limit, '@interval' => format_interval($window))), 'error');
-    drupal_access_denied();
-    drupal_exit();
-  }
-
-  // Get an array of the categories and the current default category.
-  $categories = db_select('contact', 'c')
-    ->addTag('translatable')
-    ->fields('c', array('cid', 'category'))
-    ->orderBy('weight')
-    ->orderBy('category')
-    ->execute()
-    ->fetchAllKeyed();
-  $default_category = db_query("SELECT cid FROM {contact} WHERE selected = 1")->fetchField();
-
-  // If there are no categories, do not display the form.
-  if (!$categories) {
-    if (user_access('administer contact forms')) {
-      drupal_set_message(t('The contact form has not been configured. <a href="@add">Add one or more categories</a> to the form.', array('@add' => url('admin/structure/contact/add'))), 'error');
-    }
-    else {
-      drupal_not_found();
-      drupal_exit();
-    }
-  }
-
-  // If there is more than one category available and no default category has
-  // been selected, prepend a default placeholder value.
-  if (!$default_category) {
-    if (count($categories) > 1) {
-      $categories = array(0 => t('- Please choose -')) + $categories;
-    }
-    else {
-      $default_category = key($categories);
-    }
-  }
-
-  if (!$user->uid) {
-    $form['#attached']['library'][] = array('system', 'jquery.cookie');
-    $form['#attributes']['class'][] = 'user-info-from-cookie';
-  }
-
-  $form['#attributes']['class'][] = 'contact-form';
-  $form['name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Your name'),
-    '#maxlength' => 255,
-    '#default_value' => $user->uid ? format_username($user) : '',
-    '#required' => TRUE,
-  );
-  $form['mail'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Your e-mail address'),
-    '#maxlength' => 255,
-    '#default_value' => $user->uid ? $user->mail : '',
-    '#required' => TRUE,
-  );
-  $form['subject'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Subject'),
-    '#maxlength' => 255,
-    '#required' => TRUE,
-  );
-  $form['cid'] = array(
-    '#type' => 'select',
-    '#title' => t('Category'),
-    '#default_value' => $default_category,
-    '#options' => $categories,
-    '#required' => TRUE,
-    '#access' => count($categories) > 1,
-  );
-  $form['message'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Message'),
-    '#required' => TRUE,
-  );
-  // We do not allow anonymous users to send themselves a copy
-  // because it can be abused to spam people.
-  $form['copy'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Send yourself a copy.'),
-    '#access' => $user->uid,
-  );
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Send message'),
-  );
-
-  return $form;
-}
-
-/**
- * Form validation handler for contact_site_form().
- */
-function contact_site_form_validate($form, &$form_state) {
-  if (!$form_state['values']['cid']) {
-    form_set_error('cid', t('You must select a valid category.'));
-  }
-  if (!valid_email_address($form_state['values']['mail'])) {
-    form_set_error('mail', t('You must enter a valid e-mail address.'));
-  }
-}
-
-/**
- * Form submission handler for contact_site_form().
- */
-function contact_site_form_submit($form, &$form_state) {
-  global $user, $language;
-
-  $values = $form_state['values'];
-  $values['sender'] = $user;
-  $values['sender']->name = $values['name'];
-  $values['sender']->mail = $values['mail'];
-  $values['category'] = contact_load($values['cid']);
-
-  // Save the anonymous user information to a cookie for reuse.
-  if (!$user->uid) {
-    user_cookie_save(array_intersect_key($values, array_flip(array('name', 'mail'))));
-  }
-
-  // Get the to and from e-mail addresses.
-  $to = $values['category']['recipients'];
-  $from = $values['sender']->mail;
-
-  // Send the e-mail to the recipients using the site default language.
-  drupal_mail('contact', 'page_mail', $to, language_default(), $values, $from);
-
-  // If the user requests it, send a copy using the current language.
-  if ($values['copy']) {
-    drupal_mail('contact', 'page_copy', $from, $language, $values, $from);
-  }
-
-  // Send an auto-reply if necessary using the current language.
-  if ($values['category']['reply']) {
-    drupal_mail('contact', 'page_autoreply', $from, $language, $values, $to);
-  }
-
-  flood_register_event('contact', variable_get('contact_threshold_window', 3600));
-  watchdog('mail', '%sender-name (@sender-from) sent an e-mail regarding %category.', array('%sender-name' => $values['name'], '@sender-from' => $from, '%category' => $values['category']['category']));
-
-  // Jump to home page rather than back to contact page to avoid
-  // contradictory messages if flood control has been activated.
-  drupal_set_message(t('Your message has been sent.'));
-  $form_state['redirect'] = '';
-}
-
-/**
- * Form builder; the personal contact form.
- *
- * @see contact_personal_form_validate()
- * @see contact_personal_form_submit()
- */
-function contact_personal_form($form, &$form_state, $recipient) {
-  global $user;
-
-  // Check if flood control has been activated for sending e-mails.
-  $limit = variable_get('contact_threshold_limit', 5);
-  $window = variable_get('contact_threshold_window', 3600);
-  if (!flood_is_allowed('contact', $limit, $window) && !user_access('administer contact forms') && !user_access('administer users')) {
-    drupal_set_message(t("You cannot send more than %limit messages in @interval. Try again later.", array('%limit' => $limit, '@interval' => format_interval($window))), 'error');
-    drupal_access_denied();
-    drupal_exit();
-  }
-
-  drupal_set_title(t('Contact @username', array('@username' => format_username($recipient))), PASS_THROUGH);
-
-  if (!$user->uid) {
-    $form['#attached']['library'][] = array('system', 'jquery.cookie');
-    $form['#attributes']['class'][] = 'user-info-from-cookie';
-  }
-
-  $form['#attributes']['class'][] = 'contact-form';
-  $form['recipient'] = array(
-    '#type' => 'value',
-    '#value' => $recipient,
-  );
-  $form['name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Your name'),
-    '#maxlength' => 255,
-    '#default_value' => $user->uid ? format_username($user) : '',
-    '#required' => TRUE,
-  );
-  $form['mail'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Your e-mail address'),
-    '#maxlength' => 255,
-    '#default_value' => $user->uid ? $user->mail : '',
-    '#required' => TRUE,
-  );
-  $form['to'] = array(
-    '#type' => 'item',
-    '#title' => t('To'),
-    '#markup' => theme('username', array('account' => $recipient)),
-  );
-  $form['subject'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Subject'),
-    '#maxlength' => 50,
-    '#required' => TRUE,
-  );
-  $form['message'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Message'),
-    '#rows' => 15,
-    '#required' => TRUE,
-  );
-  // We do not allow anonymous users to send themselves a copy
-  // because it can be abused to spam people.
-  $form['copy'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Send yourself a copy.'),
-    '#access' => $user->uid,
-  );
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Send message'),
-  );
-  return $form;
-}
-
-/**
- * Form validation handler for contact_personal_form().
- *
- * @see contact_personal_form()
- */
-function contact_personal_form_validate($form, &$form_state) {
-  if (!valid_email_address($form_state['values']['mail'])) {
-    form_set_error('mail', t('You must enter a valid e-mail address.'));
-  }
-}
-
-/**
- * Form submission handler for contact_personal_form().
- *
- * @see contact_personal_form()
- */
-function contact_personal_form_submit($form, &$form_state) {
-  global $user, $language;
-
-  $values = $form_state['values'];
-  $values['sender'] = $user;
-  $values['sender']->name = $values['name'];
-  $values['sender']->mail = $values['mail'];
-
-  // Save the anonymous user information to a cookie for reuse.
-  if (!$user->uid) {
-    user_cookie_save(array_intersect_key($values, array_flip(array('name', 'mail'))));
-  }
-
-  // Get the to and from e-mail addresses.
-  $to = $values['recipient']->mail;
-  $from = $values['sender']->mail;
-
-  // Send the e-mail in the requested user language.
-  drupal_mail('contact', 'user_mail', $to, user_preferred_language($values['recipient']), $values, $from);
-
-  // Send a copy if requested, using current page language.
-  if ($values['copy']) {
-    drupal_mail('contact', 'user_copy', $from, $language, $values, $from);
-  }
-
-  flood_register_event('contact', variable_get('contact_threshold_window', 3600));
-  watchdog('mail', '%sender-name (@sender-from) sent %recipient-name an e-mail.', array('%sender-name' => $values['name'], '@sender-from' => $from, '%recipient-name' => $values['recipient']->name));
-
-  // Jump to the contacted user's profile page.
-  drupal_set_message(t('Your message has been sent.'));
-  $form_state['redirect'] = user_access('access user profiles') ? 'user/' . $values['recipient']->uid : '';
-}
diff --git a/modules/contact/contact.test b/modules/contact/contact.test
deleted file mode 100644
index bc44f5a..0000000
--- a/modules/contact/contact.test
+++ /dev/null
@@ -1,416 +0,0 @@
-<?php
-
-/**
- * @file 
- * Tests for contact.module.
- */
-
-class ContactSitewideTestCase extends DrupalWebTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Site-wide contact form',
-      'description' => 'Tests site-wide contact form functionality.',
-      'group' => 'Contact',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('contact');
-  }
-
-  /**
-   * Test configuration options and site-wide contact form.
-   */
-  function testSiteWideContact() {
-    // Create and login administrative user.
-    $admin_user = $this->drupalCreateUser(array('access site-wide contact form', 'administer contact forms', 'administer users'));
-    $this->drupalLogin($admin_user);
-
-    $flood_limit = 3;
-    variable_set('contact_threshold_limit', $flood_limit);
-    variable_set('contact_threshold_window', 600);
-
-    // Set settings.
-    $edit = array();
-    $edit['contact_default_status'] = TRUE;
-    $this->drupalPost('admin/config/people/accounts', $edit, t('Save configuration'));
-    $this->assertText(t('The configuration options have been saved.'), t('Setting successfully saved.'));
-
-    // Delete old categories to ensure that new categories are used.
-    $this->deleteCategories();
-
-    // Ensure that the contact form won't be shown without categories.
-    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
-    $this->drupalLogout();
-    $this->drupalGet('contact');
-    $this->assertResponse(404);
-    $this->drupalLogin($admin_user);
-    $this->drupalGet('contact');
-    $this->assertResponse(200);
-    $this->assertText(t('The contact form has not been configured.'));
-
-    // Add categories.
-    // Test invalid recipients.
-    $invalid_recipients = array('invalid', 'invalid@', 'invalid@site.', '@site.', '@site.com');
-    foreach ($invalid_recipients as $invalid_recipient) {
-      $this->addCategory($this->randomName(16), $invalid_recipient, '', FALSE);
-      $this->assertRaw(t('%recipient is an invalid e-mail address.', array('%recipient' => $invalid_recipient)), t('Caught invalid recipient (' . $invalid_recipient . ').'));
-    }
-
-    // Test validation of empty category and recipients fields.
-    $this->addCategory($category = '', '', '', TRUE);
-    $this->assertText(t('Category field is required.'), t('Caught empty category field'));
-    $this->assertText(t('Recipients field is required.'), t('Caught empty recipients field.'));
-
-    // Create first valid category.
-    $recipients = array('simpletest@example.com', 'simpletest2@example.com', 'simpletest3@example.com');
-    $this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0])), '', TRUE);
-    $this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category successfully saved.'));
-
-    // Make sure the newly created category is included in the list of categories.
-    $this->assertNoUniqueText($category, t('New category included in categories list.'));
-
-    // Test update contact form category.
-    $categories = $this->getCategories();
-    $category_id = $this->updateCategory($categories, $category = $this->randomName(16), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomName(30), FALSE);
-    $category_array = db_query("SELECT category, recipients, reply, selected FROM {contact} WHERE cid = :cid", array(':cid' => $category_id))->fetchAssoc();
-    $this->assertEqual($category_array['category'], $category);
-    $this->assertEqual($category_array['recipients'], $recipients_str);
-    $this->assertEqual($category_array['reply'], $reply);
-    $this->assertFalse($category_array['selected']);
-    $this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category successfully saved.'));
-
-    // Ensure that the contact form is shown without a category selection input.
-    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
-    $this->drupalLogout();
-    $this->drupalGet('contact');
-    $this->assertText(t('Your e-mail address'), t('Contact form is shown when there is one category.'));
-    $this->assertNoText(t('Category'), t('When there is only one category, the category selection element is hidden.'));
-    $this->drupalLogin($admin_user);
-
-    // Add more categories.
-    $this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0], $recipients[1])), '', FALSE);
-    $this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category successfully saved.'));
-
-    $this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0], $recipients[1], $recipients[2])), '', FALSE);
-    $this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category successfully saved.'));
-
-    // Try adding a category that already exists.
-    $this->addCategory($category, '', '', FALSE);
-    $this->assertNoRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category not saved.'));
-    $this->assertRaw(t('A contact form with category %category already exists.', array('%category' => $category)), t('Duplicate category error found.'));
-
-    // Clear flood table in preparation for flood test and allow other checks to complete.
-    db_delete('flood')->execute();
-    $num_records_after = db_query("SELECT COUNT(*) FROM {flood}")->fetchField();
-    $this->assertIdentical($num_records_after, '0', t('Flood table emptied.'));
-    $this->drupalLogout();
-
-    // Check to see that anonymous user cannot see contact page without permission.
-    user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
-    $this->drupalGet('contact');
-    $this->assertResponse(403, t('Access denied to anonymous user without permission.'));
-
-    // Give anonymous user permission and see that page is viewable.
-    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
-    $this->drupalGet('contact');
-    $this->assertResponse(200, t('Access granted to anonymous user with permission.'));
-
-    // Submit contact form with invalid values.
-    $this->submitContact('', $recipients[0], $this->randomName(16), $categories[0], $this->randomName(64));
-    $this->assertText(t('Your name field is required.'), t('Name required.'));
-
-    $this->submitContact($this->randomName(16), '', $this->randomName(16), $categories[0], $this->randomName(64));
-    $this->assertText(t('Your e-mail address field is required.'), t('E-mail required.'));
-
-    $this->submitContact($this->randomName(16), $invalid_recipients[0], $this->randomName(16), $categories[0], $this->randomName(64));
-    $this->assertText(t('You must enter a valid e-mail address.'), t('Valid e-mail required.'));
-
-    $this->submitContact($this->randomName(16), $recipients[0], '', $categories[0], $this->randomName(64));
-    $this->assertText(t('Subject field is required.'), t('Subject required.'));
-
-    $this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $categories[0], '');
-    $this->assertText(t('Message field is required.'), t('Message required.'));
-
-    // Test contact form with no default category selected.
-    db_update('contact')
-      ->fields(array('selected' => 0))
-      ->execute();
-    $this->drupalGet('contact');
-    $this->assertRaw(t('- Please choose -'), t('Without selected categories the visitor is asked to chose a category.'));
-
-    // Submit contact form with invalid category id (cid 0).
-    $this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), 0, '');
-    $this->assertText(t('You must select a valid category.'), t('Valid category required.'));
-
-    // Submit contact form with correct values and check flood interval.
-    for ($i = 0; $i < $flood_limit; $i++) {
-      $this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $categories[0], $this->randomName(64));
-      $this->assertText(t('Your message has been sent.'), t('Message sent.'));
-    }
-    // Submit contact form one over limit.
-    $this->drupalGet('contact');
-    $this->assertResponse(403, t('Access denied to anonymous user after reaching message treshold.'));
-    $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => variable_get('contact_threshold_limit', 3), '@interval' => format_interval(600))), t('Message threshold reached.'));
-
-    // Delete created categories.
-    $this->drupalLogin($admin_user);
-    $this->deleteCategories();
-  }
-
-  /**
-  * Test auto-reply on the site-wide contact form.
-  */
-  function testAutoReply() {
-    // Create and login administrative user.
-    $admin_user = $this->drupalCreateUser(array('access site-wide contact form', 'administer contact forms', 'administer permissions', 'administer users'));
-    $this->drupalLogin($admin_user);
-
-    // Set up three categories, 2 with an auto-reply and one without.
-    $foo_autoreply = $this->randomName(40);
-    $bar_autoreply = $this->randomName(40);
-    $this->addCategory('foo', 'foo@example.com', $foo_autoreply, FALSE);
-    $this->addCategory('bar', 'bar@example.com', $bar_autoreply, FALSE);
-    $this->addCategory('no_autoreply', 'bar@example.com', '', FALSE);
-
-    // Test the auto-reply for category 'foo'.
-    $email = $this->randomName(32) . '@example.com';
-    $subject = $this->randomName(64);
-    $this->submitContact($this->randomName(16), $email, $subject, 2, $this->randomString(128));
-
-    // We are testing the auto-reply, so there should be one e-mail going to the sender.
-    $captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email, 'from' => 'foo@example.com'));
-    $this->assertEqual(count($captured_emails), 1, t('Auto-reply e-mail was sent to the sender for category "foo".'), t('Contact'));
-    $this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($foo_autoreply), t('Auto-reply e-mail body is correct for category "foo".'), t('Contact'));
-
-    // Test the auto-reply for category 'bar'.
-    $email = $this->randomName(32) . '@example.com';
-    $this->submitContact($this->randomName(16), $email, $this->randomString(64), 3, $this->randomString(128));
-
-    // Auto-reply for category 'bar' should result in one auto-reply e-mail to the sender.
-    $captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email, 'from' => 'bar@example.com'));
-    $this->assertEqual(count($captured_emails), 1, t('Auto-reply e-mail was sent to the sender for category "bar".'), t('Contact'));
-    $this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($bar_autoreply), t('Auto-reply e-mail body is correct for category "bar".'), t('Contact'));
-
-    // Verify that no auto-reply is sent when the auto-reply field is left blank.
-    $email = $this->randomName(32) . '@example.com';
-    $this->submitContact($this->randomName(16), $email, $this->randomString(64), 4, $this->randomString(128));
-    $captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email, 'from' => 'no_autoreply@example.com'));
-    $this->assertEqual(count($captured_emails), 0, t('No auto-reply e-mail was sent to the sender for category "no-autoreply".'), t('Contact'));
-  }
-
-  /**
-   * Add a category.
-   *
-   * @param string $category Name of category.
-   * @param string $recipients List of recipient e-mail addresses.
-   * @param string $reply Auto-reply text.
-   * @param boolean $selected Defautly selected.
-   */
-  function addCategory($category, $recipients, $reply, $selected) {
-    $edit = array();
-    $edit['category'] = $category;
-    $edit['recipients'] = $recipients;
-    $edit['reply'] = $reply;
-    $edit['selected'] = ($selected ? '1' : '0');
-    $this->drupalPost('admin/structure/contact/add', $edit, t('Save'));
-  }
-
-  /**
-   * Update a category.
-   *
-   * @param string $category Name of category.
-   * @param string $recipients List of recipient e-mail addresses.
-   * @param string $reply Auto-reply text.
-   * @param boolean $selected Defautly selected.
-   */
-  function updateCategory($categories, $category, $recipients, $reply, $selected) {
-    $category_id = $categories[array_rand($categories)];
-    $edit = array();
-    $edit['category'] = $category;
-    $edit['recipients'] = $recipients;
-    $edit['reply'] = $reply;
-    $edit['selected'] = ($selected ? '1' : '0');
-    $this->drupalPost('admin/structure/contact/edit/' . $category_id, $edit, t('Save'));
-    return ($category_id);
-  }
-
-  /**
-   * Submit contact form.
-   *
-   * @param string $name Name.
-   * @param string $mail E-mail address.
-   * @param string $subject Subject.
-   * @param integer $cid Category id.
-   * @param string $message Message.
-   */
-  function submitContact($name, $mail, $subject, $cid, $message) {
-    $edit = array();
-    $edit['name'] = $name;
-    $edit['mail'] = $mail;
-    $edit['subject'] = $subject;
-    $edit['cid'] = $cid;
-    $edit['message'] = $message;
-    $this->drupalPost('contact', $edit, t('Send message'));
-  }
-
-  /**
-   * Delete all categories.
-   */
-  function deleteCategories() {
-    $categories = $this->getCategories();
-    foreach ($categories as $category) {
-      $category_name = db_query("SELECT category FROM {contact} WHERE cid = :cid", array(':cid' => $category))->fetchField();
-      $this->drupalPost('admin/structure/contact/delete/' . $category, array(), t('Delete'));
-      $this->assertRaw(t('Category %category has been deleted.', array('%category' => $category_name)), t('Category deleted sucessfully.'));
-    }
-  }
-
-  /**
-   * Get list category ids.
-   *
-   * @return array Category ids.
-   */
-  function getCategories() {
-    $categories = db_query('SELECT cid FROM {contact}')->fetchCol();
-    return $categories;
-  }
-}
-
-/**
- * Test the personal contact form.
- */
-class ContactPersonalTestCase extends DrupalWebTestCase {
-  private $admin_user;
-  private $web_user;
-  private $contact_user;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Personal contact form',
-      'description' => 'Tests personal contact form functionality.',
-      'group' => 'Contact',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('contact');
-
-    // Create an admin user.
-    $this->admin_user = $this->drupalCreateUser(array('administer contact forms', 'administer users'));
-
-    // Create some normal users with their contact forms enabled by default.
-    variable_set('contact_default_status', TRUE);
-    $this->web_user = $this->drupalCreateUser(array('access user contact forms'));
-    $this->contact_user = $this->drupalCreateUser();
-  }
-
-  /**
-   * Test personal contact form access.
-   */
-  function testPersonalContactAccess() {
-    // Test allowed access to user with contact form enabled.
-    $this->drupalLogin($this->web_user);
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(200);
-
-    // Test denied access to the user's own contact form.
-    $this->drupalGet('user/' . $this->web_user->uid . '/contact');
-    $this->assertResponse(403);
-
-    // Test always denied access to the anonymous user contact form.
-    $this->drupalGet('user/0/contact');
-    $this->assertResponse(403);
-
-    // Test that anonymous users can access the contact form.
-    $this->drupalLogout();
-    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(200);
-
-    // Revoke the personal contact permission for the anonymous user.
-    user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(403);
-
-    // Disable the personal contact form.
-    $this->drupalLogin($this->admin_user);
-    $edit = array('contact_default_status' => FALSE);
-    $this->drupalPost('admin/config/people/accounts', $edit, t('Save configuration'));
-    $this->assertText(t('The configuration options have been saved.'), t('Setting successfully saved.'));
-    $this->drupalLogout();
-
-    // Re-create our contacted user with personal contact forms disabled by
-    // default.
-    $this->contact_user = $this->drupalCreateUser();
-
-    // Test denied access to a user with contact form disabled.
-    $this->drupalLogin($this->web_user);
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(403);
-
-    // Test allowed access for admin user to a user with contact form disabled.
-    $this->drupalLogin($this->admin_user);
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(200);
-
-    // Re-create our contacted user as a blocked user.
-    $this->contact_user = $this->drupalCreateUser();
-    user_save($this->contact_user, array('status' => 0));
-
-    // Test that blocked users can still be contacted by admin.
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(200);
-
-    // Test that blocked users cannot be contacted by non-admins.
-    $this->drupalLogin($this->web_user);
-    $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
-    $this->assertResponse(403);
-  }
-
-  /**
-   * Test the personal contact form flood protection.
-   */
-  function testPersonalContactFlood() {
-    $flood_limit = 3;
-    variable_set('contact_threshold_limit', $flood_limit);
-
-    // Clear flood table in preparation for flood test and allow other checks to complete.
-    db_delete('flood')->execute();
-    $num_records_flood = db_query("SELECT COUNT(*) FROM {flood}")->fetchField();
-    $this->assertIdentical($num_records_flood, '0', 'Flood table emptied.');
-
-    $this->drupalLogin($this->web_user);
-
-    // Submit contact form with correct values and check flood interval.
-    for ($i = 0; $i < $flood_limit; $i++) {
-      $this->submitPersonalContact($this->contact_user);
-      $this->assertText(t('Your message has been sent.'), 'Message sent.');
-    }
-
-    // Submit contact form one over limit.
-    $this->drupalGet('user/' . $this->contact_user->uid. '/contact');
-    $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => $flood_limit, '@interval' => format_interval(variable_get('contact_threshold_window', 3600)))), 'Normal user denied access to flooded contact form.');
-
-    // Test that the admin user can still access the contact form even though
-    // the flood limit was reached.
-    $this->drupalLogin($this->admin_user);
-    $this->assertNoText('Try again later.', 'Admin user not denied access to flooded contact form.');
-  }
-
-  /**
-   * Fill out a user's personal contact form and submit.
-   *
-   * @param $account
-   *   A user object of the user being contacted.
-   * @param $message
-   *   An optional array with the form fields being used.
-   */
-  protected function submitPersonalContact($account, array $message = array()) {
-    $message += array(
-      'subject' => $this->randomName(16),
-      'message' => $this->randomName(64),
-    );
-    $this->drupalPost('user/' . $account->uid . '/contact', $message, t('Send message'));
-  }
-}
diff --git a/modules/dashboard/dashboard-rtl.css b/modules/dashboard/dashboard-rtl.css
deleted file mode 100644
index cfccfa0..0000000
--- a/modules/dashboard/dashboard-rtl.css
+++ /dev/null
@@ -1,25 +0,0 @@
-#dashboard div.dashboard-region {
-  float: right;
-}
-#dashboard #disabled-blocks .block, #dashboard .block-placeholder {
-  float: right;
-  margin: 3px 0 3px 3px;
-  padding: 6px 8px 6px 4px;
-}
-#dashboard .canvas-content a.button {
-  margin: 0 10px 0 0;
-}
-#dashboard .ui-sortable .block h2 {
-  background-position: right -39px;
-  padding: 0 19px;
-}
-#dashboard.customize-inactive #disabled-blocks .block:hover h2 {
-  background-position: right -39px;
-}
-#dashboard.customize-inactive .dashboard-region .ui-sortable .block:hover h2 {
-  background-position: right -36px;
-}
-#dashboard div#dashboard_main {
-  margin-left: 1%;
-  margin-right: 0;
-}
diff --git a/modules/dashboard/dashboard.api.php b/modules/dashboard/dashboard.api.php
deleted file mode 100644
index 00bfde5..0000000
--- a/modules/dashboard/dashboard.api.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Hooks provided by the Dashboard module.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Adds regions to the dashboard.
- *
- * @return
- *   An array whose keys are the names of the dashboard regions and whose
- *   values are the titles that will be displayed in the blocks administration
- *   interface. The keys are also used as theme wrapper functions.
- */
-function hook_dashboard_regions() {
-  // Define a new dashboard region. Your module can also then define
-  // theme_mymodule_dashboard_region() as a theme wrapper function to control
-  // the region's appearance.
-  return array('mymodule_dashboard_region' => "My module's dashboard region");
-}
-
-/**
- * Alter dashboard regions provided by modules.
- *
- * @param $regions
- *   An array containing all dashboard regions, in the format provided by
- *   hook_dashboard_regions().
- */
-function hook_dashboard_regions_alter($regions) {
-  // Remove the sidebar region defined by the core dashboard module.
-  unset($regions['dashboard_sidebar']);
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/modules/dashboard/dashboard.css b/modules/dashboard/dashboard.css
deleted file mode 100644
index db9243c..0000000
--- a/modules/dashboard/dashboard.css
+++ /dev/null
@@ -1,130 +0,0 @@
-
-#dashboard div.dashboard-region {
-  float: left;
-  min-height: 1px;
-}
-
-#dashboard div#dashboard_main {
-  width: 65%;
-  margin-right: 1%; /* LTR */
-}
-
-#dashboard div#dashboard_sidebar {
-  width: 33%;
-}
-
-#dashboard div.block {
-  margin-bottom: 20px;
-}
-
-#dashboard .dashboard-region .block {
-  clear: both;
-}
-
-#dashboard div.block h2 {
-  float: none;
-}
-
-#dashboard #disabled-blocks .block,
-#dashboard .block-placeholder {
-  background: #e2e1dc;
-  padding: 6px 4px 6px 8px; /* LTR */
-  margin: 3px 3px 3px 0; /* LTR */
-  float: left; /* LTR */
-  -moz-border-radius: 4px;
-  -webkit-border-radius: 4px;
-  border-radius: 4px;
-}
-
-#dashboard .dashboard-add-other-blocks {
-  margin: 10px 0 0 0;
-}
-
-#dashboard .ui-sortable {
-  border: 2px dashed #ccc;
-  padding: 10px;
-}
-
-#dashboard .canvas-content {
-  padding: 10px;
-}
-
-#dashboard #disabled-blocks .ui-sortable {
-  padding: 0;
-  background-color: #777;
-  border: 0;
-}
-
-#dashboard .canvas-content a.button {
-  margin: 0 0 0 10px; /* LTR */
-  color: #5a5a5a;
-  text-decoration: none;
-}
-
-#dashboard .region {
-  margin: 5px;
-}
-
-#dashboard #disabled-blocks .region {
-  background-color: #E0E0D8;
-  border: #ccc 1px solid;
-  padding: 10px;
-}
-
-#dashboard #disabled-blocks {
-  padding: 5px 0;
-}
-
-#dashboard #disabled-blocks h2 {
-  display: inline;
-  font-weight: normal;
-  white-space: nowrap;
-}
-
-#dashboard #disabled-blocks .block {
-  background: #444;
-  color: #fff;
-}
-
-#dashboard.customize-inactive #disabled-blocks .block:hover {
-  background: #0074BD;
-}
-
-#dashboard #disabled-blocks .block .content,
-#dashboard .ui-sortable-helper .content {
-  display: none;
-}
-
-#dashboard .ui-sortable .block {
-  cursor: move;
-  min-height: 1px;
-}
-
-#dashboard .ui-sortable .block h2 {
-  background: transparent url(../../misc/draggable.png) no-repeat 0px -39px;
-  padding: 0 17px;
-}
-
-#dashboard.customize-inactive #disabled-blocks .block:hover h2 {
-  background: #0074BD url(../../misc/draggable.png) no-repeat 0px -39px;
-  color: #fff;
-}
-
-#dashboard.customize-inactive .dashboard-region .ui-sortable .block:hover h2 {
-  background: #0074BD url(../../misc/draggable.png) no-repeat;
-  background-position: 3px -36px;
-  color: #fff;
-}
-
-#dashboard .dashboard-region .block-placeholder {
-  margin: 0 0 20px 0;
-  padding: 0;
-  display: block;
-  height: 1.6em;
-  width: 100%;
-}
-
-#dashboard #disabled-blocks .block-placeholder {
-  width: 30px;
-  height: 1.6em;
-}
diff --git a/modules/dashboard/dashboard.info b/modules/dashboard/dashboard.info
deleted file mode 100644
index f98b235..0000000
--- a/modules/dashboard/dashboard.info
+++ /dev/null
@@ -1,8 +0,0 @@
-name = Dashboard
-description = Provides a dashboard page in the administrative interface for organizing administrative tasks and tracking information within your site.
-core = 8.x
-package = Core
-version = VERSION
-files[] = dashboard.test
-dependencies[] = block
-configure = admin/dashboard/customize
diff --git a/modules/dashboard/dashboard.install b/modules/dashboard/dashboard.install
deleted file mode 100644
index 5021826..0000000
--- a/modules/dashboard/dashboard.install
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the dashboard module.
- */
-
-/**
- * Implements hook_disable().
- *
- * Stash a list of blocks enabled on the dashboard, so they can be re-enabled
- * if the dashboard is re-enabled. Then disable those blocks, since the
- * dashboard regions will no longer be defined.
- */
-function dashboard_disable() {
-  // Stash a list of currently enabled blocks.
-  $stashed_blocks = array();
-
-  $result = db_select('block', 'b')
-    ->fields('b', array('module', 'delta', 'region'))
-    ->condition('b.region', dashboard_regions(), 'IN')
-    ->execute();
-
-  foreach ($result as $block) {
-    $stashed_blocks[] = array(
-      'module' => $block->module,
-      'delta' => $block->delta,
-      'region' => $block->region,
-    );
-  }
-  variable_set('dashboard_stashed_blocks', $stashed_blocks);
-
-  // Disable the dashboard blocks.
-  db_update('block')
-    ->fields(array(
-      'status' => 0,
-      'region' => BLOCK_REGION_NONE,
-    ))
-    ->condition('region', dashboard_regions(), 'IN')
-    ->execute();
-}
-
-/**
- * Implements hook_enable().
- *
- * Restores blocks to the dashboard that were there when the dashboard module
- * was disabled.
- */
-function dashboard_enable() {
-  global $theme_key;
-  if (!$stashed_blocks = variable_get('dashboard_stashed_blocks')) {
-    return;
-  }
-  if (!$admin_theme = variable_get('admin_theme')) {
-    drupal_theme_initialize();
-    $admin_theme = $theme_key;
-  }
-  foreach ($stashed_blocks as $block) {
-    db_update('block')
-      ->fields(array(
-        'status' => 1,
-        'region' => $block['region']
-      ))
-      ->condition('module', $block['module'])
-      ->condition('delta', $block['delta'])
-      ->condition('theme', $admin_theme)
-      ->condition('status', 0)
-      ->execute();
-  }
-  variable_del('dashboard_stashed_blocks');
-}
-
-/**
- * Implements hook_uninstall().
- */
-function dashboard_uninstall() {
-  variable_del('dashboard_stashed_blocks');
-}
diff --git a/modules/dashboard/dashboard.js b/modules/dashboard/dashboard.js
deleted file mode 100644
index ebecbf6..0000000
--- a/modules/dashboard/dashboard.js
+++ /dev/null
@@ -1,218 +0,0 @@
-(function ($) {
-
-/**
- * Implementation of Drupal.behaviors for dashboard.
- */
-Drupal.behaviors.dashboard = {
-    attach: function (context, settings) {
-    $('#dashboard', context).once(function () {
-      $(this).prepend('<div class="customize clearfix"><ul class="action-links"><li><a href="#">' + Drupal.t('Customize dashboard') + '</a></li></ul><div class="canvas"></div></div>');
-      $('.customize .action-links a', this).click(Drupal.behaviors.dashboard.enterCustomizeMode);
-    });
-    Drupal.behaviors.dashboard.addPlaceholders();
-    if (Drupal.settings.dashboard.launchCustomize) {
-      Drupal.behaviors.dashboard.enterCustomizeMode();
-    }
-  },
-
-  addPlaceholders: function() {
-    $('#dashboard .dashboard-region .region').each(function () {
-      var empty_text = "";
-      // If the region is empty
-      if ($('.block', this).length == 0) {
-        // Check if we are in customize mode and grab the correct empty text
-        if ($('#dashboard').hasClass('customize-mode')) {
-          empty_text = Drupal.settings.dashboard.emptyRegionTextActive;
-        } else {
-          empty_text = Drupal.settings.dashboard.emptyRegionTextInactive;
-        }
-        // We need a placeholder.
-        if ($('.placeholder', this).length == 0) {
-          $(this).append('<div class="placeholder"></div>');
-        }
-        $('.placeholder', this).html(empty_text);
-      }
-      else {
-        $('.placeholder', this).remove();
-      }
-    });
-  },
-
-  /**
-   * Enter "customize" mode by displaying disabled blocks.
-   */
-  enterCustomizeMode: function () {
-    $('#dashboard').addClass('customize-mode customize-inactive');
-    Drupal.behaviors.dashboard.addPlaceholders();
-    // Hide the customize link
-    $('#dashboard .customize .action-links').hide();
-    // Load up the disabled blocks
-    $('div.customize .canvas').load(Drupal.settings.dashboard.drawer, Drupal.behaviors.dashboard.setupDrawer);
-  },
-
-  /**
-   * Exit "customize" mode by simply forcing a page refresh.
-   */
-  exitCustomizeMode: function () {
-    $('#dashboard').removeClass('customize-mode customize-inactive');
-    Drupal.behaviors.dashboard.addPlaceholders();
-    location.href = Drupal.settings.dashboard.dashboard;
-  },
-
-  /**
-   * Helper for enterCustomizeMode; sets up drag-and-drop and close button.
-   */
-  setupDrawer: function () {
-    $('div.customize .canvas-content input').click(Drupal.behaviors.dashboard.exitCustomizeMode);
-    $('div.customize .canvas-content').append('<a class="button" href="' + Drupal.settings.dashboard.dashboard + '">' + Drupal.t('Done') + '</a>');
-
-    // Initialize drag-and-drop.
-    var regions = $('#dashboard div.region');
-    regions.sortable({
-      connectWith: regions,
-      cursor: 'move',
-      cursorAt: {top:0},
-      dropOnEmpty: true,
-      items: '> div.block, > div.disabled-block',
-      placeholder: 'block-placeholder clearfix',
-      tolerance: 'pointer',
-      start: Drupal.behaviors.dashboard.start,
-      over: Drupal.behaviors.dashboard.over,
-      sort: Drupal.behaviors.dashboard.sort,
-      update: Drupal.behaviors.dashboard.update
-    });
-  },
-
-  /**
-   * While dragging, make the block appear as a disabled block
-   *
-   * This function is called on the jQuery UI Sortable "start" event.
-   *
-   * @param event
-   *  The event that triggered this callback.
-   * @param ui
-   *  An object containing information about the item that is being dragged.
-   */
-  start: function (event, ui) {
-    $('#dashboard').removeClass('customize-inactive');
-    var item = $(ui.item);
-
-    // If the block is already in disabled state, don't do anything.
-    if (!item.hasClass('disabled-block')) {
-      item.css({height: 'auto'});
-    }
-  },
-
-  /**
-   * While dragging, adapt block's width to the width of the region it is moved
-   * into.
-   *
-   * This function is called on the jQuery UI Sortable "over" event.
-   *
-   * @param event
-   *  The event that triggered this callback.
-   * @param ui
-   *  An object containing information about the item that is being dragged.
-   */
-  over: function (event, ui) {
-    var item = $(ui.item);
-
-    // If the block is in disabled state, remove width.
-    if ($(this).closest('#disabled-blocks').length) {
-      item.css('width', '');
-    }
-    else {
-      item.css('width', $(this).width());
-    }
-  },
-
-  /**
-   * While dragging, adapt block's position to stay connected with the position
-   * of the mouse pointer.
-   *
-   * This function is called on the jQuery UI Sortable "sort" event.
-   *
-   * @param event
-   *  The event that triggered this callback.
-   * @param ui
-   *  An object containing information about the item that is being dragged.
-   */
-  sort: function (event, ui) {
-    var item = $(ui.item);
-
-    if (event.pageX > ui.offset.left + item.width()) {
-      item.css('left', event.pageX);
-    }
-  },
-
-  /**
-   * Send block order to the server, and expand previously disabled blocks.
-   *
-   * This function is called on the jQuery UI Sortable "update" event.
-   *
-   * @param event
-   *   The event that triggered this callback.
-   * @param ui
-   *   An object containing information about the item that was just dropped.
-   */
-  update: function (event, ui) {
-    $('#dashboard').addClass('customize-inactive');
-    var item = $(ui.item);
-
-    // If the user dragged a disabled block, load the block contents.
-    if (item.hasClass('disabled-block')) {
-      var module, delta, itemClass;
-      itemClass = item.attr('class');
-      // Determine the block module and delta.
-      module = itemClass.match(/\bmodule-(\S+)\b/)[1];
-      delta = itemClass.match(/\bdelta-(\S+)\b/)[1];
-
-      // Load the newly enabled block's content.
-      $.get(Drupal.settings.dashboard.blockContent + '/' + module + '/' + delta, {},
-        function (block) {
-          if (block) {
-            item.html(block);
-          }
-
-          if (item.find('div.content').is(':empty')) {
-            item.find('div.content').html(Drupal.settings.dashboard.emptyBlockText);
-          }
-
-          Drupal.attachBehaviors(item);
-        },
-        'html'
-      );
-      // Remove the "disabled-block" class, so we don't reload its content the
-      // next time it's dragged.
-      item.removeClass("disabled-block");
-    }
-
-    Drupal.behaviors.dashboard.addPlaceholders();
-
-    // Let the server know what the new block order is.
-    $.post(Drupal.settings.dashboard.updatePath, {
-        'form_token': Drupal.settings.dashboard.formToken,
-        'regions': Drupal.behaviors.dashboard.getOrder
-      }
-    );
-  },
-
-  /**
-   * Return the current order of the blocks in each of the sortable regions,
-   * in query string format.
-   */
-  getOrder: function () {
-    var order = [];
-    $('#dashboard div.region').each(function () {
-      var region = $(this).parent().attr('id').replace(/-/g, '_');
-      var blocks = $(this).sortable('toArray');
-      $.each(blocks, function() {
-        order.push(region + '[]=' + this);
-      });
-    });
-    order = order.join('&');
-    return order;
-  }
-};
-
-})(jQuery);
diff --git a/modules/dashboard/dashboard.module b/modules/dashboard/dashboard.module
deleted file mode 100644
index 08a4cd2..0000000
--- a/modules/dashboard/dashboard.module
+++ /dev/null
@@ -1,677 +0,0 @@
-<?php
-
-/**
- * Implements hook_help().
- */
-function dashboard_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#dashboard':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Dashboard module provides a <a href="@dashboard">Dashboard page</a> in the administrative interface for organizing administrative tasks and navigation, and tracking information within your site. The Dashboard page contains blocks, which you can add to and arrange using the drag-and-drop interface that appears when you click on the <em>Customize dashboard</em> link. Within this interface, blocks that are not primarily used for site administration do not appear by default, but can be added via the <em>Add other blocks</em> link. For more information, see the online handbook entry for <a href="@handbook">Dashboard module</a>.', array('@handbook' => 'http://drupal.org/handbook/modules/dashboard', '@dashboard' => url('admin/dashboard'))) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Tracking user activity') . '</dt>';
-      $output .= '<dd>' . t("By enabling blocks such as <em>Who's online</em> and <em>Who's new</em>, site users can track who is logged in and new user signups at a centralized location.") . '</dd>';
-      $output .= '<dt>' . t('Tracking content activity') . '</dt>';
-      $output .= '<dd>' . t('By enabling blocks such as <em>Recent blog posts</em>, <em>New forum topics</em> and <em>Recent comments</em>, site users can view newly added site content at a glance.') . '</dd>';
-      $output .= '</dl>';
-      return $output;
-
-    case 'admin/dashboard/configure':
-      // @todo This assumes the current page is being displayed using the same
-      //   theme that the dashboard is displayed in.
-      $output = '<p>' . t('Rearrange blocks for display on the <a href="@dashboard-url">Dashboard page</a>. Blocks placed in the <em>Dashboard (inactive)</em> region are not displayed when viewing the Dashboard page, but are available within its <em>Customize dashboard</em> interface. Removing a block from active dashboard display makes it available on the main <a href="@blocks-url">blocks administration page</a>.', array('@dashboard-url' => url('admin/dashboard'), '@blocks-url' => url("admin/structure/block/list/{$GLOBALS['theme_key']}"))) . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_menu().
- */
-function dashboard_menu() {
-  $items['admin/dashboard'] = array(
-    'title' => 'Dashboard',
-    'description' => 'View and customize your dashboard.',
-    'page callback' => 'dashboard_admin',
-    'access arguments' => array('access dashboard'),
-    // Make this appear first, so for example, in admin menus, it shows up on
-    // the top corner of the window as a convenient "home link".
-    'weight' => -15,
-  );
-  $items['admin/dashboard/configure'] = array(
-    'title' => 'Configure available dashboard blocks',
-    'description' => 'Configure which blocks can be shown on the dashboard.',
-    'page callback' => 'dashboard_admin_blocks',
-    'access arguments' => array('administer blocks'),
-    'type' => MENU_VISIBLE_IN_BREADCRUMB,
-  );
-  $items['admin/dashboard/customize'] = array(
-    'title' => 'Customize dashboard',
-    'description' => 'Customize your dashboard.',
-    'page callback' => 'dashboard_admin',
-    'page arguments' => array(TRUE),
-    'access arguments' => array('access dashboard'),
-    'type' => MENU_VISIBLE_IN_BREADCRUMB,
-  );
-  $items['admin/dashboard/drawer'] = array(
-    'page callback' => 'dashboard_show_disabled',
-    'access arguments' => array('administer blocks'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['admin/dashboard/block-content/%/%'] = array(
-    'page callback' => 'dashboard_show_block_content',
-    'page arguments' => array(3, 4),
-    'access arguments' => array('administer blocks'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['admin/dashboard/update'] = array(
-    'page callback' => 'dashboard_update',
-    'access arguments' => array('administer blocks'),
-    'type' => MENU_CALLBACK,
-  );
-
-  return $items;
-}
-
-/**
- * Implements hook_permission().
- */
-function dashboard_permission() {
-  return array(
-    'access dashboard' => array(
-      'title' => t('View the administrative dashboard'),
-      // Note: We translate the 'Administer blocks' permission string here with
-      // a separate t() call, to make sure it gets the same translation as when
-      // it's in block_permission().
-      'description' => t('Customizing the dashboard requires the !permission-name permission.', array(
-        '!permission-name' => l(t('Administer blocks'), 'admin/people/permissions', array('fragment' => 'module-block')),
-      )),
-    ),
-  );
-}
-
-/**
- * Implements hook_block_info_alter().
- */
-function dashboard_block_info_alter(&$blocks, $theme, $code_blocks) {
-  $admin_theme = variable_get('admin_theme');
-  if (($admin_theme && $theme == $admin_theme) || (!$admin_theme && $theme == variable_get('theme_default', 'bartik'))) {
-    foreach ($blocks as $module => &$module_blocks) {
-      foreach ($module_blocks as $delta => &$block) {
-        // Make administrative blocks that are not already in use elsewhere
-        // available for the dashboard.
-        if (empty($block['status']) && (empty($block['region']) || $block['region'] == BLOCK_REGION_NONE) && !empty($code_blocks[$module][$delta]['properties']['administrative'])) {
-          $block['status'] = 1;
-          $block['region'] = 'dashboard_inactive';
-        }
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_block_list_alter().
- *
- * Skip rendering dashboard blocks when not on the dashboard page itself. This
- * prevents expensive dashboard blocks from causing performance issues on pages
- * where they will never be displayed.
- */
-function dashboard_block_list_alter(&$blocks) {
-  if (!dashboard_is_visible()) {
-    foreach ($blocks as $key => $block) {
-      if (in_array($block->region, dashboard_regions())) {
-        unset($blocks[$key]);
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_page_build().
- *
- * Display dashboard blocks in the main content region.
- */
-function dashboard_page_build(&$page) {
-  global $theme_key;
-
-  if (dashboard_is_visible()) {
-    $block_info = array();
-
-    // Create a wrapper for the dashboard itself, then insert each dashboard
-    // region into it.
-    $page['content']['dashboard'] = array('#theme_wrappers' => array('dashboard'));
-    foreach (dashboard_regions() as $region) {
-      // Do not show dashboard blocks that are disabled.
-      if ($region == 'dashboard_inactive') {
-        continue;
-      }
-      // Insert regions even when they are empty, so that they will be
-      // displayed when the dashboard is being configured.
-      $page['content']['dashboard'][$region] = !empty($page[$region]) ? $page[$region] : array();
-      $page['content']['dashboard'][$region]['#dashboard_region'] = $region;
-      // Allow each dashboard region to be themed differently, or fall back on
-      // the generic theme wrapper function for dashboard regions.
-      $page['content']['dashboard'][$region]['#theme_wrappers'][] = array($region, 'dashboard_region');
-      unset($page[$region]);
-      $blocks_found = array();
-      foreach ($page['content']['dashboard'][$region] as $item) {
-        if (isset($item['#theme_wrappers']) && is_array($item['#theme_wrappers']) && in_array('block', $item['#theme_wrappers'])) {
-          // If this item is a block, ensure it has a subject.
-          if (empty($item['#block']->subject)) {
-            // Locally cache info data for the object for all blocks, in case
-            // we find a block similarly missing title from the same module.
-            if (!isset($block_info[$item['#block']->module])) {
-              $block_info[$item['#block']->module] = module_invoke($item['#block']->module, 'block_info');
-            }
-            $item['#block']->subject = $block_info[$item['#block']->module][$item['#block']->delta]['info'];
-          }
-          $blocks_found[$item['#block']->module . '_' . $item['#block']->delta] = TRUE;
-        }
-      }
-
-      // Find blocks which were not yet displayed on the page (were empty), and
-      // add placeholder items in their place for rendering.
-      $block_list = db_select('block')
-        ->condition('theme', $theme_key)
-        ->condition('status', 1)
-        ->condition('region', $region)
-        ->fields('block')
-        ->execute();
-      foreach ($block_list as $block) {
-        if (!isset($blocks_found[$block->module . '_' . $block->delta])) {
-          $block->enabled = $block->page_match = TRUE;
-          $block->content = array('#markup' => '<div class="dashboard-block-empty">(empty)</div>');
-          if (!isset($block_info[$block->module])) {
-            $block_info[$block->module] = module_invoke($block->module, 'block_info');
-          }
-          $block->subject = t('@title', array('@title' => $block_info[$block->module][$block->delta]['info']));
-          $block_render = array($block->module . '_' . $block->delta => $block);
-          $build = _block_get_renderable_array($block_render);
-          $page['content']['dashboard'][$block->region][] = $build;
-        }
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_system_info_alter().
- *
- * Add regions to each theme to store the dashboard blocks.
- */
-function dashboard_system_info_alter(&$info, $file, $type) {
-  if ($type == 'theme') {
-    // Add the dashboard regions (the "inactive" region should always appear
-    // last in the list, for usability reasons).
-    $dashboard_regions = dashboard_region_descriptions();
-    if (isset($dashboard_regions['dashboard_inactive'])) {
-      $inactive_region = $dashboard_regions['dashboard_inactive'];
-      unset($dashboard_regions['dashboard_inactive']);
-      $dashboard_regions['dashboard_inactive'] = $inactive_region;
-    }
-    $info['regions'] += $dashboard_regions;
-    // Indicate that these regions are intended to be displayed whenever the
-    // dashboard is displayed in an overlay. This information is provided for
-    // any module that might need to use it, not just the core Overlay module.
-    $info['overlay_regions'] = !empty($info['overlay_regions']) ? array_merge($info['overlay_regions'], dashboard_regions()) : dashboard_regions();
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function dashboard_theme() {
-  return array(
-    'dashboard' => array(
-      'render element' => 'element',
-    ),
-    'dashboard_admin' => array(
-      'render element' => 'element',
-    ),
-    'dashboard_region' => array(
-      'render element' => 'element',
-    ),
-    'dashboard_disabled_blocks' => array(
-      'variables' => array('blocks' => NULL),
-    ),
-    'dashboard_disabled_block' => array(
-      'variables' => array('block' => NULL),
-    ),
-    'dashboard_admin_display_form' => array(
-      // When building the form for configuring dashboard blocks, reuse the
-      // Block module's template for the main block configuration form.
-      'template' => 'block-admin-display-form',
-      'path' => drupal_get_path('module', 'block'),
-      'file' => 'block.admin.inc',
-      'render element' => 'form',
-    ),
-  );
-}
-
-/**
- * Implements hook_forms().
- */
-function dashboard_forms() {
-  // Reroute the dashboard configuration form to the main blocks administration
-  // form. This allows us to distinguish them by form ID in hook_form_alter().
-  $forms['dashboard_admin_display_form'] = array(
-    'callback' => 'block_admin_display_form',
-  );
-
-  return $forms;
-}
-
-/**
- * Dashboard page callback.
- *
- * @param $launch_customize
- *   Whether to launch in customization mode right away. TRUE or FALSE.
- */
-function dashboard_admin($launch_customize = FALSE) {
-  $js_settings = array(
-    'dashboard' => array(
-      'drawer' => url('admin/dashboard/drawer'),
-      'blockContent' => url('admin/dashboard/block-content'),
-      'updatePath' => url('admin/dashboard/update'),
-      'formToken' => drupal_get_token('dashboard-update'),
-      'launchCustomize' => $launch_customize,
-      'dashboard' => url('admin/dashboard'),
-      'emptyBlockText' => t('(empty)'),
-      'emptyRegionTextInactive' => t('This dashboard region is empty. Click <em>Customize dashboard</em> to add blocks to it.'),
-      'emptyRegionTextActive' => t('DRAG HERE'),
-    ),
-  );
-  $build = array(
-    '#theme' => 'dashboard_admin',
-    '#message' => t('To customize the dashboard page, move blocks to the dashboard regions on the <a href="@dashboard">Dashboard administration page</a>, or enable JavaScript on this page to use the drag-and-drop interface.', array('@dashboard' => url('admin/dashboard/configure'))),
-    '#access' => user_access('administer blocks'),
-    '#attached' => array(
-      'js' => array(
-        drupal_get_path('module', 'dashboard') . '/dashboard.js',
-        array('data' => $js_settings, 'type' => 'setting'),
-      ),
-      'library' => array(array('system', 'ui.sortable')),
-    ),
-  );
-  return $build;
-}
-
-/**
- * Menu page callback: builds the page for administering dashboard blocks.
- *
- * This page reuses the Block module's administration form but limits editing
- * to blocks that are available to appear on the dashboard.
- *
- * @see block_admin_display()
- * @see block_admin_display_form()
- * @see dashboard_form_dashboard_admin_display_form_alter()
- * @see template_preprocess_dashboard_admin_display_form()
- */
-function dashboard_admin_blocks() {
-  global $theme_key;
-  drupal_theme_initialize();
-  module_load_include('inc', 'block', 'block.admin');
-
-  // Prepare the blocks for the current theme, and remove those that are
-  // currently displayed in non-dashboard regions.
-  // @todo This assumes the current page is being displayed using the same
-  //   theme that the dashboard is displayed in.
-  $blocks = block_admin_display_prepare_blocks($theme_key);
-  $dashboard_regions = dashboard_region_descriptions();
-  $regions_to_remove = array_diff_key(system_region_list($theme_key, REGIONS_VISIBLE), $dashboard_regions);
-  foreach ($blocks as $id => $block) {
-    if (isset($regions_to_remove[$block['region']])) {
-      unset($blocks[$id]);
-    }
-  }
-
-  // Pass in the above blocks and dashboard regions to the form, so that only
-  // dashboard-related regions will be displayed.
-  return drupal_get_form('dashboard_admin_display_form', $blocks, $theme_key, $dashboard_regions);
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function dashboard_form_block_admin_display_form_alter(&$form, &$form_state, $form_id) {
-  // Hide dashboard regions (and any blocks placed within them) from the block
-  // administration form and from the options list on that form. This
-  // function is called for both the dashboard block configuration form and the
-  // standard block configuration form so that both forms can share the same
-  // constructor. As a result the form_id must be checked.
-  if ($form_id != 'dashboard_admin_display_form') {
-    $dashboard_regions = dashboard_region_descriptions();
-    $form['block_regions']['#value'] = array_diff_key($form['block_regions']['#value'], $dashboard_regions);
-    foreach (element_children($form['blocks']) as $i) {
-      $block = &$form['blocks'][$i];
-      if (isset($block['region']['#default_value']) && isset($dashboard_regions[$block['region']['#default_value']]) && $block['region']['#default_value'] != 'dashboard_inactive') {
-        $block['#access'] = FALSE;
-      }
-      elseif (isset($block['region']['#options'])) {
-        $block['region']['#options'] = array_diff_key($block['region']['#options'], $dashboard_regions);
-      }
-      // Show inactive dashboard blocks as disabled on the main block
-      // administration form, so that they are available to place in other
-      // regions of the theme. Note that when the form is submitted, any such
-      // blocks which still remain disabled will immediately be put back in the
-      // 'dashboard_inactive' region, because dashboard_block_info_alter() is
-      // called when the blocks are rehashed. Fortunately, this is the exact
-      // behavior we want.
-      if ($block['region']['#default_value'] == 'dashboard_inactive') {
-        // @todo These do not wind up in correct alphabetical order.
-        $block['region']['#default_value'] = NULL;
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function dashboard_form_dashboard_admin_display_form_alter(&$form, &$form_state) {
-  // Redirect the 'configure' and 'delete' links on each block back to the
-  // dashboard blocks administration page.
-  foreach ($form['blocks'] as &$block) {
-    if (isset($block['configure']['#href'])) {
-      $block['configure']['#options']['query']['destination'] = 'admin/dashboard/configure';
-    }
-    if (isset($block['delete']['#href'])) {
-      $block['delete']['#options']['query']['destination'] = 'admin/dashboard/configure';
-    }
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function dashboard_form_block_admin_configure_alter(&$form, &$form_state) {
-  global $theme_key;
-  drupal_theme_initialize();
-  // Hide the dashboard regions from the region select list on the block
-  // configuration form, for all themes except the current theme (since the
-  // other themes do not display the dashboard).
-  // @todo This assumes the current page is being displayed using the same
-  //   theme that the dashboard is displayed in.
-  $dashboard_regions = dashboard_region_descriptions();
-  foreach (element_children($form['regions']) as $region_name) {
-    $region = &$form['regions'][$region_name];
-    if ($region_name != $theme_key && isset($region['#options'])) {
-      $region['#options'] = array_diff_key($region['#options'], $dashboard_regions);
-    }
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function dashboard_form_block_add_block_form_alter(&$form, &$form_state) {
-  dashboard_form_block_admin_configure_alter($form, $form_state);
-}
-
-/**
- * Preprocesses variables for block-admin-display-form.tpl.php.
- */
-function template_preprocess_dashboard_admin_display_form(&$variables) {
-  template_preprocess_block_admin_display_form($variables);
-  if (isset($variables['block_regions'][BLOCK_REGION_NONE])) {
-    $variables['block_regions'][BLOCK_REGION_NONE] = t('Other blocks');
-  }
-}
-
-/**
- * Determines if the dashboard should be displayed on the current page.
- *
- * This function checks if the user is currently viewing the dashboard and has
- * access to see it. It is used by other functions in the dashboard module to
- * decide whether or not the dashboard content should be displayed to the
- * current user.
- *
- * Although the menu system normally handles the above tasks, it only does so
- * for the main page content. However, the dashboard is not part of the main
- * page content, but rather is displayed in special regions of the page (so it
- * can interface with the Block module's method of managing page regions). We
- * therefore need to maintain this separate function to check the menu item for
- * us.
- *
- * @return
- *   TRUE if the dashboard should be visible on the current page, FALSE
- *   otherwise.
- *
- * @see dashboard_block_list_alter()
- * @see dashboard_page_build()
- */
-function dashboard_is_visible() {
-  static $is_visible;
-  if (!isset($is_visible)) {
-    // If the current menu item represents the page on which we want to display
-    // the dashboard, and if the current user has access to see it, return
-    // TRUE.
-    $menu_item = menu_get_item();
-    $is_visible = isset($menu_item['page_callback']) && $menu_item['page_callback'] == 'dashboard_admin' && !empty($menu_item['access']);
-  }
-  return $is_visible;
-}
-
-/**
- * Return an array of dashboard region descriptions, keyed by region name.
- */
-function dashboard_region_descriptions() {
-  $regions = module_invoke_all('dashboard_regions');
-  drupal_alter('dashboard_regions', $regions);
-  return $regions;
-}
-
-/**
- * Return an array of dashboard region names.
- */
-function dashboard_regions() {
-  $regions = &drupal_static(__FUNCTION__);
-  if (!isset($regions)) {
-    $regions = array_keys(dashboard_region_descriptions());
-  }
-  return $regions;
-}
-
-/**
- * Implements hook_dashboard_regions().
- */
-function dashboard_dashboard_regions() {
-  return array(
-    'dashboard_main' => 'Dashboard (main)',
-    'dashboard_sidebar' => 'Dashboard (sidebar)',
-    'dashboard_inactive' => 'Dashboard (inactive)',
-  );
-}
-
-/**
- * Ajax callback to show disabled blocks in the dashboard customization mode.
- */
-function dashboard_show_disabled() {
-  global $theme_key;
-
-  // Blocks are not necessarily initialized at this point.
-  $blocks = _block_rehash();
-
-  // Limit the list to blocks that are marked as disabled for the dashboard.
-  foreach ($blocks as $key => $block) {
-    if ($block['theme'] != $theme_key || $block['region'] != 'dashboard_inactive') {
-      unset($blocks[$key]);
-    }
-  }
-
-  // Theme the output and end the page request.
-  print theme('dashboard_disabled_blocks', array('blocks' => $blocks));
-  drupal_exit();
-}
-
-/**
- * Ajax callback to display the rendered contents of a specific block.
- *
- * @param $module
- *   The block's module name.
- * @param $delta
- *   The block's delta.
- */
-function dashboard_show_block_content($module, $delta) {
-  drupal_theme_initialize();
-  global $theme_key;
-
-  $blocks = array();
-  $block_object = db_query("SELECT * FROM {block} WHERE theme = :theme AND module = :module AND delta = :delta", array(
-    ":theme" => $theme_key,
-    ":module" => $module,
-    ":delta" => $delta,
-    ))
-    ->fetchObject();
-  $block_object->enabled = $block_object->page_match = TRUE;
-  $blocks[$module . "_" . $delta] = $block_object;
-  $block_content = _block_render_blocks($blocks);
-  $build = _block_get_renderable_array($block_content);
-  $rendered_block = drupal_render($build);
-  print $rendered_block;
-  drupal_exit();
-}
-
-/**
- * Set the new weight of each region according to the drag-and-drop order.
- */
-function dashboard_update() {
-  drupal_theme_initialize();
-  global $theme_key;
-  // Check the form token to make sure we have a valid request.
-  if (!empty($_REQUEST['form_token']) && drupal_valid_token($_REQUEST['form_token'], 'dashboard-update')) {
-    parse_str($_REQUEST['regions'], $regions);
-    foreach ($regions as $region_name => $blocks) {
-      if ($region_name == 'disabled_blocks') {
-        $region_name = 'dashboard_inactive';
-      }
-      foreach ($blocks as $weight => $block_string) {
-        // Parse the query string to determine the block's module and delta.
-        preg_match('/block-([^-]+)-(.+)/', $block_string, $matches);
-        $block = new stdClass();
-        $block->module = $matches[1];
-        $block->delta = $matches[2];
-
-        $block->region = $region_name;
-        $block->weight = $weight;
-        $block->status = 1;
-
-        db_merge('block')
-          ->key(array(
-            'module' => $block->module,
-            'delta' => $block->delta,
-            'theme' => $theme_key,
-          ))
-          ->fields(array(
-            'status' => $block->status,
-            'weight' => $block->weight,
-            'region' => $block->region,
-            'pages' => '',
-          ))
-          ->execute();
-      }
-    }
-    drupal_set_message(t('The configuration options have been saved.'), 'status', FALSE);
-  }
-  drupal_exit();
-}
-
-/**
- * Returns HTML for the entire dashboard.
- *
- * @param $variables
- *   An associative array containing:
- *   - element: A render element containing the properties of the dashboard
- *     region element, #dashboard_region and #children.
- *
- * @ingroup themeable
- */
-function theme_dashboard($variables) {
-  extract($variables);
-  drupal_add_css(drupal_get_path('module', 'dashboard') . '/dashboard.css');
-  return '<div id="dashboard" class="clearfix">' . $element['#children'] . '</div>';
-}
-
-/**
- * Returns HTML for the non-customizable part of the dashboard page.
- *
- * @param $variables
- *   An associative array containing:
- *   - element: A render element containing a #message.
- *
- * @ingroup themeable
- */
-function theme_dashboard_admin($variables) {
-  // We only return a simple help message, since the actual content of the page
-  // will be populated via the dashboard regions in dashboard_page_build().
-  return '<div class="customize-dashboard js-hide">' . $variables['element']['#message'] . '</div>';
-}
-
-/**
- * Returns HTML for a generic dashboard region.
- *
- * @param $variables
- *   An associative array containing:
- *   - element: A render element containing the properties of the dashboard
- *     region element, #dashboard_region and #children.
- *
- * @ingroup themeable
- */
-function theme_dashboard_region($variables) {
-  extract($variables);
-  $output = '<div id="' . $element['#dashboard_region'] . '" class="dashboard-region">';
-  $output .= '<div class="region clearfix">';
-  $output .= $element['#children'];
-  // Closing div.region
-  $output .= '</div>';
-  // Closing div.dashboard-region
-  $output .= '</div>';
-  return $output;
-}
-
-/**
- * Returns HTML for a set of disabled blocks, for display in dashboard customization mode.
- *
- * @param $variables
- *   An associative array containing:
- *   - blocks: An array of block objects from _block_rehash().
- *
- * @ingroup themeable
- */
-function theme_dashboard_disabled_blocks($variables) {
-  extract($variables);
-  $output = '<div class="canvas-content"><p>' . t('Drag and drop these blocks to the columns below. Changes are automatically saved. More options are available on the <a href="@dashboard-url">configuration page</a>.', array('@dashboard-url' => url('admin/dashboard/configure'))) . '</p>';
-  $output .= '<div id="disabled-blocks"><div class="region disabled-blocks clearfix">';
-  foreach ($blocks as $block) {
-    $output .= theme('dashboard_disabled_block', array('block' => $block));
-  }
-  $output .= '<div class="clearfix"></div>';
-  $output .= '<p class="dashboard-add-other-blocks">' . l(t('Add other blocks'), 'admin/dashboard/configure') . '</p>';
-  $output .= '</div></div></div>';
-  return $output;
-}
-
-/**
- * Returns HTML for a disabled block, for display in dashboard customization mode.
- *
- * @param $variables
- *   An associative array containing:
- *   - block: A block object from _block_rehash().
- *
- * @ingroup themeable
- */
-function theme_dashboard_disabled_block($variables) {
-  extract($variables);
-  $output = "";
-  if (isset($block)) {
-    $output .= '<div id="block-' . $block['module'] . '-' . $block['delta']
-    . '" class="disabled-block block block-' . $block['module'] . '-' . $block['delta']
-    . ' module-' . $block['module'] . ' delta-' . $block['delta'] . '">'
-    . '<h2>' . (!empty($block['title']) && $block['title'] != '<none>' ? check_plain($block['title']) : check_plain($block['info'])) . '</h2>'
-    . '<div class="content"></div>'
-    . '</div>';
-  }
-  return $output;
-}
-
diff --git a/modules/dashboard/dashboard.test b/modules/dashboard/dashboard.test
deleted file mode 100644
index 7cb93f9..0000000
--- a/modules/dashboard/dashboard.test
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for dashboard.module.
- */
-
-class DashboardBlocksTestCase extends DrupalWebTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Dashboard blocks',
-      'description' => 'Test blocks as used by the dashboard.',
-      'group' => 'Dashboard',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-
-    // Create and log in an administrative user having access to the dashboard.
-    $admin_user = $this->drupalCreateUser(array('access dashboard', 'administer blocks', 'access administration pages', 'administer modules'));
-    $this->drupalLogin($admin_user);
-
-    // Make sure that the dashboard is using the same theme as the rest of the
-    // site (and in particular, the same theme used on 403 pages). This forces
-    // the dashboard blocks to be the same for an administrator as for a
-    // regular user, and therefore lets us test that the dashboard blocks
-    // themselves are specifically removed for a user who does not have access
-    // to the dashboard page.
-    theme_enable(array('stark'));
-    variable_set('theme_default', 'stark');
-    variable_set('admin_theme', 'stark');
-  }
-
-  /**
-   * Test adding a block to the dashboard and checking access to it.
-   */
-  function testDashboardAccess() {
-    // Add a new custom block to a dashboard region.
-    $custom_block = array();
-    $custom_block['info'] = $this->randomName(8);
-    $custom_block['title'] = $this->randomName(8);
-    $custom_block['body[value]'] = $this->randomName(32);
-    $custom_block['regions[stark]'] = 'dashboard_main';
-    $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
-
-    // Ensure admin access.
-    $this->drupalGet('admin/dashboard');
-    $this->assertResponse(200, t('Admin has access to the dashboard.'));
-    $this->assertRaw($custom_block['title'], t('Admin has access to a dashboard block.'));
-
-    // Ensure non-admin access is denied.
-    $normal_user = $this->drupalCreateUser();
-    $this->drupalLogin($normal_user);
-    $this->drupalGet('admin/dashboard');
-    $this->assertResponse(403, t('Non-admin has no access to the dashboard.'));
-    $this->assertNoText($custom_block['title'], t('Non-admin has no access to a dashboard block.'));
-  }
-
-  /**
-   * Test that dashboard regions are displayed or hidden properly.
-   */
-  function testDashboardRegions() {
-    $dashboard_regions = dashboard_region_descriptions();
-
-    // Ensure blocks can be placed in dashboard regions.
-    $this->drupalGet('admin/dashboard/configure');
-    foreach ($dashboard_regions as $region => $description) {
-      $elements = $this->xpath('//option[@value=:region]', array(':region' => $region));
-      $this->assertTrue(!empty($elements), t('%region is an available choice on the dashboard block configuration page.', array('%region' => $region)));
-    }
-
-    // Ensure blocks cannot be placed in dashboard regions on the standard
-    // blocks configuration page.
-    $this->drupalGet('admin/structure/block');
-    foreach ($dashboard_regions as $region => $description) {
-      $elements = $this->xpath('//option[@value=:region]', array(':region' => $region));
-      $this->assertTrue(empty($elements), t('%region is not an available choice on the block configuration page.', array('%region' => $region)));
-    }
-  }
-
-  /**
-   * Test that the dashboard module can be disabled and enabled again,
-   * retaining its blocks.
-   */
-  function testDisableEnable() {
-    // Add a new custom block to a dashboard region.
-    $custom_block = array();
-    $custom_block['info'] = $this->randomName(8);
-    $custom_block['title'] = $this->randomName(8);
-    $custom_block['body[value]'] = $this->randomName(32);
-    $custom_block['regions[stark]'] = 'dashboard_main';
-    $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
-    $this->drupalGet('admin/dashboard');
-    $this->assertRaw($custom_block['title'], t('Block appears on the dashboard.'));
-
-    $edit = array();
-    $edit['modules[Core][dashboard][enable]'] = FALSE;
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
-    $this->assertNoRaw('assigned to the invalid region', t('Dashboard blocks gracefully disabled.'));
-    module_list(TRUE);
-    $this->assertFalse(module_exists('dashboard'), t('Dashboard disabled.'));
-
-    $edit['modules[Core][dashboard][enable]'] = 'dashboard';
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
-    module_list(TRUE);
-    $this->assertTrue(module_exists('dashboard'), t('Dashboard enabled.'));
-
-    $this->drupalGet('admin/dashboard');
-    $this->assertRaw($custom_block['title'], t('Block still appears on the dashboard.'));
-  }
-
-  /**
-   * Test that defining a block with ['properties']['administrative'] = TRUE
-   * adds it as an available block for the dashboard.
-   */
-  function testBlockAvailability() {
-    // Test "Recent comments", which should be available (defined as
-    // "administrative") but not enabled.
-    $this->drupalGet('admin/dashboard');
-    $this->assertNoText(t('Recent comments'), t('"Recent comments" not on dashboard.'));
-    $this->drupalGet('admin/dashboard/drawer');
-    $this->assertText(t('Recent comments'), t('Drawer of disabled blocks includes a block defined as "administrative".'));
-    $this->assertNoText(t('Syndicate'), t('Drawer of disabled blocks excludes a block not defined as "administrative".'));
-    $this->drupalGet('admin/dashboard/configure');
-    $elements = $this->xpath('//select[@id=:id]//option[@selected="selected"]', array(':id' => 'edit-blocks-comment-recent-region'));
-    $this->assertTrue($elements[0]['value'] == 'dashboard_inactive', t('A block defined as "administrative" defaults to dashboard_inactive.'));
-
-    // Now enable the block on the dashboard.
-    $values = array();
-    $values['blocks[comment_recent][region]'] = 'dashboard_main';
-    $this->drupalPost('admin/dashboard/configure', $values, t('Save blocks'));
-    $this->drupalGet('admin/dashboard');
-    $this->assertText(t('Recent comments'), t('"Recent comments" was placed on dashboard.'));
-    $this->drupalGet('admin/dashboard/drawer');
-    $this->assertNoText(t('Recent comments'), t('Drawer of disabled blocks excludes enabled blocks.'));
-  }
-}
diff --git a/modules/forum/forum-icon.tpl.php b/modules/forum/forum-icon.tpl.php
deleted file mode 100644
index 9cf2cd8..0000000
--- a/modules/forum/forum-icon.tpl.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display an appropriate icon for a forum post.
- *
- * Available variables:
- * - $new_posts: Indicates whether or not the topic contains new posts.
- * - $icon_class: The icon to display. May be one of 'hot', 'hot-new', 'new',
- *   'default', 'closed', or 'sticky'.
- * - $first_new: Indicates whether this is the first topic with new posts.
- *
- * @see template_preprocess_forum_icon()
- * @see theme_forum_icon()
- */
-?>
-<div class="topic-status-<?php print $icon_class ?>" title="<?php print $icon_title ?>">
-<?php if ($first_new): ?>
-  <a id="new"></a>
-<?php endif; ?>
-
-  <span class="element-invisible"><?php print $icon_title ?></span>
-
-</div>
diff --git a/modules/forum/forum-list.tpl.php b/modules/forum/forum-list.tpl.php
deleted file mode 100644
index bc0935f..0000000
--- a/modules/forum/forum-list.tpl.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display a list of forums and containers.
- *
- * Available variables:
- * - $forums: An array of forums and containers to display. It is keyed to the
- *   numeric id's of all child forums and containers.
- * - $forum_id: Forum id for the current forum. Parent to all items within
- *   the $forums array.
- *
- * Each $forum in $forums contains:
- * - $forum->is_container: Is TRUE if the forum can contain other forums. Is
- *   FALSE if the forum can contain only topics.
- * - $forum->depth: How deep the forum is in the current hierarchy.
- * - $forum->zebra: 'even' or 'odd' string used for row class.
- * - $forum->name: The name of the forum.
- * - $forum->link: The URL to link to this forum.
- * - $forum->description: The description of this forum.
- * - $forum->new_topics: True if the forum contains unread posts.
- * - $forum->new_url: A URL to the forum's unread posts.
- * - $forum->new_text: Text for the above URL which tells how many new posts.
- * - $forum->old_topics: A count of posts that have already been read.
- * - $forum->num_posts: The total number of posts in the forum.
- * - $forum->last_reply: Text representing the last time a forum was posted or
- *   commented in.
- *
- * @see template_preprocess_forum_list()
- * @see theme_forum_list()
- */
-?>
-<table id="forum-<?php print $forum_id; ?>">
-  <thead>
-    <tr>
-      <th><?php print t('Forum'); ?></th>
-      <th><?php print t('Topics');?></th>
-      <th><?php print t('Posts'); ?></th>
-      <th><?php print t('Last post'); ?></th>
-    </tr>
-  </thead>
-  <tbody>
-  <?php foreach ($forums as $child_id => $forum): ?>
-    <tr id="forum-list-<?php print $child_id; ?>" class="<?php print $forum->zebra; ?>">
-      <td <?php print $forum->is_container ? 'colspan="4" class="container"' : 'class="forum"'; ?>>
-        <?php /* Enclose the contents of this cell with X divs, where X is the
-               * depth this forum resides at. This will allow us to use CSS
-               * left-margin for indenting.
-               */ ?>
-        <?php print str_repeat('<div class="indent">', $forum->depth); ?>
-          <div class="name"><a href="<?php print $forum->link; ?>"><?php print $forum->name; ?></a></div>
-          <?php if ($forum->description): ?>
-            <div class="description"><?php print $forum->description; ?></div>
-          <?php endif; ?>
-        <?php print str_repeat('</div>', $forum->depth); ?>
-      </td>
-      <?php if (!$forum->is_container): ?>
-        <td class="topics">
-          <?php print $forum->num_topics ?>
-          <?php if ($forum->new_topics): ?>
-            <br />
-            <a href="<?php print $forum->new_url; ?>"><?php print $forum->new_text; ?></a>
-          <?php endif; ?>
-        </td>
-        <td class="posts"><?php print $forum->num_posts ?></td>
-        <td class="last-reply"><?php print $forum->last_reply ?></td>
-      <?php endif; ?>
-    </tr>
-  <?php endforeach; ?>
-  </tbody>
-</table>
diff --git a/modules/forum/forum-rtl.css b/modules/forum/forum-rtl.css
deleted file mode 100644
index d31c9e7..0000000
--- a/modules/forum/forum-rtl.css
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#forum tr td.forum {
-  padding-left: 0.5em;
-  padding-right: 25px;
-  background-position: 98% 2px;
-}
-.forum-topic-navigation {
-  padding: 1em 3em 0 0;
-}
-.forum-topic-navigation .topic-previous {
-  text-align: left;
-  float: right;
-}
-.forum-topic-navigation .topic-next {
-  text-align: right;
-  float: left;
-}
diff --git a/modules/forum/forum-submitted.tpl.php b/modules/forum/forum-submitted.tpl.php
deleted file mode 100644
index d310448..0000000
--- a/modules/forum/forum-submitted.tpl.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to format a simple string indicated when and
- * by whom a topic was submitted.
- *
- * Available variables:
- *
- * - $author: The author of the post.
- * - $time: How long ago the post was created.
- * - $topic: An object with the raw data of the post. Unsafe, be sure
- *   to clean this data before printing.
- *
- * @see template_preprocess_forum_submitted()
- * @see theme_forum_submitted()
- */
-?>
-<?php if ($time): ?>
-  <span class="submitted">
-  <?php print t('By !author @time ago', array(
-    '@time' => $time,
-    '!author' => $author,
-    )); ?>
-  </span>
-<?php else: ?>
-  <?php print t('n/a'); ?>
-<?php endif; ?>
diff --git a/modules/forum/forum-topic-list.tpl.php b/modules/forum/forum-topic-list.tpl.php
deleted file mode 100644
index 3390703..0000000
--- a/modules/forum/forum-topic-list.tpl.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display a list of forum topics.
- *
- * Available variables:
- * - $header: The table header. This is pre-generated with click-sorting
- *   information. If you need to change this, see
- *   template_preprocess_forum_topic_list().
- * - $pager: The pager to display beneath the table.
- * - $topics: An array of topics to be displayed.
- * - $topic_id: Numeric id for the current forum topic.
- *
- * Each $topic in $topics contains:
- * - $topic->icon: The icon to display.
- * - $topic->moved: A flag to indicate whether the topic has been moved to
- *   another forum.
- * - $topic->title: The title of the topic. Safe to output.
- * - $topic->message: If the topic has been moved, this contains an
- *   explanation and a link.
- * - $topic->zebra: 'even' or 'odd' string used for row class.
- * - $topic->comment_count: The number of replies on this topic.
- * - $topic->new_replies: A flag to indicate whether there are unread comments.
- * - $topic->new_url: If there are unread replies, this is a link to them.
- * - $topic->new_text: Text containing the translated, properly pluralized count.
- * - $topic->created: An outputtable string represented when the topic was posted.
- * - $topic->last_reply: An outputtable string representing when the topic was
- *   last replied to.
- * - $topic->timestamp: The raw timestamp this topic was posted.
- *
- * @see template_preprocess_forum_topic_list()
- * @see theme_forum_topic_list()
- */
-?>
-<table id="forum-topic-<?php print $topic_id; ?>">
-  <thead>
-    <tr><?php print $header; ?></tr>
-  </thead>
-  <tbody>
-  <?php foreach ($topics as $topic): ?>
-    <tr class="<?php print $topic->zebra;?>">
-      <td class="icon"><?php print $topic->icon; ?></td>
-      <td class="title">
-        <div>
-          <?php print $topic->title; ?>
-        </div>
-        <div>
-          <?php print $topic->created; ?>
-        </div>
-      </td>
-    <?php if ($topic->moved): ?>
-      <td colspan="3"><?php print $topic->message; ?></td>
-    <?php else: ?>
-      <td class="replies">
-        <?php print $topic->comment_count; ?>
-        <?php if ($topic->new_replies): ?>
-          <br />
-          <a href="<?php print $topic->new_url; ?>"><?php print $topic->new_text; ?></a>
-        <?php endif; ?>
-      </td>
-      <td class="last-reply"><?php print $topic->last_reply; ?></td>
-    <?php endif; ?>
-    </tr>
-  <?php endforeach; ?>
-  </tbody>
-</table>
-<?php print $pager; ?>
diff --git a/modules/forum/forum.admin.inc b/modules/forum/forum.admin.inc
deleted file mode 100644
index 1e6b365..0000000
--- a/modules/forum/forum.admin.inc
+++ /dev/null
@@ -1,313 +0,0 @@
-<?php
-
-/**
- * @file
- * Administrative page callbacks for the forum module.
- */
-function forum_form_main($type, $edit = array()) {
-  $edit = (array) $edit;
-  if ((isset($_POST['op']) && $_POST['op'] == t('Delete')) || !empty($_POST['confirm'])) {
-    return drupal_get_form('forum_confirm_delete', $edit['tid']);
-  }
-  switch ($type) {
-    case 'forum':
-      return drupal_get_form('forum_form_forum', $edit);
-      break;
-    case 'container':
-      return drupal_get_form('forum_form_container', $edit);
-      break;
-  }
-}
-
-/**
- * Returns a form for adding a forum to the forum vocabulary
- *
- * @param $edit Associative array containing a forum term to be added or edited.
- * @ingroup forms
- * @see forum_form_submit()
- */
-function forum_form_forum($form, &$form_state, $edit = array()) {
-  $edit += array(
-    'name' => '',
-    'description' => '',
-    'tid' => NULL,
-    'weight' => 0,
-  );
-  $form['name'] = array('#type' => 'textfield',
-    '#title' => t('Forum name'),
-    '#default_value' => $edit['name'],
-    '#maxlength' => 255,
-    '#description' => t('Short but meaningful name for this collection of threaded discussions.'),
-    '#required' => TRUE,
-  );
-  $form['description'] = array('#type' => 'textarea',
-    '#title' => t('Description'),
-    '#default_value' => $edit['description'],
-    '#description' => t('Description and guidelines for discussions within this forum.'),
-  );
-  $form['parent']['#tree'] = TRUE;
-  $form['parent'][0] = _forum_parent_select($edit['tid'], t('Parent'), 'forum');
-  $form['weight'] = array('#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
-    '#description' => t('Forums are displayed in ascending order by weight (forums with equal weights are displayed alphabetically).'),
-  );
-
-  $form['vid'] = array('#type' => 'hidden', '#value' => variable_get('forum_nav_vocabulary', ''));
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit' ] = array('#type' => 'submit', '#value' => t('Save'));
-  if ($edit['tid']) {
-    $form['actions']['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
-    $form['tid'] = array('#type' => 'hidden', '#value' => $edit['tid']);
-  }
-  $form['#submit'][] = 'forum_form_submit';
-  $form['#theme'] = 'forum_form';
-
-  return $form;
-}
-
-/**
- * Process forum form and container form submissions.
- */
-function forum_form_submit($form, &$form_state) {
-  if ($form['form_id']['#value'] == 'forum_form_container') {
-    $container = TRUE;
-    $type = t('forum container');
-  }
-  else {
-    $container = FALSE;
-    $type = t('forum');
-  }
-
-  $term = (object) $form_state['values'];
-  $status = taxonomy_term_save($term);
-  switch ($status) {
-    case SAVED_NEW:
-      if ($container) {
-        $containers = variable_get('forum_containers', array());
-        $containers[] = $term->tid;
-        variable_set('forum_containers', $containers);
-      }
-      $form_state['values']['tid'] = $term->tid;
-      drupal_set_message(t('Created new @type %term.', array('%term' => $form_state['values']['name'], '@type' => $type)));
-      break;
-    case SAVED_UPDATED:
-      drupal_set_message(t('The @type %term has been updated.', array('%term' => $form_state['values']['name'], '@type' => $type)));
-      // Clear the page and block caches to avoid stale data.
-      cache_clear_all();
-      break;
-  }
-  $form_state['redirect'] = 'admin/structure/forum';
-  return;
-}
-
-/**
- * Returns HTML for a forum form.
- *
- * By default this does not alter the appearance of a form at all,
- * but is provided as a convenience for themers.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_forum_form($variables) {
-  return drupal_render_children($variables['form']);
-}
-
-/**
- * Returns a form for adding a container to the forum vocabulary
- *
- * @param $edit Associative array containing a container term to be added or edited.
- * @ingroup forms
- * @see forum_form_submit()
- */
-function forum_form_container($form, &$form_state, $edit = array()) {
-  $edit += array(
-    'name' => '',
-    'description' => '',
-    'tid' => NULL,
-    'weight' => 0,
-  );
-  // Handle a delete operation.
-  $form['name'] = array(
-    '#title' => t('Container name'),
-    '#type' => 'textfield',
-    '#default_value' => $edit['name'],
-    '#maxlength' => 255,
-    '#description' => t('Short but meaningful name for this collection of related forums.'),
-    '#required' => TRUE
-  );
-
-  $form['description'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#default_value' => $edit['description'],
-    '#description' => t('Description and guidelines for forums within this container.')
-  );
-  $form['parent']['#tree'] = TRUE;
-  $form['parent'][0] = _forum_parent_select($edit['tid'], t('Parent'), 'container');
-  $form['weight'] = array(
-    '#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
-    '#description' => t('Containers are displayed in ascending order by weight (containers with equal weights are displayed alphabetically).')
-  );
-
-  $form['vid'] = array(
-    '#type' => 'hidden',
-    '#value' => variable_get('forum_nav_vocabulary', ''),
-  );
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save')
-  );
-  if ($edit['tid']) {
-    $form['actions']['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
-    $form['tid'] = array('#type' => 'value', '#value' => $edit['tid']);
-  }
-  $form['#submit'][] = 'forum_form_submit';
-  $form['#theme'] = 'forum_form';
-
-  return $form;
-}
-
-/**
- * Returns a confirmation page for deleting a forum taxonomy term.
- *
- * @param $tid ID of the term to be deleted
- */
-function forum_confirm_delete($form, &$form_state, $tid) {
-  $term = taxonomy_term_load($tid);
-
-  $form['tid'] = array('#type' => 'value', '#value' => $tid);
-  $form['name'] = array('#type' => 'value', '#value' => $term->name);
-
-  return confirm_form($form, t('Are you sure you want to delete the forum %name?', array('%name' => $term->name)), 'admin/structure/forum', t('Deleting a forum or container will also delete its sub-forums, if any. To delete posts in this forum, visit <a href="@content">content administration</a> first. This action cannot be undone.', array('@content' => url('admin/content'))), t('Delete'), t('Cancel'));
-}
-
-/**
- * Implement forms api _submit call. Deletes a forum after confirmation.
- */
-function forum_confirm_delete_submit($form, &$form_state) {
-  taxonomy_term_delete($form_state['values']['tid']);
-  drupal_set_message(t('The forum %term and all sub-forums have been deleted.', array('%term' => $form_state['values']['name'])));
-  watchdog('content', 'forum: deleted %term and all its sub-forums.', array('%term' => $form_state['values']['name']));
-
-  $form_state['redirect'] = 'admin/structure/forum';
-  return;
-}
-
-/**
- * Form builder for the forum settings page.
- *
- * @see system_settings_form()
- */
-function forum_admin_settings($form) {
-  $number = drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100, 150, 200, 250, 300, 350, 400, 500));
-  $form['forum_hot_topic'] = array('#type' => 'select',
-    '#title' => t('Hot topic threshold'),
-    '#default_value' => variable_get('forum_hot_topic', 15),
-    '#options' => $number,
-    '#description' => t('The number of replies a topic must have to be considered "hot".'),
-  );
-  $number = drupal_map_assoc(array(10, 25, 50, 75, 100));
-  $form['forum_per_page'] = array('#type' => 'select',
-    '#title' => t('Topics per page'),
-    '#default_value' => variable_get('forum_per_page', 25),
-    '#options' => $number,
-    '#description' => t('Default number of forum topics displayed per page.'),
-  );
-  $forder = array(1 => t('Date - newest first'), 2 => t('Date - oldest first'), 3 => t('Posts - most active first'), 4 => t('Posts - least active first'));
-  $form['forum_order'] = array('#type' => 'radios',
-    '#title' => t('Default order'),
-    '#default_value' => variable_get('forum_order', 1),
-    '#options' => $forder,
-    '#description' => t('Default display order for topics.'),
-  );
-  return system_settings_form($form);
-}
-
-/**
- * Returns an overview list of existing forums and containers
- */
-function forum_overview($form, &$form_state) {
-  module_load_include('inc', 'taxonomy', 'taxonomy.admin');
-
-  $vid = variable_get('forum_nav_vocabulary', '');
-  $vocabulary = taxonomy_vocabulary_load($vid);
-  $form = taxonomy_overview_terms($form, $form_state, $vocabulary);
-
-  foreach (element_children($form) as $key) {
-    if (isset($form[$key]['#term'])) {
-      $term = $form[$key]['#term'];
-      $form[$key]['view']['#href'] = 'forum/' . $term['tid'];
-      if (in_array($form[$key]['#term']['tid'], variable_get('forum_containers', array()))) {
-        $form[$key]['edit']['#title'] = t('edit container');
-        $form[$key]['edit']['#href'] = 'admin/structure/forum/edit/container/' . $term['tid'];
-      }
-      else {
-        $form[$key]['edit']['#title'] = t('edit forum');
-        $form[$key]['edit']['#href'] = 'admin/structure/forum/edit/forum/' . $term['tid'];
-      }
-    }
-  }
-
-  // Remove the alphabetical reset.
-  unset($form['actions']['reset_alphabetical']);
-
-  // The form needs to have submit and validate handlers set explicitly.
-  $form['#theme'] = 'taxonomy_overview_terms';
-  $form['#submit'] = array('taxonomy_overview_terms_submit'); // Use the existing taxonomy overview submit handler.
-  $form['#empty_text'] = t('No containers or forums available. <a href="@container">Add container</a> or <a href="@forum">Add forum</a>.', array('@container' => url('admin/structure/forum/add/container'), '@forum' => url('admin/structure/forum/add/forum')));
-  return $form;
-}
-
-/**
- * Returns a select box for available parent terms
- *
- * @param $tid ID of the term which is being added or edited
- * @param $title Title to display the select box with
- * @param $child_type Whether the child is forum or container
- */
-function _forum_parent_select($tid, $title, $child_type) {
-
-  $parents = taxonomy_get_parents($tid);
-  if ($parents) {
-    $parent = array_shift($parents);
-    $parent = $parent->tid;
-  }
-  else {
-    $parent = 0;
-  }
-
-  $vid = variable_get('forum_nav_vocabulary', '');
-  $children = taxonomy_get_tree($vid, $tid);
-
-  // A term can't be the child of itself, nor of its children.
-  foreach ($children as $child) {
-    $exclude[] = $child->tid;
-  }
-  $exclude[] = $tid;
-
-  $tree = taxonomy_get_tree($vid);
-  $options[0] = '<' . t('root') . '>';
-  if ($tree) {
-    foreach ($tree as $term) {
-      if (!in_array($term->tid, $exclude)) {
-        $options[$term->tid] = str_repeat(' -- ', $term->depth) . $term->name;
-      }
-    }
-  }
-  if ($child_type == 'container') {
-    $description = t('Containers are usually placed at the top (root) level, but may also be placed inside another container or forum.');
-  }
-  elseif ($child_type == 'forum') {
-    $description = t('Forums may be placed at the top (root) level, or inside another container or forum.');
-  }
-
-  return array('#type' => 'select', '#title' => $title, '#default_value' => $parent, '#options' => $options, '#description' => $description, '#required' => TRUE);
-}
diff --git a/modules/forum/forum.css b/modules/forum/forum.css
deleted file mode 100644
index 3f3ed98..0000000
--- a/modules/forum/forum.css
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#forum .description {
-  font-size: 0.9em;
-  margin: 0.5em;
-}
-#forum td.created,
-#forum td.posts,
-#forum td.topics,
-#forum td.last-reply,
-#forum td.replies,
-#forum td.pager {
-  white-space: nowrap;
-}
-#forum tr td.forum {
-  padding-left: 25px; /* LTR */
-  background-position: 2px 2px; /* LTR */
-  background-image: url(../../misc/forum-default.png);
-  background-repeat: no-repeat;
-}
-#forum tr.new-topics td.forum {
-  background-image: url(../../misc/forum-new.png);
-}
-#forum div.indent {
-  margin-left: 20px;
-}
-#forum .icon div {
-  background-image: url(../../misc/forum-icons.png);
-  background-repeat: no-repeat;
-  width: 24px;
-  height: 24px;
-}
-#forum .icon .topic-status-new {
-  background-position: -24px 0;
-}
-#forum .icon .topic-status-hot {
-  background-position: -48px 0;
-}
-#forum .icon .topic-status-hot-new {
-  background-position: -72px 0;
-}
-#forum .icon .topic-status-sticky {
-  background-position: -96px 0;
-}
-#forum .icon .topic-status-closed {
-  background-position: -120px 0;
-}
diff --git a/modules/forum/forum.info b/modules/forum/forum.info
deleted file mode 100644
index f202f9e..0000000
--- a/modules/forum/forum.info
+++ /dev/null
@@ -1,11 +0,0 @@
-name = Forum
-description = Provides discussion forums.
-dependencies[] = node
-dependencies[] = taxonomy
-dependencies[] = comment
-package = Core
-version = VERSION
-core = 8.x
-files[] = forum.test
-configure = admin/structure/forum
-stylesheets[all][] = forum.css
diff --git a/modules/forum/forum.install b/modules/forum/forum.install
deleted file mode 100644
index b5817ab..0000000
--- a/modules/forum/forum.install
+++ /dev/null
@@ -1,241 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the forum module.
- */
-
-/**
- * Implements hook_install().
- */
-function forum_install() {
-  // Set the weight of the forum.module to 1 so it is loaded after the taxonomy.module.
-  db_update('system')
-    ->fields(array('weight' => 1))
-    ->condition('name', 'forum')
-    ->execute();
-  // Forum topics are published by default, but do not have any other default
-  // options set (for example, they are not promoted to the front page).
-  variable_set('node_options_forum', array('status'));
-}
-
-/**
- * Implements hook_enable().
- */
-function forum_enable() {
-  // If we enable forum at the same time as taxonomy we need to call
-  // field_associate_fields() as otherwise the field won't be enabled until
-  // hook modules_enabled is called which takes place after hook_enable events.
-  field_associate_fields('taxonomy');
-  // Create the forum vocabulary if it does not exist.
-  $vocabulary = taxonomy_vocabulary_load(variable_get('forum_nav_vocabulary', 0));
-  if (!$vocabulary) {
-    $edit = array(
-      'name' => t('Forums'),
-      'machine_name' => 'forums',
-      'description' => t('Forum navigation vocabulary'),
-      'hierarchy' => 1,
-      'module' => 'forum',
-      'weight' => -10,
-    );
-    $vocabulary = (object) $edit;
-    taxonomy_vocabulary_save($vocabulary);
-    variable_set('forum_nav_vocabulary', $vocabulary->vid);
-  }
-
-  // Create the 'taxonomy_forums' field if it doesn't already exist.
-  if (!field_info_field('taxonomy_forums')) {
-    $field = array(
-      'field_name' => 'taxonomy_forums',
-      'type' => 'taxonomy_term_reference',
-      'settings' => array(
-        'allowed_values' => array(
-          array(
-            'vocabulary' => $vocabulary->machine_name,
-            'parent' => 0,
-          ),
-        ),
-      ),
-    );
-    field_create_field($field);
-
-    // Create a default forum so forum posts can be created.
-    $edit = array(
-      'name' => t('General discussion'),
-      'description' => '',
-      'parent' => array(0),
-      'vid' => $vocabulary->vid,
-    );
-    $term = (object) $edit;
-    taxonomy_term_save($term);
-
-    // Create the instance on the bundle.
-    $instance = array(
-      'field_name' => 'taxonomy_forums',
-      'entity_type' => 'node',
-      'label' => $vocabulary->name,
-      'bundle' => 'forum',
-      'required' => TRUE,
-      'widget' => array(
-        'type' => 'options_select',
-      ),
-      'display' => array(
-        'default' => array(
-          'type' => 'taxonomy_term_reference_link',
-         'weight' => 10,
-        ),
-        'teaser' => array(
-          'type' => 'taxonomy_term_reference_link',
-         'weight' => 10,
-        ),
-      ),
-    );
-    field_create_instance($instance);
-  }
-
-  // Ensure the forum node type is available.
-  node_types_rebuild();
-  $types = node_type_get_types();
-  node_add_body_field($types['forum']);
-}
-
-/**
- * Implements hook_uninstall().
- */
-function forum_uninstall() {
-  // Load the dependent Taxonomy module, in case it has been disabled.
-  drupal_load('module', 'taxonomy');
-
-  variable_del('forum_containers');
-  variable_del('forum_hot_topic');
-  variable_del('forum_per_page');
-  variable_del('forum_order');
-  variable_del('forum_block_num_active');
-  variable_del('forum_block_num_new');
-  variable_del('node_options_forum');
-}
-
-/**
- * Implements hook_schema().
- */
-function forum_schema() {
-  $schema['forum'] = array(
-    'description' => 'Stores the relationship of nodes to forum terms.',
-    'fields' => array(
-      'nid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {node}.nid of the node.',
-      ),
-      'vid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Primary Key: The {node}.vid of the node.',
-      ),
-      'tid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {taxonomy_term_data}.tid of the forum term assigned to the node.',
-      ),
-    ),
-    'indexes' => array(
-      'forum_topic' => array('nid', 'tid'),
-      'tid' => array('tid'),
-    ),
-    'primary key' => array('vid'),
-    'foreign keys' => array(
-      'forum_node' => array(
-        'table' => 'node',
-        'columns' => array(
-          'nid' => 'nid',
-          'vid' => 'vid',
-        ),
-      ),
-    ),
-  );
-
-  $schema['forum_index'] = array(
-    'description' => 'Maintains denormalized information about node/term relationships.',
-    'fields' => array(
-      'nid' => array(
-        'description' => 'The {node}.nid this record tracks.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'title' => array(
-        'description' => 'The title of this node, always treated as non-markup plain text.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'tid' => array(
-         'description' => 'The term ID.',
-         'type' => 'int',
-         'unsigned' => TRUE,
-         'not null' => TRUE,
-         'default' => 0,
-      ),
-      'sticky' => array(
-        'description' => 'Boolean indicating whether the node is sticky.',
-        'type' => 'int',
-        'not null' => FALSE,
-        'default' => 0,
-        'size' => 'tiny',
-      ),
-      'created' => array(
-        'description' => 'The Unix timestamp when the node was created.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default'=> 0,
-      ),
-      'last_comment_timestamp' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The Unix timestamp of the last comment that was posted within this node, from {comment}.timestamp.',
-      ),
-      'comment_count' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The total number of comments on this node.',
-      ),
-    ),
-    'indexes' => array(
-      'forum_topics' => array('nid', 'tid', 'sticky', 'last_comment_timestamp'),
-    ),
-    'foreign keys' => array(
-      'tracked_node' => array(
-        'table' => 'node',
-        'columns' => array('nid' => 'nid'),
-      ),
-      'term' => array(
-        'table' => 'taxonomy_term_data',
-        'columns' => array(
-          'tid' => 'tid',
-        ),
-      ),
-    ),
-  );
-
-
-  return $schema;
-}
-
-/**
- * Implements hook_update_last_removed().
- */
-function forum_update_last_removed() {
-  return 7003;
-}
diff --git a/modules/forum/forum.module b/modules/forum/forum.module
deleted file mode 100644
index f2ac5ac..0000000
--- a/modules/forum/forum.module
+++ /dev/null
@@ -1,1291 +0,0 @@
-<?php
-
-/**
- * @file
- * Provides discussion forums.
- */
-
-/**
- * Implements hook_help().
- */
-function forum_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#forum':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Forum module lets you create threaded discussion forums with functionality similar to other message board systems. Forums are useful because they allow community members to discuss topics with one another while ensuring those conversations are archived for later reference. In a forum, users post topics and threads in nested hierarchies, allowing discussions to be categorized and grouped. The forum hierarchy consists of:') . '</p>';
-      $output .= '<ul>';
-      $output .= '<li>' . t('Optional containers (for example, <em>Support</em>), which can hold:') . '</li>';
-      $output .= '<ul><li>' . t('Forums (for example, <em>Installing Drupal</em>), which can hold:') . '</li>';
-      $output .= '<ul><li>' . t('Forum topics submitted by users (for example, <em>How to start a Drupal 6 Multisite</em>), which start discussions and are starting points for:') . '</li>';
-      $output .= '<ul><li>' . t('Threaded comments submitted by users (for example, <em>You have these options...</em>).') . '</li>';
-      $output .= '</ul>';
-      $output .= '</ul>';
-      $output .= '</ul>';
-      $output .= '</ul>';
-      $output .= '<p>' . t('For more information, see the online handbook entry for <a href="@forum">Forum module</a>.', array('@forum' => 'http://drupal.org/handbook/modules/forum')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Setting up forum structure') . '</dt>';
-      $output .= '<dd>' . t('Visit the <a href="@forums">Forums page</a> to set up containers and forums to hold your discussion topics.', array('@forums' => url('admin/structure/forum'))) . '</dd>';
-      $output .= '<dt>' . t('Starting a discussion') . '</dt>';
-      $output .= '<dd>' . t('The <a href="@create-topic">Forum topic</a> link on the <a href="@content-add">Add new content</a> page creates the first post of a new threaded discussion, or thread.', array('@create-topic' => url('node/add/forum'), '@content-add' => url('node/add'))) . '</dd>';
-      $output .= '<dt>' . t('Navigation') . '</dt>';
-      $output .= '<dd>' . t('Enabling the Forum module provides a default <em>Forums</em> menu item in the navigation menu that links to the <a href="@forums">Forums page</a>.', array('@forums' => url('forum'))) . '</dd>';
-      $output .= '<dt>' . t('Moving forum topics') . '</dt>';
-      $output .= '<dd>' . t('A forum topic (and all of its comments) may be moved between forums by selecting a different forum while editing a forum topic. When moving a forum topic between forums, the <em>Leave shadow copy</em> option creates a link in the original forum pointing to the new location.') . '</dd>';
-      $output .= '<dt>' . t('Locking and disabling comments') . '</dt>';
-      $output .= '<dd>' . t('Selecting <em>Closed</em> under <em>Comment settings</em> while editing a forum topic will lock (prevent new comments on) the thread. Selecting <em>Hidden</em> under <em>Comment settings</em> while editing a forum topic will hide all existing comments on the thread, and prevent new ones.') . '</dd>';
-      $output .= '</dl>';
-      return $output;
-    case 'admin/structure/forum':
-      $output = '<p>' . t('Forums contain forum topics. Use containers to group related forums.') . '</p>';
-      $output .= theme('more_help_link', array('url' => 'admin/help/forum'));
-      return $output;
-    case 'admin/structure/forum/add/container':
-      return '<p>' . t('Use containers to group related forums.') . '</p>';
-    case 'admin/structure/forum/add/forum':
-      return '<p>' . t('A forum holds related forum topics.') . '</p>';
-    case 'admin/structure/forum/settings':
-      return '<p>' . t('Adjust the display of your forum topics. Organize the forums on the <a href="@forum-structure">forum structure page</a>.', array('@forum-structure' => url('admin/structure/forum'))) . '</p>';
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function forum_theme() {
-  return array(
-    'forums' => array(
-      'template' => 'forums',
-      'variables' => array('forums' => NULL, 'topics' => NULL, 'parents' => NULL, 'tid' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
-    ),
-    'forum_list' => array(
-      'template' => 'forum-list',
-      'variables' => array('forums' => NULL, 'parents' => NULL, 'tid' => NULL),
-    ),
-    'forum_topic_list' => array(
-      'template' => 'forum-topic-list',
-      'variables' => array('tid' => NULL, 'topics' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
-    ),
-    'forum_icon' => array(
-      'template' => 'forum-icon',
-      'variables' => array('new_posts' => NULL, 'num_posts' => 0, 'comment_mode' => 0, 'sticky' => 0, 'first_new' => FALSE),
-    ),
-    'forum_submitted' => array(
-      'template' => 'forum-submitted',
-      'variables' => array('topic' => NULL),
-    ),
-    'forum_form' => array(
-      'render element' => 'form',
-      'file' => 'forum.admin.inc',
-    ),
-  );
-}
-
-/**
- * Implements hook_menu().
- */
-function forum_menu() {
-  $items['forum'] = array(
-    'title' => 'Forums',
-    'page callback' => 'forum_page',
-    'access arguments' => array('access content'),
-    'file' => 'forum.pages.inc',
-  );
-  $items['forum/%forum_forum'] = array(
-    'title' => 'Forums',
-    'page callback' => 'forum_page',
-    'page arguments' => array(1),
-    'access arguments' => array('access content'),
-    'file' => 'forum.pages.inc',
-  );
-  $items['admin/structure/forum'] = array(
-    'title' => 'Forums',
-    'description' => 'Control forum hierarchy settings.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('forum_overview'),
-    'access arguments' => array('administer forums'),
-    'file' => 'forum.admin.inc',
-  );
-  $items['admin/structure/forum/list'] = array(
-    'title' => 'List',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
-  $items['admin/structure/forum/add/container'] = array(
-    'title' => 'Add container',
-    'page callback' => 'forum_form_main',
-    'page arguments' => array('container'),
-    'access arguments' => array('administer forums'),
-    'type' => MENU_LOCAL_ACTION,
-    'parent' => 'admin/structure/forum',
-    'file' => 'forum.admin.inc',
-  );
-  $items['admin/structure/forum/add/forum'] = array(
-    'title' => 'Add forum',
-    'page callback' => 'forum_form_main',
-    'page arguments' => array('forum'),
-    'access arguments' => array('administer forums'),
-    'type' => MENU_LOCAL_ACTION,
-    'parent' => 'admin/structure/forum',
-    'file' => 'forum.admin.inc',
-  );
-  $items['admin/structure/forum/settings'] = array(
-    'title' => 'Settings',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('forum_admin_settings'),
-    'access arguments' => array('administer forums'),
-    'weight' => 5,
-    'type' => MENU_LOCAL_TASK,
-    'parent' => 'admin/structure/forum',
-    'file' => 'forum.admin.inc',
-  );
-  $items['admin/structure/forum/edit/container/%taxonomy_term'] = array(
-    'title' => 'Edit container',
-    'page callback' => 'forum_form_main',
-    'page arguments' => array('container', 5),
-    'access arguments' => array('administer forums'),
-    'file' => 'forum.admin.inc',
-  );
-  $items['admin/structure/forum/edit/forum/%taxonomy_term'] = array(
-    'title' => 'Edit forum',
-    'page callback' => 'forum_form_main',
-    'page arguments' => array('forum', 5),
-    'access arguments' => array('administer forums'),
-    'file' => 'forum.admin.inc',
-  );
-  return $items;
-}
-
-/**
- * Implements hook_menu_local_tasks_alter().
- */
-function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
-  global $user;
-
-  // Add action link to 'node/add/forum' on 'forum' sub-pages.
-  if ($root_path == 'forum' || $root_path == 'forum/%') {
-    $tid = (isset($router_item['page_arguments'][0]) ? $router_item['page_arguments'][0]->tid : 0);
-    $forum_term = forum_forum_load($tid);
-    if ($forum_term) {
-      $links = array();
-      // Loop through all bundles for forum taxonomy vocabulary field.
-      $field = field_info_field('taxonomy_forums');
-      foreach ($field['bundles']['node'] as $type) {
-        if (node_access('create', $type)) {
-          $links[$type] = array(
-            '#theme' => 'menu_local_action',
-            '#link' => array(
-              'title' => t('Add new @node_type', array('@node_type' => node_type_get_name($type))),
-              'href' => 'node/add/' . str_replace('_', '-', $type) . '/' . $forum_term->tid,
-            ),
-          );
-        }
-      }
-      if (empty($links)) {
-        // Authenticated user does not have access to create new topics.
-        if ($user->uid) {
-          $links['disallowed'] = array(
-            '#theme' => 'menu_local_action',
-            '#link' => array(
-              'title' => t('You are not allowed to post new content in the forum.'),
-            ),
-          );
-        }
-        // Anonymous user does not have access to create new topics.
-        else {
-          $links['login'] = array(
-            '#theme' => 'menu_local_action',
-            '#link' => array(
-              'title' => t('<a href="@login">Log in</a> to post new content in the forum.', array(
-                '@login' => url('user/login', array('query' => drupal_get_destination())),
-              )),
-              'localized_options' => array('html' => TRUE),
-            ),
-          );
-        }
-      }
-      $data['actions']['output'] = array_merge($data['actions']['output'], $links);
-    }
-  }
-}
-
-/**
- * Implements hook_entity_info_alter().
- */
-function forum_entity_info_alter(&$info) {
-  // Take over URI constuction for taxonomy terms that are forums.
-  if ($vid = variable_get('forum_nav_vocabulary', 0)) {
-    // Within hook_entity_info(), we can't invoke entity_load() as that would
-    // cause infinite recursion, so we call taxonomy_vocabulary_get_names()
-    // instead of taxonomy_vocabulary_load(). All we need is the machine name
-    // of $vid, so retrieving and iterating all the vocabulary names is somewhat
-    // inefficient, but entity info is cached across page requests, and an
-    // iteration of all vocabularies once per cache clearing isn't a big deal,
-    // and is done as part of taxonomy_entity_info() anyway.
-    foreach (taxonomy_vocabulary_get_names() as $machine_name => $vocabulary) {
-      if ($vid == $vocabulary->vid) {
-        $info['taxonomy_term']['bundles'][$machine_name]['uri callback'] = 'forum_uri';
-      }
-    }
-  }
-}
-
-/**
- * Entity URI callback.
- */
-function forum_uri($forum) {
-  return array(
-    'path' => 'forum/' . $forum->tid,
-  );
-}
-
-/**
- * Check whether a content type can be used in a forum.
- *
- * @param $node
- *   A node object.
- *
- * @return
- *   Boolean indicating if the node can be assigned to a forum.
- */
-function _forum_node_check_node_type($node) {
-  // Fetch information about the forum field.
-  $field = field_info_instance('node', 'taxonomy_forums', $node->type);
-
-  return is_array($field);
-}
-
-/**
- * Implements hook_node_view().
- */
-function forum_node_view($node, $view_mode) {
-  $vid = variable_get('forum_nav_vocabulary', 0);
-  $vocabulary = taxonomy_vocabulary_load($vid);
-  if (_forum_node_check_node_type($node)) {
-    if ($view_mode == 'full' && node_is_page($node)) {
-      // Breadcrumb navigation
-      $breadcrumb[] = l(t('Home'), NULL);
-      $breadcrumb[] = l($vocabulary->name, 'forum');
-      if ($parents = taxonomy_get_parents_all($node->forum_tid)) {
-        $parents = array_reverse($parents);
-        foreach ($parents as $parent) {
-          $breadcrumb[] = l($parent->name, 'forum/' . $parent->tid);
-        }
-      }
-      drupal_set_breadcrumb($breadcrumb);
-
-    }
-  }
-}
-
-/**
- * Implements hook_node_validate().
- *
- * Check in particular that only a "leaf" term in the associated taxonomy.
- */
-function forum_node_validate($node, $form) {
-  if (_forum_node_check_node_type($node)) {
-    $langcode = $form['taxonomy_forums']['#language'];
-    // vocabulary is selected, not a "container" term.
-    if (!empty($node->taxonomy_forums[$langcode])) {
-      // Extract the node's proper topic ID.
-      $containers = variable_get('forum_containers', array());
-      foreach ($node->taxonomy_forums[$langcode] as $delta => $item) {
-        // If no term was selected (e.g. when no terms exist yet), remove the
-        // item.
-        if (empty($item['tid'])) {
-          unset($node->taxonomy_forums[$langcode][$delta]);
-          continue;
-        }
-        $term = taxonomy_term_load($item['tid']);
-        if (!$term) {
-          form_set_error('taxonomy_forums', t('Select a forum.'));
-          continue;
-        }
-        $used = db_query_range('SELECT 1 FROM {taxonomy_term_data} WHERE tid = :tid AND vid = :vid',0 , 1, array(
-          ':tid' => $term->tid,
-          ':vid' => $term->vid,
-        ))->fetchField();
-        if ($used && in_array($term->tid, $containers)) {
-          form_set_error('taxonomy_forums', t('The item %forum is a forum container, not a forum. Select one of the forums below instead.', array('%forum' => $term->name)));
-        }
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_node_presave().
- *
- * Assign forum taxonomy when adding a topic from within a forum.
- */
-function forum_node_presave($node) {
-  if (_forum_node_check_node_type($node)) {
-    // Make sure all fields are set properly:
-    $node->icon = !empty($node->icon) ? $node->icon : '';
-    reset($node->taxonomy_forums);
-    $langcode = key($node->taxonomy_forums);
-    if (!empty($node->taxonomy_forums[$langcode])) {
-      $node->forum_tid = $node->taxonomy_forums[$langcode][0]['tid'];
-      $old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->nid))->fetchField();
-      if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
-        // A shadow copy needs to be created. Retain new term and add old term.
-        $node->taxonomy_forums[$langcode][] = array('tid' => $old_tid);
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_node_update().
- */
-function forum_node_update($node) {
-  if (_forum_node_check_node_type($node)) {
-    if (empty($node->revision) && db_query('SELECT tid FROM {forum} WHERE nid=:nid', array(':nid' => $node->nid))->fetchField()) {
-      if (!empty($node->forum_tid)) {
-        db_update('forum')
-          ->fields(array('tid' => $node->forum_tid))
-          ->condition('vid', $node->vid)
-          ->execute();
-      }
-      // The node is removed from the forum.
-      else {
-        db_delete('forum')
-          ->condition('nid', $node->nid)
-          ->execute();
-      }
-    }
-    else {
-      if (!empty($node->forum_tid)) {
-        db_insert('forum')
-          ->fields(array(
-            'tid' => $node->forum_tid,
-            'vid' => $node->vid,
-            'nid' => $node->nid,
-          ))
-          ->execute();
-      }
-    }
-    // If the node has a shadow forum topic, update the record for this
-    // revision.
-    if (!empty($node->shadow)) {
-      db_delete('forum')
-        ->condition('nid', $node->nid)
-        ->condition('vid', $node->vid)
-        ->execute();
-      db_insert('forum')
-        ->fields(array(
-          'nid' => $node->nid,
-          'vid' => $node->vid,
-          'tid' => $node->forum_tid,
-        ))
-        ->execute();
-     }
-  }
-}
-
-/**
- * Implements hook_node_insert().
- */
-function forum_node_insert($node) {
-  if (_forum_node_check_node_type($node)) {
-    if (!empty($node->forum_tid)) {
-      $nid = db_insert('forum')
-        ->fields(array(
-          'tid' => $node->forum_tid,
-          'vid' => $node->vid,
-          'nid' => $node->nid,
-        ))
-        ->execute();
-    }
-  }
-}
-
-/**
- * Implements hook_node_delete().
- */
-function forum_node_delete($node) {
-  if (_forum_node_check_node_type($node)) {
-    db_delete('forum')
-      ->condition('nid', $node->nid)
-      ->execute();
-    db_delete('forum_index')
-      ->condition('nid', $node->nid)
-      ->execute();
-  }
-}
-
-/**
- * Implements hook_node_load().
- */
-function forum_node_load($nodes) {
-  $node_vids = array();
-  foreach ($nodes as $node) {
-    if (_forum_node_check_node_type($node)) {
-      $node_vids[] = $node->vid;
-    }
-  }
-  if (!empty($node_vids)) {
-    $query = db_select('forum', 'f');
-    $query
-      ->fields('f', array('nid', 'tid'))
-      ->condition('f.vid', $node_vids);
-    $result = $query->execute();
-    foreach ($result as $record) {
-      $nodes[$record->nid]->forum_tid = $record->tid;
-    }
-  }
-}
-
-/**
- * Implements hook_node_info().
- */
-function forum_node_info() {
-  return array(
-    'forum' => array(
-      'name' => t('Forum topic'),
-      'base' => 'forum',
-      'description' => t('A <em>forum topic</em> starts a new discussion thread within a forum.'),
-      'title_label' => t('Subject'),
-    )
-  );
-}
-
-/**
- * Implements hook_permission().
- */
-function forum_permission() {
-  $perms = array(
-    'administer forums' => array(
-      'title' => t('Administer forums'),
-    ),
-  );
-  return $perms;
-}
-
-/**
- * Implements hook_taxonomy_term_delete().
- */
-function forum_taxonomy_term_delete($tid) {
-  // For containers, remove the tid from the forum_containers variable.
-  $containers = variable_get('forum_containers', array());
-  $key = array_search($tid, $containers);
-  if ($key !== FALSE) {
-    unset($containers[$key]);
-  }
-  variable_set('forum_containers', $containers);
-}
-
-/**
- * Implements hook_comment_publish().
- *
- * This actually handles the insert and update of published nodes since
- * comment_save() calls hook_comment_publish() for all published comments.
- */
-function forum_comment_publish($comment) {
-  _forum_update_forum_index($comment->nid);
-}
-
-/**
- * Implements hook_comment_update().
- *
- * Comment module doesn't call hook_comment_unpublish() when saving individual
- * comments so we need to check for those here.
- */
-function forum_comment_update($comment) {
-  // comment_save() calls hook_comment_publish() for all published comments
-  // so we to handle all other values here.
-  if (!$comment->status) {
-    _forum_update_forum_index($comment->nid);
-  }
-}
-
-/**
- * Implements hook_comment_unpublish().
- */
-function forum_comment_unpublish($comment) {
-  _forum_update_forum_index($comment->nid);
-}
-
-/**
- * Implements hook_comment_delete().
- */
-function forum_comment_delete($comment) {
-  _forum_update_forum_index($comment->nid);
-}
-
-/**
- * Implements hook_field_storage_pre_insert().
- */
-function forum_field_storage_pre_insert($entity_type, $entity, &$skip_fields) {
-  if ($entity_type == 'node' && $entity->status && _forum_node_check_node_type($entity)) {
-    $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
-    foreach ($entity->taxonomy_forums as $language) {
-      foreach ($language as $item) {
-        $query->values(array(
-          'nid' => $entity->nid,
-          'title' => $entity->title,
-          'tid' => $item['tid'],
-          'sticky' => $entity->sticky,
-          'created' => $entity->created,
-          'comment_count' => 0,
-          'last_comment_timestamp' => $entity->created,
-        ));
-      }
-    }
-    $query->execute();
-  }
-}
-
-/**
- * Implements hook_field_storage_pre_update().
- */
-function forum_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
-  $first_call = &drupal_static(__FUNCTION__, array());
-
-  if ($entity_type == 'node' && $entity->status && _forum_node_check_node_type($entity)) {
-    // We don't maintain data for old revisions, so clear all previous values
-    // from the table. Since this hook runs once per field, per object, make
-    // sure we only wipe values once.
-    if (!isset($first_call[$entity->nid])) {
-      $first_call[$entity->nid] = FALSE;
-      db_delete('forum_index')->condition('nid', $entity->nid)->execute();
-    }
-    // Only save data to the table if the node is published.
-    if ($entity->status) {
-      $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
-      foreach ($entity->taxonomy_forums as $language) {
-        foreach ($language as $item) {
-          $query->values(array(
-            'nid' => $entity->nid,
-            'title' => $entity->title,
-            'tid' => $item['tid'],
-            'sticky' => $entity->sticky,
-            'created' => $entity->created,
-            'comment_count' => 0,
-            'last_comment_timestamp' => $entity->created,
-          ));
-        }
-      }
-      $query->execute();
-      // The logic for determining last_comment_count is fairly complex, so
-      // call _forum_update_forum_index() too.
-      _forum_update_forum_index($entity->nid);
-    }
-  }
-}
-
-/**
- * Implements hook_form_alter().
- */
-function forum_form_alter(&$form, $form_state, $form_id) {
-  $vid = variable_get('forum_nav_vocabulary', 0);
-  if (isset($form['vid']) && $form['vid']['#value'] == $vid) {
-    // Hide critical options from forum vocabulary.
-    if ($form_id == 'taxonomy_form_vocabulary') {
-      $form['help_forum_vocab'] = array(
-        '#markup' => t('This is the designated forum vocabulary. Some of the normal vocabulary options have been removed.'),
-        '#weight' => -1,
-      );
-      $form['hierarchy'] = array('#type' => 'value', '#value' => 1);
-      $form['delete']['#access'] = FALSE;
-    }
-    // Hide multiple parents select from forum terms.
-    elseif ($form_id == 'taxonomy_form_term') {
-      $form['advanced']['parent']['#access'] = FALSE;
-    }
-  }
-  if (!empty($form['#node_edit_form']) && isset($form['taxonomy_forums'])) {
-    $langcode = $form['taxonomy_forums']['#language'];
-    // Make the vocabulary required for 'real' forum-nodes.
-    $form['taxonomy_forums'][$langcode]['#required'] = TRUE;
-    $form['taxonomy_forums'][$langcode]['#multiple'] = FALSE;
-    if (empty($form['taxonomy_forums'][$langcode]['#default_value'])) {
-      // If there is no default forum already selected, try to get the forum
-      // ID from the URL (e.g., if we are on a page like node/add/forum/2, we
-      // expect "2" to be the ID of the forum that was requested).
-      $requested_forum_id = arg(3);
-      $form['taxonomy_forums'][$langcode]['#default_value'] = is_numeric($requested_forum_id) ? $requested_forum_id : '';
-    }
-  }
-}
-
-/**
- * Implements hook_block_info().
- */
-function forum_block_info() {
-  $blocks['active'] = array(
-    'info' => t('Active forum topics'),
-    'cache' => DRUPAL_CACHE_CUSTOM,
-    'properties' => array('administrative' => TRUE),
-  );
-  $blocks['new'] = array(
-    'info' => t('New forum topics'),
-    'cache' => DRUPAL_CACHE_CUSTOM,
-    'properties' => array('administrative' => TRUE),
-  );
-  return $blocks;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function forum_block_configure($delta = '') {
-  $form['forum_block_num_' . $delta] = array('#type' => 'select', '#title' => t('Number of topics'), '#default_value' => variable_get('forum_block_num_' . $delta, '5'), '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)));
-  return $form;
-}
-
-/**
- * Implements hook_block_save().
- */
-function forum_block_save($delta = '', $edit = array()) {
-  variable_set('forum_block_num_' . $delta, $edit['forum_block_num_' . $delta]);
-}
-
-/**
- * Implements hook_block_view().
- *
- * Generates a block containing the currently active forum topics and the
- * most recently added forum topics.
- */
-function forum_block_view($delta = '') {
-  $query = db_select('forum_index', 'f')
-    ->fields('f')
-    ->addTag('node_access');
-  switch ($delta) {
-    case 'active':
-      $title = t('Active forum topics');
-      $query
-        ->orderBy('f.last_comment_timestamp', 'DESC')
-        ->range(0, variable_get('forum_block_num_active', '5'));
-      break;
-
-    case 'new':
-      $title = t('New forum topics');
-      $query
-        ->orderBy('f.created', 'DESC')
-        ->range(0, variable_get('forum_block_num_new', '5'));
-      break;
-  }
-
-  $block['subject'] = $title;
-  // Cache based on the altered query. Enables us to cache with node access enabled.
-  $block['content'] = drupal_render_cache_by_query($query, 'forum_block_view');
-  $block['content']['#access'] = user_access('access content');
-  return $block;
-}
-
-/**
-* A #pre_render callback. Lists nodes based on the element's #query property.
-*
-* @see forum_block_view()
-*
-* @return
-*   A renderable array.
-*/
-function forum_block_view_pre_render($elements) {
-  $result = $elements['#query']->execute();
-  if ($node_title_list = node_title_list($result)) {
-    $elements['forum_list'] = $node_title_list;
-    $elements['forum_more'] = array('#theme' => 'more_link', '#url' => 'forum', '#title' => t('Read the latest forum topics.'));
-  }
-  return $elements;
-}
-
-/**
- * Implements hook_form().
- */
-function forum_form($node, $form_state) {
-  $type = node_type_get_type($node);
-  $form['title'] = array(
-    '#type' => 'textfield',
-    '#title' => check_plain($type->title_label),
-    '#default_value' => !empty($node->title) ? $node->title : '',
-    '#required' => TRUE, '#weight' => -5
-  );
-
-  if (!empty($node->nid)) {
-    $forum_terms = $node->taxonomy_forums;
-    // If editing, give option to leave shadows
-    $shadow = (count($forum_terms) > 1);
-    $form['shadow'] = array('#type' => 'checkbox', '#title' => t('Leave shadow copy'), '#default_value' => $shadow, '#description' => t('If you move this topic, you can leave a link in the old forum to the new forum.'));
-    $form['forum_tid'] = array('#type' => 'value', '#value' => $node->forum_tid);
-  }
-
-  return $form;
-}
-
-/**
- * Returns a tree of all forums for a given taxonomy term ID.
- *
- * @param $tid
- *    (optional) Taxonomy ID of the forum, if not givin all forums will be returned.
- * @return
- *   A tree of taxonomy objects, with the following additional properties:
- *    - 'num_topics': Number of topics in the forum
- *    - 'num_posts': Total number of posts in all topics
- *    - 'last_post': Most recent post for the forum
- *    - 'forums': An array of child forums
- */
-function forum_forum_load($tid = NULL) {
-  $cache = &drupal_static(__FUNCTION__, array());
-
-  // Return a cached forum tree if available.
-  if (!isset($tid)) {
-    $tid = 0;
-  }
-  if (isset($cache[$tid])) {
-    return $cache[$tid];
-  }
-
-  $vid = variable_get('forum_nav_vocabulary', 0);
-
-  // Load and validate the parent term.
-  if ($tid) {
-    $forum_term = taxonomy_term_load($tid);
-    if (!$forum_term || ($forum_term->vid != $vid)) {
-      return $cache[$tid] = FALSE;
-    }
-  }
-  // If $tid is 0, create an empty object to hold the child terms.
-  elseif ($tid === 0) {
-    $forum_term = (object) array(
-      'tid' => 0,
-    );
-  }
-
-  // Determine if the requested term is a container.
-  if (!$forum_term->tid || in_array($forum_term->tid, variable_get('forum_containers', array()))) {
-    $forum_term->container = 1;
-  }
-
-  // Load parent terms.
-  $forum_term->parents = taxonomy_get_parents_all($forum_term->tid);
-
-  // Load the tree below.
-  $forums = array();
-  $_forums = taxonomy_get_tree($vid, $tid);
-
-  if (count($_forums)) {
-    $query = db_select('node', 'n');
-    $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
-    $query->join('forum', 'f', 'n.vid = f.vid');
-    $query->addExpression('COUNT(n.nid)', 'topic_count');
-    $query->addExpression('SUM(ncs.comment_count)', 'comment_count');
-    $counts = $query
-      ->fields('f', array('tid'))
-      ->condition('status', 1)
-      ->groupBy('tid')
-      ->addTag('node_access')
-      ->execute()
-      ->fetchAllAssoc('tid');
-  }
-
-  foreach ($_forums as $forum) {
-    // Determine if the child term is a container.
-    if (in_array($forum->tid, variable_get('forum_containers', array()))) {
-      $forum->container = 1;
-    }
-
-    // Merge in the topic and post counters.
-    if (!empty($counts[$forum->tid])) {
-      $forum->num_topics = $counts[$forum->tid]->topic_count;
-      $forum->num_posts = $counts[$forum->tid]->topic_count + $counts[$forum->tid]->comment_count;
-    }
-    else {
-      $forum->num_topics = 0;
-      $forum->num_posts = 0;
-    }
-
-    // Query "Last Post" information for this forum.
-    $query = db_select('node', 'n');
-    $query->join('users', 'u1', 'n.uid = u1.uid');
-    $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $forum->tid));
-    $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
-    $query->join('users', 'u2', 'ncs.last_comment_uid = u2.uid');
-    $query->addExpression('CASE ncs.last_comment_uid WHEN 0 THEN ncs.last_comment_name ELSE u2.name END', 'last_comment_name');
-
-    $topic = $query
-      ->fields('ncs', array('last_comment_timestamp', 'last_comment_uid'))
-      ->condition('n.status', 1)
-      ->orderBy('last_comment_timestamp', 'DESC')
-      ->range(0, 1)
-      ->addTag('node_access')
-      ->execute()
-      ->fetchObject();
-
-    // Merge in the "Last Post" information.
-    $last_post = new stdClass();
-    if (!empty($topic->last_comment_timestamp)) {
-      $last_post->created = $topic->last_comment_timestamp;
-      $last_post->name = $topic->last_comment_name;
-      $last_post->uid = $topic->last_comment_uid;
-    }
-    $forum->last_post = $last_post;
-
-    $forums[$forum->tid] = $forum;
-  }
-
-  // Cache the result, and return the tree.
-  $forum_term->forums = $forums;
-  $cache[$tid] = $forum_term;
-  return $forum_term;
-}
-
-/**
- * Calculate the number of nodes the user has not yet read and are newer
- * than NODE_NEW_LIMIT.
- */
-function _forum_topics_unread($term, $uid) {
-  $query = db_select('node', 'n');
-  $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $term));
-  $query->leftJoin('history', 'h', 'n.nid = h.nid AND h.uid = :uid', array(':uid' => $uid));
-  $query->addExpression('COUNT(n.nid)', 'count');
-  return $query
-    ->condition('status', 1)
-    ->condition('n.created', NODE_NEW_LIMIT, '>')
-    ->isNull('h.nid')
-    ->addTag('node_access')
-    ->execute()
-    ->fetchField();
-}
-
-function forum_get_topics($tid, $sortby, $forum_per_page) {
-  global $user, $forum_topic_list_header;
-
-  $forum_topic_list_header = array(
-    NULL,
-    array('data' => t('Topic'), 'field' => 'f.title'),
-    array('data' => t('Replies'), 'field' => 'f.comment_count'),
-    array('data' => t('Last reply'), 'field' => 'f.last_comment_timestamp'),
-  );
-
-  $order = _forum_get_topic_order($sortby);
-  for ($i = 0; $i < count($forum_topic_list_header); $i++) {
-    if ($forum_topic_list_header[$i]['field'] == $order['field']) {
-      $forum_topic_list_header[$i]['sort'] = $order['sort'];
-    }
-  }
-
-  $query = db_select('forum_index', 'f')->extend('PagerDefault')->extend('TableSort');
-  $query->fields('f');
-  $query
-    ->condition('f.tid', $tid)
-    ->addTag('node_access')
-    ->orderBy('f.sticky', 'DESC')
-    ->orderByHeader($forum_topic_list_header)
-    ->limit($forum_per_page);
-
-  $count_query = db_select('forum_index', 'f');
-  $count_query->condition('f.tid', $tid);
-  $count_query->addExpression('COUNT(*)');
-  $count_query->addTag('node_access');
-
-  $query->setCountQuery($count_query);
-  $result = $query->execute();
-  $nids = array();
-  foreach ($result as $record) {
-    $nids[] = $record->nid;
-  }
-  if ($nids) {
-    $query = db_select('node', 'n')->extend('TableSort');
-    $query->fields('n', array('title', 'nid', 'type', 'sticky', 'created', 'uid'));
-    $query->addField('n', 'comment', 'comment_mode');
-
-    $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
-    $query->fields('ncs', array('cid', 'last_comment_uid', 'last_comment_timestamp', 'comment_count'));
-
-    $query->join('forum_index', 'f', 'f.nid = ncs.nid');
-    $query->addField('f', 'tid', 'forum_tid');
-
-    $query->join('users', 'u', 'n.uid = u.uid');
-    $query->addField('u', 'name');
-
-    $query->join('users', 'u2', 'ncs.last_comment_uid = u2.uid');
-
-    $query->addExpression('CASE ncs.last_comment_uid WHEN 0 THEN ncs.last_comment_name ELSE u2.name END', 'last_comment_name');
-
-    $query
-      ->orderBy('f.sticky', 'DESC')
-      ->orderByHeader($forum_topic_list_header)
-      ->condition('n.nid', $nids);
-
-    $result = $query->execute();
-  }
-  else {
-    $result = array();
-  }
-
-  $topics = array();
-  $first_new_found = FALSE;
-  foreach ($result as $topic) {
-    if ($user->uid) {
-      // folder is new if topic is new or there are new comments since last visit
-      if ($topic->forum_tid != $tid) {
-        $topic->new = 0;
-      }
-      else {
-        $history = _forum_user_last_visit($topic->nid);
-        $topic->new_replies = comment_num_new($topic->nid, $history);
-        $topic->new = $topic->new_replies || ($topic->last_comment_timestamp > $history);
-      }
-    }
-    else {
-      // Do not track "new replies" status for topics if the user is anonymous.
-      $topic->new_replies = 0;
-      $topic->new = 0;
-    }
-
-    // Make sure only one topic is indicated as the first new topic.
-    $topic->first_new = FALSE;
-    if ($topic->new != 0 && !$first_new_found) {
-      $topic->first_new = TRUE;
-      $first_new_found = TRUE;
-    }
-
-    if ($topic->comment_count > 0) {
-      $last_reply = new stdClass();
-      $last_reply->created = $topic->last_comment_timestamp;
-      $last_reply->name = $topic->last_comment_name;
-      $last_reply->uid = $topic->last_comment_uid;
-      $topic->last_reply = $last_reply;
-    }
-    $topics[] = $topic;
-  }
-
-  return $topics;
-}
-
-/**
- * Process variables for forums.tpl.php
- *
- * The $variables array contains the following arguments:
- * - $forums
- * - $topics
- * - $parents
- * - $tid
- * - $sortby
- * - $forum_per_page
- *
- * @see forums.tpl.php
- */
-function template_preprocess_forums(&$variables) {
-  global $user;
-
-  $vid = variable_get('forum_nav_vocabulary', 0);
-  $vocabulary = taxonomy_vocabulary_load($vid);
-  $title = !empty($vocabulary->name) ? $vocabulary->name : '';
-
-  // Breadcrumb navigation:
-  $breadcrumb[] = l(t('Home'), NULL);
-  if ($variables['tid']) {
-    $breadcrumb[] = l($vocabulary->name, 'forum');
-  }
-  if ($variables['parents']) {
-    $variables['parents'] = array_reverse($variables['parents']);
-    foreach ($variables['parents'] as $p) {
-      if ($p->tid == $variables['tid']) {
-        $title = $p->name;
-      }
-      else {
-        $breadcrumb[] = l($p->name, 'forum/' . $p->tid);
-      }
-    }
-  }
-  drupal_set_breadcrumb($breadcrumb);
-  drupal_set_title($title);
-
-  if ($variables['forums_defined'] = count($variables['forums']) || count($variables['parents'])) {
-    if (!empty($variables['forums'])) {
-      $variables['forums'] = theme('forum_list', $variables);
-    }
-    else {
-      $variables['forums'] = '';
-    }
-
-    if ($variables['tid'] && !in_array($variables['tid'], variable_get('forum_containers', array()))) {
-      $variables['topics'] = theme('forum_topic_list', $variables);
-      drupal_add_feed('taxonomy/term/' . $variables['tid'] . '/feed', 'RSS - ' . $title);
-    }
-    else {
-      $variables['topics'] = '';
-    }
-
-    // Provide separate template suggestions based on what's being output. Topic id is also accounted for.
-    // Check both variables to be safe then the inverse. Forums with topic ID's take precedence.
-    if ($variables['forums'] && !$variables['topics']) {
-      $variables['theme_hook_suggestions'][] = 'forums__containers';
-      $variables['theme_hook_suggestions'][] = 'forums__' . $variables['tid'];
-      $variables['theme_hook_suggestions'][] = 'forums__containers__' . $variables['tid'];
-    }
-    elseif (!$variables['forums'] && $variables['topics']) {
-      $variables['theme_hook_suggestions'][] = 'forums__topics';
-      $variables['theme_hook_suggestions'][] = 'forums__' . $variables['tid'];
-      $variables['theme_hook_suggestions'][] = 'forums__topics__' . $variables['tid'];
-    }
-    else {
-      $variables['theme_hook_suggestions'][] = 'forums__' . $variables['tid'];
-    }
-
-  }
-  else {
-    drupal_set_title(t('No forums defined'));
-    $variables['forums'] = '';
-    $variables['topics'] = '';
-  }
-}
-
-/**
- * Process variables to format a forum listing.
- *
- * $variables contains the following information:
- * - $forums
- * - $parents
- * - $tid
- *
- * @see forum-list.tpl.php
- * @see theme_forum_list()
- */
-function template_preprocess_forum_list(&$variables) {
-  global $user;
-  $row = 0;
-  // Sanitize each forum so that the template can safely print the data.
-  foreach ($variables['forums'] as $id => $forum) {
-    $variables['forums'][$id]->description = !empty($forum->description) ? filter_xss_admin($forum->description) : '';
-    $variables['forums'][$id]->link = url("forum/$forum->tid");
-    $variables['forums'][$id]->name = check_plain($forum->name);
-    $variables['forums'][$id]->is_container = !empty($forum->container);
-    $variables['forums'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
-    $row++;
-
-    $variables['forums'][$id]->new_text = '';
-    $variables['forums'][$id]->new_url = '';
-    $variables['forums'][$id]->new_topics = 0;
-    $variables['forums'][$id]->old_topics = $forum->num_topics;
-    if ($user->uid) {
-      $variables['forums'][$id]->new_topics = _forum_topics_unread($forum->tid, $user->uid);
-      if ($variables['forums'][$id]->new_topics) {
-        $variables['forums'][$id]->new_text = format_plural($variables['forums'][$id]->new_topics, '1 new', '@count new');
-        $variables['forums'][$id]->new_url = url("forum/$forum->tid", array('fragment' => 'new'));
-      }
-      $variables['forums'][$id]->old_topics = $forum->num_topics - $variables['forums'][$id]->new_topics;
-    }
-    $variables['forums'][$id]->last_reply = theme('forum_submitted', array('topic' => $forum->last_post));
-  }
-  // Give meaning to $tid for themers. $tid actually stands for term id.
-  $variables['forum_id'] = $variables['tid'];
-  unset($variables['tid']);
-}
-
-/**
- * Preprocess variables to format the topic listing.
- *
- * $variables contains the following data:
- * - $tid
- * - $topics
- * - $sortby
- * - $forum_per_page
- *
- * @see forum-topic-list.tpl.php
- * @see theme_forum_topic_list()
- */
-function template_preprocess_forum_topic_list(&$variables) {
-  global $forum_topic_list_header;
-
-  // Create the tablesorting header.
-  $ts = tablesort_init($forum_topic_list_header);
-  $header = '';
-  foreach ($forum_topic_list_header as $cell) {
-    $cell = tablesort_header($cell, $forum_topic_list_header, $ts);
-    $header .= _theme_table_cell($cell, TRUE);
-  }
-  $variables['header'] = $header;
-
-  if (!empty($variables['topics'])) {
-    $row = 0;
-    foreach ($variables['topics'] as $id => $topic) {
-      $variables['topics'][$id]->icon = theme('forum_icon', array('new_posts' => $topic->new, 'num_posts' => $topic->comment_count, 'comment_mode' => $topic->comment_mode, 'sticky' => $topic->sticky, 'first_new' => $topic->first_new));
-      $variables['topics'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
-      $row++;
-
-      // We keep the actual tid in forum table, if it's different from the
-      // current tid then it means the topic appears in two forums, one of
-      // them is a shadow copy.
-      if ($variables['tid'] != $topic->forum_tid) {
-        $variables['topics'][$id]->moved = TRUE;
-        $variables['topics'][$id]->title = check_plain($topic->title);
-        $variables['topics'][$id]->message = l(t('This topic has been moved'), "forum/$topic->forum_tid");
-      }
-      else {
-        $variables['topics'][$id]->moved = FALSE;
-        $variables['topics'][$id]->title = l($topic->title, "node/$topic->nid");
-        $variables['topics'][$id]->message = '';
-      }
-      $topic->uid = $topic->last_comment_uid ? $topic->last_comment_uid : $topic->uid;
-      $variables['topics'][$id]->created = theme('forum_submitted', array('topic' => $topic));
-      $variables['topics'][$id]->last_reply = theme('forum_submitted', array('topic' => isset($topic->last_reply) ? $topic->last_reply : NULL));
-
-      $variables['topics'][$id]->new_text = '';
-      $variables['topics'][$id]->new_url = '';
-      if ($topic->new_replies) {
-        $variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new', '@count new');
-        $variables['topics'][$id]->new_url = url("node/$topic->nid", array('query' => comment_new_page_count($topic->comment_count, $topic->new_replies, $topic), 'fragment' => 'new'));
-      }
-
-    }
-  }
-  else {
-    // Make this safe for the template
-    $variables['topics'] = array();
-  }
-  // Give meaning to $tid for themers. $tid actually stands for term id.
-  $variables['topic_id'] = $variables['tid'];
-  unset($variables['tid']);
-
-  $variables['pager'] = theme('pager');
-}
-
-/**
- * Process variables to format the icon for each individual topic.
- *
- * $variables contains the following data:
- * - $new_posts
- * - $num_posts = 0
- * - $comment_mode = 0
- * - $sticky = 0
- * - $first_new
- *
- * @see forum-icon.tpl.php
- * @see theme_forum_icon()
- */
-function template_preprocess_forum_icon(&$variables) {
-  $variables['hot_threshold'] = variable_get('forum_hot_topic', 15);
-  if ($variables['num_posts'] > $variables['hot_threshold']) {
-    $variables['icon_class'] = $variables['new_posts'] ? 'hot-new' : 'hot';
-    $variables['icon_title'] = $variables['new_posts'] ? t('Hot topic, new comments') : t('Hot topic');
-  }
-  else {
-    $variables['icon_class'] = $variables['new_posts'] ? 'new' : 'default';
-    $variables['icon_title'] = $variables['new_posts'] ? t('New comments') : t('Normal topic');
-  }
-
-  if ($variables['comment_mode'] == COMMENT_NODE_CLOSED || $variables['comment_mode'] == COMMENT_NODE_HIDDEN) {
-    $variables['icon_class'] = 'closed';
-    $variables['icon_title'] = t('Closed topic');
-  }
-
-  if ($variables['sticky'] == 1) {
-    $variables['icon_class'] = 'sticky';
-    $variables['icon_title'] = t('Sticky topic');
-  }
-}
-
-/**
- * Process variables to format submission info for display in the forum list and topic list.
- *
- * $variables will contain: $topic
- *
- * @see forum-submitted.tpl.php
- * @see theme_forum_submitted()
- */
-function template_preprocess_forum_submitted(&$variables) {
-  $variables['author'] = isset($variables['topic']->uid) ? theme('username', array('account' => $variables['topic'])) : '';
-  $variables['time'] = isset($variables['topic']->created) ? format_interval(REQUEST_TIME - $variables['topic']->created) : '';
-}
-
-function _forum_user_last_visit($nid) {
-  global $user;
-  $history = &drupal_static(__FUNCTION__, array());
-
-  if (empty($history)) {
-    $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = :uid', array(':uid' => $user->uid));
-    foreach ($result as $t) {
-      $history[$t->nid] = $t->timestamp > NODE_NEW_LIMIT ? $t->timestamp : NODE_NEW_LIMIT;
-    }
-  }
-  return isset($history[$nid]) ? $history[$nid] : NODE_NEW_LIMIT;
-}
-
-function _forum_get_topic_order($sortby) {
-  switch ($sortby) {
-    case 1:
-      return array('field' => 'f.last_comment_timestamp', 'sort' => 'desc');
-      break;
-    case 2:
-      return array('field' => 'f.last_comment_timestamp', 'sort' => 'asc');
-      break;
-    case 3:
-      return array('field' => 'f.comment_count', 'sort' => 'desc');
-      break;
-    case 4:
-      return array('field' => 'f.comment_count', 'sort' => 'asc');
-      break;
-  }
-}
-
-/**
- * Updates the taxonomy index for a given node.
- *
- * @param $nid
- *   The ID of the node to update.
- */
-function _forum_update_forum_index($nid) {
-  $count = db_query('SELECT COUNT(cid) FROM {comment} WHERE nid = :nid AND status = :status', array(
-    ':nid' => $nid,
-    ':status' => COMMENT_PUBLISHED,
-  ))->fetchField();
-
-  if ($count > 0) {
-    // Comments exist.
-    $last_reply = db_query_range('SELECT cid, name, created, uid FROM {comment} WHERE nid = :nid AND status = :status ORDER BY cid DESC', 0, 1, array(
-      ':nid' => $nid,
-      ':status' => COMMENT_PUBLISHED,
-    ))->fetchObject();
-    db_update('forum_index')
-      ->fields( array(
-        'comment_count' => $count,
-        'last_comment_timestamp' => $last_reply->created,
-      ))
-      ->condition('nid', $nid)
-      ->execute();
-  }
-  else {
-    // Comments do not exist.
-    $node = db_query('SELECT uid, created FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject();
-    db_update('forum_index')
-      ->fields( array(
-        'comment_count' => 0,
-        'last_comment_timestamp' => $node->created,
-      ))
-      ->condition('nid', $nid)
-      ->execute();
-  }
-}
-
-/**
- * Implements hook_rdf_mapping().
- */
-function forum_rdf_mapping() {
-  return array(
-    array(
-      'type' => 'node',
-      'bundle' => 'forum',
-      'mapping' => array(
-        'rdftype' => array('sioc:Post', 'sioct:BoardPost'),
-        'taxonomy_forums' => array(
-          'predicates' => array('sioc:has_container'),
-          'type' => 'rel',
-        ),
-      ),
-    ),
-    array(
-      'type' => 'taxonomy_term',
-      'bundle' => 'forums',
-      'mapping' => array(
-        'rdftype' => array('sioc:Container', 'sioc:Forum'),
-      ),
-    ),
-  );
-}
diff --git a/modules/forum/forum.pages.inc b/modules/forum/forum.pages.inc
deleted file mode 100644
index 29307e7..0000000
--- a/modules/forum/forum.pages.inc
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the forum module.
- */
-
-/**
- * Menu callback; prints a forum listing.
- */
-function forum_page($forum_term = NULL) {
-  if (!isset($forum_term)) {
-    // On the main page, display all the top-level forums.
-    $forum_term = forum_forum_load(0);
-  }
-
-  $forum_per_page = variable_get('forum_per_page', 25);
-  $sortby = variable_get('forum_order', 1);
-
-  if (empty($forum_term->container)) {
-    $topics = forum_get_topics($forum_term->tid, $sortby, $forum_per_page);
-  }
-  else {
-    $topics = '';
-  }
-
-  return theme('forums', array('forums' => $forum_term->forums, 'topics' => $topics, 'parents' => $forum_term->parents, 'tid' => $forum_term->tid, 'sortby' => $sortby, 'forums_per_page' => $forum_per_page));
-}
diff --git a/modules/forum/forum.test b/modules/forum/forum.test
deleted file mode 100644
index 1dc45c6..0000000
--- a/modules/forum/forum.test
+++ /dev/null
@@ -1,525 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for forum.module.
- */
-
-class ForumTestCase extends DrupalWebTestCase {
-  protected $admin_user;
-  protected $edit_own_topics_user;
-  protected $edit_any_topics_user;
-  protected $web_user;
-  protected $container;
-  protected $forum;
-  protected $root_forum;
-  protected $nids;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Forum functionality',
-      'description' => 'Create, view, edit, delete, and change forum entries and verify its consistency in the database.',
-      'group' => 'Forum',
-    );
-  }
-
-  /**
-   * Enable modules and create users with specific permissions.
-   */
-  function setUp() {
-    parent::setUp('taxonomy', 'comment', 'forum');
-    // Create users.
-    $this->admin_user = $this->drupalCreateUser(array(
-      'access administration pages',
-      'administer blocks',
-      'administer forums',
-      'administer menu',
-      'administer taxonomy',
-      'create forum content',
-    ));
-    $this->edit_any_topics_user = $this->drupalCreateUser(array(
-      'access administration pages',
-      'create forum content',
-      'edit any forum content',
-      'delete any forum content',
-    ));
-    $this->edit_own_topics_user = $this->drupalCreateUser(array(
-      'create forum content',
-      'edit own forum content',
-      'delete own forum content',
-    ));
-    $this->web_user = $this->drupalCreateUser(array());
-  }
-
-  /**
-   * Login users, create forum nodes, and test forum functionality through the admin and user interfaces.
-   */
-  function testForum() {
-    //Check that the basic forum install creates a default forum topic
-    $this->drupalGet("/forum");
-    // Look for the "General discussion" default forum
-    $this->assertText(t("General discussion"), "Found the default forum at the /forum listing");
-
-    // Do the admin tests.
-    $this->doAdminTests($this->admin_user);
-    // Generate topics to populate the active forum block.
-    $this->generateForumTopics($this->forum);
-
-    // Login an unprivileged user to view the forum topics and generate an
-    // active forum topics list.
-    $this->drupalLogin($this->web_user);
-    // Verify that this user is shown a message that they may not post content.
-    $this->drupalGet('forum/' . $this->forum['tid']);
-    $this->assertText(t('You are not allowed to post new content in the forum'), "Authenticated user without permission to post forum content is shown message in local tasks to that effect.");
-
-    $this->viewForumTopics($this->nids);
-
-    // Log in, and do basic tests for a user with permission to edit any forum
-    // content.
-    $this->doBasicTests($this->edit_any_topics_user, TRUE);
-    // Create a forum node authored by this user.
-    $any_topics_user_node = $this->createForumTopic($this->forum, FALSE);
-
-    // Log in, and do basic tests for a user with permission to edit only its
-    // own forum content.
-    $this->doBasicTests($this->edit_own_topics_user, FALSE);
-    // Create a forum node authored by this user.
-    $own_topics_user_node = $this->createForumTopic($this->forum, FALSE);
-    // Verify that this user cannot edit forum content authored by another user.
-    $this->verifyForums($this->edit_any_topics_user, $any_topics_user_node, FALSE, 403);
-
-    // Verify that this user is shown a local task to add new forum content.
-    $this->drupalGet('forum');
-    $this->assertLink(t('Add new Forum topic'));
-    $this->drupalGet('forum/' . $this->forum['tid']);
-    $this->assertLink(t('Add new Forum topic'));
-
-    // Login a user with permission to edit any forum content.
-    $this->drupalLogin($this->edit_any_topics_user);
-    // Verify that this user can edit forum content authored by another user.
-    $this->verifyForums($this->edit_own_topics_user, $own_topics_user_node, TRUE);
-
-    // Verify the topic and post counts on the forum page.
-    $this->drupalGet('forum');
-
-    // Verify row for testing forum.
-    $forum_arg = array(':forum' => 'forum-list-' . $this->forum['tid']);
-
-    // Topics cell contains number of topics and number of unread topics.
-    $xpath = $this->buildXPathQuery('//tr[@id=:forum]//td[@class="topics"]', $forum_arg);
-    $topics = $this->xpath($xpath);
-    $topics = trim($topics[0]);
-    $this->assertEqual($topics, '6', t('Number of topics found.'));
-
-    // Verify the number of unread topics.
-    $unread_topics = _forum_topics_unread($this->forum['tid'], $this->edit_any_topics_user->uid);
-    $unread_topics = format_plural($unread_topics, '1 new', '@count new');
-    $xpath = $this->buildXPathQuery('//tr[@id=:forum]//td[@class="topics"]//a', $forum_arg);
-    $this->assertFieldByXPath($xpath, $unread_topics, t('Number of unread topics found.'));
-
-    // Verify total number of posts in forum.
-    $xpath = $this->buildXPathQuery('//tr[@id=:forum]//td[@class="posts"]', $forum_arg);
-    $this->assertFieldByXPath($xpath, '6', t('Number of posts found.'));
-
-    // Test loading multiple forum nodes on the front page.
-    $this->drupalLogin($this->drupalCreateUser(array('administer content types', 'create forum content')));
-    $this->drupalPost('admin/structure/types/manage/forum', array('node_options[promote]' => 'promote'), t('Save content type'));
-    $this->createForumTopic($this->forum, FALSE);
-    $this->createForumTopic($this->forum, FALSE);
-    $this->drupalGet('node');
-
-    // Test adding a comment to a forum topic.
-    $node = $this->createForumTopic($this->forum, FALSE);
-    $edit = array();
-    $edit['comment_body[' . LANGUAGE_NONE . '][0][value]'] = $this->randomName();
-    $this->drupalPost("node/$node->nid", $edit, t('Save'));
-    $this->assertResponse(200);
-
-    // Test editing a forum topic that has a comment.
-    $this->drupalLogin($this->edit_any_topics_user);
-    $this->drupalGet('forum/' . $this->forum['tid']);
-    $this->drupalPost("node/$node->nid/edit", array(), t('Save'));
-    $this->assertResponse(200);
-  }
-
-  /**
-   * Forum nodes should not be created without choosing forum from select list.
-   */
-  function testAddOrphanTopic() {
-    // Must remove forum topics to test creating orphan topics.
-    $vid = variable_get('forum_nav_vocabulary');
-    $tree = taxonomy_get_tree($vid);
-    foreach ($tree as $term) {
-      taxonomy_term_delete($term->tid);
-    }
-
-    // Create an orphan forum item.
-    $this->drupalLogin($this->admin_user);
-    $this->drupalPost('node/add/forum', array('title' => $this->randomName(10), 'body[' . LANGUAGE_NONE .'][0][value]' => $this->randomName(120)), t('Save'));
-
-    $nid_count = db_query('SELECT COUNT(nid) FROM {node}')->fetchField();
-    $this->assertEqual(0, $nid_count, t('A forum node was not created when missing a forum vocabulary.'));
-
-    // Reset the defaults for future tests.
-    module_enable(array('forum'));
-  }
-
-  /**
-   * Run admin tests on the admin user.
-   *
-   * @param object $user The logged in user.
-   */
-  private function doAdminTests($user) {
-    // Login the user.
-    $this->drupalLogin($user);
-
-    // Enable the active forum block.
-    $edit = array();
-    $edit['blocks[forum_active][region]'] = 'sidebar_second';
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertResponse(200);
-    $this->assertText(t('The block settings have been updated.'), t('Active forum topics forum block was enabled'));
-
-    // Enable the new forum block.
-    $edit = array();
-    $edit['blocks[forum_new][region]'] = 'sidebar_second';
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertResponse(200);
-    $this->assertText(t('The block settings have been updated.'), t('[New forum topics] Forum block was enabled'));
-
-    // Retrieve forum menu id.
-    $mlid = db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = 'forum' AND menu_name = 'navigation' AND module = 'system' ORDER BY mlid ASC", 0, 1)->fetchField();
-
-    // Add forum to navigation menu.
-    $edit = array();
-    $this->drupalPost('admin/structure/menu/manage/navigation', $edit, t('Save configuration'));
-    $this->assertResponse(200);
-
-    // Edit forum taxonomy.
-    // Restoration of the settings fails and causes subsequent tests to fail.
-    $this->container = $this->editForumTaxonomy();
-    // Create forum container.
-    $this->container = $this->createForum('container');
-    // Verify "edit container" link exists and functions correctly.
-    $this->drupalGet('admin/structure/forum');
-    $this->clickLink('edit container');
-    $this->assertRaw('Edit container', t('Followed the link to edit the container'));
-    // Create forum inside the forum container.
-    $this->forum = $this->createForum('forum', $this->container['tid']);
-    // Verify the "edit forum" link exists and functions correctly.
-    $this->drupalGet('admin/structure/forum');
-    $this->clickLink('edit forum');
-    $this->assertRaw('Edit forum', t('Followed the link to edit the forum'));
-    // Navigate back to forum structure page.
-    $this->drupalGet('admin/structure/forum');
-    // Create second forum in container.
-    $this->delete_forum = $this->createForum('forum', $this->container['tid']);
-    // Save forum overview.
-    $this->drupalPost('admin/structure/forum/', array(), t('Save'));
-    $this->assertRaw(t('The configuration options have been saved.'));
-    // Delete this second form.
-    $this->deleteForum($this->delete_forum['tid']);
-    // Create forum at the top (root) level.
-    $this->root_forum = $this->createForum('forum');
-  }
-
-  /**
-   * Edit the forum taxonomy.
-   */
-  function editForumTaxonomy() {
-    // Backup forum taxonomy.
-    $vid = variable_get('forum_nav_vocabulary', '');
-    $original_settings = taxonomy_vocabulary_load($vid);
-
-    // Generate a random name/description.
-    $title = $this->randomName(10);
-    $description = $this->randomName(100);
-
-    $edit = array(
-      'name' => $title,
-      'description' => $description,
-      'machine_name' => drupal_strtolower(drupal_substr($this->randomName(), 3, 9)),
-    );
-
-    // Edit the vocabulary.
-    $this->drupalPost('admin/structure/taxonomy/' . $original_settings->machine_name . '/edit', $edit, t('Save'));
-    $this->assertResponse(200);
-    $this->assertRaw(t('Updated vocabulary %name.', array('%name' => $title)), t('Vocabulary was edited'));
-
-    // Grab the newly edited vocabulary.
-    entity_get_controller('taxonomy_vocabulary')->resetCache();
-    $current_settings = taxonomy_vocabulary_load($vid);
-
-    // Make sure we actually edited the vocabulary properly.
-    $this->assertEqual($current_settings->name, $title, t('The name was updated'));
-    $this->assertEqual($current_settings->description, $description, t('The description was updated'));
-
-    // Restore the original vocabulary.
-    taxonomy_vocabulary_save($original_settings);
-    drupal_static_reset('taxonomy_vocabulary_load');
-    $current_settings = taxonomy_vocabulary_load($vid);
-    $this->assertEqual($current_settings->name, $original_settings->name, 'The original vocabulary settings were restored');
-  }
-
-  /**
-   * Create a forum container or a forum.
-   *
-   * @param $type
-   *   Forum type (forum container or forum).
-   * @param $parent
-   *   Forum parent (default = 0 = a root forum; >0 = a forum container or
-   *   another forum).
-   * @return
-   *   taxonomy_term_data created.
-   */
-  function createForum($type, $parent = 0) {
-    // Generate a random name/description.
-    $name = $this->randomName(10);
-    $description = $this->randomName(100);
-
-    $edit = array(
-      'name' => $name,
-      'description' => $description,
-      'parent[0]' => $parent,
-      'weight' => '0',
-    );
-
-    // Create forum.
-    $this->drupalPost('admin/structure/forum/add/' . $type, $edit, t('Save'));
-    $this->assertResponse(200);
-    $type = ($type == 'container') ? 'forum container' : 'forum';
-    $this->assertRaw(t('Created new @type %term.', array('%term' => $name, '@type' => t($type))), t(ucfirst($type) . ' was created'));
-
-    // Verify forum.
-    $term = db_query("SELECT * FROM {taxonomy_term_data} t WHERE t.vid = :vid AND t.name = :name AND t.description = :desc", array(':vid' => variable_get('forum_nav_vocabulary', ''), ':name' => $name, ':desc' => $description))->fetchAssoc();
-    $this->assertTrue(!empty($term), 'The ' . $type . ' exists in the database');
-
-    // Verify forum hierarchy.
-    $tid = $term['tid'];
-    $parent_tid = db_query("SELECT t.parent FROM {taxonomy_term_hierarchy} t WHERE t.tid = :tid", array(':tid' => $tid))->fetchField();
-    $this->assertTrue($parent == $parent_tid, 'The ' . $type . ' is linked to its container');
-
-    return $term;
-  }
-
-  /**
-   * Delete a forum.
-   *
-   * @param $tid
-   *   The forum ID.
-   */
-  function deleteForum($tid) {
-    // Delete the forum.
-    $this->drupalPost('admin/structure/forum/edit/forum/' . $tid, array(), t('Delete'));
-    $this->drupalPost(NULL, array(), t('Delete'));
-
-    // Assert that the forum no longer exists.
-    $this->drupalGet('forum/' . $tid);
-    $this->assertResponse(404, 'The forum was not found');
-  }
-
-  /**
-   * Run basic tests on the indicated user.
-   *
-   * @param $user
-   *   The logged in user.
-   * @param $admin
-   *   User has 'access administration pages' privilege.
-   */
-  private function doBasicTests($user, $admin) {
-    // Login the user.
-    $this->drupalLogin($user);
-    // Attempt to create forum topic under a container.
-    $this->createForumTopic($this->container, TRUE);
-    // Create forum node.
-    $node = $this->createForumTopic($this->forum, FALSE);
-    // Verify the user has access to all the forum nodes.
-    $this->verifyForums($user, $node, $admin);
-  }
-
-  /**
-   * Create forum topic.
-   *
-   * @param array $forum
-   *   Forum array.
-   * @param boolean $container
-   *   True if $forum is a container.
-   *
-   * @return object
-   *   Topic node created.
-   */
-  function createForumTopic($forum, $container = FALSE) {
-    // Generate a random subject/body.
-    $title = $this->randomName(20);
-    $body = $this->randomName(200);
-
-    $langcode = LANGUAGE_NONE;
-    $edit = array(
-      "title" => $title,
-      "body[$langcode][0][value]" => $body,
-    );
-    $tid = $forum['tid'];
-
-    // Create the forum topic, preselecting the forum ID via a URL parameter.
-    $this->drupalPost('node/add/forum/' . $tid, $edit, t('Save'));
-
-    $type = t('Forum topic');
-    if ($container) {
-      $this->assertNoRaw(t('@type %title has been created.', array('@type' => $type, '%title' => $title)), t('Forum topic was not created'));
-      $this->assertRaw(t('The item %title is a forum container, not a forum.', array('%title' => $forum['name'])), t('Error message was shown'));
-      return;
-    }
-    else {
-      $this->assertRaw(t('@type %title has been created.', array('@type' => $type, '%title' => $title)), t('Forum topic was created'));
-      $this->assertNoRaw(t('The item %title is a forum container, not a forum.', array('%title' => $forum['name'])), t('No error message was shown'));
-    }
-
-    // Retrieve node object, ensure that the topic was created and in the proper forum.
-    $node = $this->drupalGetNodeByTitle($title);
-    $this->assertTrue($node != NULL, t('Node @title was loaded', array('@title' => $title)));
-    $this->assertEqual($node->taxonomy_forums[LANGUAGE_NONE][0]['tid'], $tid, 'Saved forum topic was in the expected forum');
-
-    // View forum topic.
-    $this->drupalGet('node/' . $node->nid);
-    $this->assertRaw($title, t('Subject was found'));
-    $this->assertRaw($body, t('Body was found'));
-
-    return $node;
-  }
-
-  /**
-   * Verify the logged in user has access to a forum nodes.
-   *
-   * @param $node_user
-   *   The user who creates the node.
-   * @param $node
-   *   The node being checked.
-   * @param $admin
-   *   Boolean to indicate whether the user can 'access administration pages'.
-   * @param $response
-   *   The exptected HTTP response code.
-   */
-  private function verifyForums($node_user, $node, $admin, $response = 200) {
-    $response2 = ($admin) ? 200 : 403;
-
-    // View forum help node.
-    $this->drupalGet('admin/help/forum');
-    $this->assertResponse($response2);
-    if ($response2 == 200) {
-      $this->assertTitle(t('Forum | Drupal'), t('Forum help title was displayed'));
-      $this->assertText(t('Forum'), t('Forum help node was displayed'));
-    }
-
-    // Verify the forum blocks were displayed.
-    $this->drupalGet('');
-    $this->assertResponse(200);
-    $this->assertText(t('New forum topics'), t('[New forum topics] Forum block was displayed'));
-
-    // View forum container page.
-    $this->verifyForumView($this->container);
-    // View forum page.
-    $this->verifyForumView($this->forum, $this->container);
-    // View root forum page.
-    $this->verifyForumView($this->root_forum);
-
-    // View forum node.
-    $this->drupalGet('node/' . $node->nid);
-    $this->assertResponse(200);
-    $this->assertTitle($node->title . ' | Drupal', t('Forum node was displayed'));
-    $breadcrumb = array(
-      l(t('Home'), NULL),
-      l(t('Forums'), 'forum'),
-      l($this->container['name'], 'forum/' . $this->container['tid']),
-      l($this->forum['name'], 'forum/' . $this->forum['tid']),
-    );
-    $this->assertRaw(theme('breadcrumb', array('breadcrumb' => $breadcrumb)), t('Breadcrumbs were displayed'));
-
-    // View forum edit node.
-    $this->drupalGet('node/' . $node->nid . '/edit');
-    $this->assertResponse($response);
-    if ($response == 200) {
-      $this->assertTitle('Edit Forum topic ' . $node->title . ' | Drupal', t('Forum edit node was displayed'));
-    }
-
-    if ($response == 200) {
-      // Edit forum node (including moving it to another forum).
-      $edit = array();
-      $langcode = LANGUAGE_NONE;
-      $edit["title"] = 'node/' . $node->nid;
-      $edit["body[$langcode][0][value]"] = $this->randomName(256);
-      // Assume the topic is initially associated with $forum.
-      $edit["taxonomy_forums[$langcode]"] = $this->root_forum['tid'];
-      $edit['shadow'] = TRUE;
-      $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
-      $this->assertRaw(t('Forum topic %title has been updated.', array('%title' => $edit["title"])), t('Forum node was edited'));
-
-      // Verify topic was moved to a different forum.
-      $forum_tid = db_query("SELECT tid FROM {forum} WHERE nid = :nid AND vid = :vid", array(
-        ':nid' => $node->nid,
-        ':vid' => $node->vid,
-      ))->fetchField();
-      $this->assertTrue($forum_tid == $this->root_forum['tid'], 'The forum topic is linked to a different forum');
-
-      // Delete forum node.
-      $this->drupalPost('node/' . $node->nid . '/delete', array(), t('Delete'));
-      $this->assertResponse($response);
-      $this->assertRaw(t('Forum topic %title has been deleted.', array('%title' => $edit['title'])), t('Forum node was deleted'));
-    }
-  }
-
-  /**
-   * Verify display of forum page.
-   *
-   * @param $forum
-   *   A row from taxonomy_term_data table in array.
-   */
-  private function verifyForumView($forum, $parent = NULL) {
-    // View forum page.
-    $this->drupalGet('forum/' . $forum['tid']);
-    $this->assertResponse(200);
-    $this->assertTitle($forum['name'] . ' | Drupal', t('Forum name was displayed'));
-
-    $breadcrumb = array(
-      l(t('Home'), NULL),
-      l(t('Forums'), 'forum'),
-    );
-    if (isset($parent)) {
-      $breadcrumb[] = l($parent['name'], 'forum/' . $parent['tid']);
-    }
-
-    $this->assertRaw(theme('breadcrumb', array('breadcrumb' => $breadcrumb)), t('Breadcrumbs were displayed'));
-  }
-
-  /**
-   * Generate forum topics to test display of active forum block.
-   *
-   * @param array $forum Forum array (a row from taxonomy_term_data table).
-   */
-  private function generateForumTopics($forum) {
-    $this->nids = array();
-    for ($i = 0; $i < 5; $i++) {
-      $node = $this->createForumTopic($this->forum, FALSE);
-      $this->nids[] = $node->nid;
-    }
-  }
-
-  /**
-   * View forum topics to test display of active forum block.
-   *
-   * @todo The logic here is completely incorrect, since the active
-   * forum topics block is determined by comments on the node, not by views.
-   * @todo DIE
-   *
-   * @param $nids
-   *   An array of forum node IDs.
-   */
-  private function viewForumTopics($nids) {
-    for ($i = 0; $i < 2; $i++) {
-      foreach ($nids as $nid) {
-        $this->drupalGet('node/' . $nid);
-        $this->drupalGet('node/' . $nid);
-        $this->drupalGet('node/' . $nid);
-      }
-    }
-  }
-}
diff --git a/modules/forum/forums.tpl.php b/modules/forum/forums.tpl.php
deleted file mode 100644
index 55a760f..0000000
--- a/modules/forum/forums.tpl.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display a forum which may contain forum
- * containers as well as forum topics.
- *
- * Variables available:
- * - $forums: The forums to display (as processed by forum-list.tpl.php)
- * - $topics: The topics to display (as processed by forum-topic-list.tpl.php)
- * - $forums_defined: A flag to indicate that the forums are configured.
- *
- * @see template_preprocess_forums()
- * @see theme_forums()
- */
-?>
-<?php if ($forums_defined): ?>
-<div id="forum">
-  <?php print $forums; ?>
-  <?php print $topics; ?>
-</div>
-<?php endif; ?>
diff --git a/modules/overlay/images/background.png b/modules/overlay/images/background.png
deleted file mode 100644
index 9be21936e15f1d7016e24e78fc2ab7af3e5d0d7d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 76
zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4346LYhDc0JPDn_&;jbbW>fztY
Y5F+R`w{CCD3ZOKDr>mdKI;Vst05@9_2LJ#7

diff --git a/modules/overlay/images/close.png b/modules/overlay/images/close.png
deleted file mode 100644
index 436985e226fd080768ef3345691da20c72e38942..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 344
zcmeAS@N?(olHy`uVBq!ia0vp^QXtI13?%1G+4BcT1qS$pxB}__L<6AWGiS~Kl^Yls
zJb3URKR>^qpy2-f`+xrYNk~ZO=;-+S_peo9<7S{b{*oZSV21tY-}ejf*Bj_N*dJ(^
zaHL*H0w}fI)5S5QBChsQCttGyPebDR%Dn8;3-jLpU(g)(ny1m;O?W?tMp((}+I`1f
z^-OvdsrmNr2_e&*Ddw$LB^e%vZG6`+BV)NS@?=BWj8~Iw4yZH5+uYXJ!gkYuEAL>%
zKF5rHbIyL@H%5<4h3gDutfIA9WP}t8M6?4c4}3CuQ~S~E(uDe_EB`F~VtG<{dyLDq
y<Gvri?bFQkT|dREZI|8m&AN<1S+5gU_0>iDsi*c7l<5JT%;4$j=d#Wzp$PyVZl~7(

diff --git a/modules/overlay/overlay-child.css b/modules/overlay/overlay-child.css
deleted file mode 100644
index a832fc8..0000000
--- a/modules/overlay/overlay-child.css
+++ /dev/null
@@ -1,166 +0,0 @@
-
-html.js {
-  background: transparent !important;
-  overflow-y: scroll;
-}
-html.js body {
-  background: transparent !important;
-  margin-left: 0;
-  margin-right: 0;
-  padding: 20px 0;
-}
-
-#overlay {
-  display: table;
-  margin: 0 auto;
-  min-height: 100px;
-  min-width: 700px;
-  position: relative;
-  padding: .2em;
-  padding-right: 26px;
-  width: 88%;
-}
-#overlay-titlebar {
-  padding: 0 20px;
-  position: relative;
-  white-space: nowrap;
-  z-index: 100;
-}
-#overlay-content {
-  background: #fff;
-  clear: both;
-  color: #000;
-  padding: .5em 1em;
-  position: relative;
-}
-
-#overlay-title-wrapper {
-  overflow: hidden;
-}
-#overlay-title {
-  color: #fff;
-  float: left;
-  font-size: 20px;
-  margin: 0;
-  padding: 0.3em 0;
-}
-#overlay-title:active,
-#overlay-title:focus {
-  outline: 0;
-}
-
-.overlay #skip-link {
-  margin-top: -20px;
-}
-.overlay #skip-link a {
-  color: #fff; /* This is white to contrast with the dark background behind it. */
-}
-
-#overlay-close-wrapper {
-  position: absolute;
-  right: 0;
-}
-#overlay-close,
-#overlay-close:hover {
-  background: transparent url(images/close.png) no-repeat;
-  -moz-border-radius-topleft: 0;
-  -webkit-border-top-left-radius: 0;
-  border-top-left-radius: 0;
-  display: block;
-  height: 26px;
-  margin: 0;
-  padding: 0;
-  /* Replace with position:fixed to get a scrolling close button. */
-  position: absolute;
-  width: 26px;
-}
-
-/**
- * Tabs on the overlay.
- */
-#overlay-tabs {
-  line-height: 27px;
-  margin: -28px 0 0 0;
-  position: absolute;
-  right: 20px;
-  text-transform: uppercase;
-}
-#overlay-tabs li {
-  display: inline;
-  list-style: none;
-  margin: 0 0 0 -3px;
-  padding: 0;
-}
-#overlay-tabs li a,
-#overlay-tabs li a:active,
-#overlay-tabs li a:visited,
-#overlay-tabs li a:hover {
-  background-color: #a6a7a2;
-  -moz-border-radius: 8px 8px 0 0;
-  -webkit-border-top-left-radius: 8px;
-  -webkit-border-top-right-radius: 8px;
-  border-radius: 8px 8px 0 0;
-  color: #000;
-  display: inline-block;
-  font-size: 11px;
-  font-weight: bold;
-  margin: 0 0 2px 0;
-  outline: 0;
-  padding: 0 14px;
-  text-decoration: none;
-}
-#overlay-tabs li.active a,
-#overlay-tabs li.active a.active,
-#overlay-tabs li.active a:active,
-#overlay-tabs li.active a:visited {
-  background-color: #fff;
-  margin: 0;
-  padding-bottom: 2px;
-}
-#overlay-tabs li a:focus,
-#overlay-tabs li a:hover {
-  color: #fff;
-}
-#overlay-tabs li.active a:focus,
-#overlay-tabs li.active a:hover {
-  color: #000;
-}
-
-/**
- * Add to shortcuts link
- */
-#overlay-titlebar .add-or-remove-shortcuts {
-  padding-top: 0.9em;
-}
-
-/**
- * IE6 shows elements with position:fixed as position:static so replace
- * it with position:absolute;
- */
-* html #overlay-close,
-* html #overlay-close:hover {
-  position: absolute;
-}
-
-/**
- * Disable message.
- */
-#overlay-disable-message {
-  background-color: #fff;
-  margin: -20px auto 20px;
-  width: 80%;
-  -moz-border-radius: 0 0 8px 8px;
-  -webkit-border-bottom-left-radius: 8px;
-  -webkit-border-bottom-right-radius: 8px;
-  border-radius: 0 0 8px 8px;
-}
-.overlay-disable-message-focused {
-  padding: 0.5em;
-}
-.overlay-disable-message-focused a {
-  display: block;
-  float: left;
-}
-.overlay-disable-message-focused #overlay-dismiss-message {
-  float: right;
-}
diff --git a/modules/overlay/overlay-child.js b/modules/overlay/overlay-child.js
deleted file mode 100644
index e78e383..0000000
--- a/modules/overlay/overlay-child.js
+++ /dev/null
@@ -1,192 +0,0 @@
-
-(function ($) {
-
-/**
- * Attach the child dialog behavior to new content.
- */
-Drupal.behaviors.overlayChild = {
-  attach: function (context, settings) {
-    // Make sure this behavior is not processed more than once.
-    if (this.processed) {
-      return;
-    }
-    this.processed = true;
-
-    // If we cannot reach the parent window, break out of the overlay.
-    if (!parent.Drupal || !parent.Drupal.overlay) {
-      window.location = window.location.href.replace(/([?&]?)render=overlay&?/g, '$1').replace(/\?$/, '');
-    }
-
-    var settings = settings.overlayChild || {};
-
-    // If the entire parent window should be refreshed when the overlay is
-    // closed, pass that information to the parent window.
-    if (settings.refreshPage) {
-      parent.Drupal.overlay.refreshPage = true;
-    }
-
-    // If a form has been submitted successfully, then the server side script
-    // may have decided to tell the parent window to close the popup dialog.
-    if (settings.closeOverlay) {
-      parent.Drupal.overlay.bindChild(window, true);
-      // Use setTimeout to close the child window from a separate thread,
-      // because the current one is busy processing Drupal behaviors.
-      setTimeout(function () {
-        if (typeof settings.redirect == 'string') {
-          parent.Drupal.overlay.redirect(settings.redirect);
-        }
-        else {
-          parent.Drupal.overlay.close();
-        }
-      }, 1);
-      return;
-    }
-
-    // If one of the regions displaying outside the overlay needs to be
-    // reloaded immediately, let the parent window know.
-    if (settings.refreshRegions) {
-      parent.Drupal.overlay.refreshRegions(settings.refreshRegions);
-    }
-
-    // Ok, now we can tell the parent window we're ready.
-    parent.Drupal.overlay.bindChild(window);
-
-    // IE8 crashes on certain pages if this isn't called; reason unknown.
-    window.scrollTo(window.scrollX, window.scrollY);
-
-    // Attach child related behaviors to the iframe document.
-    Drupal.overlayChild.attachBehaviors(context, settings);
-
-    // There are two links within the message that informs people about the
-    // overlay and how to disable it. Make sure both links are visible when
-    // either one has focus and add a class to the wrapper for styling purposes.
-    $('#overlay-disable-message', context)
-      .focusin(function () {
-        $(this).addClass('overlay-disable-message-focused');
-        $('a.element-focusable', this).removeClass('element-invisible');
-      })
-      .focusout(function () {
-        $(this).removeClass('overlay-disable-message-focused');
-        $('a.element-focusable', this).addClass('element-invisible');
-      });
-  }
-};
-
-/**
- * Overlay object for child windows.
- */
-Drupal.overlayChild = Drupal.overlayChild || {
-  behaviors: {}
-};
-
-Drupal.overlayChild.prototype = {};
-
-/**
- * Attach child related behaviors to the iframe document.
- */
-Drupal.overlayChild.attachBehaviors = function (context, settings) {
-  $.each(this.behaviors, function () {
-    this(context, settings);
-  });
-};
-
-/**
- * Capture and handle clicks.
- *
- * Instead of binding a click event handler to every link we bind one to the
- * document and handle events that bubble up. This also allows other scripts
- * to bind their own handlers to links and also to prevent overlay's handling.
- */
-Drupal.overlayChild.behaviors.addClickHandler = function (context, settings) {
-  $(document).bind('click.drupal-overlay mouseup.drupal-overlay', $.proxy(parent.Drupal.overlay, 'eventhandlerOverrideLink'));
-};
-
-/**
- * Modify forms depending on their relation to the overlay.
- *
- * By default, forms are assumed to keep the flow in the overlay. Thus their
- * action attribute get a ?render=overlay suffix.
- */
-Drupal.overlayChild.behaviors.parseForms = function (context, settings) {
-  $('form', context).once('overlay', function () {
-    // Obtain the action attribute of the form.
-    var action = $(this).attr('action');
-    // Keep internal forms in the overlay.
-    if (action == undefined || (action.indexOf('http') != 0 && action.indexOf('https') != 0)) {
-      action += (action.indexOf('?') > -1 ? '&' : '?') + 'render=overlay';
-      $(this).attr('action', action);
-    }
-    // Submit external forms into a new window.
-    else {
-      $(this).attr('target', '_new');
-    }
-  });
-};
-
-/**
- * Replace the overlay title with a message while loading another page.
- */
-Drupal.overlayChild.behaviors.loading = function (context, settings) {
-  var $title;
-  var text = Drupal.t('Loading');
-  var dots = '';
-
-  $(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
-    $title = $('#overlay-title').text(text);
-    var id = setInterval(function () {
-      dots = (dots.length > 10) ? '' : dots + '.';
-      $title.text(text + dots);
-    }, 500);
-  });
-};
-
-/**
- * Switch active tab immediately.
- */
-Drupal.overlayChild.behaviors.tabs = function (context, settings) {
-  var $tabsLinks = $('#overlay-tabs > li > a');
-
-  $('#overlay-tabs > li > a').bind('click.drupal-overlay', function () {
-    var active_tab = Drupal.t('(active tab)');
-    $tabsLinks.parent().siblings().removeClass('active').find('element-invisible:contains(' + active_tab + ')').appendTo(this);
-    $(this).parent().addClass('active');
-  });
-};
-
-/**
- * If the shortcut add/delete button exists, move it to the overlay titlebar.
- */
-Drupal.overlayChild.behaviors.shortcutAddLink = function (context, settings) {
-  // Remove any existing shortcut button markup from the titlebar.
-  $('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
-  // If the shortcut add/delete button exists, move it to the titlebar.
-  var $addToShortcuts = $('.add-or-remove-shortcuts');
-  if ($addToShortcuts.length) {
-    $addToShortcuts.insertAfter('#overlay-title');
-  }
-
-  $(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
-    $('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
-  });
-};
-
-/**
- * Use displacement from parent window.
- */
-Drupal.overlayChild.behaviors.alterTableHeaderOffset = function (context, settings) {
-  if (Drupal.settings.tableHeaderOffset) {
-    Drupal.overlayChild.prevTableHeaderOffset = Drupal.settings.tableHeaderOffset;
-  }
-  Drupal.settings.tableHeaderOffset = 'Drupal.overlayChild.tableHeaderOffset';
-};
-
-/**
- * Callback for Drupal.settings.tableHeaderOffset.
- */
-Drupal.overlayChild.tableHeaderOffset = function () {
-  var topOffset = Drupal.overlayChild.prevTableHeaderOffset ? eval(Drupal.overlayChild.prevTableHeaderOffset + '()') : 0;
-
-  return topOffset + parseInt($(document.body).css('marginTop'));
-};
-
-})(jQuery);
diff --git a/modules/overlay/overlay-parent.css b/modules/overlay/overlay-parent.css
deleted file mode 100644
index dad6d55..0000000
--- a/modules/overlay/overlay-parent.css
+++ /dev/null
@@ -1,50 +0,0 @@
-
-html.overlay-open,
-html.overlay-open body {
-  height: 100%;
-  overflow: hidden;
-}
-
-#overlay-container,
-.overlay-modal-background,
-.overlay-element {
-  height: 100%;
-  left: 0;
-  position: absolute;
-  top: 0;
-  width: 100%;
-  z-index: 500;
-}
-
-.overlay-modal-background {
-  /* Using a transparent png renders faster than using opacity */
-  background: transparent url(images/background.png) repeat;
-}
-
-.overlay-element {
-  background: transparent;
-  left: -200%;
-  z-index: 501;
-}
-.overlay-element.overlay-active {
-  left: 0;
-}
-
-html.overlay-open .displace-top,
-html.overlay-open .displace-bottom {
-  z-index: 600;
-}
-
-/**
- * Within the overlay parent, the message about disabling the overlay is for
- * screen-reader users only. It is always kept invisible with the
- * element-invisible class, and removed from the tab order. Overlay-child.css
- * contains styling for the same message appearing within the overlay, and
- * intended for sighted users.
- */
-#overlay-disable-message {
-  display: none;
-}
-html.overlay-open #overlay-disable-message {
-  display: block;
-}
diff --git a/modules/overlay/overlay-parent.js b/modules/overlay/overlay-parent.js
deleted file mode 100644
index 8010d01..0000000
--- a/modules/overlay/overlay-parent.js
+++ /dev/null
@@ -1,961 +0,0 @@
-
-(function ($) {
-
-/**
- * Open the overlay, or load content into it, when an admin link is clicked.
- */
-Drupal.behaviors.overlayParent = {
-  attach: function (context, settings) {
-    if (Drupal.overlay.isOpen) {
-      Drupal.overlay.makeDocumentUntabbable(context);
-    }
-
-    if (this.processed) {
-      return;
-    }
-    this.processed = true;
-
-    $(window)
-      // When the hash (URL fragment) changes, open the overlay if needed.
-      .bind('hashchange.drupal-overlay', $.proxy(Drupal.overlay, 'eventhandlerOperateByURLFragment'))
-      // Trigger the hashchange handler once, after the page is loaded, so that
-      // permalinks open the overlay.
-      .triggerHandler('hashchange.drupal-overlay');
-
-    $(document)
-      // Instead of binding a click event handler to every link we bind one to
-      // the document and only handle events that bubble up. This allows other
-      // scripts to bind their own handlers to links and also to prevent
-      // overlay's handling.
-      .bind('click.drupal-overlay mouseup.drupal-overlay', $.proxy(Drupal.overlay, 'eventhandlerOverrideLink'));
-  }
-};
-
-/**
- * Overlay object for parent windows.
- *
- * Events
- * Overlay triggers a number of events that can be used by other scripts.
- * - drupalOverlayOpen: This event is triggered when the overlay is opened.
- * - drupalOverlayBeforeClose: This event is triggered when the overlay attempts
- *   to close. If an event handler returns false, the close will be prevented.
- * - drupalOverlayClose: This event is triggered when the overlay is closed.
- * - drupalOverlayBeforeLoad: This event is triggered right before a new URL
- *   is loaded into the overlay.
- * - drupalOverlayReady: This event is triggered when the DOM of the overlay
- *   child document is fully loaded.
- * - drupalOverlayLoad: This event is triggered when the overlay is finished
- *   loading.
- * - drupalOverlayResize: This event is triggered when the overlay is being
- *   resized to match the parent window.
- */
-Drupal.overlay = Drupal.overlay || {
-  isOpen: false,
-  isOpening: false,
-  isClosing: false,
-  isLoading: false
-};
-
-Drupal.overlay.prototype = {};
-
-/**
- * Open the overlay.
- *
- * @param url
- *   The URL of the page to open in the overlay.
- *
- * @return
- *   TRUE if the overlay was opened, FALSE otherwise.
- */
-Drupal.overlay.open = function (url) {
-  // Just one overlay is allowed.
-  if (this.isOpen || this.isOpening) {
-    return this.load(url);
-  }
-  this.isOpening = true;
-  // Store the original document title.
-  this.originalTitle = document.title;
-
-  // Create the dialog and related DOM elements.
-  this.create();
-
-  this.isOpening = false;
-  this.isOpen = true;
-  $(document.documentElement).addClass('overlay-open');
-  this.makeDocumentUntabbable();
-
-  // Allow other scripts to respond to this event.
-  $(document).trigger('drupalOverlayOpen');
-
-  return this.load(url);
-};
-
-/**
- * Create the underlying markup and behaviors for the overlay.
- */
-Drupal.overlay.create = function () {
-  this.$container = $(Drupal.theme('overlayContainer'))
-    .appendTo(document.body);
-
-  // Overlay uses transparent iframes that cover the full parent window.
-  // When the overlay is open the scrollbar of the parent window is hidden.
-  // Because some browsers show a white iframe background for a short moment
-  // while loading a page into an iframe, overlay uses two iframes. By loading
-  // the page in a hidden (inactive) iframe the user doesn't see the white
-  // background. When the page is loaded the active and inactive iframes
-  // are switched.
-  this.activeFrame = this.$iframeA = $(Drupal.theme('overlayElement'))
-    .appendTo(this.$container);
-
-  this.inactiveFrame = this.$iframeB = $(Drupal.theme('overlayElement'))
-    .appendTo(this.$container);
-
-  this.$iframeA.bind('load.drupal-overlay', { self: this.$iframeA[0], sibling: this.$iframeB }, $.proxy(this, 'loadChild'));
-  this.$iframeB.bind('load.drupal-overlay', { self: this.$iframeB[0], sibling: this.$iframeA }, $.proxy(this, 'loadChild'));
-
-  // Add a second class "drupal-overlay-open" to indicate these event handlers
-  // should only be bound when the overlay is open.
-  var eventClass = '.drupal-overlay.drupal-overlay-open';
-  $(window)
-    .bind('resize' + eventClass, $.proxy(this, 'eventhandlerOuterResize'));
-  $(document)
-    .bind('drupalOverlayLoad' + eventClass, $.proxy(this, 'eventhandlerOuterResize'))
-    .bind('drupalOverlayReady' + eventClass +
-          ' drupalOverlayClose' + eventClass, $.proxy(this, 'eventhandlerSyncURLFragment'))
-    .bind('drupalOverlayClose' + eventClass, $.proxy(this, 'eventhandlerRefreshPage'))
-    .bind('drupalOverlayBeforeClose' + eventClass +
-          ' drupalOverlayBeforeLoad' + eventClass +
-          ' drupalOverlayResize' + eventClass, $.proxy(this, 'eventhandlerDispatchEvent'));
-
-  if ($('.overlay-displace-top, .overlay-displace-bottom').length) {
-    $(document)
-      .bind('drupalOverlayResize' + eventClass, $.proxy(this, 'eventhandlerAlterDisplacedElements'))
-      .bind('drupalOverlayClose' + eventClass, $.proxy(this, 'eventhandlerRestoreDisplacedElements'));
-  }
-};
-
-/**
- * Load the given URL into the overlay iframe.
- *
- * Use this method to change the URL being loaded in the overlay if it is
- * already open.
- *
- * @return
- *   TRUE if URL is loaded into the overlay, FALSE otherwise.
- */
-Drupal.overlay.load = function (url) {
-  if (!this.isOpen) {
-    return false;
-  }
-
-  // Allow other scripts to respond to this event.
-  $(document).trigger('drupalOverlayBeforeLoad');
-
-  $(document.documentElement).addClass('overlay-loading');
-
-  // The contentDocument property is not supported in IE until IE8.
-  var iframeDocument = this.inactiveFrame[0].contentDocument || this.inactiveFrame[0].contentWindow.document;
-
-  // location.replace doesn't create a history entry. location.href does.
-  // In this case, we want location.replace, as we're creating the history
-  // entry using URL fragments.
-  iframeDocument.location.replace(url);
-
-  return true;
-};
-
-/**
- * Close the overlay and remove markup related to it from the document.
- *
- * @return
- *   TRUE if the overlay was closed, FALSE otherwise.
- */
-Drupal.overlay.close = function () {
-  // Prevent double execution when close is requested more than once.
-  if (!this.isOpen || this.isClosing) {
-    return false;
-  }
-
-  // Allow other scripts to respond to this event.
-  var event = $.Event('drupalOverlayBeforeClose');
-  $(document).trigger(event);
-  // If a handler returned false, the close will be prevented.
-  if (event.isDefaultPrevented()) {
-    return false;
-  }
-
-  this.isClosing = true;
-  this.isOpen = false;
-  $(document.documentElement).removeClass('overlay-open');
-  // Restore the original document title.
-  document.title = this.originalTitle;
-  this.makeDocumentTabbable();
-
-  // Allow other scripts to respond to this event.
-  $(document).trigger('drupalOverlayClose');
-
-  // When the iframe is still loading don't destroy it immediately but after
-  // the content is loaded (see Drupal.overlay.loadChild).
-  if (!this.isLoading) {
-    this.destroy();
-    this.isClosing = false;
-  }
-  return true;
-};
-
-/**
- * Destroy the overlay.
- */
-Drupal.overlay.destroy = function () {
-  $([document, window]).unbind('.drupal-overlay-open');
-  this.$container.remove();
-
-  this.$container = null;
-  this.$iframeA = null;
-  this.$iframeB = null;
-
-  this.iframeWindow = null;
-};
-
-/**
- * Redirect the overlay parent window to the given URL.
- *
- * @param url
- *   Can be an absolute URL or a relative link to the domain root.
- */
-Drupal.overlay.redirect = function (url) {
-  // Create a native Link object, so we can use its object methods.
-  var link = $(url.link(url)).get(0);
-
-  // If the link is already open, force the hashchange event to simulate reload.
-  if (window.location.href == link.href) {
-    $(window).triggerHandler('hashchange.drupal-overlay');
-  }
-
-  window.location.href = link.href;
-  return true;
-};
-
-/**
- * Bind the child window.
- *
- * Note that this function is fired earlier than Drupal.overlay.loadChild.
- */
-Drupal.overlay.bindChild = function (iframeWindow, isClosing) {
-  this.iframeWindow = iframeWindow;
-
-  // We are done if the child window is closing.
-  if (isClosing || this.isClosing || !this.isOpen) {
-    return;
-  }
-
-  // Allow other scripts to respond to this event.
-  $(document).trigger('drupalOverlayReady');
-};
-
-/**
- * Event handler: load event handler for the overlay iframe.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: load
- *   - event.currentTarget: iframe
- */
-Drupal.overlay.loadChild = function (event) {
-  var iframe = event.data.self;
-  var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
-  var iframeWindow = iframeDocument.defaultView || iframeDocument.parentWindow;
-  if (iframeWindow.location == 'about:blank') {
-    return;
-  }
-
-  this.isLoading = false;
-  $(document.documentElement).removeClass('overlay-loading');
-  event.data.sibling.removeClass('overlay-active').attr({ 'tabindex': -1 });
-
-  // Only continue when overlay is still open and not closing.
-  if (this.isOpen && !this.isClosing) {
-    // And child document is an actual overlayChild.
-    if (iframeWindow.Drupal && iframeWindow.Drupal.overlayChild) {
-      // Replace the document title with title of iframe.
-      document.title = iframeWindow.document.title;
-
-      this.activeFrame = $(iframe)
-        .addClass('overlay-active')
-        // Add a title attribute to the iframe for accessibility.
-        .attr('title', Drupal.t('@title dialog', { '@title': iframeWindow.jQuery('#overlay-title').text() })).removeAttr('tabindex');
-      this.inactiveFrame = event.data.sibling;
-
-      // Load an empty document into the inactive iframe.
-      (this.inactiveFrame[0].contentDocument || this.inactiveFrame[0].contentWindow.document).location.replace('about:blank');
-
-      // Move the focus to just before the "skip to main content" link inside
-      // the overlay.
-      this.activeFrame.focus();
-      var skipLink = iframeWindow.jQuery('a:first');
-      Drupal.overlay.setFocusBefore(skipLink, iframeWindow.document);
-
-      // Allow other scripts to respond to this event.
-      $(document).trigger('drupalOverlayLoad');
-    }
-    else {
-      window.location = iframeWindow.location.href.replace(/([?&]?)render=overlay&?/g, '$1').replace(/\?$/, '');
-    }
-  }
-  else {
-    this.destroy();
-  }
-};
-
-/**
- * Creates a placeholder element to receive document focus.
- *
- * Setting the document focus to a link will make it visible, even if it's a
- * "skip to main content" link that should normally be visible only when the
- * user tabs to it. This function can be used to set the document focus to
- * just before such an invisible link.
- *
- * @param $element
- *   The jQuery element that should receive focus on the next tab press.
- * @param document
- *   The iframe window element to which the placeholder should be added. The
- *   placeholder element has to be created inside the same iframe as the element
- *   it precedes, to keep IE happy. (http://bugs.jquery.com/ticket/4059)
- */
-Drupal.overlay.setFocusBefore = function ($element, document) {
-  // Create an anchor inside the placeholder document.
-  var placeholder = document.createElement('a');
-  var $placeholder = $(placeholder).addClass('element-invisible').attr('href', '#');
-  // Put the placeholder where it belongs, and set the document focus to it.
-  $placeholder.insertBefore($element);
-  $placeholder.focus();
-  // Make the placeholder disappear as soon as it loses focus, so that it
-  // doesn't appear in the tab order again.
-  $placeholder.one('blur', function () {
-    $(this).remove();
-  });
-}
-
-/**
- * Check if the given link is in the administrative section of the site.
- *
- * @param url
- *   The url to be tested.
- *
- * @return boolean
- *   TRUE if the URL represents an administrative link, FALSE otherwise.
- */
-Drupal.overlay.isAdminLink = function (url) {
-  if (Drupal.overlay.isExternalLink(url)) {
-    return false;
-  }
-
-  var path = this.getPath(url);
-
-  // Turn the list of administrative paths into a regular expression.
-  if (!this.adminPathRegExp) {
-    var regExpPrefix = '^' + Drupal.settings.pathPrefix + '(';
-    var adminPaths = regExpPrefix + Drupal.settings.overlay.paths.admin.replace(/\s+/g, ')$|' + regExpPrefix) + ')$';
-    var nonAdminPaths = regExpPrefix + Drupal.settings.overlay.paths.non_admin.replace(/\s+/g, ')$|'+ regExpPrefix) + ')$';
-    adminPaths = adminPaths.replace(/\*/g, '.*');
-    nonAdminPaths = nonAdminPaths.replace(/\*/g, '.*');
-    this.adminPathRegExp = new RegExp(adminPaths);
-    this.nonAdminPathRegExp = new RegExp(nonAdminPaths);
-  }
-
-  return this.adminPathRegExp.exec(path) && !this.nonAdminPathRegExp.exec(path);
-};
-
-/**
- * Determine whether a link is external to the site.
- *
- * @param url
- *   The url to be tested.
- *
- * @return boolean
- *   TRUE if the URL is external to the site, FALSE otherwise.
- */
-Drupal.overlay.isExternalLink = function (url) {
-  var re = RegExp('^((f|ht)tps?:)?//(?!' + window.location.host + ')');
-  return re.test(url);
-};
-
-/**
- * Event handler: resizes overlay according to the size of the parent window.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: any
- *   - event.currentTarget: any
- */
-Drupal.overlay.eventhandlerOuterResize = function (event) {
-  // Proceed only if the overlay still exists.
-  if (!(this.isOpen || this.isOpening) || this.isClosing || !this.iframeWindow) {
-    return;
-  }
-
-  // IE6 uses position:absolute instead of position:fixed.
-  if (typeof document.body.style.maxHeight != 'string') {
-    this.activeFrame.height($(window).height());
-  }
-
-  // Allow other scripts to respond to this event.
-  $(document).trigger('drupalOverlayResize');
-};
-
-/**
- * Event handler: resizes displaced elements so they won't overlap the scrollbar
- * of overlay's iframe.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: any
- *   - event.currentTarget: any
- */
-Drupal.overlay.eventhandlerAlterDisplacedElements = function (event) {
-  // Proceed only if the overlay still exists.
-  if (!(this.isOpen || this.isOpening) || this.isClosing || !this.iframeWindow) {
-    return;
-  }
-
-  $(this.iframeWindow.document.body).css({
-    marginTop: Drupal.overlay.getDisplacement('top'),
-    marginBottom: Drupal.overlay.getDisplacement('bottom')
-  })
-  // IE7 isn't reflowing the document immediately.
-  // @todo This might be fixed in a cleaner way.
-  .addClass('overlay-trigger-reflow').removeClass('overlay-trigger-reflow');
-
-  var documentHeight = this.iframeWindow.document.body.clientHeight;
-  var documentWidth = this.iframeWindow.document.body.clientWidth;
-  // IE6 doesn't support maxWidth, use width instead.
-  var maxWidthName = (typeof document.body.style.maxWidth == 'string') ? 'maxWidth' : 'width';
-
-  // Consider any element that should be visible above the overlay (such as
-  // a toolbar).
-  $('.overlay-displace-top, .overlay-displace-bottom').each(function () {
-    var data = $(this).data();
-    var maxWidth = documentWidth;
-    // In IE, Shadow filter makes element to overlap the scrollbar with 1px.
-    if (this.filters && this.filters.length && this.filters.item('DXImageTransform.Microsoft.Shadow')) {
-      maxWidth -= 1;
-    }
-
-    // Prevent displaced elements overlapping window's scrollbar.
-    var currentMaxWidth = parseInt($(this).css(maxWidthName));
-    if ((data.drupalOverlay && data.drupalOverlay.maxWidth) || isNaN(currentMaxWidth) || currentMaxWidth > maxWidth || currentMaxWidth <= 0) {
-      $(this).css(maxWidthName, maxWidth);
-      (data.drupalOverlay = data.drupalOverlay || {}).maxWidth = true;
-    }
-
-    // Use a more rigorous approach if the displaced element still overlaps
-    // window's scrollbar; clip the element on the right.
-    var offset = $(this).offset();
-    var offsetRight = offset.left + $(this).outerWidth();
-    if ((data.drupalOverlay && data.drupalOverlay.clip) || offsetRight > maxWidth) {
-      $(this).css('clip', 'rect(auto, ' + (maxWidth - offset.left) + 'px, ' + (documentHeight - offset.top) + 'px, auto)');
-      (data.drupalOverlay = data.drupalOverlay || {}).clip = true;
-    }
-  });
-};
-
-/**
- * Event handler: restores size of displaced elements as they were before
- * overlay was opened.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: any
- *   - event.currentTarget: any
- */
-Drupal.overlay.eventhandlerRestoreDisplacedElements = function (event) {
-  var $displacedElements = $('.overlay-displace-top, .overlay-displace-bottom');
-  try {
-    $displacedElements.css({ maxWidth: '', clip: '' });
-  }
-  // IE bug that doesn't allow unsetting style.clip (http://dev.jquery.com/ticket/6512).
-  catch (err) {
-    $displacedElements.attr('style', function (index, attr) {
-      return attr.replace(/clip\s*:\s*rect\([^)]+\);?/i, '');
-    });
-  }
-};
-
-/**
- * Event handler: overrides href of administrative links to be opened in
- * the overlay.
- *
- * This click event handler should be bound to any document (for example the
- * overlay iframe) of which you want links to open in the overlay.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: click, mouseup
- *   - event.currentTarget: document
- *
- * @see Drupal.overlayChild.behaviors.addClickHandler
- */
-Drupal.overlay.eventhandlerOverrideLink = function (event) {
-  // In some browsers the click event isn't fired for right-clicks. Use the
-  // mouseup event for right-clicks and the click event for everything else.
-  if ((event.type == 'click' && event.button == 2) || (event.type == 'mouseup' && event.button != 2)) {
-    return;
-  }
-
-  var $target = $(event.target);
-
-  // Only continue if clicked target (or one of its parents) is a link.
-  if (!$target.is('a')) {
-    $target = $target.closest('a');
-    if (!$target.length) {
-      return;
-    }
-  }
-
-  // Never open links in the overlay that contain the overlay-exclude class.
-  if ($target.hasClass('overlay-exclude')) {
-    return;
-  }
-
-  // Close the overlay when the link contains the overlay-close class.
-  if ($target.hasClass('overlay-close')) {
-    // Clearing the overlay URL fragment will close the overlay.
-    $.bbq.removeState('overlay');
-    return;
-  }
-
-  var target = $target[0];
-  var href = target.href;
-  // Only handle links that have an href attribute and use the http(s) protocol.
-  if (href != undefined && href != '' && target.protocol.match(/^https?\:/)) {
-    var anchor = href.replace(target.ownerDocument.location.href, '');
-    // Skip anchor links.
-    if (anchor.length == 0 || anchor.charAt(0) == '#') {
-      return;
-    }
-    // Open admin links in the overlay.
-    else if (this.isAdminLink(href)) {
-      // If the link contains the overlay-restore class and the overlay-context
-      // state is set, also update the parent window's location.
-      var parentLocation = ($target.hasClass('overlay-restore') && typeof $.bbq.getState('overlay-context') == 'string')
-        ? Drupal.settings.basePath + $.bbq.getState('overlay-context')
-        : null;
-      href = this.fragmentizeLink($target.get(0), parentLocation);
-      // Only override default behavior when left-clicking and user is not
-      // pressing the ALT, CTRL, META (Command key on the Macintosh keyboard)
-      // or SHIFT key.
-      if (event.button == 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
-        // Redirect to a fragmentized href. This will trigger a hashchange event.
-        this.redirect(href);
-        // Prevent default action and further propagation of the event.
-        return false;
-      }
-      // Otherwise alter clicked link's href. This is being picked up by
-      // the default action handler.
-      else {
-        $target
-          // Restore link's href attribute on blur or next click.
-          .one('blur mousedown', { target: target, href: target.href }, function (event) { $(event.data.target).attr('href', event.data.href); })
-          .attr('href', href);
-      }
-    }
-    // Non-admin links should close the overlay and open in the main window,
-    // which is the default action for a link. We only need to handle them
-    // if the overlay is open and the clicked link is inside the overlay iframe.
-    else if (this.isOpen && target.ownerDocument === this.iframeWindow.document) {
-      // Open external links in the immediate parent of the frame, unless the
-      // link already has a different target.
-      if (target.hostname != window.location.hostname) {
-        if (!$target.attr('target')) {
-          $target.attr('target', '_parent');
-        }
-      }
-      else {
-        // Add the overlay-context state to the link, so "overlay-restore" links
-        // can restore the context.
-        $target.attr('href', $.param.fragment(href, { 'overlay-context': this.getPath(window.location) + window.location.search }));
-
-        // When the link has a destination query parameter and that destination
-        // is an admin link we need to fragmentize it. This will make it reopen
-        // in the overlay.
-        var params = $.deparam.querystring(href);
-        if (params.destination && this.isAdminLink(params.destination)) {
-          var fragmentizedDestination = $.param.fragment(this.getPath(window.location), { overlay: params.destination });
-          $target.attr('href', $.param.querystring(href, { destination: fragmentizedDestination }));
-        }
-
-        // Make the link open in the immediate parent of the frame.
-        $target.attr('target', '_parent');
-      }
-    }
-  }
-};
-
-/**
- * Event handler: opens or closes the overlay based on the current URL fragment.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: hashchange
- *   - event.currentTarget: document
- */
-Drupal.overlay.eventhandlerOperateByURLFragment = function (event) {
-  // If we changed the hash to reflect an internal redirect in the overlay,
-  // its location has already been changed, so don't do anything.
-  if ($.data(window.location, window.location.href) === 'redirect') {
-    $.data(window.location, window.location.href, null);
-    return;
-  }
-
-  // Get the overlay URL from the current URL fragment.
-  var state = $.bbq.getState('overlay');
-  if (state) {
-    // Append render variable, so the server side can choose the right
-    // rendering and add child frame code to the page if needed.
-    var url = $.param.querystring(Drupal.settings.basePath + state, { render: 'overlay' });
-
-    this.open(url);
-    this.resetActiveClass(this.getPath(Drupal.settings.basePath + state));
-  }
-  // If there is no overlay URL in the fragment and the overlay is (still)
-  // open, close the overlay.
-  else if (this.isOpen && !this.isClosing) {
-    this.close();
-    this.resetActiveClass(this.getPath(window.location));
-  }
-};
-
-/**
- * Event handler: makes sure the internal overlay URL is reflected in the parent
- * URL fragment.
- *
- * Normally the parent URL fragment determines the overlay location. However, if
- * the overlay redirects internally, the parent doesn't get informed, and the
- * parent URL fragment will be out of date. This is a sanity check to make
- * sure we're in the right place.
- *
- * The parent URL fragment is also not updated automatically when overlay's
- * open, close or load functions are used directly (instead of through
- * eventhandlerOperateByURLFragment).
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: drupalOverlayReady, drupalOverlayClose
- *   - event.currentTarget: document
- */
-Drupal.overlay.eventhandlerSyncURLFragment = function (event) {
-  if (this.isOpen) {
-    var expected = $.bbq.getState('overlay');
-    // This is just a sanity check, so we're comparing paths, not query strings.
-    if (this.getPath(Drupal.settings.basePath + expected) != this.getPath(this.iframeWindow.document.location)) {
-      // There may have been a redirect inside the child overlay window that the
-      // parent wasn't aware of. Update the parent URL fragment appropriately.
-      var newLocation = Drupal.overlay.fragmentizeLink(this.iframeWindow.document.location);
-      // Set a 'redirect' flag on the new location so the hashchange event handler
-      // knows not to change the overlay's content.
-      $.data(window.location, newLocation, 'redirect');
-      // Use location.replace() so we don't create an extra history entry.
-      window.location.replace(newLocation);
-    }
-  }
-  else {
-    $.bbq.removeState('overlay');
-  }
-};
-
-/**
- * Event handler: if the child window suggested that the parent refresh on
- * close, force a page refresh.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: drupalOverlayClose
- *   - event.currentTarget: document
- */
-Drupal.overlay.eventhandlerRefreshPage = function (event) {
-  if (Drupal.overlay.refreshPage) {
-    window.location.reload(true);
-  }
-};
-
-/**
- * Event handler: dispatches events to the overlay document.
- *
- * @param event
- *   Event being triggered, with the following restrictions:
- *   - event.type: any
- *   - event.currentTarget: any
- */
-Drupal.overlay.eventhandlerDispatchEvent = function (event) {
-  if (this.iframeWindow && this.iframeWindow.document) {
-    this.iframeWindow.jQuery(this.iframeWindow.document).trigger(event);
-  }
-};
-
-/**
- * Make a regular admin link into a URL that will trigger the overlay to open.
- *
- * @param link
- *   A JavaScript Link object (i.e. an <a> element).
- * @param parentLocation
- *   (optional) URL to override the parent window's location with.
- *
- * @return
- *   A URL that will trigger the overlay (in the form
- *   /node/1#overlay=admin/config).
- */
-Drupal.overlay.fragmentizeLink = function (link, parentLocation) {
-  // Don't operate on links that are already overlay-ready.
-  var params = $.deparam.fragment(link.href);
-  if (params.overlay) {
-    return link.href;
-  }
-
-  // Determine the link's original destination. Set ignorePathFromQueryString to
-  // true to prevent transforming this link into a clean URL while clean URLs
-  // may be disabled.
-  var path = this.getPath(link, true);
-  // Preserve existing query and fragment parameters in the URL, except for
-  // "render=overlay" which is re-added in Drupal.overlay.eventhandlerOperateByURLFragment.
-  var destination = path + link.search.replace(/&?render=overlay/, '').replace(/\?$/, '') + link.hash;
-
-  // Assemble and return the overlay-ready link.
-  return $.param.fragment(parentLocation || window.location.href, { overlay: destination });
-};
-
-/**
- * Refresh any regions of the page that are displayed outside the overlay.
- *
- * @param data
- *   An array of objects with information on the page regions to be refreshed.
- *   For each object, the key is a CSS class identifying the region to be
- *   refreshed, and the value represents the section of the Drupal $page array
- *   corresponding to this region.
- */
-Drupal.overlay.refreshRegions = function (data) {
-  $.each(data, function () {
-    var region_info = this;
-    $.each(region_info, function (regionClass) {
-      var regionName = region_info[regionClass];
-      var regionSelector = '.' + regionClass;
-      // Allow special behaviors to detach.
-      Drupal.detachBehaviors($(regionSelector));
-      $.get(Drupal.settings.basePath + Drupal.settings.overlay.ajaxCallback + '/' + regionName, function (newElement) {
-        $(regionSelector).replaceWith($(newElement));
-        Drupal.attachBehaviors($(regionSelector), Drupal.settings);
-      });
-    });
-  });
-};
-
-/**
- * Reset the active class on links in displaced elements according to
- * given path.
- *
- * @param activePath
- *   Path to match links against.
- */
-Drupal.overlay.resetActiveClass = function(activePath) {
-  var self = this;
-  var windowDomain = window.location.protocol + window.location.hostname;
-
-  $('.overlay-displace-top, .overlay-displace-bottom')
-  .find('a[href]')
-  // Remove active class from all links in displaced elements.
-  .removeClass('active')
-  // Add active class to links that match activePath.
-  .each(function () {
-    var linkDomain = this.protocol + this.hostname;
-    var linkPath = self.getPath(this);
-
-    // A link matches if it is part of the active trail of activePath, except
-    // for frontpage links.
-    if (linkDomain == windowDomain && (activePath + '/').indexOf(linkPath + '/') === 0 && (linkPath !== '' || activePath === '')) {
-      $(this).addClass('active');
-    }
-  });
-};
-
-/**
- * Helper function to get the (corrected) Drupal path of a link.
- *
- * @param link
- *   Link object or string to get the Drupal path from.
- * @param ignorePathFromQueryString
- *   Boolean whether to ignore path from query string if path appears empty.
- *
- * @return
- *   The Drupal path.
- */
-Drupal.overlay.getPath = function (link, ignorePathFromQueryString) {
-  if (typeof link == 'string') {
-    // Create a native Link object, so we can use its object methods.
-    link = $(link.link(link)).get(0);
-  }
-
-  var path = link.pathname;
-  // Ensure a leading slash on the path, omitted in some browsers.
-  if (path.charAt(0) != '/') {
-    path = '/' + path;
-  }
-  path = path.replace(new RegExp(Drupal.settings.basePath + '(?:index.php)?'), '');
-  if (path == '' && !ignorePathFromQueryString) {
-    // If the path appears empty, it might mean the path is represented in the
-    // query string (clean URLs are not used).
-    var match = new RegExp('([?&])q=(.+)([&#]|$)').exec(link.search);
-    if (match && match.length == 4) {
-      path = match[2];
-    }
-  }
-
-  return path;
-};
-
-/**
- * Get the total displacement of given region.
- *
- * @param region
- *   Region name. Either "top" or "bottom".
- *
- * @return
- *   The total displacement of given region in pixels.
- */
-Drupal.overlay.getDisplacement = function (region) {
-  var displacement = 0;
-  var lastDisplaced = $('.overlay-displace-' + region + ':last');
-  if (lastDisplaced.length) {
-    displacement = lastDisplaced.offset().top + lastDisplaced.outerHeight();
-
-    // Remove height added by IE Shadow filter.
-    if (lastDisplaced[0].filters && lastDisplaced[0].filters.length && lastDisplaced[0].filters.item('DXImageTransform.Microsoft.Shadow')) {
-      displacement -= lastDisplaced[0].filters.item('DXImageTransform.Microsoft.Shadow').strength;
-      displacement = Math.max(0, displacement);
-    }
-  }
-  return displacement;
-};
-
-/**
- * Makes elements outside the overlay unreachable via the tab key.
- *
- * @param context
- *   The part of the DOM that should have its tabindexes changed. Defaults to
- *   the entire page.
- */
-Drupal.overlay.makeDocumentUntabbable = function (context) {
-  // Manipulating tabindexes for the entire document is unacceptably slow in IE6
-  // and IE7, so in those browsers, the underlying page will still be reachable
-  // via the tab key. However, we still make the links within the Disable
-  // message unreachable, because the same message also exists within the
-  // child document. The duplicate copy in the underlying document is only for
-  // assisting screen-reader users navigating the document with reading commands
-  // that follow markup order rather than tab order.
-  if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 8) {
-    $('#overlay-disable-message a', context).attr('tabindex', -1);
-    return;
-  }
-
-  context = context || document.body;
-  var $overlay, $tabbable, $hasTabindex;
-
-  // Determine which elements on the page already have a tabindex.
-  $hasTabindex = $('[tabindex] :not(.overlay-element)', context);
-  // Record the tabindex for each element, so we can restore it later.
-  $hasTabindex.each(Drupal.overlay._recordTabindex);
-  // Add the tabbable elements from the current context to any that we might
-  // have previously recorded.
-  Drupal.overlay._hasTabindex = $hasTabindex.add(Drupal.overlay._hasTabindex);
-
-  // Set tabindex to -1 on everything outside the overlay and toolbars, so that
-  // the underlying page is unreachable.
-
-  // By default, browsers make a, area, button, input, object, select, textarea,
-  // and iframe elements reachable via the tab key.
-  $tabbable = $('a, area, button, input, object, select, textarea, iframe');
-  // If another element (like a div) has a tabindex, it's also tabbable.
-  $tabbable = $tabbable.add($hasTabindex);
-  // Leave links inside the overlay and toolbars alone.
-  $overlay = $('.overlay-element, #overlay-container, .overlay-displace-top, .overlay-displace-bottom').find('*');
-  $tabbable = $tabbable.not($overlay);
-  // We now have a list of everything in the underlying document that could
-  // possibly be reachable via the tab key. Make it all unreachable.
-  $tabbable.attr('tabindex', -1);
-};
-
-/**
- * Restores the original tabindex value of a group of elements.
- *
- * @param context
- *   The part of the DOM that should have its tabindexes restored. Defaults to
- *   the entire page.
- */
-Drupal.overlay.makeDocumentTabbable = function (context) {
-  // Manipulating tabindexes is unacceptably slow in IE6 and IE7. In those
-  // browsers, the underlying page was never made unreachable via tab, so
-  // there is no work to be done here.
-  if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 8) {
-    return;
-  }
-
-  var $needsTabindex;
-  context = context || document.body;
-
-  // Make the underlying document tabbable again by removing all existing
-  // tabindex attributes.
-  var $tabindex = $('[tabindex]', context);
-  if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 8) {
-    // removeAttr('tabindex') is broken in IE6-7, but the DOM function
-    // removeAttribute works.
-    var i;
-    var length = $tabindex.length;
-    for (i = 0; i < length; i++) {
-      $tabindex[i].removeAttribute('tabIndex');
-    }
-  }
-  else {
-    $tabindex.removeAttr('tabindex');
-  }
-
-  // Restore the tabindex attributes that existed before the overlay was opened.
-  $needsTabindex = $(Drupal.overlay._hasTabindex, context);
-  $needsTabindex.each(Drupal.overlay._restoreTabindex);
-  Drupal.overlay._hasTabindex = Drupal.overlay._hasTabindex.not($needsTabindex);
-};
-
-/**
- * Record the tabindex for an element, using $.data.
- *
- * Meant to be used as a jQuery.fn.each callback.
- */
-Drupal.overlay._recordTabindex = function () {
-  var $element = $(this);
-  var tabindex = $(this).attr('tabindex');
-  $element.data('drupalOverlayOriginalTabIndex', tabindex);
-}
-
-/**
- * Restore an element's original tabindex.
- *
- * Meant to be used as a jQuery.fn.each callback.
- */
-Drupal.overlay._restoreTabindex = function () {
-  var $element = $(this);
-  var tabindex = $element.data('drupalOverlayOriginalTabIndex');
-  $element.attr('tabindex', tabindex);
-};
-
-/**
- * Theme function to create the overlay iframe element.
- */
-Drupal.theme.prototype.overlayContainer = function () {
-  return '<div id="overlay-container"><div class="overlay-modal-background"></div></div>';
-};
-
-/**
- * Theme function to create an overlay iframe element.
- */
-Drupal.theme.prototype.overlayElement = function (url) {
-  return '<iframe class="overlay-element" frameborder="0" scrolling="auto" allowtransparency="true"></iframe>';
-};
-
-})(jQuery);
diff --git a/modules/overlay/overlay.api.php b/modules/overlay/overlay.api.php
deleted file mode 100644
index c763d1f..0000000
--- a/modules/overlay/overlay.api.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Hooks provided by Overlay module.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Allow modules to act when an overlay parent window is initialized.
- *
- * The parent window is initialized when a page is displayed in which the
- * overlay might be required to be displayed, so modules can act here if they
- * need to take action to accomodate the possibility of the overlay appearing
- * within a Drupal page.
- */
-function hook_overlay_parent_initialize() {
-  // Add our custom JavaScript.
-  drupal_add_js(drupal_get_path('module', 'hook') . '/hook-overlay.js');
-}
-
-/**
- * Allow modules to act when an overlay child window is initialized.
- *
- * The child window is initialized when a page is displayed from within the
- * overlay, so modules can act here if they need to take action to work from
- * within the confines of the overlay.
- */
-function hook_overlay_child_initialize() {
-  // Add our custom JavaScript.
-  drupal_add_js(drupal_get_path('module', 'hook') . '/hook-overlay-child.js');
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/modules/overlay/overlay.info b/modules/overlay/overlay.info
deleted file mode 100644
index a782792..0000000
--- a/modules/overlay/overlay.info
+++ /dev/null
@@ -1,5 +0,0 @@
-name = Overlay
-description = Displays the Drupal administration interface in an overlay.
-package = Core
-version = VERSION
-core = 8.x
diff --git a/modules/overlay/overlay.install b/modules/overlay/overlay.install
deleted file mode 100644
index 2fa7c84..0000000
--- a/modules/overlay/overlay.install
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the overlay module.
- */
-
-/**
- * Implements hook_enable().
- *
- * If the module is being enabled through the admin UI, and not from an
- * install profile, reopen the modules page in an overlay.
- */
-function overlay_enable() {
-  if (strpos(current_path(), 'admin/modules') === 0) {
-    // Flag for a redirect to <front>#overlay=admin/modules on hook_init().
-    $_SESSION['overlay_enable_redirect'] = 1;
-  }
-}
diff --git a/modules/overlay/overlay.module b/modules/overlay/overlay.module
deleted file mode 100644
index 900e307..0000000
--- a/modules/overlay/overlay.module
+++ /dev/null
@@ -1,975 +0,0 @@
-<?php
-
-/**
- * @file
- * Displays the Drupal administration interface in an overlay.
- */
-
-/**
- * Implements hook_help().
- */
-function overlay_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#overlay':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Overlay module makes the administration pages on your site display in a JavaScript overlay of the page you were viewing when you clicked the administrative link, instead of replacing the page in your browser window. Use the close link on the overlay to return to the page you were viewing when you clicked the link. For more information, see the online handbook entry for <a href="@overlay">Overlay module</a>.', array('@overlay' => 'http://drupal.org/handbook/modules/overlay')) . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_menu().
- */
-function overlay_menu() {
-  $items['overlay-ajax/%'] = array(
-    'title' => '',
-    'page callback' => 'overlay_ajax_render_region',
-    'page arguments' => array(1),
-    'access arguments' => array('access overlay'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['overlay/dismiss-message'] = array(
-    'title' => '',
-    'page callback' => 'overlay_user_dismiss_message',
-    'access arguments' => array('access overlay'),
-    'type' => MENU_CALLBACK,
-  );
-  return $items;
-}
-
-/**
- * Implements hook_admin_paths().
- */
-function overlay_admin_paths() {
-  $paths = array(
-    // This is marked as an administrative path so that if it is visited from
-    // within the overlay, the user will stay within the overlay while the
-    // callback is being processed.
-    'overlay/dismiss-message' => TRUE,
-  );
-  return $paths;
-}
-
-/**
- * Implements hook_permission().
- */
-function overlay_permission() {
-  return array(
-    'access overlay' => array(
-      'title' => t('Access the administrative overlay'),
-      'description' => t('View administrative pages in the overlay.'),
-    ),
-  );
-}
-
-/**
- * Implements hook_theme().
- */
-function overlay_theme() {
-  return array(
-    'overlay' => array(
-      'render element' => 'page',
-      'template' => 'overlay',
-    ),
-    'overlay_disable_message' => array(
-      'render element' => 'element',
-    ),
-  );
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function overlay_form_user_profile_form_alter(&$form, &$form_state) {
-  if ($form['#user_category'] == 'account') {
-    $account = $form['#user'];
-    if (user_access('access overlay', $account)) {
-      $form['overlay_control'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Administrative overlay'),
-        '#weight' => 4,
-        '#collapsible' => TRUE,
-      );
-
-      $form['overlay_control']['overlay'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Use the overlay for administrative pages.'),
-        '#description' => t('Show administrative pages on top of the page you started from.'),
-        '#default_value' => isset($account->data['overlay']) ? $account->data['overlay'] : 1,
-      );
-    }
-  }
-}
-
-/**
- * Implements hook_user_presave().
- */
-function overlay_user_presave(&$edit, $account, $category) {
-  if (isset($edit['overlay'])) {
-    $edit['data']['overlay'] = $edit['overlay'];
-  }
-}
-
-/**
- * Implements hook_init().
- *
- * Determine whether the current page request is destined to appear in the
- * parent window or in the overlay window, and format the page accordingly.
- *
- * @see overlay_set_mode()
- */
-function overlay_init() {
-  global $user;
-
-  $mode = overlay_get_mode();
-
-  // Only act if the user has access to the overlay and a mode was not already
-  // set. Other modules can also enable the overlay directly for other uses.
-  $use_overlay = !isset($user->data['overlay']) || $user->data['overlay'];
-  if (empty($mode) && user_access('access overlay') && $use_overlay) {
-    $current_path = current_path();
-    // After overlay is enabled on the modules page, redirect to
-    // <front>#overlay=admin/modules to actually enable the overlay.
-    if (isset($_SESSION['overlay_enable_redirect']) && $_SESSION['overlay_enable_redirect']) {
-      unset($_SESSION['overlay_enable_redirect']);
-      drupal_goto('<front>', array('fragment' => 'overlay=' . $current_path));
-    }
-
-    if (isset($_GET['render']) && $_GET['render'] == 'overlay') {
-      // If a previous page requested that we close the overlay, close it and
-      // redirect to the final destination.
-      if (isset($_SESSION['overlay_close_dialog'])) {
-        call_user_func_array('overlay_close_dialog', $_SESSION['overlay_close_dialog']);
-        unset($_SESSION['overlay_close_dialog']);
-      }
-      // If this page shouldn't be rendered inside the overlay, redirect to the
-      // parent.
-      elseif (!path_is_admin($current_path)) {
-        overlay_close_dialog($current_path);
-      }
-
-      // Indicate that we are viewing an overlay child page.
-      overlay_set_mode('child');
-
-      // Unset the render parameter to avoid it being included in URLs on the page.
-      unset($_GET['render']);
-    }
-    // Do not enable the overlay if we already are on an admin page.
-    elseif (!path_is_admin($current_path)) {
-      // Otherwise add overlay parent code and our behavior.
-      overlay_set_mode('parent');
-    }
-  }
-}
-
-/**
- * Implements hook_exit().
- *
- * When viewing an overlay child page, check if we need to trigger a refresh of
- * the supplemental regions of the overlay on the next page request.
- */
-function overlay_exit() {
-  // Check that we are in an overlay child page. Note that this should never
-  // return TRUE on a cached page view, since the child mode is not set until
-  // overlay_init() is called.
-  if (overlay_get_mode() == 'child') {
-    // Load any markup that was stored earlier in the page request, via calls
-    // to overlay_store_rendered_content(). If none was stored, this is not a
-    // page request where we expect any changes to the overlay supplemental
-    // regions to have occurred, so we do not need to proceed any further.
-    $original_markup = overlay_get_rendered_content();
-    if (!empty($original_markup)) {
-      // Compare the original markup to the current markup that we get from
-      // rendering each overlay supplemental region now. If they don't match,
-      // something must have changed, so we request a refresh of that region
-      // within the parent window on the next page request.
-      foreach (overlay_supplemental_regions() as $region) {
-        if (!isset($original_markup[$region]) || $original_markup[$region] != overlay_render_region($region)) {
-          overlay_request_refresh($region);
-        }
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_library().
- */
-function overlay_library() {
-  $module_path = drupal_get_path('module', 'overlay');
-
-  // Overlay parent.
-  $libraries['parent'] = array(
-    'title' => 'Overlay: Parent',
-    'website' => 'http://drupal.org/handbook/modules/overlay',
-    'version' => '1.0',
-    'js' => array(
-      $module_path . '/overlay-parent.js' => array(),
-    ),
-    'css' => array(
-      $module_path . '/overlay-parent.css' => array(),
-    ),
-    'dependencies' => array(
-      array('system', 'ui'),
-      array('system', 'jquery.bbq'),
-    ),
-  );
-  // Overlay child.
-  $libraries['child'] = array(
-    'title' => 'Overlay: Child',
-    'website' => 'http://drupal.org/handbook/modules/overlay',
-    'version' => '1.0',
-    'js' => array(
-      $module_path . '/overlay-child.js' => array(),
-    ),
-    'css' => array(
-      $module_path . '/overlay-child.css' => array(),
-    ),
-  );
-
-  return $libraries;
-}
-
-/**
- * Implements hook_drupal_goto_alter().
- */
-function overlay_drupal_goto_alter(&$path, &$options, &$http_response_code) {
-  if (overlay_get_mode() == 'child') {
-    // The authorize.php script bootstraps Drupal to a very low level, where
-    // the PHP code that is necessary to close the overlay properly will not be
-    // loaded. Therefore, if we are redirecting to authorize.php inside the
-    // overlay, instead redirect back to the current page with instructions to
-    // close the overlay there before redirecting to the final destination; see
-    // overlay_init().
-    if ($path == system_authorized_get_url() || $path == system_authorized_batch_processing_url()) {
-      $_SESSION['overlay_close_dialog'] = array($path, $options);
-      $path = current_path();
-      $options = drupal_get_query_parameters();
-    }
-
-    // If the current page request is inside the overlay, add ?render=overlay
-    // to the new path, so that it appears correctly inside the overlay.
-    if (isset($options['query'])) {
-      $options['query'] += array('render' => 'overlay');
-    }
-    else {
-      $options['query'] = array('render' => 'overlay');
-    }
-  }
-}
-
-/**
- * Implements hook_batch_alter().
- *
- * If the current page request is inside the overlay, add ?render=overlay to
- * the success callback URL, so that it appears correctly within the overlay.
- *
- * @see overlay_get_mode()
- */
-function overlay_batch_alter(&$batch) {
-  if (overlay_get_mode() == 'child') {
-    if (isset($batch['url_options']['query'])) {
-      $batch['url_options']['query']['render'] = 'overlay';
-    }
-    else {
-      $batch['url_options']['query'] = array('render' => 'overlay');
-    }
-  }
-}
-
-/**
- * Implements hook_page_alter().
- */
-function overlay_page_alter(&$page) {
-  // If we are limiting rendering to a subset of page regions, deny access to
-  // all other regions so that they will not be processed.
-  if ($regions_to_render = overlay_get_regions_to_render()) {
-    $skipped_regions = array_diff(element_children($page), $regions_to_render);
-    foreach ($skipped_regions as $skipped_region) {
-      $page[$skipped_region]['#access'] = FALSE;
-    }
-  }
-
-  $mode = overlay_get_mode();
-  if ($mode == 'child') {
-    // Add the overlay wrapper before the html wrapper.
-    array_unshift($page['#theme_wrappers'], 'overlay');
-  }
-  elseif ($mode == 'parent' && ($message = overlay_disable_message())) {
-    $page['page_top']['disable_overlay'] = $message;
-  }
-}
-
-/**
- * Menu callback; dismisses the overlay accessibility message for this user.
- */
-function overlay_user_dismiss_message() {
-  global $user;
-  // It's unlikely, but possible that "access overlay" permission is granted to
-  // the anonymous role. In this case, we do not display the message to disable
-  // the overlay, so there is nothing to dismiss. Also, protect against
-  // cross-site request forgeries by validating a token.
-  if (empty($user->uid) || !isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'overlay')) {
-    return MENU_ACCESS_DENIED;
-  }
-  else {
-    user_save(user_load($user->uid), array('data' => array('overlay_message_dismissed' => 1)));
-    drupal_set_message(t('The message has been dismissed. You can change your overlay settings at any time by visiting your profile page.'));
-    // Destination is normally given. Go to the user profile as a fallback.
-    drupal_goto('user/' . $user->uid . '/edit');
-  }
-}
-
-/**
- * Returns a renderable array representing a message for disabling the overlay.
- *
- * If the current user can access the overlay and has not previously indicated
- * that this message should be dismissed, this function returns a message
- * containing a link to disable the overlay. Nothing is returned for anonymous
- * users, because the links control per-user settings. Therefore, because some
- * screen readers are unable to properly read overlay contents, site builders
- * are discouraged from granting the "access overlay" permission to the
- * anonymous role. See http://drupal.org/node/890284.
- */
-function overlay_disable_message() {
-  global $user;
-
-  if (!empty($user->uid) && empty($user->data['overlay_message_dismissed']) && (!isset($user->data['overlay']) || $user->data['overlay']) && user_access('access overlay')) {
-    $build = array(
-      '#theme' => 'overlay_disable_message',
-      '#weight' => -99,
-      // Link to the user's profile page, where the overlay can be disabled.
-      'profile_link' => array(
-        '#type' => 'link',
-        '#title' => t('If you have problems accessing administrative pages on this site, disable the overlay on your profile page.'),
-        '#href' => 'user/' . $user->uid . '/edit',
-        '#options' => array(
-          'query' => drupal_get_destination(),
-          'fragment' => 'edit-overlay-control',
-          'attributes' => array(
-            'id' => 'overlay-profile-link',
-            // Prevent the target page from being opened in the overlay.
-            'class' => array('overlay-exclude'),
-          ),
-        ),
-      ),
-      // Link to a menu callback that allows this message to be permanently
-      // dismissed for the current user.
-      'dismiss_message_link' => array(
-        '#type' => 'link',
-        '#title' => t('Dismiss this message.'),
-        '#href' => 'overlay/dismiss-message',
-        '#options' => array(
-          'query' => drupal_get_destination() + array(
-            // Add a token to protect against cross-site request forgeries.
-            'token' => drupal_get_token('overlay'),
-          ),
-          'attributes' => array(
-            'id' => 'overlay-dismiss-message',
-            // If this message is being displayed outside the overlay, prevent
-            // this link from opening the overlay.
-            'class' => (overlay_get_mode() == 'parent') ? array('overlay-exclude') : array(),
-          ),
-        ),
-      )
-    );
-  }
-  else {
-    $build = array();
-  }
-
-  return $build;
-}
-
-/**
- * Returns the HTML for the message about how to disable the overlay.
- *
- * @see overlay_disable_message()
- */
-function theme_overlay_disable_message($variables) {
-  $element = $variables['element'];
-
-  // Add CSS classes to hide the links from most sighted users, while keeping
-  // them accessible to screen-reader users and keyboard-only users. To assist
-  // screen-reader users, this message appears in both the parent and child
-  // documents, but only the one in the child document is part of the tab order.
-  foreach (array('profile_link', 'dismiss_message_link') as $key) {
-    $element[$key]['#options']['attributes']['class'][] = 'element-invisible';
-    if (overlay_get_mode() == 'child') {
-      $element[$key]['#options']['attributes']['class'][] = 'element-focusable';
-    }
-  }
-
-  // Render the links.
-  $output = drupal_render($element['profile_link']) . ' ' . drupal_render($element['dismiss_message_link']);
-
-  // Add a heading for screen-reader users. The heading doesn't need to be seen
-  // by sighted users.
-  $output = '<h3 class="element-invisible">' . t('Options for the administrative overlay') . '</h3>' . $output;
-
-  // Wrap in a container for styling.
-  $output = '<div id="overlay-disable-message" class="clearfix">' . $output . '</div>';
-
-  return $output;
-}
-
-/**
- * Implements hook_block_list_alter().
- */
-function overlay_block_list_alter(&$blocks) {
-  // If we are limiting rendering to a subset of page regions, hide all blocks
-  // which appear in regions not on that list. Note that overlay_page_alter()
-  // does a more comprehensive job of preventing unwanted regions from being
-  // displayed (regardless of whether they contain blocks or not), but the
-  // reason for duplicating effort here is performance; we do not even want
-  // these blocks to be built if they are not going to be displayed.
-  if ($regions_to_render = overlay_get_regions_to_render()) {
-    foreach ($blocks as $bid => $block) {
-      if (!in_array($block->region, $regions_to_render)) {
-        unset($blocks[$bid]);
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_system_info_alter().
- *
- * Add default regions for the overlay.
- */
-function overlay_system_info_alter(&$info, $file, $type) {
-  if ($type == 'theme') {
-    $info['overlay_regions'][] = 'content';
-    $info['overlay_regions'][] = 'help';
-  }
-}
-
-/**
- * Implements hook_preprocess_html().
- *
- * If the current page request is inside the overlay, add appropriate classes
- * to the <body> element, and simplify the page title.
- *
- * @see overlay_get_mode()
- */
-function overlay_preprocess_html(&$variables) {
-  if (overlay_get_mode() == 'child') {
-    // Add overlay class, so themes can react to being displayed in the overlay.
-    $variables['classes_array'][] = 'overlay';
-  }
-}
-
-/**
- * Implements hook_preprocess_maintenance_page().
- *
- * If the current page request is inside the overlay, add appropriate classes
- * to the <body> element, and simplify the page title.
- *
- * @see overlay_preprocess_maintenance_page()
- */
-function overlay_preprocess_maintenance_page(&$variables) {
-  overlay_preprocess_html($variables);
-}
-
-/**
- * Preprocesses template variables for overlay.tpl.php
- *
- * @see overlay.tpl.php
- */
-function template_preprocess_overlay(&$variables) {
-  $variables['tabs'] = menu_primary_local_tasks();
-  $variables['title'] = drupal_get_title();
-  $variables['disable_overlay'] = overlay_disable_message();
-  $variables['content_attributes_array']['class'][] = 'clearfix';
-}
-
-/**
- * Processes variables for overlay.tpl.php
- *
- * @see template_preprocess_overlay()
- * @see overlay.tpl.php
- */
-function template_process_overlay(&$variables) {
-  // Place the rendered HTML for the page body into a top level variable.
-  $variables['page'] = $variables['page']['#children'];
-}
-
-/**
- * Implements hook_preprocess_page().
- *
- * Hide tabs inside the overlay.
- *
- * @see overlay_get_mode()
- */
-function overlay_preprocess_page(&$variables) {
-  if (overlay_get_mode() == 'child') {
-    unset($variables['tabs']['#primary']);
-  }
-}
-
-/**
- * Callback to request that the overlay display an empty page.
- *
- * This is used to prevent a page request which closes the overlay (for
- * example, a form submission) from being fully re-rendered before the overlay
- * is closed. Instead, we store a variable which will cause the page to be
- * rendered by a delivery callback function that does not actually print
- * visible HTML (but rather only the bare minimum scripts and styles necessary
- * to trigger the overlay to close), thereby allowing the dialog to be closed
- * faster and with less interruption, and also allowing the display of messages
- * to be deferred to the parent window (rather than displaying them in the
- * child window, which will close before the user has had a chance to read
- * them).
- *
- * @param $value
- *   By default, an empty page will not be displayed. Set to TRUE to request
- *   an empty page display, or FALSE to disable the empty page display (if it
- *   was previously enabled on this page request).
- *
- * @return
- *   TRUE if the current behavior is to display an empty page, or FALSE if not.
- *
- * @see overlay_page_delivery_callback_alter()
- */
-function overlay_display_empty_page($value = NULL) {
-  $display_empty_page = &drupal_static(__FUNCTION__, FALSE);
-  if (isset($value)) {
-    $display_empty_page = $value;
-  }
-  return $display_empty_page;
-}
-
-/**
- * Implements hook_page_delivery_callback_alter().
- */
-function overlay_page_delivery_callback_alter(&$callback) {
-  if (overlay_display_empty_page()) {
-    $callback = 'overlay_deliver_empty_page';
-  }
-}
-
-/**
- * Delivery callback to display an empty page.
- *
- * This function is used to print out a bare minimum empty page which still has
- * the scripts and styles necessary in order to trigger the overlay to close.
- */
-function overlay_deliver_empty_page() {
-  $empty_page = '<html><head><title></title>' . drupal_get_css() . drupal_get_js() . '</head><body class="overlay"></body></html>';
-  print $empty_page;
-  drupal_exit();
-}
-
-/**
- * Get the current overlay mode.
- *
- * @see overlay_set_mode()
- */
-function overlay_get_mode() {
-  return overlay_set_mode(NULL);
-}
-
-/**
- * Sets the overlay mode and adds proper JavaScript and styles to the page.
- *
- * Note that since setting the overlay mode triggers a variety of behaviors
- * (including hooks being invoked), it can only be done once per page request.
- * Therefore, the first call to this function which passes along a value of the
- * $mode parameter controls the overlay mode that will be used.
- *
- * @param $mode
- *   To set the mode, pass in one of the following values:
- *   - 'parent': This is used in the context of a parent window (a regular
- *     browser window). If set, JavaScript is added so that administrative
- *     links in the parent window will open in an overlay.
- *   - 'child': This is used in the context of the child overlay window (the
- *     page actually appearing within the overlay iframe). If set, JavaScript
- *     and CSS are added so that Drupal behaves nicely from within the overlay.
- *   - 'none': This is used to avoid adding any overlay-related code to the
- *     page at all. Modules can set this to explicitly prevent the overlay from
- *     being used. For example, since the overlay module itself sets the mode
- *     to 'parent' or 'child' in overlay_init() when certain conditions are
- *     met, other modules which want to override that behavior can do so by
- *     setting the mode to 'none' earlier in the page request - e.g., in their
- *     own hook_init() implementations, if they have a lower weight.
- *   This parameter is optional, and if omitted, the current mode will be
- *   returned with no action taken.
- *
- * @return
- *   The current mode, if any has been set, or NULL if no mode has been set.
- *
- * @ingroup overlay_api
- * @see overlay_init()
- */
-function overlay_set_mode($mode = NULL) {
-  global $base_path;
-  $overlay_mode = &drupal_static(__FUNCTION__);
-
-  // Make sure external resources are not included more than once. Also return
-  // the current mode, if no mode was specified.
-  if (isset($overlay_mode) || !isset($mode)) {
-    return $overlay_mode;
-  }
-  $overlay_mode = $mode;
-
-  switch ($overlay_mode) {
-    case 'parent':
-      drupal_add_library('overlay', 'parent');
-
-      // Allow modules to act upon overlay events.
-      module_invoke_all('overlay_parent_initialize');
-      break;
-
-    case 'child':
-      drupal_add_library('overlay', 'child');
-
-      // Allow modules to act upon overlay events.
-      module_invoke_all('overlay_child_initialize');
-      break;
-  }
-  return $overlay_mode;
-}
-
-/**
- * Implements hook_overlay_parent_initialize().
- */
-function overlay_overlay_parent_initialize() {
-  // Let the client side know which paths are administrative.
-  $paths = path_get_admin_paths();
-  foreach ($paths as &$type) {
-    $type = str_replace('<front>', variable_get('site_frontpage', 'user'), $type);
-  }
-  drupal_add_js(array('overlay' => array('paths' => $paths)), 'setting');
-  // Pass along the Ajax callback for rerendering sections of the parent window.
-  drupal_add_js(array('overlay' => array('ajaxCallback' => 'overlay-ajax')), 'setting');
-}
-
-/**
- * Implements hook_overlay_child_initialize().
- */
-function overlay_overlay_child_initialize() {
-  // Check if the parent window needs to refresh any page regions on this page
-  // request.
-  overlay_trigger_refresh();
-  // If this is a POST request, or a GET request with a token parameter, we
-  // have an indication that something in the supplemental regions of the
-  // overlay might change during the current page request. We therefore store
-  // the initial rendered content of those regions here, so that we can compare
-  // it to the same content rendered in overlay_exit(), at the end of the page
-  // request. This allows us to check if anything actually did change, and, if
-  // so, trigger an immediate Ajax refresh of the parent window.
-  if (!empty($_POST) || isset($_GET['token'])) {
-    foreach (overlay_supplemental_regions() as $region) {
-      overlay_store_rendered_content($region, overlay_render_region($region));
-    }
-    // In addition, notify the parent window that when the overlay closes,
-    // the entire parent window should be refreshed.
-    overlay_request_page_refresh();
-  }
-  // Indicate that when the main page rendering occurs later in the page
-  // request, only the regions that appear within the overlay should be
-  // rendered.
-  overlay_set_regions_to_render(overlay_regions());
-}
-
-/**
- * Callback to request that the overlay close as soon as the page is displayed.
- *
- * @param $redirect
- *   (optional) The path that should open in the parent window after the
- *   overlay closes. If not set, no redirect will be performed on the parent
- *   window.
- * @param $redirect_options
- *   (optional) An associative array of options to use when generating the
- *   redirect URL.
- */
-function overlay_close_dialog($redirect = NULL, $redirect_options = array()) {
-  $settings = array(
-    'overlayChild' => array(
-      'closeOverlay' => TRUE,
-    ),
-  );
-
-  // Tell the child window to perform the redirection when requested to.
-  if (isset($redirect)) {
-    $settings['overlayChild']['redirect'] = url($redirect, $redirect_options);
-  }
-
-  drupal_add_js($settings, array('type' => 'setting'));
-
-  // Since we are closing the overlay as soon as the page is displayed, we do
-  // not want to show any of the page's actual content.
-  overlay_display_empty_page(TRUE);
-}
-
-/**
- * Returns a list of page regions that appear in the overlay.
- *
- * Overlay regions correspond to the entire contents of the overlay child
- * window and are refreshed each time a new page request is made within the
- * overlay.
- *
- * @return
- *   An array of region names that correspond to those which appear in the
- *   overlay, within the theme that is being used to display the current page.
- *
- * @see overlay_supplemental_regions()
- */
-function overlay_regions() {
-  return _overlay_region_list('overlay_regions');
-}
-
-/**
- * Returns a list of supplemental page regions for the overlay.
- *
- * Supplemental overlay regions are those which are technically part of the
- * parent window, but appear to the user as being related to the overlay
- * (usually because they are displayed next to, rather than underneath, the
- * main overlay regions) and therefore need to be dynamically refreshed if any
- * administrative actions taken within the overlay change their contents.
- *
- * An example of a typical overlay supplemental region would be the 'page_top'
- * region, in the case where a toolbar is being displayed there.
- *
- * @return
- *   An array of region names that correspond to supplemental overlay regions,
- *   within the theme that is being used to display the current page.
- *
- * @see overlay_regions()
- */
-function overlay_supplemental_regions() {
-  return _overlay_region_list('overlay_supplemental_regions');
-}
-
-/**
- * Helper function for returning a list of page regions related to the overlay.
- *
- * @param $type
- *   The type of regions to return. This can either be 'overlay_regions' or
- *   'overlay_supplemental_regions'.
- *
- * @return
- *   An array of region names of the given type, within the theme that is being
- *   used to display the current page.
- *
- * @see overlay_regions()
- * @see overlay_supplemental_regions()
- */
-function _overlay_region_list($type) {
-  // Obtain the current theme. We need to first make sure the theme system is
-  // initialized, since this function can be called early in the page request.
-  drupal_theme_initialize();
-  $themes = list_themes();
-  $theme = $themes[$GLOBALS['theme']];
-  // Return the list of regions stored within the theme's info array, or an
-  // empty array if no regions of the appropriate type are defined.
-  return !empty($theme->info[$type]) ? $theme->info[$type] : array();
-}
-
-/**
- * Returns a list of page regions that rendering should be limited to.
- *
- * @return
- *   An array containing the names of the regions that will be rendered when
- *   drupal_render_page() is called. If empty, then no limits will be imposed,
- *   and all regions of the page will be rendered.
- *
- * @see overlay_page_alter()
- * @see overlay_block_list_alter()
- * @see overlay_set_regions_to_render()
- */
-function overlay_get_regions_to_render() {
-  return overlay_set_regions_to_render();
-}
-
-/**
- * Sets the regions of the page that rendering will be limited to.
- *
- * @param $regions
- *   (Optional) An array containing the names of the regions that should be
- *   rendered when drupal_render_page() is called. Pass in an empty array to
- *   remove all limits and cause drupal_render_page() to render all page
- *   regions (the default behavior). If this parameter is omitted, no change
- *   will be made to the current list of regions to render.
- *
- * @return
- *   The current list of regions to render, or an empty array if the regions
- *   are not being limited.
- *
- * @see overlay_page_alter()
- * @see overlay_block_list_alter()
- * @see overlay_get_regions_to_render()
- */
-function overlay_set_regions_to_render($regions = NULL) {
-  $regions_to_render = &drupal_static(__FUNCTION__, array());
-  if (isset($regions)) {
-    $regions_to_render = $regions;
-  }
-  return $regions_to_render;
-}
-
-/**
- * Renders an individual page region.
- *
- * This function is primarily intended to be used for checking the content of
- * supplemental overlay regions (e.g., a region containing a toolbar). Passing
- * in a region that is intended to display the main page content is not
- * supported; the region will be rendered by this function, but the main page
- * content will not appear in it. In addition, although this function returns
- * the rendered HTML for the provided region, it does not place it on the final
- * page, nor add any of its associated JavaScript or CSS to the page.
- *
- * @param $region
- *   The name of the page region that should be rendered.
- *
- * @return
- *   The rendered HTML of the provided region.
- */
-function overlay_render_region($region) {
-  // Indicate the region that we will be rendering, so that other regions will
-  // be hidden by overlay_page_alter() and overlay_block_list_alter().
-  overlay_set_regions_to_render(array($region));
-  // Do what is necessary to force drupal_render_page() to only display HTML
-  // from the requested region. Specifically, declare that the main page
-  // content does not need to automatically be added to the page, and pass in
-  // a page array that has all theme functions removed (so that overall HTML
-  // for the page will not be added either).
-  $system_main_content_added = &drupal_static('system_main_content_added');
-  $system_main_content_added = TRUE;
-  $page = array(
-    '#type' => 'page',
-    '#theme' => NULL,
-    '#theme_wrappers' => array(),
-  );
-  // Render the region, but do not cache any JavaScript or CSS associated with
-  // it. This region might not be included the next time drupal_render_page()
-  // is called, and we do not want its JavaScript or CSS to erroneously appear
-  // on the final rendered page.
-  $original_js = drupal_add_js();
-  $original_css = drupal_add_css();
-  $original_libraries = drupal_static('drupal_add_library');
-  $js = &drupal_static('drupal_add_js');
-  $css = &drupal_static('drupal_add_css');
-  $libraries = &drupal_static('drupal_add_library');
-  $markup = drupal_render_page($page);
-  $js = $original_js;
-  $css = $original_css;
-  $libraries = $original_libraries;
-  // Indicate that the main page content has not, in fact, been displayed, so
-  // that future calls to drupal_render_page() will be able to render it
-  // correctly.
-  $system_main_content_added = FALSE;
-  // Restore the original behavior of rendering all regions for the next time
-  // drupal_render_page() is called.
-  overlay_set_regions_to_render(array());
-  return $markup;
-}
-
-/**
- * Returns any rendered content that was stored earlier in the page request.
- *
- * @return
- *   An array of all rendered HTML that was stored earlier in the page request,
- *   keyed by the identifier with which it was stored. If no content was
- *   stored, an empty array is returned.
- *
- * @see overlay_store_rendered_content()
- */
-function overlay_get_rendered_content() {
-  return overlay_store_rendered_content();
-}
-
-/**
- * Stores strings representing rendered HTML content.
- *
- * This function is used to keep a static cache of rendered content that can be
- * referred to later in the page request.
- *
- * @param $id
- *   (Optional) An identifier for the content which is being stored, which will
- *   be used as an array key in the returned array. If omitted, no change will
- *   be made to the current stored data.
- * @param $content
- *   (Optional) A string representing the rendered data to store. This only has
- *   an effect if $id is also provided.
- *
- * @return
- *   An array representing all data that is currently being stored, or an empty
- *   array if there is none.
- *
- * @see overlay_get_rendered_content()
- */
-function overlay_store_rendered_content($id = NULL, $content = NULL) {
-  $rendered_content = &drupal_static(__FUNCTION__, array());
-  if (isset($id)) {
-    $rendered_content[$id] = $content;
-  }
-  return $rendered_content;
-}
-
-/**
- * Request that the parent window refresh a particular page region.
- *
- * @param $region
- *   The name of the page region to refresh. The parent window will trigger a
- *   refresh of this region on the next page load.
- *
- * @see overlay_trigger_refresh()
- * @see Drupal.overlay.refreshRegions()
- */
-function overlay_request_refresh($region) {
-  $class = drupal_region_class($region);
-  $_SESSION['overlay_regions_to_refresh'][] = array($class => $region);
-}
-
-/**
- * Request that the entire parent window be reloaded when the overlay closes.
- *
- * @see overlay_trigger_refresh()
- */
-function overlay_request_page_refresh() {
-  $_SESSION['overlay_refresh_parent'] = TRUE;
-}
-
-/**
- * Check if the parent window needs to be refreshed on this page load.
- *
- * If the previous page load requested that any page regions be refreshed, or
- * if it requested that the entire page be refreshed when the overlay closes,
- * pass that request via JavaScript to the child window, so it can in turn pass
- * the request to the parent window.
- *
- * @see overlay_request_refresh()
- * @see overlay_request_page_refresh()
- * @see Drupal.overlay.refreshRegions()
- */
-function overlay_trigger_refresh() {
-  if (!empty($_SESSION['overlay_regions_to_refresh'])) {
-    $settings = array(
-      'overlayChild' => array(
-        'refreshRegions' => $_SESSION['overlay_regions_to_refresh'],
-      ),
-    );
-    drupal_add_js($settings, array('type' => 'setting'));
-    unset($_SESSION['overlay_regions_to_refresh']);
-  }
-  if (!empty($_SESSION['overlay_refresh_parent'])) {
-    drupal_add_js(array('overlayChild' => array('refreshPage' => TRUE)), array('type' => 'setting'));
-    unset($_SESSION['overlay_refresh_parent']);
-  }
-}
-
-/**
- * Prints the markup obtained by rendering a single region of the page.
- *
- * This function is intended to be called via Ajax.
- *
- * @param $region
- *   The name of the page region to render.
- *
- * @see Drupal.overlay.refreshRegions()
- */
-function overlay_ajax_render_region($region) {
-  print overlay_render_region($region);
-}
diff --git a/modules/overlay/overlay.tpl.php b/modules/overlay/overlay.tpl.php
deleted file mode 100644
index 54b10af..0000000
--- a/modules/overlay/overlay.tpl.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display a page in the overlay.
- *
- * Available variables:
- * - $title: the (sanitized) title of the page.
- * - $page: The rendered page content.
- * - $tabs (array): Tabs linking to any sub-pages beneath the current page
- *   (e.g., the view and edit tabs when displaying a node).
- *
- * Helper variables:
- * - $classes_array: Array of html class attribute values. It is flattened
- *   into a string within the variable $classes.
- *
- * @see template_preprocess()
- * @see template_preprocess_overlay()
- * @see template_process()
- */
-?>
-
-<?php print render($disable_overlay); ?>
-<div id="overlay" <?php print $attributes; ?>>
-  <div id="overlay-titlebar" class="clearfix">
-    <div id="overlay-title-wrapper" class="clearfix">
-      <h1 id="overlay-title"<?php print $title_attributes; ?>><?php print $title; ?></h1>
-    </div>
-    <div id="overlay-close-wrapper">
-      <a id="overlay-close" href="#" class="overlay-close"><span class="element-invisible"><?php print t('Close overlay'); ?></span></a>
-    </div>
-    <?php if ($tabs): ?><h2 class="element-invisible"><?php print t('Primary tabs'); ?></h2><ul id="overlay-tabs"><?php print render($tabs); ?></ul><?php endif; ?>
-  </div>
-  <div id="overlay-content"<?php print $content_attributes; ?>>
-    <?php print $page; ?>
-  </div>
-</div>
diff --git a/modules/poll/poll-bar--block.tpl.php b/modules/poll/poll-bar--block.tpl.php
deleted file mode 100644
index 3b91afc..0000000
--- a/modules/poll/poll-bar--block.tpl.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display the bar for a single choice in a
- * poll.
- *
- * Variables available:
- * - $title: The title of the poll.
- * - $votes: The number of votes for this choice
- * - $total_votes: The number of votes for this choice
- * - $percentage: The percentage of votes for this choice.
- * - $vote: The choice number of the current user's vote.
- * - $voted: Set to TRUE if the user voted for this choice.
- *
- * @see template_preprocess_poll_bar()
- */
-?>
-
-<div class="text"><?php print $title; ?></div>
-<div class="bar">
-  <div style="width: <?php print $percentage; ?>%;" class="foreground"></div>
-</div>
-<div class="percent">
-  <?php print $percentage; ?>%
-</div>
diff --git a/modules/poll/poll-bar.tpl.php b/modules/poll/poll-bar.tpl.php
deleted file mode 100644
index 9426ff5..0000000
--- a/modules/poll/poll-bar.tpl.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display the bar for a single choice in a
- * poll.
- *
- * Variables available:
- * - $title: The title of the poll.
- * - $votes: The number of votes for this choice
- * - $total_votes: The number of votes for this choice
- * - $percentage: The percentage of votes for this choice.
- * - $vote: The choice number of the current user's vote.
- * - $voted: Set to TRUE if the user voted for this choice.
- *
- * @see template_preprocess_poll_bar()
- */
-?>
-
-<div class="text"><?php print $title; ?></div>
-<div class="bar">
-  <div style="width: <?php print $percentage; ?>%;" class="foreground"></div>
-</div>
-<div class="percent">
-  <?php print $percentage; ?>% (<?php print format_plural($votes, '1 vote', '@count votes'); ?>)
-</div>
diff --git a/modules/poll/poll-results--block.tpl.php b/modules/poll/poll-results--block.tpl.php
deleted file mode 100644
index f8387f5..0000000
--- a/modules/poll/poll-results--block.tpl.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- * @file
- * Default theme implementation to display the poll results in a block.
- *
- * Variables available:
- * - $title: The title of the poll.
- * - $results: The results of the poll.
- * - $votes: The total results in the poll.
- * - $links: Links in the poll.
- * - $nid: The nid of the poll
- * - $cancel_form: A form to cancel the user's vote, if allowed.
- * - $raw_links: The raw array of links. Should be run through theme('links')
- *   if used.
- * - $vote: The choice number of the current user's vote.
- *
- * @see template_preprocess_poll_results()
- */
-?>
-
-<div class="poll">
-  <div class="title"><?php print $title ?></div>
-  <?php print $results ?>
-  <div class="total">
-    <?php print t('Total votes: @votes', array('@votes' => $votes)); ?>
-  </div>
-</div>
-<div class="links"><?php print $links; ?></div>
diff --git a/modules/poll/poll-results.tpl.php b/modules/poll/poll-results.tpl.php
deleted file mode 100644
index 5e14dec..0000000
--- a/modules/poll/poll-results.tpl.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display the poll results in a block.
- *
- * Variables available:
- * - $title: The title of the poll.
- * - $results: The results of the poll.
- * - $votes: The total results in the poll.
- * - $links: Links in the poll.
- * - $nid: The nid of the poll
- * - $cancel_form: A form to cancel the user's vote, if allowed.
- * - $raw_links: The raw array of links.
- * - $vote: The choice number of the current user's vote.
- *
- * @see template_preprocess_poll_results()
- */
-?>
-<div class="poll">
-  <?php print $results; ?>
-  <div class="total">
-    <?php print t('Total votes: @votes', array('@votes' => $votes)); ?>
-  </div>
-  <?php if (!empty($cancel_form)): ?>
-    <?php print $cancel_form; ?>
-  <?php endif; ?>
-</div>
diff --git a/modules/poll/poll-rtl.css b/modules/poll/poll-rtl.css
deleted file mode 100644
index 14d42e6..0000000
--- a/modules/poll/poll-rtl.css
+++ /dev/null
@@ -1,10 +0,0 @@
-
-.poll .bar .foreground {
-  float: right;
-}
-.poll .percent {
-  text-align: left;
-}
-.poll .vote-form .choices {
-  text-align: right;
-}
diff --git a/modules/poll/poll-vote.tpl.php b/modules/poll/poll-vote.tpl.php
deleted file mode 100644
index 068ff7c..0000000
--- a/modules/poll/poll-vote.tpl.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation to display voting form for a poll.
- *
- * - $choice: The radio buttons for the choices in the poll.
- * - $title: The title of the poll.
- * - $block: True if this is being displayed as a block.
- * - $vote: The vote button
- * - $rest: Anything else in the form that may have been added via
- *   form_alter hooks.
- *
- * @see template_preprocess_poll_vote()
- */
-?>
-<div class="poll">
-  <div class="vote-form">
-    <div class="choices">
-      <?php if ($block): ?>
-        <div class="title"><?php print $title; ?></div>
-      <?php endif; ?>
-      <?php print $choice; ?>
-    </div>
-    <?php print $vote; ?>
-  </div>
-  <?php // This is the 'rest' of the form, in case items have been added. ?>
-  <?php print $rest ?>
-</div>
diff --git a/modules/poll/poll.css b/modules/poll/poll.css
deleted file mode 100644
index 8b04e38..0000000
--- a/modules/poll/poll.css
+++ /dev/null
@@ -1,51 +0,0 @@
-
-.poll {
-  overflow: hidden;
-}
-.poll .bar {
-  height: 1em;
-  margin: 1px 0;
-  background-color: #ddd;
-}
-.poll .bar .foreground {
-  background-color: #000;
-  height: 1em;
-  float: left; /* LTR */
-}
-.poll .links {
-  text-align: center;
-}
-.poll .percent {
-  text-align: right; /* LTR */
-}
-.poll .total {
-  text-align: center;
-}
-.poll .vote-form {
-  text-align: center;
-}
-.poll .vote-form .choices {
-  text-align: left; /* LTR */
-  margin: 0 auto;
-  display: table;
-}
-.poll .vote-form .choices .title {
-  font-weight: bold;
-}
-.node-form #edit-poll-more {
-  margin: 0;
-}
-.node-form #poll-choice-table .form-text {
-  display: inline;
-  width: auto;
-}
-.node-form #poll-choice-table td.choice-flag {
-  white-space: nowrap;
-  width: 4em;
-}
-td.poll-chtext {
-  width: 80%;
-}
-td.poll-chvotes .form-text {
-  width: 85%;
-}
diff --git a/modules/poll/poll.info b/modules/poll/poll.info
deleted file mode 100644
index dbdd621..0000000
--- a/modules/poll/poll.info
+++ /dev/null
@@ -1,8 +0,0 @@
-name = Poll
-description = Allows your site to capture votes on different topics in the form of multiple choice questions.
-package = Core
-version = VERSION
-core = 8.x
-dependencies[] = node
-files[] = poll.test
-stylesheets[all][] = poll.css
diff --git a/modules/poll/poll.install b/modules/poll/poll.install
deleted file mode 100644
index c848445..0000000
--- a/modules/poll/poll.install
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the poll module.
- */
-
-/**
- * Implements hook_schema().
- */
-function poll_schema() {
-  $schema['poll'] = array(
-    'description' => 'Stores poll-specific information for poll nodes.',
-    'fields' => array(
-      'nid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => "The poll's {node}.nid.",
-      ),
-      'runtime' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The number of seconds past {node}.created during which the poll is open.',
-      ),
-      'active' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Boolean indicating whether or not the poll is open.',
-      ),
-    ),
-    'primary key' => array('nid'),
-    'foreign keys' => array(
-      'poll_node' => array(
-        'table' => 'node',
-        'columns' => array('nid' => 'nid'),
-      ),
-    ),
-  );
-
-  $schema['poll_choice'] = array(
-    'description' => 'Stores information about all choices for all {poll}s.',
-    'fields' => array(
-      'chid' => array(
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'description' => 'Unique identifier for a poll choice.',
-      ),
-      'nid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {node}.nid this choice belongs to.',
-      ),
-      'chtext' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The text for this choice.',
-        'translatable' => TRUE,
-      ),
-      'chvotes' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The total number of votes this choice has received by all users.',
-      ),
-      'weight' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The sort order of this choice among all choices for the same node.',
-      ),
-    ),
-    'indexes' => array(
-      'nid' => array('nid'),
-    ),
-    'primary key' => array('chid'),
-    'foreign keys' => array(
-      'choice_node' => array(
-        'table' => 'node',
-        'columns' => array('nid' => 'nid'),
-      ),
-    ),
-  );
-
-  $schema['poll_vote'] = array(
-    'description' => 'Stores per-{users} votes for each {poll}.',
-    'fields' => array(
-      'chid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'description' => "The {users}'s vote for this poll.",
-      ),
-      'nid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'description' => 'The {poll} node this vote is for.',
-      ),
-      'uid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {users}.uid this vote is from unless the voter was anonymous.',
-      ),
-      'hostname' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The IP address this vote is from unless the voter was logged in.',
-      ),
-      'timestamp' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The timestamp of the vote creation.',
-      ),
-    ),
-    'primary key' => array('nid', 'uid', 'hostname'),
-    'foreign keys' => array(
-      'poll_node' => array(
-        'table' => 'node',
-        'columns' => array('nid' => 'nid'),
-      ),
-      'voter' => array(
-        'table' => 'users',
-        'columns' => array('uid' => 'uid'),
-      ),
-    ),
-    'indexes' => array(
-      'chid'     => array('chid'),
-      'hostname' => array('hostname'),
-      'uid' => array('uid'),
-    ),
-  );
-
-  return $schema;
-}
diff --git a/modules/poll/poll.module b/modules/poll/poll.module
deleted file mode 100644
index 8619695..0000000
--- a/modules/poll/poll.module
+++ /dev/null
@@ -1,1005 +0,0 @@
-<?php
-
-/**
- * @file
- * Enables your site to capture votes on different topics in the form of multiple
- * choice questions.
- */
-
-/**
- * Implements hook_help().
- */
-function poll_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#poll':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Poll module can be used to create simple surveys or questionnaires that display cumulative results. A poll is a good way to receive feedback from site users and community members. For more information, see the online handbook entry for the <a href="@poll">Poll module</a>.', array('@poll' => 'http://drupal.org/handbook/modules/poll/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Creating a poll') . '</dt>';
-      $output .= '<dd>' . t('Users can create a poll by clicking on Poll on the <a href="@add-content">Add new content</a> page, and entering the question being posed, the answer choices, and beginning vote counts for each choice. The status (closed or active) and duration (length of time the poll remains active for new votes) can also be specified.', array('@add-content' => url('node/add'))) . '</dd>';
-      $output .= '<dt>' . t('Viewing polls') . '</dt>';
-      $output .= '<dd>' . t('You can visit the <a href="@poll">Polls</a> page to view all current polls, or alternately enable the <em>Most recent poll</em> block on the <a href="@blocks">Blocks administration page</a>. To vote in or view the results of a specific poll, you can click on the poll itself.', array('@poll' => url('poll'), '@blocks' => url('admin/structure/block'))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function poll_theme() {
-  $theme_hooks = array(
-    'poll_vote' => array(
-      'template' => 'poll-vote',
-      'render element' => 'form',
-    ),
-    'poll_choices' => array(
-      'render element' => 'form',
-    ),
-    'poll_results' => array(
-      'template' => 'poll-results',
-      'variables' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL),
-    ),
-    'poll_bar' => array(
-      'template' => 'poll-bar',
-      'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
-    ),
-  );
-  // The theme system automatically discovers the theme's functions and
-  // templates that implement more targeted "suggestions" of generic theme
-  // hooks. But suggestions implemented by a module must be explicitly
-  // registered.
-  $theme_hooks += array(
-    'poll_results__block' => array(
-      'template' => 'poll-results--block',
-      'variables' => $theme_hooks['poll_results']['variables'],
-    ),
-    'poll_bar__block' => array(
-      'template' => 'poll-bar--block',
-      'variables' => $theme_hooks['poll_bar']['variables'],
-    ),
-  );
-  return $theme_hooks;
-}
-
-/**
- * Implements hook_permission().
- */
-function poll_permission() {
-  $perms = array(
-    'vote on polls' => array(
-      'title' => t('Vote on polls'),
-    ),
-    'cancel own vote' => array(
-      'title' => t('Cancel and change own votes'),
-    ),
-    'inspect all votes' => array(
-      'title' => t('View voting results'),
-    ),
-  );
-
-  return $perms;
-}
-
-/**
- * Implements hook_menu().
- */
-function poll_menu() {
-  $items['poll'] = array(
-    'title' => 'Polls',
-    'page callback' => 'poll_page',
-    'access arguments' => array('access content'),
-    'type' => MENU_SUGGESTED_ITEM,
-    'file' => 'poll.pages.inc',
-  );
-
-  $items['node/%node/votes'] = array(
-    'title' => 'Votes',
-    'page callback' => 'poll_votes',
-    'page arguments' => array(1),
-    'access callback' => '_poll_menu_access',
-    'access arguments' => array(1, 'inspect all votes', FALSE),
-    'weight' => 3,
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'poll.pages.inc',
-  );
-
-  $items['node/%node/results'] = array(
-    'title' => 'Results',
-    'page callback' => 'poll_results',
-    'page arguments' => array(1),
-    'access callback' => '_poll_menu_access',
-    'access arguments' => array(1, 'access content', TRUE),
-    'weight' => 3,
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'poll.pages.inc',
-  );
-
-  return $items;
-}
-
-/**
- * Callback function to see if a node is acceptable for poll menu items.
- */
-function _poll_menu_access($node, $perm, $inspect_allowvotes) {
-  return user_access($perm) && ($node->type == 'poll') && ($node->allowvotes || !$inspect_allowvotes);
-}
-
-/**
- * Implements hook_block_info().
- */
-function poll_block_info() {
-  $blocks['recent']['info'] = t('Most recent poll');
-  $blocks['recent']['properties']['administrative'] = TRUE;
-  return $blocks;
-}
-
-/**
- * Implements hook_block_view().
- *
- * Generates a block containing the latest poll.
- */
-function poll_block_view($delta = '') {
-  if (user_access('access content')) {
-    // Retrieve the latest poll.
-    $select = db_select('node', 'n');
-    $select->join('poll', 'p', 'p.nid = n.nid');
-    $select->fields('n', array('nid'))
-      ->condition('n.status', 1)
-      ->condition('p.active', 1)
-      ->orderBy('n.created', 'DESC')
-      ->range(0, 1)
-      ->addTag('node_access');
-
-    $record = $select->execute()->fetchObject();
-    if ($record) {
-      $poll = node_load($record->nid);
-      if ($poll->nid) {
-        $poll = poll_block_latest_poll_view($poll);
-        $block['subject'] = t('Poll');
-        $block['content'] = $poll->content;
-        return $block;
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_cron().
- *
- * Closes polls that have exceeded their allowed runtime.
- */
-function poll_cron() {
-  $nids = db_query('SELECT p.nid FROM {poll} p INNER JOIN {node} n ON p.nid = n.nid WHERE (n.created + p.runtime) < :request_time AND p.active = :active AND p.runtime <> :runtime', array(':request_time' => REQUEST_TIME, ':active' => 1, ':runtime' => 0))->fetchCol();
-  if (!empty($nids)) {
-    db_update('poll')
-      ->fields(array('active' => 0))
-      ->condition('nid', $nids, 'IN')
-      ->execute();
-  }
-}
-
-/**
- * Implements hook_node_info().
- */
-function poll_node_info() {
-  return array(
-    'poll' => array(
-      'name' => t('Poll'),
-      'base' => 'poll',
-      'description' => t('A <em>poll</em> is a question with a set of possible responses. A <em>poll</em>, once created, automatically provides a simple running count of the number of votes received for each response.'),
-      'title_label' => t('Question'),
-      'has_body' => FALSE,
-    )
-  );
-}
-
-/**
- * Implements hook_field_extra_fields().
- */
-function poll_field_extra_fields() {
-  $extra['node']['poll'] = array(
-    'form' => array(
-      'choice_wrapper' => array(
-        'label' => t('Poll choices'),
-        'description' => t('Poll choices'),
-        'weight' => -4,
-      ),
-      'settings' => array(
-        'label' => t('Poll settings'),
-        'description' => t('Poll module settings'),
-        'weight' => -3,
-      ),
-    ),
-    'display' => array(
-      'poll_view_voting' => array(
-        'label' => t('Poll vote'),
-        'description' => t('Poll vote'),
-        'weight' => 0,
-      ),
-      'poll_view_results' => array(
-        'label' => t('Poll results'),
-        'description' => t('Poll results'),
-        'weight' => 0,
-      ),
-    )
-  );
-
-  return $extra;
-}
-
-/**
- * Implements hook_form().
- */
-function poll_form($node, &$form_state) {
-  global $user;
-
-  $admin = user_access('bypass node access') || user_access('edit any poll content') || (user_access('edit own poll content') && $user->uid == $node->uid);
-
-  $type = node_type_get_type($node);
-
-  // The submit handlers to add more poll choices require that this form is
-  // cached, regardless of whether Ajax is used.
-  $form_state['cache'] = TRUE;
-
-  $form['title'] = array(
-    '#type' => 'textfield',
-    '#title' => check_plain($type->title_label),
-    '#required' => TRUE,
-    '#default_value' => $node->title,
-    '#weight' => -5,
-  );
-
-  if (isset($form_state['choice_count'])) {
-    $choice_count = $form_state['choice_count'];
-  }
-  else {
-    $choice_count = max(2, empty($node->choice) ? 2 : count($node->choice));
-  }
-
-  // Add a wrapper for the choices and more button.
-  $form['choice_wrapper'] = array(
-    '#tree' => FALSE,
-    '#weight' => -4,
-    '#prefix' => '<div class="clearfix" id="poll-choice-wrapper">',
-    '#suffix' => '</div>',
-  );
-
-  // Container for just the poll choices.
-  $form['choice_wrapper']['choice'] = array(
-    '#prefix' => '<div id="poll-choices">',
-    '#suffix' => '</div>',
-    '#theme' => 'poll_choices',
-  );
-
-  // Add the current choices to the form.
-  $delta = 0;
-  $weight = 0;
-  if (isset($node->choice)) {
-    $delta = count($node->choice);
-    foreach ($node->choice as $chid => $choice) {
-      $key = 'chid:' . $chid;
-      $form['choice_wrapper']['choice'][$key] = _poll_choice_form($key, $choice['chid'], $choice['chtext'], $choice['chvotes'], $choice['weight'], $choice_count);
-      $weight = max($choice['weight'], $weight);
-    }
-  }
-
-  // Add initial or additional choices.
-  $existing_delta = $delta;
-  $weight++;
-  for ($delta; $delta < $choice_count; $delta++) {
-    $key = 'new:' . ($delta - $existing_delta);
-    $form['choice_wrapper']['choice'][$key] = _poll_choice_form($key, NULL, '', 0, $weight, $choice_count);
-  }
-
-  // We name our button 'poll_more' to avoid conflicts with other modules using
-  // Ajax-enabled buttons with the id 'more'.
-  $form['choice_wrapper']['poll_more'] = array(
-    '#type' => 'submit',
-    '#value' => t('More choices'),
-    '#description' => t("If the amount of boxes above isn't enough, click here to add more choices."),
-    '#weight' => 1,
-    '#limit_validation_errors' => array(array('choice')),
-    '#submit' => array('poll_more_choices_submit'),
-    '#ajax' => array(
-      'callback' => 'poll_choice_js',
-      'wrapper' => 'poll-choices',
-      'effect' => 'fade',
-    ),
-  );
-
-  // Poll attributes
-  $duration = array(
-    // 1-6 days.
-    86400, 2 * 86400, 3 * 86400, 4 * 86400, 5 * 86400, 6 * 86400,
-    // 1-3 weeks (7 days).
-    604800, 2 * 604800, 3 * 604800,
-    // 1-3,6,9 months (30 days).
-    2592000, 2 * 2592000, 3 * 2592000, 6 * 2592000, 9 * 2592000,
-    // 1 year (365 days).
-    31536000,
-  );
-  $duration = array(0 => t('Unlimited')) + drupal_map_assoc($duration, 'format_interval');
-  $active = array(0 => t('Closed'), 1 => t('Active'));
-
-  $form['settings'] = array(
-    '#type' => 'fieldset',
-    '#collapsible' => TRUE,
-    '#title' => t('Poll settings'),
-    '#weight' => -3,
-    '#access' => $admin,
-  );
-
-  $form['settings']['active'] = array(
-    '#type' => 'radios',
-    '#title' => t('Poll status'),
-    '#default_value' => isset($node->active) ? $node->active : 1,
-    '#options' => $active,
-    '#description' => t('When a poll is closed, visitors can no longer vote for it.'),
-    '#access' => $admin,
-  );
-  $form['settings']['runtime'] = array(
-    '#type' => 'select',
-    '#title' => t('Poll duration'),
-    '#default_value' => isset($node->runtime) ? $node->runtime : 0,
-    '#options' => $duration,
-    '#description' => t('After this period, the poll will be closed automatically.'),
-  );
-
-  return $form;
-}
-
-/**
- * Submit handler to add more choices to a poll form.
- *
- * This handler is run regardless of whether JS is enabled or not. It makes
- * changes to the form state. If the button was clicked with JS disabled, then
- * the page is reloaded with the complete rebuilt form. If the button was
- * clicked with JS enabled, then ajax_form_callback() calls poll_choice_js() to
- * return just the changed part of the form.
- */
-function poll_more_choices_submit($form, &$form_state) {
-  // If this is a Ajax POST, add 1, otherwise add 5 more choices to the form.
-  if ($form_state['values']['poll_more']) {
-    $n = $_GET['q'] == 'system/ajax' ? 1 : 5;
-    $form_state['choice_count'] = count($form_state['values']['choice']) + $n;
-  }
-  // Renumber the choices. This invalidates the corresponding key/value
-  // associations in $form_state['input'], so clear that out. This requires
-  // poll_form() to rebuild the choices with the values in
-  // $form_state['node']->choice, which it does.
-  $form_state['node']->choice = array_values($form_state['values']['choice']);
-  unset($form_state['input']['choice']);
-  $form_state['rebuild'] = TRUE;
-}
-
-function _poll_choice_form($key, $chid = NULL, $value = '', $votes = 0, $weight = 0, $size = 10) {
-  $form = array(
-    '#tree' => TRUE,
-    '#weight' => $weight,
-  );
-
-  // We'll manually set the #parents property of these fields so that
-  // their values appear in the $form_state['values']['choice'] array.
-  $form['chid'] = array(
-    '#type' => 'value',
-    '#value' => $chid,
-    '#parents' => array('choice', $key, 'chid'),
-  );
-
-  $form['chtext'] = array(
-    '#type' => 'textfield',
-    '#title' => $value !== '' ? t('Choice label') : t('New choice label'),
-    '#title_display' => 'invisible',
-    '#default_value' => $value,
-    '#parents' => array('choice', $key, 'chtext'),
-  );
-
-  $form['chvotes'] = array(
-    '#type' => 'textfield',
-    '#title' => $value !== '' ? t('Vote count for choice @label', array('@label' => $value)) : t('Vote count for new choice'),
-    '#title_display' => 'invisible',
-    '#default_value' => $votes,
-    '#size' => 5,
-    '#maxlength' => 7,
-    '#parents' => array('choice', $key, 'chvotes'),
-    '#access' => user_access('administer nodes'),
-  );
-
-  $form['weight'] = array(
-    '#type' => 'weight',
-    '#title' => $value !== '' ? t('Weight for choice @label', array('@label' => $value)) : t('Weight for new choice'),
-    '#title_display' => 'invisible',
-    '#default_value' => $weight,
-    '#delta' => $size,
-    '#parents' => array('choice', $key, 'weight'),
-  );
-
-  return $form;
-}
-
-/**
- * Ajax callback in response to new choices being added to the form.
- *
- * This returns the new page content to replace the page content made obsolete
- * by the form submission.
- *
- * @see poll_more_choices_submit()
- */
-function poll_choice_js($form, $form_state) {
-  return $form['choice_wrapper']['choice'];
-}
-
-/**
- * Form submit handler for node_form().
- *
- * Upon preview and final submission, we need to renumber poll choices and
- * create a teaser output.
- */
-function poll_node_form_submit(&$form, &$form_state) {
-  // Renumber choices.
-  $form_state['values']['choice'] = array_values($form_state['values']['choice']);
-  $form_state['values']['teaser'] = poll_teaser((object) $form_state['values']);
-}
-
-/**
- * Implements hook_validate().
- */
-function poll_validate($node, $form) {
-  if (isset($node->title)) {
-    // Check for at least two options and validate amount of votes:
-    $realchoices = 0;
-    // Renumber fields
-    $node->choice = array_values($node->choice);
-    foreach ($node->choice as $i => $choice) {
-      if ($choice['chtext'] != '') {
-        $realchoices++;
-      }
-      if (isset($choice['chvotes']) && $choice['chvotes'] < 0) {
-        form_set_error("choice][$i][chvotes", t('Negative values are not allowed.'));
-      }
-    }
-
-    if ($realchoices < 2) {
-      form_set_error("choice][$realchoices][chtext", t('You must fill in at least two choices.'));
-    }
-  }
-}
-
-/**
- * Implements hook_field_attach_prepare_translation_alter().
- */
-function poll_field_attach_prepare_translation_alter(&$entity, $context) {
-  if ($context['entity_type'] == 'node' && $entity->type == 'poll') {
-    $entity->choice = $context['source_entity']->choice;
-  }
-}
-
-/**
- * Implements hook_load().
- */
-function poll_load($nodes) {
-  global $user;
-  foreach ($nodes as $node) {
-    $poll = db_query("SELECT runtime, active FROM {poll} WHERE nid = :nid", array(':nid' => $node->nid))->fetchObject();
-
-    if (empty($poll)) {
-      $poll = new stdClass();
-    }
-
-    // Load the appropriate choices into the $poll object.
-    $poll->choice = db_select('poll_choice', 'c')
-      ->addTag('translatable')
-      ->fields('c', array('chid', 'chtext', 'chvotes', 'weight'))
-      ->condition('c.nid', $node->nid)
-      ->orderBy('weight')
-      ->execute()->fetchAllAssoc('chid', PDO::FETCH_ASSOC);
-
-    // Determine whether or not this user is allowed to vote.
-    $poll->allowvotes = FALSE;
-    if (user_access('vote on polls') && $poll->active) {
-      if ($user->uid) {
-        // If authenticated, find existing vote based on uid.
-        $poll->vote = db_query('SELECT chid FROM {poll_vote} WHERE nid = :nid AND uid = :uid', array(':nid' => $node->nid, ':uid' => $user->uid))->fetchField();
-        if (empty($poll->vote)) {
-          $poll->vote = -1;
-          $poll->allowvotes = TRUE;
-        }
-      }
-      elseif (!empty($_SESSION['poll_vote'][$node->nid])) {
-        // Otherwise the user is anonymous. Look for an existing vote in the
-        // user's session.
-        $poll->vote = $_SESSION['poll_vote'][$node->nid];
-      }
-      else {
-        // Finally, query the database for an existing vote based on anonymous
-        // user's hostname.
-        $poll->allowvotes = !db_query("SELECT 1 FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname AND uid = 0", array(':nid' => $node->nid, ':hostname' => ip_address()))->fetchField();
-      }
-    }
-    foreach ($poll as $key => $value) {
-      $nodes[$node->nid]->$key = $value;
-    }
-  }
-}
-
-/**
- * Implements hook_insert().
- */
-function poll_insert($node) {
-  if (!user_access('administer nodes')) {
-    // Make sure all votes are 0 initially
-    foreach ($node->choice as $i => $choice) {
-      $node->choice[$i]['chvotes'] = 0;
-    }
-    $node->active = 1;
-  }
-
-  db_insert('poll')
-    ->fields(array(
-      'nid' => $node->nid,
-      'runtime' => $node->runtime,
-      'active' => $node->active,
-    ))
-    ->execute();
-
-  foreach ($node->choice as $choice) {
-    if ($choice['chtext'] != '') {
-      db_insert('poll_choice')
-        ->fields(array(
-          'nid' => $node->nid,
-          'chtext' => $choice['chtext'],
-          'chvotes' => $choice['chvotes'],
-          'weight' => $choice['weight'],
-        ))
-        ->execute();
-    }
-  }
-}
-
-/**
- * Implements hook_update().
- */
-function poll_update($node) {
-  // Update poll settings.
-  db_update('poll')
-    ->fields(array(
-      'runtime' => $node->runtime,
-      'active' => $node->active,
-    ))
-    ->condition('nid', $node->nid)
-    ->execute();
-
-  // Poll choices with empty titles signifies removal. We remove all votes to
-  // the removed options, so people who voted on them can vote again.
-  foreach ($node->choice as $key => $choice) {
-    if (!empty($choice['chtext'])) {
-      db_merge('poll_choice')
-        ->key(array('chid' => $choice['chid']))
-        ->fields(array(
-          'chtext' => $choice['chtext'],
-          'chvotes' => (int) $choice['chvotes'],
-          'weight' => $choice['weight'],
-        ))
-        ->insertFields(array('nid' => $node->nid))
-        ->execute();
-    }
-    else {
-      db_delete('poll_vote')
-        ->condition('nid', $node->nid)
-        ->condition('chid', $key)
-        ->execute();
-    }
-  }
-}
-
-/**
- * Implements hook_delete().
- */
-function poll_delete($node) {
-  db_delete('poll')
-    ->condition('nid', $node->nid)
-    ->execute();
-  db_delete('poll_choice')
-    ->condition('nid', $node->nid)
-    ->execute();
-  db_delete('poll_vote')
-    ->condition('nid', $node->nid)
-    ->execute();
-}
-
-/**
- * Return content for 'latest poll' block.
- *
- * @param $node
- *   The node object to load.
- */
-function poll_block_latest_poll_view($node) {
-  global $user;
-  $output = '';
-
-  // This is necessary for shared objects because PHP doesn't copy objects, but
-  // passes them by reference.  So when the objects are cached it can result in
-  // the wrong output being displayed on subsequent calls.  The cloning and
-  // unsetting of $node->content prevents the block output from being the same
-  // as the node output.
-  $node = clone $node;
-  unset($node->content);
-
-  // No 'read more' link.
-  $node->readmore = FALSE;
-  $node->teaser = '';
-
-  $links = array();
-  $links[] = array('title' => t('Older polls'), 'href' => 'poll', 'attributes' => array('title' => t('View the list of polls on this site.')));
-  if ($node->allowvotes) {
-    $links[] = array('title' => t('Results'), 'href' => 'node/' . $node->nid . '/results', 'attributes' => array('title' => t('View the current poll results.')));
-  }
-
-  $node->links = $links;
-
-  if (!empty($node->allowvotes)) {
-    $node->content['poll_view_voting'] = drupal_get_form('poll_view_voting', $node, TRUE);
-    $node->content['links'] = array(
-      '#theme' => 'links',
-      '#links' => $node->links,
-      '#weight' => 5,
-    );
-  }
-  else {
-    $node->content['poll_view_results'] = array('#markup' => poll_view_results($node, TRUE, TRUE));
-  }
-
-  return $node;
-}
-
-
-/**
- * Implements hook_view().
- */
-function poll_view($node, $view_mode) {
-  global $user;
-  $output = '';
-
-  if (!empty($node->allowvotes) && empty($node->show_results)) {
-    $node->content['poll_view_voting'] = drupal_get_form('poll_view_voting', $node);
-  }
-  else {
-    $node->content['poll_view_results'] = array('#markup' => poll_view_results($node, $view_mode));
-  }
-  return $node;
-}
-
-/**
- * Creates a simple teaser that lists all the choices.
- *
- * This is primarily used for RSS.
- */
-function poll_teaser($node) {
-  $teaser = NULL;
-  if (is_array($node->choice)) {
-    foreach ($node->choice as $k => $choice) {
-      if ($choice['chtext'] != '') {
-        $teaser .= '* ' . check_plain($choice['chtext']) . "\n";
-      }
-    }
-  }
-  return $teaser;
-}
-
-/**
- * Generates the voting form for a poll.
- *
- * @ingroup forms
- * @see poll_vote()
- * @see phptemplate_preprocess_poll_vote()
- */
-function poll_view_voting($form, &$form_state, $node, $block = FALSE) {
-  if ($node->choice) {
-    $list = array();
-    foreach ($node->choice as $i => $choice) {
-      $list[$i] = check_plain($choice['chtext']);
-    }
-    $form['choice'] = array(
-      '#type' => 'radios',
-      '#title' => t('Choices'),
-      '#title_display' => 'invisible',
-      '#default_value' => -1,
-      '#options' => $list,
-    );
-  }
-
-  $form['vote'] = array(
-    '#type' => 'submit',
-    '#value' => t('Vote'),
-    '#submit' => array('poll_vote'),
-  );
-
-  // Store the node so we can get to it in submit functions.
-  $form['#node'] = $node;
-  $form['#block'] = $block;
-
-  // Set form caching because we could have multiple of these forms on
-  // the same page, and we want to ensure the right one gets picked.
-  $form_state['cache'] = TRUE;
-
-  // Provide a more cleanly named voting form theme.
-  $form['#theme'] = 'poll_vote';
-  return $form;
-}
-
-/**
- * Validation function for processing votes
- */
-function poll_view_voting_validate($form, &$form_state) {
-  if ($form_state['values']['choice'] == -1) {
-    form_set_error( 'choice', t('Your vote could not be recorded because you did not select any of the choices.'));
-  }
-}
-
-/**
- * Submit handler for processing a vote.
- */
-function poll_vote($form, &$form_state) {
-  $node = $form['#node'];
-  $choice = $form_state['values']['choice'];
-
-  global $user;
-  db_insert('poll_vote')
-    ->fields(array(
-      'nid' => $node->nid,
-      'chid' => $choice,
-      'uid' => $user->uid,
-      'hostname' => ip_address(),
-      'timestamp' => REQUEST_TIME,
-    ))
-    ->execute();
-
-  // Add one to the votes.
-  db_update('poll_choice')
-    ->expression('chvotes', 'chvotes + 1')
-    ->condition('chid', $choice)
-    ->execute();
-
-  cache_clear_all();
-
-  if (!$user->uid) {
-    // The vote is recorded so the user gets the result view instead of the
-    // voting form when viewing the poll. Saving a value in $_SESSION has the
-    // convenient side effect of preventing the user from hitting the page
-    // cache. When anonymous voting is allowed, the page cache should only
-    // contain the voting form, not the results.
-    $_SESSION['poll_vote'][$node->nid] = $choice;
-  }
-
-  drupal_set_message(t('Your vote was recorded.'));
-
-  // Return the user to whatever page they voted from.
-}
-
-/**
- * Themes the voting form for a poll.
- *
- * Inputs: $form
- */
-function template_preprocess_poll_vote(&$variables) {
-  $form = $variables['form'];
-  $variables['choice'] = drupal_render($form['choice']);
-  $variables['title'] = check_plain($form['#node']->title);
-  $variables['vote'] = drupal_render($form['vote']);
-  $variables['rest'] = drupal_render_children($form);
-  $variables['block'] = $form['#block'];
-  if ($variables['block']) {
-    $variables['theme_hook_suggestions'][] = 'poll_vote__block';
-  }
-}
-
-/**
- * Generates a graphical representation of the results of a poll.
- */
-function poll_view_results($node, $view_mode, $block = FALSE) {
-  // Make sure that choices are ordered by their weight.
-  uasort($node->choice, 'drupal_sort_weight');
-
-  // Count the votes and find the maximum
-  $total_votes = 0;
-  $max_votes = 0;
-  foreach ($node->choice as $choice) {
-    if (isset($choice['chvotes'])) {
-      $total_votes += $choice['chvotes'];
-      $max_votes = max($max_votes, $choice['chvotes']);
-    }
-  }
-
-  $poll_results = '';
-  foreach ($node->choice as $i => $choice) {
-    if (!empty($choice['chtext'])) {
-      $chvotes = isset($choice['chvotes']) ? $choice['chvotes'] : NULL;
-      $poll_results .= theme('poll_bar', array('title' => $choice['chtext'], 'votes' => $chvotes, 'total_votes' => $total_votes, 'vote' => isset($node->vote) && $node->vote == $i, 'block' => $block));
-    }
-  }
-
-  return theme('poll_results', array('raw_title' => $node->title, 'results' => $poll_results, 'votes' => $total_votes, 'raw_links' => isset($node->links) ? $node->links : array(), 'block' => $block, 'nid' => $node->nid, 'vote' => isset($node->vote) ? $node->vote : NULL));
-}
-
-
-/**
- * Returns HTML for an admin poll form for choices.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_poll_choices($variables) {
-  $form = $variables['form'];
-
-  drupal_add_tabledrag('poll-choice-table', 'order', 'sibling', 'poll-weight');
-
-  $is_admin= user_access('administer nodes');
-  $delta = 0;
-  $rows = array();
-  $headers = array('', t('Choice'));
-  if ($is_admin) {
-    $headers[] = t('Vote count');
-  }
-  $headers[] = t('Weight');
-
-  foreach (element_children($form) as $key) {
-    $delta++;
-    // Set special classes for drag and drop updating.
-    $form[$key]['weight']['#attributes']['class'] = array('poll-weight');
-
-    // Build the table row.
-    $row = array(
-      'data' => array(
-        array('class' => array('choice-flag')),
-        drupal_render($form[$key]['chtext']),
-      ),
-      'class' => array('draggable'),
-    );
-    if ($is_admin) {
-      $row['data'][] = drupal_render($form[$key]['chvotes']);
-    }
-    $row['data'][] = drupal_render($form[$key]['weight']);
-
-    // Add any additional classes set on the row.
-    if (!empty($form[$key]['#attributes']['class'])) {
-      $row['class'] = array_merge($row['class'], $form[$key]['#attributes']['class']);
-    }
-
-    $rows[] = $row;
-  }
-
-  $output = theme('table', array('header' => $headers, 'rows' => $rows, 'attributes' => array('id' => 'poll-choice-table')));
-  $output .= drupal_render_children($form);
-  return $output;
-}
-
-/**
- * Preprocess the poll_results theme hook.
- *
- * Inputs: $raw_title, $results, $votes, $raw_links, $block, $nid, $vote. The
- * $raw_* inputs to this are naturally unsafe; often safe versions are
- * made to simply overwrite the raw version, but in this case it seems likely
- * that the title and the links may be overridden by the theme layer, so they
- * are left in with a different name for that purpose.
- *
- * @see poll-results.tpl.php
- * @see poll-results--block.tpl.php
- */
-function template_preprocess_poll_results(&$variables) {
-  $variables['links'] = theme('links__poll_results', array('links' => $variables['raw_links']));
-  if (isset($variables['vote']) && $variables['vote'] > -1 && user_access('cancel own vote')) {
-    $elements = drupal_get_form('poll_cancel_form', $variables['nid']);
-    $variables['cancel_form'] = drupal_render($elements);
-  }
-  $variables['title'] = check_plain($variables['raw_title']);
-
-  if ($variables['block']) {
-    $variables['theme_hook_suggestions'][] = 'poll_results__block';
-  }
-}
-
-/**
- * Preprocess the poll_bar theme hook.
- *
- * Inputs: $title, $votes, $total_votes, $voted, $block
- *
- * @see poll-bar.tpl.php
- * @see poll-bar--block.tpl.php
- * @see theme_poll_bar()
- */
-function template_preprocess_poll_bar(&$variables) {
-  if ($variables['block']) {
-    $variables['theme_hook_suggestions'][] = 'poll_bar__block';
-  }
-  $variables['title'] = check_plain($variables['title']);
-  $variables['percentage'] = round($variables['votes'] * 100 / max($variables['total_votes'], 1));
-}
-
-/**
- * Builds the cancel form for a poll.
- *
- * @ingroup forms
- * @see poll_cancel()
- */
-function poll_cancel_form($form, &$form_state, $nid) {
-  $form_state['cache'] = TRUE;
-
-  // Store the nid so we can get to it in submit functions.
-  $form['#nid'] = $nid;
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Cancel your vote'),
-    '#submit' => array('poll_cancel')
-  );
-
-  return $form;
-}
-
-/**
- * Submit callback for poll_cancel_form().
- */
-function poll_cancel($form, &$form_state) {
-  global $user;
-  $node = node_load($form['#nid']);
-
-  db_delete('poll_vote')
-    ->condition('nid', $node->nid)
-    ->condition($user->uid ? 'uid' : 'hostname', $user->uid ? $user->uid : ip_address())
-    ->execute();
-
-  // Subtract from the votes.
-  db_update('poll_choice')
-    ->expression('chvotes', 'chvotes - 1')
-    ->condition('chid', $node->vote)
-    ->execute();
-
-  unset($_SESSION['poll_vote'][$node->nid]);
-
-  drupal_set_message(t('Your vote was cancelled.'));
-}
-
-/**
- * Implements hook_user_cancel().
- */
-function poll_user_cancel($edit, $account, $method) {
-  switch ($method) {
-    case 'user_cancel_reassign':
-      db_update('poll_vote')
-        ->fields(array('uid' => 0))
-        ->condition('uid', $account->uid)
-        ->execute();
-      break;
-  }
-}
-
-/**
- * Implements hook_user_delete().
- */
-function poll_user_delete($account) {
-  db_delete('poll_vote')
-    ->condition('uid', $account->uid)
-    ->execute();
-}
-
-/**
- * Implements hook_rdf_mapping().
- */
-function poll_rdf_mapping() {
-  return array(
-    array(
-      'type' => 'node',
-      'bundle' => 'poll',
-      'mapping' => array(
-        'rdftype' => array('sioc:Post', 'sioct:Poll'),
-      ),
-    ),
-  );
-}
diff --git a/modules/poll/poll.pages.inc b/modules/poll/poll.pages.inc
deleted file mode 100644
index 15f3ba7..0000000
--- a/modules/poll/poll.pages.inc
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the poll module.
- */
-
-/**
- * Menu callback to provide a simple list of all polls available.
- */
-function poll_page() {
-  $polls_per_page = 15;
-
-  $count_select = db_select('node', 'n');
-  $count_select->addExpression('COUNT(*)', 'expression');
-  $count_select->join('poll', 'p', 'p.nid = n.nid');
-  $count_select->condition('n.status', 1);
-
-  // List all polls.
-  $select = db_select('node', 'n');
-  $select->join('poll', 'p', 'p.nid = n.nid');
-  $select->join('poll_choice', 'c', 'c.nid = n.nid');
-  $select->addExpression('SUM(c.chvotes)', 'votes');
-  $select = $select->fields('n', array('nid', 'title', 'created'))
-    ->fields('p', array('active'))
-    ->condition('n.status', 1)
-    ->orderBy('n.created', 'DESC')
-    ->groupBy('n.nid')
-    ->groupBy('n.title')
-    ->groupBy('p.active')
-    ->groupBy('n.created')
-    ->extend('PagerDefault')
-    ->limit($polls_per_page)
-    ->addTag('node_access');
-  $select->setCountQuery($count_select);
-  $queried_nodes = $select->execute()
-    ->fetchAllAssoc('nid');
-
-  $output = '<ul>';
-  foreach ($queried_nodes as $node) {
-    $output .= '<li>' . l($node->title, "node/$node->nid") . ' - ' . format_plural($node->votes, '1 vote', '@count votes') . ' - ' . ($node->active ? t('open') : t('closed')) . '</li>';
-  }
-  $output .= '</ul>';
-  $output .= theme('pager');
-  return $output;
-}
-
-/**
- * Callback for the 'votes' tab for polls you can see other votes on
- */
-function poll_votes($node) {
-  $votes_per_page = 20;
-  drupal_set_title($node->title);
-
-  $header[] = array('data' => t('Visitor'), 'field' => 'u.name');
-  $header[] = array('data' => t('Vote'), 'field' => 'pc.chtext');
-  $header[] = array('data' => t('Timestamp'), 'field' => 'pv.timestamp', 'sort' => 'desc');
-
-  $select = db_select('poll_vote', 'pv')->extend('PagerDefault')->extend('TableSort');
-  $select->join('poll_choice', 'pc', 'pv.chid = pc.chid');
-  $select->join('users', 'u', 'pv.uid = u.uid');
-  $queried_votes = $select
-    ->addTag('translatable')
-    ->fields('pv', array('chid', 'uid', 'hostname', 'timestamp', 'nid'))
-    ->fields('pc', array('chtext'))
-    ->fields('u', array('name'))
-    ->condition('pv.nid', $node->nid)
-    ->limit($votes_per_page)
-    ->orderByHeader($header)
-    ->execute();
-
-  $rows = array();
-  foreach ($queried_votes as $vote) {
-    $rows[] = array(
-      $vote->name ? theme('username', array('account' => $vote)) : check_plain($vote->hostname),
-      check_plain($vote->chtext),
-      format_date($vote->timestamp),
-    );
-  }
-  $build['poll_votes_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#prefix' => t('This table lists all the recorded votes for this poll. If anonymous users are allowed to vote, they will be identified by the IP address of the computer they used when they voted.'),
-  );
-  $build['poll_votes_pager'] = array('#theme' => 'pager');
-  return $build;
-}
-
-/**
- * Callback for the 'results' tab for polls you can vote on
- */
-function poll_results($node) {
-  drupal_set_title($node->title);
-  $node->show_results = TRUE;
-  return node_show($node);
-}
diff --git a/modules/poll/poll.test b/modules/poll/poll.test
deleted file mode 100644
index 6fabf95..0000000
--- a/modules/poll/poll.test
+++ /dev/null
@@ -1,729 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for poll.module.
- */
-
-class PollTestCase extends DrupalWebTestCase {
-
-  /**
-   * Creates a poll.
-   *
-   * @param string $title
-   *   The title of the poll.
-   * @param array $choices
-   *   A list of choice labels.
-   * @param boolean $preview
-   *   (optional) Whether to test if the preview is working or not. Defaults to
-   *   TRUE.
-   *
-   * @return
-   *   The node id of the created poll, or FALSE on error.
-   */
-  function pollCreate($title, $choices, $preview = TRUE) {
-    $this->assertTrue(TRUE, 'Create a poll');
-
-    $web_user = $this->drupalCreateUser(array('create poll content', 'access content', 'edit own poll content'));
-    $this->drupalLogin($web_user);
-
-    // Get the form first to initialize the state of the internal browser.
-    $this->drupalGet('node/add/poll');
-
-    // Prepare a form with two choices.
-    list($edit, $index) = $this->_pollGenerateEdit($title, $choices);
-
-    // Re-submit the form until all choices are filled in.
-    if (count($choices) > 2) {
-      while ($index < count($choices)) {
-        $this->drupalPost(NULL, $edit, t('More choices'));
-        $this->assertPollChoiceOrder($choices, $index);
-        list($edit, $index) = $this->_pollGenerateEdit($title, $choices, $index);
-      }
-    }
-
-    if ($preview) {
-      $this->drupalPost(NULL, $edit, t('Preview'));
-      $this->assertPollChoiceOrder($choices, $index, TRUE);
-      list($edit, $index) = $this->_pollGenerateEdit($title, $choices, $index);
-    }
-
-    $this->drupalPost(NULL, $edit, t('Save'));
-    $node = $this->drupalGetNodeByTitle($title);
-    $this->assertText(t('@type @title has been created.', array('@type' => node_type_get_name('poll'), '@title' => $title)), 'Poll has been created.');
-    $this->assertTrue($node->nid, t('Poll has been found in the database.'));
-
-    return isset($node->nid) ? $node->nid : FALSE;
-  }
-
-  /**
-   * Generates POST values for the poll node form, specifically poll choices.
-   *
-   * @param $title
-   *   The title for the poll node.
-   * @param $choices
-   *   An array containing poll choices, as generated by
-   *   PollTestCase::_generateChoices().
-   * @param $index
-   *   (optional) The amount/number of already submitted poll choices. Defaults
-   *   to 0.
-   *
-   * @return
-   *   An indexed array containing:
-   *   - The generated POST values, suitable for
-   *     DrupalWebTestCase::drupalPost().
-   *   - The number of poll choices contained in 'edit', for potential re-usage
-   *     in subsequent invocations of this function.
-   */
-  function _pollGenerateEdit($title, array $choices, $index = 0) {
-    $max_new_choices = ($index == 0 ? 2 : 5);
-    $already_submitted_choices = array_slice($choices, 0, $index);
-    $new_choices = array_values(array_slice($choices, $index, $max_new_choices));
-
-    $edit = array(
-      'title' => $title,
-    );
-    foreach ($already_submitted_choices as $k => $text) {
-      $edit['choice[chid:' . $k . '][chtext]'] = $text;
-    }
-    foreach ($new_choices as $k => $text) {
-      $edit['choice[new:' . $k . '][chtext]'] = $text;
-      // To test poll choice weights, every new choice is sorted in front of
-      // existing choices. Existing/already submitted choices should keep their
-      // weight.
-      $edit['choice[new:' . $k . '][weight]'] = (- $index - $k);
-    }
-    return array($edit, count($already_submitted_choices) + count($new_choices));
-  }
-
-  function _generateChoices($count = 7) {
-    $choices = array();
-    for ($i = 1; $i <= $count; $i++) {
-      $choices[] = $this->randomName();
-    }
-    return $choices;
-  }
-
-  /**
-   * Assert correct poll choice order in the node form after submission.
-   *
-   * Verifies both the order in the DOM and in the 'weight' form elements.
-   *
-   * @param $choices
-   *   An array containing poll choices, as generated by
-   *   PollTestCase::_generateChoices().
-   * @param $index
-   *   (optional) The amount/number of already submitted poll choices. Defaults
-   *   to 0.
-   * @param $preview
-   *   (optional) Whether to also check the poll preview.
-   *
-   * @see PollTestCase::_pollGenerateEdit()
-   */
-  function assertPollChoiceOrder(array $choices, $index = 0, $preview = FALSE) {
-    $expected = array();
-    foreach ($choices as $id => $label) {
-      if ($id < $index) {
-        // The expected weight of each choice is exactly the negated id.
-        // @see PollTestCase::_pollGenerateEdit()
-        $weight = -$id;
-        // Directly assert the weight form element value for this choice.
-        $this->assertFieldByName('choice[chid:' . $id . '][weight]', $weight, t('Found choice @id with weight @weight.', array(
-          '@id' => $id,
-          '@weight' => $weight,
-        )));
-        // Append to our (to be reversed) stack of labels.
-        $expected[$weight] = $label;
-      }
-    }
-    ksort($expected);
-
-    // Verify DOM order of poll choices (i.e., #weight of form elements).
-    $elements = $this->xpath('//input[starts-with(@name, :prefix) and contains(@name, :suffix)]', array(
-      ':prefix' => 'choice[chid:',
-      ':suffix' => '][chtext]',
-    ));
-    $expected_order = $expected;
-    foreach ($elements as $element) {
-      $next_label = array_shift($expected_order);
-      $this->assertEqual((string) $element['value'], $next_label);
-    }
-
-    // If requested, also verify DOM order in preview.
-    if ($preview) {
-      $elements = $this->xpath('//div[contains(@class, :teaser)]/descendant::div[@class=:text]', array(
-        ':teaser' => 'node-teaser',
-        ':text' => 'text',
-      ));
-      $expected_order = $expected;
-      foreach ($elements as $element) {
-        $next_label = array_shift($expected_order);
-        $this->assertEqual((string) $element, $next_label, t('Found choice @label in preview.', array(
-          '@label' => $next_label,
-        )));
-      }
-    }
-  }
-
-  function pollUpdate($nid, $title, $edit) {
-    // Edit the poll node.
-    $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save'));
-    $this->assertText(t('@type @title has been updated.', array('@type' => node_type_get_name('poll'), '@title' => $title)), 'Poll has been updated.');
-  }
-}
-
-class PollCreateTestCase extends PollTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Poll create',
-      'description' => 'Adds "more choices", previews and creates a poll.',
-      'group' => 'Poll'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-  }
-
-  function testPollCreate() {
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(7);
-    $this->pollCreate($title, $choices, TRUE);
-
-    // Verify poll appears on 'poll' page.
-    $this->drupalGet('poll');
-    $this->assertText($title, 'Poll appears in poll list.');
-    $this->assertText('open', 'Poll is active.');
-
-    // Click on the poll title to go to node page.
-    $this->clickLink($title);
-    $this->assertText('Total votes: 0', 'Link to poll correct.');
-  }
-
-  function testPollClose() {
-    $content_user = $this->drupalCreateUser(array('create poll content', 'edit any poll content', 'access content'));
-    $vote_user = $this->drupalCreateUser(array('cancel own vote', 'inspect all votes', 'vote on polls', 'access content'));
-
-    // Create poll.
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(7);
-    $poll_nid = $this->pollCreate($title, $choices, FALSE);
-
-    $this->drupalLogout();
-    $this->drupalLogin($content_user);
-
-    // Edit the poll node and close the poll.
-    $close_edit = array('active' => 0);
-    $this->pollUpdate($poll_nid, $title, $close_edit);
-
-    // Verify 'Vote' button no longer appears.
-    $this->drupalGet('node/' . $poll_nid);
-    $elements = $this->xpath('//input[@id="edit-vote"]');
-    $this->assertTrue(empty($elements), t("Vote button doesn't appear."));
-
-    // Verify status on 'poll' page is 'closed'.
-    $this->drupalGet('poll');
-    $this->assertText($title, 'Poll appears in poll list.');
-    $this->assertText('closed', 'Poll is closed.');
-
-    // Edit the poll node and re-activate.
-    $open_edit = array('active' => 1);
-    $this->pollUpdate($poll_nid, $title, $open_edit);
-
-    // Vote on the poll.
-    $this->drupalLogout();
-    $this->drupalLogin($vote_user);
-    $vote_edit = array('choice' => '1');
-    $this->drupalPost('node/' . $poll_nid, $vote_edit, t('Vote'));
-    $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(isset($elements[0]), t("'Cancel your vote' button appears."));
-
-    // Edit the poll node and close the poll.
-    $this->drupalLogout();
-    $this->drupalLogin($content_user);
-    $close_edit = array('active' => 0);
-    $this->pollUpdate($poll_nid, $title, $close_edit);
-
-    // Verify 'Cancel your vote' button no longer appears.
-    $this->drupalGet('node/' . $poll_nid);
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(empty($elements), t("'Cancel your vote' button no longer appears."));
-  }
-}
-
-class PollVoteTestCase extends PollTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Poll vote',
-      'description' => 'Vote on a poll',
-      'group' => 'Poll'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-  }
-
-  function tearDown() {
-    parent::tearDown();
-  }
-
-  function testPollVote() {
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(7);
-    $poll_nid = $this->pollCreate($title, $choices, FALSE);
-    $this->drupalLogout();
-
-    $vote_user = $this->drupalCreateUser(array('cancel own vote', 'inspect all votes', 'vote on polls', 'access content'));
-    $restricted_vote_user = $this->drupalCreateUser(array('vote on polls', 'access content'));
-
-    $this->drupalLogin($vote_user);
-
-    // Record a vote for the first choice.
-    $edit = array(
-      'choice' => '1',
-    );
-    $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
-    $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
-    $this->assertText('Total votes: 1', 'Vote count updated correctly.');
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(isset($elements[0]), t("'Cancel your vote' button appears."));
-
-    $this->drupalGet("node/$poll_nid/votes");
-    $this->assertText(t('This table lists all the recorded votes for this poll. If anonymous users are allowed to vote, they will be identified by the IP address of the computer they used when they voted.'), 'Vote table text.');
-    $this->assertText($choices[0], 'Vote recorded');
-
-    // Ensure poll listing page has correct number of votes.
-    $this->drupalGet('poll');
-    $this->assertText($title, 'Poll appears in poll list.');
-    $this->assertText('1 vote', 'Poll has 1 vote.');
-
-    // Cancel a vote.
-    $this->drupalPost('node/' . $poll_nid, array(), t('Cancel your vote'));
-    $this->assertText('Your vote was cancelled.', 'Your vote was cancelled.');
-    $this->assertNoText('Cancel your vote', "Cancel vote button doesn't appear.");
-
-    $this->drupalGet("node/$poll_nid/votes");
-    $this->assertNoText($choices[0], 'Vote cancelled');
-
-    // Ensure poll listing page has correct number of votes.
-    $this->drupalGet('poll');
-    $this->assertText($title, 'Poll appears in poll list.');
-    $this->assertText('0 votes', 'Poll has 0 votes.');
-
-    // Log in as a user who can only vote on polls.
-    $this->drupalLogout();
-    $this->drupalLogin($restricted_vote_user);
-
-    // Vote on a poll.
-    $edit = array(
-      'choice' => '1',
-    );
-    $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
-    $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
-    $this->assertText('Total votes: 1', 'Vote count updated correctly.');
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(empty($elements), t("'Cancel your vote' button does not appear."));
-  }
-}
-
-class PollBlockTestCase extends PollTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Block availability',
-      'description' => 'Check if the most recent poll block is available.',
-      'group' => 'Poll',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-
-    // Create and login user
-    $admin_user = $this->drupalCreateUser(array('administer blocks'));
-    $this->drupalLogin($admin_user);
-  }
-
-  function testRecentBlock() {
-    // Set block title to confirm that the interface is available.
-    $this->drupalPost('admin/structure/block/manage/poll/recent/configure', array('title' => $this->randomName(8)), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
-
-    // Set the block to a region to confirm block is available.
-    $edit = array();
-    $edit['blocks[poll_recent][region]'] = 'footer';
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.'));
-
-    // Create a poll which should appear in recent polls block.
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(7);
-    $poll_nid = $this->pollCreate($title, $choices, TRUE);
-
-    // Verify poll appears in a block.
-    // View user page so we're not matching the poll node on front page.
-    $this->drupalGet('user');
-    // If a 'block' view not generated, this title would not appear even though
-    // the choices might.
-    $this->assertText($title, 'Poll appears in block.');
-
-    // Logout and login back in as a user who can vote.
-    $this->drupalLogout();
-    $vote_user = $this->drupalCreateUser(array('cancel own vote', 'inspect all votes', 'vote on polls', 'access content'));
-    $this->drupalLogin($vote_user);
-
-    // Verify we can vote via the block.
-    $edit = array(
-      'choice' => '1',
-    );
-    $this->drupalPost('user/' . $vote_user->uid, $edit, t('Vote'));
-    $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
-    $this->assertText('Total votes: 1', 'Vote count updated correctly.');
-    $this->assertText('Older polls', 'Link to older polls appears.');
-    $this->clickLink('Older polls');
-    $this->assertText('1 vote - open', 'Link to poll listing correct.');
-
-    // Close the poll and verify block doesn't appear.
-    $content_user = $this->drupalCreateUser(array('create poll content', 'edit any poll content', 'access content'));
-    $this->drupalLogout();
-    $this->drupalLogin($content_user);
-    $close_edit = array('active' => 0);
-    $this->pollUpdate($poll_nid, $title, $close_edit);
-    $this->drupalGet('user/' . $content_user->uid);
-    $this->assertNoText($title, 'Poll no longer appears in block.');
-  }
-}
-
-/**
- * Test adding new choices.
- */
-class PollJSAddChoice extends DrupalWebTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Poll add choice',
-      'description' => 'Submits a POST request for an additional poll choice.',
-      'group' => 'Poll'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-  }
-
-  /**
-   * Test adding a new choice.
-   */
-  function testAddChoice() {
-    $web_user = $this->drupalCreateUser(array('create poll content', 'access content'));
-    $this->drupalLogin($web_user);
-    $this->drupalGet('node/add/poll');
-    $edit = array(
-      "title" => $this->randomName(),
-      'choice[new:0][chtext]' => $this->randomName(),
-      'choice[new:1][chtext]' => $this->randomName(),
-    );
-
-    // Press 'add choice' button through Ajax, and place the expected HTML result
-    // as the tested content.
-    $commands = $this->drupalPostAJAX(NULL, $edit, array('op' => t('More choices')));
-    $this->content = $commands[1]['data'];
-
-    $this->assertFieldByName('choice[chid:0][chtext]', $edit['choice[new:0][chtext]'], t('Field !i found', array('!i' => 0)));
-    $this->assertFieldByName('choice[chid:1][chtext]', $edit['choice[new:1][chtext]'], t('Field !i found', array('!i' => 1)));
-    $this->assertFieldByName('choice[new:0][chtext]', '', t('Field !i found', array('!i' => 2)));
-  }
-}
-
-class PollVoteCheckHostname extends PollTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'User poll vote capability.',
-      'description' => 'Check that users and anonymous users from specified ip-address can only vote once.',
-      'group' => 'Poll'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-
-    // Create and login user.
-    $this->admin_user = $this->drupalCreateUser(array('administer permissions', 'create poll content'));
-    $this->drupalLogin($this->admin_user);
-
-    // Allow anonymous users to vote on polls.
-    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
-      'access content' => TRUE,
-      'vote on polls' => TRUE,
-      'cancel own vote' => TRUE,
-    ));
-
-    // Enable page cache to verify that the result page is not saved in the
-    // cache when anonymous voting is allowed.
-    variable_set('cache', 1);
-
-    // Create poll.
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(3);
-    $this->poll_nid = $this->pollCreate($title, $choices, FALSE);
-
-    $this->drupalLogout();
-
-    // Create web users.
-    $this->web_user1 = $this->drupalCreateUser(array('access content', 'vote on polls', 'cancel own vote'));
-    $this->web_user2 = $this->drupalCreateUser(array('access content', 'vote on polls'));
-  }
-
-  /**
-   * Check that anonymous users with same ip cannot vote on poll more than once
-   * unless user is logged in.
-   */
-  function testHostnamePollVote() {
-    // Login User1.
-    $this->drupalLogin($this->web_user1);
-
-    $edit = array(
-      'choice' => '1',
-    );
-
-    // User1 vote on Poll.
-    $this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
-    $this->assertText(t('Your vote was recorded.'), t('%user vote was recorded.', array('%user' => $this->web_user1->name)));
-    $this->assertText(t('Total votes: @votes', array('@votes' => 1)), t('Vote count updated correctly.'));
-
-    // Check to make sure User1 cannot vote again.
-    $this->drupalGet('node/' . $this->poll_nid);
-    $elements = $this->xpath('//input[@value="Vote"]');
-    $this->assertTrue(empty($elements), t("%user is not able to vote again.", array('%user' => $this->web_user1->name)));
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
-
-    // Logout User1.
-    $this->drupalLogout();
-
-    // Fill the page cache by requesting the poll.
-    $this->drupalGet('node/' . $this->poll_nid);
-    $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', t('Page was cacheable but was not in the cache.'));
-    $this->drupalGet('node/' . $this->poll_nid);
-    $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'HIT', t('Page was cached.'));
-
-    // Anonymous user vote on Poll.
-    $this->drupalPost(NULL, $edit, t('Vote'));
-    $this->assertText(t('Your vote was recorded.'), t('Anonymous vote was recorded.'));
-    $this->assertText(t('Total votes: @votes', array('@votes' => 2)), t('Vote count updated correctly.'));
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
-
-    // Check to make sure Anonymous user cannot vote again.
-    $this->drupalGet('node/' . $this->poll_nid);
-    $this->assertFalse($this->drupalGetHeader('x-drupal-cache'), t('Page was not cacheable.'));
-    $elements = $this->xpath('//input[@value="Vote"]');
-    $this->assertTrue(empty($elements), t("Anonymous is not able to vote again."));
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
-
-    // Login User2.
-    $this->drupalLogin($this->web_user2);
-
-    // User2 vote on poll.
-    $this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
-    $this->assertText(t('Your vote was recorded.'), t('%user vote was recorded.', array('%user' => $this->web_user2->name)));
-    $this->assertText(t('Total votes: @votes', array('@votes' => 3)), 'Vote count updated correctly.');
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(empty($elements), t("'Cancel your vote' button does not appear."));
-
-    // Logout User2.
-    $this->drupalLogout();
-
-    // Change host name for anonymous users.
-    db_update('poll_vote')
-      ->fields(array(
-        'hostname' => '123.456.789.1',
-      ))
-      ->condition('hostname', '', '<>')
-      ->execute();
-
-    // Check to make sure Anonymous user can vote again with a new session after
-    // a hostname change.
-    $this->drupalGet('node/' . $this->poll_nid);
-    $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', t('Page was cacheable but was not in the cache.'));
-    $this->drupalPost(NULL, $edit, t('Vote'));
-    $this->assertText(t('Your vote was recorded.'), t('%user vote was recorded.', array('%user' => $this->web_user2->name)));
-    $this->assertText(t('Total votes: @votes', array('@votes' => 4)), 'Vote count updated correctly.');
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
-
-    // Check to make sure Anonymous user cannot vote again with a new session,
-    // and that the vote from the previous session cannot be cancelledd.
-    $this->curlClose();
-    $this->drupalGet('node/' . $this->poll_nid);
-    $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', t('Page was cacheable but was not in the cache.'));
-    $elements = $this->xpath('//input[@value="Vote"]');
-    $this->assertTrue(empty($elements), t('Anonymous is not able to vote again.'));
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(empty($elements), t("'Cancel your vote' button does not appear."));
-
-    // Login User1.
-    $this->drupalLogin($this->web_user1);
-
-    // Check to make sure User1 still cannot vote even after hostname changed.
-    $this->drupalGet('node/' . $this->poll_nid);
-    $elements = $this->xpath('//input[@value="Vote"]');
-    $this->assertTrue(empty($elements), t("%user is not able to vote again.", array('%user' => $this->web_user1->name)));
-    $elements = $this->xpath('//input[@value="Cancel your vote"]');
-    $this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
-  }
-}
-
-/**
- * Test poll token replacement in strings.
- */
-class PollTokenReplaceTestCase extends PollTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Poll token replacement',
-      'description' => 'Generates text using placeholders for dummy content to check poll token replacement.',
-      'group' => 'Poll',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-  }
-
-  /**
-   * Creates a poll, then tests the tokens generated from it.
-   */
-  function testPollTokenReplacement() {
-    global $language;
-
-    // Craete a poll with three choices.
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(3);
-    $poll_nid = $this->pollCreate($title, $choices, FALSE);
-    $this->drupalLogout();
-
-    // Create four users and have each of them vote.
-    $vote_user1 = $this->drupalCreateUser(array('vote on polls', 'access content'));
-    $this->drupalLogin($vote_user1);
-    $edit = array(
-      'choice' => '1',
-    );
-    $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
-    $this->drupalLogout();
-
-    $vote_user2 = $this->drupalCreateUser(array('vote on polls', 'access content'));
-    $this->drupalLogin($vote_user2);
-    $edit = array(
-      'choice' => '1',
-    );
-    $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
-    $this->drupalLogout();
-
-    $vote_user3 = $this->drupalCreateUser(array('vote on polls', 'access content'));
-    $this->drupalLogin($vote_user3);
-    $edit = array(
-      'choice' => '2',
-    );
-    $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
-    $this->drupalLogout();
-
-    $vote_user4 = $this->drupalCreateUser(array('vote on polls', 'access content'));
-    $this->drupalLogin($vote_user4);
-    $edit = array(
-      'choice' => '3',
-    );
-    $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
-    $this->drupalLogout();
-
-    $poll = node_load($poll_nid, NULL, TRUE);
-
-    // Generate and test sanitized tokens.
-    $tests = array();
-    $tests['[node:poll-votes]'] = 4;
-    $tests['[node:poll-winner]'] = filter_xss($poll->choice[1]['chtext']);
-    $tests['[node:poll-winner-votes]'] = 2;
-    $tests['[node:poll-winner-percent]'] = 50;
-    $tests['[node:poll-duration]'] = format_interval($poll->runtime, 1, $language->language);
-
-    // Test to make sure that we generated something for each token.
-    $this->assertFalse(in_array(0, array_map('strlen', $tests)), t('No empty tokens generated.'));
-
-    foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $poll), array('language' => $language));
-      $this->assertEqual($output, $expected, t('Sanitized poll token %token replaced.', array('%token' => $input)));
-    }
-
-    // Generate and test unsanitized tokens.
-    $tests['[node:poll-winner]'] = $poll->choice[1]['chtext'];
-
-    foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $poll), array('language' => $language, 'sanitize' => FALSE));
-      $this->assertEqual($output, $expected, t('Unsanitized poll token %token replaced.', array('%token' => $input)));
-    }
-  }
-}
-
-class PollExpirationTestCase extends PollTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Poll expiration',
-      'description' => 'Test the poll auto-expiration logic.',
-      'group' => 'Poll',
-    );
-  }
-
-  function setUp() {
-    parent::setUp('poll');
-  }
-
-  function testAutoExpire() {
-    // Set up a poll.
-    $title = $this->randomName();
-    $choices = $this->_generateChoices(2);
-    $poll_nid = $this->pollCreate($title, $choices, FALSE);
-    $this->assertTrue($poll_nid, t('Poll for auto-expire test created.'));
-
-    // Visit the poll edit page and verify that by default, expiration
-    // is set to unlimited.
-    $this->drupalGet("node/$poll_nid/edit");
-    $this->assertField('runtime', t('Poll expiration setting found.'));
-    $elements = $this->xpath('//select[@id="edit-runtime"]/option[@selected="selected"]');
-    $this->assertTrue(isset($elements[0]['value']) && $elements[0]['value'] == 0, t('Poll expiration set to unlimited.'));
-
-    // Set the expiration to one week.
-    $edit = array();
-    $poll_expiration = 604800; // One week.
-    $edit['runtime'] = $poll_expiration;
-    $this->drupalPost(NULL, $edit, t('Save'));
-    $this->assertRaw(t('Poll %title has been updated.', array('%title' => $title)), t('Poll expiration settings saved.'));
-
-    // Make sure that the changed expiration settings is kept.
-    $this->drupalGet("node/$poll_nid/edit");
-    $elements = $this->xpath('//select[@id="edit-runtime"]/option[@selected="selected"]');
-    $this->assertTrue(isset($elements[0]['value']) && $elements[0]['value'] == $poll_expiration, t('Poll expiration set to unlimited.'));
-
-    // Force a cron run. Since the expiration date has not yet been reached,
-    // the poll should remain active.
-    drupal_cron_run();
-    $this->drupalGet("node/$poll_nid/edit");
-    $elements = $this->xpath('//input[@id="edit-active-1"]');
-    $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), t('Poll is still active.'));
-
-    // Test expiration. Since REQUEST_TIME is a constant and we don't
-    // want to keep SimpleTest waiting until the moment of expiration arrives,
-    // we forcibly change the expiration date in the database.
-    $created = db_query('SELECT created FROM {node} WHERE nid = :nid', array(':nid' => $poll_nid))->fetchField();
-    db_update('node')
-      ->fields(array('created' => $created - ($poll_expiration * 1.01)))
-      ->condition('nid', $poll_nid)
-      ->execute();
-
-    // Run cron and verify that the poll is now marked as "closed".
-    drupal_cron_run();
-    $this->drupalGet("node/$poll_nid/edit");
-    $elements = $this->xpath('//input[@id="edit-active-0"]');
-    $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), t('Poll has expired.'));
-  }
-}
diff --git a/modules/poll/poll.tokens.inc b/modules/poll/poll.tokens.inc
deleted file mode 100644
index eda628b..0000000
--- a/modules/poll/poll.tokens.inc
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-
-/**
- * @file
- * Builds placeholder replacement tokens for values specific to Poll nodes.
- */
-
-/**
- * Implements hook_token_info().
- */
-function poll_token_info() {
-  $node['poll-votes'] = array(
-    'name' => t("Poll votes"),
-    'description' => t("The number of votes that have been cast on a poll."),
-  );
-  $node['poll-winner'] = array(
-    'name' => t("Poll winner"),
-    'description' => t("The winning poll answer."),
-  );
-  $node['poll-winner-votes'] = array(
-    'name' => t("Poll winner votes"),
-    'description' => t("The number of votes received by the winning poll answer."),
-  );
-  $node['poll-winner-percent'] = array(
-    'name' => t("Poll winner percent"),
-    'description' => t("The percentage of votes received by the winning poll answer."),
-  );
-  $node['poll-duration'] = array(
-    'name' => t("Poll duration"),
-    'description' => t("The length of time the poll is set to run."),
-  );
-
-  return array(
-    'tokens' => array('node' => $node),
-  );
-}
-
-/**
- * Implements hook_tokens().
- */
-function poll_tokens($type, $tokens, array $data = array(), array $options = array()) {
-  $sanitize = !empty($options['sanitize']);
-  if (isset($options['language'])) {
-    $url_options['language'] = $options['language'];
-    $language_code = $options['language']->language;
-  }
-  else {
-    $language_code = NULL;
-  }
-
-  $replacements = array();
-
-  if ($type == 'node' && !empty($data['node']) && $data['node']->type == 'poll') {
-    $node = $data['node'];
-
-    $total_votes = 0;
-    $highest_votes = 0;
-    foreach ($node->choice as $choice) {
-      if ($choice['chvotes'] > $highest_votes) {
-        $winner = $choice;
-        $highest_votes = $choice['chvotes'];
-      }
-      $total_votes = $total_votes + $choice['chvotes'];
-    }
-    foreach ($tokens as $name => $original) {
-      switch ($name) {
-        case 'poll-votes':
-          $replacements[$original] = $total_votes;
-          break;
-
-        case 'poll-winner':
-          if (isset($winner)) {
-            $replacements[$original] = $sanitize ? filter_xss($winner['chtext']) : $winner['chtext'];
-          }
-          else {
-            $replacements[$original] = '';
-          }
-          break;
-
-        case 'poll-winner-votes':
-          if (isset($winner)) {
-            $replacements[$original] = $winner['chvotes'];
-          }
-          else {
-            $replacements[$original] = '';
-          }
-          break;
-
-        case 'poll-winner-percent':
-          if (isset($winner)) {
-            $percent = ($winner['chvotes'] / $total_votes) * 100;
-            $replacements[$original] = number_format($percent, 0);
-          }
-          else {
-            $replacements[$original] = '';
-          }
-          break;
-
-        case 'poll-duration':
-          $replacements[$original] = format_interval($node->runtime, 1, $language_code);
-          break;
-      }
-    }
-  }
-
-  return $replacements;
-}
diff --git a/modules/profile/profile-block.tpl.php b/modules/profile/profile-block.tpl.php
deleted file mode 100644
index 0bd8331..0000000
--- a/modules/profile/profile-block.tpl.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for displaying a users profile within a
- * block. It only shows in relation to a node displayed as a full page.
- *
- * Available variables:
- * - $user_picture: Image configured for the account linking to the users page.
- * - $profile: Keyed array of all profile fields that have a value.
- *
- * Each $field in $profile contains:
- * - $field->title: Title of the profile field.
- * - $field->value: Value of the profile field.
- * - $field->type: Type of the profile field, i.e., checkbox, textfield,
- *   textarea, selection, list, url or date.
- *
- * Since $profile is keyed, a direct print of the field is possible. Not
- * all accounts may have a value for a profile so do a check first. If a field
- * of "last_name" was set for the site, the following can be used.
- *
- *  <?php if (isset($profile['last_name'])): ?>
- *    <div class="field last-name">
- *      <?php print $profile['last_name']->title; ?>:<br />
- *      <?php print $profile['last_name']->value; ?>
- *    </div>
- *  <?php endif; ?>
- *
- * @see template_preprocess_profile_block()
- */
-?>
-<?php print $user_picture; ?>
-
-<?php foreach ($profile as $field) : ?>
-  <p>
-    <?php if ($field->type != 'checkbox') : ?>
-      <strong><?php print $field->title; ?></strong><br />
-    <?php endif; ?>
-    <?php print $field->value; ?>
-  </p>
-<?php endforeach; ?>
diff --git a/modules/profile/profile-listing.tpl.php b/modules/profile/profile-listing.tpl.php
deleted file mode 100644
index d484ed2..0000000
--- a/modules/profile/profile-listing.tpl.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for displaying a user and their profile data
- * for member listing pages.
- *
- * @see profile-wrapper.tpl.php
- *      where all the data is collected and printed out.
- *
- * Available variables:
- * - $account: User's account object.
- * - $user_picture: Image configured for the account linking to the users page.
- * - $name: User's account name linking to the users page.
- * - $profile: Keyed array of all profile fields that are set as visible
- *   in member list pages (configured by site administrators). It also needs
- *   to have a value in order to be present.
- *
- * Each $field in $profile contains:
- * - $field->title: Title of the profile field.
- * - $field->value: Value of the profile field.
- * - $field->type: Type of the profile field, i.e., checkbox, textfield,
- *   textarea, selection, list, url or date.
- *
- * Since $profile is keyed, a direct print of the field is possible. Not
- * all accounts may have a value for a profile so do a check first. If a field
- * of "last_name" was set for the site, the following can be used.
- *
- *  <?php if (isset($profile['last_name'])): ?>
- *    <div class="field last-name">
- *      <?php print $profile['last_name']->title; ?>:<br />
- *      <?php print $profile['last_name']->value; ?>
- *    </div>
- *  <?php endif; ?>
- *
- * @see template_preprocess_profile_listing()
- */
-?>
-<div class="profile clearfix">
-  <?php print $user_picture; ?>
-
-  <div class="name">
-    <?php print $name; ?>
-  </div>
-
-  <?php foreach ($profile as $field) : ?>
-    <div class="field">
-      <?php print $field->value; ?>
-    </div>
-  <?php endforeach; ?>
-
-</div>
diff --git a/modules/profile/profile-wrapper.tpl.php b/modules/profile/profile-wrapper.tpl.php
deleted file mode 100644
index 997ab98..0000000
--- a/modules/profile/profile-wrapper.tpl.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Default theme implementation for wrapping member listings and their
- * profiles.
- *
- * This template is used when viewing a list of users. It can be a general
- * list for viewing all users with the url of "example.com/profile" or when
- * viewing a set of users who share a specific value for a profile such
- * as "example.com/profile/country/belgium".
- *
- * Available variables:
- * - $content: User account profiles iterated through profile-listing.tpl.php.
- * - $current_field: The named field being browsed. Provided here for context.
- *   The above example would result in "last_name". An alternate template name
- *   is also based on this, e.g., "profile-wrapper-last_name.tpl.php".
- *
- * @see template_preprocess_profile_wrapper()
- */
-?>
-<div id="profile">
-  <?php print $content; ?>
-</div>
diff --git a/modules/profile/profile.admin.inc b/modules/profile/profile.admin.inc
deleted file mode 100644
index d6ac3c3..0000000
--- a/modules/profile/profile.admin.inc
+++ /dev/null
@@ -1,446 +0,0 @@
-<?php
-
-/**
- * @file
- * Administrative page callbacks for the profile module.
- */
-
-/**
- * Form builder to display a listing of all editable profile fields.
- *
- * @ingroup forms
- * @see profile_admin_overview_submit()
- */
-function profile_admin_overview($form) {
-  $result = db_query('SELECT title, name, type, category, fid, weight FROM {profile_field} ORDER BY category, weight');
-
-  $categories = array();
-  foreach ($result as $field) {
-    // Collect all category information
-    $categories[] = $field->category;
-
-    // Save all field information
-    $form[$field->fid]['name'] = array('#markup' => check_plain($field->name));
-    $form[$field->fid]['title'] = array('#markup' => check_plain($field->title));
-    $form[$field->fid]['type'] = array('#markup' => $field->type);
-    $form[$field->fid]['category'] = array(
-      '#type' => 'select',
-      '#title' => t('Category for @title', array('@title' => $field->title)),
-      '#title_display' => 'invisible',
-      '#default_value' => $field->category,
-      '#options' => array(),
-    );
-    $form[$field->fid]['weight'] = array(
-      '#type' => 'weight',
-      '#title' => t('Weight for @title', array('@title' => $field->title)),
-      '#title_display' => 'invisible',
-      '#default_value' => $field->weight,
-    );
-    $form[$field->fid]['edit'] = array('#type' => 'link', '#title' => t('edit'), '#href' => "admin/config/people/profile/edit/$field->fid");
-    $form[$field->fid]['delete'] = array('#type' => 'link', '#title' => t('delete'), '#href' => "admin/config/people/profile/delete/$field->fid");
-  }
-
-  // Add the category combo boxes
-  $categories = array_unique($categories);
-  foreach ($form as $fid => $field) {
-    foreach ($categories as $cat => $category) {
-      $form[$fid]['category']['#options'][$category] = $category;
-    }
-  }
-
-  // Display the submit button only when there's more than one field
-  if (count($form) > 1) {
-    $form['actions'] = array('#type' => 'actions');
-    $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
-  }
-  else {
-    // Disable combo boxes when there isn't a submit button
-    foreach ($form as $fid => $field) {
-      unset($form[$fid]['weight']);
-      $form[$fid]['category']['#type'] = 'value';
-    }
-  }
-  $form['#tree'] = TRUE;
-
-  // @todo: Any reason this isn't done using an element with #theme = 'links'?
-  $addnewfields = '<h2>' . t('Add new field') . '</h2>';
-  $addnewfields .= '<ul>';
-  foreach (_profile_field_types() as $key => $value) {
-    $addnewfields .= '<li>' . l($value, "admin/config/people/profile/add/$key") . '</li>';
-  }
-  $addnewfields .= '</ul>';
-  $form['addnewfields'] = array('#markup' => $addnewfields);
-
-  return $form;
-}
-
-/**
- * Submit handler to update changed profile field weights and categories.
- *
- * @see profile_admin_overview()
- */
-function profile_admin_overview_submit($form, &$form_state) {
-  foreach (element_children($form_state['values']) as $fid) {
-    if (is_numeric($fid)) {
-      $weight = $form_state['values'][$fid]['weight'];
-      $category = $form_state['values'][$fid]['category'];
-      if ($weight != $form[$fid]['weight']['#default_value'] || $category != $form[$fid]['category']['#default_value']) {
-        db_update('profile_field')
-          ->fields(array(
-            'weight' => $weight,
-            'category' => $category,
-          ))
-          ->condition('fid', $fid)
-          ->execute();
-      }
-    }
-  }
-
-  drupal_set_message(t('Profile fields have been updated.'));
-  cache_clear_all();
-  menu_rebuild();
-}
-
-/**
- * Returns HTML for the profile field overview form into a drag and drop enabled table.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @see profile_admin_overview()
- * @ingroup themeable
- */
-function theme_profile_admin_overview($variables) {
-  $form = $variables['form'];
-
-  drupal_add_css(drupal_get_path('module', 'profile') . '/profile.css');
-  // Add javascript if there's more than one field.
-  if (isset($form['actions'])) {
-    drupal_add_js(drupal_get_path('module', 'profile') . '/profile.js');
-  }
-
-  $rows = array();
-  $categories = array();
-  $category_number = 0;
-  foreach (element_children($form) as $key) {
-    // Don't take form control structures.
-    if (isset($form[$key]['category'])) {
-      $field = &$form[$key];
-      $category = $field['category']['#default_value'];
-
-      if (!isset($categories[$category])) {
-        // Category classes are given numeric IDs because there's no guarantee
-        // class names won't contain invalid characters.
-        $categories[$category] = $category_number;
-        $category_field['#attributes']['class'] = array('profile-category', 'profile-category-' . $category_number);
-        $rows[] = array(array('data' => check_plain($category), 'colspan' => 7, 'class' => array('category')));
-        $rows[] = array('data' => array(array('data' => '<em>' . t('No fields in this category. If this category remains empty when saved, it will be removed.') . '</em>', 'colspan' => 7)), 'class' => array('category-' . $category_number . '-message', 'category-message', 'category-populated'));
-
-        // Make it draggable only if there is more than one field
-        if (isset($form['actions'])) {
-          drupal_add_tabledrag('profile-fields', 'order', 'sibling', 'profile-weight', 'profile-weight-' . $category_number);
-          drupal_add_tabledrag('profile-fields', 'match', 'sibling', 'profile-category', 'profile-category-' . $category_number);
-        }
-        $category_number++;
-      }
-
-      // Add special drag and drop classes that group fields together.
-      $field['weight']['#attributes']['class'] = array('profile-weight', 'profile-weight-' . $categories[$category]);
-      $field['category']['#attributes']['class'] = array('profile-category', 'profile-category-' . $categories[$category]);
-
-      // Add the row
-      $row = array();
-      $row[] = drupal_render($field['title']);
-      $row[] = drupal_render($field['name']);
-      $row[] = drupal_render($field['type']);
-      if (isset($form['actions'])) {
-        $row[] = drupal_render($field['category']);
-        $row[] = drupal_render($field['weight']);
-      }
-      $row[] = drupal_render($field['edit']);
-      $row[] = drupal_render($field['delete']);
-      $rows[] = array('data' => $row, 'class' => array('draggable'));
-    }
-  }
-
-  $header = array(t('Title'), t('Name'), t('Type'));
-  if (isset($form['actions'])) {
-    $header[] = t('Category');
-    $header[] = t('Weight');
-  }
-  $header[] = array('data' => t('Operations'), 'colspan' => 2);
-
-  $output = theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No fields available.'), 'attributes' => array('id' => 'profile-fields')));
-  $output .= drupal_render_children($form);
-
-  return $output;
-}
-
-/**
- * Menu callback: Generate a form to add/edit a user profile field.
- *
- * @ingroup forms
- * @see profile_field_form_validate()
- * @see profile_field_form_submit()
- */
-function profile_field_form($form, &$form_state, $arg = NULL) {
-  if (arg(4) == 'edit') {
-    if (is_numeric($arg)) {
-      $fid = $arg;
-
-      $edit = db_query('SELECT * FROM {profile_field} WHERE fid = :fid', array('fid' => $fid))->fetchAssoc();
-
-      if (!$edit) {
-        drupal_not_found();
-        return;
-      }
-      drupal_set_title(t('Edit %title', array('%title' => $edit['title'])), PASS_THROUGH);
-      $form['fid'] = array('#type' => 'value',
-        '#value' => $fid,
-      );
-      $type = $edit['type'];
-    }
-    else {
-      drupal_not_found();
-      return;
-    }
-  }
-  else {
-    $types = _profile_field_types();
-    if (!isset($types[$arg])) {
-      drupal_not_found();
-      return;
-    }
-    $type = $arg;
-    drupal_set_title(t('Add new %type', array('%type' => $types[$type])), PASS_THROUGH);
-    $edit = array('name' => 'profile_');
-    $form['type'] = array('#type' => 'value', '#value' => $type);
-  }
-  $edit += array(
-    'category' => '',
-    'title' => '',
-    'explanation' => '',
-    'weight' => 0,
-    'page' => '',
-    'autocomplete' => '',
-    'required' => '',
-    'register' => '',
-  );
-  $form['category'] = array('#type' => 'textfield',
-    '#title' => t('Category'),
-    '#default_value' => $edit['category'],
-    '#autocomplete_path' => 'admin/config/people/profile/autocomplete',
-    '#description' => t('The category the new field should be part of. Categories are used to group fields logically. An example category is "Personal information".'),
-    '#required' => TRUE,
-  );
-  $form['title'] = array('#type' => 'textfield',
-    '#title' => t('Title'),
-    '#default_value' => $edit['title'],
-    '#description' => t('The title of the new field. The title will be shown to the user. An example title is "Favorite color".'),
-    '#required' => TRUE,
-  );
-  $form['name'] = array('#type' => 'textfield',
-    '#title' => t('Form name'),
-    '#default_value' => $edit['name'],
-    '#description' => t('The name of the field. The form name is not shown to the user but used internally in the HTML code and URLs.
-Unless you know what you are doing, it is highly recommended that you prefix the form name with <code>profile_</code> to avoid name clashes with other fields. Spaces or any other special characters except dash (-) and underscore (_) are not allowed. An example name is "profile_favorite_color" or perhaps just "profile_color".'),
-    '#required' => TRUE,
-  );
-  $form['explanation'] = array('#type' => 'textarea',
-    '#title' => t('Explanation'),
-    '#default_value' => $edit['explanation'],
-    '#description' => t('An optional explanation to go with the new field. The explanation will be shown to the user.'),
-  );
-  if ($type == 'selection') {
-    $form['fields']['options'] = array('#type' => 'textarea',
-      '#title' => t('Selection options'),
-      '#default_value' => isset($edit['options']) ? $edit['options'] : '',
-      '#description' => t('A list of all options. Put each option on a separate line. Example options are "red", "blue", "green", etc.'),
-    );
-  }
-  $form['visibility'] = array('#type' => 'radios',
-    '#title' => t('Visibility'),
-    '#default_value' => isset($edit['visibility']) ? $edit['visibility'] : PROFILE_PUBLIC,
-    '#options' => array(PROFILE_HIDDEN => t('Hidden profile field, only accessible by administrators, modules and themes.'), PROFILE_PRIVATE => t('Private field, content only available to privileged users.'), PROFILE_PUBLIC => t('Public field, content shown on profile page but not used on member list pages.'), PROFILE_PUBLIC_LISTINGS => t('Public field, content shown on profile page and on member list pages.')),
-  );
-  if ($type == 'selection' || $type == 'list' || $type == 'textfield') {
-    $form['fields']['page'] = array('#type' => 'textfield',
-      '#title' => t('Page title'),
-      '#default_value' => $edit['page'],
-      '#description' => t('To enable browsing this field by value, enter a title for the resulting page. The word <code>%value</code> will be substituted with the corresponding value. An example page title is "People whose favorite color is %value" . This is only applicable for a public field.'),
-    );
-  }
-  elseif ($type == 'checkbox') {
-    $form['fields']['page'] = array('#type' => 'textfield',
-      '#title' => t('Page title'),
-      '#default_value' => $edit['page'],
-      '#description' => t('To enable browsing this field by value, enter a title for the resulting page. An example page title is "People who are employed" . This is only applicable for a public field.'),
-    );
-  }
-  $form['weight'] = array('#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
-    '#description' => t('The weights define the order in which the form fields are shown. Lighter fields "float up" towards the top of the category.'),
-  );
-  $form['autocomplete'] = array('#type' => 'checkbox',
-    '#title' => t('Form will auto-complete while user is typing.'),
-    '#default_value' => $edit['autocomplete'],
-    '#description' => t('For security, auto-complete will be disabled if the user does not have access to user profiles.'),
-  );
-  $form['required'] = array('#type' => 'checkbox',
-    '#title' => t('The user must enter a value.'),
-    '#default_value' => $edit['required'],
-  );
-  $form['register'] = array('#type' => 'checkbox',
-    '#title' => t('Visible in user registration form.'),
-    '#default_value' => $edit['register'],
-  );
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array('#type' => 'submit',
-    '#value' => t('Save field'),
-  );
-  return $form;
-}
-
-/**
- * Validate profile_field_form submissions.
- */
-function profile_field_form_validate($form, &$form_state) {
-  // Validate the 'field name':
-  if (preg_match('/[^a-zA-Z0-9_-]/', $form_state['values']['name'])) {
-    form_set_error('name', t('The specified form name contains one or more illegal characters. Spaces or any other special characters except dash (-) and underscore (_) are not allowed.'));
-  }
-
-  $users_table = drupal_get_schema('users');
-  if (!empty($users_table['fields'][$form_state['values']['name']])) {
-    form_set_error('name', t('The specified form name is reserved for use by Drupal.'));
-  }
-  // Validate the category:
-  if (!$form_state['values']['category']) {
-    form_set_error('category', t('You must enter a category.'));
-  }
-  if (strtolower($form_state['values']['category']) == 'account') {
-    form_set_error('category', t('The specified category name is reserved for use by Drupal.'));
-  }
-  $query = db_select('profile_field');
-  $query->fields('profile_field', array('fid'));
-
-  if (isset($form_state['values']['fid'])) {
-    $query->condition('fid', $form_state['values']['fid'], '<>');
-  }
-  $query_name = clone $query;
-
-  $title = $query
-    ->condition('title', $form_state['values']['title'])
-    ->condition('category', $form_state['values']['category'])
-    ->execute()
-    ->fetchField();
-  if ($title) {
-    form_set_error('title', t('The specified title is already in use.'));
-  }
-  $name = $query_name
-    ->condition('name', $form_state['values']['name'])
-    ->execute()
-    ->fetchField();
-  if ($name) {
-    form_set_error('name', t('The specified name is already in use.'));
-  }
-  if ($form_state['values']['visibility'] == PROFILE_HIDDEN) {
-    if ($form_state['values']['required']) {
-      form_set_error('required', t('A hidden field cannot be required.'));
-    }
-    if ($form_state['values']['register']) {
-      form_set_error('register', t('A hidden field cannot be set to visible on the user registration form.'));
-    }
-  }
-}
-
-/**
- * Process profile_field_form submissions.
- */
-function profile_field_form_submit($form, &$form_state) {
-  if (!isset($form_state['values']['options'])) {
-    $form_state['values']['options'] = '';
-  }
-  if (!isset($form_state['values']['page'])) {
-    $form_state['values']['page'] = '';
-  }
-  // Remove all elements that are not profile_field columns.
-  $values = array_intersect_key($form_state['values'], array_flip(array('type', 'category', 'title', 'name', 'explanation', 'visibility', 'page', 'weight', 'autocomplete', 'required', 'register', 'options')));
-  if (!isset($form_state['values']['fid'])) {
-    db_insert('profile_field')
-      ->fields($values)
-      ->execute();
-    drupal_set_message(t('The field has been created.'));
-    watchdog('profile', 'Profile field %field added under category %category.', array('%field' => $form_state['values']['title'], '%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/people/profile'));
-  }
-  else {
-    db_update('profile_field')
-      ->fields($values)
-      ->condition('fid', $form_state['values']['fid'])
-      ->execute();
-    drupal_set_message(t('The field has been updated.'));
-  }
-  cache_clear_all();
-  menu_rebuild();
-
-  $form_state['redirect'] = 'admin/config/people/profile';
-  return;
-}
-
-/**
- * Menu callback; deletes a field from all user profiles.
- */
-function profile_field_delete($form, &$form_state, $fid) {
-  $field = db_query("SELECT title FROM {profile_field} WHERE fid = :fid", array(':fid' => $fid))->fetchObject();
-  if (!$field) {
-    drupal_not_found();
-    return;
-  }
-  $form['fid'] = array('#type' => 'value', '#value' => $fid);
-  $form['title'] = array('#type' => 'value', '#value' => $field->title);
-
-  return confirm_form($form,
-    t('Are you sure you want to delete the field %field?', array('%field' => $field->title)), 'admin/config/people/profile',
-    t('This action cannot be undone. If users have entered values into this field in their profile, these entries will also be deleted. If you want to keep the user-entered data, instead of deleting the field you may wish to <a href="@edit-field">edit this field</a> and change it to a hidden profile field so that it may only be accessed by administrators.', array('@edit-field' => url('admin/config/people/profile/edit/' . $fid))),
-    t('Delete'), t('Cancel'));
-}
-
-/**
- * Process a field delete form submission.
- */
-function profile_field_delete_submit($form, &$form_state) {
-  db_delete('profile_field')
-    ->condition('fid', $form_state['values']['fid'])
-    ->execute();
-  db_delete('profile_value')
-    ->condition('fid', $form_state['values']['fid'])
-    ->execute();
-
-  cache_clear_all();
-
-  drupal_set_message(t('The field %field has been deleted.', array('%field' => $form_state['values']['title'])));
-  watchdog('profile', 'Profile field %field deleted.', array('%field' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/people/profile'));
-
-  $form_state['redirect'] = 'admin/config/people/profile';
-  return;
-}
-
-/**
- * Retrieve a pipe delimited string of autocomplete suggestions for profile categories
- */
-function profile_admin_settings_autocomplete($string) {
-  $matches = array();
-  $result = db_select('profile_field')
-    ->fields('profile_field', array('category'))
-    ->condition('category', db_like($string) . '%', 'LIKE')
-    ->range(0, 10)
-    ->execute();
-
-  foreach ($result as $data) {
-    $matches[$data->category] = check_plain($data->category);
-  }
-  drupal_json_output($matches);
-}
diff --git a/modules/profile/profile.css b/modules/profile/profile.css
deleted file mode 100644
index c3132f9..0000000
--- a/modules/profile/profile.css
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#profile-fields td.category {
-  font-weight: bold;
-}
-#profile-fields tr.category-message {
-  color: #999;
-}
-#profile-fields tr.category-populated {
-  display: none;
-}
diff --git a/modules/profile/profile.info b/modules/profile/profile.info
deleted file mode 100644
index f4c8699..0000000
--- a/modules/profile/profile.info
+++ /dev/null
@@ -1,12 +0,0 @@
-name = Profile
-description = Supports configurable user profiles.
-package = Core
-version = VERSION
-core = 8.x
-files[] = profile.test
-configure = admin/config/people/profile
-; The Profile module is deprecated, and included in Drupal 7 for legacy
-; purposes only. By default, the module will be hidden from the UI unless you
-; are upgrading a site that uses the Profile module to extend user profiles.
-; See user_system_info_alter().
-hidden = TRUE
diff --git a/modules/profile/profile.install b/modules/profile/profile.install
deleted file mode 100644
index c5747cf..0000000
--- a/modules/profile/profile.install
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the profile module.
- */
-
-/**
- * Implements hook_uninstall().
- */
-function profile_uninstall() {
-  variable_del('profile_block_author_fields');
-}
-
-/**
- * Implements hook_schema().
- */
-function profile_schema() {
-  $schema['profile_field'] = array(
-    'description' => 'Stores profile field information.',
-    'fields' => array(
-      'fid' => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique profile field ID.',
-      ),
-      'title' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-        'description' => 'Title of the field shown to the end user.',
-      ),
-      'name' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Internal name of the field used in the form HTML and URLs.',
-      ),
-      'explanation' => array(
-        'type' => 'text',
-        'not null' => FALSE,
-        'description' => 'Explanation of the field to end users.',
-      ),
-      'category' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-        'description' => 'Profile category that the field will be grouped under.',
-      ),
-      'page' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-        'description' => "Title of page used for browsing by the field's value",
-      ),
-      'type' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => FALSE,
-        'description' => 'Type of form field.',
-      ),
-      'weight' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Weight of field in relation to other profile fields.',
-      ),
-      'required' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Whether the user is required to enter a value. (0 = no, 1 = yes)',
-      ),
-      'register' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Whether the field is visible in the user registration form. (1 = yes, 0 = no)',
-      ),
-      'visibility' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'The level of visibility for the field. (0 = hidden, 1 = private, 2 = public on profile but not member list pages, 3 = public on profile and list pages)',
-      ),
-      'autocomplete' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Whether form auto-completion is enabled. (0 = disabled, 1 = enabled)',
-      ),
-      'options' => array(
-        'type' => 'text',
-        'not null' => FALSE,
-        'description' => 'List of options to be used in a list selection field.',
-      ),
-    ),
-    'indexes' => array(
-      'category' => array('category'),
-    ),
-    'unique keys' => array(
-      'name' => array('name'),
-    ),
-    'primary key' => array('fid'),
-  );
-
-  $schema['profile_value'] = array(
-    'description' => 'Stores values for profile fields.',
-    'fields' => array(
-      'fid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {profile_field}.fid of the field.',
-      ),
-      'uid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {users}.uid of the profile user.',
-      ),
-      'value' => array(
-        'type' => 'text',
-        'not null' => FALSE,
-        'description' => 'The value for the field.',
-      ),
-    ),
-    'primary key' => array('uid', 'fid'),
-    'indexes' => array(
-      'fid' => array('fid'),
-    ),
-    'foreign keys' => array(
-      'profile_field' => array(
-        'table' => 'profile_field',
-        'columns' => array('fid' => 'fid'),
-      ),
-      'profile_user' => array(
-        'table' => 'users',
-        'columns' => array('uid' => 'uid'),
-      ),
-    ),
-  );
-
-  return $schema;
-}
diff --git a/modules/profile/profile.js b/modules/profile/profile.js
deleted file mode 100644
index f842aa0..0000000
--- a/modules/profile/profile.js
+++ /dev/null
@@ -1,58 +0,0 @@
-(function ($) {
-
-/**
- * Add functionality to the profile drag and drop table.
- *
- * This behavior is dependent on the tableDrag behavior, since it uses the
- * objects initialized in that behavior to update the row. It shows and hides
- * a warning message when removing the last field from a profile category.
- */
-Drupal.behaviors.profileDrag = {
-  attach: function (context, settings) {
-    var table = $('#profile-fields');
-    var tableDrag = Drupal.tableDrag['profile-fields']; // Get the profile tableDrag object.
-
-    // Add a handler for when a row is swapped, update empty categories.
-    tableDrag.row.prototype.onSwap = function (swappedRow) {
-      var rowObject = this;
-      $('tr.category-message', table).each(function () {
-        // If the dragged row is in this category, but above the message row, swap it down one space.
-        if ($(this).prev('tr').get(0) == rowObject.element) {
-          // Prevent a recursion problem when using the keyboard to move rows up.
-          if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) {
-            rowObject.swap('after', this);
-          }
-        }
-        // This category has become empty
-        if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) {
-          $(this).removeClass('category-populated').addClass('category-empty');
-        }
-        // This category has become populated.
-        else if ($(this).is('.category-empty')) {
-          $(this).removeClass('category-empty').addClass('category-populated');
-        }
-      });
-    };
-
-    // Add a handler so when a row is dropped, update fields dropped into new categories.
-    tableDrag.onDrop = function () {
-      dragObject = this;
-      if ($(dragObject.rowObject.element).prev('tr').is('.category-message')) {
-        var categoryRow = $(dragObject.rowObject.element).prev('tr').get(0);
-        var categoryNum = categoryRow.className.replace(/([^ ]+[ ]+)*category-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
-        var categoryField = $('select.profile-category', dragObject.rowObject.element);
-        var weightField = $('select.profile-weight', dragObject.rowObject.element);
-        var oldcategoryNum = weightField[0].className.replace(/([^ ]+[ ]+)*profile-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
-
-        if (!categoryField.is('.profile-category-' + categoryNum)) {
-          categoryField.removeClass('profile-category-' + oldcategoryNum).addClass('profile-category-' + categoryNum);
-          weightField.removeClass('profile-weight-' + oldcategoryNum).addClass('profile-weight-' + categoryNum);
-
-          categoryField.val(categoryField[0].options[categoryNum].value);
-        }
-      }
-    };
-  }
-};
-
-})(jQuery);
diff --git a/modules/profile/profile.module b/modules/profile/profile.module
deleted file mode 100644
index 8cac6d7..0000000
--- a/modules/profile/profile.module
+++ /dev/null
@@ -1,628 +0,0 @@
-<?php
-
-/**
- * @file
- * Support for configurable user profiles.
- */
-
-/**
- * Private field, content only available to privileged users.
- */
-define('PROFILE_PRIVATE', 1);
-
-/**
- * Public field, content shown on profile page but not used on member list pages.
- */
-define('PROFILE_PUBLIC', 2);
-
-/**
- * Public field, content shown on profile page and on member list pages.
- */
-define('PROFILE_PUBLIC_LISTINGS', 3);
-
-/**
- * Hidden profile field, only accessible by administrators, modules and themes.
- */
-define('PROFILE_HIDDEN', 4);
-
-/**
- * Implements hook_help().
- */
-function profile_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#profile':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Profile module allows site administrators to define custom fields (such as country, full name, or age) for user profiles, which are then displayed in the <a href="@user">My Account</a> section. This permits users of a site to share more information about themselves, and can help community-based sites organize users around specific information. For more information, see the online handbook entry for <a href="@profile">Profile module</a>.', array('@user' => url('user'), '@profile' => 'http://drupal.org/handbook/modules/profile/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Adding fields to the default profile') . '</dt>';
-      $output .= '<dd>' . t('To provide the ability for users to enter more information about themselves, the Profile module allows additional fields to be added to the default user profile. Examples of common additions would be <em>Location</em>, <em>Company</em>, <em>Age</em>, or <em>About me</em>.') . '</dd>';
-      $output .= '<dt>' . t('User information pages') . '</dt>';
-      $output .= '<dd>' . t('The Profile module enables links to see further information about site users. You can view both a main <a href="@profile">User list page</a>, and more specified pages by clicking on linked fields in any profile. For example, the <a href="@profile-country">People who live in Canada</a> listing on Drupal.org displays all users who have entered <em>Canada</em> in the <em>Country</em> field on their user profile.', array('@profile' => url('profile'), '@profile-country' => 'http://drupal.org/profile/country/Canada')) . '</dd>';
-      $output .= '<dt>' . t('Author information block') . '</dt>';
-      $output .= '<dd>' . t('The <em>Author information block</em> is a default block created by the Profile module that can be enabled on the <a href="@blocks">Blocks administration page</a>. It shows visitors of your website information about the author of the page they are reading.', array('@blocks' => url('admin/structure/block'))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-    case 'admin/config/people/profile':
-      return '<p>' . t("This page displays a list of the existing custom profile fields to be displayed on a user's <em>My account</em> page. To provide structure, similar or related fields may be placed inside a category. To add a new category (or edit an existing one), edit a profile field and provide a new category name.") . '</p>';
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function profile_theme() {
-  return array(
-    'profile_block' => array(
-      'variables' => array('account' => NULL, 'fields' => array()),
-      'template' => 'profile-block',
-    ),
-    'profile_listing' => array(
-      'variables' => array('account' => NULL, 'fields' => array()),
-      'template' => 'profile-listing',
-    ),
-    'profile_wrapper' => array(
-      'variables' => array('content' => NULL),
-      'template' => 'profile-wrapper',
-    ),
-    'profile_admin_overview' => array(
-      'render element' => 'form',
-      'file' => 'profile.admin.inc',
-    )
-  );
-}
-
-/**
- * Implements hook_menu().
- */
-function profile_menu() {
-  $items['profile'] = array(
-    'title' => 'User list',
-    'page callback' => 'profile_browse',
-    'access arguments' => array('access user profiles'),
-    'file' => 'profile.pages.inc',
-    'type' => MENU_SUGGESTED_ITEM,
-  );
-  $items['admin/config/people/profile'] = array(
-    'title' => 'Profiles',
-    'description' => 'Create customizable fields for your users.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('profile_admin_overview'),
-    'access arguments' => array('administer users'),
-    'file' => 'profile.admin.inc',
-  );
-  $items['admin/config/people/profile/add'] = array(
-    'title' => 'Add field',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('profile_field_form'),
-    'access arguments' => array('administer users'),
-    'type' => MENU_VISIBLE_IN_BREADCRUMB,
-    'file' => 'profile.admin.inc',
-  );
-  $items['admin/config/people/profile/autocomplete'] = array(
-    'title' => 'Profile category autocomplete',
-    'page callback' => 'profile_admin_settings_autocomplete',
-    'access arguments' => array('administer users'),
-    'file' => 'profile.admin.inc',
-    'type' => MENU_CALLBACK,
-  );
-  $items['admin/config/people/profile/edit'] = array(
-    'title' => 'Edit field',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('profile_field_form'),
-    'access arguments' => array('administer users'),
-    'type' => MENU_VISIBLE_IN_BREADCRUMB,
-    'file' => 'profile.admin.inc',
-  );
-  $items['admin/config/people/profile/delete'] = array(
-    'title' => 'Delete field',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('profile_field_delete'),
-    'access arguments' => array('administer users'),
-    'type' => MENU_VISIBLE_IN_BREADCRUMB,
-    'file' => 'profile.admin.inc',
-  );
-  $items['profile/autocomplete'] = array(
-    'title' => 'Profile autocomplete',
-    'page callback' => 'profile_autocomplete',
-    'access arguments' => array('access user profiles'),
-    'file' => 'profile.pages.inc',
-    'type' => MENU_CALLBACK,
-  );
-  return $items;
-}
-
-/**
- * Implements hook_block_info().
- */
- function profile_block_info() {
-  $blocks['author-information']['info'] = t('Author information');
-  $blocks['author-information']['cache'] = DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE;
-  return $blocks;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function profile_block_configure($delta = '') {
-  // Compile a list of fields to show
-  $fields = array();
-  $result = db_query('SELECT name, title, weight, visibility FROM {profile_field} WHERE visibility IN (:visibility) ORDER BY weight', array(':visibility' => array(PROFILE_PUBLIC, PROFILE_PUBLIC_LISTINGS)));
-  foreach ($result as $record) {
-    $fields[$record->name] = check_plain($record->title);
-  }
-  $fields['user_profile'] = t('Link to full user profile');
-  $form['profile_block_author_fields'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Profile fields to display'),
-    '#default_value' => variable_get('profile_block_author_fields', array()),
-    '#options' => $fields,
-    '#description' => t('Select which profile fields you wish to display in the block. Only fields designated as public in the <a href="@profile-admin">profile field configuration</a> are available.', array('@profile-admin' => url('admin/config/people/profile'))),
-  );
-  return $form;
-}
-
-/**
- * Implements hook_block_save().
- */
-function profile_block_save($delta = '', $edit = array()) {
-  variable_set('profile_block_author_fields', $edit['profile_block_author_fields']);
-}
-
-/**
- * Implements hook_block_view().
- */
-function profile_block_view($delta = '') {
-  if (user_access('access user profiles')) {
-    $output = '';
-    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == NULL) {
-      $node = node_load(arg(1));
-      $account = user_load($node->uid);
-
-      if ($use_fields = variable_get('profile_block_author_fields', array())) {
-        // Compile a list of fields to show.
-        $fields = array();
-        $result = db_query('SELECT * FROM {profile_field} WHERE visibility IN (:visibility) ORDER BY weight', array(':visibility' => array(PROFILE_PUBLIC, PROFILE_PUBLIC_LISTINGS)));
-        foreach ($result as $record) {
-          // Ensure that field is displayed only if it is among the defined block fields and, if it is private, the user has appropriate permissions.
-          if (isset($use_fields[$record->name]) && $use_fields[$record->name]) {
-            $fields[] = $record;
-          }
-        }
-      }
-
-      if (!empty($fields)) {
-        $profile = _profile_update_user_fields($fields, $account);
-        $output .= theme('profile_block', array('account' => $account, 'fields' => $profile));
-      }
-
-      if (isset($use_fields['user_profile']) && $use_fields['user_profile']) {
-        $output .= '<div>' . l(t('View full user profile'), 'user/' . $account->uid) . '</div>';
-      }
-    }
-
-    if ($output) {
-      $block['subject'] = t('About %name', array('%name' => format_username($account)));
-      $block['content'] = $output;
-      return $block;
-    }
-  }
-}
-
-/**
- * Implements hook_user_presave().
- */
-function profile_user_presave(&$edit, $account, $category) {
-  if ($account->uid) {
-    profile_save_profile($edit, $account, $category);
-  }
-}
-
-/**
- * Implements hook_user_insert().
- */
-function profile_user_insert(&$edit, $account, $category) {
-  profile_save_profile($edit, $account, $category, TRUE);
-}
-
-/**
- * Implements hook_user_cancel().
- */
-function profile_user_cancel(&$edit, $account, $method) {
-  switch ($method) {
-    case 'user_cancel_reassign':
-      db_delete('profile_value')
-        ->condition('uid', $account->uid)
-        ->execute();
-  }
-}
-
-/**
- * Implements hook_user_delete().
- */
-function profile_user_delete($account) {
-  db_delete('profile_value')
-    ->condition('uid', $account->uid)
-    ->execute();
-}
-
-/**
- * Implements hook_user_load().
- */
-function profile_user_load($users) {
-  $result = db_query('SELECT f.name, f.type, v.uid, v.value FROM {profile_field} f INNER JOIN {profile_value} v ON f.fid = v.fid WHERE uid IN (:uids)', array(':uids' => array_keys($users)));
-  foreach ($result as $record) {
-    if (empty($users[$record->uid]->{$record->name})) {
-      $users[$record->uid]->{$record->name} = _profile_field_serialize($record->type) ? unserialize($record->value) : $record->value;
-    }
-  }
-}
-
-function profile_save_profile(&$edit, $account, $category, $register = FALSE) {
-  $result = _profile_get_fields($category, $register);
-  foreach ($result as $field) {
-    if (_profile_field_serialize($field->type)) {
-      $edit[$field->name] = serialize($edit[$field->name]);
-    }
-    db_merge('profile_value')
-      ->key(array(
-        'fid' => $field->fid,
-        'uid' => $account->uid,
-      ))
-      ->fields(array('value' => $edit[$field->name]))
-      ->execute();
-  }
-}
-
-function profile_view_field($account, $field) {
-  // Only allow browsing of private fields for admins, if browsing is enabled,
-  // and if a user has permission to view profiles. Note that this check is
-  // necessary because a user may always see their own profile.
-  $browse = user_access('access user profiles')
-        && (user_access('administer users') || $field->visibility != PROFILE_PRIVATE)
-        && !empty($field->page);
-
-  if (isset($account->{$field->name}) && $value = $account->{$field->name}) {
-    switch ($field->type) {
-      case 'textarea':
-        return check_markup($value, filter_default_format($account), '', TRUE);
-      case 'textfield':
-      case 'selection':
-        return $browse ? l($value, 'profile/' . $field->name . '/' . $value) : check_plain($value);
-      case 'checkbox':
-        return $browse ? l($field->title, 'profile/' . $field->name) : check_plain($field->title);
-      case 'url':
-        return '<a href="' . check_url($value) . '">' . check_plain($value) . '</a>';
-      case 'date':
-        $format = substr(variable_get('date_format_short', 'm/d/Y - H:i'), 0, 5);
-        // Note: Avoid PHP's date() because it does not handle dates before
-        // 1970 on Windows. This would make the date field useless for e.g.
-        // birthdays.
-        $replace = array(
-          'd' => sprintf('%02d', $value['day']),
-          'j' => $value['day'],
-          'm' => sprintf('%02d', $value['month']),
-          'M' => map_month($value['month']),
-          'Y' => $value['year'],
-          'H:i' => NULL,
-          'g:ia' => NULL,
-        );
-        return strtr($format, $replace);
-      case 'list':
-        $values = preg_split("/[,\n\r]/", $value);
-        $fields = array();
-        foreach ($values as $value) {
-          if ($value = trim($value)) {
-            $fields[] = $browse ? l($value, 'profile/' . $field->name . '/' . $value) : check_plain($value);
-          }
-        }
-        return implode(', ', $fields);
-    }
-  }
-}
-
-/**
- * Implements hook_user_view().
- */
-function profile_user_view($account) {
-  // Show private fields to administrators and people viewing their own account.
-  if (user_access('administer users') || $GLOBALS['user']->uid == $account->uid) {
-    $result = db_query('SELECT * FROM {profile_field} WHERE visibility <> :hidden ORDER BY category, weight', array(':hidden' => PROFILE_HIDDEN));
-  }
-  else {
-    $result = db_query('SELECT * FROM {profile_field} WHERE visibility <> :private AND visibility <> :hidden ORDER BY category, weight', array(':private' => PROFILE_PRIVATE, ':hidden' => PROFILE_HIDDEN));
-  }
-
-  $fields = array();
-  foreach ($result as $field) {
-    if ($value = profile_view_field($account, $field)) {
-      $title = ($field->type != 'checkbox') ? check_plain($field->title) : NULL;
-
-      // Create a single fieldset for each category.
-      if (!isset($account->content[$field->category])) {
-        $account->content[$field->category] = array(
-          '#type' => 'user_profile_category',
-          '#title' => $field->category,
-        );
-      }
-
-      $account->content[$field->category][$field->name] = array(
-        '#type' => 'user_profile_item',
-        '#title' => $title,
-        '#markup' => $value,
-        '#weight' => $field->weight,
-        '#attributes' => array('class' => array('profile-' . $field->name)),
-      );
-    }
-  }
-}
-
-function _profile_form_explanation($field) {
-  $output = filter_xss_admin($field->explanation);
-
-  if ($field->type == 'list') {
-    $output .= ' ' . t('Put each item on a separate line or separate them by commas. No HTML allowed.');
-  }
-
-  if ($field->visibility == PROFILE_PRIVATE) {
-    $output .= ' ' . t('The content of this field is kept private and will not be shown publicly.');
-  }
-
-  return $output;
-}
-
-/**
- * Implements hook_form_alter().
- */
-function profile_form_alter(&$form, &$form_state, $form_id) {
-  if (!($form_id == 'user_register_form' || $form_id == 'user_profile_form')) {
-    return;
-  }
-  $form['#validate'][] = 'profile_user_form_validate';
-  $account = $form['#user'];
-  $result = _profile_get_fields($form['#user_category'], $form['#user_category'] == 'register');
-  $weight = 1;
-  foreach ($result as $field) {
-    $category = $field->category;
-    if (!isset($form[$category])) {
-      $form[$category] = array('#type' => 'fieldset', '#title' => check_plain($category), '#weight' => $weight++);
-    }
-    switch ($field->type) {
-      case 'textfield':
-      case 'url':
-        $form[$category][$field->name] = array(
-          '#type' => 'textfield',
-          '#title' => check_plain($field->title),
-          '#default_value' => isset($account->{$field->name}) ? $account->{$field->name} : '',
-          '#maxlength' => 255,
-          '#description' => _profile_form_explanation($field),
-          '#required' => $field->required,
-        );
-        if ($field->autocomplete) {
-          $form[$category][$field->name]['#autocomplete_path'] = "profile/autocomplete/" . $field->fid;
-        }
-        break;
-
-      case 'textarea':
-        $form[$category][$field->name] = array(
-          '#type' => 'textarea',
-          '#title' => check_plain($field->title),
-          '#default_value' => isset($account->{$field->name}) ? $account->{$field->name} : '',
-          '#description' => _profile_form_explanation($field),
-          '#required' => $field->required,
-        );
-        break;
-
-      case 'list':
-        $form[$category][$field->name] = array(
-          '#type' => 'textarea',
-          '#title' => check_plain($field->title),
-          '#default_value' => isset($account->{$field->name}) ? $account->{$field->name} : '',
-          '#description' => _profile_form_explanation($field),
-          '#required' => $field->required,
-        );
-        break;
-
-      case 'checkbox':
-        $form[$category][$field->name] = array(
-          '#type' => 'checkbox',
-          '#title' => check_plain($field->title),
-          '#default_value' => isset($account->{$field->name}) ? $account->{$field->name} : '',
-          '#description' => _profile_form_explanation($field),
-          '#required' => $field->required,
-        );
-        break;
-
-      case 'selection':
-        $options = $field->required ? array() : array('--');
-        $lines = preg_split("/[\n\r]/", $field->options);
-        foreach ($lines as $line) {
-          if ($line = trim($line)) {
-            $options[$line] = $line;
-          }
-        }
-        $form[$category][$field->name] = array(
-          '#type' => 'select',
-          '#title' => check_plain($field->title),
-          '#default_value' => isset($account->{$field->name}) ? $account->{$field->name} : '',
-          '#options' => $options,
-          '#description' => _profile_form_explanation($field),
-          '#required' => $field->required,
-        );
-        break;
-
-      case 'date':
-        $form[$category][$field->name] = array(
-          '#type' => 'date',
-          '#title' => check_plain($field->title),
-          '#default_value' => isset($account->{$field->name}) ? $account->{$field->name} : '',
-          '#description' => _profile_form_explanation($field),
-          '#required' => $field->required,
-        );
-        break;
-    }
-  }
-}
-
-/**
- * Helper function: update an array of user fields by calling profile_view_field
- */
-function _profile_update_user_fields($fields, $account) {
-  foreach ($fields as $key => $field) {
-    $fields[$key]->value = profile_view_field($account, $field);
-  }
-  return $fields;
-}
-
-/**
- * Form validation handler for the user register/profile form.
- *
- * @see profile_form_alter()
- */
-function profile_user_form_validate($form, &$form_state) {
-  $result = _profile_get_fields($form['#user_category'], $form['#user_category'] == 'register');
-  foreach ($result as $field) {
-    if (!empty($form_state['values'][$field->name])) {
-      if ($field->type == 'url' && !valid_url($form_state['values'][$field->name], TRUE)) {
-        form_set_error($field->name, t('The value provided for %field is not a valid URL.', array('%field' => $field->title)));
-      }
-    }
-    elseif ($field->required && !user_access('administer users')) {
-      form_set_error($field->name, t('The field %field is required.', array('%field' => $field->title)));
-    }
-  }
-}
-
-/**
- * Implements hook_user_categories().
- */
-function profile_user_categories() {
-  $result = db_query("SELECT DISTINCT(category) FROM {profile_field}");
-  $data = array();
-  foreach ($result as $category) {
-    $data[] = array(
-      'name' => $category->category,
-      'title' => $category->category,
-      'weight' => 3,
-      'access callback' => 'profile_category_access',
-      'access arguments' => array(1, $category->category)
-    );
-  }
-  return $data;
-}
-
-/**
- * Menu item access callback - check if a user has access to a profile category.
- */
-function profile_category_access($account, $category) {
-  if (user_access('administer users') && $account->uid > 0) {
-    return TRUE;
-  }
-  else {
-    $category_visible = (bool) db_query_range('SELECT 1 FROM {profile_field} WHERE category = :category AND visibility <> :visibility', 0, 1, array(
-      ':category' => $category,
-      ':visibility' => PROFILE_HIDDEN
-    ))->fetchField();
-    return user_edit_access($account) && $category_visible;
-  }
-}
-
-/**
- * Process variables for profile-block.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $account
- * - $fields
- *
- * @see profile-block.tpl.php
- */
-function template_preprocess_profile_block(&$variables) {
-
-  $variables['user_picture'] = theme('user_picture', array('account' => $variables['account']));
-  $variables['profile'] = array();
-  // Supply filtered version of $fields that have values.
-  foreach ($variables['fields'] as $field) {
-    if ($field->value) {
-      $variables['profile'][$field->name] = new stdClass();
-      $variables['profile'][$field->name]->title = check_plain($field->title);
-      $variables['profile'][$field->name]->value = $field->value;
-      $variables['profile'][$field->name]->type = $field->type;
-    }
-  }
-
-}
-
-/**
- * Process variables for profile-listing.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $account
- * - $fields
- *
- * @see profile-listing.tpl.php
- */
-function template_preprocess_profile_listing(&$variables) {
-
-  $variables['user_picture'] = theme('user_picture', array('account' => $variables['account']));
-  $variables['name'] = theme('username', array('account' => $variables['account']));
-  $variables['profile'] = array();
-  // Supply filtered version of $fields that have values.
-  foreach ($variables['fields'] as $field) {
-    if ($field->value) {
-      $variables['profile'][$field->name]->title = $field->title;
-      $variables['profile'][$field->name]->value = $field->value;
-      $variables['profile'][$field->name]->type = $field->type;
-    }
-  }
-
-}
-
-/**
- * Process variables for profile-wrapper.tpl.php.
- *
- * The $variables array contains the following arguments:
- * - $content
- *
- * @see profile-wrapper.tpl.php
- */
-function template_preprocess_profile_wrapper(&$variables) {
-  $variables['current_field'] = '';
-  if ($field = arg(1)) {
-    $variables['current_field'] = $field;
-    $variables['theme_hook_suggestions'][] = 'profile_wrapper__' . $field;
-  }
-}
-
-function _profile_field_types($type = NULL) {
-  $types = array('textfield' => t('single-line textfield'),
-                 'textarea' => t('multi-line textfield'),
-                 'checkbox' => t('checkbox'),
-                 'selection' => t('list selection'),
-                 'list' => t('freeform list'),
-                 'url' => t('URL'),
-                 'date' => t('date'));
-  return isset($type) ? $types[$type] : $types;
-}
-
-function _profile_field_serialize($type = NULL) {
-  return $type == 'date';
-}
-
-function _profile_get_fields($category, $register = FALSE) {
-  $query = db_select('profile_field');
-  if ($register) {
-    $query->condition('register', 1);
-  }
-  else {
-    $query->condition('category', db_like($category), 'LIKE');
-  }
-  if (!user_access('administer users')) {
-    $query->condition('visibility', PROFILE_HIDDEN, '<>');
-  }
-  return $query
-    ->fields('profile_field')
-    ->orderBy('category', 'ASC')
-    ->orderBy('weight', 'ASC')
-    ->execute();
-}
diff --git a/modules/profile/profile.pages.inc b/modules/profile/profile.pages.inc
deleted file mode 100644
index 06f9632..0000000
--- a/modules/profile/profile.pages.inc
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the profile module.
- */
-
-/**
- * Menu callback; display a list of user information.
- */
-function profile_browse() {
-  // Ensure that the path is converted to 3 levels always.
-  list(, $name, $value) = array_pad(explode('/', $_GET['q'], 3), 3, '');
-
-  $field = db_query("SELECT DISTINCT(fid), type, title, page, visibility FROM {profile_field} WHERE name = :name", array(':name' => $name))->fetchObject();
-
-  if ($name && $field->fid) {
-    // Only allow browsing of fields that have a page title set.
-    if (empty($field->page)) {
-      drupal_not_found();
-      return;
-    }
-    // Do not allow browsing of private and hidden fields by non-admins.
-    if (!user_access('administer users') && ($field->visibility == PROFILE_PRIVATE || $field->visibility == PROFILE_HIDDEN)) {
-      drupal_access_denied();
-      return;
-    }
-
-    // Compile a list of fields to show.
-    $fields = db_query('SELECT name, title, type, weight, page FROM {profile_field} WHERE fid <> :fid AND visibility = :visibility ORDER BY weight', array(
-      ':fid' => $field->fid,
-      ':visibility' => PROFILE_PUBLIC_LISTINGS,
-    ))->fetchAll();
-
-    $query = db_select('users', 'u')->extend('PagerDefault');
-    $query->join('profile_value', 'v', 'u.uid = v.uid');
-    $query
-      ->fields('u', array('uid', 'access'))
-      ->condition('v.fid', $field->fid)
-      ->condition('u.status', 0, '<>')
-      ->orderBy('u.access', 'DESC');
-
-    // Determine what query to use:
-    $arguments = array($field->fid);
-    switch ($field->type) {
-      case 'checkbox':
-        $query->condition('v.value', 1);
-        break;
-      case 'textfield':
-      case 'selection':
-        $query->condition('v.value', $value);
-        break;
-      case 'list':
-        $query->condition('v.value', '%' . db_like($value) . '%', 'LIKE');
-        break;
-      default:
-        drupal_not_found();
-        return;
-    }
-
-    $uids = $query
-      ->limit(20)
-      ->execute()
-      ->fetchCol();
-
-    // Load the users.
-    $users = user_load_multiple($uids);
-
-    $content = '';
-    foreach ($users as $account) {
-      $profile = _profile_update_user_fields($fields, $account);
-      $content .= theme('profile_listing', array('account' => $account, 'fields' => $profile));
-    }
-    $output = theme('profile_wrapper', array('content' => $content));
-    $output .= theme('pager');
-
-    if ($field->type == 'selection' || $field->type == 'list' || $field->type == 'textfield') {
-      $title = strtr(check_plain($field->page), array('%value' => drupal_placeholder($value)));
-    }
-    else {
-      $title = check_plain($field->page);
-    }
-
-    drupal_set_title($title, PASS_THROUGH);
-    return $output;
-  }
-  elseif ($name && !$field->fid) {
-    drupal_not_found();
-  }
-  else {
-    // Compile a list of fields to show.
-    $fields = db_query('SELECT name, title, type, weight, page, visibility FROM {profile_field} WHERE visibility = :visibility ORDER BY category, weight', array(':visibility' => PROFILE_PUBLIC_LISTINGS))->fetchAll();
-
-    // Extract the affected users:
-    $query = db_select('users', 'u')->extend('PagerDefault');
-    $uids = $query
-      ->fields('u', array('uid', 'access'))
-      ->condition('u.uid', 0, '>')
-      ->condition('u.status', 0, '>')
-      ->orderBy('u.access', 'DESC')
-      ->limit(20)
-      ->execute()
-      ->fetchCol();
-    $users = user_load_multiple($uids);
-    $content = '';
-    foreach ($users as $account) {
-      $profile = _profile_update_user_fields($fields, $account);
-      $content .= theme('profile_listing', array('account' => $account, 'fields' => $profile));
-    }
-    $output = theme('profile_wrapper', array('content' => $content));
-    $output .= theme('pager');
-
-    drupal_set_title(t('User list'));
-    return $output;
-  }
-}
-
-/**
- * Callback to allow autocomplete of profile text fields.
- */
-function profile_autocomplete($field, $string) {
-  $matches = array();
-  $autocomplete_field = (bool) db_query_range("SELECT 1 FROM {profile_field} WHERE fid = :fid AND autocomplete = 1", 0, 1, array(':fid' => $field))->fetchField();
-  if ($autocomplete_field) {
-    $values = db_select('profile_value')
-      ->fields('profile_value', array('value'))
-      ->condition('fid', $field)
-      ->condition('value', db_like($string) . '%', 'LIKE')
-      ->groupBy('value')
-      ->orderBy('value')
-      ->range(0, 10)
-      ->execute()->fetchCol();
-    foreach ($values as $value) {
-      $matches[$value] = check_plain($value);
-    }
-  }
-
-  drupal_json_output($matches);
-}
diff --git a/modules/profile/profile.test b/modules/profile/profile.test
deleted file mode 100644
index 83bed25..0000000
--- a/modules/profile/profile.test
+++ /dev/null
@@ -1,490 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for profile.module.
- */
-
-/**
- * A class for common methods for testing profile fields.
- */
-class ProfileTestCase extends DrupalWebTestCase {
-  protected $admin_user;
-  protected $normal_user;
-
-  function setUp() {
-    parent::setUp('profile');
-    variable_set('user_register', USER_REGISTER_VISITORS);
-
-    $this->admin_user = $this->drupalCreateUser(array('administer users', 'access user profiles', 'administer blocks'));
-
-    // This is the user whose profile will be edited.
-    $this->normal_user = $this->drupalCreateUser();
-  }
-
-  /**
-   * Create a profile field.
-   *
-   * @param $type
-   *   The field type to be created.
-   * @param $category
-   *   The category in which the field should be created.
-   * @param $edit
-   *   Additional parameters to be submitted.
-   * @return
-   *   The fid of the field that was just created.
-   */
-  function createProfileField($type = 'textfield', $category = 'simpletest', $edit = array()) {
-    $edit['title'] = $title = $this->randomName(8);
-    $edit['name'] = $form_name = 'profile_' . $title;
-    $edit['category'] = $category;
-    $edit['explanation'] = $this->randomName(50);
-
-    $this->drupalPost('admin/config/people/profile/add/' . $type, $edit, t('Save field'));
-    $fid = db_query("SELECT fid FROM {profile_field} WHERE title = :title", array(':title' => $title))->fetchField();
-    $this->assertTrue($fid, t('New Profile field has been entered in the database'));
-
-    // Check that the new field is appearing on the user edit form.
-    $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
-
-    // Checking field.
-    if ($type == 'date') {
-      $this->assertField($form_name . '[month]', t('Found month selection field'));
-      $this->assertField($form_name . '[day]', t('Found day selection field'));
-      $this->assertField($form_name . '[year]', t('Found day selection field'));
-    }
-    else {
-      $this->assertField($form_name , t('Found form named @name', array('@name' => $form_name)));
-    }
-
-    // Checking name.
-    $this->assertText($title, t('Checking title for field %title', array('%title' => $title)));
-    // Checking explanation.
-    $this->assertText($edit['explanation'], t('Checking explanation for field %title', array('%title' => $title)));
-
-    return array(
-      'fid' => $fid,
-      'type' => $type,
-      'form_name' => $form_name,
-      'title' => $title,
-      'category' => $category,
-    );
-  }
-
-  /**
-   * Update a profile field.
-   *
-   * @param $fid
-   *   The fid of the field to be updated.
-   * @param $type
-   *   The type of field to be updated.
-   * @param $edit
-   *   Field parameters to be submitted.
-   * @return
-   *   Array representation of the updated field.
-   */
-  function updateProfileField($fid, $type = 'textfield', $edit = array()) {
-
-    $form_name = $edit['name'];
-    $title = $edit['title'];
-    $category = $edit['category'];
-
-    $this->drupalPost('admin/config/people/profile/edit/' . $fid, $edit, t('Save field'));
-
-    // Check that the updated field is appearing on the user edit form.
-    $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
-
-    // Checking field.
-    if ($type == 'date') {
-      $this->assertField($form_name . '[month]', t('Found month selection field'));
-      $this->assertField($form_name . '[day]', t('Found day selection field'));
-      $this->assertField($form_name . '[year]', t('Found day selection field'));
-    }
-    else {
-      $this->assertField($form_name , t('Found form named @name', array('@name' => $form_name)));
-    }
-
-    // Checking name.
-    $this->assertText($title, t('Checking title for field %title', array('%title' => $title)));
-    // Checking explanation.
-    $this->assertText($edit['explanation'], t('Checking explanation for field %title', array('%title' => $title)));
-
-    return array(
-      'fid' => $fid,
-      'type' => $type,
-      'form_name' => $form_name,
-      'title' => $title,
-      'category' => $category,
-    );
-  }
-
-  /**
-   * Set the profile field to a random value
-   *
-   * @param $field
-   *   The field that should be set.
-   * @param $value
-   *   The value for the field, defaults to a random string.
-   * @return
-   *   The value that has been assigned to
-   */
-  function setProfileField($field, $value = NULL) {
-
-    if (!isset($value)) {
-      $value = $this->randomName();
-    }
-
-    $edit = array(
-      $field['form_name'] => $value,
-    );
-    $this->drupalPost('user/' . $this->normal_user->uid . '/edit/' . $field['category'], $edit, t('Save'));
-
-    // Check profile page.
-    $content = $this->drupalGet('user/' . $this->normal_user->uid);
-    $this->assertText($field['title'], t('Found profile field with title %title', array('%title' => $field['title'])));
-
-    if ($field['type'] != 'checkbox') {
-      // $value must be cast to a string in order to be found by assertText.
-      $this->assertText("$value", t('Found profile field with value %value', array('%value' => $value)));
-    }
-
-    return $value;
-  }
-
-  /**
-   * Delete a profile field.
-   *
-   * @param $field
-   *   The field to be deleted.
-   */
-  function deleteProfileField($field) {
-    $this->drupalPost('admin/config/people/profile/delete/' . $field['fid'], array(), t('Delete'));
-    $this->drupalGet('admin/config/people/profile');
-    $this->assertNoText($field['title'], t('Checking deleted field %title', array('%title' => $field['title'])));
-  }
-}
-
-class ProfileTestFields extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Test single fields',
-      'description' => 'Testing profile module with add/edit/delete textfield, textarea, list, checkbox, and url fields into profile page',
-      'group' => 'Profile'
-    );
-  }
-
-  /**
-   * Test each of the field types. List selection and date fields are tested
-   * separately because they need some special handling.
-   */
-  function testProfileFields() {
-    $this->drupalLogin($this->admin_user);
-
-    // Set test values for every field type.
-    $field_types = array(
-      'textfield' => $this->randomName(),
-      'textarea' => $this->randomName(),
-      'list' => $this->randomName(),
-      'checkbox' => 1,
-      // An underscore is an invalid character in a domain name. The method randomName can
-      // return an underscore.
-      'url' => 'http://www.' . str_replace('_', '', $this->randomName(10)) . '.org',
-    );
-
-    // For each field type, create a field, give it a value, update the field,
-    // and delete the field.
-    foreach ($field_types as $type => $value) {
-      $field = $this->createProfileField($type);
-      $this->setProfileField($field, $value);
-      $edit = array(
-        'name' => $field['form_name'],
-        'title' => $this->randomName(),
-        'category' => $field['category'],
-        'explanation' => $this->randomName(),
-      );
-      $field = $this->updateProfileField($field['fid'], $field['type'], $edit);
-      $this->deleteProfileField($field);
-    }
-  }
-}
-
-class ProfileTestSelect extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Test select field',
-      'description' => 'Testing profile module with add/edit/delete a select field',
-      'group' => 'Profile'
-    );
-  }
-
-  /**
-   * Create a list selection field, give it a value, update and delete the field.
-   */
-  function testProfileSelectionField() {
-    $this->drupalLogin($this->admin_user);
-
-    $edit = array(
-      'options' => implode("\n", range(1, 10)),
-    );
-    $field = $this->createProfileField('selection', 'simpletest', $edit);
-
-    $this->setProfileField($field, rand(1, 10));
-
-    $edit = array(
-      'name' => $field['form_name'],
-      'title' => $this->randomName(),
-      'category' => $field['category'],
-      'explanation' => $this->randomName(),
-    );
-    $field = $this->updateProfileField($field['fid'], $field['type'], $edit);
-    $this->deleteProfileField($field);
-  }
-}
-
-class ProfileTestDate extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Test date field',
-      'description' => 'Testing profile module with add/edit/delete a date field',
-      'group' => 'Profile'
-    );
-  }
-
-  /**
-   * Create a date field, give it a value, update and delete the field.
-   */
-  function testProfileDateField() {
-    $this->drupalLogin($this->admin_user);
-
-    variable_set('date_format_short', 'm/d/Y - H:i');
-    $field = $this->createProfileField('date');
-
-    // Set date to January 09, 1983
-    $edit = array(
-      $field['form_name'] . '[month]' => 1,
-      $field['form_name'] . '[day]' => 9,
-      $field['form_name'] . '[year]' => 1983,
-    );
-
-    $this->drupalPost('user/' . $this->normal_user->uid . '/edit/' . $field['category'], $edit, t('Save'));
-
-    // Check profile page.
-    $this->drupalGet('user/' . $this->normal_user->uid);
-    $this->assertText($field['title'], t('Found profile field with title %title', array('%title' => $field['title'])));
-
-    $this->assertText('01/09/1983', t('Found date profile field.'));
-
-    $edit = array(
-      'name' => $field['form_name'],
-      'title' => $this->randomName(),
-      'category' => $field['category'],
-      'explanation' => $this->randomName(),
-    );
-    $field = $this->updateProfileField($field['fid'], $field['type'], $edit);
-    $this->deleteProfileField($field);
-  }
-}
-
-class ProfileTestWeights extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Test field weights',
-      'description' => 'Testing profile modules weigting of fields',
-      'group' => 'Profile'
-    );
-  }
-
-  function testProfileFieldWeights() {
-    $this->drupalLogin($this->admin_user);
-
-    $category = $this->randomName();
-    $field1 = $this->createProfileField('textfield', $category, array('weight' => 1));
-    $field2 = $this->createProfileField('textfield', $category, array('weight' => -1));
-
-    $this->setProfileField($field1, $this->randomName(8));
-    $this->setProfileField($field2, $this->randomName(8));
-
-    $profile_edit = $this->drupalGet('user/' . $this->normal_user->uid . '/edit/' . $category);
-    $this->assertTrue(strpos($profile_edit, $field1['title']) > strpos($profile_edit, $field2['title']), t('Profile field weights are respected on the user edit form.'));
-
-    $profile_page = $this->drupalGet('user/' . $this->normal_user->uid);
-    $this->assertTrue(strpos($profile_page, $field1['title']) > strpos($profile_page, $field2['title']), t('Profile field weights are respected on the user profile page.'));
-  }
-}
-
-/**
- * Test profile field autocompletion and access.
- */
-class ProfileTestAutocomplete extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Autocompletion',
-      'description' => 'Test profile fields with autocompletion.',
-      'group' => 'Profile'
-    );
-  }
-
-  /**
-   * Tests profile field autocompletion and access.
-   */
-  function testAutocomplete() {
-    $this->drupalLogin($this->admin_user);
-
-    // Create a new profile field with autocompletion enabled.
-    $category = $this->randomName();
-    $field = $this->createProfileField('textfield', $category, array('weight' => 1, 'autocomplete' => 1));
-
-    // Enter profile field value.
-    $field['value'] = $this->randomName();
-    $this->setProfileField($field, $field['value']);
-
-    // Set some html for what we want to see in the page output later.
-    $autocomplete_html = '<input type="hidden" id="' . drupal_html_id('edit-' . $field['form_name'] . '-autocomplete') . '" value="' . url('profile/autocomplete/' . $field['fid'], array('absolute' => TRUE)) . '" disabled="disabled" class="autocomplete" />';
-    $field_html = '<input type="text" maxlength="255" name="' . $field['form_name'] . '" id="' . drupal_html_id('edit-' . $field['form_name']) . '" size="60" value="' . $field['value'] . '" class="form-text form-autocomplete required" />';
-
-    // Check that autocompletion html is found on the user's profile edit page.
-    $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
-    $this->assertRaw($autocomplete_html, t('Autocomplete found.'));
-    $this->assertRaw('misc/autocomplete.js', t('Autocomplete JavaScript found.'));
-    $this->assertRaw('class="form-text form-autocomplete"', t('Autocomplete form element class found.'));
-
-    // Check the autocompletion path using the first letter of our user's profile
-    // field value to make sure access is allowed and a valid result if found.
-    $this->drupalGet('profile/autocomplete/' . $field['fid'] . '/' . $field['value'][0]);
-    $this->assertResponse(200, t('Autocomplete path allowed to user with permission.'));
-    $this->assertRaw($field['value'], t('Autocomplete value found.'));
-
-    // Logout and login with a user without the 'access user profiles' permission.
-    $this->drupalLogout();
-    $this->drupalLogin($this->normal_user);
-
-    // Check that autocompletion html is not found on the user's profile edit page.
-    $this->drupalGet('user/' . $this->normal_user->uid . '/edit/' . $category);
-    $this->assertNoRaw($autocomplete_html, t('Autocomplete not found.'));
-
-    // User should be denied access to the profile autocomplete path.
-    $this->drupalGet('profile/autocomplete/' . $field['fid'] . '/' . $field['value'][0]);
-    $this->assertResponse(403, t('Autocomplete path denied to user without permission.'));
-  }
-}
-
-class ProfileBlockTestCase extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Block availability',
-      'description' => 'Check if the Author Information block is available.',
-      'group' => 'Profile',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-
-    // Login the admin user.
-    $this->drupalLogin($this->admin_user);
-
-    // Create two fields.
-    $category = $this->randomName();
-    $this->field1 = $this->createProfileField('textfield', $category, array('weight' => 0));
-    $this->field2 = $this->createProfileField('textfield', $category, array('weight' => 1));
-
-    // Assign values to those fields.
-    $this->value1 = $this->setProfileField($this->field1);
-    $this->value2 = $this->setProfileField($this->field2);
-
-    // Create a node authored by the normal user.
-    $this->node = $this->drupalCreateNode(array(
-      'uid' => $this->normal_user->uid,
-    ));
-  }
-
-  function testAuthorInformationBlock() {
-    // Set the block to a region to confirm the block is availble.
-    $edit = array();
-    $edit['blocks[profile_author-information][region]'] = 'footer';
-    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
-    $this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.'));
-
-    // Enable field 1.
-    $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
-      'profile_block_author_fields[' . $this->field1['form_name'] . ']' => TRUE,
-    ), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
-
-    // Visit the node and confirm that the field is displayed.
-    $this->drupalGet('node/' . $this->node->nid);
-    $this->assertRaw($this->value1, t('Field 1 is displayed'));
-    $this->assertNoRaw($this->value2, t('Field 2 is not displayed'));
-
-    // Enable only field 2.
-    $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
-      'profile_block_author_fields[' . $this->field1['form_name'] . ']' => FALSE,
-      'profile_block_author_fields[' . $this->field2['form_name'] . ']' => TRUE,
-    ), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
-
-    // Visit the node and confirm that the field is displayed.
-    $this->drupalGet('node/' . $this->node->nid);
-    $this->assertNoRaw($this->value1, t('Field 1 is not displayed'));
-    $this->assertRaw($this->value2, t('Field 2 is displayed'));
-
-    // Enable both fields.
-    $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
-      'profile_block_author_fields[' . $this->field1['form_name'] . ']' => TRUE,
-      'profile_block_author_fields[' . $this->field2['form_name'] . ']' => TRUE,
-    ), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
-
-    // Visit the node and confirm that the field is displayed.
-    $this->drupalGet('node/' . $this->node->nid);
-    $this->assertRaw($this->value1, t('Field 1 is displayed'));
-    $this->assertRaw($this->value2, t('Field 2 is displayed'));
-
-    // Enable the link to the user profile.
-    $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
-      'profile_block_author_fields[user_profile]' => TRUE,
-    ), t('Save block'));
-    $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
-
-    // Visit the node and confirm that the user profile link is displayed.
-    $this->drupalGet('node/' . $this->node->nid);
-    $this->clickLink(t('View full user profile'));
-    $this->assertEqual($this->getUrl(), url('user/' . $this->normal_user->uid, array('absolute' => TRUE)));
-  }
-}
-
-/**
- * Test profile browsing.
- */
-class ProfileTestBrowsing extends ProfileTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Profile browsing',
-      'description' => 'Test profile browsing.',
-      'group' => 'Profile',
-    );
-  }
-
-  /**
-   * Test profile browsing.
-   */
-  function testProfileBrowsing() {
-    $this->drupalLogin($this->admin_user);
-    $field = $this->createProfileField('list', 'simpletest', array('page' => '%value'));
-
-    // Set a random value for the profile field.
-    $value = $this->setProfileField($field);
-
-    // Check that user is found on the profile browse page.
-    $this->drupalGet("profile/{$field['form_name']}/$value");
-    $this->assertText($this->normal_user->name);
-  }
-}
-
-  /**
-   * TODO:
-   * - Test field visibility
-   * - Test required fields
-   * - Test fields on registration form
-   * - Test updating fields
-   */
diff --git a/modules/shortcut/shortcut-rtl.css b/modules/shortcut/shortcut-rtl.css
deleted file mode 100644
index 4a37927..0000000
--- a/modules/shortcut/shortcut-rtl.css
+++ /dev/null
@@ -1,47 +0,0 @@
-
-div#toolbar a#edit-shortcuts {
-  position: absolute;
-  left: 0;
-  top: 0;
-  padding: 5px 5px 5px 10px;
-}
-div#toolbar div.toolbar-shortcuts ul {
-  float: none;
-  margin-right: 5px;
-  margin-left: 10em;
-}
-div#toolbar div.toolbar-shortcuts ul li a {
-  margin-left: 5px;
-  margin-right: 0;
-  padding: 0 5px;
-}
-div#toolbar div.toolbar-shortcuts span.icon {
-  float: right;
-}
-div.add-or-remove-shortcuts a span.icon {
-  float: right;
-  margin-right: 8px;
-  margin-left: 0;
-}
-div.add-or-remove-shortcuts a span.text {
-  float: right;
-  padding-right: 10px;
-  padding-left: 0;
-}
-div.add-or-remove-shortcuts a:hover span.text {
-  -moz-border-radius: 5px 0 0 5px;
-  -webkit-border-top-left-radius: 5px;
-  -webkit-border-bottom-left-radius: 5px;
-  border-radius: 5px 0 0 5px;
-  padding-left: 6px;
-}
-#shortcut-set-switch .form-item-new {
-  padding-right: 17px;
-  padding-left: 0;
-}
-div.add-shortcut a:hover span.icon {
-  background-position: 0 -24px;
-}
-div.remove-shortcut a:hover span.icon {
-  background-position: -12px -24px;
-}
diff --git a/modules/shortcut/shortcut.admin.css b/modules/shortcut/shortcut.admin.css
deleted file mode 100644
index 8ca03be..0000000
--- a/modules/shortcut/shortcut.admin.css
+++ /dev/null
@@ -1,8 +0,0 @@
-
-.shortcut-slot-hidden {
-  display: none;
-}
-
-div.form-item-set div.form-item-new {
-  display: inline;
-}
diff --git a/modules/shortcut/shortcut.admin.inc b/modules/shortcut/shortcut.admin.inc
deleted file mode 100644
index 9735d37..0000000
--- a/modules/shortcut/shortcut.admin.inc
+++ /dev/null
@@ -1,770 +0,0 @@
-<?php
-
-/**
- * @file
- * Administrative page callbacks for the shortcut module.
- */
-
-/**
- * Returns the maximum number of shortcut "slots" available per shortcut set.
- *
- * This is used as a limitation in the user interface only.
- *
- * @return
- *   The maximum number of shortcuts allowed to be added to a shortcut set.
- */
-function shortcut_max_slots() {
-  return variable_get('shortcut_max_slots', 7);
-}
-
-/**
- * Form callback: builds the form for switching shortcut sets.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param $account
- *   (optional) The user account whose shortcuts will be switched. Defaults to
- *   the current logged-in user.
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_set_switch_validate()
- * @see shortcut_set_switch_submit()
- */
-function shortcut_set_switch($form, &$form_state, $account = NULL) {
-  global $user;
-  if (!isset($account)) {
-    $account = $user;
-  }
-
-  // Prepare the list of shortcut sets.
-  $sets = shortcut_sets();
-  $current_set = shortcut_current_displayed_set($account);
-
-  $options = array();
-  foreach ($sets as $name => $set) {
-    $options[$name] = check_plain($set->title);
-  }
-
-  // Only administrators can add shortcut sets.
-  $add_access = user_access('administer shortcuts');
-  if ($add_access) {
-    $options['new'] = t('New set');
-  }
-
-  if (count($options) > 1) {
-    $form['account'] = array(
-      '#type' => 'value',
-      '#value' => $account,
-    );
-
-    $form['set'] = array(
-      '#type' => 'radios',
-      '#title' => $user->uid == $account->uid ? t('Choose a set of shortcuts to use') : t('Choose a set of shortcuts for this user'),
-      '#options' => $options,
-      '#default_value' => $current_set->set_name,
-    );
-
-    $form['new'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Name'),
-      '#title_display' => 'invisible',
-      '#description' => t('The new set is created by copying items from your default shortcut set.'),
-      '#access' => $add_access,
-    );
-
-    if ($user->uid != $account->uid) {
-      $default_set = shortcut_default_set($account);
-      $form['new']['#description'] = t('The new set is created by copying items from the %default set.', array('%default' => $default_set->title));
-    }
-
-    $form['#attached'] = array(
-      'css' => array(drupal_get_path('module', 'shortcut') . '/shortcut.admin.css'),
-      'js' => array(drupal_get_path('module', 'shortcut') . '/shortcut.admin.js'),
-    );
-
-    $form['actions'] = array('#type' => 'actions');
-    $form['actions']['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Change set'),
-    );
-  }
-  else {
-    // There is only 1 option, so output a message in the $form array.
-    $form['info'] = array(
-      '#markup' => '<p>' . t('You are currently using the %set-name shortcut set.', array('%set-name' => $current_set->title)) . '</p>',
-    );
-  }
-
-  return $form;
-}
-
-/**
- * Validation handler for shortcut_set_switch().
- */
-function shortcut_set_switch_validate($form, &$form_state) {
-  if ($form_state['values']['set'] == 'new') {
-    // Check to prevent creating a shortcut set with an empty title.
-    if (trim($form_state['values']['new']) == '') {
-      form_set_error('new', t('The new set name is required.'));
-    }
-    // Check to prevent a duplicate title.
-    if (shortcut_set_title_exists($form_state['values']['new'])) {
-      form_set_error('new', t('The shortcut set %name already exists. Choose another name.', array('%name' => $form_state['values']['new'])));
-    }
-  }
-}
-
-/**
- * Submit handler for shortcut_set_switch().
- */
-function shortcut_set_switch_submit($form, &$form_state) {
-  global $user;
-  $account = $form_state['values']['account'];
-
-  if ($form_state['values']['set'] == 'new') {
-    // Save a new shortcut set with links copied from the user's default set.
-    $default_set = shortcut_default_set($account);
-    $set = (object) array(
-      'title' => $form_state['values']['new'],
-      'links' => menu_links_clone($default_set->links),
-    );
-    shortcut_set_save($set);
-    $replacements = array(
-      '%user' => $account->name,
-      '%set_name' => $set->title,
-      '@switch-url' => url(current_path()),
-    );
-    if ($account->uid == $user->uid) {
-      // Only administrators can create new shortcut sets, so we know they have
-      // access to switch back.
-      drupal_set_message(t('You are now using the new %set_name shortcut set. You can edit it from this page or <a href="@switch-url">switch back to a different one.</a>', $replacements));
-    }
-    else {
-      drupal_set_message(t('%user is now using a new shortcut set called %set_name. You can edit it from this page.', $replacements));
-    }
-    $form_state['redirect'] = 'admin/config/user-interface/shortcut/' . $set->set_name;
-  }
-  else {
-    // Switch to a different shortcut set.
-    $set = shortcut_set_load($form_state['values']['set']);
-    $replacements = array(
-      '%user' => $account->name,
-      '%set_name' => $set->title,
-    );
-    drupal_set_message($account->uid == $user->uid ? t('You are now using the %set_name shortcut set.', $replacements) : t('%user is now using the %set_name shortcut set.', $replacements));
-  }
-
-  // Assign the shortcut set to the provided user account.
-  shortcut_set_assign_user($set, $account);
-}
-
-/**
- * Menu page callback: builds the page for administering shortcut sets.
- */
-function shortcut_set_admin() {
-  $shortcut_sets = shortcut_sets();
-  $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => 4));
-
-  $rows = array();
-  foreach ($shortcut_sets as $set) {
-    $row = array(
-      check_plain($set->title),
-      l(t('list links'), "admin/config/user-interface/shortcut/$set->set_name"),
-      l(t('edit set name'), "admin/config/user-interface/shortcut/$set->set_name/edit"),
-    );
-    if (shortcut_set_delete_access($set)) {
-      $row[] = l(t('delete set'), "admin/config/user-interface/shortcut/$set->set_name/delete");
-    }
-    else {
-      $row[] = '';
-    }
-
-    $rows[] = $row;
-  }
-
-  return theme('table', array('header' => $header, 'rows' => $rows));
-}
-
-/**
- * Form callback: builds the form for adding a shortcut set.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_set_add_form_validate()
- * @see shortcut_set_add_form_submit()
- */
-function shortcut_set_add_form($form, &$form_state) {
-  $form['new'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Set name'),
-    '#description' => t('The new set is created by copying items from your default shortcut set.'),
-    '#required' => TRUE,
-  );
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Create new set'),
-  );
-
-  return $form;
-}
-
-/**
- * Validation handler for shortcut_set_add_form().
- */
-function shortcut_set_add_form_validate($form, &$form_state) {
-  // Check to prevent a duplicate title.
-  if (shortcut_set_title_exists($form_state['values']['new'])) {
-    form_set_error('new', t('The shortcut set %name already exists. Choose another name.', array('%name' => $form_state['values']['new'])));
-  }
-}
-
-/**
- * Submit handler for shortcut_set_add_form().
- */
-function shortcut_set_add_form_submit($form, &$form_state) {
-  // Save a new shortcut set with links copied from the user's default set.
-  $default_set = shortcut_default_set();
-  $set = (object) array(
-    'title' => $form_state['values']['new'],
-    'links' => menu_links_clone($default_set->links),
-  );
-  shortcut_set_save($set);
-  drupal_set_message(t('The %set_name shortcut set has been created. You can edit it from this page.', array('%set_name' => $set->title)));
-  $form_state['redirect'] = 'admin/config/user-interface/shortcut/' . $set->set_name;
-}
-
-/**
- * Form callback: builds the form for customizing shortcut sets.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param $shortcut_set
- *   An object representing the shortcut set which is being edited.
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_set_customize_submit()
- */
-function shortcut_set_customize($form, &$form_state, $shortcut_set) {
-  $form['shortcuts'] = array(
-    '#tree' => TRUE,
-    '#weight' => -20,
-    'enabled' => array(),
-    'disabled' => array(),
-  );
-
-  foreach ($shortcut_set->links as $link) {
-    $mlid = $link['mlid'];
-    $status = $link['hidden'] ? 'disabled' : 'enabled';
-    $form['shortcuts'][$status][$mlid]['name']['#markup'] = l($link['link_title'], $link['link_path']);
-    $form['shortcuts'][$status][$mlid]['weight'] = array(
-      '#type' => 'weight',
-      '#title' => t('Weight'),
-      '#delta' => 50,
-      '#default_value' => $link['weight'],
-      '#attributes' => array('class' => array('shortcut-weight')),
-    );
-    $form['shortcuts'][$status][$mlid]['status'] = array(
-      '#type' => 'select',
-      '#title' => t('Status'),
-      '#options' => array('disabled' => t('Disabled'), 'enabled' => t('Enabled')),
-      '#default_value' => $status,
-      '#attributes' => array('class' => array('shortcut-status-select')),
-    );
-
-    $form['shortcuts'][$status][$mlid]['edit']['#markup'] = l(t('edit'), 'admin/config/user-interface/shortcut/link/' . $mlid);
-    $form['shortcuts'][$status][$mlid]['delete']['#markup'] = l(t('delete'), 'admin/config/user-interface/shortcut/link/' . $mlid . '/delete');
-  }
-
-  $form['#attached'] = array(
-    'css' => array(drupal_get_path('module', 'shortcut') . '/shortcut.admin.css'),
-    'js' => array(drupal_get_path('module', 'shortcut') . '/shortcut.admin.js'),
-  );
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save changes'),
-  );
-
-  return $form;
-}
-
-/**
- * Submit handler for shortcut_set_customize().
- */
-function shortcut_set_customize_submit($form, &$form_state) {
-  foreach ($form_state['values']['shortcuts'] as $group => $links) {
-    foreach ($links as $mlid => $data) {
-      $link = menu_link_load($mlid);
-      $link['hidden'] = $data['status'] == 'enabled' ? 0 : 1;
-      $link['weight'] = $data['weight'];
-      menu_link_save($link);
-    }
-  }
-  drupal_set_message(t('The shortcut set has been updated.'));
-}
-
-/**
- * Returns HTML for a shortcut set customization form.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @see shortcut_set_customize()
- * @ingroup themeable
- */
-function theme_shortcut_set_customize($variables) {
-  $form = $variables['form'];
-  $map = array('disabled' => t('Disabled'), 'enabled' => t('Enabled'));
-
-  $rows = array();
-  foreach (array('enabled', 'disabled') as $status) {
-    drupal_add_tabledrag('shortcuts', 'match', 'sibling', 'shortcut-status-select');
-    drupal_add_tabledrag('shortcuts', 'order', 'sibling', 'shortcut-weight');
-    $rows[] = array(
-      'data' => array(array(
-        'colspan' => 5,
-        'data' => '<strong>' . $map[$status] . '</strong>',
-      )),
-      'class' => array('shortcut-status', 'shortcut-status-' . $status),
-    );
-
-    foreach (element_children($form['shortcuts'][$status]) as $key) {
-      $shortcut = &$form['shortcuts'][$status][$key];
-      $row = array();
-      $row[] = drupal_render($shortcut['name']);
-      $row[] = drupal_render($shortcut['weight']);
-      $row[] = drupal_render($shortcut['status']);
-      $row[] = drupal_render($shortcut['edit']);
-      $row[] = drupal_render($shortcut['delete']);
-      $rows[] = array(
-        'data' => $row,
-        'class' => array('draggable'),
-      );
-    }
-
-    if ($status == 'enabled') {
-      for ($i = 0; $i < shortcut_max_slots(); $i++) {
-        $rows['empty-' . $i] = array(
-          'data' => array(array(
-            'colspan' => 5,
-            'data' => '<em>' . t('Empty') . '</em>',
-          )),
-          'class' => array('shortcut-slot-empty'),
-        );
-      }
-      $count_shortcuts = count(element_children($form['shortcuts'][$status]));
-      if (!empty($count_shortcuts)) {
-        for ($i = 0; $i < min($count_shortcuts, shortcut_max_slots()); $i++) {
-          $rows['empty-' . $i]['class'][] = 'shortcut-slot-hidden';
-        }
-      }
-    }
-  }
-
-  $header = array(t('Name'), t('Weight'), t('Status'), array('data' => t('Operations'), 'colspan' => 2));
-  $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'shortcuts')));
-  $output .= drupal_render($form['actions']);
-  $output = drupal_render_children($form) . $output;
-  return $output;
-}
-
-/**
- * Form callback: builds the form for adding a new shortcut link.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param $shortcut_set
- *   An object representing the shortcut set to which the link will be added.
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_link_edit_validate()
- * @see shortcut_link_add_submit()
- */
-function shortcut_link_add($form, &$form_state, $shortcut_set) {
-  drupal_set_title(t('Add new shortcut'));
-  $form['shortcut_set'] = array(
-    '#type' => 'value',
-    '#value' => $shortcut_set,
-  );
-  $form += _shortcut_link_form_elements();
-  return $form;
-}
-
-/**
- * Form callback: builds the form for editing a shortcut link.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param $shortcut_link
- *   An array representing the link that is being edited.
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_link_edit_validate()
- * @see shortcut_link_edit_submit()
- */
-function shortcut_link_edit($form, &$form_state, $shortcut_link) {
-  drupal_set_title(t('Editing @shortcut', array('@shortcut' => $shortcut_link['link_title'])));
-  $form['original_shortcut_link'] = array(
-    '#type' => 'value',
-    '#value' => $shortcut_link,
-  );
-  $form += _shortcut_link_form_elements($shortcut_link);
-  return $form;
-}
-
-/**
- * Helper function for building a form for adding or editing shortcut links.
- *
- * @param $shortcut_link
- *   (optional) An array representing the shortcut link that will be edited. If
- *   not provided, a new link will be created.
- *
- * @return
- *   An array of form elements.
- */
-function _shortcut_link_form_elements($shortcut_link = NULL) {
-  if (!isset($shortcut_link)) {
-    $shortcut_link = array(
-      'link_title' => '',
-      'link_path' => ''
-    );
-  }
-  else {
-    $shortcut_link['link_path'] = drupal_get_path_alias($shortcut_link['link_path']);
-  }
-
-  $form['shortcut_link']['#tree'] = TRUE;
-  $form['shortcut_link']['link_title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Name'),
-    '#description' => t('The name of the shortcut.'),
-    '#size' => 40,
-    '#maxlength' => 255,
-    '#default_value' => $shortcut_link['link_title'],
-  );
-
-  $form['shortcut_link']['link_path'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Path'),
-    '#description' => t('The path to the shortcut.'),
-    '#size' => 40,
-    '#maxlength' => 255,
-    '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='),
-    '#default_value' => $shortcut_link['link_path'],
-  );
-
-  $form['#validate'][] = 'shortcut_link_edit_validate';
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
-
-  return $form;
-}
-
-/**
- * Validation handler for the shortcut link add and edit forms.
- */
-function shortcut_link_edit_validate($form, &$form_state) {
-  if (!shortcut_valid_link($form_state['values']['shortcut_link']['link_path'])) {
-    form_set_error('shortcut_link][link_path', t('The link must correspond to a valid path on the site.'));
-  }
-}
-
-/**
- * Submit handler for shortcut_link_edit().
- */
-function shortcut_link_edit_submit($form, &$form_state) {
-  // Normalize the path in case it is an alias.
-  $form_state['values']['shortcut_link']['link_path'] = drupal_get_normal_path($form_state['values']['shortcut_link']['link_path']);
-
-  $shortcut_link = array_merge($form_state['values']['original_shortcut_link'], $form_state['values']['shortcut_link']);
-
-  menu_link_save($shortcut_link);
-  $form_state['redirect'] = 'admin/config/user-interface/shortcut/' . $shortcut_link['menu_name'];
-  drupal_set_message(t('The shortcut %link has been updated.', array('%link' => $shortcut_link['link_title'])));
-}
-
-/**
- * Submit handler for shortcut_link_add().
- */
-function shortcut_link_add_submit($form, &$form_state) {
-  // Add the shortcut link to the set.
-  $shortcut_set = $form_state['values']['shortcut_set'];
-  $shortcut_link = $form_state['values']['shortcut_link'];
-  $shortcut_link['menu_name'] = $shortcut_set->set_name;
-  shortcut_admin_add_link($shortcut_link, $shortcut_set, shortcut_max_slots());
-  shortcut_set_save($shortcut_set);
-  $form_state['redirect'] = 'admin/config/user-interface/shortcut/' . $shortcut_link['menu_name'];
-  drupal_set_message(t('Added a shortcut for %title.', array('%title' => $shortcut_link['link_title'])));
-}
-
-/**
- * Adds a link to the end of a shortcut set, keeping within a prescribed limit.
- *
- * @param $link
- *   An array representing a shortcut link.
- * @param $shortcut_set
- *   An object representing the shortcut set which the link will be added to.
- *   The links in the shortcut set will be re-weighted so that the new link is
- *   at the end, and some existing links may be disabled (if the $limit
- *   parameter is provided).
- * @param $limit
- *   (optional) The maximum number of links that are allowed to be enabled for
- *   this shortcut set. If provided, existing links at the end of the list that
- *   exceed the limit will be automatically disabled. If not provided, no limit
- *   will be enforced.
- */
-function shortcut_admin_add_link($shortcut_link, &$shortcut_set, $limit = NULL) {
-  if (isset($limit)) {
-    // Disable any existing links at the end of the list that would cause the
-    // limit to be exceeded. Take into account whether or not the new link will
-    // be enabled and count towards the total.
-    $number_enabled = !empty($shortcut_link['hidden']) ? 0 : 1;
-    foreach ($shortcut_set->links as &$link) {
-      if (!$link['hidden']) {
-        $number_enabled++;
-        if ($number_enabled > $limit) {
-          $link['hidden'] = 1;
-        }
-      }
-    }
-  }
-
-  // Normalize the path in case it is an alias.
-  $shortcut_link['link_path'] = drupal_get_normal_path($shortcut_link['link_path']);
-
-  // Add the link to the end of the list.
-  $shortcut_set->links[] = $shortcut_link;
-  shortcut_set_reset_link_weights($shortcut_set);
-}
-
-/**
- * Form callback: builds the form for editing the shortcut set name.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param object $shortcut_set
- *   An object representing the shortcut set, as returned from
- *   shortcut_set_load().
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_set_edit_form_validate()
- * @see shortcut_set_edit_form_submit()
- */
-function shortcut_set_edit_form($form, &$form_state, $shortcut_set) {
-  $form['shortcut_set'] = array(
-    '#type' => 'value',
-    '#value' => $shortcut_set,
-  );
-  $form['title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Set name'),
-    '#default_value' => $shortcut_set->title,
-    '#maxlength' => 255,
-    '#required' => TRUE,
-    '#weight' => -5,
-  );
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-    '#weight' => 5,
-  );
-
-  return $form;
-}
-
-/**
- * Validation handler for shortcut_set_edit_form().
- */
-function shortcut_set_edit_form_validate($form, &$form_state) {
-  // Check to prevent a duplicate title, if the title was edited from its
-  // original value.
-  if ($form_state['values']['title'] != $form_state['values']['shortcut_set']->title && shortcut_set_title_exists($form_state['values']['title'])) {
-    form_set_error('title', t('The shortcut set %name already exists. Choose another name.', array('%name' => $form_state['values']['title'])));
-  }
-}
-
-/**
- * Submit handler for shortcut_set_edit_form().
- */
-function shortcut_set_edit_form_submit($form, &$form_state) {
-  $shortcut_set = $form_state['values']['shortcut_set'];
-  $shortcut_set->title = $form_state['values']['title'];
-  shortcut_set_save($shortcut_set);
-  drupal_set_message(t('Updated set name to %set-name.', array('%set-name' => $shortcut_set->title)));
-  $form_state['redirect'] = "admin/config/user-interface/shortcut/$shortcut_set->set_name";
-}
-
-/**
- * Form callback: builds the confirmation form for deleting a shortcut set.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param object $shortcut_set
- *   An object representing the shortcut set, as returned from
- *   shortcut_set_load().
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_set_delete_form_submit()
- */
-function shortcut_set_delete_form($form, &$form_state, $shortcut_set) {
-  $form['shortcut_set'] = array(
-    '#type' => 'value',
-    '#value' => $shortcut_set->set_name,
-  );
-
-  // Find out how many users are directly assigned to this shortcut set, and
-  // make a message.
-  $number = db_query('SELECT COUNT(*) FROM {shortcut_set_users} WHERE set_name = :name', array(':name' => $shortcut_set->set_name))->fetchField();
-  $info = '';
-  if ($number) {
-    $info .= '<p>' . format_plural($number,
-      '1 user has chosen or been assigned to this shortcut set.',
-      '@count users have chosen or been assigned to this shortcut set.') . '</p>';
-  }
-
-  // Also, if a module implements hook_shortcut_default_set(), it's possible
-  // that this set is being used as a default set. Add a message about that too.
-  if (count(module_implements('shortcut_default_set')) > 0) {
-    $info .= '<p>' . t('If you have chosen this shortcut set as the default for some or all users, they may also be affected by deleting it.') . '</p>';
-  }
-
-  $form['info'] = array(
-    '#markup' => $info,
-  );
-
-  return confirm_form(
-    $form,
-    t('Are you sure you want to delete the shortcut set %title?', array('%title' => $shortcut_set->title)),
-    'admin/config/user-interface/shortcut/' . $shortcut_set->set_name,
-    t('This action cannot be undone.'),
-    t('Delete'),
-    t('Cancel')
-  );
-}
-
-/**
- * Submit handler for shortcut_set_delete_form().
- */
-function shortcut_set_delete_form_submit($form, &$form_state) {
-  $shortcut_set = shortcut_set_load($form_state['values']['shortcut_set']);
-  shortcut_set_delete($shortcut_set);
-  $form_state['redirect'] = 'admin/config/user-interface/shortcut';
-  drupal_set_message(t('The shortcut set %title has been deleted.', array('%title' => $shortcut_set->title)));
-}
-
-/**
- * Form callback: builds the confirmation form for deleting a shortcut link.
- *
- * @param $form
- *   An associative array containing the structure of the form.
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param $shortcut_link
- *   An array representing the link that will be deleted.
- *
- * @return
- *   An array representing the form definition.
- *
- * @ingroup forms
- * @see shortcut_link_delete_submit()
- */
-function shortcut_link_delete($form, &$form_state, $shortcut_link) {
-  $form['shortcut_link'] = array(
-    '#type' => 'value',
-    '#value' => $shortcut_link,
-  );
-
-  return confirm_form(
-    $form,
-    t('Are you sure you want to delete the shortcut %title?', array('%title' => $shortcut_link['link_title'])),
-    'admin/config/user-interface/shortcut/' . $shortcut_link['menu_name'],
-    t('This action cannot be undone.'),
-    t('Delete'),
-    t('Cancel')
-  );
-}
-
-/**
- * Submit handler for shortcut_link_delete_submit().
- */
-function shortcut_link_delete_submit($form, &$form_state) {
-  $shortcut_link = $form_state['values']['shortcut_link'];
-  menu_link_delete($shortcut_link['mlid']);
-  $form_state['redirect'] = 'admin/config/user-interface/shortcut/' . $shortcut_link['menu_name'];
-  drupal_set_message(t('The shortcut %title has been deleted.', array('%title' => $shortcut_link['link_title'])));
-}
-
-/**
- * Menu page callback: creates a new link in the provided shortcut set.
- *
- * After completion, redirects the user back to where they came from.
- *
- * @param $shortcut_set
- *   Returned from shortcut_set_load().
- */
-function shortcut_link_add_inline($shortcut_set) {
-  if (isset($_REQUEST['token']) && drupal_valid_token($_REQUEST['token'], 'shortcut-add-link') && shortcut_valid_link($_GET['link'])) {
-    $item = menu_get_item($_GET['link']);
-    $title = ($item && $item['title']) ? $item['title'] : $_GET['name'];
-    $link = array(
-      'link_title' => $title,
-      'link_path' => $_GET['link'],
-    );
-    shortcut_admin_add_link($link, $shortcut_set, shortcut_max_slots());
-    if (shortcut_set_save($shortcut_set)) {
-      drupal_set_message(t('Added a shortcut for %title.', array('%title' => $link['link_title'])));
-    }
-    else {
-      drupal_set_message(t('Unable to add a shortcut for %title.', array('%title' => $link['link_title'])));
-    }
-    drupal_goto();
-  }
-
-  return drupal_access_denied();
-}
diff --git a/modules/shortcut/shortcut.admin.js b/modules/shortcut/shortcut.admin.js
deleted file mode 100644
index 5e71e6f..0000000
--- a/modules/shortcut/shortcut.admin.js
+++ /dev/null
@@ -1,99 +0,0 @@
-(function ($) {
-
-/**
- * Handle the concept of a fixed number of slots.
- *
- * This behavior is dependent on the tableDrag behavior, since it uses the
- * objects initialized in that behavior to update the row.
- */
-Drupal.behaviors.shortcutDrag = {
-  attach: function (context, settings) {
-    if (Drupal.tableDrag) {
-      var table = $('table#shortcuts'),
-        visibleLength = 0,
-        slots = 0,
-        tableDrag = Drupal.tableDrag.shortcuts;
-      $('> tbody > tr, > tr', table)
-        .filter(':visible')
-          .filter(':odd').filter('.odd')
-            .removeClass('odd').addClass('even')
-          .end().end()
-          .filter(':even').filter('.even')
-            .removeClass('even').addClass('odd')
-          .end().end()
-        .end()
-        .filter('.shortcut-slot-empty').each(function(index) {
-          if ($(this).is(':visible')) {
-            visibleLength++;
-          }
-          slots++;
-        });
-
-      // Add a handler for when a row is swapped.
-      tableDrag.row.prototype.onSwap = function (swappedRow) {
-        var disabledIndex = $(table).find('tr').index($(table).find('tr.shortcut-status-disabled')) - slots - 2,
-          count = 0;
-        $(table).find('tr.shortcut-status-enabled').nextAll().filter(':not(.shortcut-slot-empty)').each(function(index) {
-          if (index < disabledIndex) {
-            count++;
-          }
-        });
-        var total = slots - count;
-        if (total == -1) {
-          var disabled = $(table).find('tr.shortcut-status-disabled');
-          disabled.after(disabled.prevAll().filter(':not(.shortcut-slot-empty)').get(0));
-        }
-        else if (total != visibleLength) {
-          if (total > visibleLength) {
-            // Less slots on screen than needed.
-            $('.shortcut-slot-empty:hidden:last').show();
-            visibleLength++;
-          }
-          else {
-            // More slots on screen than needed.
-            $('.shortcut-slot-empty:visible:last').hide();
-            visibleLength--;
-          }
-        }
-      };
-
-      // Add a handler so when a row is dropped, update fields dropped into new regions.
-      tableDrag.onDrop = function () {
-        // Use "status-message" row instead of "status" row because
-        // "status-{status_name}-message" is less prone to regexp match errors.
-        var statusRow = $(this.rowObject.element).prevAll('tr.shortcut-status').get(0);
-        var statusName = statusRow.className.replace(/([^ ]+[ ]+)*shortcut-status-([^ ]+)([ ]+[^ ]+)*/, '$2');
-        var statusField = $('select.shortcut-status-select', this.rowObject.element);
-        statusField.val(statusName);
-        return true;
-      };
-
-      tableDrag.restripeTable = function () {
-        // :even and :odd are reversed because jQuery counts from 0 and
-        // we count from 1, so we're out of sync.
-        // Match immediate children of the parent element to allow nesting.
-        $('> tbody > tr:visible, > tr:visible', this.table)
-          .filter(':odd').filter('.odd')
-            .removeClass('odd').addClass('even')
-          .end().end()
-          .filter(':even').filter('.even')
-            .removeClass('even').addClass('odd');
-      };
-    }
-  }
-};
-
-/**
- * Make it so when you enter text into the "New set" textfield, the
- * corresponding radio button gets selected.
- */
-Drupal.behaviors.newSet = {
-  attach: function (context, settings) {
-    var selectDefault = function() {
-      $($(this).parents('div.form-item').get(1)).find('> label > input').attr('checked', 'checked');
-    };
-    $('div.form-item-new input').focus(selectDefault).keyup(selectDefault);
-  }
-};
-
-})(jQuery);
diff --git a/modules/shortcut/shortcut.api.php b/modules/shortcut/shortcut.api.php
deleted file mode 100644
index 717a7c9..0000000
--- a/modules/shortcut/shortcut.api.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Hooks provided by the Shortcut module.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Return the name of a default shortcut set for the provided user account.
- *
- * This hook allows modules to define default shortcut sets for a particular
- * user that differ from the site-wide default (for example, a module may want
- * to define default shortcuts on a per-role basis).
- *
- * The default shortcut set is used only when the user does not have any other
- * shortcut set explicitly assigned to them.
- *
- * Note that only one default shortcut set can exist per user, so when multiple
- * modules implement this hook, the last (i.e., highest weighted) module which
- * returns a valid shortcut set name will prevail.
- *
- * @param $account
- *   The user account whose default shortcut set is being requested.
- * @return
- *   The name of the shortcut set that this module recommends for that user, if
- *   there is one.
- */
-function hook_shortcut_default_set($account) {
-  // Use a special set of default shortcuts for administrators only.
-  if (in_array(variable_get('user_admin_role', 0), $account->roles)) {
-    return variable_get('mymodule_shortcut_admin_default_set');
-  }
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/modules/shortcut/shortcut.css b/modules/shortcut/shortcut.css
deleted file mode 100644
index 3afcb94..0000000
--- a/modules/shortcut/shortcut.css
+++ /dev/null
@@ -1,106 +0,0 @@
-div#toolbar a#edit-shortcuts {
-  float: right;
-  padding: 5px 10px 5px 5px;
-  line-height: 24px;
-  color: #fefefe;
-}
-div#toolbar a#edit-shortcuts:focus,
-div#toolbar a#edit-shortcuts:hover,
-div#toolbar a#edit-shortcuts.active {
-  color: #fff;
-  text-decoration: underline;
-}
-
-div#toolbar div.toolbar-shortcuts ul {
-  padding: 5px 0 2px 0;
-  height: 28px;
-  line-height: 24px;
-  float: left; /* LTR */
-  margin-left:5px; /* LTR */
-}
-
-div#toolbar div.toolbar-shortcuts ul li a {
-  padding: 0 5px 0 5px;
-  margin-right: 5px; /* LTR */
-  -moz-border-radius: 5px;
-  -webkit-border-radius: 5px;
-  border-radius: 5px;
-}
-
-div#toolbar div.toolbar-shortcuts ul li a:focus,
-div#toolbar div.toolbar-shortcuts ul li a:hover,
-div#toolbar div.toolbar-shortcuts ul li a.active:focus {
-  background: #555;
-}
-
-div#toolbar div.toolbar-shortcuts ul li a.active:hover,
-div#toolbar div.toolbar-shortcuts ul li a.active {
-  background: #000;
-}
-
-div#toolbar div.toolbar-shortcuts span.icon {
-  float: left; /* LTR */
-  background: #444;
-  width: 30px;
-  height: 30px;
-  margin-right: 5px; /* LTR */
-  -moz-border-radius: 5px;
-  -webkit-border-radius: 5px;
-  border-radius: 5px;
-}
-
-div.add-or-remove-shortcuts {
-  padding-top: 5px;
-}
-
-div.add-or-remove-shortcuts a span.icon {
-  display: block;
-  width: 12px;
-  background: transparent url(shortcut.png) no-repeat scroll 0 0;
-  height: 12px;
-  float: left;
-  margin-left:8px;
-}
-
-div.add-shortcut a:focus span.icon,
-div.add-shortcut a:hover span.icon {
-  background-position: 0 -12px;
-}
-div.remove-shortcut a span.icon {
-  background-position: -12px 0;
-}
-div.remove-shortcut a:focus span.icon,
-div.remove-shortcut a:hover span.icon {
-  background-position: -12px -12px;
-}
-
-div.add-or-remove-shortcuts a span.text {
-  float: left;
-  padding-left:10px;
-  display: none;
-}
-
-div.add-or-remove-shortcuts a:focus span.text,
-div.add-or-remove-shortcuts a:hover span.text {
-  font-size: 10px;
-  line-height: 12px;
-  color: #fff;
-  background-color: #5f605b;
-  display: block;
-  padding-right: 6px; /* LTR */
-  cursor: pointer;
-  -moz-border-radius: 0 5px 5px 0; /* LTR */
-  -webkit-border-top-right-radius: 5px; /* LTR */
-  -webkit-border-bottom-right-radius: 5px; /* LTR */
-  border-radius: 0 5px 5px 0; /* LTR */
-}
-
-#shortcut-set-switch .form-type-radios {
-  padding-bottom: 0;
-  margin-bottom: 0;
-}
-
-#shortcut-set-switch .form-item-new {
-  padding-top: 0;
-  padding-left: 17px; /* LTR */
-}
diff --git a/modules/shortcut/shortcut.info b/modules/shortcut/shortcut.info
deleted file mode 100644
index 0030605..0000000
--- a/modules/shortcut/shortcut.info
+++ /dev/null
@@ -1,7 +0,0 @@
-name = Shortcut
-description = Allows users to manage customizable lists of shortcut links.
-package = Core
-version = VERSION
-core = 8.x
-files[] = shortcut.test
-configure = admin/config/user-interface/shortcut
diff --git a/modules/shortcut/shortcut.install b/modules/shortcut/shortcut.install
deleted file mode 100644
index 7aee9c9..0000000
--- a/modules/shortcut/shortcut.install
+++ /dev/null
@@ -1,116 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the shortcut module.
- */
-
-/**
- * Implements hook_install().
- */
-function shortcut_install() {
-  $t = get_t();
-  // Create an initial default shortcut set.
-  $shortcut_set = new stdClass();
-  $shortcut_set->title = $t('Default');
-  $shortcut_set->links = array();
-  if (module_exists('node')) {
-    $shortcut_set->links[] = array(
-      'link_path' => 'node/add',
-      'link_title' => $t('Add content'),
-      'weight' => -20,
-    );
-    $shortcut_set->links[] = array(
-      'link_path' => 'admin/content',
-      'link_title' => $t('Find content'),
-      'weight' => -19,
-    );
-  }
-  // If Drupal is being installed, rebuild the menu before saving the shortcut
-  // set, to make sure the links defined above can be correctly saved. (During
-  // installation, the menu might not have been built at all yet, or it might
-  // have been built but without the node module's links in it.)
-  if (drupal_installation_attempted()) {
-    menu_rebuild();
-  }
-  shortcut_set_save($shortcut_set);
-}
-
-/**
- * Implements hook_uninstall().
- */
-function shortcut_uninstall() {
-  drupal_load('module', 'shortcut');
-  // Delete the menu links associated with each shortcut set.
-  foreach (shortcut_sets() as $shortcut_set) {
-    menu_delete_links($shortcut_set->set_name);
-  }
-}
-
-/**
- * Implements hook_schema().
- */
-function shortcut_schema() {
-  $schema['shortcut_set'] = array(
-    'description' => 'Stores information about sets of shortcuts links.',
-    'fields' => array(
-      'set_name' => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => "Primary Key: The {menu_links}.menu_name under which the set's links are stored.",
-      ),
-      'title' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The title of the set.',
-      ),
-    ),
-    'primary key' => array('set_name'),
-    'foreign keys' => array(
-      'menu_name' => array(
-        'table' => 'menu_links',
-        'columns' => array('set_name' => 'menu_name'),
-      ),
-    ),
-  );
-
-  $schema['shortcut_set_users'] = array(
-    'description' => 'Maps users to shortcut sets.',
-    'fields' => array(
-      'uid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'The {users}.uid for this set.',
-      ),
-      'set_name' => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => "The {shortcut_set}.set_name that will be displayed for this user.",
-      ),
-    ),
-    'primary key' => array('uid'),
-    'indexes' => array(
-      'set_name' => array('set_name'),
-    ),
-    'foreign keys' => array(
-      'set_user' => array(
-        'table' => 'users',
-        'columns' => array('uid' => 'uid'),
-      ),
-      'set_name' => array(
-        'table' => 'shortcut_set',
-        'columns' => array('set_name' => 'set_name'),
-      ),
-    ),
-  );
-
-  return $schema;
-}
diff --git a/modules/shortcut/shortcut.module b/modules/shortcut/shortcut.module
deleted file mode 100644
index 8642d9d..0000000
--- a/modules/shortcut/shortcut.module
+++ /dev/null
@@ -1,745 +0,0 @@
-<?php
-
-/**
- * @file
- * Allows users to manage customizable lists of shortcut links.
- */
-
-/**
- * The name of the default shortcut set.
- *
- * This set will be displayed to any user that does not have another set
- * assigned, unless overridden by a hook_shortcut_default_set() implementation.
- */
-define('SHORTCUT_DEFAULT_SET_NAME', 'shortcut-set-1');
-
-/**
- * Implements hook_help().
- */
-function shortcut_help($path, $arg) {
-  global $user;
-
-  switch ($path) {
-    case 'admin/help#shortcut':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Shortcut module allows users to create sets of <em>shortcut</em> links to commonly-visited pages of the site. Shortcuts are contained within <em>sets</em>. Each user with <em>Select any shortcut set</em> permission can select a shortcut set created by anyone at the site. For more information, see the online handbook entry for <a href="@shortcut">Shortcut module</a>.', array('@shortcut' => 'http://drupal.org/handbook/modules/shortcut/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl><dt>' . t('Administering shortcuts') . '</dt>';
-      $output .= '<dd>' . t('Users with the <em>Administer shortcuts</em> permission can manage shortcut sets and edit the shortcuts within sets from the <a href="@shortcuts">Shortcuts administration page</a>.', array('@shortcuts' => url('admin/config/user-interface/shortcut'))) . '</dd>';
-      $output .= '<dt>' . t('Choosing shortcut sets') . '</dt>';
-      $output .= '<dd>' . t('Users with permission to switch shortcut sets can choose a shortcut set to use from the Shortcuts tab of their user account page.') . '</dd>';
-      $output .= '<dt>' . t('Adding and removing shortcuts') . '</dt>';
-      $output .= '<dd>' . t('The Shortcut module creates an add/remove link for each page on your site; the link lets you add or remove the current page from the currently-enabled set of shortcuts (if your theme displays it and you have permission to edit your shortcut set). The core Seven administration theme displays this link next to the page title, as a small + or - sign. If you click on the + sign, you will add that page to your preferred set of shortcuts. If the page is already part of your shortcut set, the link will be a - sign, and will allow you to remove the current page from your shortcut set.') . '</dd>';
-      $output .= '<dt>' . t('Displaying shortcuts') . '</dt>';
-      $output .= '<dd>' . t('You can display your shortcuts by enabling the Shortcuts block on the <a href="@blocks">Blocks administration page</a>. Certain administrative modules also display your shortcuts; for example, the core <a href="@toolbar-help">Toolbar module</a> displays them near the top of the page, along with an <em>Edit shortcuts</em> link.', array('@blocks' => url('admin/structure/block'), '@toolbar-help' => url('admin/help/toolbar'))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-
-    case 'admin/config/user-interface/shortcut':
-    case 'admin/config/user-interface/shortcut/%':
-      if (user_access('switch shortcut sets')) {
-        $output = '<p>' . t('Define which shortcut set you are using on the <a href="@shortcut-link">Shortcuts tab</a> of your account page.', array('@shortcut-link' => url("user/{$user->uid}/shortcuts"))) . '</p>';
-        return $output;
-      }
-  }
-}
-
-/**
- * Implements hook_permission().
- */
-function shortcut_permission() {
-  return array(
-    'administer shortcuts' => array(
-      'title' => t('Administer shortcuts'),
-    ),
-    'customize shortcut links' => array(
-      'title' => t('Edit current shortcut set'),
-      'description' => t('Editing the current shortcut set will affect other users if that set has been assigned to or selected by other users. Granting "Select any shortcut set" permission along with this permission will grant permission to edit any shortcut set.'),
-    ),
-    'switch shortcut sets' => array(
-      'title' => t('Select any shortcut set'),
-      'description' => t('From all shortcut sets, select one to be own active set. Without this permission, an administrator selects shortcut sets for users.'),
-    ),
-  );
-}
-
-/**
- * Implements hook_menu().
- */
-function shortcut_menu() {
-  $items['admin/config/user-interface/shortcut'] = array(
-    'title' => 'Shortcuts',
-    'description' => 'Add and modify shortcut sets.',
-    'page callback' => 'shortcut_set_admin',
-    'access arguments' => array('administer shortcuts'),
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/add-set'] = array(
-    'title' => 'Add shortcut set',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_set_add_form'),
-    'access arguments' => array('administer shortcuts'),
-    'type' => MENU_LOCAL_ACTION,
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/%shortcut_set'] = array(
-    'title' => 'Edit shortcuts',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_set_customize', 4),
-    'title callback' => 'shortcut_set_title',
-    'title arguments' => array(4),
-    'access callback' => 'shortcut_set_edit_access',
-    'access arguments' => array(4),
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/%shortcut_set/links'] = array(
-    'title' => 'List links',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-  );
-  $items['admin/config/user-interface/shortcut/%shortcut_set/edit'] = array(
-    'title' => 'Edit set name',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_set_edit_form', 4),
-    'access callback' => 'shortcut_set_edit_access',
-    'access arguments' => array(4),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'shortcut.admin.inc',
-    'weight' => 10,
-  );
-  $items['admin/config/user-interface/shortcut/%shortcut_set/delete'] = array(
-    'title' => 'Delete shortcut set',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_set_delete_form', 4),
-    'access callback' => 'shortcut_set_delete_access',
-    'access arguments' => array(4),
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/%shortcut_set/add-link'] = array(
-    'title' => 'Add shortcut',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_link_add', 4),
-    'access callback' => 'shortcut_set_edit_access',
-    'access arguments' => array(4),
-    'type' => MENU_LOCAL_ACTION,
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/%shortcut_set/add-link-inline'] = array(
-    'title' => 'Add shortcut',
-    'page callback' => 'shortcut_link_add_inline',
-    'page arguments' => array(4),
-    'access callback' => 'shortcut_set_edit_access',
-    'access arguments' => array(4),
-    'type' => MENU_CALLBACK,
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/link/%menu_link'] = array(
-    'title' => 'Edit shortcut',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_link_edit', 5),
-    'access callback' => 'shortcut_link_access',
-    'access arguments' => array(5),
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['admin/config/user-interface/shortcut/link/%menu_link/delete'] = array(
-    'title' => 'Delete shortcut',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_link_delete', 5),
-    'access callback' => 'shortcut_link_access',
-    'access arguments' => array(5),
-    'file' => 'shortcut.admin.inc',
-  );
-  $items['user/%user/shortcuts'] = array(
-    'title' => 'Shortcuts',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('shortcut_set_switch', 1),
-    'access callback' => 'shortcut_set_switch_access',
-    'access arguments' => array(1),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'shortcut.admin.inc',
-  );
-
-  return $items;
-}
-
-/**
- * Implements hook_admin_paths().
- */
-function shortcut_admin_paths() {
-  $paths = array(
-    'user/*/shortcuts' => TRUE,
-  );
-  return $paths;
-}
-
-/**
- * Implements hook_theme().
- */
-function shortcut_theme() {
-  return array(
-    'shortcut_set_customize' => array(
-      'render element' => 'form',
-      'file' => 'shortcut.admin.inc',
-    ),
-  );
-}
-
-/**
- * Implements hook_block_info().
- */
-function shortcut_block_info() {
-  $blocks['shortcuts']['info'] = t('Shortcuts');
-  // Shortcut blocks can't be cached because each menu item can have a custom
-  // access callback. menu.inc manages its own caching.
-  $blocks['shortcuts']['cache'] = DRUPAL_NO_CACHE;
-  return $blocks;
-}
-
-/**
- * Implements hook_block_view().
- */
-function shortcut_block_view($delta = '') {
-  if ($delta == 'shortcuts') {
-    $shortcut_set = shortcut_current_displayed_set();
-    $data['subject'] = t('@shortcut_set shortcuts', array('@shortcut_set' => $shortcut_set->title));
-    $data['content'] = shortcut_renderable_links($shortcut_set);
-    return $data;
-  }
-}
-
-/**
- * Access callback for editing a shortcut set.
- *
- * @param object $shortcut_set
- *   (optional) The shortcut set to be edited. If not set, the current user's
- *   shortcut set will be used.
- *
- * @return
- *   TRUE if the current user has access to edit the shortcut set, FALSE
- *   otherwise.
- */
-function shortcut_set_edit_access($shortcut_set = NULL) {
-  // Sufficiently-privileged users can edit their currently displayed shortcut
-  // set, but not other sets. Shortcut administrators can edit any set.
-  if (user_access('administer shortcuts')) {
-    return TRUE;
-  }
-  if (user_access('customize shortcut links')) {
-    return !isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set();
-  }
-  return FALSE;
-}
-
-/**
- * Access callback for deleting a shortcut set.
- *
- * @param $shortcut_set
- *   The shortcut set to be deleted.
- *
- * @return
- *   TRUE if the current user has access to delete shortcut sets and this is
- *   not the site-wide default set; FALSE otherwise.
- */
-function shortcut_set_delete_access($shortcut_set) {
-  // Only admins can delete sets.
-  if (!user_access('administer shortcuts')) {
-    return FALSE;
-  }
-
-  // Never let the default shortcut set be deleted.
-  if ($shortcut_set->set_name == SHORTCUT_DEFAULT_SET_NAME) {
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * Access callback for switching the shortcut set assigned to a user account.
- *
- * @param object $account
- *   (optional) The user account whose shortcuts will be switched. If not set,
- *   permissions will be checked for switching the logged-in user's own
- *   shortcut set.
- *
- * @return
- *   TRUE if the current user has access to switch the shortcut set of the
- *   provided account, FALSE otherwise.
- */
-function shortcut_set_switch_access($account = NULL) {
-  global $user;
-
-  if (user_access('administer shortcuts')) {
-    // Administrators can switch anyone's shortcut set.
-    return TRUE;
-  }
-
-  if (!user_access('switch shortcut sets')) {
-    // The user has no permission to switch anyone's shortcut set.
-    return FALSE;
-  }
-
-  if (!isset($account) || $user->uid == $account->uid) {
-    // Users with the 'switch shortcut sets' permission can switch their own
-    // shortcuts sets.
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-/**
- * Access callback for editing a link in a shortcut set.
- */
-function shortcut_link_access($menu_link) {
-  // The link must belong to a shortcut set that the current user has access
-  // to edit.
-  if ($shortcut_set = shortcut_set_load($menu_link['menu_name'])) {
-    return shortcut_set_edit_access($shortcut_set);
-  }
-  return FALSE;
-}
-
-/**
- * Loads the data for a shortcut set.
- *
- * @param $set_name
- *   The name of the shortcut set to load.
- *
- * @return object
- *   If the shortcut set exists, an object containing the following properties:
- *   - 'set_name': The internal name of the shortcut set.
- *   - 'title': The title of the shortcut set.
- *   - 'links': An array of links associated with this shortcut set.
- *   If the shortcut set does not exist, the function returns FALSE.
- */
-function shortcut_set_load($set_name) {
-  $set = db_select('shortcut_set', 'ss')
-  ->fields('ss')
-  ->condition('set_name', $set_name)
-  ->execute()
-  ->fetchObject();
-  if (!$set) {
-    return FALSE;
-  }
-  $set->links = menu_load_links($set_name);
-  return $set;
-}
-
-/**
- * Saves a shortcut set.
- *
- * @param $shortcut_set
- *   An object containing the following properties:
- *   - 'title': The title of the shortcut set.
- *   - 'set_name': (optional) The internal name of the shortcut set. If
- *     omitted, a new shortcut set will be created, and the 'set_name' property
- *     will be added to the passed-in object.
- *   - 'links': (optional) An array of menu links to save for the shortcut set.
- *     Each link is an array containing at least the following keys (which will
- *     be expanded to fill in other default values after the shortcut set is
- *     saved):
- *     - 'link_path': The Drupal path or external path that the link points to.
- *     - 'link_title': The title of the link.
- *     Any other keys accepted by menu_link_save() may also be provided.
- *
- * @return
- *   A constant which is either SAVED_NEW or SAVED_UPDATED depending on whether
- *   a new set was created or an existing one was updated.
- *
- * @see menu_link_save()
- */
-function shortcut_set_save(&$shortcut_set) {
-  // First save the shortcut set itself.
-  if (isset($shortcut_set->set_name)) {
-    $return = drupal_write_record('shortcut_set', $shortcut_set, 'set_name');
-  }
-  else {
-    $shortcut_set->set_name = shortcut_set_get_unique_name();
-    $return = drupal_write_record('shortcut_set', $shortcut_set);
-  }
-  // If links were provided for the set, save them.
-  if (isset($shortcut_set->links)) {
-    foreach ($shortcut_set->links as &$link) {
-      // Do not specifically associate these links with the shortcut module,
-      // since other modules may make them editable via the menu system.
-      // However, we do need to specify the correct menu name.
-      $link['menu_name'] = $shortcut_set->set_name;
-      $link['plid'] = 0;
-      menu_link_save($link);
-    }
-    // Make sure that we have a return value, since if the links were updated
-    // but the shortcut set was not, the call to drupal_write_record() above
-    // would not return an indication that anything had changed.
-    if (empty($return)) {
-      $return = SAVED_UPDATED;
-    }
-  }
-  return $return;
-}
-
-/**
- * Deletes a shortcut set.
- *
- * Note that the default set cannot be deleted.
- *
- * @param $shortcut_set
- *   An object representing the shortcut set to delete.
- *
- * @return
- *   TRUE if the set was deleted, FALSE otherwise.
- */
-function shortcut_set_delete($shortcut_set) {
-  // Don't allow deletion of the system default shortcut set.
-  if ($shortcut_set->set_name == SHORTCUT_DEFAULT_SET_NAME) {
-    return FALSE;
-  }
-
-  // First, delete any user assignments for this set, so that each of these
-  // users will go back to using whatever default set applies.
-  db_delete('shortcut_set_users')
-    ->condition('set_name', $shortcut_set->set_name)
-    ->execute();
-
-  // Next, delete the menu links for this set.
-  menu_delete_links($shortcut_set->set_name);
-
-  // Finally, delete the set itself.
-  $deleted = db_delete('shortcut_set')
-    ->condition('set_name', $shortcut_set->set_name)
-    ->execute();
-
-  return (bool) $deleted;
-}
-
-/**
- * Resets the link weights in a shortcut set to match their current order.
- *
- * This function can be used, for example, when a new shortcut link is added to
- * the set. If the link is added to the end of the array and this function is
- * called, it will force that link to display at the end of the list.
- *
- * @param object $shortcut_set
- *   An object representing a shortcut set. The link weights of the passed-in
- *   object will be reset as described above.
- */
-function shortcut_set_reset_link_weights(&$shortcut_set) {
-  $weight = -50;
-  foreach ($shortcut_set->links as &$link) {
-    $link['weight'] = $weight;
-    $weight++;
-  }
-}
-
-/**
- * Assigns a user to a particular shortcut set.
- *
- * @param $shortcut_set
- *   An object representing the shortcut set.
- * @param $account
- *   A user account that will be assigned to use the set.
- */
-function shortcut_set_assign_user($shortcut_set, $account) {
-  db_merge('shortcut_set_users')
-    ->key(array('uid' => $account->uid))
-    ->fields(array('set_name' => $shortcut_set->set_name))
-    ->execute();
-  drupal_static_reset('shortcut_current_displayed_set');
-}
-
-/**
- * Unassigns a user from any shortcut set they may have been assigned to.
- *
- * The user will go back to using whatever default set applies.
- *
- * @param $account
- *   A user account that will be removed from the shortcut set assignment.
- *
- * @return
- *   TRUE if the user was previously assigned to a shortcut set and has been
- *   successfully removed from it. FALSE if the user was already not assigned
- *   to any set.
- */
-function shortcut_set_unassign_user($account) {
-  $deleted = db_delete('shortcut_set_users')
-    ->condition('uid', $account->uid)
-    ->execute();
-  return (bool) $deleted;
-}
-
-/**
- * Returns the current displayed shortcut set for the provided user account.
- *
- * @param $account
- *   (optional) The user account whose shortcuts will be returned. Defaults to
- *   the currently logged-in user.
- *
- * @return
- *   An object representing the shortcut set that should be displayed to the
- *   current user. If the user does not have an explicit shortcut set defined,
- *   the default set is returned.
- */
-function shortcut_current_displayed_set($account = NULL) {
-  $shortcut_sets = &drupal_static(__FUNCTION__, array());
-  global $user;
-  if (!isset($account)) {
-    $account = $user;
-  }
-  // Try to return a shortcut set from the static cache.
-  if (isset($shortcut_sets[$account->uid])) {
-    return $shortcut_sets[$account->uid];
-  }
-  // If none was found, try to find a shortcut set that is explicitly assigned
-  // to this user.
-  $query = db_select('shortcut_set', 's');
-  $query->addField('s', 'set_name');
-  $query->join('shortcut_set_users', 'u', 's.set_name = u.set_name');
-  $query->condition('u.uid', $account->uid);
-  $shortcut_set_name = $query->execute()->fetchField();
-  if ($shortcut_set_name) {
-    $shortcut_set = shortcut_set_load($shortcut_set_name);
-  }
-  // Otherwise, use the default set.
-  else {
-    $shortcut_set = shortcut_default_set($account);
-  }
-
-  $shortcut_sets[$account->uid] = $shortcut_set;
-  return $shortcut_set;
-}
-
-/**
- * Returns the default shortcut set for a given user account.
- *
- * @param object $account
- *   (optional) The user account whose default shortcut set will be returned.
- *   If not provided, the function will return the currently logged-in user's
- *   default shortcut set.
- *
- * @return
- *   An object representing the default shortcut set.
- */
-function shortcut_default_set($account = NULL) {
-  global $user;
-  if (!isset($account)) {
-    $account = $user;
-  }
-
-  // Allow modules to return a default shortcut set name. Since we can only
-  // have one, we allow the last module which returns a valid result to take
-  // precedence. If no module returns a valid set, fall back on the site-wide
-  // default, which is the lowest-numbered shortcut set.
-  $suggestions = array_reverse(module_invoke_all('shortcut_default_set', $account));
-  $suggestions[] = SHORTCUT_DEFAULT_SET_NAME;
-  foreach ($suggestions as $name) {
-    if ($shortcut_set = shortcut_set_load($name)) {
-      break;
-    }
-  }
-
-  return $shortcut_set;
-}
-
-/**
- * Returns a unique, machine-readable shortcut set name.
- */
-function shortcut_set_get_unique_name() {
-  // Shortcut sets are numbered sequentially, so we keep trying until we find
-  // one that is available. For better performance, we start with a number
-  // equal to one more than the current number of shortcut sets, so that if
-  // no shortcut sets have been deleted from the database, this will
-  // automatically give us the correct one.
-  $number = db_query("SELECT COUNT(*) FROM {shortcut_set}")->fetchField() + 1;
-  do {
-    $name = shortcut_set_name($number);
-    $number++;
-  } while ($shortcut_set = shortcut_set_load($name));
-  return $name;
-}
-
-/**
- * Returns the name of a shortcut set, based on a provided number.
- *
- * All shortcut sets have names like "shortcut-set-N" so that they can be
- * matched with a properly-namespaced entry in the {menu_links} table.
- *
- * @param $number
- *   A number representing the shortcut set whose name should be retrieved.
- *
- * @return
- *   A string representing the expected shortcut name.
- */
-function shortcut_set_name($number) {
-  return "shortcut-set-$number";
-}
-
-/**
- * Returns an array of all shortcut sets, keyed by the set name.
- *
- * @return
- *   An array of shortcut sets. Note that only the basic shortcut set
- *   properties (name and title) are returned by this function, not the list
- *   of menu links that belong to the set.
- */
-function shortcut_sets() {
-  return db_select('shortcut_set', 'ss')
-  ->fields('ss')
-  ->execute()
-  ->fetchAllAssoc('set_name');
-}
-
-/**
- * Check to see if a shortcut set with the given title already exists.
- *
- * @param $title
- *   Human-readable name of the shortcut set to check.
- *
- * @return
- *   TRUE if a shortcut set with that title exists; FALSE otherwise.
- */
-function shortcut_set_title_exists($title) {
-  return (bool) db_query_range('SELECT 1 FROM {shortcut_set} WHERE title = :title', 0, 1, array(':title' => $title))->fetchField();
-}
-
-/**
- * Determines if a path corresponds to a valid shortcut link.
- *
- * @param $path
- *   The path to the link.
- * @return
- *   TRUE if the shortcut link is valid, FALSE otherwise. Valid links are ones
- *   that correspond to actual paths on the site.
- *
- * @see menu_edit_item_validate()
- */
-function shortcut_valid_link($path) {
-  // Do not use URL aliases.
-  $normal_path = drupal_get_normal_path($path);
-  if ($path != $normal_path) {
-    $path = $normal_path;
-  }
-  // Only accept links that correspond to valid paths on the site itself.
-  return !url_is_external($path) && menu_get_item($path);
-}
-
-/**
- * Returns an array of shortcut links, suitable for rendering.
- *
- * @param $shortcut_set
- *   (optional) An object representing the set whose links will be displayed.
- *   If not provided, the user's current set will be displayed.
- * @return
- *   An array of shortcut links, in the format returned by the menu system.
- *
- * @see menu_tree()
- */
-function shortcut_renderable_links($shortcut_set = NULL) {
-  if (!isset($shortcut_set)) {
-    $shortcut_set = shortcut_current_displayed_set();
-  }
-  return menu_tree($shortcut_set->set_name);
-}
-
-/**
- * Implements hook_preprocess_page().
- */
-function shortcut_preprocess_page(&$variables) {
-  if (shortcut_set_edit_access()) {
-    $link = $_GET['q'];
-    $query_parameters = drupal_get_query_parameters();
-    if (!empty($query_parameters)) {
-     $link .= '?' . drupal_http_build_query($query_parameters);
-    }
-    $query = array(
-     'link' => $link,
-     'name' => drupal_get_title(),
-    );
-    $query += drupal_get_destination();
-
-    $shortcut_set = shortcut_current_displayed_set();
-
-    // Check if $link is already a shortcut and set $link_mode accordingly.
-    foreach ($shortcut_set->links as $shortcut) {
-      if ($link == $shortcut['link_path']) {
-        $mlid = $shortcut['mlid'];
-        break;
-      }
-    }
-    $link_mode = isset($mlid) ? "remove" : "add";
-
-    if ($link_mode == "add") {
-      $query['token'] = drupal_get_token('shortcut-add-link');
-      $link_text = shortcut_set_switch_access() ? t('Add to %shortcut_set shortcuts', array('%shortcut_set' => $shortcut_set->title)) : t('Add to shortcuts');
-      $link_path = 'admin/config/user-interface/shortcut/' . $shortcut_set->set_name . '/add-link-inline';
-    }
-    else {
-      $query['mlid'] = $mlid;
-      $link_text = shortcut_set_switch_access() ? t('Remove from %shortcut_set shortcuts', array('%shortcut_set' => $shortcut_set->title)) : t('Remove from shortcuts');
-      $link_path = 'admin/config/user-interface/shortcut/link/' . $mlid . '/delete';
-    }
-
-    if (theme_get_setting('shortcut_module_link')) {
-      $variables['title_suffix']['add_or_remove_shortcut'] = array(
-        '#attached' => array('css' => array(drupal_get_path('module', 'shortcut') . '/shortcut.css')),
-        '#prefix' => '<div class="add-or-remove-shortcuts ' . $link_mode . '-shortcut">',
-        '#type' => 'link',
-        '#title' => '<span class="icon"></span><span class="text">' . $link_text . '</span>',
-        '#href' => $link_path,
-        '#options' => array('query' => $query, 'html' => TRUE),
-        '#suffix' => '</div>',
-      );
-    }
-  }
-}
-
-/**
- * Implements hook_page_alter().
- */
-function shortcut_page_alter(&$page) {
-  if (isset($page['page_top']['toolbar'])) {
-    // If the toolbar is available, add a pre-render function to display the
-    // current shortcuts in the toolbar drawer.
-    $page['page_top']['toolbar']['#pre_render'][] = 'shortcut_toolbar_pre_render';
-  }
-}
-
-/**
- * Pre-render function for adding shortcuts to the toolbar drawer.
- */
-function shortcut_toolbar_pre_render($toolbar) {
-  $links = shortcut_renderable_links();
-  $links['#attached'] = array('css' => array(drupal_get_path('module', 'shortcut') . '/shortcut.css'));
-  $links['#prefix'] = '<div class="toolbar-shortcuts">';
-  $links['#suffix'] = '</div>';
-  $shortcut_set = shortcut_current_displayed_set();
-  $configure_link = NULL;
-  if (shortcut_set_edit_access($shortcut_set)) {
-    $configure_link = array(
-      '#type' => 'link',
-      '#title' => t('Edit shortcuts'),
-      '#href' => 'admin/config/user-interface/shortcut/' . $shortcut_set->set_name,
-      '#options' => array('attributes' => array('id' => 'edit-shortcuts')),
-    );
-  }
-
-  $drawer = array(
-    'shortcuts' => $links,
-    'configure' => $configure_link,
-  );
-
-  $toolbar['toolbar_drawer'][] = $drawer;
-  return $toolbar;
-}
-
-/**
- * Returns the title of a shortcut set.
- *
- * Title callback for the editing pages for shortcut sets.
- *
- * @param $shortcut_set
- *   An object representing the shortcut set, as returned by
- *   shortcut_set_load().
- */
-function shortcut_set_title($shortcut_set) {
-  return check_plain($shortcut_set->title);
-}
-
diff --git a/modules/shortcut/shortcut.png b/modules/shortcut/shortcut.png
deleted file mode 100644
index 2924557bfaab7bee329231c8bd3d821a32b9e031..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 558
zcmeAS@N?(olHy`uVBq!ia0vp^5<slN!3-pq2y)2)DVB6cUq=RpjeRx011AIdlLLH0
zT!Hj|4Dj>kPc*TmOBdg~b>rc~2iI?0`~Ktm?c29*-n_AN>7u&2y7u;VKR>^moE&Ls
zX%7#Ny?gh%y1EJp2~|{7Y}vBq<jIpumoAl%kXXEUK|x{8_U+qsb#*sx-1z(V@5hfH
zC8xxTii&!BdowdL$0tMsEd{!Vz2?9=AjMk}<QL4qb}1)c`oPb_=a2pTY?ivXm4Sg#
z*VDx@MB{wyq{zNz0|A%YHw2v2q;Gz26(~FL*WbJ>U1$1oy9>?JqOST2Oq_5rMaa|f
zNwG!U9R0H!CED$}6aGKUVQTc*bish<*F^6$KRwO5+m6!4#kXd-&Hb12DO2r)#Sh12
zN7i}?ZP!vP-P}Am>Dinq>#9@VY+JT2xi)0N_Vb6|$+g(M77jJx*(mh?<`2!&u3_Kz
zp1*ef&(-QTe?m-+cAYv9+O{t3K~|fWSBi|z#EYR^>w-$QvV~_Cq`tB$tJ5l0_%MI|
z)i0}$6yCpnbCJ%^c&BCmO!fQDKK*myzmU<@tIwiS<T+AK6-95KaAuCvr8Qfd%g>yt
zJRV{e=4|e?Om&Y!@T)M@mC;i#{7PXrKYC`TW^DOw!+77=<G)tC+GlNZ+lIr|OlsNc
f#EvN+eu`UM&AoYROY}rwh%$J(`njxgN@xNA8U+<(

diff --git a/modules/shortcut/shortcut.test b/modules/shortcut/shortcut.test
deleted file mode 100644
index 75a5a67..0000000
--- a/modules/shortcut/shortcut.test
+++ /dev/null
@@ -1,346 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for shortcut.module.
- */
-
-/**
- * Defines base class for shortcut test cases.
- */
-class ShortcutTestCase extends DrupalWebTestCase {
-
-  /**
-   * User with permission to administer shortcuts.
-   */
-  protected $admin_user;
-
-  /**
-   * User with permission to use shortcuts, but not administer them.
-   */
-  protected $shortcut_user;
-
-  /**
-   * Generic node used for testing.
-   */
-  protected $node;
-
-  /**
-   * Site-wide default shortcut set.
-   */
-  protected $set;
-
-  function setUp() {
-    parent::setUp('toolbar', 'shortcut');
-    // Create users.
-    $this->admin_user = $this->drupalCreateUser(array('access toolbar', 'administer shortcuts', 'view the administration theme', 'create article content', 'create page content', 'access content overview'));
-    $this->shortcut_user = $this->drupalCreateUser(array('customize shortcut links', 'switch shortcut sets'));
-
-    // Create a node.
-    $this->node = $this->drupalCreateNode(array('type' => 'article'));
-
-    // Log in as admin and grab the default shortcut set.
-    $this->drupalLogin($this->admin_user);
-    $this->set = shortcut_set_load(SHORTCUT_DEFAULT_SET_NAME);
-    shortcut_set_assign_user($this->set, $this->admin_user);
-  }
-
-  /**
-   * Creates a generic shortcut set.
-   */
-  function generateShortcutSet($title = '', $default_links = TRUE) {
-    $set = new stdClass();
-    $set->title = empty($title) ? $this->randomName(10) : $title;
-    if ($default_links) {
-      $set->links = array();
-      $set->links[] = $this->generateShortcutLink('node/add');
-      $set->links[] = $this->generateShortcutLink('admin/content');
-    }
-    shortcut_set_save($set);
-
-    return $set;
-  }
-
-  /**
-   * Creates a generic shortcut link.
-   */
-  function generateShortcutLink($path, $title = '') {
-    $link = array(
-      'link_path' => $path,
-      'link_title' => !empty($title) ? $title : $this->randomName(10),
-    );
-
-    return $link;
-  }
-
-  /**
-   * Extracts information from shortcut set links.
-   * 
-   * @param object $set
-   *   The shortcut set object to extract information from.
-   * @param string $key
-   *   The array key indicating what information to extract from each link:
-   *    - 'link_path': Extract link paths.
-   *    - 'link_title': Extract link titles.
-   *    - 'mlid': Extract the menu link item ID numbers.
-   *
-   * @return array
-   *   Array of the requested information from each link.
-   */
-  function getShortcutInformation($set, $key) {
-    $info = array();
-    foreach ($set->links as $link) {
-      $info[] = $link[$key];
-    }
-    return $info;
-  }
-}
-
-/**
- * Defines shortcut links test cases.
- */
-class ShortcutLinksTestCase extends ShortcutTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Shortcut link functionality',
-      'description' => 'Create, view, edit, delete, and change shortcut links.',
-      'group' => 'Shortcut',
-    );
-  }
-
-  /**
-   * Tests that creating a shortcut works properly.
-   */
-  function testShortcutLinkAdd() {
-    $set = $this->set;
-
-    // Create an alias for the node so we can test aliases.
-    $path = array(
-      'source' => 'node/' . $this->node->nid,
-      'alias' => $this->randomName(8),
-    );
-    path_save($path);
-
-    // Create some paths to test.
-    $test_cases = array(
-      array('path' => 'admin'),
-      array('path' => 'admin/config/system/site-information'),
-      array('path' => "node/{$this->node->nid}/edit"),
-      array('path' => $path['alias']),
-    );
-
-    // Check that each new shortcut links where it should.
-    foreach ($test_cases as $test) {
-      $title = $this->randomName(10);
-      $form_data = array(
-        'shortcut_link[link_title]' => $title,
-        'shortcut_link[link_path]'  => $test['path'],
-      );
-      $this->drupalPost('admin/config/user-interface/shortcut/' . $set->set_name . '/add-link', $form_data, t('Save'));
-      $this->assertResponse(200);
-      $saved_set = shortcut_set_load($set->set_name);
-      $paths = $this->getShortcutInformation($saved_set, 'link_path');
-      $this->assertTrue(in_array(drupal_get_normal_path($test['path']), $paths), 'Shortcut created: '. $test['path']);
-      $this->assertLink($title, 0, 'Shortcut link found on the page.');
-    }
-  }
-
-  /**
-   * Tests that the "add to shortcut" link changes to "remove shortcut".
-   */
-  function testShortcutQuickLink() {
-    $this->drupalGet($this->set->links[0]['link_path']);
-    $this->assertRaw(t('Remove from %title shortcuts', array('%title' => $this->set->title)), '"Add to shortcuts" link properly switched to "Remove from shortcuts".');
-  }
-
-  /**
-   * Tests that shortcut links can be renamed.
-   */
-  function testShortcutLinkRename() {
-    $set = $this->set;
-
-    // Attempt to rename shortcut link.
-    $new_link_name = $this->randomName(10);
-
-    $this->drupalPost('admin/config/user-interface/shortcut/link/' . $set->links[0]['mlid'], array('shortcut_link[link_title]' => $new_link_name, 'shortcut_link[link_path]' => $set->links[0]['link_path']), t('Save'));
-    $saved_set = shortcut_set_load($set->set_name);
-    $titles = $this->getShortcutInformation($saved_set, 'link_title');
-    $this->assertTrue(in_array($new_link_name, $titles), 'Shortcut renamed: ' . $new_link_name);
-    $this->assertLink($new_link_name, 0, 'Renamed shortcut link appears on the page.');
-  }
-
-  /**
-   * Tests that changing the path of a shortcut link works.
-   */
-  function testShortcutLinkChangePath() {
-    $set = $this->set;
-
-    // Tests changing a shortcut path.
-    $new_link_path = 'admin/config';
-
-    $this->drupalPost('admin/config/user-interface/shortcut/link/' . $set->links[0]['mlid'], array('shortcut_link[link_title]' => $set->links[0]['link_title'], 'shortcut_link[link_path]' => $new_link_path), t('Save'));
-    $saved_set = shortcut_set_load($set->set_name);
-    $paths = $this->getShortcutInformation($saved_set, 'link_path');
-    $this->assertTrue(in_array($new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
-    $this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.');
-  }
-
-  /**
-   * Tests deleting a shortcut link.
-   */
-  function testShortcutLinkDelete() {
-    $set = $this->set;
-
-    $this->drupalPost('admin/config/user-interface/shortcut/link/' . $set->links[0]['mlid'] . '/delete', array(), 'Delete');
-    $saved_set = shortcut_set_load($set->set_name);
-    $mlids = $this->getShortcutInformation($saved_set, 'mlid');
-    $this->assertFalse(in_array($set->links[0]['mlid'], $mlids), 'Successfully deleted a shortcut.');
-  }
-}
-
-/**
- * Defines shortcut set test cases.
- */
-class ShortcutSetsTestCase extends ShortcutTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Shortcut set functionality',
-      'description' => 'Create, view, edit, delete, and change shortcut sets.',
-      'group' => 'Shortcut',
-    );
-  }
-
-  /**
-   * Tests creating a shortcut set.
-   */
-  function testShortcutSetAdd() {
-    $new_set = $this->generateShortcutSet($this->randomName(10));
-    $sets = shortcut_sets();
-    $this->assertTrue(isset($sets[$new_set->set_name]), 'Successfully created a shortcut set.');
-    $this->drupalGet('user/' . $this->admin_user->uid . '/shortcuts');
-    $this->assertText($new_set->title, 'Generated shortcut set was listed as a choice on the user account page.');
-  }
-
-  /**
-   * Tests switching a user's own shortcut set.
-   */
-  function testShortcutSetSwitchOwn() {
-    $new_set = $this->generateShortcutSet($this->randomName(10));
-
-    // Attempt to switch the default shortcut set to the newly created shortcut
-    // set.
-    $this->drupalPost('user/' . $this->admin_user->uid . '/shortcuts', array('set' => $new_set->set_name), t('Change set'));
-    $this->assertResponse(200);
-    $current_set = shortcut_current_displayed_set($this->admin_user);
-    $this->assertTrue($new_set->set_name == $current_set->set_name, 'Successfully switched own shortcut set.');
-  }
-
-  /**
-   * Tests switching another user's shortcut set.
-   */
-  function testShortcutSetAssign() {
-    $new_set = $this->generateShortcutSet($this->randomName(10));
-
-    shortcut_set_assign_user($new_set, $this->shortcut_user);
-    $current_set = shortcut_current_displayed_set($this->shortcut_user);
-    $this->assertTrue($new_set->set_name == $current_set->set_name, "Successfully switched another user's shortcut set.");
-  }
-
-  /**
-   * Tests switching a user's shortcut set and creating one at the same time.
-   */
-  function testShortcutSetSwitchCreate() {
-    $edit = array(
-      'set' => 'new',
-      'new' => $this->randomName(10),
-    );
-    $this->drupalPost('user/' . $this->admin_user->uid . '/shortcuts', $edit, t('Change set'));
-    $current_set = shortcut_current_displayed_set($this->admin_user);
-    $this->assertNotEqual($current_set->set_name, $this->set->set_name, 'A shortcut set can be switched to at the same time as it is created.');
-    $this->assertEqual($current_set->title, $edit['new'], 'The new set is correctly assigned to the user.');
-  }
-
-  /**
-   * Tests switching a user's shortcut set without providing a new set name.
-   */
-  function testShortcutSetSwitchNoSetName() {
-    $edit = array('set' => 'new');
-    $this->drupalPost('user/' . $this->admin_user->uid . '/shortcuts', $edit, t('Change set'));
-    $this->assertText(t('The new set name is required.'));
-    $current_set = shortcut_current_displayed_set($this->admin_user);
-    $this->assertEqual($current_set->set_name, $this->set->set_name, 'Attempting to switch to a new shortcut set without providing a set name does not succeed.');
-  }
-
-  /**
-   * Tests that shortcut_set_save() correctly updates existing links.
-   */
-  function testShortcutSetSave() {
-    $set = $this->set;
-    $old_mlids = $this->getShortcutInformation($set, 'mlid');
-
-    $set->links[] = $this->generateShortcutLink('admin', $this->randomName(10));
-    shortcut_set_save($set);
-    $saved_set = shortcut_set_load($set->set_name);
-
-    $new_mlids = $this->getShortcutInformation($saved_set, 'mlid');
-    $this->assertTrue(count(array_intersect($old_mlids, $new_mlids)) == count($old_mlids), 'shortcut_set_save() did not inadvertently change existing mlids.');
-  }
-
-  /**
-   * Tests renaming a shortcut set.
-   */
-  function testShortcutSetRename() {
-    $set = $this->set;
-    
-    $new_title = $this->randomName(10);
-    $this->drupalPost('admin/config/user-interface/shortcut/' . $set->set_name . '/edit', array('title' => $new_title), t('Save'));
-    $set = shortcut_set_load($set->set_name);
-    $this->assertTrue($set->title == $new_title, 'Shortcut set has been successfully renamed.');
-  }
-
-  /**
-   * Tests renaming a shortcut set to the same name as another set.
-   */
-  function testShortcutSetRenameAlreadyExists() {
-    $set = $this->generateShortcutSet($this->randomName(10));
-    $existing_title = $this->set->title;
-    $this->drupalPost('admin/config/user-interface/shortcut/' . $set->set_name . '/edit', array('title' => $existing_title), t('Save'));
-    $this->assertRaw(t('The shortcut set %name already exists. Choose another name.', array('%name' => $existing_title)));
-    $set = shortcut_set_load($set->set_name);
-    $this->assertNotEqual($set->title, $existing_title, t('The shortcut set %title cannot be renamed to %new-title because a shortcut set with that title already exists.', array('%title' => $set->title, '%new-title' => $existing_title)));
-  }
-
-  /**
-   * Tests unassigning a shortcut set.
-   */
-  function testShortcutSetUnassign() {
-    $new_set = $this->generateShortcutSet($this->randomName(10));
-
-    shortcut_set_assign_user($new_set, $this->shortcut_user);
-    shortcut_set_unassign_user($this->shortcut_user);
-    $current_set = shortcut_current_displayed_set($this->shortcut_user);
-    $default_set = shortcut_default_set($this->shortcut_user);
-    $this->assertTrue($current_set->set_name == $default_set->set_name, "Successfully unassigned another user's shortcut set.");
-  }
-
-  /**
-   * Tests deleting a shortcut set.
-   */
-  function testShortcutSetDelete() {
-    $new_set = $this->generateShortcutSet($this->randomName(10));
-
-    $this->drupalPost('admin/config/user-interface/shortcut/' . $new_set->set_name . '/delete', array(), t('Delete'));
-    $sets = shortcut_sets();
-    $this->assertFalse(isset($sets[$new_set->set_name]), 'Successfully deleted a shortcut set.');
-  }
-
-  /**
-   * Tests deleting the default shortcut set.
-   */
-  function testShortcutSetDeleteDefault() {
-    $this->drupalGet('admin/config/user-interface/shortcut/' . SHORTCUT_DEFAULT_SET_NAME . '/delete');
-    $this->assertResponse(403);
-  }
-}
diff --git a/modules/statistics/statistics.admin.inc b/modules/statistics/statistics.admin.inc
deleted file mode 100644
index 6606b8b..0000000
--- a/modules/statistics/statistics.admin.inc
+++ /dev/null
@@ -1,274 +0,0 @@
-<?php
-
-/**
- * @file
- * Admin page callbacks for the statistics module.
- */
-
-/**
- * Menu callback; presents the "recent hits" page.
- */
-function statistics_recent_hits() {
-  $header = array(
-    array('data' => t('Timestamp'), 'field' => 'a.timestamp', 'sort' => 'desc'),
-    array('data' => t('Page'), 'field' => 'a.path'),
-    array('data' => t('User'), 'field' => 'u.name'),
-    array('data' => t('Operations'))
-  );
-
-  $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
-  $query->join('users', 'u', 'a.uid = u.uid');
-  $query
-    ->fields('a', array('aid', 'timestamp', 'path', 'title', 'uid'))
-    ->fields('u', array('name'))
-    ->limit(30)
-    ->orderByHeader($header);
-
-  $result = $query->execute();
-  $rows = array();
-  foreach ($result as $log) {
-    $rows[] = array(
-      array('data' => format_date($log->timestamp, 'short'), 'class' => array('nowrap')),
-      _statistics_format_item($log->title, $log->path),
-      theme('username', array('account' => $log)),
-      l(t('details'), "admin/reports/access/$log->aid"));
-  }
-
-  $build['statistics_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No statistics available.'),
-  );
-  $build['statistics_pager'] = array('#theme' => 'pager');
-  return $build;
-}
-
-/**
- * Menu callback; presents the "top pages" page.
- */
-function statistics_top_pages() {
-  $header = array(
-    array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
-    array('data' => t('Page'), 'field' => 'path'),
-    array('data' => t('Average page generation time'), 'field' => 'average_time'),
-    array('data' => t('Total page generation time'), 'field' => 'total_time')
-  );
-
-  $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
-  $query->addExpression('COUNT(path)', 'hits');
-  // MAX(title) avoids having empty node titles which otherwise causes duplicates in the top pages list
-  $query->addExpression('MAX(title)', 'title');
-  $query->addExpression('AVG(timer)', 'average_time');
-  $query->addExpression('SUM(timer)', 'total_time');
-
-  $query
-    ->fields('a', array('path'))
-    ->groupBy('path')
-    ->limit(30)
-    ->orderByHeader($header);
-
-  $count_query = db_select('accesslog', 'a', array('target' => 'slave'));
-  $count_query->addExpression('COUNT(DISTINCT path)');
-  $query->setCountQuery($count_query);
-
-  $result = $query->execute();
-  $rows = array();
-  foreach ($result as $page) {
-    $rows[] = array($page->hits, _statistics_format_item($page->title, $page->path), t('%time ms', array('%time' => round($page->average_time))), format_interval(round($page->total_time / 1000)));
-  }
-
-  drupal_set_title(t('Top pages in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))), PASS_THROUGH);
-  $build['statistics_top_pages_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No statistics available.'),
-  );
-  $build['statistics_top_pages_pager'] = array('#theme' => 'pager');
-  return $build;
-}
-
-/**
- * Menu callback; presents the "top visitors" page.
- */
-function statistics_top_visitors() {
-
-  $header = array(
-    array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
-    array('data' => t('Visitor'), 'field' => 'u.name'),
-    array('data' => t('Total page generation time'), 'field' => 'total'),
-    array('data' => user_access('block IP addresses') ? t('Operations') : '', 'colspan' => 2),
-  );
-  $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
-  $query->leftJoin('blocked_ips', 'bl', 'a.hostname = bl.ip');
-  $query->leftJoin('users', 'u', 'a.uid = u.uid');
-
-  $query->addExpression('COUNT(a.uid)', 'hits');
-  $query->addExpression('SUM(a.timer)', 'total');
-  $query
-    ->fields('a', array('uid', 'hostname'))
-    ->fields('u', array('name'))
-    ->fields('bl', array('iid'))
-    ->groupBy('a.hostname')
-    ->groupBy('a.uid')
-    ->groupBy('u.name')
-    ->groupBy('bl.iid')
-    ->limit(30)
-    ->orderByHeader($header);
-
-  $uniques_query = db_select('accesslog')->distinct();
-  $uniques_query->fields('accesslog', array('uid', 'hostname'));
-  $count_query = db_select($uniques_query);
-  $count_query->addExpression('COUNT(*)');
-  $query->setCountQuery($count_query);
-
-  $result = $query->execute();
-  $rows = array();
-  $destination = drupal_get_destination();
-  foreach ($result as $account) {
-    $ban_link = $account->iid ? l(t('unblock IP address'), "admin/config/people/ip-blocking/delete/$account->iid", array('query' => $destination)) : l(t('block IP address'), "admin/config/people/ip-blocking/$account->hostname", array('query' => $destination));
-    $rows[] = array($account->hits, ($account->uid ? theme('username', array('account' => $account)) : $account->hostname), format_interval(round($account->total / 1000)), (user_access('block IP addresses') && !$account->uid) ? $ban_link : '');
-  }
-
-  drupal_set_title(t('Top visitors in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))), PASS_THROUGH);
-  $build['statistics_top_visitors_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No statistics available.'),
-  );
-  $build['statistics_top_visitors_pager'] = array('#theme' => 'pager');
-  return $build;
-}
-
-/**
- * Menu callback; presents the "referrer" page.
- */
-function statistics_top_referrers() {
-  drupal_set_title(t('Top referrers in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))), PASS_THROUGH);
-
-  $header = array(
-    array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
-    array('data' => t('Url'), 'field' => 'url'),
-    array('data' => t('Last visit'), 'field' => 'last'),
-  );
-  $query = db_select('accesslog', 'a')->extend('PagerDefault')->extend('TableSort');
-
-  $query->addExpression('COUNT(url)', 'hits');
-  $query->addExpression('MAX(timestamp)', 'last');
-  $query
-    ->fields('a', array('url'))
-    ->condition('url', '%' . $_SERVER['HTTP_HOST'] . '%', 'NOT LIKE')
-    ->condition('url', '', '<>')
-    ->groupBy('url')
-    ->limit(30)
-    ->orderByHeader($header);
-
-  $count_query = db_select('accesslog', 'a', array('target' => 'slave'));
-  $count_query->addExpression('COUNT(DISTINCT url)');
-  $count_query
-    ->condition('url', '%' . $_SERVER['HTTP_HOST'] . '%', 'NOT LIKE')
-    ->condition('url', '', '<>');
-  $query->setCountQuery($count_query);
-
-  $result = $query->execute();
-  $rows = array();
-  foreach ($result as $referrer) {
-    $rows[] = array($referrer->hits, _statistics_link($referrer->url), t('@time ago', array('@time' => format_interval(REQUEST_TIME - $referrer->last))));
-  }
-
-  $build['statistics_top_referrers_table'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No statistics available.'),
-  );
-  $build['statistics_top_referrers_pager'] = array('#theme' => 'pager');
-  return $build;
-}
-
-/**
- * Menu callback; Displays recent page accesses.
- */
-function statistics_access_log($aid) {
-  $access = db_query('SELECT a.*, u.name FROM {accesslog} a LEFT JOIN {users} u ON a.uid = u.uid WHERE aid = :aid', array(':aid' => $aid))->fetch();
-  if ($access) {
-    $rows[] = array(
-      array('data' => t('URL'), 'header' => TRUE),
-      l(url($access->path, array('absolute' => TRUE)), $access->path)
-    );
-    // It is safe to avoid filtering $access->title through check_plain because
-    // it comes from drupal_get_title().
-    $rows[] = array(
-      array('data' => t('Title'), 'header' => TRUE),
-      $access->title
-    );
-    $rows[] = array(
-      array('data' => t('Referrer'), 'header' => TRUE),
-      ($access->url ? l($access->url, $access->url) : '')
-    );
-    $rows[] = array(
-      array('data' => t('Date'), 'header' => TRUE),
-      format_date($access->timestamp, 'long')
-    );
-    $rows[] = array(
-      array('data' => t('User'), 'header' => TRUE),
-      theme('username', array('account' => $access))
-    );
-    $rows[] = array(
-      array('data' => t('Hostname'), 'header' => TRUE),
-      check_plain($access->hostname)
-    );
-
-    $build['statistics_table'] = array(
-      '#theme' => 'table',
-      '#rows' => $rows,
-    );
-    return $build;
-  }
-  else {
-    drupal_not_found();
-  }
-}
-
-/**
- * Form builder; Configure access logging.
- *
- * @ingroup forms
- * @see system_settings_form()
- */
-function statistics_settings_form() {
-  // Access log settings.
-  $form['access'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Access log settings'),
-  );
-  $form['access']['statistics_enable_access_log'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable access log'),
-    '#default_value' => variable_get('statistics_enable_access_log', 0),
-    '#description' => t('Log each page access. Required for referrer statistics.'),
-  );
-  $form['access']['statistics_flush_accesslog_timer'] = array(
-    '#type' => 'select',
-    '#title' => t('Discard access logs older than'),
-    '#default_value' => variable_get('statistics_flush_accesslog_timer', 259200),
-    '#options' => array(0 => t('Never')) + drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval'),
-    '#description' => t('Older access log entries (including referrer statistics) will be automatically discarded. (Requires a correctly configured <a href="@cron">cron maintenance task</a>.)', array('@cron' => url('admin/reports/status'))),
-  );
-
-  // Content counter settings.
-  $form['content'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Content viewing counter settings'),
-  );
-  $form['content']['statistics_count_content_views'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Count content views'),
-    '#default_value' => variable_get('statistics_count_content_views', 0),
-    '#description' => t('Increment a counter each time content is viewed.'),
-  );
-
-  return system_settings_form($form);
-}
diff --git a/modules/statistics/statistics.info b/modules/statistics/statistics.info
deleted file mode 100644
index e7add60..0000000
--- a/modules/statistics/statistics.info
+++ /dev/null
@@ -1,7 +0,0 @@
-name = Statistics
-description = Logs access statistics for your site.
-package = Core
-version = VERSION
-core = 8.x
-files[] = statistics.test
-configure = admin/config/system/statistics
diff --git a/modules/statistics/statistics.install b/modules/statistics/statistics.install
deleted file mode 100644
index a5dc7f8..0000000
--- a/modules/statistics/statistics.install
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the statistics module.
- */
-
-/**
- * Implements hook_uninstall().
- */
-function statistics_uninstall() {
-  // Remove variables.
-  variable_del('statistics_count_content_views');
-  variable_del('statistics_enable_access_log');
-  variable_del('statistics_flush_accesslog_timer');
-  variable_del('statistics_day_timestamp');
-  variable_del('statistics_block_top_day_num');
-  variable_del('statistics_block_top_all_num');
-  variable_del('statistics_block_top_last_num');
-}
-
-/**
- * Implements hook_schema().
- */
-function statistics_schema() {
-  $schema['accesslog'] = array(
-    'description' => 'Stores site access information for statistics.',
-    'fields' => array(
-      'aid' => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique accesslog ID.',
-      ),
-      'sid' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Browser session ID of user that visited page.',
-      ),
-      'title' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-        'description' => 'Title of page visited.',
-      ),
-      'path' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => FALSE,
-        'description' => 'Internal path to page visited (relative to Drupal root.)',
-      ),
-      'url' => array(
-        'type' => 'text',
-        'not null' => FALSE,
-        'description' => 'Referrer URI.',
-      ),
-      'hostname' => array(
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => FALSE,
-        'description' => 'Hostname of user that visited the page.',
-      ),
-      'uid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => FALSE,
-        'default' => 0,
-        'description' => 'User {users}.uid that visited the page.',
-      ),
-      'timer' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Time in milliseconds that the page took to load.',
-      ),
-      'timestamp' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Timestamp of when the page was visited.',
-      ),
-    ),
-    'indexes' => array(
-      'accesslog_timestamp' => array('timestamp'),
-      'uid' => array('uid'),
-    ),
-    'primary key' => array('aid'),
-    'foreign keys' => array(
-      'visitor' => array(
-        'table' => 'users',
-        'columns' => array('uid' => 'uid'),
-      ),
-    ),
-  );
-
-  $schema['node_counter'] = array(
-    'description' => 'Access statistics for {node}s.',
-    'fields' => array(
-      'nid' => array(
-        'description' => 'The {node}.nid for these statistics.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'totalcount' => array(
-        'description' => 'The total number of times the {node} has been viewed.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'big',
-      ),
-      'daycount' => array(
-        'description' => 'The total number of times the {node} has been viewed today.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'medium',
-      ),
-      'timestamp' => array(
-        'description' => 'The most recent time the {node} has been viewed.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-    ),
-    'primary key' => array('nid'),
-  );
-
-  return $schema;
-}
diff --git a/modules/statistics/statistics.module b/modules/statistics/statistics.module
deleted file mode 100644
index 6b7be8a..0000000
--- a/modules/statistics/statistics.module
+++ /dev/null
@@ -1,427 +0,0 @@
-<?php
-
-/**
- * @file
- * Logs access statistics for your site.
- */
-
-/**
- * Implements hook_help().
- */
-function statistics_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#statistics':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Statistics module shows you how often a given page is viewed, who viewed it, the previous page the user visited (referrer URL), and when it was viewed. These statistics are useful in determining how users are visiting and navigating your site. For more information, see the online handbook entry for the <a href="@statistics">Statistics module</a>.', array('@statistics' => url('http://drupal.org/handbook/modules/statistics/'))) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Managing logs') . '</dt>';
-      $output .= '<dd>' . t('To enable collection of statistics, the <em>Enable access log</em> checkbox on the <a href="@statistics-settings">Statistics settings page</a> must be checked. The <em>Discard access logs older than</em> setting on the settings page specifies the length of time entries are kept in the log before they are deleted. This setting requires a correctly configured <a href="@cron">cron maintenance task</a> to run.', array('@statistics-settings' => url('admin/config/system/statistics'), '@cron' => 'http://drupal.org/cron')) . '</dd>';
-      $output .= '<dt>' . t('Viewing site usage') . '</dt>';
-      $output .= '<dd>' . t('The Statistics module can help you break down details about your users and how they are using the site. The module offers four reports:');
-      $output .= '<ul><li>' . t('<a href="@recent-hits">Recent hits</a> displays information about the latest activity on your site, including the URL and title of the page that was accessed, the user name (if available) and the IP address of the viewer.', array('@recent-hits' => url('admin/reports/hits'))) . '</li>';
-      $output .= '<li>' . t('<a href="@top-referrers">Top referrers</a> displays where visitors came from (referrer URL).', array('@top-referrers' => url('admin/reports/referrers'))) . '</li>';
-      $output .= '<li>' . t('<a href="@top-pages">Top pages</a> displays a list of pages ordered by how often they were viewed.', array('@top-pages' => url('admin/reports/pages'))) . '</li>';
-      $output .= '<li>' . t('<a href="@top-visitors">Top visitors</a> shows you the most active visitors for your site and allows you to ban abusive visitors.', array('@top-visitors' => url('admin/reports/visitors'))) . '</li></ul>';
-      $output .= '<dt>' . t('Displaying popular content') . '</dt>';
-      $output .= '<dd>' . t('The module includes a <em>Popular content</em> block that displays the most viewed pages today and for all time, and the last content viewed. To use the block, enable <em>Count content views</em> on the <a href="@statistics-settings">statistics settings page</a>, and then you can enable and configure the block on the <a href="@blocks">blocks administration page</a>.', array('@statistics-settings' => url('admin/config/system/statistics'), '@blocks' => url('admin/structure/block'))) . '</dd>';
-      $output .= '<dt>' . t('Page view counter') . '</dt>';
-      $output .= '<dd>' . t('The Statistics module includes a counter for each page that increases whenever the page is viewed. To use the counter, enable <em>Count content views</em> on the <a href="@statistics-settings">statistics settings page</a>, and set the necessary <a href="@permissions">permissions</a> (<em>View content hits</em>) so that the counter is visible to the users.', array('@statistics-settings' => url('admin/config/system/statistics'), '@permissions' => url('admin/people/permissions', array('fragment' => 'module-statistics')))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-    case 'admin/config/system/statistics':
-      return '<p>' . t('Settings for the statistical information that Drupal will keep about the site. See <a href="@statistics">site statistics</a> for the actual information.', array('@statistics' => url('admin/reports/hits'))) . '</p>';
-    case 'admin/reports/hits':
-      return '<p>' . t("This page displays the site's most recent hits.") . '</p>';
-    case 'admin/reports/referrers':
-      return '<p>' . t('This page displays all external referrers, or external references to your website.') . '</p>';
-    case 'admin/reports/visitors':
-      return '<p>' . t("When you ban a visitor, you prevent the visitor's IP address from accessing your site. Unlike blocking a user, banning a visitor works even for anonymous users. This is most commonly used to block resource-intensive bots or web crawlers.") . '</p>';
-  }
-}
-
-
-/**
- * Implements hook_exit().
- *
- * This is where statistics are gathered on page accesses.
- */
-function statistics_exit() {
-  global $user;
-
-  // When serving cached pages with the 'page_cache_without_database'
-  // configuration, system variables need to be loaded. This is a major
-  // performance decrease for non-database page caches, but with Statistics
-  // module, it is likely to also have 'statistics_enable_access_log' enabled,
-  // in which case we need to bootstrap to the session phase anyway.
-  drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES);
-
-  if (variable_get('statistics_count_content_views', 0)) {
-    // We are counting content views.
-    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == NULL) {
-      // A node has been viewed, so update the node's counters.
-      db_merge('node_counter')
-        ->key(array('nid' => arg(1)))
-        ->fields(array(
-          'daycount' => 1,
-          'totalcount' => 1,
-          'timestamp' => REQUEST_TIME,
-        ))
-        ->expression('daycount', 'daycount + 1')
-        ->expression('totalcount', 'totalcount + 1')
-        ->execute();
-    }
-  }
-  if (variable_get('statistics_enable_access_log', 0)) {
-    drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
-    // Log this page access.
-    db_insert('accesslog')
-      ->fields(array(
-        'title' => strip_tags(drupal_get_title()),
-        'path' => $_GET['q'],
-        'url' => $_SERVER['HTTP_REFERER'],
-        'hostname' => ip_address(),
-        'uid' => $user->uid,
-        'sid' => session_id(),
-        'timer' => (int) timer_read('page'),
-        'timestamp' => REQUEST_TIME,
-      ))
-      ->execute();
-  }
-}
-
-/**
- * Implements hook_permission().
- */
-function statistics_permission() {
-  return array(
-    'administer statistics' => array(
-      'title' => t('Administer statistics'),
-    ),
-    'access statistics' => array(
-      'title' => t('View content access statistics'),
-    ),
-    'view post access counter' => array(
-      'title' => t('View content hits'),
-    ),
-  );
-}
-
-/**
- * Implements hook_node_view().
- */
-function statistics_node_view($node, $view_mode) {
-  if ($view_mode != 'rss') {
-    if (user_access('view post access counter')) {
-      $statistics = statistics_get($node->nid);
-      if ($statistics) {
-        $links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads');
-        $node->content['links']['statistics'] = array(
-          '#theme' => 'links__node__statistics',
-          '#links' => $links,
-          '#attributes' => array('class' => array('links', 'inline')),
-        );
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_menu().
- */
-function statistics_menu() {
-  $items['admin/reports/hits'] = array(
-    'title' => 'Recent hits',
-    'description' => 'View pages that have recently been visited.',
-    'page callback' => 'statistics_recent_hits',
-    'access arguments' => array('access statistics'),
-    'file' => 'statistics.admin.inc',
-  );
-  $items['admin/reports/pages'] = array(
-    'title' => 'Top pages',
-    'description' => 'View pages that have been hit frequently.',
-    'page callback' => 'statistics_top_pages',
-    'access arguments' => array('access statistics'),
-    'weight' => 1,
-    'file' => 'statistics.admin.inc',
-  );
-  $items['admin/reports/visitors'] = array(
-    'title' => 'Top visitors',
-    'description' => 'View visitors that hit many pages.',
-    'page callback' => 'statistics_top_visitors',
-    'access arguments' => array('access statistics'),
-    'weight' => 2,
-    'file' => 'statistics.admin.inc',
-  );
-  $items['admin/reports/referrers'] = array(
-    'title' => 'Top referrers',
-    'description' => 'View top referrers.',
-    'page callback' => 'statistics_top_referrers',
-    'access arguments' => array('access statistics'),
-    'file' => 'statistics.admin.inc',
-  );
-  $items['admin/reports/access/%'] = array(
-    'title' => 'Details',
-    'description' => 'View access log.',
-    'page callback' => 'statistics_access_log',
-    'page arguments' => array(3),
-    'access arguments' => array('access statistics'),
-    'file' => 'statistics.admin.inc',
-  );
-  $items['admin/config/system/statistics'] = array(
-    'title' => 'Statistics',
-    'description' => 'Control details about what and how your site logs access statistics.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('statistics_settings_form'),
-    'access arguments' => array('administer statistics'),
-    'file' => 'statistics.admin.inc',
-    'weight' => -15,
-  );
-  $items['user/%user/track/navigation'] = array(
-    'title' => 'Track page visits',
-    'page callback' => 'statistics_user_tracker',
-    'access callback' => 'user_access',
-    'access arguments' => array('access statistics'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 2,
-    'file' => 'statistics.pages.inc',
-  );
-  $items['node/%node/track'] = array(
-    'title' => 'Track',
-    'page callback' => 'statistics_node_tracker',
-    'access callback' => 'user_access',
-    'access arguments' => array('access statistics'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 2,
-    'file' => 'statistics.pages.inc',
-  );
-
-  return $items;
-}
-
-/**
- * Implements hook_user_cancel().
- */
-function statistics_user_cancel($edit, $account, $method) {
-  switch ($method) {
-    case 'user_cancel_reassign':
-      db_update('accesslog')
-        ->fields(array('uid' => 0))
-        ->condition('uid', $account->uid)
-        ->execute();
-      break;
-  }
-}
-
-/**
- * Implements hook_user_delete().
- */
-function statistics_user_delete($account) {
-  db_delete('accesslog')
-    ->condition('uid', $account->uid)
-    ->execute();
-}
-
-/**
- * Implements hook_cron().
- */
-function statistics_cron() {
-  $statistics_timestamp = variable_get('statistics_day_timestamp', '');
-
-  if ((REQUEST_TIME - $statistics_timestamp) >= 86400) {
-    // Reset day counts.
-    db_update('node_counter')
-      ->fields(array('daycount' => 0))
-      ->execute();
-    variable_set('statistics_day_timestamp', REQUEST_TIME);
-  }
-
-  // Clean up expired access logs (if applicable).
-  if (variable_get('statistics_flush_accesslog_timer', 259200) > 0) {
-    db_delete('accesslog')
-      ->condition('timestamp', REQUEST_TIME - variable_get('statistics_flush_accesslog_timer', 259200), '<')
-      ->execute();
-  }
-}
-
-/**
- * Returns all time or today top or last viewed node(s).
- *
- * @param $dbfield
- *   one of
- *   - 'totalcount': top viewed content of all time.
- *   - 'daycount': top viewed content for today.
- *   - 'timestamp': last viewed node.
- *
- * @param $dbrows
- *   number of rows to be returned.
- *
- * @return
- *   A query result containing n.nid, n.title, u.uid, u.name of the selected node(s)
- *   or FALSE if the query could not be executed correctly.
- */
-function statistics_title_list($dbfield, $dbrows) {
-  if (in_array($dbfield, array('totalcount', 'daycount', 'timestamp'))) {
-    $query = db_select('node', 'n');
-    $query->addTag('node_access');
-    $query->join('node_counter', 's', 'n.nid = s.nid');
-    $query->join('users', 'u', 'n.uid = u.uid');
-
-    return $query
-      ->fields('n', array('nid', 'title'))
-      ->fields('u', array('uid', 'name'))
-      ->condition($dbfield, 0, '<>')
-      ->condition('n.status', 1)
-      ->orderBy($dbfield, 'DESC')
-      ->range(0, $dbrows)
-      ->execute();
-  }
-  return FALSE;
-}
-
-
-/**
- * Retrieves a node's "view statistics".
- *
- * @param $nid
- *   node ID
- *
- * @return
- *   An array with three entries: [0]=totalcount, [1]=daycount, [2]=timestamp
- *   - totalcount: count of the total number of times that node has been viewed.
- *   - daycount: count of the total number of times that node has been viewed "today".
- *     For the daycount to be reset, cron must be enabled.
- *   - timestamp: timestamp of when that node was last viewed.
- */
-function statistics_get($nid) {
-
-  if ($nid > 0) {
-    // Retrieve an array with both totalcount and daycount.
-    return db_query('SELECT totalcount, daycount, timestamp FROM {node_counter} WHERE nid = :nid', array(':nid' => $nid), array('target' => 'slave'))->fetchAssoc();
-  }
-}
-
-/**
- * Implements hook_block_info().
- */
-function statistics_block_info() {
-  $blocks = array();
-
-  if (variable_get('statistics_count_content_views', 0)) {
-    $blocks['popular']['info'] = t('Popular content');
-    // Too dynamic to cache.
-    $blocks['popular']['cache'] = DRUPAL_NO_CACHE;
-  }
-  return $blocks;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function statistics_block_configure($delta = '') {
-  // Popular content block settings
-  $numbers = array('0' => t('Disabled')) + drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40));
-  $form['statistics_block_top_day_num'] = array('#type' => 'select', '#title' => t("Number of day's top views to display"), '#default_value' => variable_get('statistics_block_top_day_num', 0), '#options' => $numbers, '#description' => t('How many content items to display in "day" list.'));
-  $form['statistics_block_top_all_num'] = array('#type' => 'select', '#title' => t('Number of all time views to display'), '#default_value' => variable_get('statistics_block_top_all_num', 0), '#options' => $numbers, '#description' => t('How many content items to display in "all time" list.'));
-  $form['statistics_block_top_last_num'] = array('#type' => 'select', '#title' => t('Number of most recent views to display'), '#default_value' => variable_get('statistics_block_top_last_num', 0), '#options' => $numbers, '#description' => t('How many content items to display in "recently viewed" list.'));
-  return $form;
-}
-
-/**
- * Implements hook_block_save().
- */
-function statistics_block_save($delta = '', $edit = array()) {
-  variable_set('statistics_block_top_day_num', $edit['statistics_block_top_day_num']);
-  variable_set('statistics_block_top_all_num', $edit['statistics_block_top_all_num']);
-  variable_set('statistics_block_top_last_num', $edit['statistics_block_top_last_num']);
-}
-
-/**
- * Implements hook_block_view().
- */
-function statistics_block_view($delta = '') {
-  if (user_access('access content')) {
-    $content = array();
-
-    $daytop = variable_get('statistics_block_top_day_num', 0);
-    if ($daytop && ($result = statistics_title_list('daycount', $daytop)) && ($node_title_list = node_title_list($result, t("Today's:")))) {
-      $content['top_day'] = $node_title_list;
-      $content['top_day']['#suffix'] = '<br />';
-    }
-
-    $alltimetop = variable_get('statistics_block_top_all_num', 0);
-    if ($alltimetop && ($result = statistics_title_list('totalcount', $alltimetop)) && ($node_title_list = node_title_list($result, t('All time:')))) {
-      $content['top_all'] = $node_title_list;
-      $content['top_all']['#suffix'] = '<br />';
-    }
-
-    $lasttop = variable_get('statistics_block_top_last_num', 0);
-    if ($lasttop && ($result = statistics_title_list('timestamp', $lasttop)) && ($node_title_list = node_title_list($result, t('Last viewed:')))) {
-      $content['top_last'] = $node_title_list;
-      $content['top_last']['#suffix'] = '<br />';
-    }
-
-    if (count($content)) {
-      $block['content'] = $content;
-      $block['subject'] = t('Popular content');
-      return $block;
-    }
-  }
-}
-
-/**
- * It is possible to adjust the width of columns generated by the
- * statistics module.
- */
-function _statistics_link($path, $width = 35) {
-  $title = drupal_get_path_alias($path);
-  $title = truncate_utf8($title, $width, FALSE, TRUE);
-  return l($title, $path);
-}
-
-function _statistics_format_item($title, $path) {
-  $path = ($path ? $path : '/');
-  $output  = ($title ? "$title<br />" : '');
-  $output .= _statistics_link($path);
-  return $output;
-}
-
-/**
- * Implements hook_node_delete().
- */
-function statistics_node_delete($node) {
-  // clean up statistics table when node is deleted
-  db_delete('node_counter')
-    ->condition('nid', $node->nid)
-    ->execute();
-}
-
-/**
- * Implements hook_ranking().
- */
-function statistics_ranking() {
-  if (variable_get('statistics_count_content_views', 0)) {
-    return array(
-      'views' => array(
-        'title' => t('Number of views'),
-        'join' => array(
-          'type' => 'LEFT',
-          'table' => 'node_counter',
-          'alias' => 'node_counter',
-          'on' => 'node_counter.nid = i.sid',
-        ),
-        // Inverse law that maps the highest view count on the site to 1 and 0 to 0.
-        'score' => '2.0 - 2.0 / (1.0 + node_counter.totalcount * CAST(:scale AS DECIMAL))',
-        'arguments' => array(':scale' => variable_get('node_cron_views_scale', 0)),
-      ),
-    );
-  }
-}
-
-/**
- * Implements hook_update_index().
- */
-function statistics_update_index() {
-  variable_set('node_cron_views_scale', 1.0 / max(1, db_query('SELECT MAX(totalcount) FROM {node_counter}')->fetchField()));
-}
diff --git a/modules/statistics/statistics.pages.inc b/modules/statistics/statistics.pages.inc
deleted file mode 100644
index bb31f98..0000000
--- a/modules/statistics/statistics.pages.inc
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the statistics module.
- */
-
-function statistics_node_tracker() {
-  if ($node = node_load(arg(1))) {
-
-    $header = array(
-        array('data' => t('Time'), 'field' => 'a.timestamp', 'sort' => 'desc'),
-        array('data' => t('Referrer'), 'field' => 'a.url'),
-        array('data' => t('User'), 'field' => 'u.name'),
-        array('data' => t('Operations')));
-
-    $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
-    $query->join('users', 'u', 'a.uid = u.uid');
-
-    $query
-      ->fields('a', array('aid', 'timestamp', 'url', 'uid'))
-      ->fields('u', array('name'))
-      ->condition(db_or()
-        ->condition('a.path', 'node/' . $node->nid)
-        ->condition('a.path', 'node/' . $node->nid . '/%', 'LIKE'))
-      ->limit(30)
-      ->orderByHeader($header);
-
-    $result = $query->execute();
-    $rows = array();
-    foreach ($result as $log) {
-      $rows[] = array(
-        array('data' => format_date($log->timestamp, 'short'), 'class' => array('nowrap')),
-        _statistics_link($log->url),
-        theme('username', array('account' => $log)),
-        l(t('details'), "admin/reports/access/$log->aid"),
-      );
-    }
-
-    drupal_set_title($node->title);
-    $build['statistics_table'] = array(
-      '#theme' => 'table',
-      '#header' => $header,
-      '#rows' => $rows,
-      '#empty' => t('No statistics available.'),
-    );
-    $build['statistics_pager'] = array('#theme' => 'pager');
-    return $build;
-  }
-  else {
-    drupal_not_found();
-  }
-}
-
-function statistics_user_tracker() {
-  if ($account = user_load(arg(1))) {
-
-    $header = array(
-        array('data' => t('Timestamp'), 'field' => 'timestamp', 'sort' => 'desc'),
-        array('data' => t('Page'), 'field' => 'path'),
-        array('data' => t('Operations')));
-    $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
-    $query
-      ->fields('a', array('aid', 'timestamp', 'path', 'title'))
-      ->condition('uid', $account->uid)
-      ->limit(30)
-      ->orderByHeader($header);
-
-    $result = $query->execute();
-    $rows = array();
-    foreach ($result as $log) {
-      $rows[] = array(
-        array('data' => format_date($log->timestamp, 'short'), 'class' => array('nowrap')),
-        _statistics_format_item($log->title, $log->path),
-        l(t('details'), "admin/reports/access/$log->aid"));
-    }
-
-    drupal_set_title(format_username($account));
-    $build['statistics_table'] = array(
-      '#theme' => 'table',
-      '#header' => $header,
-      '#rows' => $rows,
-      '#empty' => t('No statistics available.'),
-    );
-    $build['statistics_pager'] = array('#theme' => 'pager');
-    return $build;
-  }
-  else {
-    drupal_not_found();
-  }
-}
diff --git a/modules/statistics/statistics.test b/modules/statistics/statistics.test
deleted file mode 100644
index 126828f..0000000
--- a/modules/statistics/statistics.test
+++ /dev/null
@@ -1,444 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for statistics.module.
- */
-
-/**
- * Sets up a base class for the Statistics module.
- */
-class StatisticsTestCase extends DrupalWebTestCase {
-
-  function setUp() {
-    parent::setUp('statistics');
-
-    // Create user.
-    $this->blocking_user = $this->drupalCreateUser(array(
-      'access administration pages',
-      'access site reports',
-      'access statistics',
-      'block IP addresses',
-      'administer blocks',
-      'administer statistics',
-      'administer users',
-    ));
-    $this->drupalLogin($this->blocking_user);
-
-    // Enable access logging.
-    variable_set('statistics_enable_access_log', 1);
-    variable_set('statistics_count_content_views', 1);
-
-    // Insert dummy access by anonymous user into access log.
-    db_insert('accesslog')
-      ->fields(array(
-        'title' => 'test',
-        'path' => 'node/1',
-        'url' => 'http://example.com',
-        'hostname' => '192.168.1.1',
-        'uid' => 0,
-        'sid' => 10,
-        'timer' => 10,
-        'timestamp' => REQUEST_TIME,
-      ))
-      ->execute();
-  }
-}
-
-/**
- * Tests that logging via statistics_exit() works for cached and uncached pages.
- *
- * Subclass DrupalWebTestCase rather than StatisticsTestCase, because we want
- * to test requests from an anonymous user.
- */
-class StatisticsLoggingTestCase extends DrupalWebTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Statistics logging tests',
-      'description' => 'Tests request logging for cached and uncached pages.',
-      'group' => 'Statistics'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('statistics');
-
-    // Ensure we have a node page to access.
-    $this->node = $this->drupalCreateNode();
-    $this->auth_user = $this->drupalCreateUser();
-
-    // Enable page caching.
-    variable_set('cache', TRUE);
-
-    // Enable access logging.
-    variable_set('statistics_enable_access_log', 1);
-    variable_set('statistics_count_content_views', 1);
-
-    // Clear the logs.
-    db_truncate('accesslog');
-    db_truncate('node_counter');
-  }
-
-  /**
-   * Verifies request logging for cached and uncached pages.
-   */
-  function testLogging() {
-    $path = 'node/' . $this->node->nid;
-    $expected = array(
-      'title' => $this->node->title,
-      'path' => $path,
-    );
-
-    // Verify logging of an uncached page.
-    $this->drupalGet($path);
-    $this->assertIdentical($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', t('Testing an uncached page.'));
-    $log = db_query('SELECT * FROM {accesslog}')->fetchAll(PDO::FETCH_ASSOC);
-    $this->assertTrue(is_array($log) && count($log) == 1, t('Page request was logged.'));
-    $this->assertEqual(array_intersect_key($log[0], $expected), $expected);
-    $node_counter = statistics_get($this->node->nid);
-    $this->assertIdentical($node_counter['totalcount'], '1');
-
-    // Verify logging of a cached page.
-    $this->drupalGet($path);
-    $this->assertIdentical($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Testing a cached page.'));
-    $log = db_query('SELECT * FROM {accesslog}')->fetchAll(PDO::FETCH_ASSOC);
-    $this->assertTrue(is_array($log) && count($log) == 2, t('Page request was logged.'));
-    $this->assertEqual(array_intersect_key($log[1], $expected), $expected);
-    $node_counter = statistics_get($this->node->nid);
-    $this->assertIdentical($node_counter['totalcount'], '2');
-
-    // Test logging from authenticated users
-    $this->drupalLogin($this->auth_user);
-    $this->drupalGet($path);
-    $log = db_query('SELECT * FROM {accesslog}')->fetchAll(PDO::FETCH_ASSOC);
-    // Check the 6th item since login and account pages are also logged
-    $this->assertTrue(is_array($log) && count($log) == 6, t('Page request was logged.'));
-    $this->assertEqual(array_intersect_key($log[5], $expected), $expected);
-    $node_counter = statistics_get($this->node->nid);
-    $this->assertIdentical($node_counter['totalcount'], '3');
-  }
-}
-
-/**
- * Tests that report pages render properly, and that access logging works.
- */
-class StatisticsReportsTestCase extends StatisticsTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Statistics reports tests',
-      'description' => 'Tests display of statistics report pages and access logging.',
-      'group' => 'Statistics'
-    );
-  }
-
-  /**
-   * Verifies that 'Recent hits' renders properly and displays the added hit.
-   */
-  function testRecentHits() {
-    $this->drupalGet('admin/reports/hits');
-    $this->assertText('test', t('Hit title found.'));
-    $this->assertText('node/1', t('Hit URL found.'));
-    $this->assertText('Anonymous', t('Hit user found.'));
-  }
-
-  /**
-   * Verifies that 'Top pages' renders properly and displays the added hit.
-   */
-  function testTopPages() {
-    $this->drupalGet('admin/reports/pages');
-    $this->assertText('test', t('Hit title found.'));
-    $this->assertText('node/1', t('Hit URL found.'));
-  }
-
-  /**
-   * Verifies that 'Top referrers' renders properly and displays the added hit.
-   */
-  function testTopReferrers() {
-    $this->drupalGet('admin/reports/referrers');
-    $this->assertText('http://example.com', t('Hit referrer found.'));
-  }
-
-  /**
-   * Verifies that 'Details' page renders properly and displays the added hit.
-   */
-  function testDetails() {
-    $this->drupalGet('admin/reports/access/1');
-    $this->assertText('test', t('Hit title found.'));
-    $this->assertText('node/1', t('Hit URL found.'));
-    $this->assertText('Anonymous', t('Hit user found.'));
-  }
-
-  /**
-   * Verifies that access logging is working and is reported correctly.
-   */
-  function testAccessLogging() {
-    $this->drupalGet('admin/reports/referrers');
-    $this->drupalGet('admin/reports/hits');
-    $this->assertText('Top referrers in the past 3 days', t('Hit title found.'));
-    $this->assertText('admin/reports/referrers', t('Hit URL found.'));
-  }
-
-  /**
-   * Tests the "popular content" block.
-   */
-  function testPopularContentBlock() {
-    // Visit a node to have something show up in the block.
-    $node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->blocking_user->uid));
-    $this->drupalGet('node/' . $node->nid);
-
-    // Configure and save the block.
-    $block = block_load('statistics', 'popular');
-    $block->theme = variable_get('theme_default', 'bartik');
-    $block->status = 1;
-    $block->pages = '';
-    $block->region = 'sidebar_first';
-    $block->cache = -1;
-    $block->visibility = 0;
-    $edit = array('statistics_block_top_day_num' => 3, 'statistics_block_top_all_num' => 3, 'statistics_block_top_last_num' => 3);
-    module_invoke('statistics', 'block_save', 'popular', $edit);
-    drupal_write_record('block', $block);
-
-    // Get some page and check if the block is displayed.
-    $this->drupalGet('user');
-    $this->assertText('Popular content', t('Found the popular content block.'));
-    $this->assertText("Today's", t('Found today\'s popular content.'));
-    $this->assertText('All time', t('Found the alll time popular content.'));
-    $this->assertText('Last viewed', t('Found the last viewed popular content.'));
-
-    $this->assertRaw(l($node->title, 'node/' . $node->nid), t('Found link to visited node.'));
-  }
-}
-
-/**
- * Tests that the visitor blocking functionality works.
- */
-class StatisticsBlockVisitorsTestCase extends StatisticsTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Top visitor blocking',
-      'description' => 'Tests blocking of IP addresses via the top visitors report.',
-      'group' => 'Statistics'
-    );
-  }
-
-  /**
-   * Blocks an IP address via the top visitors report and then unblocks it.
-   */
-  function testIPAddressBlocking() {
-    // IP address for testing.
-    $test_ip_address = '192.168.1.1';
-
-    // Verify the IP address from accesslog appears on the top visitors page
-    // and that a 'block IP address' link is displayed.
-    $this->drupalLogin($this->blocking_user);
-    $this->drupalGet('admin/reports/visitors');
-    $this->assertText($test_ip_address, t('IP address found.'));
-    $this->assertText(t('block IP address'), t('Block IP link displayed'));
-
-    // Block the IP address.
-    $this->clickLink('block IP address');
-    $this->assertText(t('IP address blocking'), t('IP blocking page displayed.'));
-    $edit = array();
-    $edit['ip'] = $test_ip_address;
-    $this->drupalPost('admin/config/people/ip-blocking', $edit, t('Add'));
-    $ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $edit['ip']))->fetchField();
-    $this->assertNotEqual($ip, FALSE, t('IP address found in database'));
-    $this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $edit['ip'])), t('IP address was blocked.'));
-
-    // Verify that the block/unblock link on the top visitors page has been
-    // altered.
-    $this->drupalGet('admin/reports/visitors');
-    $this->assertText(t('unblock IP address'), t('Unblock IP address link displayed'));
-
-    // Unblock the IP address.
-    $this->clickLink('unblock IP address');
-    $this->assertRaw(t('Are you sure you want to delete %ip?', array('%ip' => $test_ip_address)), t('IP address deletion confirmation found.'));
-    $edit = array();
-    $this->drupalPost('admin/config/people/ip-blocking/delete/1', NULL, t('Delete'));
-    $this->assertRaw(t('The IP address %ip was deleted.', array('%ip' => $test_ip_address)), t('IP address deleted.'));
-  }
-}
-
-/**
- * Test statistics administration screen.
- */
-class StatisticsAdminTestCase extends DrupalWebTestCase {
-  protected $privileged_user;
-  protected $test_node;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Test statistics admin.',
-      'description' => 'Tests the statistics admin.',
-      'group' => 'Statistics'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('statistics');
-    $this->privileged_user = $this->drupalCreateUser(array('access statistics', 'administer statistics', 'view post access counter', 'create page content'));
-    $this->drupalLogin($this->privileged_user);
-    $this->test_node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->privileged_user->uid));
-  }
-
-  /**
-   * Verifies that the statistics settings page works.
-   */
-  function testStatisticsSettings() {
-    $this->assertFalse(variable_get('statistics_enable_access_log', 0), t('Access log is disabled by default.'));
-    $this->assertFalse(variable_get('statistics_count_content_views', 0), t('Count content view log is disabled by default.'));
-
-    $this->drupalGet('admin/reports/pages');
-    $this->assertRaw(t('No statistics available.'), t('Verifying text shown when no statistics is available.'));
-
-    // Enable access log and counter on content view.
-    $edit['statistics_enable_access_log'] = 1;
-    $edit['statistics_count_content_views'] = 1;
-    $this->drupalPost('admin/config/system/statistics', $edit, t('Save configuration'));
-    $this->assertTrue(variable_get('statistics_enable_access_log'), t('Access log is enabled.'));
-    $this->assertTrue(variable_get('statistics_count_content_views'), t('Count content view log is enabled.'));
-
-    // Hit the node.
-    $this->drupalGet('node/' . $this->test_node->nid);
-
-    $this->drupalGet('admin/reports/pages');
-    $this->assertText('node/1', t('Test node found.'));
-
-    // Hit the node again (the counter is incremented after the hit, so
-    // "1 read" will actually be shown when the node is hit the second time).
-    $this->drupalGet('node/' . $this->test_node->nid);
-    $this->assertText('1 read', t('Node is read once.'));
-
-    $this->drupalGet('node/' . $this->test_node->nid);
-    $this->assertText('2 reads', t('Node is read 2 times.'));
-  }
-
-  /**
-   * Tests that when a node is deleted, the node counter is deleted too.
-   */
-  function testDeleteNode() {
-    variable_set('statistics_count_content_views', 1);
-
-    $this->drupalGet('node/' . $this->test_node->nid);
-
-    $result = db_select('node_counter', 'n')
-      ->fields('n', array('nid'))
-      ->condition('n.nid', $this->test_node->nid)
-      ->execute()
-      ->fetchAssoc();
-    $this->assertEqual($result['nid'], $this->test_node->nid, 'Verifying that the node counter is incremented.');
-
-    node_delete($this->test_node->nid);
-
-    $result = db_select('node_counter', 'n')
-      ->fields('n', array('nid'))
-      ->condition('n.nid', $this->test_node->nid)
-      ->execute()
-      ->fetchAssoc();
-    $this->assertFalse($result, 'Verifying that the node counter is deleted.');
-  }
-
-  /**
-   * Tests that accesslog reflects when a user is deleted.
-   */
-  function testDeleteUser() {
-    variable_set('statistics_enable_access_log', 1);
-
-    variable_set('user_cancel_method', 'user_cancel_delete');
-    $this->drupalLogout($this->privileged_user);
-    $account = $this->drupalCreateUser(array('access content', 'cancel account'));
-    $this->drupalLogin($account);
-    $this->drupalGet('node/' . $this->test_node->nid);
-
-    $account = user_load($account->uid, TRUE);
-
-    $this->drupalGet('user/' . $account->uid . '/edit');
-    $this->drupalPost(NULL, NULL, t('Cancel account'));
-
-    $timestamp = time();
-    $this->drupalPost(NULL, NULL, t('Cancel account'));
-    // Confirm account cancellation request.
-    $this->drupalGet("user/$account->uid/cancel/confirm/$timestamp/" . user_pass_rehash($account->pass, $timestamp, $account->login));
-    $this->assertFalse(user_load($account->uid, TRUE), t('User is not found in the database.'));
-
-    $this->drupalGet('admin/reports/visitors');
-    $this->assertNoText($account->name, t('Did not find user in visitor statistics.'));
-  }
-
-  /**
-   * Tests that cron clears day counts and expired access logs.
-   */
-  function testExpiredLogs() {
-    variable_set('statistics_enable_access_log', 1);
-    variable_set('statistics_count_content_views', 1);
-    variable_set('statistics_day_timestamp', 8640000);
-    variable_set('statistics_flush_accesslog_timer', 1);
-
-    $this->drupalGet('node/' . $this->test_node->nid);
-    $this->drupalGet('node/' . $this->test_node->nid);
-    $this->assertText('1 read', t('Node is read once.'));
-
-    $this->drupalGet('admin/reports/pages');
-    $this->assertText('node/' . $this->test_node->nid, t('Hit URL found.'));
-
-    // statistics_cron will subtract the statistics_flush_accesslog_timer
-    // variable from REQUEST_TIME in the delete query, so wait two secs here to
-    // make sure the access log will be flushed for the node just hit.
-    sleep(2);
-    $this->cronRun();
-
-    $this->drupalGet('admin/reports/pages');
-    $this->assertNoText('node/' . $this->test_node->nid, t('No hit URL found.'));
-
-    $result = db_select('node_counter', 'nc')
-      ->fields('nc', array('daycount'))
-      ->condition('nid', $this->test_node->nid, '=')
-      ->execute()
-      ->fetchField();
-    $this->assertFalse($result, t('Daycounter is zero.'));
-  }
-}
-
-/**
- * Test statistics token replacement in strings.
- */
-class StatisticsTokenReplaceTestCase extends StatisticsTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Statistics token replacement',
-      'description' => 'Generates text using placeholders for dummy content to check statistics token replacement.',
-      'group' => 'Statistics',
-    );
-  }
-
-  /**
-   * Creates a node, then tests the statistics tokens generated from it.
-   */
-  function testStatisticsTokenReplacement() {
-    global $language;
-
-    // Create user and node.
-    $user = $this->drupalCreateUser(array('create page content'));
-    $this->drupalLogin($user);
-    $node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $user->uid));
-
-    // Hit the node.
-    $this->drupalGet('node/' . $node->nid);
-    $statistics = statistics_get($node->nid);
-
-    // Generate and test tokens.
-    $tests = array();
-    $tests['[node:total-count]'] = 1;
-    $tests['[node:day-count]'] = 1;
-    $tests['[node:last-view]'] = format_date($statistics['timestamp']);
-    $tests['[node:last-view:short]'] = format_date($statistics['timestamp'], 'short');
-
-    // Test to make sure that we generated something for each token.
-    $this->assertFalse(in_array(0, array_map('strlen', $tests)), t('No empty tokens generated.'));
-
-    foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('language' => $language));
-      $this->assertEqual($output, $expected, t('Statistics token %token replaced.', array('%token' => $input)));
-    }
-  }
-}
diff --git a/modules/statistics/statistics.tokens.inc b/modules/statistics/statistics.tokens.inc
deleted file mode 100644
index c2c8fc3..0000000
--- a/modules/statistics/statistics.tokens.inc
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Builds placeholder replacement tokens for node visitor statistics.
- */
-
-/**
- * Implements hook_token_info().
- */
-function statistics_token_info() {
-  $node['total-count'] = array(
-    'name' => t("Number of views"),
-    'description' => t("The number of visitors who have read the node."),
-  );
-  $node['day-count'] = array(
-    'name' => t("Views today"),
-    'description' => t("The number of visitors who have read the node today."),
-  );
-  $node['last-view'] = array(
-    'name' => t("Last view"),
-    'description' => t("The date on which a visitor last read the node."),
-    'type' => 'date',
-  );
-
-  return array(
-    'tokens' => array('node' => $node),
-  );
-}
-
-/**
- * Implements hook_tokens().
- */
-function statistics_tokens($type, $tokens, array $data = array(), array $options = array()) {
-  $url_options = array('absolute' => TRUE);
-  $replacements = array();
-
-  if ($type == 'node' & !empty($data['node'])) {
-    $node = $data['node'];
-
-    foreach ($tokens as $name => $original) {
-      if ($name == 'total-count') {
-        $statistics = statistics_get($node->nid);
-        $replacements[$original] = $statistics['totalcount'];
-      }
-      elseif ($name == 'day-count') {
-        $statistics = statistics_get($node->nid);
-        $replacements[$original] = $statistics['daycount'];
-      }
-      elseif ($name == 'last-view') {
-        $statistics = statistics_get($node->nid);
-        $replacements[$original] = format_date($statistics['timestamp']);
-      }
-    }
-
-    if ($created_tokens = token_find_with_prefix($tokens, 'last-view')) {
-      $statistics = statistics_get($node->nid);
-      $replacements += token_generate('date', $created_tokens, array('date' => $statistics['timestamp']), $options);
-    }
-  }
-
-  return $replacements;
-}
diff --git a/modules/toolbar/toolbar-rtl.css b/modules/toolbar/toolbar-rtl.css
deleted file mode 100644
index acbc98f..0000000
--- a/modules/toolbar/toolbar-rtl.css
+++ /dev/null
@@ -1,41 +0,0 @@
-
-#toolbar,
-#toolbar * {
-  text-align: right;
-}
-#toolbar ul li {
-  float: right;
-}
-#toolbar ul li a {
-  display: inline-block;
-  float: none;
-  zoom: 1;
-}
-#toolbar div.toolbar-menu {
-  padding: 5px 50px 5px 50px;
-}
-#toolbar-user {
-  float: left;
-}
-#toolbar ul#toolbar-user li {
-  float: none;
-  display: inline;
-}
-#toolbar-menu {
-  float: none;
-}
-#toolbar-home {
-  float: right;
-}
-#toolbar ul li.home a {
-  position: absolute;
-  right: 10px;
-}
-#toolbar div.toolbar-menu a.toggle {
-  left: 10px;
-  right: auto;
-}
-* html #toolbar {
-  left: 0;
-  padding-left: 0;
-}
diff --git a/modules/toolbar/toolbar.css b/modules/toolbar/toolbar.css
deleted file mode 100644
index cbf3c14..0000000
--- a/modules/toolbar/toolbar.css
+++ /dev/null
@@ -1,150 +0,0 @@
-
-body.toolbar {
-  padding-top: 2.2em;
-}
-body.toolbar-drawer {
-  padding-top: 5.3em;
-}
-
-/**
- * Aggressive resets so we can achieve a consistent look in hostile CSS
- * environments.
- */
-#toolbar,
-#toolbar * {
-  border: 0;
-  font-size: 100%;
-  line-height: inherit;
-  list-style: none;
-  margin: 0;
-  outline: 0;
-  padding: 0;
-  text-align: left; /* LTR */
-  vertical-align: baseline;
-}
-
-/**
- * Base styles.
- *
- * We use a keyword for the toolbar font size to make it display consistently
- * across different themes, while still allowing browsers to resize the text.
- */
-#toolbar {
-  background: #666;
-  color: #ccc;
-  font: normal small "Lucida Grande", Verdana, sans-serif;
-  left: 0;
-  margin: 0 -20px;
-  padding: 0 20px;
-  position: fixed;
-  right: 0;
-  top: 0;
-  -moz-box-shadow: 0 3px 20px #000;
-  -webkit-box-shadow: 0 3px 20px #000;
-  box-shadow: 0 3px 20px #000;
-  filter: progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10');
-  -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10')";
-  z-index: 600;
-}
-#toolbar div.collapsed {
-  display: none;
-  visibility: hidden;
-}
-#toolbar a {
-  color: #fff;
-  font-size: .846em;
-  text-decoration: none;
-}
-#toolbar ul li,
-#toolbar ul li a {
-  float: left; /* LTR */
-}
-
-/**
- * Administration menu.
- */
-#toolbar div.toolbar-menu {
-  background: #000;
-  line-height: 20px;
-  padding: 5px 50px 5px 10px; /* LTR */
-  position: relative;
-}
-#toolbar-home a span {
-  background: url(toolbar.png) no-repeat 0 -45px;
-  display: block;
-  height: 14px;
-  margin: 3px 0px;
-  text-indent: -9999px;
-  vertical-align: text-bottom;
-  width: 11px;
-}
-#toolbar-user {
-  float: right; /* LTR */
-}
-#toolbar-menu {
-  float: left; /* LTR */
-}
-#toolbar div.toolbar-menu a.toggle {
-  background: url(toolbar.png) 0 -20px no-repeat;
-  bottom: 0;
-  cursor: pointer;
-  height: 25px;
-  overflow: hidden;
-  position: absolute;
-  right: 10px; /* LTR */
-  text-indent: -9999px;
-  width: 25px;
-}
-#toolbar div.toolbar-menu a.toggle:focus,
-#toolbar div.toolbar-menu a.toggle:hover {
-  background-position:  -50px -20px;
-}
-#toolbar div.toolbar-menu a.toggle-active {
-  background-position:  -25px -20px;
-}
-#toolbar div.toolbar-menu a.toggle-active.toggle:focus,
-#toolbar div.toolbar-menu a.toggle-active.toggle:hover {
-  background-position:  -75px -20px;
-}
-#toolbar div.toolbar-menu ul li a {
-  padding: 0 10px;
-  -moz-border-radius: 10px;
-  -webkit-border-radius: 10px;
-  border-radius: 10px;
-}
-#toolbar div.toolbar-menu ul li a:focus,
-#toolbar div.toolbar-menu ul li a:hover,
-#toolbar div.toolbar-menu ul li a:active,
-#toolbar div.toolbar-menu ul li a.active:focus {
-  background: #444;
-}
-#toolbar div.toolbar-menu ul li a.active:hover,
-#toolbar div.toolbar-menu ul li a.active:active,
-#toolbar div.toolbar-menu ul li a.active,
-#toolbar div.toolbar-menu ul li.active-trail a {
-  background: url(toolbar.png) 0 0 repeat-x;
-  text-shadow: #333 0 1px 0;
-}
-
-/**
- * Collapsed drawer of additional toolbar content.
- */
-#toolbar div.toolbar-drawer {
-  position: relative;
-  padding: 0 10px;
-}
-
-/**
- * IE 6 Fix.
- *
- * IE 6 shows elements with position:fixed as position:static so we replace
- * it with position:absolute; toolbar needs its z-index to stay above overlay.
- */
-* html #toolbar {
-  left: -20px;
-  margin: 0;
-  padding-right: 0;
-  position: absolute;
-  right: 0;
-  width: 100%;
-}
diff --git a/modules/toolbar/toolbar.info b/modules/toolbar/toolbar.info
deleted file mode 100644
index 758dc9c..0000000
--- a/modules/toolbar/toolbar.info
+++ /dev/null
@@ -1,5 +0,0 @@
-name = Toolbar
-description = Provides a toolbar that shows the top-level administration menu items and links from other modules.
-core = 8.x
-package = Core
-version = VERSION
diff --git a/modules/toolbar/toolbar.js b/modules/toolbar/toolbar.js
deleted file mode 100644
index 5b61634..0000000
--- a/modules/toolbar/toolbar.js
+++ /dev/null
@@ -1,106 +0,0 @@
-(function ($) {
-
-Drupal.toolbar = Drupal.toolbar || {};
-
-/**
- * Attach toggling behavior and notify the overlay of the toolbar.
- */
-Drupal.behaviors.toolbar = {
-  attach: function(context) {
-
-    // Set the initial state of the toolbar.
-    $('#toolbar', context).once('toolbar', Drupal.toolbar.init);
-
-    // Toggling toolbar drawer.
-    $('#toolbar a.toggle', context).once('toolbar-toggle').click(function(e) {
-      Drupal.toolbar.toggle();
-      // Allow resize event handlers to recalculate sizes/positions.
-      $(window).triggerHandler('resize');
-      return false;
-    });
-  }
-};
-
-/**
- * Retrieve last saved cookie settings and set up the initial toolbar state.
- */
-Drupal.toolbar.init = function() {
-  // Retrieve the collapsed status from a stored cookie.
-  var collapsed = $.cookie('Drupal.toolbar.collapsed');
-
-  // Expand or collapse the toolbar based on the cookie value.
-  if (collapsed == 1) {
-    Drupal.toolbar.collapse();
-  }
-  else {
-    Drupal.toolbar.expand();
-  }
-};
-
-/**
- * Collapse the toolbar.
- */
-Drupal.toolbar.collapse = function() {
-  var toggle_text = Drupal.t('Show shortcuts');
-  $('#toolbar div.toolbar-drawer').addClass('collapsed');
-  $('#toolbar a.toggle')
-    .removeClass('toggle-active')
-    .attr('title',  toggle_text)
-    .html(toggle_text);
-  $('body').removeClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
-  $.cookie(
-    'Drupal.toolbar.collapsed',
-    1,
-    {
-      path: Drupal.settings.basePath,
-      // The cookie should "never" expire.
-      expires: 36500
-    }
-  );
-};
-
-/**
- * Expand the toolbar.
- */
-Drupal.toolbar.expand = function() {
-  var toggle_text = Drupal.t('Hide shortcuts');
-  $('#toolbar div.toolbar-drawer').removeClass('collapsed');
-  $('#toolbar a.toggle')
-    .addClass('toggle-active')
-    .attr('title',  toggle_text)
-    .html(toggle_text);
-  $('body').addClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
-  $.cookie(
-    'Drupal.toolbar.collapsed',
-    0,
-    {
-      path: Drupal.settings.basePath,
-      // The cookie should "never" expire.
-      expires: 36500
-    }
-  );
-};
-
-/**
- * Toggle the toolbar.
- */
-Drupal.toolbar.toggle = function() {
-  if ($('#toolbar div.toolbar-drawer').hasClass('collapsed')) {
-    Drupal.toolbar.expand();
-  }
-  else {
-    Drupal.toolbar.collapse();
-  }
-};
-
-Drupal.toolbar.height = function() {
-  var height = $('#toolbar').outerHeight();
-  // In IE, Shadow filter adds some extra height, so we need to remove it from
-  // the returned height.
-  if ($('#toolbar').css('filter').match(/DXImageTransform\.Microsoft\.Shadow/)) {
-    height -= $('#toolbar').get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength;
-  }
-  return height;
-};
-
-})(jQuery);
diff --git a/modules/toolbar/toolbar.module b/modules/toolbar/toolbar.module
deleted file mode 100644
index 61ae648..0000000
--- a/modules/toolbar/toolbar.module
+++ /dev/null
@@ -1,350 +0,0 @@
-<?php
-
-/**
- * @file
- * Administration toolbar for quick access to top level administration items.
- */
-
-/**
- * Implements hook_help().
- */
-function toolbar_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#toolbar':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Toolbar module displays links to top-level administration menu items and links from other modules at the top of the screen. For more information, see the online handbook entry for <a href="@toolbar">Toolbar module</a>.', array('@toolbar' => 'http://drupal.org/handbook/modules/toolbar/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Displaying administrative links') . '</dt>';
-      $output .= '<dd>' . t('The Toolbar module displays a bar containing top-level administrative links across the top of the screen. Below that, the Toolbar module has a <em>drawer</em> section where it displays links provided by other modules, such as the core <a href="@shortcuts-help">Shortcut module</a>. The drawer can be hidden/shown by using the show/hide shortcuts link at the end of the toolbar.', array('@shortcuts-help' => url('admin/help/shortcut'))) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_permission().
- */
-function toolbar_permission() {
-  return array(
-    'access toolbar' => array(
-      'title' => t('Use the administration toolbar'),
-    ),
-  );
-}
-
-/**
- * Implements hook_theme().
- */
-function toolbar_theme($existing, $type, $theme, $path) {
-  $items['toolbar'] = array(
-    'render element' => 'toolbar',
-    'template' => 'toolbar',
-    'path' => drupal_get_path('module', 'toolbar'),
-  );
-  $items['toolbar_toggle'] = array(
-    'variables' => array(
-      'collapsed' => NULL,
-      'attributes' => array(),
-    ),
-  );
-  return $items;
-}
-
-/**
- * Implements hook_menu().
- */
-function toolbar_menu() {
-  $items['toolbar/toggle'] = array(
-    'title' => 'Toggle drawer visibility',
-    'type' => MENU_CALLBACK,
-    'page callback' => 'toolbar_toggle_page',
-    'access arguments' => array('access toolbar'),
-  );
-  return $items;
-}
-
-/**
- * Menu callback; toggles the visibility of the toolbar drawer.
- */
-function toolbar_toggle_page() {
-  global $base_path;
-  // Toggle the value in the cookie.
-  setcookie('Drupal.toolbar.collapsed', !_toolbar_is_collapsed(), NULL, $base_path);
-  // Redirect the user from where he used the toggle element.
-  drupal_goto();
-}
-
-/**
- * Formats an element used to toggle the toolbar drawer's visibility.
- *
- * @param $variables
- *   An associative array containing:
- *   - collapsed: A boolean value representing the toolbar drawer's visibility.
- *   - attributes: An associative array of HTML attributes.
- * @return
- *   An HTML string representing the element for toggling.
- *
- * @ingroup themable
- */
-function theme_toolbar_toggle($variables) {
-  if ($variables['collapsed']) {
-    $toggle_text = t('Show shortcuts');
-  }
-  else {
-    $toggle_text = t('Hide shortcuts');
-    $variables['attributes']['class'][] = 'toggle-active';
-  }
-  return l($toggle_text, 'toolbar/toggle', array('query' => drupal_get_destination(), 'attributes' => array('title' => $toggle_text) + $variables['attributes']));
-}
-
-/**
- * Determines the current state of the toolbar drawer's visibility.
- *
- * @return
- *   TRUE when drawer is collapsed, FALSE when it is expanded.
- */
-function _toolbar_is_collapsed() {
-  // PHP converts dots into underscores in cookie names to avoid problems with
-  // its parser, so we use a converted cookie name.
-  return isset($_COOKIE['Drupal_toolbar_collapsed']) ? $_COOKIE['Drupal_toolbar_collapsed'] : 0;
-}
-
-/**
- * Implements hook_page_build().
- *
- * Add admin toolbar to the page_top region automatically.
- */
-function toolbar_page_build(&$page) {
-  $page['page_top']['toolbar'] = array(
-    '#pre_render' => array('toolbar_pre_render'),
-    '#access' => user_access('access toolbar'),
-    'toolbar_drawer' => array(),
-  );
-}
-
-/**
- * Prerender function for the toolbar.
- *
- * Since building the toolbar takes some time, it is done just prior to
- * rendering to ensure that it is built only if it will be displayed.
- */
-function toolbar_pre_render($toolbar) {
-  $toolbar = array_merge($toolbar, toolbar_view());
-  return $toolbar;
-}
-
-/**
- * Implements hook_preprocess_html().
- *
- * Add some page classes, so global page theming can adjust to the toolbar.
- */
-function toolbar_preprocess_html(&$vars) {
-  if (isset($vars['page']['page_top']['toolbar']) && user_access('access toolbar')) {
-    $vars['classes_array'][] = 'toolbar';
-    if (!_toolbar_is_collapsed()) {
-      $vars['classes_array'][] = 'toolbar-drawer';
-    }
-  }
-}
-
-/**
- * Implements hook_preprocess_toolbar().
- *
- * Adding the 'overlay-displace-top' class to the toolbar pushes the overlay
- * down, so it appears below the toolbar.
- */
-function toolbar_preprocess_toolbar(&$variables) {
-  $variables['classes_array'][] = "overlay-displace-top";
-}
-
-/**
- * Implements hook_system_info_alter().
- *
- * Indicate that the 'page_top' region (in which the toolbar will be displayed)
- * is an overlay supplemental region that should be refreshed whenever its
- * content is updated.
- *
- * This information is provided for any module that might need to use it, not
- * just the core Overlay module.
- */
-function toolbar_system_info_alter(&$info, $file, $type) {
-  if ($type == 'theme') {
-    $info['overlay_supplemental_regions'][] = 'page_top';
-  }
-}
-
-/**
- * Build the admin menu as a structured array ready for drupal_render().
- */
-function toolbar_view() {
-  global $user;
-
-  $module_path = drupal_get_path('module', 'toolbar');
-  $build = array(
-    '#theme' => 'toolbar',
-    '#attached'=> array(
-      'js' => array(
-        $module_path . '/toolbar.js',
-        array(
-          'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'),
-          'type' => 'setting'
-        ),
-      ),
-      'css' => array(
-        $module_path . '/toolbar.css',
-      ),
-      'library' => array(array('system', 'jquery.cookie')),
-    ),
-  );
-
-  // Retrieve the admin menu from the database.
-  $links = toolbar_menu_navigation_links(toolbar_get_menu_tree());
-  $build['toolbar_menu'] = array(
-    '#theme' => 'links__toolbar_menu',
-    '#links' => $links,
-    '#attributes' => array('id' => 'toolbar-menu'),
-    '#heading' => array('text' => t('Administrative toolbar'), 'level' => 'h2', 'class' => 'element-invisible'),
-  );
-
-  // Add logout & user account links or login link.
-  if ($user->uid) {
-    $links = array(
-      'account' => array(
-        'title' => t('Hello <strong>@username</strong>', array('@username' => format_username($user))),
-        'href' => 'user',
-        'html' => TRUE,
-        'attributes' => array('title' => t('User account')),
-      ),
-      'logout' => array(
-        'title' => t('Log out'),
-        'href' => 'user/logout',
-      ),
-    );
-  }
-  else {
-     $links = array(
-      'login' => array(
-        'title' => t('Log in'),
-        'href' => 'user',
-      ),
-    );
-  }
-  $build['toolbar_user'] = array(
-    '#theme' => 'links__toolbar_user',
-    '#links' => $links,
-    '#attributes' => array('id' => 'toolbar-user'),
-  );
-
-  // Add a "home" link.
-  $link = array(
-    'home' => array(
-      'title' => '<span class="home-link">Home</span>',
-      'href' => '<front>',
-      'html' => TRUE,
-      'attributes' => array('title' => t('Home')),
-    ),
-  );
-  $build['toolbar_home'] = array(
-    '#theme' => 'links',
-    '#links' => $link,
-    '#attributes' => array('id' => 'toolbar-home'),
-  );
-
-  // Add an anchor to be able to toggle the visibility of the drawer.
-  $build['toolbar_toggle'] = array(
-    '#theme' => 'toolbar_toggle',
-    '#collapsed' => _toolbar_is_collapsed(),
-    '#attributes' => array('class' => array('toggle')),
-  );
-
-  // Prepare the drawer links CSS classes.
-  $toolbar_drawer_classes = array(
-    'toolbar-drawer',
-    'clearfix',
-  );
-  if(_toolbar_is_collapsed()) {
-    $toolbar_drawer_classes[] = 'collapsed';
-  }
-  $build['toolbar_drawer_classes'] = implode(' ', $toolbar_drawer_classes);
-
-  return $build;
-}
-
-/**
- * Get only the top level items below the 'admin' path.
- */
-function toolbar_get_menu_tree() {
-  $tree = array();
-  $admin_link = db_query('SELECT * FROM {menu_links} WHERE menu_name = :menu_name AND module = :module AND link_path = :path', array(':menu_name' => 'management', ':module' => 'system', ':path' => 'admin'))->fetchAssoc();
-  if ($admin_link) {
-    $tree = menu_build_tree('management', array(
-      'expanded' => array($admin_link['mlid']),
-      'min_depth' => $admin_link['depth'] + 1,
-      'max_depth' => $admin_link['depth'] + 1,
-    ));
-  }
-
-  return $tree;
-}
-
-/**
- * Generate a links array from a menu tree array.
- *
- * Based on menu_navigation_links(). Adds path based IDs and icon placeholders
- * to the links.
- */
-function toolbar_menu_navigation_links($tree) {
-  $links = array();
-  foreach ($tree as $item) {
-    if (!$item['link']['hidden'] && $item['link']['access']) {
-      // Make sure we have a path specific ID in place, so we can attach icons
-      // and behaviors to the items.
-      $id = str_replace(array('/', '<', '>'), array('-', '', ''), $item['link']['href']);
-
-      $link = $item['link']['localized_options'];
-      $link['href'] = $item['link']['href'];
-      // Add icon placeholder.
-      $link['title'] = '<span class="icon"></span>' . check_plain($item['link']['title']);
-      // Add admin link ID.
-      $link['attributes'] = array('id' => 'toolbar-link-' . $id);
-      if (!empty($item['link']['description'])) {
-        $link['title'] .= ' <span class="element-invisible">(' . $item['link']['description'] . ')</span>';
-        $link['attributes']['title'] = $item['link']['description'];
-      }
-      $link['html'] = TRUE;
-
-      $class = ' path-' . $id;
-      if (toolbar_in_active_trail($item['link']['href'])) {
-        $class .= ' active-trail';
-      }
-      $links['menu-' . $item['link']['mlid'] . $class] = $link;
-    }
-  }
-  return $links;
-}
-
-/**
- * Checks whether an item is in the active trail.
- *
- * Useful when using a menu generated by menu_tree_all_data() which does
- * not set the 'in_active_trail' flag on items.
- *
- * @todo
- *   Look at migrating to a menu system level function.
- */
-function toolbar_in_active_trail($path) {
-  $active_paths = &drupal_static(__FUNCTION__);
-
-  // Gather active paths.
-  if (!isset($active_paths)) {
-    $active_paths = array();
-    $trail = menu_get_active_trail();
-    foreach ($trail as $item) {
-      if (!empty($item['href'])) {
-        $active_paths[] = $item['href'];
-      }
-    }
-  }
-  return in_array($path, $active_paths);
-}
diff --git a/modules/toolbar/toolbar.png b/modules/toolbar/toolbar.png
deleted file mode 100644
index f2c7f355a6d9d8acb478f25a74ec1670cde26445..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 558
zcmeAS@N?(olHy`uVBq!ia0vp^DL`z=!3-q7>(u!JsqFziA+A9B|NsAKX=!j0$Up`_
zDF^_nWMpJyVq#)uW@cew;o#t~wY9agvvYTM_weut2nYxa42+0~04i>1XlQC`YH4X{
zZEbCDZ|~^n=<4d~>FMe1?d|XHpD<y<q)C&eOqnuu>eT7er_Y!%W7e!$bLPyMJ9qB<
z`SX`AU%qbLy7lYVZ{NOs$BrEb4<0;p=+O7?-+%x9{pZi0zkmP!`}Ys%yrsn~H-HY}
zD+%%oW?&GIZRqIkn>cmmg$Ez}_rz5JT`J+};uunK>+R)e|3eM}Z4dJ|aEYwo2;*D4
zsOh<|h~SZ*|Mz>F_Znul2~2v|(p{_fEluy<T~D$1Y#-7X*0X&`VmQzCA%&rz?Lz{?
zcea9bhV5(yh7B7T??@cj$`~Vg-~@vn?}I}O=Xe=9X2o3T33#>OQiAW|phpaXuNMii
zXKY*-`iLP%!Nuu_#-;S58)jSFRn#^L^O^ogXL*#0uV19$i$7*o%walDCW~&K+Oa0>
zmUq?LCqH_+KRNC`-t{wTpS>B+wc^y+pRN8^dY5|c`gkaQ=D#DX;!4rs_wVoewMggB
zWC6~JwLKOtHyGdYoI9vk*&m?e{>0KLRB+{_>l{~)tekk9<Em=7di}(Re@Ff)eL5e1
hBy_@j#ZB@P<q!DTXx&t5{QwL-22WQ%mvv4FO#l<-22ub3

diff --git a/modules/toolbar/toolbar.tpl.php b/modules/toolbar/toolbar.tpl.php
deleted file mode 100644
index 1df0cf0..0000000
--- a/modules/toolbar/toolbar.tpl.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Default template for admin toolbar.
- *
- * Available variables:
- * - $classes: String of classes that can be used to style contextually through
- *   CSS. It can be manipulated through the variable $classes_array from
- *   preprocess functions. The default value has the following:
- *   - toolbar: The current template type, i.e., "theming hook".
- * - $toolbar['toolbar_user']: User account / logout links.
- * - $toolbar['toolbar_menu']: Top level management menu links.
- * - $toolbar['toolbar_drawer']: A place for extended toolbar content.
- *
- * Other variables:
- * - $classes_array: Array of html class attribute values. It is flattened
- *   into a string within the variable $classes.
- *
- * @see template_preprocess()
- * @see template_preprocess_toolbar()
- */
-?>
-<div id="toolbar" class="<?php print $classes; ?> clearfix">
-  <div class="toolbar-menu clearfix">
-    <?php print render($toolbar['toolbar_home']); ?>
-    <?php print render($toolbar['toolbar_user']); ?>
-    <?php print render($toolbar['toolbar_menu']); ?>
-    <?php if ($toolbar['toolbar_drawer']):?>
-      <?php print render($toolbar['toolbar_toggle']); ?>
-    <?php endif; ?>
-  </div>
-
-  <div class="<?php echo $toolbar['toolbar_drawer_classes']; ?>">
-    <?php print render($toolbar['toolbar_drawer']); ?>
-  </div>
-</div>
diff --git a/modules/tracker/tracker.css b/modules/tracker/tracker.css
deleted file mode 100644
index d3531c4..0000000
--- a/modules/tracker/tracker.css
+++ /dev/null
@@ -1,7 +0,0 @@
-
-.page-tracker td.replies {
-  text-align: center;
-}
-.page-tracker table {
-  width: 100%;
-}
diff --git a/modules/tracker/tracker.info b/modules/tracker/tracker.info
deleted file mode 100644
index a765504..0000000
--- a/modules/tracker/tracker.info
+++ /dev/null
@@ -1,7 +0,0 @@
-name = Tracker
-description = Enables tracking of recent content for users.
-dependencies[] = comment
-package = Core
-version = VERSION
-core = 8.x
-files[] = tracker.test
diff --git a/modules/tracker/tracker.install b/modules/tracker/tracker.install
deleted file mode 100644
index cfe8dc7..0000000
--- a/modules/tracker/tracker.install
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-
-/**
- * Implements hook_uninstall().
- */
-function tracker_uninstall() {
-  variable_del('tracker_index_nid');
-  variable_del('tracker_batch_size');
-}
-
-/**
- * Implements hook_enable().
- */
-function tracker_enable() {
-  $max_nid = db_query('SELECT MAX(nid) FROM {node}')->fetchField();
-  if ($max_nid != 0) {
-    variable_set('tracker_index_nid', $max_nid);
-    // To avoid timing out while attempting to do a complete indexing, we
-    // simply call our cron job to remove stale records and begin the process.
-    tracker_cron();
-  }
-}
-
-/**
- * Implements hook_schema().
- */
-function tracker_schema() {
-  $schema['tracker_node'] = array(
-    'description' => 'Tracks when nodes were last changed or commented on.',
-    'fields' => array(
-      'nid' => array(
-        'description' => 'The {node}.nid this record tracks.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'published' => array(
-        'description' => 'Boolean indicating whether the node is published.',
-        'type' => 'int',
-        'not null' => FALSE,
-        'default' => 0,
-        'size' => 'tiny',
-      ),
-      'changed' => array(
-        'description' => 'The Unix timestamp when the node was most recently saved or commented on.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-    ),
-    'indexes' => array(
-      'tracker' => array('published', 'changed'),
-    ),
-    'primary key' => array('nid'),
-    'foreign keys' => array(
-      'tracked_node' => array(
-        'table' => 'node',
-        'columns' => array('nid' => 'nid'),
-      ),
-    ),
-  );
-
-  $schema['tracker_user'] = array(
-    'description' => 'Tracks when nodes were last changed or commented on, for each user that authored the node or one of its comments.',
-    'fields' => array(
-      'nid' => array(
-        'description' => 'The {node}.nid this record tracks.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'uid' => array(
-        'description' => 'The {users}.uid of the node author or commenter.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'published' => array(
-        'description' => 'Boolean indicating whether the node is published.',
-        'type' => 'int',
-        'not null' => FALSE,
-        'default' => 0,
-        'size' => 'tiny',
-      ),
-      'changed' => array(
-        'description' => 'The Unix timestamp when the node was most recently saved or commented on.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-    ),
-    'indexes' => array(
-      'tracker' => array('uid', 'published', 'changed'),
-    ),
-    'primary key' => array('nid', 'uid'),
-    'foreign keys' => array(
-      'tracked_node' => array(
-        'table' => 'node',
-        'columns' => array('nid' => 'nid'),
-      ),
-      'tracked_user' => array(
-        'table' => 'users',
-        'columns' => array('uid' => 'uid'),
-      ),
-    ),
-  );
-
-  return $schema;
-}
diff --git a/modules/tracker/tracker.module b/modules/tracker/tracker.module
deleted file mode 100644
index 227cf72..0000000
--- a/modules/tracker/tracker.module
+++ /dev/null
@@ -1,370 +0,0 @@
-<?php
-
-/**
- * @file
- * Enables tracking of recent content for users.
- */
-
-/**
- * Implements hook_help().
- */
-function tracker_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#tracker':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Tracker module displays the most recently added and updated content on your site, and allows you to follow new content created by each user. This module has no configuration options. For more information, see the online handbook entry for <a href="@tracker">Tracker module</a>.', array('@tracker' => 'http://drupal.org/handbook/modules/tracker/')) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Navigation') . '</dt>';
-      $output .= '<dd>' . t('The Tracker module adds a new menu item to the Navigation menu, called <em>Recent content</em>. You can configure menu items via the <a href="@menus">Menus administration page</a>.', array('@menus' => url('admin/structure/menu'))) . '</dd>';
-      $output .= '<dt>' . t('Tracking new and updated site content') . '</dt>';
-      $output .= '<dd>' . t("The <a href='@recent'>Recent content</a> page shows new and updated content in reverse chronological order, listing the content type, title, author's name, number of comments, and time of last update. Content is considered updated when changes occur in the text, or when new comments are added. The <em>My recent content</em> tab limits the list to the currently logged-in user.", array('@recent' => url('tracker'))) . '</dd>';
-      $output .= '<dt>' . t('Tracking user-specific content') . '</dt>';
-      $output .= '<dd>' . t("To follow a specific user's new and updated content, select the <em>Track</em> tab from the user's profile page.") . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_menu().
- */
-function tracker_menu() {
-  $items['tracker'] = array(
-    'title' => 'Recent content',
-    'page callback' => 'tracker_page',
-    'access arguments' => array('access content'),
-    'weight' => 1,
-    'file' => 'tracker.pages.inc',
-  );
-  $items['tracker/all'] = array(
-    'title' => 'All recent content',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-  );
-  $items['tracker/%user_uid_optional'] = array(
-    'title' => 'My recent content',
-    'page callback' => 'tracker_page',
-    'access callback' => '_tracker_myrecent_access',
-    'access arguments' => array(1),
-    'page arguments' => array(1),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'tracker.pages.inc',
-  );
-
-  $items['user/%user/track'] = array(
-    'title' => 'Track',
-    'page callback' => 'tracker_page',
-    'page arguments' => array(1, TRUE),
-    'access callback' => '_tracker_user_access',
-    'access arguments' => array(1),
-    'type' => MENU_LOCAL_TASK,
-    'file' => 'tracker.pages.inc',
-  );
-  $items['user/%user/track/content'] = array(
-    'title' => 'Track content',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-  );
-
-  return $items;
-}
-
-/**
- * Implements hook_cron().
- */
-function tracker_cron() {
-  $max_nid = variable_get('tracker_index_nid', 0);
-  $batch_size = variable_get('tracker_batch_size', 1000);
-  if ($max_nid > 0) {
-    $last_nid = FALSE;
-    $result = db_query_range('SELECT nid, uid, status FROM {node} WHERE nid <= :max_nid ORDER BY nid DESC', 0, $batch_size, array(':max_nid' => $max_nid), array('target' => 'slave'));
-
-    $count = 0;
-
-    foreach ($result as $row) {
-      // Calculate the changed timestamp for this node.
-      $changed = _tracker_calculate_changed($row->nid);
-
-      // Remove existing data for this node.
-      db_delete('tracker_node')
-        ->condition('nid', $row->nid)
-        ->execute();
-      db_delete('tracker_user')
-        ->condition('nid', $row->nid)
-        ->execute();
-
-      // Insert the node-level data.
-      db_insert('tracker_node')
-        ->fields(array(
-          'nid' => $row->nid,
-          'published' => $row->status,
-          'changed' => $changed,
-        ))
-        ->execute();
-
-      // Insert the user-level data for the node's author.
-      db_insert('tracker_user')
-        ->fields(array(
-          'nid' => $row->nid,
-          'published' => $row->status,
-          'changed' => $changed,
-          'uid' => $row->uid,
-        ))
-        ->execute();
-
-      $query = db_select('comment', 'c', array('target' => 'slave'));
-      // Force PostgreSQL to do an implicit cast by adding 0.
-      $query->addExpression('0 + :changed', 'changed', array(':changed' => $changed));
-      $query->addField('c', 'status', 'published');
-      $query
-        ->distinct()
-        ->fields('c', array('uid', 'nid'))
-        ->condition('c.nid', $row->nid)
-        ->condition('c.uid', $row->uid, '<>')
-        ->condition('c.status', COMMENT_PUBLISHED);
-
-      // Insert the user-level data for the commenters (except if a commenter
-      // is the node's author).
-      db_insert('tracker_user')
-        ->from($query)
-        ->execute();
-
-      // Note that we have indexed at least one node.
-      $last_nid = $row->nid;
-
-      $count++;
-    }
-
-    if ($last_nid !== FALSE) {
-      // Prepare a starting point for the next run.
-      variable_set('tracker_index_nid', $last_nid - 1);
-
-      watchdog('tracker', 'Indexed %count content items for tracking.', array('%count' => $count));
-    }
-    else {
-      // If all nodes have been indexed, set to zero to skip future cron runs.
-      variable_set('tracker_index_nid', 0);
-    }
-  }
-}
-
-/**
- * Access callback for tracker/%user_uid_optional.
- */
-function _tracker_myrecent_access($account) {
-  // This path is only allowed for authenticated users looking at their own content.
-  return $account->uid && ($GLOBALS['user']->uid == $account->uid) && user_access('access content');
-}
-
-/**
- * Access callback for user/%user/track.
- */
-function _tracker_user_access($account) {
-  return user_view_access($account) && user_access('access content');
-}
-
-/**
- * Implements hook_node_insert().
- */
-function tracker_node_insert($node, $arg = 0) {
-  _tracker_add($node->nid, $node->uid, $node->changed);
-}
-
-/**
- * Implements hook_node_update().
- */
-function tracker_node_update($node, $arg = 0) {
-  _tracker_add($node->nid, $node->uid, $node->changed);
-}
-
-/**
- * Implements hook_node_delete().
- */
-function tracker_node_delete($node, $arg = 0) {
-  db_delete('tracker_node')
-    ->condition('nid', $node->nid)
-    ->execute();
-  db_delete('tracker_user')
-    ->condition('nid', $node->nid)
-    ->execute();
-}
-
-/**
- * Implements hook_comment_update().
- *
- * Comment module doesn't call hook_comment_unpublish() when saving individual
- * comments so we need to check for those here.
- */
-function tracker_comment_update($comment) {
-  // comment_save() calls hook_comment_publish() for all published comments
-  // so we to handle all other values here.
-  if ($comment->status != COMMENT_PUBLISHED) {
-    _tracker_remove($comment->nid, $comment->uid, $comment->changed);
-  }
-}
-
-/**
- * Implements hook_comment_publish().
- *
- * This actually handles the insert and update of published nodes since
- * comment_save() calls hook_comment_publish() for all published comments.
- */
-function tracker_comment_publish($comment) {
-  _tracker_add($comment->nid, $comment->uid, $comment->changed);
-}
-
-/**
- * Implements hook_comment_unpublish().
- */
-function tracker_comment_unpublish($comment) {
-  _tracker_remove($comment->nid, $comment->uid, $comment->changed);
-}
-
-/**
- * Implements hook_comment_delete().
- */
-function tracker_comment_delete($comment) {
-  _tracker_remove($comment->nid, $comment->uid, $comment->changed);
-}
-
-/**
- * Update indexing tables when a node is added, updated or commented on.
- *
- * @param $nid
- *   A node ID.
- * @param $uid
- *   The node or comment author.
- * @param $changed
- *   The node updated timestamp or comment timestamp.
- */
-function _tracker_add($nid, $uid, $changed) {
-  $node = db_query('SELECT nid, status, uid, changed FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject();
-
-  // Adding a comment can only increase the changed timestamp, so our
-  // calculation here is simple.
-  $changed = max($node->changed, $changed);
-
-  // Update the node-level data.
-  db_merge('tracker_node')
-    ->key(array('nid' => $nid))
-    ->fields(array(
-      'changed' => $changed,
-      'published' => $node->status,
-    ))
-    ->execute();
-
-  // Create or update the user-level data.
-  db_merge('tracker_user')
-    ->key(array(
-      'nid' => $nid,
-      'uid' => $uid,
-    ))
-    ->fields(array(
-      'changed' => $changed,
-      'published' => $node->status,
-    ))
-    ->execute();
-}
-
-/**
- * Determine the max timestamp between $node->changed and the last comment.
- *
- * @param $nid
- *   A node ID.
- *
- * @return
- *  The $node->changed timestamp, or most recent comment timestamp, whichever
- *  is the greatest.
- */
-function _tracker_calculate_changed($nid) {
-  $changed = db_query('SELECT changed FROM {node} WHERE nid = :nid', array(':nid' => $nid), array('target' => 'slave'))->fetchField();
-  $latest_comment = db_query_range('SELECT cid, changed FROM {comment} WHERE nid = :nid AND status = :status ORDER BY changed DESC', 0, 1, array(
-    ':nid' => $nid,
-    ':status' => COMMENT_PUBLISHED,
-  ), array('target' => 'slave'))->fetchObject();
-  if ($latest_comment && $latest_comment->changed > $changed) {
-    $changed = $latest_comment->changed;
-  }
-  return $changed;
-}
-
-/**
- * Clean up indexed data when nodes or comments are removed.
- *
- * @param $nid
- *  The node ID.
- * @param $uid
- *   The author of the node or comment.
- * @param $changed
- *   The last changed timestamp of the node.
- */
-function _tracker_remove($nid, $uid = NULL, $changed = NULL) {
-  $node = db_query('SELECT nid, status, uid, changed FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject();
-
-  // The user only keeps his or her subscription if both of the following are true:
-  // (1) The node exists.
-  // (2) The user is either the node author or has commented on the node.
-  $keep_subscription = FALSE;
-
-  if ($node) {
-    // Self-authorship is one reason to keep the user's subscription.
-    $keep_subscription = ($node->uid == $uid);
-
-    // Comments are a second reason to keep the user's subscription.
-    if (!$keep_subscription) {
-      // Check if the user has commented at least once on the given nid
-      $keep_subscription = db_query_range('SELECT COUNT(*) FROM {comment} WHERE nid = :nid AND uid = :uid AND status = :status', 0, 1, array(
-        ':nid' => $nid,
-        ':uid' => $uid,
-        ':status' => COMMENT_PUBLISHED,
-      ))->fetchField();
-    }
-
-    // If we haven't found a reason to keep the user's subscription, delete it.
-    if (!$keep_subscription) {
-      db_delete('tracker_user')
-        ->condition('nid', $nid)
-        ->condition('uid', $uid)
-        ->execute();
-    }
-
-    // Now we need to update the (possibly) changed timestamps for other users
-    // and the node itself.
-
-    // We only need to do this if the removed item has a timestamp that equals
-    // or exceeds the listed changed timestamp for the node
-    $tracker_node = db_query('SELECT nid, changed FROM {tracker_node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject();
-    if ($tracker_node && $changed >= $tracker_node->changed) {
-      // If we're here, the item being removed is *possibly* the item that
-      // established the node's changed timestamp.
-
-      // We just have to recalculate things from scratch.
-      $changed = _tracker_calculate_changed($nid);
-
-      // And then we push the out the new changed timestamp to our denormalized
-      // tables.
-      db_update('tracker_node')
-        ->fields(array(
-          'changed' => $changed,
-          'published' => $node->status,
-        ))
-        ->condition('nid', $nid)
-        ->execute();
-      db_update('tracker_node')
-        ->fields(array(
-          'changed' => $changed,
-          'published' => $node->status,
-        ))
-        ->condition('nid', $nid)
-        ->execute();
-   }
-  }
-  else {
-    // If the node doesn't exist, remove everything.
-    db_delete('tracker_node')
-      ->condition('nid', $nid)
-      ->execute();
-    db_delete('tracker_user')
-      ->condition('nid', $nid)
-      ->execute();
-  }
-}
diff --git a/modules/tracker/tracker.pages.inc b/modules/tracker/tracker.pages.inc
deleted file mode 100644
index 7b1e946..0000000
--- a/modules/tracker/tracker.pages.inc
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-
-/**
- * @file
- * User page callbacks for the tracker module.
- */
-
-
-/**
- * Menu callback; prints a listing of active nodes on the site.
- */
-function tracker_page($account = NULL, $set_title = FALSE) {
-  if ($account) {
-    $query = db_select('tracker_user', 't')->extend('PagerDefault');
-    $query->condition('t.uid', $account->uid);
-
-    if ($set_title) {
-      // When viewed from user/%user/track, display the name of the user
-      // as page title -- the tab title remains Track so this needs to be done
-      // here and not in the menu definition.
-      drupal_set_title(format_username($account));
-    }
-  }
-  else {
-    $query = db_select('tracker_node', 't', array('target' => 'slave'))->extend('PagerDefault');
-  }
-
-  // This array acts as a placeholder for the data selected later
-  // while keeping the correct order.
-  $nodes = $query
-    ->addTag('node_access')
-    ->fields('t', array('nid', 'changed'))
-    ->condition('t.published', 1)
-    ->orderBy('t.changed', 'DESC')
-    ->limit(25)
-    ->execute()
-    ->fetchAllAssoc('nid');
-
-  $rows = array();
-  if (!empty($nodes)) {
-    // Now, get the data and put into the placeholder array
-    $result = db_query('SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.nid IN (:nids)', array(':nids' => array_keys($nodes)), array('target' => 'slave'));
-    foreach ($result as $node) {
-      $node->last_activity = $nodes[$node->nid]->changed;
-      $nodes[$node->nid] = $node;
-    }
-
-    // Finally display the data
-    foreach ($nodes as $node) {
-      // Determine the number of comments:
-      $comments = 0;
-      if ($node->comment_count) {
-        $comments = $node->comment_count;
-
-        if ($new = comment_num_new($node->nid)) {
-          $comments .= '<br />';
-          $comments .= l(format_plural($new, '1 new', '@count new'), 'node/'. $node->nid, array('fragment' => 'new'));
-        }
-      }
-
-      $row = array(
-        'type' => check_plain(node_type_get_name($node->type)),
-        'title' => array('data' => l($node->title, 'node/' . $node->nid) . ' ' . theme('mark', array('type' => node_mark($node->nid, $node->changed)))),
-        'author' => array('data' => theme('username', array('account' => $node))),
-        'replies' => array('class' => array('replies'), 'data' => $comments),
-        'last updated' => array('data' => t('!time ago', array('!time' => format_interval(REQUEST_TIME - $node->last_activity)))),
-      );
-
-      // Adds extra RDFa markup to the $row array if the RDF module is enabled.
-      if (function_exists('rdf_mapping_load')) {
-        // Each node is not loaded for performance reasons, as a result we need
-        // to retrieve the RDF mapping for each node type.
-        $mapping = rdf_mapping_load('node', $node->type);
-        // Adds RDFa markup to the title of the node. Because the RDFa markup is
-        // added to the td tag which might contain HTML code, we specify an
-        // empty datatype to ensure the value of the title read by the RDFa
-        // parsers is a plain literal.
-        $row['title'] += rdf_rdfa_attributes($mapping['title']) + array('datatype' => '');
-        // Annotates the td tag containing the author of the node.
-        $row['author'] += rdf_rdfa_attributes($mapping['uid']);
-        // Annotates the td tag containing the number of replies. We add the
-        // content attribute to ensure that only the comment count is used as
-        // the value for 'num_replies'. Otherwise, other text such as a link
-        // to the number of new comments could be included in the 'num_replies'
-        // value.
-        $row['replies'] += rdf_rdfa_attributes($mapping['comment_count']);
-        $row['replies'] += array('content' => $node->comment_count);
-        // If the node has no comments, we assume the node itself was modified
-        // and apply 'changed' in addition to 'last_activity'.  If there are
-        // comments present, we cannot infer whether the node itself was
-        // modified or a comment was posted, so we use only 'last_activity'.
-        $mapping_last_activity = rdf_rdfa_attributes($mapping['last_activity'], $node->last_activity);
-        if ($node->comment_count == 0) {
-          $mapping_changed = rdf_rdfa_attributes($mapping['changed'], $node->last_activity);
-          $mapping_last_activity['property'] = array_merge($mapping_last_activity['property'], $mapping_changed['property']);
-        }
-        $row['last updated'] += $mapping_last_activity;
-
-        // We need to add the about attribute on the tr tag to specify which
-        // node the RDFa annoatations above apply to. We move the content of
-        // $row to a 'data' sub array so we can specify attributes for the row.
-        $row = array('data' => $row);
-        $row['about'] = url('node/' . $node->nid);
-      }
-      $rows[] = $row;
-    }
-  }
-
-  $page['tracker'] = array(
-    '#rows' => $rows,
-    '#header' => array(t('Type'), t('Title'), t('Author'), t('Replies'), t('Last updated')),
-    '#theme' => 'table',
-    '#empty' => t('No content available.'),
-    '#attached' => array(
-      'css' => array(drupal_get_path('module', 'tracker') . '/tracker.css' => array()),
-    ),
-  );
-  $page['pager'] = array(
-    '#theme' => 'pager',
-    '#quantity' => 25,
-    '#weight' => 10,
-  );
-  $page['#sorted'] = TRUE;
-
-  return $page;
-}
diff --git a/modules/tracker/tracker.test b/modules/tracker/tracker.test
deleted file mode 100644
index 3cc227e..0000000
--- a/modules/tracker/tracker.test
+++ /dev/null
@@ -1,254 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests for tracker.module.
- */
-
-class TrackerTest extends DrupalWebTestCase {
-  protected $user;
-  protected $other_user;
-  protected $new_node;
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Tracker',
-      'description' => 'Create and delete nodes and check for their display in the tracker listings.',
-      'group' => 'Tracker'
-    );
-  }
-
-  function setUp() {
-    parent::setUp('comment', 'tracker');
-
-    $permissions = array('access comments', 'create page content', 'post comments', 'skip comment approval');
-    $this->user = $this->drupalCreateUser($permissions);
-    $this->other_user = $this->drupalCreateUser($permissions);
-
-    // Make node preview optional.
-    variable_set('comment_preview_page', 0);
-  }
-
-  /**
-   * Test the presence of nodes on the global tracker listing.
-   */
-  function testTrackerAll() {
-    $this->drupalLogin($this->user);
-
-    $unpublished = $this->drupalCreateNode(array(
-      'title' =>$this->randomName(8),
-      'status' => 0,
-    ));
-    $published = $this->drupalCreateNode(array(
-      'title' => $this->randomName(8),
-      'status' => 1,
-    ));
-
-    $this->drupalGet('tracker');
-    $this->assertNoText($unpublished->title, t('Unpublished node do not show up in the tracker listing.'));
-    $this->assertText($published->title, t('Published node show up in the tracker listing.'));
-    $this->assertLink(t('My recent content'), 0, t('User tab shows up on the global tracker page.'));
-
-    // Delete a node and ensure it no longer appears on the tracker.
-    node_delete($published->nid);
-    $this->drupalGet('tracker');
-    $this->assertNoText($published->title, t('Deleted node do not show up in the tracker listing.'));
-  }
-
-  /**
-   * Test the presence of nodes on a user's tracker listing.
-   */
-  function testTrackerUser() {
-    $this->drupalLogin($this->user);
-
-    $unpublished = $this->drupalCreateNode(array(
-      'title' => $this->randomName(8),
-      'uid' => $this->user->uid,
-      'status' => 0,
-    ));
-    $my_published = $this->drupalCreateNode(array(
-      'title' => $this->randomName(8),
-      'uid' => $this->user->uid,
-      'status' => 1,
-    ));
-    $other_published_no_comment = $this->drupalCreateNode(array(
-      'title' => $this->randomName(8),
-      'uid' => $this->other_user->uid,
-      'status' => 1,
-    ));
-    $other_published_my_comment = $this->drupalCreateNode(array(
-      'title' => $this->randomName(8),
-      'uid' => $this->other_user->uid,
-      'status' => 1,
-    ));
-    $comment = array(
-      'subject' => $this->randomName(),
-      'comment_body[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(20),
-    );
-    $this->drupalPost('comment/reply/' . $other_published_my_comment->nid, $comment, t('Save'));
-
-    $this->drupalGet('user/' . $this->user->uid . '/track');
-    $this->assertNoText($unpublished->title, t("Unpublished nodes do not show up in the users's tracker listing."));
-    $this->assertText($my_published->title, t("Published nodes show up in the user's tracker listing."));
-    $this->assertNoText($other_published_no_comment->title, t("Other user's nodes do not show up in the user's tracker listing."));
-    $this->assertText($other_published_my_comment->title, t("Nodes that the user has commented on appear in the user's tracker listing."));
-
-    // Verify that unpublished comments are removed from the tracker.
-    $admin_user = $this->drupalCreateUser(array('administer comments', 'access user profiles'));
-    $this->drupalLogin($admin_user);
-    $this->drupalPost('comment/1/edit', array('status' => COMMENT_NOT_PUBLISHED), t('Save'));
-    $this->drupalGet('user/' . $this->user->uid . '/track');
-    $this->assertNoText($other_published_my_comment->title, 'Unpublished comments are not counted on the tracker listing.');
-  }
-
-  /**
-   * Test the presence of the "new" flag for nodes.
-   */
-  function testTrackerNewNodes() {
-    $this->drupalLogin($this->user);
-
-    $edit = array(
-      'title' => $this->randomName(8),
-    );
-
-    $node = $this->drupalCreateNode($edit);
-    $title = $edit['title'];
-    $this->drupalGet('tracker');
-    $this->assertPattern('/' . $title . '.*new/', t('New nodes are flagged as such in the tracker listing.'));
-
-    $this->drupalGet('node/' . $node->nid);
-    $this->drupalGet('tracker');
-    $this->assertNoPattern('/' . $title . '.*new/', t('Visited nodes are not flagged as new.'));
-
-    $this->drupalLogin($this->other_user);
-    $this->drupalGet('tracker');
-    $this->assertPattern('/' . $title . '.*new/', t('For another user, new nodes are flagged as such in the tracker listing.'));
-
-    $this->drupalGet('node/' . $node->nid);
-    $this->drupalGet('tracker');
-    $this->assertNoPattern('/' . $title . '.*new/', t('For another user, visited nodes are not flagged as new.'));
-  }
-
-  /**
-   * Test comment counters on the tracker listing.
-   */
-  function testTrackerNewComments() {
-    $this->drupalLogin($this->user);
-
-    $node = $this->drupalCreateNode(array(
-      'comment' => 2,
-      'title' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(8)))),
-    ));
-
-    // Add a comment to the page.
-    $comment = array(
-      'subject' => $this->randomName(),
-      'comment_body[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(20),
-    );
-    $this->drupalPost('comment/reply/' . $node->nid, $comment, t('Save')); // The new comment is automatically viewed by the current user.
-
-    $this->drupalLogin($this->other_user);
-    $this->drupalGet('tracker');
-    $this->assertText('1 new', t('New comments are counted on the tracker listing pages.'));
-    $this->drupalGet('node/' . $node->nid);
-
-    // Add another comment as other_user.
-    $comment = array(
-      'subject' => $this->randomName(),
-      'comment_body[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(20),
-    );
-    // If the comment is posted in the same second as the last one then Drupal
-    // can't tell a difference, so wait one second here.
-    sleep(1);
-    $this->drupalPost('comment/reply/' . $node->nid, $comment, t('Save'));
-
-    $this->drupalLogin($this->user);
-    $this->drupalGet('tracker');
-    $this->assertText('1 new', t('New comments are counted on the tracker listing pages.'));
-  }
-
-  /**
-   * Test that existing nodes are indexed by cron.
-   */
-  function testTrackerCronIndexing() {
-    $this->drupalLogin($this->user);
-
-    // Create 3 nodes.
-    $edits = array();
-    $nodes = array();
-    for ($i = 1; $i <= 3; $i++) {
-      $edits[$i] = array(
-        'comment' => 2,
-        'title' => $this->randomName(),
-      );
-      $nodes[$i] = $this->drupalCreateNode($edits[$i]);
-    }
-
-    // Add a comment to the last node as other user.
-    $this->drupalLogin($this->other_user);
-    $comment = array(
-      'subject' => $this->randomName(),
-      'comment_body[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(20),
-    );
-    $this->drupalPost('comment/reply/' . $nodes[3]->nid, $comment, t('Save'));
-
-    // Start indexing backwards from node 3.
-    variable_set('tracker_index_nid', 3);
-
-    // Clear the current tracker tables and rebuild them.
-    db_delete('tracker_node')
-      ->execute();
-    db_delete('tracker_user')
-      ->execute();
-    tracker_cron();
-
-    $this->drupalLogin($this->user);
-
-    // Fetch the user's tracker.
-    $this->drupalGet('tracker/' . $this->user->uid);
-
-    // Assert that all node titles are displayed.
-    foreach ($nodes as $i => $node) {
-      $this->assertText($node->title, t('Node @i is displayed on the tracker listing pages.', array('@i' => $i)));
-    }
-    $this->assertText('1 new', t('New comment is counted on the tracker listing pages.'));
-    $this->assertText('updated', t('Node is listed as updated'));
-
-
-    // Fetch the site-wide tracker.
-    $this->drupalGet('tracker');
-
-    // Assert that all node titles are displayed.
-    foreach ($nodes as $i => $node) {
-      $this->assertText($node->title, t('Node @i is displayed on the tracker listing pages.', array('@i' => $i)));
-    }
-    $this->assertText('1 new', t('New comment is counted on the tracker listing pages.'));
-  }
-
-  /**
-   * Test that publish/unpublish works at admin/content/node
-   */
-  function testTrackerAdminUnpublish() {
-    $admin_user = $this->drupalCreateUser(array('access content overview', 'administer nodes', 'bypass node access'));
-    $this->drupalLogin($admin_user);
-
-    $node = $this->drupalCreateNode(array(
-      'comment' => 2,
-      'title' => $this->randomName(),
-    ));
-
-    // Assert that the node is displayed.
-    $this->drupalGet('tracker');
-    $this->assertText($node->title, t('Node is displayed on the tracker listing pages.'));
-
-    // Unpublish the node and ensure that it's no longer displayed.
-    $edit = array(
-      'operation' => 'unpublish',
-      'nodes[' . $node->nid . ']' => $node->nid,
-    );
-    $this->drupalPost('admin/content', $edit, t('Update'));
-
-    $this->drupalGet('tracker');
-    $this->assertText(t('No content available.'), t('Node is displayed on the tracker listing pages.'));
-  }
-}
diff --git a/profiles/standard/standard.info b/profiles/standard/standard.info
index e21c18c..5a80e98 100644
--- a/profiles/standard/standard.info
+++ b/profiles/standard/standard.info
@@ -4,10 +4,8 @@ version = VERSION
 core = 8.x
 dependencies[] = node
 dependencies[] = block
-dependencies[] = color
 dependencies[] = comment
 dependencies[] = contextual
-dependencies[] = dashboard
 dependencies[] = help
 dependencies[] = image
 dependencies[] = list
@@ -18,9 +16,6 @@ dependencies[] = path
 dependencies[] = taxonomy
 dependencies[] = dblog
 dependencies[] = search
-dependencies[] = shortcut
-dependencies[] = toolbar
-dependencies[] = overlay
 dependencies[] = field_ui
 dependencies[] = file
 dependencies[] = rdf
diff --git a/profiles/standard/standard.install b/profiles/standard/standard.install
index fa5383c..fece805 100644
--- a/profiles/standard/standard.install
+++ b/profiles/standard/standard.install
@@ -87,16 +87,6 @@ function standard_install() {
       'cache' => -1,
     ),
     array(
-      'module' => 'node',
-      'delta' => 'recent',
-      'theme' => $admin_theme,
-      'status' => 1,
-      'weight' => 10,
-      'region' => 'dashboard_main',
-      'pages' => '',
-      'cache' => -1,
-    ),
-    array(
       'module' => 'user',
       'delta' => 'login',
       'theme' => $default_theme,
@@ -166,26 +156,6 @@ function standard_install() {
       'pages' => '',
       'cache' => -1,
     ),
-    array(
-      'module' => 'user',
-      'delta' => 'new',
-      'theme' => $admin_theme,
-      'status' => 1,
-      'weight' => 0,
-      'region' => 'dashboard_sidebar',
-      'pages' => '',
-      'cache' => -1,
-    ),
-    array(
-      'module' => 'search',
-      'delta' => 'form',
-      'theme' => $admin_theme,
-      'status' => 1,
-      'weight' => -10,
-      'region' => 'dashboard_sidebar',
-      'pages' => '',
-      'cache' => -1,
-    ),
   );
   $query = db_insert('block')->fields(array('module', 'delta', 'theme', 'status', 'weight', 'region', 'pages', 'cache'));
   foreach ($values as $record) {
-- 
1.7.4.msysgit.0

