From 8c316779ad6c8b80f22eb92cf055ed45701fa90c Mon Sep 17 00:00:00 2001
From: Tim Steiner <tsteiner2@unl.edu>
Date: Tue, 19 Jul 2011 20:50:53 +0000
Subject: [PATCH] [gh-164] Merging from testing into staging

git-svn-id: file:///tmp/wdn_thm_drupal/branches/drupal-7.x/staging@862 20a16fea-79d4-4915-8869-1ea9d5ebf173
---
 CHANGELOG.txt                                 |  20 ++
 MAINTAINERS.txt                               |   1 +
 includes/batch.inc                            |  18 +-
 includes/bootstrap.inc                        |  15 +-
 includes/common.inc                           |  15 +-
 includes/database/database.inc                |  51 ++--
 includes/database/mysql/database.inc          |  52 ++++
 includes/database/select.inc                  |   2 +-
 includes/database/sqlite/database.inc         |  14 +-
 includes/entity.inc                           |  15 +-
 includes/errors.inc                           |   6 +-
 includes/file.inc                             |  22 +-
 includes/form.inc                             |  34 ++-
 includes/install.inc                          |   2 +-
 includes/locale.inc                           |   2 +-
 misc/machine-name.js                          |   5 +-
 modules/aggregator/aggregator.info            |   6 +-
 modules/aggregator/tests/aggregator_test.info |   6 +-
 modules/block/block.admin.inc                 | 112 ++++----
 modules/block/block.info                      |   6 +-
 modules/block/block.module                    |  10 +-
 modules/block/tests/block_test.info           |   6 +-
 modules/blog/blog.info                        |   6 +-
 modules/blog/blog.module                      |   4 +-
 modules/book/book.info                        |   6 +-
 modules/book/book.install                     |   4 +
 modules/color/color.info                      |   6 +-
 modules/color/color.install                   |   2 +-
 modules/color/color.module                    |   2 +-
 modules/color/color.test                      |  37 +++
 modules/comment/comment.css                   |   2 +-
 modules/comment/comment.info                  |   6 +-
 modules/comment/comment.install               |   1 +
 modules/comment/comment.module                |   5 +-
 modules/contact/contact.info                  |   6 +-
 modules/contextual/contextual.info            |   6 +-
 modules/dashboard/dashboard-rtl.css           |   2 -
 modules/dashboard/dashboard.info              |   6 +-
 modules/dblog/dblog.admin.inc                 |   2 +-
 modules/dblog/dblog.info                      |   6 +-
 modules/field/field.api.php                   |  14 +-
 modules/field/field.attach.inc                |  27 +-
 modules/field/field.crud.inc                  |   2 +-
 modules/field/field.info                      |   6 +-
 modules/field/field.info.inc                  |   8 +-
 modules/field/field.module                    |  22 +-
 modules/field/field.multilingual.inc          |   2 +-
 .../field_sql_storage/field_sql_storage.info  |   6 +-
 modules/field/modules/list/list.info          |   6 +-
 .../field/modules/list/tests/list_test.info   |   6 +-
 modules/field/modules/number/number.info      |   6 +-
 modules/field/modules/number/number.module    |  16 +-
 modules/field/modules/number/number.test      |  22 ++
 modules/field/modules/options/options.info    |   6 +-
 modules/field/modules/text/text.info          |   6 +-
 modules/field/tests/field.test                |   8 +-
 modules/field/tests/field_test.info           |   6 +-
 modules/field/tests/field_test.module         |   9 +-
 modules/field_ui/field_ui.info                |   6 +-
 modules/field_ui/field_ui.test                |  11 +-
 modules/file/file.info                        |   6 +-
 modules/file/tests/file_module_test.info      |   6 +-
 modules/filter/filter.info                    |   6 +-
 modules/forum/forum.info                      |   6 +-
 modules/help/help.info                        |   6 +-
 modules/image/image.api.php                   |   4 +-
 modules/image/image.field.inc                 |   6 +-
 modules/image/image.info                      |   6 +-
 modules/image/image.install                   |   2 +-
 modules/image/image.module                    |  52 ++++
 modules/image/image.test                      |  22 +-
 modules/image/tests/image_module_test.info    |   6 +-
 modules/locale/locale.admin.inc               |  12 +-
 modules/locale/locale.info                    |   6 +-
 modules/locale/tests/locale_test.info         |   6 +-
 modules/menu/menu.admin.inc                   |   2 +-
 modules/menu/menu.info                        |   6 +-
 modules/menu/menu.install                     |  43 +++
 modules/menu/menu.module                      |   3 +-
 modules/node/content_types.inc                |  18 +-
 modules/node/node.api.php                     |  14 +-
 modules/node/node.info                        |   6 +-
 modules/node/node.module                      |  60 +++-
 modules/node/node.test                        | 150 ++++++++++
 modules/node/tests/node_access_test.info      |   6 +-
 modules/node/tests/node_access_test.install   |  84 ++++++
 modules/node/tests/node_access_test.module    |  90 +++++-
 modules/node/tests/node_test.info             |   6 +-
 modules/node/tests/node_test_exception.info   |   6 +-
 modules/openid/openid.info                    |   6 +-
 modules/openid/tests/openid_test.info         |   6 +-
 modules/overlay/overlay-child.css             |   7 +
 modules/overlay/overlay.info                  |   6 +-
 modules/overlay/overlay.module                |   3 +
 modules/path/path.info                        |   6 +-
 modules/php/php.info                          |   6 +-
 modules/poll/poll.info                        |   6 +-
 modules/profile/profile.info                  |   6 +-
 modules/rdf/rdf.info                          |   6 +-
 modules/rdf/tests/rdf_test.info               |   6 +-
 modules/search/search-result.tpl.php          |   2 -
 modules/search/search.info                    |   6 +-
 .../search/tests/search_embedded_form.info    |   6 +-
 modules/search/tests/search_extra_type.info   |   6 +-
 modules/shortcut/shortcut.info                |   6 +-
 modules/shortcut/shortcut.install             |   1 +
 modules/simpletest/drupal_web_test_case.php   |   3 +-
 modules/simpletest/simpletest.info            |  10 +-
 modules/simpletest/simpletest.install         |   3 +-
 modules/simpletest/simpletest.module          |  14 +-
 modules/simpletest/simpletest.pages.inc       |  14 +-
 modules/simpletest/simpletest.test            |   6 +-
 .../simpletest/tests/actions_loop_test.info   |   6 +-
 modules/simpletest/tests/ajax_forms_test.info |   6 +-
 modules/simpletest/tests/ajax_test.info       |   6 +-
 modules/simpletest/tests/batch.test           |  13 +
 modules/simpletest/tests/batch_test.info      |   6 +-
 modules/simpletest/tests/common.test          |   7 +
 modules/simpletest/tests/common_test.info     |   6 +-
 modules/simpletest/tests/database_test.info   |   6 +-
 modules/simpletest/tests/database_test.test   |  65 ++++-
 ...drupal_system_listing_compatible_test.info |   6 +-
 ...upal_system_listing_incompatible_test.info |   6 +-
 .../simpletest/tests/entity_cache_test.info   |   6 +-
 .../tests/entity_cache_test_dependency.info   |   6 +-
 .../tests/entity_crud_hook_test.info          |   6 +-
 modules/simpletest/tests/error_test.info      |   6 +-
 modules/simpletest/tests/file_test.info       |   6 +-
 modules/simpletest/tests/filter_test.info     |   6 +-
 modules/simpletest/tests/form_test.info       |   6 +-
 modules/simpletest/tests/image_test.info      |   6 +-
 modules/simpletest/tests/menu_test.info       |   6 +-
 modules/simpletest/tests/module_test.info     |   6 +-
 .../simpletest/tests/requirements1_test.info  |   8 +-
 .../simpletest/tests/requirements2_test.info  |   8 +-
 modules/simpletest/tests/session_test.info    |   6 +-
 .../tests/system_dependencies_test.info       |   6 +-
 modules/simpletest/tests/system_test.info     |   6 +-
 modules/simpletest/tests/system_test.module   |  55 +++-
 modules/simpletest/tests/taxonomy_test.info   |   6 +-
 modules/simpletest/tests/theme.test           |   5 +
 modules/simpletest/tests/theme_test.info      |   6 +-
 modules/simpletest/tests/update_test_1.info   |   6 +-
 modules/simpletest/tests/update_test_2.info   |   6 +-
 modules/simpletest/tests/update_test_3.info   |   6 +-
 .../tests/upgrade/drupal-6.forum.database.php |   1 -
 .../tests/upgrade/drupal-6.menu.database.php  |  10 +
 ...upal-6.user-no-password-token.database.php |  10 +
 .../drupal-6.user-password-token.database.php |  10 +
 .../tests/upgrade/upgrade.forum.test          |   1 -
 .../tests/upgrade/upgrade.menu.test           |  44 +++
 .../tests/upgrade/upgrade.user.test           |  60 ++++
 modules/simpletest/tests/url_alter_test.info  |   6 +-
 modules/simpletest/tests/xmlrpc_test.info     |   6 +-
 modules/statistics/statistics.info            |   6 +-
 modules/syslog/syslog.info                    |   6 +-
 modules/system/system.api.php                 |  32 ++-
 modules/system/system.info                    |   6 +-
 modules/system/system.module                  |   1 +
 modules/system/system.test                    | 269 ++++++++++++++----
 modules/taxonomy/taxonomy.info                |   6 +-
 modules/taxonomy/taxonomy.install             |   5 +
 modules/taxonomy/taxonomy.module              |  32 ++-
 modules/taxonomy/taxonomy.test                |  34 +++
 modules/toolbar/toolbar.info                  |   6 +-
 modules/tracker/tracker.info                  |   6 +-
 .../translation/tests/translation_test.info   |   6 +-
 modules/translation/translation.info          |   6 +-
 modules/trigger/tests/trigger_test.info       |   6 +-
 modules/trigger/trigger.info                  |   6 +-
 modules/update/tests/aaa_update_test.info     |   6 +-
 modules/update/tests/bbb_update_test.info     |   6 +-
 modules/update/tests/ccc_update_test.info     |   6 +-
 modules/update/tests/update_test.info         |   6 +-
 modules/update/update.info                    |   6 +-
 modules/update/update.module                  |   1 +
 modules/update/update.test                    |  31 +-
 modules/user/tests/user_form_test.info        |   6 +-
 modules/user/user.info                        |   6 +-
 modules/user/user.install                     |  88 +++---
 modules/user/user.module                      |  29 +-
 profiles/minimal/minimal.info                 |   6 +-
 profiles/standard/standard.info               |   6 +-
 ...drupal_system_listing_compatible_test.info |   6 +-
 ...upal_system_listing_incompatible_test.info |   6 +-
 profiles/testing/testing.info                 |   6 +-
 robots.txt                                    |   2 +
 scripts/run-tests.sh                          |   2 +-
 themes/bartik/bartik.info                     |   6 +-
 themes/bartik/color/color.inc                 |  36 +--
 themes/bartik/css/style.css                   |   1 -
 themes/garland/garland.info                   |   6 +-
 themes/seven/seven.info                       |   6 +-
 themes/stark/stark.info                       |   6 +-
 themes/tests/test_theme/test_theme.info       |   6 +-
 .../update_test_basetheme.info                |   6 +-
 .../update_test_subtheme.info                 |   6 +-
 update.php                                    |   4 -
 198 files changed, 2012 insertions(+), 705 deletions(-)
 create mode 100644 modules/node/tests/node_access_test.install
 create mode 100644 modules/simpletest/tests/upgrade/drupal-6.menu.database.php
 create mode 100644 modules/simpletest/tests/upgrade/drupal-6.user-no-password-token.database.php
 create mode 100644 modules/simpletest/tests/upgrade/drupal-6.user-password-token.database.php
 create mode 100644 modules/simpletest/tests/upgrade/upgrade.menu.test
 create mode 100644 modules/simpletest/tests/upgrade/upgrade.user.test

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 131e1724..c859f028 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,4 +1,21 @@
 
+Drupal 7.4, 2011-06-29
+----------------------
+- Rolled back patch that caused fatal errors in CTools, Feeds, and other modules using the class registry.
+- Fixed critical bug with saving default images.
+- Fixed fatal errors when uninstalling some modules.
+- Added workaround for MySQL transaction support breaking on DDL statments.
+- Improved page caching with external caching systems.
+- Fix to Batch API, which was terminating too early.
+- Numerous upgrade path fixes.
+- Performance fixes.
+- Additional test coverage.
+- Numerous documentation fixes.
+
+Drupal 7.3, 2011-06-29
+----------------------
+- Fixed security issue (Access bypass), see SA-CORE-2011-002.
+
 Drupal 7.2, 2011-05-25
 ----------------------
 - Added a default .gitignore file.
@@ -236,6 +253,9 @@ Drupal 7.0, 2011-01-05
     * Added a locking framework to coordinate long-running operations across
       requests.
 
+Drupal 6.23-dev, xxxx-xx-xx (development release)
+-----------------------
+
 Drupal 6.22, 2011-05-25
 -----------------------
 - Made Drupal 6 work better with IIS and Internet Explorer.
diff --git a/MAINTAINERS.txt b/MAINTAINERS.txt
index 0af271d4..97f2d631 100644
--- a/MAINTAINERS.txt
+++ b/MAINTAINERS.txt
@@ -209,6 +209,7 @@ Node module
 - David Strauss 'David Strauss' <http://drupal.org/user/93254>
 
 OpenID module
+- Vojtech Kusy 'wojtha' <http://drupal.org/user/56154>
 - Heine Deelstra 'Heine' <http://drupal.org/user/17943>
 - Christian Schmidt 'c960657' <http://drupal.org/user/216078>
 - Damien Tournoud 'DamZ' <http://drupal.org/user/22211>
diff --git a/includes/batch.inc b/includes/batch.inc
index 7011abfb..727c6256 100644
--- a/includes/batch.inc
+++ b/includes/batch.inc
@@ -339,6 +339,8 @@ function _batch_process() {
       $progress_message = $old_set['progress_message'];
     }
 
+    // Total progress is the number of operations that have fully run plus the
+    // completion level of the current operation.
     $current    = $total - $remaining + $finished;
     $percentage = _batch_api_percentage($total, $current);
     $elapsed    = isset($current_set['elapsed']) ? $current_set['elapsed'] : 0;
@@ -373,7 +375,10 @@ function _batch_process() {
  * @param $total
  *   The total number of operations.
  * @param $current
- *   The number of the current operation.
+ *   The number of the current operation. This may be a floating point number
+ *   rather than an integer in the case of a multi-step operation that is not
+ *   yet complete; in that case, the fractional part of $current represents the
+ *   fraction of the operation that has been completed.
  * @return
  *   The properly formatted percentage, as a string. We output percentages
  *   using the correct number of decimal places so that we never print "100%"
@@ -390,7 +395,16 @@ function _batch_api_percentage($total, $current) {
     // We add a new digit at 200, 2000, etc. (since, for example, 199/200
     // would round up to 100% if we didn't).
     $decimal_places = max(0, floor(log10($total / 2.0)) - 1);
-    $percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
+    do {
+      // Calculate the percentage to the specified number of decimal places.
+      $percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
+      // When $current is an integer, the above calculation will always be
+      // correct. However, if $current is a floating point number (in the case
+      // of a multi-step batch operation that is not yet complete), $percentage
+      // may be erroneously rounded up to 100%. To prevent that, we add one
+      // more decimal place and try again.
+      $decimal_places++;
+    } while ($percentage == '100');
   }
   return $percentage;
 }
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index b0e5be83..bb07cca4 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
 /**
  * The current system version.
  */
-define('VERSION', '7.2');
+define('VERSION', '7.4');
 
 /**
  * Core API compatibility.
@@ -1128,13 +1128,12 @@ function drupal_serve_page_from_cache(stdClass $cache) {
     }
   }
 
-  // If a cache is served from a HTTP proxy without hitting the web server,
-  // the boot and exit hooks cannot be fired, so only allow caching in
-  // proxies if boot hooks are disabled. If the client send a session cookie,
-  // do not bother caching the page in a public proxy, because the cached copy
-  // will only be served to that particular user due to Vary: Cookie, unless
-  // the Vary header has been replaced or unset in hook_boot() (see below).
-  $max_age = !variable_get('page_cache_invoke_hooks', TRUE) && (!isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary'])) ? variable_get('page_cache_maximum_age', 0) : 0;
+  // If the client sent a session cookie, a cached copy will only be served
+  // to that one particular client due to Vary: Cookie. Thus, do not set
+  // max-age > 0, allowing the page to be cached by external proxies, when a
+  // session cookie is present unless the Vary header has been replaced or
+  // unset in hook_boot().
+  $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? variable_get('page_cache_maximum_age', 0) : 0;
   $default_headers['Cache-Control'] = 'public, max-age=' . $max_age;
 
   // Entity tag should change if the output changes.
diff --git a/includes/common.inc b/includes/common.inc
index 5158c5a9..a3c77ef9 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -752,7 +752,8 @@ function drupal_access_denied() {
  *     received.
  *   - redirect_code: If redirected, an integer containing the initial response
  *     status code.
- *   - redirect_url: If redirected, a string containing the redirection location.
+ *   - redirect_url: If redirected, a string containing the URL of the redirect
+ *     target.
  *   - error: If an error occurred, the error message. Otherwise not set.
  *   - headers: An array containing the response headers as name/value pairs.
  *     HTTP header names are case-insensitive (RFC 2616, section 4.2), so for
@@ -1008,7 +1009,9 @@ function drupal_http_request($url, array $options = array()) {
         $result = drupal_http_request($location, $options);
         $result->redirect_code = $code;
       }
-      $result->redirect_url = $location;
+      if (!isset($result->redirect_url)) {
+        $result->redirect_url = $location;
+      }
       break;
     default:
       $result->error = $status_message;
@@ -2825,6 +2828,8 @@ function drupal_add_html_head_link($attributes, $header = FALSE) {
  *
  * @return
  *   An array of queued cascading stylesheets.
+ *
+ * @see drupal_get_css()
  */
 function drupal_add_css($data = NULL, $options = NULL) {
   $css = &drupal_static(__FUNCTION__, array());
@@ -2905,8 +2910,11 @@ function drupal_add_css($data = NULL, $options = NULL) {
  *   (optional) If set to TRUE, this function skips calling drupal_alter() on
  *   $css, useful when the calling function passes a $css array that has already
  *   been altered.
+ *
  * @return
  *   A string of XHTML CSS tags.
+ *
+ * @see drupal_add_css()
  */
 function drupal_get_css($css = NULL, $skip_alter = FALSE) {
   if (!isset($css)) {
@@ -7434,7 +7442,8 @@ function entity_create_stub_entity($entity_type, $ids) {
  *   Whether to reset the internal cache for the requested entity type.
  *
  * @return
- *   An array of entity objects indexed by their ids.
+ *   An array of entity objects indexed by their ids. When no results are
+ *   found, an empty array is returned.
  *
  * @todo Remove $conditions in Drupal 8.
  */
diff --git a/includes/database/database.inc b/includes/database/database.inc
index 4cc1a33d..e08f9074 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -273,20 +273,25 @@ abstract class DatabaseConnection extends PDO {
   protected $schema = NULL;
 
   /**
-   * The default prefix used by this database connection.
+   * The prefixes used by this database connection.
    *
-   * Separated from the other prefixes for performance reasons.
+   * @var array
+   */
+  protected $prefixes = array();
+
+  /**
+   * List of search values for use in prefixTables().
    *
-   * @var string
+   * @var array
    */
-  protected $defaultPrefix = '';
+  protected $prefixSearch = array();
 
   /**
-   * The non-default prefixes used by this database connection.
+   * List of replacement values for use in prefixTables().
    *
    * @var array
    */
-  protected $prefixes = array();
+  protected $prefixReplace = array();
 
   function __construct($dsn, $username, $password, $driver_options = array()) {
     // Initialize and prepare the connection prefix.
@@ -375,7 +380,7 @@ abstract class DatabaseConnection extends PDO {
   }
 
   /**
-   * Preprocess the prefixes used by this database connection.
+   * Set the list of prefixes used by this database connection.
    *
    * @param $prefix
    *   The prefixes, in any of the multiple forms documented in
@@ -383,14 +388,27 @@ abstract class DatabaseConnection extends PDO {
    */
   protected function setPrefix($prefix) {
     if (is_array($prefix)) {
-      $this->defaultPrefix = isset($prefix['default']) ? $prefix['default'] : '';
-      unset($prefix['default']);
-      $this->prefixes = $prefix;
+      $this->prefixes = $prefix + array('default' => '');
     }
     else {
-      $this->defaultPrefix = $prefix;
-      $this->prefixes = array();
+      $this->prefixes = array('default' => $prefix);
     }
+
+    // Set up variables for use in prefixTables(). Replace table-specific
+    // prefixes first.
+    $this->prefixSearch = array();
+    $this->prefixReplace = array();
+    foreach ($this->prefixes as $key => $val) {
+      if ($key != 'default') {
+        $this->prefixSearch[] = '{' . $key . '}';
+        $this->prefixReplace[] = $val . $key;
+      }
+    }
+    // Then replace remaining tables with the default prefix.
+    $this->prefixSearch[] = '{';
+    $this->prefixReplace[] = $this->prefixes['default'];
+    $this->prefixSearch[] = '}';
+    $this->prefixReplace[] = '';
   }
 
   /**
@@ -408,12 +426,7 @@ abstract class DatabaseConnection extends PDO {
    *   The properly-prefixed string.
    */
   public function prefixTables($sql) {
-    // Replace specific table prefixes first.
-    foreach ($this->prefixes as $key => $val) {
-      $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
-    }
-    // Then replace remaining tables with the default prefix.
-    return strtr($sql, array('{' => $this->defaultPrefix , '}' => ''));
+    return str_replace($this->prefixSearch, $this->prefixReplace, $sql);
   }
 
   /**
@@ -427,7 +440,7 @@ abstract class DatabaseConnection extends PDO {
       return $this->prefixes[$table];
     }
     else {
-      return $this->defaultPrefix;
+      return $this->prefixes['default'];
     }
   }
 
diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc
index 262cc605..bc31feaa 100644
--- a/includes/database/mysql/database.inc
+++ b/includes/database/mysql/database.inc
@@ -133,6 +133,58 @@ class DatabaseConnection_mysql extends DatabaseConnection {
     catch (PDOException $e) {
     }
   }
+
+  /**
+   * Overridden to work around issues to MySQL not supporting transactional DDL.
+   */
+  public function popTransaction($name) {
+    if (!$this->supportsTransactions()) {
+      return;
+    }
+    if (!$this->inTransaction()) {
+      throw new DatabaseTransactionNoActiveException();
+    }
+
+    // Commit everything since SAVEPOINT $name.
+    while ($savepoint = array_pop($this->transactionLayers)) {
+      if ($savepoint != $name) {
+        continue;
+      }
+
+      // If there are no more layers left then we should commit.
+      if (empty($this->transactionLayers)) {
+        if (!PDO::commit()) {
+          throw new DatabaseTransactionCommitFailedException();
+        }
+      }
+      else {
+        // Attempt to release this savepoint in the standard way.
+        try {
+          $this->query('RELEASE SAVEPOINT ' . $name);
+        }
+        catch (PDOException $e) {
+          // However, in MySQL (InnoDB), savepoints are automatically committed
+          // when tables are altered or created (DDL transactions are not
+          // supported). This can cause exceptions due to trying to release
+          // savepoints which no longer exist.
+          //
+          // To avoid exceptions when no actual error has occurred, we silently
+          // succeed for PDOExceptions with SQLSTATE 42000 ("Syntax error or
+          // access rule violation") and MySQL error code 1305 ("SAVEPOINT does
+          // not exist").
+          if ($e->getCode() == '42000' && $e->errorInfo[1] == '1305') {
+            // If one SAVEPOINT was released automatically, then all were.
+            // Therefore, we keep just the topmost transaction.
+            $this->transactionLayers = array('drupal_transaction');
+          }
+          else {
+            throw $e;
+          }
+        }
+        break;
+      }
+    }
+  }
 }
 
 
diff --git a/includes/database/select.inc b/includes/database/select.inc
index 716c2fc3..53be20ad 100644
--- a/includes/database/select.inc
+++ b/includes/database/select.inc
@@ -414,7 +414,7 @@ interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableIn
    * @param $start
    *   The first record from the result set to return. If NULL, removes any
    *   range directives that are set.
-   * @param $limit
+   * @param $length
    *   The number of records to return from the result set.
    * @return SelectQueryInterface
    *   The called object.
diff --git a/includes/database/sqlite/database.inc b/includes/database/sqlite/database.inc
index cf3b9551..0fc0b552 100644
--- a/includes/database/sqlite/database.inc
+++ b/includes/database/sqlite/database.inc
@@ -71,12 +71,8 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
     ));
 
     // Attach one database for each registered prefix.
-    $prefixes = &$this->prefixes;
-    if (!empty($this->defaultPrefix)) {
-      // Add in the default prefix, which is also attached.
-      $prefixes[] = &$this->defaultPrefix;
-    }
-    foreach ($this->prefixes as $table => &$prefix) {
+    $prefixes = $this->prefixes;
+    foreach ($prefixes as $table => &$prefix) {
       // Empty prefix means query the main database -- no need to attach anything.
       if (!empty($prefix)) {
         // Only attach the database once.
@@ -90,6 +86,8 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
         $prefix .= '.';
       }
     }
+    // Regenerate the prefixes replacement table.
+    $this->setPrefix($prefixes);
 
     // Detect support for SAVEPOINT.
     $version = $this->query('SELECT sqlite_version()')->fetchField();
@@ -240,7 +238,9 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
     // Generate a new temporary table name and protect it from prefixing.
     // SQLite requires that temporary tables to be non-qualified.
     $tablename = $this->generateTemporaryTableName();
-    $this->prefixes[$tablename] = '';
+    $prefixes = $this->prefixes;
+    $prefixes[$tablename] = '';
+    $this->setPrefix($prefixes);
 
     $this->query(preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' . $tablename . ' AS SELECT', $query), $args, $options);
     return $tablename;
diff --git a/includes/entity.inc b/includes/entity.inc
index a3cdf741..9ee7889c 100644
--- a/includes/entity.inc
+++ b/includes/entity.inc
@@ -39,7 +39,8 @@ interface DrupalEntityControllerInterface {
    *   An array of conditions in the form 'field' => $value.
    *
    * @return
-   *   An array of entity objects indexed by their ids.
+   *   An array of entity objects indexed by their ids. When no results are
+   *   found, an empty array is returned.
    */
   public function load($ids = array(), $conditions = array());
 }
@@ -650,7 +651,11 @@ class EntityFieldQuery {
    */
   public function fieldCondition($field, $column = NULL, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL) {
     if (is_scalar($field)) {
-      $field = field_info_field($field);
+      $field_definition = field_info_field($field);
+      if (empty($field_definition)) {
+        throw new EntityFieldQueryException(t('Unknown field: @field_name', array('@field_name' => $field)));
+      }
+      $field = $field_definition;
     }
     // Ensure the same index is used for fieldConditions as for fields.
     $index = count($this->fields);
@@ -752,7 +757,11 @@ class EntityFieldQuery {
    */
   public function fieldOrderBy($field, $column, $direction = 'ASC') {
     if (is_scalar($field)) {
-      $field = field_info_field($field);
+      $field_definition = field_info_field($field);
+      if (empty($field_definition)) {
+        throw new EntityFieldQueryException(t('Unknown field: @field_name', array('@field_name' => $field)));
+      }
+      $field = $field_definition;
     }
     // Save the index used for the new field, for later use in field storage.
     $index = count($this->fields);
diff --git a/includes/errors.inc b/includes/errors.inc
index 3a97b6da..be724285 100644
--- a/includes/errors.inc
+++ b/includes/errors.inc
@@ -172,9 +172,9 @@ function error_displayable($error = NULL) {
  * Log a PHP error or exception, display an error page in fatal cases.
  *
  * @param $error
- *   An array with the following keys: %type, !message, %function, %file, %line.
- *   All the parameters are plain-text, exception message, which needs to be
- *   a safe HTML string.
+ *   An array with the following keys: %type, !message, %function, %file, %line
+ *   and severity_level. All the parameters are plain-text, with the exception of
+ *   !message, which needs to be a safe HTML string.
  * @param $fatal
  *   TRUE if the error is fatal.
  */
diff --git a/includes/file.inc b/includes/file.inc
index 6dc7f88b..73e75cd4 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -737,8 +737,7 @@ function file_usage_delete(stdClass $file, $module, $type = NULL, $id = NULL, $c
  *   A file object.
  * @param $destination
  *   A string containing the destination that $source should be copied to.
- *   This must be a stream wrapper URI. If this value is omitted, Drupal's
- *   default files scheme will be used, usually "public://".
+ *   This must be a stream wrapper URI.
  * @param $replace
  *   Replace behavior when the destination file already exists:
  *   - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with
@@ -967,8 +966,7 @@ function file_destination($destination, $replace) {
  *   A file object.
  * @param $destination
  *   A string containing the destination that $source should be moved to.
- *   This must be a stream wrapper URI. If this value is omitted, Drupal's
- *   default files scheme will be used, usually "public://".
+ *   This must be a stream wrapper URI.
  * @param $replace
  *   Replace behavior when the destination file already exists:
  *   - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with
@@ -1755,9 +1753,9 @@ function file_validate_image_resolution(stdClass $file, $maximum_dimensions = 0,
  * @param $data
  *   A string containing the contents of the file.
  * @param $destination
- *   A string containing the destination URI.
- *   This must be a stream wrapper URI. If this value is omitted, Drupal's
- *   default files scheme will be used, usually "public://".
+ *   A string containing the destination URI. This must be a stream wrapper URI.
+ *   If no value is provided, a randomized name will be generated and the file
+ *   will be saved using Drupal's default files scheme, usually "public://".
  * @param $replace
  *   Replace behavior when the destination file already exists:
  *   - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with
@@ -1823,10 +1821,9 @@ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAM
  * @param $data
  *   A string containing the contents of the file.
  * @param $destination
- *   A string containing the destination location.
- *   This must be a stream wrapper URI.  If no value is provided, a
- *   randomized name will be generated and the file is saved using Drupal's
- *   default files scheme, usually "public://".
+ *   A string containing the destination location. This must be a stream wrapper
+ *   URI. If no value is provided, a randomized name will be generated and the
+ *   file will be saved using Drupal's default files scheme, usually "public://".
  * @param $replace
  *   Replace behavior when the destination file already exists:
  *   - FILE_EXISTS_REPLACE - Replace the existing file.
@@ -2153,8 +2150,7 @@ function drupal_unlink($uri, $context = NULL) {
  * @see http://drupal.org/node/515192
  *
  * @param $uri
- *   A string containing the URI to verify. If this value is omitted,
- *   Drupal's public files directory will be used [public://].
+ *   A string containing the URI to verify.
  *
  * @return
  *   The absolute pathname, or FALSE on failure.
diff --git a/includes/form.inc b/includes/form.inc
index a337b03d..38ef41cf 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -104,8 +104,10 @@
  *   function via $form_state. This is commonly used for wizard-style
  *   multi-step forms, add-more buttons, and the like. For further information
  *   see drupal_build_form().
- * - 'redirect': a URL that will be used to redirect the form on submission.
- *   See drupal_redirect_form() for complete information.
+ * - 'redirect': $form_state['redirect'] is used to redirect the form on
+ *   submission. It may either be a string containing the destination URL, or
+ *   an array of arguments compatible with drupal_goto(). See
+ *   drupal_redirect_form() for complete information.
  * - 'storage': $form_state['storage'] is not a special key, and no specific
  *   support is provided for it in the Form API, but by tradition it was
  *   the location where application-specific data was stored for communication
@@ -1128,10 +1130,28 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
  * Redirects the user to a URL after a form has been processed.
  *
  * After a form was executed, the data in $form_state controls whether the form
- * is redirected. By default, we redirect to a new destination page. The path of
- * the destination page can be set in $form_state['redirect']. If that is not
- * set, the user is redirected to the current page to display a fresh,
- * unpopulated copy of the form.
+ * is redirected. By default, we redirect to a new destination page. The path
+ * of the destination page can be set in $form_state['redirect'], as either a
+ * string containing the destination or an array of arguments compatible with
+ * drupal_goto(). If that is not set, the user is redirected to the current
+ * page to display a fresh, unpopulated copy of the form.
+ *
+ * For example, to redirect to 'node':
+ * @code
+ * $form_state['redirect'] = 'node';
+ * @endcode
+ * Or to redirect to 'node/123?foo=bar#baz':
+ * @code
+ * $form_state['redirect'] = array(
+ *   'node/123',
+ *   array(
+ *     'query' => array(
+ *       'foo' => 'bar',
+ *     ),
+ *     'fragment' => 'baz',
+ *   ),
+ * );
+ * @endcode
  *
  * There are several triggers that may prevent a redirection though:
  * - If $form_state['redirect'] is FALSE, a form builder function or form
@@ -4074,6 +4094,8 @@ function _form_set_class(&$element, $class = array()) {
  * Sample 'finished' callback:
  * @code
  * function batch_test_finished($success, $results, $operations) {
+ *   // The 'success' parameter means no fatal PHP errors were detected. All
+ *   // other error management should be handled using 'results'.
  *   if ($success) {
  *     $message = format_plural(count($results), 'One post processed.', '@count posts processed.');
  *   }
diff --git a/includes/install.inc b/includes/install.inc
index d22f4f9c..089cdee8 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -570,7 +570,7 @@ abstract class DatabaseTasks {
 }
 
 /**
- * @class Exception class used to throw error if the DatabaseInstaller fails.
+ * Exception thrown if the database installer fails.
  */
 class DatabaseTaskException extends Exception {
 }
diff --git a/includes/locale.inc b/includes/locale.inc
index 578b1b3c..6154cf3c 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -1863,7 +1863,7 @@ function _locale_rebuild_js($langcode = NULL) {
 
   // Construct the array for JavaScript translations.
   // Only add strings with a translation to the translations array.
-  $result = db_query("SELECT s.lid, s.source, t.translation FROM {locales_source} s INNER JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.location LIKE '%.js%' AND s.textgroup = :textgroup AND t.translation IS NOT NULL", array(':language' => $language->language, ':textgroup' => 'default'));
+  $result = db_query("SELECT s.lid, s.source, t.translation FROM {locales_source} s INNER JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.location LIKE '%.js%' AND s.textgroup = :textgroup", array(':language' => $language->language, ':textgroup' => 'default'));
 
   $translations = array();
   foreach ($result as $data) {
diff --git a/misc/machine-name.js b/misc/machine-name.js
index 00a648a1..2691c3b7 100644
--- a/misc/machine-name.js
+++ b/misc/machine-name.js
@@ -35,6 +35,8 @@ Drupal.behaviors.machineName = {
       if ($target.hasClass('error')) {
         return;
       }
+      // Figure out the maximum length for the machine name.
+      options.maxlength = $target.attr('maxlength');
       // Hide the form item container of the machine name form element.
       $wrapper.hide();
       // Determine the initial machine name value. Unless the machine name form
@@ -103,13 +105,14 @@ Drupal.behaviors.machineName = {
    *     disallowed characters in the machine name; e.g., '[^a-z0-9]+'.
    *   - replace: A character to replace disallowed characters with; e.g., '_'
    *     or '-'.
+   *   - maxlength: The maximum length of the machine name.
    *
    * @return
    *   The transliterated source string.
    */
   transliterate: function (source, settings) {
     var rx = new RegExp(settings.replace_pattern, 'g');
-    return source.toLowerCase().replace(rx, settings.replace);
+    return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength);
   }
 };
 
diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info
index 667e77ce..c0063fe5 100644
--- a/modules/aggregator/aggregator.info
+++ b/modules/aggregator/aggregator.info
@@ -7,8 +7,8 @@ files[] = aggregator.test
 configure = admin/config/services/aggregator/settings
 stylesheets[all][] = aggregator.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/aggregator/tests/aggregator_test.info b/modules/aggregator/tests/aggregator_test.info
index 31fcf1d5..aab1b401 100644
--- a/modules/aggregator/tests/aggregator_test.info
+++ b/modules/aggregator/tests/aggregator_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/block/block.admin.inc b/modules/block/block.admin.inc
index 7cf299c0..c91cc80f 100644
--- a/modules/block/block.admin.inc
+++ b/modules/block/block.admin.inc
@@ -170,21 +170,27 @@ function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_r
  * @see block_admin_display_form()
  */
 function block_admin_display_form_submit($form, &$form_state) {
-  $txn = db_transaction();
-
-  foreach ($form_state['values']['blocks'] as $block) {
-    $block['status'] = (int) ($block['region'] != BLOCK_REGION_NONE);
-    $block['region'] = $block['status'] ? $block['region'] : '';
-    db_update('block')
-      ->fields(array(
-        'status' => $block['status'],
-        'weight' => $block['weight'],
-        'region' => $block['region'],
-      ))
-      ->condition('module', $block['module'])
-      ->condition('delta', $block['delta'])
-      ->condition('theme', $block['theme'])
-      ->execute();
+  $transaction = db_transaction();
+  try {
+    foreach ($form_state['values']['blocks'] as $block) {
+      $block['status'] = (int) ($block['region'] != BLOCK_REGION_NONE);
+      $block['region'] = $block['status'] ? $block['region'] : '';
+      db_update('block')
+        ->fields(array(
+          'status' => $block['status'],
+          'weight' => $block['weight'],
+          'region' => $block['region'],
+        ))
+        ->condition('module', $block['module'])
+        ->condition('delta', $block['delta'])
+        ->condition('theme', $block['theme'])
+        ->execute();
+    }
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    watchdog_exception('block', $e);
+    throw $e;
   }
   drupal_set_message(t('The block settings have been updated.'));
   cache_clear_all();
@@ -460,46 +466,52 @@ function block_admin_configure_validate($form, &$form_state) {
  */
 function block_admin_configure_submit($form, &$form_state) {
   if (!form_get_errors()) {
-    $txn = db_transaction();
-
-    db_update('block')
-      ->fields(array(
-        'visibility' => (int) $form_state['values']['visibility'],
-        'pages' => trim($form_state['values']['pages']),
-        'custom' => (int) $form_state['values']['custom'],
-        'title' => $form_state['values']['title'],
-      ))
-      ->condition('module', $form_state['values']['module'])
-      ->condition('delta', $form_state['values']['delta'])
-      ->execute();
-
-    db_delete('block_role')
-      ->condition('module', $form_state['values']['module'])
-      ->condition('delta', $form_state['values']['delta'])
-      ->execute();
-    $query = db_insert('block_role')->fields(array('rid', 'module', 'delta'));
-    foreach (array_filter($form_state['values']['roles']) as $rid) {
-      $query->values(array(
-        'rid' => $rid,
-        'module' => $form_state['values']['module'],
-        'delta' => $form_state['values']['delta'],
-      ));
-    }
-    $query->execute();
-
-    // Store regions per theme for this block
-    foreach ($form_state['values']['regions'] as $theme => $region) {
-      db_merge('block')
-        ->key(array('theme' => $theme, 'delta' => $form_state['values']['delta'], 'module' => $form_state['values']['module']))
+    $transaction = db_transaction();
+    try {
+      db_update('block')
         ->fields(array(
-          'region' => ($region == BLOCK_REGION_NONE ? '' : $region),
+          'visibility' => (int) $form_state['values']['visibility'],
           'pages' => trim($form_state['values']['pages']),
-          'status' => (int) ($region != BLOCK_REGION_NONE),
+          'custom' => (int) $form_state['values']['custom'],
+          'title' => $form_state['values']['title'],
         ))
+        ->condition('module', $form_state['values']['module'])
+        ->condition('delta', $form_state['values']['delta'])
         ->execute();
-    }
 
-    module_invoke($form_state['values']['module'], 'block_save', $form_state['values']['delta'], $form_state['values']);
+      db_delete('block_role')
+        ->condition('module', $form_state['values']['module'])
+        ->condition('delta', $form_state['values']['delta'])
+        ->execute();
+      $query = db_insert('block_role')->fields(array('rid', 'module', 'delta'));
+      foreach (array_filter($form_state['values']['roles']) as $rid) {
+        $query->values(array(
+          'rid' => $rid,
+          'module' => $form_state['values']['module'],
+          'delta' => $form_state['values']['delta'],
+        ));
+      }
+      $query->execute();
+
+      // Store regions per theme for this block
+      foreach ($form_state['values']['regions'] as $theme => $region) {
+        db_merge('block')
+          ->key(array('theme' => $theme, 'delta' => $form_state['values']['delta'], 'module' => $form_state['values']['module']))
+          ->fields(array(
+            'region' => ($region == BLOCK_REGION_NONE ? '' : $region),
+            'pages' => trim($form_state['values']['pages']),
+            'status' => (int) ($region != BLOCK_REGION_NONE),
+          ))
+          ->execute();
+      }
+
+      module_invoke($form_state['values']['module'], 'block_save', $form_state['values']['delta'], $form_state['values']);
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      watchdog_exception('block', $e);
+      throw $e;
+    }
     drupal_set_message(t('The block configuration has been saved.'));
     cache_clear_all();
     $form_state['redirect'] = 'admin/structure/block';
diff --git a/modules/block/block.info b/modules/block/block.info
index b891bf74..0c6c4ba6 100644
--- a/modules/block/block.info
+++ b/modules/block/block.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = block.test
 configure = admin/structure/block
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/block/block.module b/modules/block/block.module
index 73eba331..6b3b23af 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -633,14 +633,14 @@ function block_theme_initialize($theme) {
  *   The name of a region.
  *
  * @return
- *   An array of block objects, indexed with <i>module</i>_<i>delta</i>.
- *   If you are displaying your blocks in one or two sidebars, you may check
- *   whether this array is empty to see how many columns are going to be
- *   displayed.
+ *   An array of block objects, indexed with the module name and block delta
+ *   concatenated with an underscore, thus: MODULE_DELTA. If you are displaying
+ *   your blocks in one or two sidebars, you may check whether this array is
+ *   empty to see how many columns are going to be displayed.
  *
  * @todo
  *   Now that the blocks table has a primary key, we should use that as the
- *   array key instead of <i>module</i>_<i>delta</i>.
+ *   array key instead of MODULE_DELTA.
  */
 function block_list($region) {
   $blocks = &drupal_static(__FUNCTION__);
diff --git a/modules/block/tests/block_test.info b/modules/block/tests/block_test.info
index 6da4918f..87df447a 100644
--- a/modules/block/tests/block_test.info
+++ b/modules/block/tests/block_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/blog/blog.info b/modules/blog/blog.info
index 3b93b82e..c154b86e 100644
--- a/modules/blog/blog.info
+++ b/modules/blog/blog.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = blog.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/blog/blog.module b/modules/blog/blog.module
index 98ebe515..731bd2f6 100644
--- a/modules/blog/blog.module
+++ b/modules/blog/blog.module
@@ -26,6 +26,7 @@ function blog_user_view($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')),
     );
@@ -67,7 +68,7 @@ function blog_form($node, $form_state) {
  */
 function blog_view($node, $view_mode) {
   if ($view_mode == 'full' && node_is_page($node)) {
-    // Breadcrumb navigation.
+    // 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;
@@ -79,6 +80,7 @@ function blog_view($node, $view_mode) {
 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",
diff --git a/modules/book/book.info b/modules/book/book.info
index 6a7c8d5e..15ff031c 100644
--- a/modules/book/book.info
+++ b/modules/book/book.info
@@ -7,8 +7,8 @@ files[] = book.test
 configure = admin/content/book/settings
 stylesheets[all][] = book.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/book/book.install b/modules/book/book.install
index 1bd094c2..e92aca6e 100644
--- a/modules/book/book.install
+++ b/modules/book/book.install
@@ -17,6 +17,10 @@ function book_install() {
  * 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')
diff --git a/modules/color/color.info b/modules/color/color.info
index 1ac87285..ee2b2866 100644
--- a/modules/color/color.info
+++ b/modules/color/color.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = color.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/color/color.install b/modules/color/color.install
index b0eb95ef..2a6b9cdd 100644
--- a/modules/color/color.install
+++ b/modules/color/color.install
@@ -24,7 +24,7 @@ function color_requirements($phase) {
         $requirements['color_gd']['severity'] = REQUIREMENT_OK;
       }
       else {
-        $requirements['color_gd']['severity'] = REQUIREMENT_ERROR;
+        $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'));
       }
     }
diff --git a/modules/color/color.module b/modules/color/color.module
index f3fafe7b..fbc00f13 100644
--- a/modules/color/color.module
+++ b/modules/color/color.module
@@ -216,7 +216,7 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
     if (isset($names[$name])) {
       $form['palette'][$name] = array(
         '#type' => 'textfield',
-        '#title' => $names[$name],
+        '#title' => check_plain($names[$name]),
         '#default_value' => $value,
         '#size' => 8,
       );
diff --git a/modules/color/color.test b/modules/color/color.test
index 1ddfc064..0a8e78f4 100644
--- a/modules/color/color.test
+++ b/modules/color/color.test
@@ -11,6 +11,7 @@
 class ColorTestCase extends DrupalWebTestCase {
   protected $big_user;
   protected $themes;
+  protected $colorTests;
 
   public static function getInfo() {
     return array(
@@ -40,6 +41,19 @@ class ColorTestCase extends DrupalWebTestCase {
       ),
     );
     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,
+    );
   }
 
   /**
@@ -93,4 +107,27 @@ class ColorTestCase extends DrupalWebTestCase {
     $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('Main background must be a valid hexadecimal CSS color value.');
+      }
+    }
+  }
 }
diff --git a/modules/comment/comment.css b/modules/comment/comment.css
index 4a2675af..a55f527c 100644
--- a/modules/comment/comment.css
+++ b/modules/comment/comment.css
@@ -8,6 +8,6 @@
 .comment-unpublished {
   background-color: #fff4f4;
 }
-.preview .comment {
+.comment-preview {
   background-color: #ffffea;
 }
diff --git a/modules/comment/comment.info b/modules/comment/comment.info
index 85847e6f..c948e32d 100644
--- a/modules/comment/comment.info
+++ b/modules/comment/comment.info
@@ -9,8 +9,8 @@ files[] = comment.test
 configure = admin/content/comment
 stylesheets[all][] = comment.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/comment/comment.install b/modules/comment/comment.install
index d64b3acd..120467fd 100644
--- a/modules/comment/comment.install
+++ b/modules/comment/comment.install
@@ -16,6 +16,7 @@ function comment_uninstall() {
   variable_del('comment_block_count');
   $node_types = array_keys(node_type_get_types());
   foreach ($node_types as $node_type) {
+    field_attach_delete_bundle('comment', 'comment_node_' . $node_type);
     variable_del('comment_' . $node_type);
     variable_del('comment_anonymous_' . $node_type);
     variable_del('comment_controls_' . $node_type);
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index 4a737557..8d0c3d36 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -508,6 +508,9 @@ function comment_get_recent($number = 10) {
     ->condition('c.status', COMMENT_PUBLISHED)
     ->condition('n.status', NODE_PUBLISHED)
     ->orderBy('c.created', 'DESC')
+    // Additionally order by cid to ensure that comments with the same timestamp
+    // are returned in the exact order posted.
+    ->orderBy('c.cid', 'DESC')
     ->range(0, $number)
     ->execute()
     ->fetchAll();
@@ -1366,7 +1369,7 @@ function comment_node_search_result($node) {
     // Do not make a string if comments are closed and there are currently
     // zero comments.
     if ($node->comment != COMMENT_NODE_CLOSED || $comments > 0) {
-      return format_plural($comments, '1 comment', '@count comments');
+      return array('comment' => format_plural($comments, '1 comment', '@count comments'));
     }
   }
 }
diff --git a/modules/contact/contact.info b/modules/contact/contact.info
index 25cee494..9a10e285 100644
--- a/modules/contact/contact.info
+++ b/modules/contact/contact.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = contact.test
 configure = admin/structure/contact
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/contextual/contextual.info b/modules/contextual/contextual.info
index e279fd29..65066d79 100644
--- a/modules/contextual/contextual.info
+++ b/modules/contextual/contextual.info
@@ -4,8 +4,8 @@ package = Core
 version = VERSION
 core = 7.x
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/dashboard/dashboard-rtl.css b/modules/dashboard/dashboard-rtl.css
index 2ab53818..cfccfa03 100644
--- a/modules/dashboard/dashboard-rtl.css
+++ b/modules/dashboard/dashboard-rtl.css
@@ -1,5 +1,3 @@
-/* $Id */
-
 #dashboard div.dashboard-region {
   float: right;
 }
diff --git a/modules/dashboard/dashboard.info b/modules/dashboard/dashboard.info
index 3b12f527..b2d2c4d8 100644
--- a/modules/dashboard/dashboard.info
+++ b/modules/dashboard/dashboard.info
@@ -7,8 +7,8 @@ files[] = dashboard.test
 dependencies[] = block
 configure = admin/dashboard/customize
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/dblog/dblog.admin.inc b/modules/dblog/dblog.admin.inc
index 947100da..963e6f8e 100644
--- a/modules/dblog/dblog.admin.inc
+++ b/modules/dblog/dblog.admin.inc
@@ -59,7 +59,7 @@ function dblog_overview() {
         format_date($dblog->timestamp, 'short'),
         theme('dblog_message', array('event' => $dblog, 'link' => TRUE)),
         theme('username', array('account' => $dblog)),
-        $dblog->link,
+        filter_xss($dblog->link),
       ),
       // Attributes for tr
       'class' => array(drupal_html_class('dblog-' . $dblog->type), $classes[$dblog->severity]),
diff --git a/modules/dblog/dblog.info b/modules/dblog/dblog.info
index 85c90aee..f8c213d6 100644
--- a/modules/dblog/dblog.info
+++ b/modules/dblog/dblog.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = dblog.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/field.api.php b/modules/field/field.api.php
index 9c52d24e..ba44c735 100644
--- a/modules/field/field.api.php
+++ b/modules/field/field.api.php
@@ -256,8 +256,8 @@ function hook_field_schema($field) {
   }
   $columns += array(
     'format' => array(
-      'type' => 'int',
-      'unsigned' => TRUE,
+      'type' => 'varchar',
+      'length' => 255,
       'not null' => FALSE,
     ),
   );
@@ -2136,7 +2136,7 @@ function hook_field_info_max_weight($entity_type, $bundle, $context) {
  *   found in the 'display' key of $instance definitions.
  * @param $context
  *   An associative array containing:
- *   - entity_type: The entity type; e.g. 'node' or 'user'.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
  *   - field: The field being rendered.
  *   - instance: The instance being rendered.
  *   - entity: The entity being rendered.
@@ -2171,7 +2171,7 @@ function hook_field_display_alter(&$display, $context) {
  *   found in the 'display' key of $instance definitions.
  * @param $context
  *   An associative array containing:
- *   - entity_type: The entity type; e.g. 'node' or 'user'.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
  *   - field: The field being rendered.
  *   - instance: The instance being rendered.
  *   - entity: The entity being rendered.
@@ -2198,7 +2198,7 @@ function hook_field_display_ENTITY_TYPE_alter(&$display, $context) {
  *   by pseudo-field names.
  * @param $context
  *   An associative array containing:
- *   - entity_type: The entity type; e.g. 'node' or 'user'.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
  *   - bundle: The bundle name.
  *   - view_mode: The view mode, e.g. 'full', 'teaser'...
  */
@@ -2224,7 +2224,7 @@ function hook_field_extra_fields_display_alter(&$displays, $context) {
  *   The instance's widget properties.
  * @param $context
  *   An associative array containing:
- *   - entity_type: The entity type; e.g. 'node' or 'user'.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
  *   - entity: The entity object.
  *   - field: The field that the widget belongs to.
  *   - instance: The instance of the field.
@@ -2256,7 +2256,7 @@ function hook_field_widget_properties_alter(&$widget, $context) {
  *   The instance's widget properties.
  * @param $context
  *   An associative array containing:
- *   - entity_type: The entity type; e.g. 'node' or 'user'.
+ *   - entity_type: The entity type; e.g., 'node' or 'user'.
  *   - entity: The entity object.
  *   - field: The field that the widget belongs to.
  *   - instance: The instance of the field.
diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc
index 4ca15f54..2419201d 100644
--- a/modules/field/field.attach.inc
+++ b/modules/field/field.attach.inc
@@ -43,7 +43,7 @@ class FieldValidationException extends FieldException {
  * such as a cloud-based database.
  *
  * Each field defines which storage backend it uses. The Drupal system variable
- * 'field_default_storage' identifies the storage backend used by default.
+ * 'field_storage_default' identifies the storage backend used by default.
  */
 
 /**
@@ -303,9 +303,6 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b =
         if (!isset($fields[$field_id])) {
           $fields[$field_id] = $field;
         }
-        // Group the corresponding instances and entities.
-        $grouped_instances[$field_id][$id] = $instance;
-        $grouped_entities[$field_id][$id] = $entities[$id];
         // Extract the field values into a separate variable, easily accessed
         // by hook implementations.
         // Unless a language suggestion is provided we iterate on all the
@@ -315,6 +312,10 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b =
         $languages = _field_language_suggestion($available_languages, $language, $field_name);
         foreach ($languages as $langcode) {
           $grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
+          // Group the instances and entities corresponding to the current
+          // field.
+          $grouped_instances[$field_id][$langcode][$id] = $instance;
+          $grouped_entities[$field_id][$langcode][$id] = $entities[$id];
         }
       }
     }
@@ -327,8 +328,10 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b =
     $field_name = $field['field_name'];
     $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
     // Iterate over all the field translations.
-    foreach ($grouped_items[$field_id] as $langcode => $items) {
-      $results = $function($entity_type, $grouped_entities[$field_id], $field, $grouped_instances[$field_id], $langcode, $grouped_items[$field_id][$langcode], $a, $b);
+    foreach ($grouped_items[$field_id] as $langcode => &$items) {
+      $entities = $grouped_entities[$field_id][$langcode];
+      $instances = $grouped_instances[$field_id][$langcode];
+      $results = $function($entity_type, $entities, $field, $instances, $langcode, $items, $a, $b);
       if (isset($results)) {
         // Collect results by entity.
         // For hooks with array results, we merge results together.
@@ -346,9 +349,9 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b =
 
     // Populate field values back in the entities, but avoid replacing missing
     // fields with an empty array (those are not equivalent on update).
-    foreach ($grouped_entities[$field_id] as $id => $entity) {
-      foreach ($grouped_items[$field_id] as $langcode => $items) {
-        if (isset($grouped_items[$field_id][$langcode][$id]) && ($grouped_items[$field_id][$langcode][$id] !== array() || isset($entity->{$field_name}[$langcode]))) {
+    foreach ($grouped_entities[$field_id] as $langcode => $entities) {
+      foreach ($entities as $id => $entity) {
+        if ($grouped_items[$field_id][$langcode][$id] !== array() || isset($entity->{$field_name}[$langcode])) {
           $entity->{$field_name}[$langcode] = $grouped_items[$field_id][$langcode][$id];
         }
       }
@@ -1333,8 +1336,10 @@ function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
  *   The bundle to delete.
  */
 function field_attach_delete_bundle($entity_type, $bundle) {
-  // First, delete the instances themseves.
-  $instances = field_info_instances($entity_type, $bundle);
+  // First, delete the instances themselves. field_read_instances() must be
+  // used here since field_info_instances() does not return instances for
+  // disabled entity types or bundles.
+  $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle), array('include_inactive' => 1));
   foreach ($instances as $instance) {
     field_delete_instance($instance);
   }
diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc
index 339e9c4e..a6aaab12 100644
--- a/modules/field/field.crud.inc
+++ b/modules/field/field.crud.inc
@@ -38,7 +38,7 @@
  *   - settings: each omitted setting is given the default value defined in
  *     hook_field_info().
  *   - storage:
- *     - type: the storage backend specified in the 'field_default_storage'
+ *     - type: the storage backend specified in the 'field_storage_default'
  *       system variable.
  *     - settings: each omitted setting is given the default value specified in
  *       hook_field_storage_info().
diff --git a/modules/field/field.info b/modules/field/field.info
index 8a6f0a75..a0008888 100644
--- a/modules/field/field.info
+++ b/modules/field/field.info
@@ -10,8 +10,8 @@ dependencies[] = field_sql_storage
 required = TRUE
 stylesheets[all][] = theme/field.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/field.info.inc b/modules/field/field.info.inc
index 02707f6d..6b172dd3 100644
--- a/modules/field/field.info.inc
+++ b/modules/field/field.info.inc
@@ -458,7 +458,7 @@ function field_behaviors_widget($op, $instance) {
  * Returns information about field types from hook_field_info().
  *
  * @param $field_type
- *   (optional) A field type name. If ommitted, all field types will be
+ *   (optional) A field type name. If omitted, all field types will be
  *   returned.
  *
  * @return
@@ -482,7 +482,7 @@ function field_info_field_types($field_type = NULL) {
  * Returns information about field widgets from hook_field_widget_info().
  *
  * @param $widget_type
- *   (optional) A widget type name. If ommitted, all widget types will be
+ *   (optional) A widget type name. If omitted, all widget types will be
  *   returned.
  *
  * @return
@@ -507,7 +507,7 @@ function field_info_widget_types($widget_type = NULL) {
  * Returns information about field formatters from hook_field_formatter_info().
  *
  * @param $formatter_type
- *   (optional) A formatter type name. If ommitted, all formatter types will be
+ *   (optional) A formatter type name. If omitted, all formatter types will be
  *   returned.
  *
  * @return
@@ -532,7 +532,7 @@ function field_info_formatter_types($formatter_type = NULL) {
  * Returns information about field storage from hook_field_storage_info().
  *
  * @param $storage_type
- *   (optional) A storage type name. If ommitted, all storage types will be
+ *   (optional) A storage type name. If omitted, all storage types will be
  *   returned.
  *
  * @return
diff --git a/modules/field/field.module b/modules/field/field.module
index 9e03c8d9..af9e8c83 100644
--- a/modules/field/field.module
+++ b/modules/field/field.module
@@ -445,7 +445,7 @@ function field_associate_fields($module) {
  * Helper function to get the default value for a field on an entity.
  *
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $entity
  *   The entity for the operation.
  * @param $field
@@ -569,7 +569,7 @@ function _field_sort_items_value_helper($a, $b) {
  * @endcode
  *
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $bundle
  *   The bundle name.
  * @param $settings
@@ -674,7 +674,7 @@ function field_get_display($instance, $view_mode, $entity) {
  * Returns the display settings to use for pseudo-fields in a given view mode.
  *
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $bundle
  *   The bundle name.
  * @param $view_mode
@@ -773,7 +773,7 @@ function _field_filter_xss_display_allowed_tags() {
  * Returns a renderable array for a single field value.
  *
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $entity
  *   The entity containing the field to display. Must at least contain the id
  *   key and the field data to display.
@@ -825,12 +825,14 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
  *   render($content[FIELD_NAME]) instead.
  * - Do not use to display all fields in an entity, use
  *   field_attach_prepare_view() and field_attach_view() instead.
+ * - The field_view_value() function can be used to output a single formatted
+ *   field value, without label or wrapping field markup.
  *
  * The function takes care of invoking the prepare_view steps. It also respects
  * field access permissions.
  *
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $entity
  *   The entity containing the field to display. Must at least contain the id
  *   key and the field data to display.
@@ -864,6 +866,8 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
  *   used.
  * @return
  *   A renderable array for the field value.
+ *
+ * @see field_view_value()
  */
 function field_view_field($entity_type, $entity, $field_name, $display = array(), $langcode = NULL) {
   $output = array();
@@ -917,7 +921,7 @@ function field_view_field($entity_type, $entity, $field_name, $display = array()
  * Returns the field items in the language they currently would be displayed.
  *
  * @param $entity_type
- *   The type of $entity.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $entity
  *   The entity containing the data to be displayed.
  * @param $field_name
@@ -961,7 +965,7 @@ function field_has_data($field) {
  * @param $field
  *   The field on which the operation is to be performed.
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $entity
  *   (optional) The entity for the operation.
  * @param $account
@@ -991,7 +995,7 @@ function field_access($op, $field, $entity_type, $entity = NULL, $account = NULL
  * Helper function to extract the bundle name of from a bundle object.
  *
  * @param $entity_type
- *   The type of $entity; e.g. 'node' or 'user'.
+ *   The type of $entity; e.g., 'node' or 'user'.
  * @param $bundle
  *   The bundle object (or string if bundles for this entity type do not exist
  *   as standalone objects).
@@ -1136,7 +1140,7 @@ function template_process_field(&$variables, $hook) {
  *   - label_hidden: A boolean indicating to show or hide the field label.
  *   - title_attributes: A string containing the attributes for the title.
  *   - label: The label for the field.
- *   - content_attributes: A string containing the attaributes for the content's
+ *   - content_attributes: A string containing the attributes for the content's
  *     div.
  *   - items: An array of field items.
  *   - item_attributes: An array of attributes for each item.
diff --git a/modules/field/field.multilingual.inc b/modules/field/field.multilingual.inc
index 00adf927..5373d970 100644
--- a/modules/field/field.multilingual.inc
+++ b/modules/field/field.multilingual.inc
@@ -20,7 +20,7 @@
  * - For untranslatable fields this set only contains LANGUAGE_NONE.
  * - For translatable fields this set can contain any language code. By default
  *   it is the list returned by field_content_languages(), which contains all
- *   enabled languages with the addition of LANGUAGE_NONE. This default can be
+ *   installed languages with the addition of LANGUAGE_NONE. This default can be
  *   altered by modules implementing hook_field_available_languages_alter().
  *
  * The available languages for a particular field are returned by
diff --git a/modules/field/modules/field_sql_storage/field_sql_storage.info b/modules/field/modules/field_sql_storage/field_sql_storage.info
index 204bdb79..48e9c59c 100644
--- a/modules/field/modules/field_sql_storage/field_sql_storage.info
+++ b/modules/field/modules/field_sql_storage/field_sql_storage.info
@@ -7,8 +7,8 @@ dependencies[] = field
 files[] = field_sql_storage.test
 required = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/modules/list/list.info b/modules/field/modules/list/list.info
index 496e7670..6d3a1f71 100644
--- a/modules/field/modules/list/list.info
+++ b/modules/field/modules/list/list.info
@@ -7,8 +7,8 @@ dependencies[] = field
 dependencies[] = options
 files[] = tests/list.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/modules/list/tests/list_test.info b/modules/field/modules/list/tests/list_test.info
index 23cac1e1..69ab5276 100644
--- a/modules/field/modules/list/tests/list_test.info
+++ b/modules/field/modules/list/tests/list_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/modules/number/number.info b/modules/field/modules/number/number.info
index ca9e5fa8..608bcdaf 100644
--- a/modules/field/modules/number/number.info
+++ b/modules/field/modules/number/number.info
@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = number.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/modules/number/number.module b/modules/field/modules/number/number.module
index 20e38077..3c8132cb 100644
--- a/modules/field/modules/number/number.module
+++ b/modules/field/modules/number/number.module
@@ -379,9 +379,21 @@ function number_field_widget_validate($element, &$form_state) {
       form_error($element, $message);
     }
     else {
-      // Substitute the decimal separator,
       if ($type == 'decimal' || $type == 'float') {
-        $value = strtr($value, $field['settings']['decimal_separator'], '.');
+        // Verify that only one decimal separator exists in the field.
+        if (substr_count($value, $field['settings']['decimal_separator']) > 1) {
+          $message = t('%field: There should only be one decimal separator (@separator).',
+            array(
+              '%field' => t($instance['label']),
+              '@separator' => $field['settings']['decimal_separator'],
+            )
+          );
+          form_error($element, $message);
+        }
+        else {
+          // Substitute the decimal separator; things should be fine.
+          $value = strtr($value, $field['settings']['decimal_separator'], '.');
+        }
       }
       form_set_value($element, $value, $form_state);
     }
diff --git a/modules/field/modules/number/number.test b/modules/field/modules/number/number.test
index ec100f18..3b0cbafa 100644
--- a/modules/field/modules/number/number.test
+++ b/modules/field/modules/number/number.test
@@ -70,5 +70,27 @@ class NumberFieldTestCase extends DrupalWebTestCase {
     $id = $match[1];
     $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), t('Entity was created'));
     $this->assertRaw(round($value, 2), t('Value is displayed.'));
+
+    // Try to create entries with more than one decimal separator; assert fail.
+    $wrong_entries = array(
+      '3.14.159',
+      '0..45469',
+      '..4589',
+      '6.459.52',
+      '6.3..25',
+    );
+
+    foreach ($wrong_entries as $wrong_entry) {
+      $this->drupalGet('test-entity/add/test-bundle');
+      $edit = array(
+        "{$this->field['field_name']}[$langcode][0][value]" => $wrong_entry,
+      );
+      $this->drupalPost(NULL, $edit, t('Save'));
+      $this->assertText(
+        t('There should only be one decimal separator (@separator)',
+          array('@separator' => $this->field['settings']['decimal_separator'])),
+        t('Correctly failed to save decimal value with more than one decimal point.')
+      );
+    }
   }
 }
diff --git a/modules/field/modules/options/options.info b/modules/field/modules/options/options.info
index 02263f7c..84a8351e 100644
--- a/modules/field/modules/options/options.info
+++ b/modules/field/modules/options/options.info
@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = options.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/modules/text/text.info b/modules/field/modules/text/text.info
index 4c5e875d..518cf934 100644
--- a/modules/field/modules/text/text.info
+++ b/modules/field/modules/text/text.info
@@ -7,8 +7,8 @@ dependencies[] = field
 files[] = text.test
 required = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test
index 9281273f..ebb1c9f9 100644
--- a/modules/field/tests/field.test
+++ b/modules/field/tests/field.test
@@ -2681,6 +2681,9 @@ class FieldTranslationsTestCase extends FieldTestCase {
    * Test the multilanguage logic of _field_invoke().
    */
   function testFieldInvoke() {
+    // Enable field translations for the entity.
+    field_test_entity_info_translatable('test_entity', TRUE);
+
     $entity_type = 'test_entity';
     $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
 
@@ -2708,6 +2711,7 @@ class FieldTranslationsTestCase extends FieldTestCase {
       // forwarded to the callback function.
       $this->assertEqual($hash, $result, t('The result for %language is correctly stored.', array('%language' => $langcode)));
     }
+
     $this->assertEqual(count($results), count($available_languages), t('No unavailable language has been processed.'));
   }
 
@@ -2767,8 +2771,8 @@ class FieldTranslationsTestCase extends FieldTestCase {
       foreach ($results as $langcode => $result) {
         if (isset($values[$id][$langcode])) {
           $hash = hash('sha256', serialize(array($entity_type, $entities[$id], $this->field_name, $langcode, $values[$id][$langcode])));
-          // Check whether the parameters passed to _field_invoke() were correctly
-          // forwarded to the callback function.
+          // Check whether the parameters passed to _field_invoke_multiple()
+          // were correctly forwarded to the callback function.
           $this->assertEqual($hash, $result, t('The result for entity %id/%language is correctly stored.', array('%id' => $id, '%language' => $langcode)));
         }
       }
diff --git a/modules/field/tests/field_test.info b/modules/field/tests/field_test.info
index 3ff58850..dc1b41c9 100644
--- a/modules/field/tests/field_test.info
+++ b/modules/field/tests/field_test.info
@@ -6,8 +6,8 @@ files[] = field_test.entity.inc
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field/tests/field_test.module b/modules/field/tests/field_test.module
index 9e2fef62..7f43fbf0 100644
--- a/modules/field/tests/field_test.module
+++ b/modules/field/tests/field_test.module
@@ -88,9 +88,12 @@ function field_test_field_test_op($entity_type, $entity, $field, $instance, $lan
 function field_test_field_test_op_multiple($entity_type, $entities, $field, $instances, $langcode, &$items) {
   $result = array();
   foreach ($entities as $id => $entity) {
-    if (isset($items[$id])) {
-      $result[$id] = array($langcode => hash('sha256', serialize(array($entity_type, $entity, $field['field_name'], $langcode, $items[$id]))));
-    }
+    // Entities, instances and items are assumed to be consistently grouped by
+    // language. To verify this we try to access all the passed data structures
+    // by entity id. If they are grouped correctly, one entity, one instance and
+    // one array of items should be available for each entity id.
+    $field_name = $instances[$id]['field_name'];
+    $result[$id] = array($langcode => hash('sha256', serialize(array($entity_type, $entity, $field_name, $langcode, $items[$id]))));
   }
   return $result;
 }
diff --git a/modules/field_ui/field_ui.info b/modules/field_ui/field_ui.info
index b8b12900..e84d8eed 100644
--- a/modules/field_ui/field_ui.info
+++ b/modules/field_ui/field_ui.info
@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = field_ui.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/field_ui/field_ui.test b/modules/field_ui/field_ui.test
index 77f79ce3..5d2ff9bf 100644
--- a/modules/field_ui/field_ui.test
+++ b/modules/field_ui/field_ui.test
@@ -10,8 +10,15 @@
  */
 class FieldUITestCase extends DrupalWebTestCase {
 
-  function setUp($modules = array()) {
-    array_unshift($modules, 'field_test');
+  function setUp() {
+    // Since this is a base class for many test cases, support the same
+    // flexibility that DrupalWebTestCase::setUp() has for the modules to be
+    // passed in as either an array or a variable number of string arguments.
+    $modules = func_get_args();
+    if (isset($modules[0]) && is_array($modules[0])) {
+      $modules = $modules[0];
+    }
+    $modules[] = 'field_test';
     parent::setUp($modules);
 
     // Create test user.
diff --git a/modules/file/file.info b/modules/file/file.info
index ffb4c774..b3a1dc0b 100644
--- a/modules/file/file.info
+++ b/modules/file/file.info
@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 files[] = tests/file.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/file/tests/file_module_test.info b/modules/file/tests/file_module_test.info
index d49bd9a9..80b5d649 100644
--- a/modules/file/tests/file_module_test.info
+++ b/modules/file/tests/file_module_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/filter/filter.info b/modules/filter/filter.info
index e60046d4..049577c0 100644
--- a/modules/filter/filter.info
+++ b/modules/filter/filter.info
@@ -7,8 +7,8 @@ files[] = filter.test
 required = TRUE
 configure = admin/config/content/formats
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/forum/forum.info b/modules/forum/forum.info
index 6c62fa8f..00f5fce7 100644
--- a/modules/forum/forum.info
+++ b/modules/forum/forum.info
@@ -9,8 +9,8 @@ files[] = forum.test
 configure = admin/structure/forum
 stylesheets[all][] = forum.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/help/help.info b/modules/help/help.info
index 34fb192c..e944227e 100644
--- a/modules/help/help.info
+++ b/modules/help/help.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = help.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/image/image.api.php b/modules/image/image.api.php
index 5b635ec7..acb3f9c1 100644
--- a/modules/image/image.api.php
+++ b/modules/image/image.api.php
@@ -55,8 +55,8 @@ function hook_image_effect_info() {
  */
 function hook_image_effect_info_alter(&$effects) {
   // Override the Image module's crop effect with more options.
-  $effect['image_crop']['effect callback'] = 'mymodule_crop_effect';
-  $effect['image_crop']['form callback'] = 'mymodule_crop_form';
+  $effects['image_crop']['effect callback'] = 'mymodule_crop_effect';
+  $effects['image_crop']['form callback'] = 'mymodule_crop_form';
 }
 
 /**
diff --git a/modules/image/image.field.inc b/modules/image/image.field.inc
index 07cc1e06..43e118a7 100644
--- a/modules/image/image.field.inc
+++ b/modules/image/image.field.inc
@@ -51,16 +51,18 @@ function image_field_settings_form($field, $instance) {
     '#description' => t('Select where the final files should be stored. Private file storage has significantly more overhead than public files, but allows restricted access to files within this field.'),
   );
 
+  // When the user sets the scheme on the UI, even for the first time, it's
+  // updating a field because fields are created on the "Manage fields"
+  // page. So image_field_update_field() can handle this change.
   $form['default_image'] = array(
     '#title' => t('Default image'),
     '#type' => 'managed_file',
     '#description' => t('If no image is uploaded, this image will be shown on display.'),
     '#default_value' => $field['settings']['default_image'],
-    '#upload_location' => 'public://default_images/',
+    '#upload_location' => $settings['uri_scheme'] . '://default_images/',
   );
 
   return $form;
-
 }
 
 /**
diff --git a/modules/image/image.info b/modules/image/image.info
index 0f5afae8..401cd050 100644
--- a/modules/image/image.info
+++ b/modules/image/image.info
@@ -7,8 +7,8 @@ dependencies[] = file
 files[] = image.test
 configure = admin/config/media/image-styles
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/image/image.install b/modules/image/image.install
index fbd20de5..5f096cc2 100644
--- a/modules/image/image.install
+++ b/modules/image/image.install
@@ -264,7 +264,7 @@ function image_requirements($phase) {
         $requirements['image_gd']['severity'] = REQUIREMENT_OK;
       }
       else {
-        $requirements['image_gd']['severity'] = REQUIREMENT_ERROR;
+        $requirements['image_gd']['severity'] = REQUIREMENT_WARNING;
         $requirements['image_gd']['description'] = t('The GD Library for PHP is enabled, but was compiled without support for functions used by the rotate and desaturate effects. It was probably compiled using the official GD libraries from http://www.libgd.org instead of the GD library bundled with PHP. You should recompile PHP --with-gd using the bundled GD library. See <a href="http://www.php.net/manual/book.image.php">the PHP manual</a>.');
       }
     }
diff --git a/modules/image/image.module b/modules/image/image.module
index d2d081c3..008a3651 100644
--- a/modules/image/image.module
+++ b/modules/image/image.module
@@ -412,6 +412,58 @@ function image_image_style_delete($style) {
   image_image_style_save($style);
 }
 
+/**
+ * Implements hook_field_delete_field().
+ */
+function image_field_delete_field($field) {
+  if ($field['type'] != 'image') {
+    return;
+  }
+
+  // The value of a managed_file element can be an array if #extended == TRUE.
+  $fid = (is_array($field['settings']['default_image']) ? $field['settings']['default_image']['fid'] : $field['settings']['default_image']);
+  if ($fid && ($file = file_load($fid))) {
+    file_usage_delete($file, 'image', 'default_image', $field['id']);
+  }
+}
+
+/**
+ * Implements hook_field_update_field().
+ */
+function image_field_update_field($field, $prior_field, $has_data) {
+  if ($field['type'] != 'image') {
+    return;
+  }
+
+  // The value of a managed_file element can be an array if #extended == TRUE.
+  $fid_new = (is_array($field['settings']['default_image']) ? $field['settings']['default_image']['fid'] : $field['settings']['default_image']);
+  $fid_old = (is_array($prior_field['settings']['default_image']) ? $prior_field['settings']['default_image']['fid'] : $prior_field['settings']['default_image']);
+
+  $file_new = $fid_new ? file_load($fid_new) : FALSE;
+
+  if ($fid_new != $fid_old) {
+
+    // Is there a new file?
+    if ($file_new) {
+      $file_new->status = FILE_STATUS_PERMANENT;
+      file_save($file_new);
+      file_usage_add($file_new, 'image', 'default_image', $field['id']);
+    }
+
+    // Is there an old file?
+    if ($fid_old && ($file_old = file_load($fid_old))) {
+      file_usage_delete($file_old, 'image', 'default_image', $field['id']);
+    }
+  }
+
+  // If the upload destination changed, then move the file.
+  if ($file_new && (file_uri_scheme($file_new->uri) != $field['settings']['uri_scheme'])) {
+    $directory = $field['settings']['uri_scheme'] . '://default_images/';
+    file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
+    file_move($file_new, $directory . $file_new->filename);
+  }
+}
+
 /**
  * Clear cached versions of a specific file in all styles.
  *
diff --git a/modules/image/image.test b/modules/image/image.test
index 00f79d85..8596d668 100644
--- a/modules/image/image.test
+++ b/modules/image/image.test
@@ -796,7 +796,7 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
     // that would be used on the image field.
     $this->assertNoPattern('<div class="(.*?)field-name-' . strtr($field_name, '_', '-') . '(.*?)">', t('No image displayed when no image is attached and no default image specified.'));
 
-    // Add a default image to the imagefield instance.
+    // Add a default image to the public imagefield instance.
     $images = $this->drupalGetTestFiles('image');
     $edit = array(
       'files[field_settings_default_image]' => drupal_realpath($images[0]->uri),
@@ -806,6 +806,7 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
     field_info_cache_clear();
     $field = field_info_field($field_name);
     $image = file_load($field['settings']['default_image']);
+    $this->assertTrue($image->status == FILE_STATUS_PERMANENT, t('The default image status is permanent.'));
     $default_output = theme('image', array('path' => $image->uri));
     $this->drupalGet('node/' . $node->nid);
     $this->assertRaw($default_output, t('Default image displayed when no user supplied image is present.'));
@@ -831,6 +832,25 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
     field_info_cache_clear();
     $field = field_info_field($field_name);
     $this->assertFalse($field['settings']['default_image'], t('Default image removed from field.'));
+    // Create an image field that uses the private:// scheme and test that the
+    // default image works as expected.
+    $private_field_name = strtolower($this->randomName());
+    $this->createImageField($private_field_name, 'article', array('uri_scheme' => 'private'));
+    // Add a default image to the new field.
+    $edit = array(
+      'files[field_settings_default_image]' => drupal_realpath($images[1]->uri),
+    );
+    $this->drupalPost('admin/structure/types/manage/article/fields/' . $private_field_name, $edit, t('Save settings'));
+    $private_field = field_info_field($private_field_name);
+    $image = file_load($private_field['settings']['default_image']);
+    $this->assertEqual('private', file_uri_scheme($image->uri), t('Default image uses private:// scheme.'));
+    $this->assertTrue($image->status == FILE_STATUS_PERMANENT, t('The default image status is permanent.'));
+    // Create a new node with no image attached and ensure that default private
+    // image is displayed.
+    $node = $this->drupalCreateNode(array('type' => 'article'));
+    $default_output = theme('image', array('path' => $image->uri));
+    $this->drupalGet('node/' . $node->nid);
+    $this->assertRaw($default_output, t('Default private image displayed when no user supplied image is present.'));
   }
 }
 
diff --git a/modules/image/tests/image_module_test.info b/modules/image/tests/image_module_test.info
index bfbb1217..ffa11f00 100644
--- a/modules/image/tests/image_module_test.info
+++ b/modules/image/tests/image_module_test.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = image_module_test.module
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/locale/locale.admin.inc b/modules/locale/locale.admin.inc
index d8201dbf..01cee134 100644
--- a/modules/locale/locale.admin.inc
+++ b/modules/locale/locale.admin.inc
@@ -80,9 +80,19 @@ function theme_locale_languages_overview_form($variables) {
       if ($key == $default->language) {
         $form['enabled'][$key]['#attributes']['disabled'] = 'disabled';
       }
+
+      // Add invisible labels for the checkboxes and radio buttons in the table
+      // for accessibility. These changes are only required and valid when the
+      // form is themed as a table, so it would be wrong to perform them in the
+      // form constructor.
+      $title = drupal_render($form['name'][$key]);
+      $form['enabled'][$key]['#title'] = t('Enable !title', array('!title' => $title));
+      $form['enabled'][$key]['#title_display'] = 'invisible';
+      $form['site_default'][$key]['#title'] = t('Set !title as default', array('!title' => $title));
+      $form['site_default'][$key]['#title_display'] = 'invisible';
       $rows[] = array(
         'data' => array(
-          '<strong>' . drupal_render($form['name'][$key]) . '</strong>',
+          '<strong>' . $title . '</strong>',
           drupal_render($form['native'][$key]),
           check_plain($key),
           drupal_render($form['direction'][$key]),
diff --git a/modules/locale/locale.info b/modules/locale/locale.info
index 714eec63..7489d334 100644
--- a/modules/locale/locale.info
+++ b/modules/locale/locale.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = locale.test
 configure = admin/config/regional/language
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/locale/tests/locale_test.info b/modules/locale/tests/locale_test.info
index ca297f51..41b5cb99 100644
--- a/modules/locale/tests/locale_test.info
+++ b/modules/locale/tests/locale_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/menu/menu.admin.inc b/modules/menu/menu.admin.inc
index 1f3c4f72..7b5882c5 100644
--- a/modules/menu/menu.admin.inc
+++ b/modules/menu/menu.admin.inc
@@ -678,7 +678,7 @@ function menu_configure() {
     '#empty_option' => t('No Secondary links'),
     '#options' => $menu_options,
     '#tree' => FALSE,
-    '#description' => t('Select the source for the Secondary links. An advanced option allows you to use the same source for both Main links (currently %main) and Secondary links: if your source menu has two levels of hierarchy, the top level menu links will appear in the Main links, and the children of the active link will appear in the Secondary links.', array('%main' => $menu_options[$main])),
+    '#description' => t('Select the source for the Secondary links. An advanced option allows you to use the same source for both Main links (currently %main) and Secondary links: if your source menu has two levels of hierarchy, the top level menu links will appear in the Main links, and the children of the active link will appear in the Secondary links.', array('%main' => $main ? $menu_options[$main] : 'none')),
   );
 
   return system_settings_form($form);
diff --git a/modules/menu/menu.info b/modules/menu/menu.info
index c4b24654..4ab447a3 100644
--- a/modules/menu/menu.info
+++ b/modules/menu/menu.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = menu.test
 configure = admin/structure/menu
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/menu/menu.install b/modules/menu/menu.install
index 05aed283..717c5e71 100644
--- a/modules/menu/menu.install
+++ b/modules/menu/menu.install
@@ -69,3 +69,46 @@ function menu_uninstall() {
   menu_rebuild();
 }
 
+/**
+ * @defgroup updates-7.x-extra Extra updates for 7.x
+ * @{
+ */
+
+/**
+ * Migrate the "Default menu for content" setting to individual node types.
+ */
+function menu_update_7000() {
+  // Act only on sites originally on Drupal 6 that have a custom "Default menu
+  // for content" setting.
+  $default_node_menu = variable_get('menu_default_node_menu');
+  if (isset($default_node_menu)) {
+    // Remove variable no longer used in Drupal 7.
+    variable_del('menu_default_node_menu');
+
+    // Make sure the menu chosen as the default still exists.
+    $defined_menus = db_query('SELECT * FROM {menu_custom}')->fetchAllAssoc('menu_name', PDO::FETCH_ASSOC);
+    // If the menu does not exist, do nothing; nodes will use the default D7
+    // node menu settings.
+    if (!isset($defined_menus[$default_node_menu])) {
+      return;
+    }
+
+    // Update the menu settings for each node type.
+    foreach (_update_7000_node_get_types() as $type => $type_object) {
+      $type_menus = variable_get('menu_options_' . $type);
+      // If the site already has a custom menu setting for this node type (set
+      // on the initial upgrade to Drupal 7.0), don't override it.
+      if (!isset($type_menus)) {
+        // Set up this node type so that the Drupal 6 "Default menu for content"
+        // is still available in the "Menu settings" section.
+        variable_set('menu_options_' . $type, array($default_node_menu));
+        variable_set('menu_parent_' . $type, $default_node_menu . ':0');
+      }
+    }
+  }
+}
+
+/**
+ * @} End of "defgroup updates-7.x-extra"
+ * The next series of updates should start at 8000.
+ */
diff --git a/modules/menu/menu.module b/modules/menu/menu.module
index fc8f68a6..25407970 100644
--- a/modules/menu/menu.module
+++ b/modules/menu/menu.module
@@ -246,7 +246,8 @@ function menu_load_all() {
  *
  * @param $menu
  *   An array representing a custom menu:
- *   - menu_name: The unique name of the custom menu.
+ *   - menu_name: The unique name of the custom menu (composed of lowercase
+ *     letters, numbers, and hyphens).
  *   - title: The human readable menu title.
  *   - description: The custom menu description.
  *
diff --git a/modules/node/content_types.inc b/modules/node/content_types.inc
index 11ecc2c3..d58bc318 100644
--- a/modules/node/content_types.inc
+++ b/modules/node/content_types.inc
@@ -75,7 +75,15 @@ function theme_node_admin_overview($variables) {
 }
 
 /**
- * Generates the node type editing form.
+ * Form constructor for the node type editing form.
+ *
+ * @param $type
+ *   (optional) The machine name of the node type when editing an existing node
+ *   type.
+ *
+ * @see node_type_form_validate()
+ * @see node_type_form_submit()
+ * @ingroup forms
  */
 function node_type_form($form, &$form_state, $type = NULL) {
   if (!isset($type->type)) {
@@ -241,7 +249,9 @@ function _node_characters($length) {
 }
 
 /**
- * Validates the content type submission form generated by node_type_form().
+ * Form validation handler for node_type_form().
+ *
+ * @see node_type_form_submit()
  */
 function node_type_form_validate($form, &$form_state) {
   $type = new stdClass();
@@ -269,7 +279,9 @@ function node_type_form_validate($form, &$form_state) {
 }
 
 /**
- * Implements hook_form_submit().
+ * Form submission handler for node_type_form().
+ *
+ * @see node_type_form_validate()
  */
 function node_type_form_submit($form, &$form_state) {
   $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
diff --git a/modules/node/node.api.php b/modules/node/node.api.php
index 3e8029cf..90ffd8b7 100644
--- a/modules/node/node.api.php
+++ b/modules/node/node.api.php
@@ -642,14 +642,20 @@ function hook_node_prepare($node) {
  * @param $node
  *   The node being displayed in a search result.
  *
- * @return
- *   Extra information to be displayed with search result.
+ * @return array
+ *   Extra information to be displayed with search result. This information
+ *   should be presented as an associative array. It will be concatenated
+ *   with the post information (last updated, author) in the default search
+ *   result theming.
+ *
+ * @see template_preprocess_search_result()
+ * @see search-result.tpl.php
  *
  * @ingroup node_api_hooks
  */
 function hook_node_search_result($node) {
   $comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array('nid' => $node->nid))->fetchField();
-  return format_plural($comments, '1 comment', '@count comments');
+  return array('comment' => format_plural($comments, '1 comment', '@count comments'));
 }
 
 /**
@@ -758,7 +764,7 @@ function hook_node_validate($node, $form, &$form_state) {
  * properties.
  *
  * @param $node
- *   The node being updated in response to a form submission.
+ *   The node object being updated in response to a form submission.
  * @param $form
  *   The form being used to edit the node.
  * @param $form_state
diff --git a/modules/node/node.info b/modules/node/node.info
index d61ee3e6..c33a80eb 100644
--- a/modules/node/node.info
+++ b/modules/node/node.info
@@ -9,8 +9,8 @@ required = TRUE
 configure = admin/structure/types
 stylesheets[all][] = node.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/node/node.module b/modules/node/node.module
index 524a57fa..66e93c73 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1455,6 +1455,7 @@ function template_preprocess_node(&$variables) {
   $variables = array_merge((array) $node, $variables);
 
   // Helpful $content variable for templates.
+  $variables += array('content' => array());
   foreach (element_children($variables['elements']) as $key) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
@@ -3109,7 +3110,7 @@ function node_access_view_all_nodes($account = NULL) {
  * 'update' and 'delete').
  */
 function node_query_node_access_alter(QueryAlterableInterface $query) {
-  _node_query_node_access_alter($query, 'node', 'node');
+  _node_query_node_access_alter($query, 'node');
 }
 
 /**
@@ -3120,7 +3121,7 @@ function node_query_node_access_alter(QueryAlterableInterface $query) {
  * conditions are added for field values belonging to nodes only.
  */
 function node_query_entity_field_access_alter(QueryAlterableInterface $query) {
-  _node_query_node_access_alter($query, $query->getMetaData('base_table'), 'entity');
+  _node_query_node_access_alter($query, 'entity');
 }
 
 /**
@@ -3128,14 +3129,12 @@ function node_query_entity_field_access_alter(QueryAlterableInterface $query) {
  *
  * @param $query
  *   The query to add conditions to.
- * @param $base_table
- *   The table holding node ids.
  * @param $type
  *   Either 'node' or 'entity' depending on what sort of query it is. See
  *   node_query_node_access_alter() and node_query_entity_field_access_alter()
  *   for more.
  */
-function _node_query_node_access_alter($query, $base_table, $type) {
+function _node_query_node_access_alter($query, $type) {
   global $user;
 
   // Read meta-data from query, if provided.
@@ -3159,14 +3158,61 @@ function _node_query_node_access_alter($query, $base_table, $type) {
     return;
   }
 
+  $tables = $query->getTables();
+  $base_table = $query->getMetaData('base_table');
+  // If no base table is specified explicitly, search for one.
+  if (!$base_table) {
+    $fallback = '';
+    foreach ($tables as $alias => $table_info) {
+      if (!($table_info instanceof SelectQueryInterface)) {
+        $table = $table_info['table'];
+        // If the node table is in the query, it wins immediately.
+        if ($table == 'node') {
+          $base_table = $table;
+          break;
+        }
+        // Check whether the table has a foreign key to node.nid. If it does,
+        // do not run this check again as we found a base table and only node
+        // can triumph that.
+        if (!$base_table) {
+          // The schema is cached.
+          $schema = drupal_get_schema($table);
+          if (isset($schema['fields']['nid'])) {
+            if (isset($schema['foreign keys'])) {
+              foreach ($schema['foreign keys'] as $relation) {
+                if ($relation['table'] === 'node' && $relation['columns'] === array('nid' => 'nid')) {
+                  $base_table = $table;
+                }
+              }
+            }
+            else {
+              // At least it's a nid. A table with a field called nid is very
+              // very likely to be a node.nid in a node access query.
+              $fallback = $table;
+            }
+          }
+        }
+      }
+    }
+    // If there is nothing else, use the fallback.
+    if (!$base_table) {
+      if ($fallback) {
+        watchdog('security', 'Your node listing query is using @fallback as a base table in a query tagged for node access. This might not be secure and might not even work. Specify foreign keys in your schema to node.nid ', array('@fallback' => $fallback), WATCHDOG_WARNING);
+        $base_table = $fallback;
+      }
+      else {
+        throw new Exception(t('Query tagged for node access but there is no nid. Add foreign keys to node.nid in schema to fix.'));
+      }
+    }
+  }
+
   // Prevent duplicate records.
   $query->distinct();
 
-  // Find all instances of the {node} table being joined -- could appear
+  // Find all instances of the base table being joined -- could appear
   // more than once in the query, and could be aliased. Join each one to
   // the node_access table.
 
-  $tables = $query->getTables();
   $grants = node_access_grants($op, $account);
   if ($type == 'entity') {
     // The original query looked something like:
diff --git a/modules/node/node.test b/modules/node/node.test
index 8a871c0c..56a2d342 100644
--- a/modules/node/node.test
+++ b/modules/node/node.test
@@ -968,6 +968,156 @@ class NodeAccessRecordsUnitTest extends DrupalWebTestCase {
   }
 }
 
+/**
+ * Tests for Node Access with a non-node base table.
+ */
+class NodeAccessBaseTableTestCase extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Node Access on any table',
+      'description' => 'Checks behavior of the node access subsystem if the base table is not node.',
+      'group' => 'Node',
+    );
+  }
+
+  /**
+   * Enable modules and create user with specific permissions.
+   */
+  public function setUp() {
+    parent::setUp('node_access_test');
+    node_access_rebuild();
+    variable_set('node_access_test_private', TRUE);
+  }
+
+  /**
+   * Test the "private" node access.
+   *
+   * - Create 2 users with "access content" and "create article" permissions.
+   * - Each user creates one private and one not private article.
+
+   * - Test that each user can view the other user's non-private article.
+   * - Test that each user cannot view the other user's private article.
+   * - Test that each user finds only appropriate (non-private + own private)
+   *   in taxonomy listing.
+   * - Create another user with 'view any private content'.
+   * - Test that user 4 can view all content created above.
+   * - Test that user 4 can view all content on taxonomy listing.
+   */
+  function testNodeAccessBasic() {
+    $num_simple_users = 2;
+    $simple_users = array();
+
+    // nodes keyed by uid and nid: $nodes[$uid][$nid] = $is_private;
+    $this->nodesByUser = array();
+    $titles = array(); // Titles keyed by nid
+    $private_nodes = array(); // Array of nids marked private.
+    for ($i = 0; $i < $num_simple_users; $i++) {
+      $simple_users[$i] = $this->drupalCreateUser(array('access content', 'create article content'));
+    }
+    foreach ($simple_users as $this->webUser) {
+      $this->drupalLogin($this->webUser);
+      foreach (array(0 => 'Public', 1 => 'Private') as $is_private => $type) {
+        $edit = array(
+          'title' => t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $this->webUser->name)),
+        );
+        if ($is_private) {
+          $edit['private'] = TRUE;
+          $edit['body[und][0][value]'] = 'private node';
+          $edit['field_tags[und]'] = 'private';
+        }
+        else {
+          $edit['body[und][0][value]'] = 'public node';
+          $edit['field_tags[und]'] = 'public';
+        }
+
+        $this->drupalPost('node/add/article', $edit, t('Save'));
+        $nid = db_query('SELECT nid FROM {node} WHERE title = :title', array(':title' => $edit['title']))->fetchField();
+        $private_status = db_query('SELECT private FROM {node_access_test} where nid = :nid', array(':nid' => $nid))->fetchField();
+        $this->assertTrue($is_private == $private_status, t('The private status of the node was properly set in the node_access_test table.'));
+        if ($is_private) {
+          $private_nodes[] = $nid;
+        }
+        $titles[$nid] = $edit['title'];
+        $this->nodesByUser[$this->webUser->uid][$nid] = $is_private;
+      }
+    }
+    $this->publicTid = db_query('SELECT tid FROM {taxonomy_term_data} WHERE name = :name', array(':name' => 'public'))->fetchField();
+    $this->privateTid = db_query('SELECT tid FROM {taxonomy_term_data} WHERE name = :name', array(':name' => 'private'))->fetchField();
+    $this->assertTrue($this->publicTid, t('Public tid was found'));
+    $this->assertTrue($this->privateTid, t('Private tid was found'));
+    foreach ($simple_users as $this->webUser) {
+      $this->drupalLogin($this->webUser);
+      // Check own nodes to see that all are readable.
+      foreach ($this->nodesByUser as $uid => $data) {
+        foreach ($data as $nid => $is_private) {
+          $this->drupalGet('node/' . $nid);
+          if ($is_private) {
+            $should_be_visible = $uid == $this->webUser->uid;
+          }
+          else {
+            $should_be_visible = TRUE;
+          }
+          $this->assertResponse($should_be_visible ? 200 : 403, strtr('A %private node by user %uid is %visible for user %current_uid.', array(
+            '%private' => $is_private ? 'private' : 'public',
+            '%uid' => $uid,
+            '%visible' => $should_be_visible ? 'visible' : 'not visible',
+            '%current_uid' => $this->webUser->uid,
+          )));
+        }
+      }
+
+      // Check to see that the correct nodes are shown on taxonomy/private
+      // and taxonomy/public.
+      $this->assertTaxonomyPage(FALSE);
+    }
+
+    // Now test that a user with 'access any private content' can view content.
+    $access_user = $this->drupalCreateUser(array('access content', 'create article content', 'node test view', 'search content'));
+    $this->drupalLogin($access_user);
+
+    foreach ($this->nodesByUser as $uid => $private_status) {
+      foreach ($private_status as $nid => $is_private) {
+        $this->drupalGet('node/' . $nid);
+        $this->assertResponse(200);
+      }
+    }
+
+    // This user should be able to see all of the nodes on the relevant
+    // taxonomy pages.
+    $this->assertTaxonomyPage(TRUE);
+  }
+
+  protected function assertTaxonomyPage($super) {
+    foreach (array($this->publicTid, $this->privateTid) as $tid_is_private => $tid) {
+      $this->drupalGet("taxonomy/term/$tid");
+      $this->nids_visible = array();
+      foreach ($this->xpath("//a[text()='Read more']") as $link) {
+        $this->assertTrue(preg_match('|node/(\d+)$|', (string) $link['href'], $matches), 'Read more points to a node');
+        $this->nids_visible[$matches[1]] = TRUE;
+      }
+      foreach ($this->nodesByUser as $uid => $data) {
+        foreach ($data as $nid => $is_private) {
+          // Private nodes should be visible on the private term page,
+          // public nodes should be visible on the public term page.
+          $should_be_visible = $tid_is_private == $is_private;
+          // Non-superusers on the private page can only see their own nodes.
+          if (!$super && $tid_is_private) {
+            $should_be_visible = $should_be_visible && $uid == $this->webUser->uid;
+          }
+          $this->assertIdentical(isset($this->nids_visible[$nid]), $should_be_visible, strtr('A %private node by user %uid is %visible for user %current_uid on the %tid_is_private page.', array(
+            '%private' => $is_private ? 'private' : 'public',
+            '%uid' => $uid,
+            '%visible' => isset($this->nids_visible[$nid]) ? 'visible' : 'not visible',
+            '%current_uid' => $this->webUser->uid,
+            '%tid_is_private' => $tid_is_private ? 'private' : 'public',
+          )));
+        }
+      }
+    }
+  }
+}
+
 /**
  * Test case to check node save related functionality, including import-save
  */
diff --git a/modules/node/tests/node_access_test.info b/modules/node/tests/node_access_test.info
index ee2433c2..f8775200 100644
--- a/modules/node/tests/node_access_test.info
+++ b/modules/node/tests/node_access_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/node/tests/node_access_test.install b/modules/node/tests/node_access_test.install
new file mode 100644
index 00000000..3535ab19
--- /dev/null
+++ b/modules/node/tests/node_access_test.install
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for the node_access_test module.
+ */
+
+/**
+ * Implements hook_schema().
+ */
+function node_access_test_schema() {
+  $schema['node_access_test'] = array(
+    'description' => 'The base table for node_access_test.',
+    'fields' => array(
+      'nid' => array(
+        'description' => 'The {node}.nid this record affects.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'private' => array(
+        'description' => 'Boolean indicating whether the node is private (visible to administrator) or not (visible to non-administrators).',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'nid' => array('nid'),
+    ),
+    'primary key' => array('nid'),
+    'foreign keys' => array(
+      'versioned_node' => array(
+        'table' => 'node',
+        'columns' => array('nid' => 'nid'),
+      ),
+    ),
+  );
+
+  return $schema;
+}
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for the node_access_test module.
+ */
+
+/**
+ * Implements hook_schema().
+ */
+function node_access_test_schema() {
+  $schema['node_access_test'] = array(
+    'description' => 'The base table for node_access_test.',
+    'fields' => array(
+      'nid' => array(
+        'description' => 'The {node}.nid this record affects.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'private' => array(
+        'description' => 'Boolean indicating whether the node is private (visible to administrator) or not (visible to non-administrators).',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'nid' => array('nid'),
+    ),
+    'primary key' => array('nid'),
+    'foreign keys' => array(
+      'versioned_node' => array(
+        'table' => 'node',
+        'columns' => array('nid' => 'nid'),
+      ),
+    ),
+  );
+
+  return $schema;
+}
\ No newline at end of file
diff --git a/modules/node/tests/node_access_test.module b/modules/node/tests/node_access_test.module
index 3004e0c9..91c117a6 100644
--- a/modules/node/tests/node_access_test.module
+++ b/modules/node/tests/node_access_test.module
@@ -12,8 +12,10 @@
  */
 function node_access_test_node_grants($account, $op) {
   $grants = array();
+  // First grant a grant to the author for own content.
+  $grants['node_access_test_author'] = array($account->uid);
   if ($op == 'view' && user_access('node test view', $account)) {
-    $grants['node_access_test'] = array(888);
+    $grants['node_access_test'] = array(8888);
   }
   if ($op == 'view' && $account->uid == variable_get('node_test_node_access_all_uid', 0)) {
     $grants['node_access_all'] = array(0);
@@ -26,14 +28,27 @@ function node_access_test_node_grants($account, $op) {
  */
 function node_access_test_node_access_records($node) {
   $grants = array();
-  $grants[] = array(
-    'realm' => 'node_access_test',
-    'gid' => 888,
-    'grant_view' => 1,
-    'grant_update' => 0,
-    'grant_delete' => 0,
-    'priority' => 999,
+  // For NodeAccessBaseTableTestCase, only set records for private nodes.
+  if (!variable_get('node_access_test_private') || $node->private) {
+    $grants[] = array(
+      'realm' => 'node_access_test',
+      'gid' => 8888,
+      'grant_view' => 1,
+      'grant_update' => 0,
+      'grant_delete' => 0,
+      'priority' => 0,
     );
+    // For the author realm, the GID is equivalent to a UID, which
+    // means there are many many groups of just 1 user.
+    $grants[] = array(
+      'realm' => 'node_access_test_author',
+      'gid' => $node->uid,
+      'grant_view' => 1,
+      'grant_update' => 1,
+      'grant_delete' => 1,
+      'priority' => 0,
+    );
+  }
 
   return $grants;
 }
@@ -142,3 +157,62 @@ function node_access_entity_test_page() {
 
   return $output;
 }
+
+/**
+ * Implements hook_form_node_form_alter().
+ */
+function node_access_test_form_node_form_alter(&$form, $form_state) {
+  // Only show this checkbox for NodeAccessBaseTableTestCase.
+  if (variable_get('node_access_test_private')) {
+    $form['private'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Private'),
+      '#description' => t('Check here if this content should be set private and only shown to privileged users.'),
+      '#default_value' => isset($form['#node']->private) ? $form['#node']->private : FALSE,
+    );
+  }
+}
+
+/**
+ * Implements hook_node_load().
+ */
+function node_access_test_node_load($nodes, $types) {
+  $result = db_query('SELECT nid, private FROM {node_access_test} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)));
+  foreach ($result as $record) {
+    $nodes[$record->nid]->private = $record->private;
+  }
+}
+
+/**
+ * Implements hook_node_delete().
+ */
+
+function node_access_test_node_delete($node) {
+  db_delete('node_access_test')->condition('nid', $node->nid)->execute();
+}
+
+/**
+ * Implements hook_node_insert().
+ */
+function node_access_test_node_insert($node) {
+  _node_access_test_node_write($node);
+}
+
+/**
+ * Implements hook_nodeapi_update().
+ */
+function node_access_test_node_update($node) {
+  _node_access_test_node_write($node);
+}
+
+/**
+ * Helper for node insert/update.
+ */
+function _node_access_test_node_write($node) {
+  if (isset($node->private)) {
+    db_merge('node_access_test')
+      ->key(array('nid' => $node->nid))
+      ->fields(array('private' => (int) $node->private))
+      ->execute();
+  }
+}
diff --git a/modules/node/tests/node_test.info b/modules/node/tests/node_test.info
index 29640594..3ad84971 100644
--- a/modules/node/tests/node_test.info
+++ b/modules/node/tests/node_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/node/tests/node_test_exception.info b/modules/node/tests/node_test_exception.info
index 37d2af91..b30b64b9 100644
--- a/modules/node/tests/node_test_exception.info
+++ b/modules/node/tests/node_test_exception.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/openid/openid.info b/modules/openid/openid.info
index 69623671..8f7e176b 100644
--- a/modules/openid/openid.info
+++ b/modules/openid/openid.info
@@ -5,8 +5,8 @@ package = Core
 core = 7.x
 files[] = openid.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/openid/tests/openid_test.info b/modules/openid/tests/openid_test.info
index d9760b96..a40013ba 100644
--- a/modules/openid/tests/openid_test.info
+++ b/modules/openid/tests/openid_test.info
@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = openid
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/overlay/overlay-child.css b/modules/overlay/overlay-child.css
index 5a297cb4..a832fc8c 100644
--- a/modules/overlay/overlay-child.css
+++ b/modules/overlay/overlay-child.css
@@ -49,6 +49,13 @@ html.js body {
   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;
diff --git a/modules/overlay/overlay.info b/modules/overlay/overlay.info
index c4d05ba2..1688b0d4 100644
--- a/modules/overlay/overlay.info
+++ b/modules/overlay/overlay.info
@@ -4,8 +4,8 @@ package = Core
 version = VERSION
 core = 7.x
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/overlay/overlay.module b/modules/overlay/overlay.module
index 84b75548..44c230b6 100644
--- a/modules/overlay/overlay.module
+++ b/modules/overlay/overlay.module
@@ -832,11 +832,14 @@ function overlay_render_region($region) {
   // 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.
diff --git a/modules/path/path.info b/modules/path/path.info
index 29903db6..ab494d3e 100644
--- a/modules/path/path.info
+++ b/modules/path/path.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = path.test
 configure = admin/config/search/path
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/php/php.info b/modules/php/php.info
index 259e7432..162c5fbe 100644
--- a/modules/php/php.info
+++ b/modules/php/php.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = php.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/poll/poll.info b/modules/poll/poll.info
index 16744e8c..f53726e4 100644
--- a/modules/poll/poll.info
+++ b/modules/poll/poll.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = poll.test
 stylesheets[all][] = poll.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/profile/profile.info b/modules/profile/profile.info
index 6f89a05c..59c28cb8 100644
--- a/modules/profile/profile.info
+++ b/modules/profile/profile.info
@@ -11,8 +11,8 @@ configure = admin/config/people/profile
 ; See user_system_info_alter().
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/rdf/rdf.info b/modules/rdf/rdf.info
index 0617577d..029ff2ce 100644
--- a/modules/rdf/rdf.info
+++ b/modules/rdf/rdf.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = rdf.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/rdf/tests/rdf_test.info b/modules/rdf/tests/rdf_test.info
index 1ace4167..a0ff30ba 100644
--- a/modules/rdf/tests/rdf_test.info
+++ b/modules/rdf/tests/rdf_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/search/search-result.tpl.php b/modules/search/search-result.tpl.php
index 30b321fb..db9f2202 100644
--- a/modules/search/search-result.tpl.php
+++ b/modules/search/search-result.tpl.php
@@ -31,8 +31,6 @@
  * - $info_split['date']: Last update of the node. Short formatted.
  * - $info_split['comment']: Number of comments output as "% comments", %
  *   being the count. Depends on comment.module.
- * - $info_split['upload']: Number of attachments output as "% attachments", %
- *   being the count. Depends on upload.module.
  *
  * Other variables:
  * - $classes_array: Array of HTML class attribute values. It is flattened
diff --git a/modules/search/search.info b/modules/search/search.info
index 81947389..b0032763 100644
--- a/modules/search/search.info
+++ b/modules/search/search.info
@@ -8,8 +8,8 @@ files[] = search.test
 configure = admin/config/search/settings
 stylesheets[all][] = search.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/search/tests/search_embedded_form.info b/modules/search/tests/search_embedded_form.info
index be2af5b7..de81aaec 100644
--- a/modules/search/tests/search_embedded_form.info
+++ b/modules/search/tests/search_embedded_form.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/search/tests/search_extra_type.info b/modules/search/tests/search_extra_type.info
index 6ca086e0..32adacc9 100644
--- a/modules/search/tests/search_extra_type.info
+++ b/modules/search/tests/search_extra_type.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/shortcut/shortcut.info b/modules/shortcut/shortcut.info
index 2748c62f..39728aa3 100644
--- a/modules/shortcut/shortcut.info
+++ b/modules/shortcut/shortcut.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = shortcut.test
 configure = admin/config/user-interface/shortcut
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/shortcut/shortcut.install b/modules/shortcut/shortcut.install
index 209a9075..9dbab806 100644
--- a/modules/shortcut/shortcut.install
+++ b/modules/shortcut/shortcut.install
@@ -32,6 +32,7 @@ function shortcut_install() {
  * 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);
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index b60c6829..40af4585 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -1315,7 +1315,8 @@ class DrupalWebTestCase extends DrupalTestCase {
       $modules = $modules[0];
     }
     if ($modules) {
-      module_enable($modules, TRUE);
+      $success = module_enable($modules, TRUE);
+      $this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', $modules))));
     }
 
     // Run the profile tasks.
diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info
index 33088eaa..42257dc3 100644
--- a/modules/simpletest/simpletest.info
+++ b/modules/simpletest/simpletest.info
@@ -41,13 +41,15 @@ files[] = tests/upgrade/upgrade.test
 files[] = tests/upgrade/upgrade.comment.test
 files[] = tests/upgrade/upgrade.filter.test
 files[] = tests/upgrade/upgrade.forum.test
+files[] = tests/upgrade/upgrade.locale.test
+files[] = tests/upgrade/upgrade.menu.test
 files[] = tests/upgrade/upgrade.node.test
 files[] = tests/upgrade/upgrade.taxonomy.test
 files[] = tests/upgrade/upgrade.upload.test
-files[] = tests/upgrade/upgrade.locale.test
+files[] = tests/upgrade/upgrade.user.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/simpletest.install b/modules/simpletest/simpletest.install
index 0f017e75..ea847f4e 100644
--- a/modules/simpletest/simpletest.install
+++ b/modules/simpletest/simpletest.install
@@ -167,7 +167,8 @@ function simpletest_schema() {
  * Implements hook_uninstall().
  */
 function simpletest_uninstall() {
-  simpletest_clean_environment();
+  drupal_load('module', 'simpletest');
+  simpletest_clean_database();
 
   // Remove settings variables.
   variable_del('simpletest_httpauth_method');
diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module
index b992fd2a..586b23ae 100644
--- a/modules/simpletest/simpletest.module
+++ b/modules/simpletest/simpletest.module
@@ -452,13 +452,15 @@ function simpletest_clean_database() {
  * Find all leftover temporary directories and remove them.
  */
 function simpletest_clean_temporary_directories() {
-  $files = scandir('public://simpletest');
   $count = 0;
-  foreach ($files as $file) {
-    $path = 'public://simpletest/' . $file;
-    if (is_dir($path) && is_numeric($file)) {
-      file_unmanaged_delete_recursive($path);
-      $count++;
+  if (is_dir('public://simpletest')) {
+    $files = scandir('public://simpletest');
+    foreach ($files as $file) {
+      $path = 'public://simpletest/' . $file;
+      if (is_dir($path) && is_numeric($file)) {
+        file_unmanaged_delete_recursive($path);
+        $count++;
+      }
     }
   }
 
diff --git a/modules/simpletest/simpletest.pages.inc b/modules/simpletest/simpletest.pages.inc
index 31d0b2ce..a39e8b79 100644
--- a/modules/simpletest/simpletest.pages.inc
+++ b/modules/simpletest/simpletest.pages.inc
@@ -128,7 +128,7 @@ function theme_simpletest_test_table($variables) {
     );
 
     // Sorting $element by children's #title attribute instead of by class name.
-    uasort($element, '_simpletest_sort_by_title');
+    uasort($element, 'element_sort_by_title');
 
     // Cycle through each test within the current group.
     foreach (element_children($element) as $test_name) {
@@ -177,18 +177,6 @@ function theme_simpletest_test_table($variables) {
   }
 }
 
-/**
- * Sort element by title instead of by class name.
- */
-function _simpletest_sort_by_title($a, $b) {
-  // This is for parts of $element that are not an array.
-  if (!isset($a['#title']) || !isset($b['#title'])) {
-    return 1;
-  }
-
-  return strcasecmp($a['#title'], $b['#title']);
-}
-
 /**
  * Run selected tests.
  */
diff --git a/modules/simpletest/simpletest.test b/modules/simpletest/simpletest.test
index f5163642..e5b6042a 100644
--- a/modules/simpletest/simpletest.test
+++ b/modules/simpletest/simpletest.test
@@ -37,7 +37,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
       $this->drupalLogin($admin_user);
     }
     else {
-      parent::setUp();
+      parent::setUp('non_existent_module');
     }
   }
 
@@ -189,6 +189,8 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
    * Confirm that the stub test produced the desired results.
    */
   function confirmStubTestResults() {
+    $this->assertAssertion(t('Enabled modules: %modules', array('%modules' => 'non_existent_module')), 'Other', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->setUp()');
+
     $this->assertAssertion($this->pass, 'Other', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
     $this->assertAssertion($this->fail, 'Other', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
 
@@ -208,7 +210,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
 
     $this->assertAssertion("Debug: 'Foo'", 'Debug', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
 
-    $this->assertEqual('6 passes, 2 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct');
+    $this->assertEqual('6 passes, 5 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct');
 
     $this->test_ids[] = $test_id = $this->getTestIdFromResults();
     $this->assertTrue($test_id, t('Found test ID in results.'));
diff --git a/modules/simpletest/tests/actions_loop_test.info b/modules/simpletest/tests/actions_loop_test.info
index 3eccda36..701d0a20 100644
--- a/modules/simpletest/tests/actions_loop_test.info
+++ b/modules/simpletest/tests/actions_loop_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/ajax_forms_test.info b/modules/simpletest/tests/ajax_forms_test.info
index 580f2723..a2190461 100644
--- a/modules/simpletest/tests/ajax_forms_test.info
+++ b/modules/simpletest/tests/ajax_forms_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/ajax_test.info b/modules/simpletest/tests/ajax_test.info
index daa84cec..5cddb491 100644
--- a/modules/simpletest/tests/ajax_test.info
+++ b/modules/simpletest/tests/ajax_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/batch.test b/modules/simpletest/tests/batch.test
index d1c0e0b2..f668e522 100644
--- a/modules/simpletest/tests/batch.test
+++ b/modules/simpletest/tests/batch.test
@@ -365,6 +365,19 @@ class BatchPercentagesUnitTestCase extends DrupalUnitTestCase {
       '99.95' => array('total' => 2000, 'current' => 1999),
       // 19999/20000 should add yet another digit and go to 99.995%.
       '99.995' => array('total' => 20000, 'current' => 19999),
+      // The next five test cases simulate a batch with a single operation
+      // ('total' equals 1) that takes several steps to complete. Within the
+      // operation, we imagine that there are 501 items to process, and 100 are
+      // completed during each step. The percentages we get back should be
+      // rounded the usual way for the first few passes (i.e., 20%, 40%, etc.),
+      // but for the last pass through, when 500 out of 501 items have been
+      // processed, we do not want to round up to 100%, since that would
+      // erroneously indicate that the processing is complete.
+      '20' => array('total' => 1, 'current' => 100/501),
+      '40' => array('total' => 1, 'current' => 200/501),
+      '60' => array('total' => 1, 'current' => 300/501),
+      '80' => array('total' => 1, 'current' => 400/501),
+      '99.8' => array('total' => 1, 'current' => 500/501),
     );
     require_once DRUPAL_ROOT . '/includes/batch.inc';
     parent::setUp();
diff --git a/modules/simpletest/tests/batch_test.info b/modules/simpletest/tests/batch_test.info
index d8ec56d7..602a4fd3 100644
--- a/modules/simpletest/tests/batch_test.info
+++ b/modules/simpletest/tests/batch_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index d618ddb0..177e4573 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -1000,6 +1000,13 @@ class DrupalHTTPRequestTestCase extends DrupalWebTestCase {
 
     $redirect_307 = drupal_http_request(url('system-test/redirect/307', array('absolute' => TRUE)), array('max_redirects' => 0));
     $this->assertFalse(isset($redirect_307->redirect_code), t('drupal_http_request does not follow 307 redirect if max_redirects = 0.'));
+
+    $multiple_redirect_final_url = url('system-test/multiple-redirects/0', array('absolute' => TRUE));
+    $multiple_redirect_1 = drupal_http_request(url('system-test/multiple-redirects/1', array('absolute' => TRUE)), array('max_redirects' => 1));
+    $this->assertEqual($multiple_redirect_1->redirect_url, $multiple_redirect_final_url, t('redirect_url contains the final redirection location after 1 redirect.'));
+
+    $multiple_redirect_3 = drupal_http_request(url('system-test/multiple-redirects/3', array('absolute' => TRUE)), array('max_redirects' => 3));
+    $this->assertEqual($multiple_redirect_3->redirect_url, $multiple_redirect_final_url, t('redirect_url contains the final redirection location after 3 redirects.'));
   }
 }
 
diff --git a/modules/simpletest/tests/common_test.info b/modules/simpletest/tests/common_test.info
index 4e07d820..97ec552d 100644
--- a/modules/simpletest/tests/common_test.info
+++ b/modules/simpletest/tests/common_test.info
@@ -7,8 +7,8 @@ stylesheets[all][] = common_test.css
 stylesheets[print][] = common_test.print.css
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/database_test.info b/modules/simpletest/tests/database_test.info
index 660f1a05..7893409d 100644
--- a/modules/simpletest/tests/database_test.info
+++ b/modules/simpletest/tests/database_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index c22d1fc5..143640d6 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -3251,8 +3251,10 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
    *   Suffix to add to field values to differentiate tests.
    * @param $rollback
    *   Whether or not to try rolling back the transaction when we're done.
+   * @param $ddl_statement
+   *   Whether to execute a DDL statement during the inner transaction.
    */
-  protected function transactionOuterLayer($suffix, $rollback = FALSE) {
+  protected function transactionOuterLayer($suffix, $rollback = FALSE, $ddl_statement = FALSE) {
     $connection = Database::getConnection();
     $depth = $connection->transactionDepth();
     $txn = db_transaction();
@@ -3269,7 +3271,7 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
 
     // We're already in a transaction, but we call ->transactionInnerLayer
     // to nest another transaction inside the current one.
-    $this->transactionInnerLayer($suffix, $rollback);
+    $this->transactionInnerLayer($suffix, $rollback, $ddl_statement);
 
     $this->assertTrue($connection->inTransaction(), t('In transaction after calling nested transaction.'));
 
@@ -3289,12 +3291,12 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
    *   Suffix to add to field values to differentiate tests.
    * @param $rollback
    *   Whether or not to try rolling back the transaction when we're done.
+   * @param $ddl_statement
+   *   Whether to execute a DDL statement during the transaction.
    */
-  protected function transactionInnerLayer($suffix, $rollback = FALSE) {
+  protected function transactionInnerLayer($suffix, $rollback = FALSE, $ddl_statement = FALSE) {
     $connection = Database::getConnection();
 
-    $this->assertTrue($connection->inTransaction(), t('In transaction in nested transaction.'));
-
     $depth = $connection->transactionDepth();
     // Start a transaction. If we're being called from ->transactionOuterLayer,
     // then we're already in a transaction. Normally, that would make starting
@@ -3315,6 +3317,22 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
 
     $this->assertTrue($connection->inTransaction(), t('In transaction inside nested transaction.'));
 
+    if ($ddl_statement) {
+      $table = array(
+        'fields' => array(
+          'id' => array(
+            'type' => 'serial',
+            'unsigned' => TRUE,
+            'not null' => TRUE,
+          ),
+        ),
+        'primary key' => array('id'),
+      );
+      db_create_table('database_test_1', $table);
+
+      $this->assertTrue($connection->inTransaction(), t('In transaction inside nested transaction.'));
+    }
+
     if ($rollback) {
       // Roll back the transaction, if requested.
       // This rollback should propagate to the last savepoint.
@@ -3396,6 +3414,43 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
       $this->fail($e->getMessage());
     }
   }
+
+  /**
+   * Test the compatibility of transactions with DDL statements.
+   */
+  function testTransactionWithDdlStatement() {
+    // First, test that a commit works normally, even with DDL statements.
+    try {
+      $this->transactionOuterLayer('D', FALSE, TRUE);
+
+      // Because we committed, the inserted rows should both be present.
+      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidD'))->fetchField();
+      $this->assertIdentical($saved_age, '24', t('Can retrieve DavidD row after commit.'));
+      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielD'))->fetchField();
+      $this->assertIdentical($saved_age, '19', t('Can retrieve DanielD row after commit.'));
+      // The created table should also exist.
+      $count = db_query('SELECT COUNT(id) FROM {database_test_1}')->fetchField();
+      $this->assertIdentical($count, '0', t('Table was successfully created inside a transaction.'));
+    }
+    catch (Exception $e) {
+      $this->fail($e->getMessage());
+    }
+
+    // If we rollback the transaction, an exception might be thrown.
+    try {
+      $this->transactionOuterLayer('E', TRUE, TRUE);
+
+      // Because we rolled back, the inserted rows shouldn't be present.
+      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidE'))->fetchField();
+      $this->assertNotIdentical($saved_age, '24', t('Cannot retrieve DavidE row after rollback.'));
+      $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielE'))->fetchField();
+      $this->assertNotIdentical($saved_age, '19', t('Cannot retrieve DanielE row after rollback.'));
+    }
+    catch (Exception $e) {
+      // An exception also lets the test pass.
+      $this->assertTrue(true, t('Exception thrown on rollback after a DDL statement was executed.'));
+    }
+  }
 }
 
 
diff --git a/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
index 030649d1..52228081 100644
--- a/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
+++ b/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
index 1b97a000..a170f8c7 100644
--- a/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
+++ b/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/entity_cache_test.info b/modules/simpletest/tests/entity_cache_test.info
index 9926fa03..e977f7e6 100644
--- a/modules/simpletest/tests/entity_cache_test.info
+++ b/modules/simpletest/tests/entity_cache_test.info
@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = entity_cache_test_dependency
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/entity_cache_test_dependency.info b/modules/simpletest/tests/entity_cache_test_dependency.info
index ec93b21e..0dfe6eb3 100644
--- a/modules/simpletest/tests/entity_cache_test_dependency.info
+++ b/modules/simpletest/tests/entity_cache_test_dependency.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/entity_crud_hook_test.info b/modules/simpletest/tests/entity_crud_hook_test.info
index c9ea4e9b..b4d8bedf 100644
--- a/modules/simpletest/tests/entity_crud_hook_test.info
+++ b/modules/simpletest/tests/entity_crud_hook_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/error_test.info b/modules/simpletest/tests/error_test.info
index f742d62d..9a0566d0 100644
--- a/modules/simpletest/tests/error_test.info
+++ b/modules/simpletest/tests/error_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/file_test.info b/modules/simpletest/tests/file_test.info
index 24d05cf4..d258299b 100644
--- a/modules/simpletest/tests/file_test.info
+++ b/modules/simpletest/tests/file_test.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = file_test.module
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/filter_test.info b/modules/simpletest/tests/filter_test.info
index 4532e509..a77a6f50 100644
--- a/modules/simpletest/tests/filter_test.info
+++ b/modules/simpletest/tests/filter_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/form_test.info b/modules/simpletest/tests/form_test.info
index 430b0fe6..29cb7fe8 100644
--- a/modules/simpletest/tests/form_test.info
+++ b/modules/simpletest/tests/form_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/image_test.info b/modules/simpletest/tests/image_test.info
index eb280e5f..7919f23c 100644
--- a/modules/simpletest/tests/image_test.info
+++ b/modules/simpletest/tests/image_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/menu_test.info b/modules/simpletest/tests/menu_test.info
index 710e530b..480b741a 100644
--- a/modules/simpletest/tests/menu_test.info
+++ b/modules/simpletest/tests/menu_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/module_test.info b/modules/simpletest/tests/module_test.info
index 2e8c9c8a..328307af 100644
--- a/modules/simpletest/tests/module_test.info
+++ b/modules/simpletest/tests/module_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/requirements1_test.info b/modules/simpletest/tests/requirements1_test.info
index b227e418..5fb5dd04 100644
--- a/modules/simpletest/tests/requirements1_test.info
+++ b/modules/simpletest/tests/requirements1_test.info
@@ -1,12 +1,12 @@
 name = Requirements 1 Test
 description = "Tests that a module is not installed when it fails hook_requirements('install')."
-package = Core
+package = Testing
 version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/requirements2_test.info b/modules/simpletest/tests/requirements2_test.info
index b0bf1187..1952c423 100644
--- a/modules/simpletest/tests/requirements2_test.info
+++ b/modules/simpletest/tests/requirements2_test.info
@@ -2,13 +2,13 @@ name = Requirements 2 Test
 description = "Tests that a module is not installed when the one it depends on fails hook_requirements('install)."
 dependencies[] = requirements1_test
 dependencies[] = comment
-package = Core
+package = Testing
 version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/session_test.info b/modules/simpletest/tests/session_test.info
index c541d437..38e28a63 100644
--- a/modules/simpletest/tests/session_test.info
+++ b/modules/simpletest/tests/session_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/system_dependencies_test.info b/modules/simpletest/tests/system_dependencies_test.info
index b371f635..c6353303 100644
--- a/modules/simpletest/tests/system_dependencies_test.info
+++ b/modules/simpletest/tests/system_dependencies_test.info
@@ -6,8 +6,8 @@ core = 7.x
 hidden = TRUE
 dependencies[] = _missing_dependency
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/system_test.info b/modules/simpletest/tests/system_test.info
index 1681ccb7..9e1bed97 100644
--- a/modules/simpletest/tests/system_test.info
+++ b/modules/simpletest/tests/system_test.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = system_test.module
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/system_test.module b/modules/simpletest/tests/system_test.module
index 76841fb6..9516c918 100644
--- a/modules/simpletest/tests/system_test.module
+++ b/modules/simpletest/tests/system_test.module
@@ -28,6 +28,13 @@ function system_test_menu() {
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
+  $items['system-test/multiple-redirects/%'] = array(
+    'title' => 'Redirect',
+    'page callback' => 'system_test_multiple_redirects',
+    'page arguments' => array(2),
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
   $items['system-test/set-header'] = array(
     'page callback' => 'system_test_set_header',
     'access arguments' => array('access content'),
@@ -122,6 +129,30 @@ function system_test_redirect($code) {
   return '';
 }
 
+/**
+ * Menu callback; sends a redirect header to itself until $count argument is 0.
+ *
+ * Emulates the variable number of redirects (given by initial $count argument)
+ * to the final destination URL by continuous sending of 301 HTTP redirect
+ * headers to itself together with decrementing the $count parameter until the
+ * $count parameter reaches 0. After that it returns an empty string to render
+ * the final destination page.
+ *
+ * @param $count
+ *   The count of redirects left until the final destination page.
+ *
+ * @returns
+ *   The location redirect if the $count > 0, otherwise an empty string.
+ */
+function system_test_multiple_redirects($count) {
+  $count = (int) $count;
+  if ($count > 0) {
+    header("location: " . url('system-test/multiple-redirects/' . --$count, array('absolute' => TRUE)), TRUE, 301);
+    exit;
+  }
+  return '';
+}
+
 function system_test_set_header() {
   drupal_add_http_header($_GET['name'], $_GET['value']);
   return t('The following header was set: %name: %value', array('%name' => $_GET['name'], '%value' => $_GET['value']));
@@ -146,8 +177,10 @@ function system_test_redirect_invalid_scheme() {
  * Implements hook_modules_installed().
  */
 function system_test_modules_installed($modules) {
-  if (in_array('aggregator', $modules)) {
-    drupal_set_message(t('hook_modules_installed fired for aggregator'));
+  if (variable_get('test_verbose_module_hooks')) {
+    foreach ($modules as $module) {
+      drupal_set_message(t('hook_modules_installed fired for @module', array('@module' => $module)));
+    }
   }
 }
 
@@ -155,8 +188,10 @@ function system_test_modules_installed($modules) {
  * Implements hook_modules_enabled().
  */
 function system_test_modules_enabled($modules) {
-  if (in_array('aggregator', $modules)) {
-    drupal_set_message(t('hook_modules_enabled fired for aggregator'));
+  if (variable_get('test_verbose_module_hooks')) {
+    foreach ($modules as $module) {
+      drupal_set_message(t('hook_modules_enabled fired for @module', array('@module' => $module)));
+    }
   }
 }
 
@@ -164,8 +199,10 @@ function system_test_modules_enabled($modules) {
  * Implements hook_modules_disabled().
  */
 function system_test_modules_disabled($modules) {
-  if (in_array('aggregator', $modules)) {
-    drupal_set_message(t('hook_modules_disabled fired for aggregator'));
+  if (variable_get('test_verbose_module_hooks')) {
+    foreach ($modules as $module) {
+      drupal_set_message(t('hook_modules_disabled fired for @module', array('@module' => $module)));
+    }
   }
 }
 
@@ -173,8 +210,10 @@ function system_test_modules_disabled($modules) {
  * Implements hook_modules_uninstalled().
  */
 function system_test_modules_uninstalled($modules) {
-  if (in_array('aggregator', $modules)) {
-    drupal_set_message(t('hook_modules_uninstalled fired for aggregator'));
+  if (variable_get('test_verbose_module_hooks')) {
+    foreach ($modules as $module) {
+      drupal_set_message(t('hook_modules_uninstalled fired for @module', array('@module' => $module)));
+    }
   }
 }
 
diff --git a/modules/simpletest/tests/taxonomy_test.info b/modules/simpletest/tests/taxonomy_test.info
index 8d3aa1ef..376a5bb3 100644
--- a/modules/simpletest/tests/taxonomy_test.info
+++ b/modules/simpletest/tests/taxonomy_test.info
@@ -6,8 +6,8 @@ core = 7.x
 hidden = TRUE
 dependencies[] = taxonomy
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/theme.test b/modules/simpletest/tests/theme.test
index d0ad77d7..f1e1bd58 100644
--- a/modules/simpletest/tests/theme.test
+++ b/modules/simpletest/tests/theme.test
@@ -42,6 +42,11 @@ class ThemeUnitTest extends DrupalWebTestCase {
     $args = array('node', "1\0");
     $suggestions = theme_get_suggestions($args, 'page');
     $this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1'), t('Removed invalid \\0 from suggestions'));
+    // Define path with hyphens to be used to generate suggestions.
+    $args = array('node', '1', 'hyphen-path');
+    $result = array('page__node', 'page__node__%', 'page__node__1', 'page__node__hyphen_path');
+    $suggestions = theme_get_suggestions($args, 'page');
+    $this->assertEqual($suggestions, $result, t('Found expected page suggestions for paths containing hyphens.'));
   }
 
   /**
diff --git a/modules/simpletest/tests/theme_test.info b/modules/simpletest/tests/theme_test.info
index 7a9c2dbf..721e469a 100644
--- a/modules/simpletest/tests/theme_test.info
+++ b/modules/simpletest/tests/theme_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/update_test_1.info b/modules/simpletest/tests/update_test_1.info
index ae9a726f..da04d6c1 100644
--- a/modules/simpletest/tests/update_test_1.info
+++ b/modules/simpletest/tests/update_test_1.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/update_test_2.info b/modules/simpletest/tests/update_test_2.info
index ae9a726f..da04d6c1 100644
--- a/modules/simpletest/tests/update_test_2.info
+++ b/modules/simpletest/tests/update_test_2.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/update_test_3.info b/modules/simpletest/tests/update_test_3.info
index ae9a726f..da04d6c1 100644
--- a/modules/simpletest/tests/update_test_3.info
+++ b/modules/simpletest/tests/update_test_3.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/upgrade/drupal-6.forum.database.php b/modules/simpletest/tests/upgrade/drupal-6.forum.database.php
index 07dfcb34..5a2cc332 100644
--- a/modules/simpletest/tests/upgrade/drupal-6.forum.database.php
+++ b/modules/simpletest/tests/upgrade/drupal-6.forum.database.php
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * Database additions for forum tests.
diff --git a/modules/simpletest/tests/upgrade/drupal-6.menu.database.php b/modules/simpletest/tests/upgrade/drupal-6.menu.database.php
new file mode 100644
index 00000000..d10c4eec
--- /dev/null
+++ b/modules/simpletest/tests/upgrade/drupal-6.menu.database.php
@@ -0,0 +1,10 @@
+<?php
+db_insert('variable')->fields(array(
+  'name',
+  'value',
+))
+->values(array(
+  'name' => 'menu_default_node_menu',
+  'value' => 's:15:"secondary-links";',
+))
+->execute();
diff --git a/modules/simpletest/tests/upgrade/drupal-6.user-no-password-token.database.php b/modules/simpletest/tests/upgrade/drupal-6.user-no-password-token.database.php
new file mode 100644
index 00000000..64631946
--- /dev/null
+++ b/modules/simpletest/tests/upgrade/drupal-6.user-no-password-token.database.php
@@ -0,0 +1,10 @@
+<?php
+db_insert('variable')->fields(array(
+  'name',
+  'value',
+))
+->values(array(
+  'name' => 'user_mail_register_no_approval_required_body',
+  'value' => 's:86:"!username, !site, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url.";',
+))
+->execute();
diff --git a/modules/simpletest/tests/upgrade/drupal-6.user-password-token.database.php b/modules/simpletest/tests/upgrade/drupal-6.user-password-token.database.php
new file mode 100644
index 00000000..367c7048
--- /dev/null
+++ b/modules/simpletest/tests/upgrade/drupal-6.user-password-token.database.php
@@ -0,0 +1,10 @@
+<?php
+db_insert('variable')->fields(array(
+  'name',
+  'value',
+))
+->values(array(
+  'name' => 'user_mail_register_no_approval_required_body',
+  'value' => 's:97:"!password, !username, !site, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url.";',
+))
+->execute();
diff --git a/modules/simpletest/tests/upgrade/upgrade.forum.test b/modules/simpletest/tests/upgrade/upgrade.forum.test
index 827988da..99269d9f 100644
--- a/modules/simpletest/tests/upgrade/upgrade.forum.test
+++ b/modules/simpletest/tests/upgrade/upgrade.forum.test
@@ -1,5 +1,4 @@
 <?php
-// $Id$
 
 /**
  * Upgrade test for forum.module.
diff --git a/modules/simpletest/tests/upgrade/upgrade.menu.test b/modules/simpletest/tests/upgrade/upgrade.menu.test
new file mode 100644
index 00000000..beb20277
--- /dev/null
+++ b/modules/simpletest/tests/upgrade/upgrade.menu.test
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Upgrade test for menu.module.
+ */
+class MenuUpgradePathTestCase extends UpgradePathTestCase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'Menu upgrade path',
+      'description'  => 'Menu upgrade path tests.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.filled.database.php',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.menu.database.php',
+    );
+    parent::setUp();
+
+    $this->uninstallModulesExcept(array('menu'));
+  }
+
+  /**
+   * Test a successful upgrade.
+   */
+  public function testMenuUpgrade() {
+    $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
+
+    // Test the migration of "Default menu for content" setting to individual node types.
+    $this->drupalGet("admin/structure/types/manage/page/edit");
+    $this->assertNoFieldChecked('edit-menu-options-management', 'Management menu is not selected as available menu');
+    $this->assertNoFieldChecked('edit-menu-options-navigation', 'Navigation menu is not selected as available menu');
+    $this->assertNoFieldChecked('edit-menu-options-primary-links', 'Primary Links menu is not selected as available menu');
+    $this->assertFieldChecked('edit-menu-options-secondary-links', 'Secondary Links menu is selected as available menu');
+    $this->assertNoFieldChecked('edit-menu-options-user-menu', 'User menu is not selected as available menu');
+    $this->assertOptionSelected('edit-menu-parent', 'secondary-links:0', 'Secondary links is selected as default parent item');
+
+    $this->assertEqual(variable_get('menu_default_node_menu'), NULL, 'Redundant variable menu_default_node_menu has been removed');
+
+  }
+}
diff --git a/modules/simpletest/tests/upgrade/upgrade.user.test b/modules/simpletest/tests/upgrade/upgrade.user.test
new file mode 100644
index 00000000..6c669219
--- /dev/null
+++ b/modules/simpletest/tests/upgrade/upgrade.user.test
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Upgrade test for user.module (password token involved).
+ */
+class UserUpgradePathPasswordTokenTestCase extends UpgradePathTestCase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'User upgrade path (password token involved)',
+      'description'  => 'User upgrade path tests (password token involved).',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.bare.database.php',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.user-password-token.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Test a successful upgrade.
+   */
+  public function testUserUpgrade() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+    $this->assertEqual(variable_get('user_mail_register_no_approval_required_body'), ', [user:name], [site:name], [site:url], [site:url-brief], [user:mail], [date:medium], [site:login-url], [user:edit-url], [user:one-time-login-url].', 'Existing email templates have been modified (password token involved).');
+  }
+}
+
+/**
+ * Upgrade test for user.module (password token not involved).
+ */
+class UserUpgradePathNoPasswordTokenTestCase extends UpgradePathTestCase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'User upgrade path (password token not involved)',
+      'description'  => 'User upgrade path tests (password token not involved).',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.bare.database.php',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.user-no-password-token.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Test a successful upgrade.
+   */
+  public function testUserUpgrade() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+    $this->assertEqual(variable_get('user_mail_register_no_approval_required_body'), '[user:name], [site:name], [site:url], [site:url-brief], [user:mail], [date:medium], [site:login-url], [user:edit-url], [user:one-time-login-url].', 'Existing email templates have been modified (password token not involved).');
+  }
+}
diff --git a/modules/simpletest/tests/url_alter_test.info b/modules/simpletest/tests/url_alter_test.info
index adea384c..ce07be55 100644
--- a/modules/simpletest/tests/url_alter_test.info
+++ b/modules/simpletest/tests/url_alter_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/simpletest/tests/xmlrpc_test.info b/modules/simpletest/tests/xmlrpc_test.info
index 92a93578..e30d855d 100644
--- a/modules/simpletest/tests/xmlrpc_test.info
+++ b/modules/simpletest/tests/xmlrpc_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/statistics/statistics.info b/modules/statistics/statistics.info
index a1339f24..9746a792 100644
--- a/modules/statistics/statistics.info
+++ b/modules/statistics/statistics.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = statistics.test
 configure = admin/config/system/statistics
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/syslog/syslog.info b/modules/syslog/syslog.info
index a0467d49..e8806a9e 100644
--- a/modules/syslog/syslog.info
+++ b/modules/syslog/syslog.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 files[] = syslog.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/system/system.api.php b/modules/system/system.api.php
index c7db6f1d..40053890 100644
--- a/modules/system/system.api.php
+++ b/modules/system/system.api.php
@@ -947,8 +947,11 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
  * called, the corresponding path components will be substituted for the
  * integers. That is, the integer 0 in an argument list will be replaced with
  * the first path component, integer 1 with the second, and so on (path
- * components are numbered starting from zero). This substitution feature allows
- * you to re-use a callback function for several different paths. For example:
+ * components are numbered starting from zero). To pass an integer without it
+ * being replaced with its respective path component, use the string value of
+ * the integer (e.g., '1') as the argument value. This substitution feature
+ * allows you to re-use a callback function for several different paths. For
+ * example:
  * @code
  *   function mymodule_menu() {
  *     $items['abc/def'] = array(
@@ -961,9 +964,12 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
  * When path 'abc/def' is requested, the page callback function will get 'def'
  * as the first argument and (always) 'foo' as the second argument.
  *
- * Note that if a page or theme callback function has an argument list array,
- * these arguments will be passed first to the function, followed by any
- * any arguments generated by optional path arguments as described above.
+ * If a page callback function uses an argument list array, and its path is
+ * requested with optional path arguments, then the list array's arguments are
+ * passed to the callback function first, followed by the optional path
+ * arguments. Using the above example, when path 'abc/def/bar/baz' is requested,
+ * mymodule_abc_view() will be called with 'def', 'foo', 'bar' and 'baz' as
+ * arguments, in that order.
  *
  * Special care should be taken for the page callback drupal_get_form(), because
  * your specific form callback function will always receive $form and
@@ -1295,7 +1301,7 @@ function hook_menu_link_insert($link) {
  */
 function hook_menu_link_update($link) {
   // If the parent menu has changed, update our record.
-  $menu_name = db_result(db_query("SELECT mlid, menu_name, status FROM {menu_example} WHERE mlid = :mlid", array(':mlid' => $link['mlid'])));
+  $menu_name = db_query("SELECT menu_name FROM {menu_example} WHERE mlid = :mlid", array(':mlid' => $link['mlid']))->fetchField();
   if ($menu_name != $link['menu_name']) {
     db_update('menu_example')
       ->fields(array('menu_name' => $link['menu_name']))
@@ -3264,6 +3270,14 @@ function hook_update_last_removed() {
  * module's database tables are removed, allowing your module to query its own
  * tables during this routine.
  *
+ * When hook_uninstall() is called, your module will already be disabled, so
+ * its .module file will not be automatically included. If you need to call API
+ * functions from your .module file in this hook, use drupal_load() to make
+ * them available. (Keep this usage to a minimum, though, especially when
+ * calling API functions that invoke hooks, or API functions from modules
+ * listed as dependencies, since these may not be available or work as expected
+ * when the module is disabled.)
+ *
  * @see hook_install()
  * @see hook_schema()
  * @see hook_disable()
@@ -3924,7 +3938,11 @@ function hook_system_themes_page_alter(&$theme_groups) {
   foreach ($theme_groups as $state => &$group) {
     foreach ($theme_groups[$state] as &$theme) {
       // Add a foo link to each list of theme operations.
-      $theme->operations[] = l(t('Foo'), 'admin/appearance/foo', array('query' => array('theme' => $theme->name)));
+      $theme->operations[] = array(
+        'title' => t('Foo'),
+        'href' => 'admin/appearance/foo',
+        'query' => array('theme' => $theme->name)
+      );
     }
   }
 }
diff --git a/modules/system/system.info b/modules/system/system.info
index e54331f5..fbb452fe 100644
--- a/modules/system/system.info
+++ b/modules/system/system.info
@@ -12,8 +12,8 @@ files[] = system.test
 required = TRUE
 configure = admin/config/system
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/system/system.module b/modules/system/system.module
index 5af9ad4e..c3b4a1e3 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -2018,6 +2018,7 @@ function system_block_info() {
   $blocks['help'] = array(
     'info' => t('System help'),
     'weight' => '5',
+    'cache' => DRUPAL_NO_CACHE,
   );
   // System-defined menu blocks.
   foreach (menu_list_system_menus() as $menu_name => $title) {
diff --git a/modules/system/system.test b/modules/system/system.test
index be4e3669..0fe0bc05 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -36,6 +36,40 @@ class ModuleTestCase extends DrupalWebTestCase {
     return $this->assertFalse($tables, t('Tables matching "@base_table" not found.', array('@base_table' => $base_table)));
   }
 
+  /**
+   * Assert that all tables defined in a module's hook_schema() exist.
+   *
+   * @param $module
+   *   The name of the module.
+   */
+  function assertModuleTablesExist($module) {
+    $tables = array_keys(drupal_get_schema_unprocessed($module));
+    $tables_exist = TRUE;
+    foreach ($tables as $table) {
+      if (!db_table_exists($table)) {
+        $tables_exist = FALSE;
+      }
+    }
+    return $this->assertTrue($tables_exist, t('All database tables defined by the @module module exist.', array('@module' => $module)));
+  }
+
+  /**
+   * Assert that none of the tables defined in a module's hook_schema() exist.
+   *
+   * @param $module
+   *   The name of the module.
+   */
+  function assertModuleTablesDoNotExist($module) {
+    $tables = array_keys(drupal_get_schema_unprocessed($module));
+    $tables_exist = FALSE;
+    foreach ($tables as $table) {
+      if (db_table_exists($table)) {
+        $tables_exist = TRUE;
+      }
+    }
+    return $this->assertFalse($tables_exist, t('None of the database tables defined by the @module module exist.', array('@module' => $module)));
+  }
+
   /**
    * Assert the list of modules are enabled or disabled.
    *
@@ -96,6 +130,8 @@ class ModuleTestCase extends DrupalWebTestCase {
  * Test module enabling/disabling functionality.
  */
 class EnableDisableTestCase extends ModuleTestCase {
+  protected $profile = 'testing';
+
   public static function getInfo() {
     return array(
       'name' => 'Enable/disable modules',
@@ -105,59 +141,132 @@ class EnableDisableTestCase extends ModuleTestCase {
   }
 
   /**
-   * Enable a module, check the database for related tables, disable module,
-   * check for related tables, uninstall module, check for related tables.
-   * Also check for invocation of the hook_module_action hook.
+   * Test that all core modules can be enabled, disabled and uninstalled.
    */
   function testEnableDisable() {
-    // Enable aggregator, and check tables.
-    $this->assertModules(array('aggregator'), FALSE);
-    $this->assertTableCount('aggregator', FALSE);
-
-    // Install (and enable) aggregator module.
-    $edit = array();
-    $edit['modules[Core][aggregator][enable]'] = 'aggregator';
-    $edit['modules[Core][forum][enable]'] = 'forum';
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
-
-    // Check that hook_modules_installed and hook_modules_enabled hooks were invoked and check tables.
-    $this->assertText(t('hook_modules_installed fired for aggregator'), t('hook_modules_installed fired.'));
-    $this->assertText(t('hook_modules_enabled fired for aggregator'), t('hook_modules_enabled fired.'));
-    $this->assertModules(array('aggregator'), TRUE);
-    $this->assertTableCount('aggregator', TRUE);
-    $this->assertLogMessage('system', "%module module installed.", array('%module' => 'aggregator'), WATCHDOG_INFO);
-    $this->assertLogMessage('system', "%module module enabled.", array('%module' => 'aggregator'), WATCHDOG_INFO);
+    // Try to enable, disable and uninstall all core modules, unless they are
+    // hidden or required.
+    $modules = system_rebuild_module_data();
+    foreach ($modules as $name => $module) {
+      if ($module->info['package'] != 'Core' || !empty($module->info['hidden']) || !empty($module->info['required'])) {
+        unset($modules[$name]);
+      }
+    }
+    $this->assertTrue(count($modules), t('Found @count core modules that we can try to enable in this test.', array('@count' => count($modules))));
+
+    // Enable the dblog module first, since we will be asserting the presence
+    // of log messages throughout the test.
+   if (isset($modules['dblog'])) {
+     $modules = array('dblog' => $modules['dblog']) + $modules;
+   }
+
+   // Set a variable so that the hook implementations in system_test.module
+   // will display messages via drupal_set_message().
+   variable_set('test_verbose_module_hooks', TRUE);
+
+    // Throughout this test, some modules may be automatically enabled (due to
+    // dependencies). We'll keep track of them in an array, so we can handle
+    // them separately.
+    $automatically_enabled = array();
+
+    // Go through each module in the list and try to enable it (unless it was
+    // already enabled automatically due to a dependency).
+    foreach ($modules as $name => $module) {
+      if (empty($automatically_enabled[$name])) {
+        // Start a list of modules that we expect to be enabled this time.
+        $modules_to_enable = array($name);
+
+        // Find out if the module has any dependencies that aren't enabled yet;
+        // if so, add them to the list of modules we expect to be automatically
+        // enabled.
+        foreach (array_keys($module->requires) as $dependency) {
+          if (isset($modules[$dependency]) && empty($automatically_enabled[$dependency])) {
+            $modules_to_enable[] = $dependency;
+            $automatically_enabled[$dependency] = TRUE;
+          }
+        }
 
-    // Disable aggregator, check tables, uninstall aggregator, check tables.
-    $edit = array();
-    $edit['modules[Core][aggregator][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.'));
+        // Check that each module is not yet enabled and does not have any
+        // database tables yet.
+        foreach ($modules_to_enable as $module_to_enable) {
+          $this->assertModules(array($module_to_enable), FALSE);
+          $this->assertModuleTablesDoNotExist($module_to_enable);
+        }
 
-    // Check that hook_modules_disabled hook was invoked and check tables.
-    $this->assertText(t('hook_modules_disabled fired for aggregator'), t('hook_modules_disabled fired.'));
-    $this->assertModules(array('aggregator'), FALSE);
-    $this->assertTableCount('aggregator', TRUE);
-    $this->assertLogMessage('system', "%module module disabled.", array('%module' => 'aggregator'), WATCHDOG_INFO);
+        // Install and enable the module.
+        $edit = array();
+        $edit['modules[Core][' . $name . '][enable]'] = $name;
+        $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+        // Handle the case where modules were installed along with this one and
+        // where we therefore hit a confirmation screen.
+        if (count($modules_to_enable) > 1) {
+          $this->drupalPost(NULL, array(), t('Continue'));
+        }
+        $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
+
+        // Check that hook_modules_installed() and hook_modules_enabled() were
+        // invoked with the expected list of modules, that each module's
+        // database tables now exist, and that appropriate messages appear in
+        // the logs.
+        foreach ($modules_to_enable as $module_to_enable) {
+          $this->assertText(t('hook_modules_installed fired for @module', array('@module' => $module_to_enable)));
+          $this->assertText(t('hook_modules_enabled fired for @module', array('@module' => $module_to_enable)));
+          $this->assertModules(array($module_to_enable), TRUE);
+          $this->assertModuleTablesExist($module_to_enable);
+          $this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_enable), WATCHDOG_INFO);
+          $this->assertLogMessage('system', "%module module enabled.", array('%module' => $module_to_enable), WATCHDOG_INFO);
+        }
 
-    // Uninstall the module.
-    $edit = array();
-    $edit['uninstall[aggregator]'] = 'aggregator';
-    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
+        // Disable and uninstall the original module, and check appropriate
+        // hooks, tables, and log messages. (Later, we'll go back and do the
+        // same thing for modules that were enabled automatically.) Skip this
+        // for the dblog module, because that is needed for the test; we'll go
+        // back and do that one at the end also.
+        if ($name != 'dblog') {
+          $this->assertSuccessfulDisableAndUninstall($name);
+        }
+      }
+    }
 
-    $this->drupalPost(NULL, NULL, t('Uninstall'));
-    $this->assertText(t('The selected modules have been uninstalled.'), t('Modules status has been updated.'));
+    // Go through all modules that were automatically enabled, and try to
+    // disable and uninstall them one by one.
+    while (!empty($automatically_enabled)) {
+      $initial_count = count($automatically_enabled);
+      foreach (array_keys($automatically_enabled) as $name) {
+        // If the module can't be disabled due to dependencies, skip it and try
+        // again the next time. Otherwise, try to disable it.
+        $this->drupalGet('admin/modules');
+        $disabled_checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Core][' . $name . '][enable]"]');
+        if (empty($disabled_checkbox) && $name != 'dblog') {
+          unset($automatically_enabled[$name]);
+          $this->assertSuccessfulDisableAndUninstall($name);
+        }
+      }
+      $final_count = count($automatically_enabled);
+      // If all checkboxes were disabled, something is really wrong with the
+      // test. Throw a failure and avoid an infinite loop.
+      if ($initial_count == $final_count) {
+        $this->fail(t('Remaining modules could not be disabled.'));
+        break;
+      }
+    }
 
-    // Check that hook_modules_uninstalled hook was invoked and check tables.
-    $this->assertText(t('hook_modules_uninstalled fired for aggregator'), t('hook_modules_uninstalled fired.'));
-    $this->assertModules(array('aggregator'), FALSE);
-    $this->assertTableCount('aggregator', FALSE);
-    $this->assertLogMessage('system', "%module module uninstalled.", array('%module' => 'aggregator'), WATCHDOG_INFO);
+    // Disable and uninstall the dblog module last, since we needed it for
+    // assertions in all the above tests.
+    if (isset($modules['dblog'])) {
+      $this->assertSuccessfulDisableAndUninstall('dblog');
+    }
 
-    // Reinstall (and enable) aggregator module.
+    // Now that all modules have been tested, go back and try to enable them
+    // all again at once. This tests two things:
+    // - That each module can be successfully enabled again after being
+    //   uninstalled.
+    // - That enabling more than one module at the same time does not lead to
+    //   any errors.
     $edit = array();
-    $edit['modules[Core][aggregator][enable]'] = 'aggregator';
+    foreach (array_keys($modules) as $name) {
+      $edit['modules[Core][' . $name . '][enable]'] = $name;
+    }
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
     $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
   }
@@ -174,6 +283,49 @@ class EnableDisableTestCase extends ModuleTestCase {
     $this->assertEqual($info['label'], 'Entity Cache Test', 'Entity info label is correct.');
     $this->assertEqual($info['controller class'], 'DrupalDefaultEntityController', 'Entity controller class info is correct.');
   }
+
+  /**
+   * Disables and uninstalls a module and asserts that it was done correctly.
+   *
+   * @param $module
+   *   The name of the module to disable and uninstall.
+   */
+  function assertSuccessfulDisableAndUninstall($module) {
+    // Disable the module.
+    $edit = array();
+    $edit['modules[Core][' . $module . '][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->assertModules(array($module), FALSE);
+
+    // Check that the appropriate hook was fired and the appropriate log
+    // message appears.
+    $this->assertText(t('hook_modules_disabled fired for @module', array('@module' => $module)));
+    $this->assertLogMessage('system', "%module module disabled.", array('%module' => $module), WATCHDOG_INFO);
+
+    //  Check that the module's database tables still exist.
+    $this->assertModuleTablesExist($module);
+
+    // Uninstall the module.
+    $edit = array();
+    $edit['uninstall[' . $module . ']'] = $module;
+    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
+    $this->drupalPost(NULL, NULL, t('Uninstall'));
+    $this->assertText(t('The selected modules have been uninstalled.'), t('Modules status has been updated.'));
+    $this->assertModules(array($module), FALSE);
+
+    // Check that the appropriate hook was fired and the appropriate log
+    // message appears. (But don't check for the log message if the dblog
+    // module was just uninstalled, since the {watchdog} table won't be there
+    // anymore.)
+    $this->assertText(t('hook_modules_uninstalled fired for @module', array('@module' => $module)));
+    if ($module != 'dblog') {
+      $this->assertLogMessage('system', "%module module uninstalled.", array('%module' => $module), WATCHDOG_INFO);
+    }
+
+    // Check that the module's database tables no longer exist.
+    $this->assertModuleTablesDoNotExist($module);
+  }
 }
 
 /**
@@ -196,7 +348,7 @@ class HookRequirementsTestCase extends ModuleTestCase {
 
     // Attempt to install the requirements1_test module.
     $edit = array();
-    $edit['modules[Core][requirements1_test][enable]'] = 'requirements1_test';
+    $edit['modules[Testing][requirements1_test][enable]'] = 'requirements1_test';
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
 
     // Makes sure the module was NOT installed.
@@ -278,8 +430,8 @@ class ModuleDependencyTestCase extends ModuleTestCase {
 
     // Attempt to install both modules at the same time.
     $edit = array();
-    $edit['modules[Core][requirements1_test][enable]'] = 'requirements1_test';
-    $edit['modules[Core][requirements2_test][enable]'] = 'requirements2_test';
+    $edit['modules[Testing][requirements1_test][enable]'] = 'requirements1_test';
+    $edit['modules[Testing][requirements2_test][enable]'] = 'requirements2_test';
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
 
     // Makes sure the modules were NOT installed.
@@ -1210,6 +1362,8 @@ class FrontPageTestCase extends DrupalWebTestCase {
 }
 
 class SystemBlockTestCase extends DrupalWebTestCase {
+  protected $profile = 'testing';
+
   public static function getInfo() {
     return array(
       'name' => 'Block functionality',
@@ -1219,17 +1373,17 @@ class SystemBlockTestCase extends DrupalWebTestCase {
   }
 
   function setUp() {
-    parent::setUp();
+    parent::setUp('block');
 
     // Create and login user
-    $admin_user = $this->drupalCreateUser(array('administer blocks'));
+    $admin_user = $this->drupalCreateUser(array('administer blocks', 'access administration pages'));
     $this->drupalLogin($admin_user);
   }
 
   /**
-   * Test displaying and hiding the powered-by block.
+   * Test displaying and hiding the powered-by and help blocks.
    */
-  function testPoweredByBlock() {
+  function testSystemBlocks() {
     // Set block title and some settings to confirm that the interface is available.
     $this->drupalPost('admin/structure/block/manage/system/powered-by/configure', array('title' => $this->randomName(8)), t('Save block'));
     $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
@@ -1237,6 +1391,7 @@ class SystemBlockTestCase extends DrupalWebTestCase {
     // Set the powered-by block to the footer region.
     $edit = array();
     $edit['blocks[system_powered-by][region]'] = 'footer';
+    $edit['blocks[system_main][region]'] = 'content';
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
     $this->assertText(t('The block settings have been updated.'), t('Block successfully moved to footer region.'));
 
@@ -1257,6 +1412,18 @@ class SystemBlockTestCase extends DrupalWebTestCase {
     $edit['blocks[system_powered-by][region]'] = 'footer';
     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
     $this->drupalPost('admin/structure/block/manage/system/powered-by/configure', array('title' => ''), t('Save block'));
+
+    // Set the help block to the help region.
+    $edit = array();
+    $edit['blocks[system_help][region]'] = 'help';
+    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
+
+    // Test displaying the help block with block caching enabled.
+    variable_set('block_cache', TRUE);
+    $this->drupalGet('admin/structure/block/add');
+    $this->assertRaw(t('Use this page to create a new custom block.'));
+    $this->drupalGet('admin/index');
+    $this->assertRaw(t('This page shows you all available administration tasks for each module.'));
   }
 }
 
diff --git a/modules/taxonomy/taxonomy.info b/modules/taxonomy/taxonomy.info
index cf57006a..2dea1189 100644
--- a/modules/taxonomy/taxonomy.info
+++ b/modules/taxonomy/taxonomy.info
@@ -8,8 +8,8 @@ files[] = taxonomy.module
 files[] = taxonomy.test
 configure = admin/structure/taxonomy
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/taxonomy/taxonomy.install b/modules/taxonomy/taxonomy.install
index f28ffedf..56b7e01c 100644
--- a/modules/taxonomy/taxonomy.install
+++ b/modules/taxonomy/taxonomy.install
@@ -12,6 +12,11 @@ function taxonomy_uninstall() {
   // Remove variables.
   variable_del('taxonomy_override_selector');
   variable_del('taxonomy_terms_per_page_admin');
+  // Remove taxonomy_term bundles.
+  $vocabularies = db_query("SELECT machine_name FROM {taxonomy_vocabulary}")->fetchCol();
+  foreach ($vocabularies as $vocabulary) {
+    field_attach_delete_bundle('taxonomy_term', $vocabulary);
+  }
 }
 
 /**
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 50d2fd60..dc2847d3 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -532,12 +532,35 @@ function taxonomy_check_vocabulary_hierarchy($vocabulary, $changed_term) {
 }
 
 /**
- * Save a term object to the database.
+ * Saves a term object to the database.
  *
  * @param $term
- *  A term object.
+ *   The taxonomy term object with the following properties:
+ *   - vid: The ID of the vocabulary the term is assigned to.
+ *   - name: The name of the term.
+ *   - tid: (optional) The unique ID for the term being saved. If $term->tid is
+ *     empty or omitted, a new term will be inserted.
+ *   - description: (optional) The term's description.
+ *   - format: (optional) The text format for the term's description.
+ *   - weight: (optional) The weight of this term in relation to other terms
+ *     within the same vocabulary.
+ *   - parent: (optional) The parent term(s) for this term. This can be a single
+ *     term ID or an array of term IDs. A value of 0 means this term does not
+ *     have any parents. When omitting this variable during an update, the
+ *     existing hierarchy for the term remains unchanged.
+ *   - vocabulary_machine_name: (optional) The machine name of the vocabulary
+ *     the term is assigned to. If not given, this value will be set
+ *     automatically by loading the vocabulary based on $term->vid.
+ *   - original: (optional) The original taxonomy term object before any changes
+ *     were applied. When omitted, the unchanged taxonomy term object is
+ *     loaded from the database and stored in this property.
+ *   Since a taxonomy term is an entity, any fields contained in the term object
+ *   are saved alongside the term object.
+ *
  * @return
- *   Status constant indicating if term was inserted or updated.
+ *   Status constant indicating whether term was inserted (SAVED_NEW) or updated
+ *   (SAVED_UPDATED). When inserting a new term, $term->tid will contain the
+ *   term ID of the newly created term.
  */
 function taxonomy_term_save($term) {
   // Prevent leading and trailing spaces in term names.
@@ -1092,7 +1115,8 @@ class TaxonomyVocabularyController extends DrupalDefaultEntityController {
  *   this function.
  *
  * @return
- *   An array of term objects, indexed by tid.
+ *   An array of term objects, indexed by tid. When no results are found, an
+ *   empty array is returned.
  *
  * @todo Remove $conditions in Drupal 8.
  */
diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test
index 1fd47f5e..97cfe448 100644
--- a/modules/taxonomy/taxonomy.test
+++ b/modules/taxonomy/taxonomy.test
@@ -350,6 +350,40 @@ class TaxonomyVocabularyUnitTest extends TaxonomyWebTestCase {
     // Check that the field instance is still attached to the vocabulary.
     $this->assertTrue(field_info_instance('taxonomy_term', 'field_test', $new_name), t('The bundle name was updated correctly.'));
   }
+
+  /**
+   * Test uninstall and reinstall of the taxonomy module.
+   */
+  function testUninstallReinstall() {
+    // Fields and field instances attached to taxonomy term bundles should be
+    // removed when the module is uninstalled.
+    $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
+    $this->field = array('field_name' => $this->field_name, 'type' => 'text', 'cardinality' => 4);
+    $this->field = field_create_field($this->field);
+    $this->field_id = $this->field['id'];
+    $this->instance = array(
+      'field_name' => $this->field_name,
+      'entity_type' => 'taxonomy_term',
+      'bundle' => $this->vocabulary->machine_name,
+      'label' => $this->randomName() . '_label',
+    );
+    field_create_instance($this->instance);
+
+    module_disable(array('taxonomy'));
+    require_once DRUPAL_ROOT . '/includes/install.inc';
+    drupal_uninstall_modules(array('taxonomy'));
+    module_enable(array('taxonomy'));
+
+    // Now create a vocabulary with the same name. All field instances
+    // connected to this vocabulary name should have been removed when the
+    // module was uninstalled. Creating a new field with the same name and
+    // an instance of this field on the same bundle name should be successful.
+    unset($this->vocabulary->vid);
+    taxonomy_vocabulary_save($this->vocabulary);
+    unset($this->field['id']);
+    field_create_field($this->field);
+    field_create_instance($this->instance);
+  }
 }
 
 /**
diff --git a/modules/toolbar/toolbar.info b/modules/toolbar/toolbar.info
index e168fd72..798d24a7 100644
--- a/modules/toolbar/toolbar.info
+++ b/modules/toolbar/toolbar.info
@@ -4,8 +4,8 @@ core = 7.x
 package = Core
 version = VERSION
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/tracker/tracker.info b/modules/tracker/tracker.info
index d640655b..db7549bb 100644
--- a/modules/tracker/tracker.info
+++ b/modules/tracker/tracker.info
@@ -6,8 +6,8 @@ version = VERSION
 core = 7.x
 files[] = tracker.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/translation/tests/translation_test.info b/modules/translation/tests/translation_test.info
index 88021e6a..467f4935 100644
--- a/modules/translation/tests/translation_test.info
+++ b/modules/translation/tests/translation_test.info
@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/translation/translation.info b/modules/translation/translation.info
index e3e1e4aa..d7cd35fd 100644
--- a/modules/translation/translation.info
+++ b/modules/translation/translation.info
@@ -6,8 +6,8 @@ version = VERSION
 core = 7.x
 files[] = translation.test
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/trigger/tests/trigger_test.info b/modules/trigger/tests/trigger_test.info
index e5aa50df..406a1af1 100644
--- a/modules/trigger/tests/trigger_test.info
+++ b/modules/trigger/tests/trigger_test.info
@@ -4,8 +4,8 @@ package = Testing
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/trigger/trigger.info b/modules/trigger/trigger.info
index cb76d1ad..8c460549 100644
--- a/modules/trigger/trigger.info
+++ b/modules/trigger/trigger.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = trigger.test
 configure = admin/structure/trigger
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/update/tests/aaa_update_test.info b/modules/update/tests/aaa_update_test.info
index 17da66ad..dd1becd4 100644
--- a/modules/update/tests/aaa_update_test.info
+++ b/modules/update/tests/aaa_update_test.info
@@ -4,8 +4,8 @@ package = Testing
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/update/tests/bbb_update_test.info b/modules/update/tests/bbb_update_test.info
index 016153ef..f6ed550d 100644
--- a/modules/update/tests/bbb_update_test.info
+++ b/modules/update/tests/bbb_update_test.info
@@ -4,8 +4,8 @@ package = Testing
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/update/tests/ccc_update_test.info b/modules/update/tests/ccc_update_test.info
index a2855233..a5190eff 100644
--- a/modules/update/tests/ccc_update_test.info
+++ b/modules/update/tests/ccc_update_test.info
@@ -4,8 +4,8 @@ package = Testing
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/update/tests/update_test.info b/modules/update/tests/update_test.info
index 94a2308a..0f0d649e 100644
--- a/modules/update/tests/update_test.info
+++ b/modules/update/tests/update_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/update/update.info b/modules/update/update.info
index 67c95650..2b53994b 100644
--- a/modules/update/update.info
+++ b/modules/update/update.info
@@ -6,8 +6,8 @@ core = 7.x
 files[] = update.test
 configure = admin/reports/updates/settings
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/update/update.module b/modules/update/update.module
index a66cfa51..a2d705a0 100644
--- a/modules/update/update.module
+++ b/modules/update/update.module
@@ -293,6 +293,7 @@ function update_cron() {
     // the cached data for all projects, attempt to re-fetch, and trigger any
     // configured notifications about the new status.
     update_refresh();
+    update_fetch_data();
     _update_cron_notify();
   }
   else {
diff --git a/modules/update/update.test b/modules/update/update.test
index 6f9ef08e..f0c214ed 100644
--- a/modules/update/update.test
+++ b/modules/update/update.test
@@ -133,6 +133,19 @@ class UpdateCoreTestCase extends UpdateTestHelper {
     $this->assertNoText(t('Security update required!'));
   }
 
+  /**
+   * Check that running cron updates the list of available updates.
+   */
+  function testModulePageRunCron() {
+    $this->setSystemInfo7_0();
+    variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
+    variable_set('update_test_xml_map', array('drupal' => '0'));
+
+    $this->cronRun();
+    $this->drupalGet('admin/modules');
+    $this->assertNoText(t('No update information available.'));
+  }
+
   /**
    * Check the messages at admin/modules when the site is up to date.
    */
@@ -142,10 +155,10 @@ class UpdateCoreTestCase extends UpdateTestHelper {
     variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
     variable_set('update_test_xml_map', array('drupal' => '0'));
 
-    $this->drupalGet('admin/modules');
-    $this->assertText(t('No update information available.'));
-    $this->clickLink(t('check manually'));
+    $this->drupalGet('admin/reports/updates');
+    $this->clickLink(t('Check manually'));
     $this->assertText(t('Checked available update data for one project.'));
+    $this->drupalGet('admin/modules');
     $this->assertNoText(t('There are updates available for your version of Drupal.'));
     $this->assertNoText(t('There is a security update available for your version of Drupal.'));
   }
@@ -159,10 +172,10 @@ class UpdateCoreTestCase extends UpdateTestHelper {
     variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
     variable_set('update_test_xml_map', array('drupal' => '1'));
 
-    $this->drupalGet('admin/modules');
-    $this->assertText(t('No update information available.'));
-    $this->clickLink(t('check manually'));
+    $this->drupalGet('admin/reports/updates');
+    $this->clickLink(t('Check manually'));
     $this->assertText(t('Checked available update data for one project.'));
+    $this->drupalGet('admin/modules');
     $this->assertText(t('There are updates available for your version of Drupal.'));
     $this->assertNoText(t('There is a security update available for your version of Drupal.'));
   }
@@ -176,10 +189,10 @@ class UpdateCoreTestCase extends UpdateTestHelper {
     variable_set('update_fetch_url', url('update-test', array('absolute' => TRUE)));
     variable_set('update_test_xml_map', array('drupal' => '2-sec'));
 
-    $this->drupalGet('admin/modules');
-    $this->assertText(t('No update information available.'));
-    $this->clickLink(t('check manually'));
+    $this->drupalGet('admin/reports/updates');
+    $this->clickLink(t('Check manually'));
     $this->assertText(t('Checked available update data for one project.'));
+    $this->drupalGet('admin/modules');
     $this->assertNoText(t('There are updates available for your version of Drupal.'));
     $this->assertText(t('There is a security update available for your version of Drupal.'));
 
diff --git a/modules/user/tests/user_form_test.info b/modules/user/tests/user_form_test.info
index 45d961c1..8e9af847 100644
--- a/modules/user/tests/user_form_test.info
+++ b/modules/user/tests/user_form_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/user/user.info b/modules/user/user.info
index 80f6962c..27f47350 100644
--- a/modules/user/user.info
+++ b/modules/user/user.info
@@ -9,8 +9,8 @@ required = TRUE
 configure = admin/config/people
 stylesheets[all][] = user.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/modules/user/user.install b/modules/user/user.install
index df94ad53..75fca659 100644
--- a/modules/user/user.install
+++ b/modules/user/user.install
@@ -683,46 +683,13 @@ function user_update_7010() {
 }
 
 /**
- * Updates email templates to use new tokens.
+ * Placeholder function.
  *
- * This function upgrades customized email templates from the old !token format
- * to the new core tokens format. Additionally, in Drupal 7 we no longer e-mail
- * plain text passwords to users, and there is no token for a plain text
- * password in the new token system. Therefore, it also modifies any saved
- * templates using the old '!password' token such that the token is removed, and
- * displays a warning to users that they may need to go and modify the wording
- * of their templates.
+ * As a fix for user_update_7011() not updating email templates to use the new
+ * tokens, user_update_7017() now targets email templates of Drupal 6 sites and
+ * already upgraded sites.
  */
 function user_update_7011() {
-  $message = '';
-
-  $tokens = array(
-    '!site-name-token' => '[site:name]',
-    '!site-url-token' => '[site:url]',
-    '!user-name-token' => '[user:name]',
-    '!user-mail-token' => '[user:mail]',
-    '!site-login-url-token' => '[site:login-url]',
-    '!site-url-brief-token' => '[site:url-brief]',
-    '!user-edit-url-token' => '[user:edit-url]',
-    '!user-one-time-login-url-token' => '[user:one-time-login-url]',
-    '!user-cancel-url-token' => '[user:cancel-url]',
-    '!password' => '',
-  );
-
-  $result = db_select('variable', 'v')
-    ->fields('v', array('name', 'value'))
-    ->condition('value', db_like('user_mail_') . '%', 'LIKE')
-    ->execute();
-
-  foreach ($result as $row) {
-    if (empty($message) && (strpos($row->value, '!password') !== FALSE)) {
-      $message = t('The ability to send users their passwords in plain text has been removed in Drupal 7. Your existing email templates have been modified to remove it. You should <a href="@template-url">review these templates</a> to make sure they read properly.', array('@template-url' => url('admin/config/people/accounts')));
-    }
-
-    variable_set($row->name, str_replace(array_keys($tokens), $tokens, $row->value));
-  }
-
-  return $message;
 }
 
 /**
@@ -866,6 +833,53 @@ function user_update_7016() {
   ));
 }
 
+/**
+ * Update email templates to use new tokens.
+ *
+ * This function upgrades customized email templates from the old !token format
+ * to the new core tokens format. Additionally, in Drupal 7 we no longer e-mail
+ * plain text passwords to users, and there is no token for a plain text
+ * password in the new token system. Therefore, it also modifies any saved
+ * templates using the old '!password' token such that the token is removed, and
+ * displays a warning to users that they may need to go and modify the wording
+ * of their templates.
+ */
+function user_update_7017() {
+  $message = '';
+
+  $tokens = array(
+    '!site' => '[site:name]',
+    '!username' => '[user:name]',
+    '!mailto' => '[user:mail]',
+    '!login_uri' => '[site:login-url]',
+    '!uri_brief' => '[site:url-brief]',
+    '!edit_uri' => '[user:edit-url]',
+    '!login_url' => '[user:one-time-login-url]',
+    '!uri' => '[site:url]',
+    '!date' => '[date:medium]',
+    '!password' => '',
+  );
+
+  $result = db_select('variable', 'v')
+    ->fields('v', array('name'))
+    ->condition('name', db_like('user_mail_') . '%', 'LIKE')
+    ->execute();
+
+  foreach ($result as $row) {
+    // Use variable_get() to get the unserialized value for free.
+    if ($value = variable_get($row->name, FALSE)) {
+
+      if (empty($message) && (strpos($value, '!password') !== FALSE)) {
+        $message = t('The ability to send users their passwords in plain text has been removed in Drupal 7. Your existing email templates have been modified to remove it. You should <a href="@template-url">review these templates</a> to make sure they read properly.', array('@template-url' => url('admin/config/people/accounts')));
+      }
+
+      variable_set($row->name, str_replace(array_keys($tokens), $tokens, $value));
+    }
+  }
+
+  return $message;
+}
+
 /**
  * @} End of "addtogroup updates-6.x-to-7.x"
  */
diff --git a/modules/user/user.module b/modules/user/user.module
index 90d313b1..84430b2f 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -2266,7 +2266,18 @@ function user_pass_reset_url($account) {
 }
 
 /**
- * Generate a URL to confirm an account cancellation request.
+ * Generates a URL to confirm an account cancellation request.
+ *
+ * @param object $account
+ *   The user account object, which must contain at least the following
+ *   properties:
+ *   - uid: The user uid number.
+ *   - pass: The hashed user password string.
+ *   - login: The user login name.
+ *
+ * @return
+ *   A unique URL that may be used to confirm the cancellation of the user
+ *   account.
  *
  * @see user_mail_tokens()
  * @see user_cancel_confirm()
@@ -2698,7 +2709,21 @@ Your account on [site:name] has been canceled.
 /**
  * Token callback to add unsafe tokens for user mails.
  *
- * @see user_mail()
+ * This function is used by the token_replace() call at the end of
+ * _user_mail_text() to set up some additional tokens that can be
+ * used in email messages generated by user_mail().
+ *
+ * @param $replacements
+ *   An associative array variable containing mappings from token names to
+ *   values (for use with strtr()).
+ * @param $data
+ *   An associative array of token replacement values. If the 'user' element
+ *   exists, it must contain a user account object with the following
+ *   properties:
+ *   - login: The account login name.
+ *   - pass: The hashed account login password.
+ * @param $options
+ *   Unused parameter required by the token_replace() function.
  */
 function user_mail_tokens(&$replacements, $data, $options) {
   if (isset($data['user'])) {
diff --git a/profiles/minimal/minimal.info b/profiles/minimal/minimal.info
index f7102f95..b5b1187a 100644
--- a/profiles/minimal/minimal.info
+++ b/profiles/minimal/minimal.info
@@ -6,8 +6,8 @@ dependencies[] = block
 dependencies[] = dblog
 files[] = minimal.profile
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/profiles/standard/standard.info b/profiles/standard/standard.info
index 857f7062..9008fea9 100644
--- a/profiles/standard/standard.info
+++ b/profiles/standard/standard.info
@@ -25,8 +25,8 @@ dependencies[] = file
 dependencies[] = rdf
 files[] = standard.profile
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
index 030649d1..52228081 100644
--- a/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
+++ b/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
index f61b8724..277349d7 100644
--- a/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
+++ b/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
@@ -8,8 +8,8 @@ version = VERSION
 core = 6.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/profiles/testing/testing.info b/profiles/testing/testing.info
index dc403e5f..4f6271c4 100644
--- a/profiles/testing/testing.info
+++ b/profiles/testing/testing.info
@@ -4,8 +4,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/robots.txt b/robots.txt
index 490fa59f..35ea42db 100644
--- a/robots.txt
+++ b/robots.txt
@@ -40,6 +40,7 @@ Disallow: /xmlrpc.php
 # Paths (clean URLs)
 Disallow: /admin/
 Disallow: /comment/reply/
+Disallow: /filter/tips/
 Disallow: /node/add/
 Disallow: /search/
 Disallow: /user/register/
@@ -49,6 +50,7 @@ Disallow: /user/logout/
 # Paths (no clean URLs)
 Disallow: /?q=admin/
 Disallow: /?q=comment/reply/
+Disallow: /?q=filter/tips/
 Disallow: /?q=node/add/
 Disallow: /?q=search/
 Disallow: /?q=user/password/
diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh
index 2cfbcac9..db34924c 100755
--- a/scripts/run-tests.sh
+++ b/scripts/run-tests.sh
@@ -166,7 +166,7 @@ Drupal installation as the webserver user (differs per configuration), or root:
 sudo -u [wwwrun|www-data|etc] php ./scripts/{$args['script']}
   --url http://example.com/ --all
 sudo -u [wwwrun|www-data|etc] php ./scripts/{$args['script']}
-  --url http://example.com/ --class UploadTestCase
+  --url http://example.com/ --class BlockTestCase
 \n
 EOF;
 }
diff --git a/themes/bartik/bartik.info b/themes/bartik/bartik.info
index efdb8846..8ebd6c83 100644
--- a/themes/bartik/bartik.info
+++ b/themes/bartik/bartik.info
@@ -34,8 +34,8 @@ regions[footer] = Footer
 settings[shortcut_module_link] = 0
 
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/themes/bartik/color/color.inc b/themes/bartik/color/color.inc
index fa323eda..7c29f50b 100644
--- a/themes/bartik/color/color.inc
+++ b/themes/bartik/color/color.inc
@@ -6,86 +6,86 @@ drupal_add_js(array('color' => array('logo' => theme_get_setting('logo', 'bartik
 $info = array(
   // Available colors and color labels used in theme.
   'fields' => array(
-    'bg' => t('Main background'),
-    'link' => t('Link color'),
     'top' => t('Header top'),
     'bottom' => t('Header bottom'),
-    'text' => t('Text color'),
+    'bg' => t('Main background'),
     'sidebar' => t('Sidebar background'),
     'sidebarborders' => t('Sidebar borders'),
     'footer' => t('Footer background'),
     'titleslogan' => t('Title and slogan'),
+    'text' => t('Text color'),
+    'link' => t('Link color'),
   ),
   // Pre-defined color schemes.
   'schemes' => array(
     'default' => array(
       'title' => t('Blue Lagoon (default)'),
       'colors' => array(
-        'bg' => '#ffffff',
-        'link' => '#0071B3',
         'top' => '#0779bf',
         'bottom' => '#48a9e4',
-        'text' => '#3b3b3b',
+        'bg' => '#ffffff',
         'sidebar' => '#f6f6f2',
         'sidebarborders' => '#f9f9f9',
         'footer' => '#292929',
         'titleslogan' => '#fffeff',
+        'text' => '#3b3b3b',
+        'link' => '#0071B3',
       ),
     ),
     'firehouse' => array(
       'title' => t('Firehouse'),
       'colors' => array(
-        'bg' => '#ffffff',
-        'link' => '#d6121f',
         'top' => '#cd2d2d',
         'bottom' => '#cf3535',
-        'text' => '#3b3b3b',
+        'bg' => '#ffffff',
         'sidebar' => '#f1f4f0',
         'sidebarborders' => '#ededed',
         'footer' => '#1f1d1c',
         'titleslogan' => '#fffeff',
+        'text' => '#3b3b3b',
+        'link' => '#d6121f',
       ),
     ),
     'ice' => array(
       'title' => t('Ice'),
       'colors' => array(
-        'bg' => '#ffffff',
-        'link' => '#019dbf',
         'top' => '#d0d0d0',
         'bottom' => '#c2c4c5',
-        'text' => '#4a4a4a',
+        'bg' => '#ffffff',
         'sidebar' => '#ffffff',
         'sidebarborders' => '#cccccc',
         'footer' => '#24272c',
         'titleslogan' => '#000000',
+        'text' => '#4a4a4a',
+        'link' => '#019dbf',
       ),
     ),
     'plum' => array(
       'title' => t('Plum'),
       'colors' => array(
-        'bg' => '#fffdf7',
-        'link' => '#9d408d',
         'top' => '#4c1c58',
         'bottom' => '#593662',
-        'text' => '#301313',
+        'bg' => '#fffdf7',
         'sidebar' => '#edede7',
         'sidebarborders' => '#e7e7e7',
         'footer' => '#2c2c28',
         'titleslogan' => '#ffffff',
+        'text' => '#301313',
+        'link' => '#9d408d',
       ),
     ),
     'slate' => array(
       'title' => t('Slate'),
       'colors' => array(
-        'bg' => '#ffffff',
-        'link' => '#0073b6',
         'top' => '#4a4a4a',
         'bottom' => '#4e4e4e',
-        'text' => '#3b3b3b',
+        'bg' => '#ffffff',
         'sidebar' => '#ffffff',
         'sidebarborders' => '#d0d0d0',
         'footer' => '#161617',
         'titleslogan' => '#ffffff',
+        'text' => '#3b3b3b',
+        'link' => '#0073b6',
       ),
     ),
   ),
diff --git a/themes/bartik/css/style.css b/themes/bartik/css/style.css
index 7c142778..39e78051 100644
--- a/themes/bartik/css/style.css
+++ b/themes/bartik/css/style.css
@@ -1588,7 +1588,6 @@ div.admin-panel .description {
 .overlay #page {
   padding: 0 2em;
 }
-.overlay #skip-link,
 .overlay .region-page-top,
 .overlay #header,
 .overlay #page-title,
diff --git a/themes/garland/garland.info b/themes/garland/garland.info
index adc37e38..8e805840 100644
--- a/themes/garland/garland.info
+++ b/themes/garland/garland.info
@@ -7,8 +7,8 @@ stylesheets[all][] = style.css
 stylesheets[print][] = print.css
 settings[garland_width] = fluid
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/themes/seven/seven.info b/themes/seven/seven.info
index 599879f7..de5f3fb6 100644
--- a/themes/seven/seven.info
+++ b/themes/seven/seven.info
@@ -13,8 +13,8 @@ regions[page_bottom] = Page bottom
 regions[sidebar_first] = First sidebar
 regions_hidden[] = sidebar_first
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/themes/stark/stark.info b/themes/stark/stark.info
index d860b8d8..e27d53d6 100644
--- a/themes/stark/stark.info
+++ b/themes/stark/stark.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 stylesheets[all][] = layout.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/themes/tests/test_theme/test_theme.info b/themes/tests/test_theme/test_theme.info
index 2dfc17d9..0a791d48 100644
--- a/themes/tests/test_theme/test_theme.info
+++ b/themes/tests/test_theme/test_theme.info
@@ -15,8 +15,8 @@ hidden = TRUE
 ; file within the theme folder.
 stylesheets[all][] = system.base.css
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/themes/tests/update_test_basetheme/update_test_basetheme.info b/themes/tests/update_test_basetheme/update_test_basetheme.info
index f45f7e07..cc800fa8 100644
--- a/themes/tests/update_test_basetheme/update_test_basetheme.info
+++ b/themes/tests/update_test_basetheme/update_test_basetheme.info
@@ -3,8 +3,8 @@ description = Test theme which acts as a base theme for other test subthemes.
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/themes/tests/update_test_subtheme/update_test_subtheme.info b/themes/tests/update_test_subtheme/update_test_subtheme.info
index d4719a49..0265dc54 100644
--- a/themes/tests/update_test_subtheme/update_test_subtheme.info
+++ b/themes/tests/update_test_subtheme/update_test_subtheme.info
@@ -4,8 +4,8 @@ core = 7.x
 base theme = update_test_basetheme
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-05-25
-version = "7.2"
+; Information added by drupal.org packaging script on 2011-06-30
+version = "7.4"
 project = "drupal"
-datestamp = "1306357016"
+datestamp = "1309397516"
 
diff --git a/update.php b/update.php
index e238f9d3..fac9ca7d 100644
--- a/update.php
+++ b/update.php
@@ -387,10 +387,6 @@ if (empty($op) && update_access_allowed()) {
   // Set up theme system for the maintenance page.
   drupal_maintenance_theme();
 
-  // Rebuild the registry to ensure that removed hooks in modules do not result
-  // in undefined function errors and that newly defined hooks are called.
-  registry_rebuild();
-
   // Check the update requirements for Drupal.
   update_check_requirements();
 
-- 
GitLab