From dfdbe63cfc7ce0a6d64538974d05c85268fb60fc Mon Sep 17 00:00:00 2001
From: Tim Steiner <tsteiner2@unl.edu>
Date: Mon, 20 Feb 2012 20:17:06 +0000
Subject: [PATCH] [gh-290] Merging from testing into staging -c 1435

git-svn-id: file:///tmp/wdn_thm_drupal/branches/drupal-7.x/staging@1459 20a16fea-79d4-4915-8869-1ea9d5ebf173
---
 CHANGELOG.txt                                 |  42 +-
 INSTALL.mysql.txt                             |   2 +-
 MAINTAINERS.txt                               |   4 +-
 UPGRADE.txt                                   |  36 +-
 includes/actions.inc                          |  17 +-
 includes/ajax.inc                             |  33 +-
 includes/archiver.inc                         |  24 +-
 includes/authorize.inc                        |  26 +-
 includes/batch.inc                            |  31 +-
 includes/batch.queue.inc                      |  35 +-
 includes/bootstrap.inc                        | 265 +++++----
 includes/cache-install.inc                    |  18 +-
 includes/cache.inc                            |  86 ++-
 includes/common.inc                           | 545 ++++++++++--------
 includes/database/database.inc                |  12 +-
 includes/database/mysql/database.inc          |  41 +-
 includes/database/pgsql/database.inc          |  15 +-
 includes/database/query.inc                   |   6 +
 includes/database/select.inc                  |  63 +-
 includes/database/sqlite/database.inc         |  16 +-
 includes/file.inc                             |  63 +-
 includes/filetransfer/filetransfer.inc        |   6 +-
 includes/form.inc                             |  39 +-
 includes/graph.inc                            |   1 -
 includes/image.inc                            |  42 +-
 includes/json-encode.inc                      | 102 ++++
 includes/locale.inc                           |   2 +-
 includes/mail.inc                             |  46 +-
 includes/menu.inc                             |  85 ++-
 includes/module.inc                           |   2 +-
 includes/password.inc                         |   1 -
 includes/registry.inc                         |   1 -
 includes/stream_wrappers.inc                  |   4 +-
 includes/theme.inc                            |  53 +-
 includes/token.inc                            |   7 +-
 includes/update.inc                           |   2 +-
 includes/updater.inc                          |   4 +-
 includes/xmlrpc.inc                           |   1 -
 includes/xmlrpcs.inc                          |   1 -
 misc/ajax.js                                  |   2 +-
 misc/autocomplete.js                          |   2 +-
 misc/drupal.js                                |   2 +-
 .../aggregator/aggregator-feed-source.tpl.php |   2 +
 modules/aggregator/aggregator-item.tpl.php    |   2 +
 .../aggregator-summary-item.tpl.php           |   2 +
 .../aggregator-summary-items.tpl.php          |   2 +
 modules/aggregator/aggregator-wrapper.tpl.php |   2 +
 modules/aggregator/aggregator.admin.inc       |  70 ++-
 modules/aggregator/aggregator.api.php         |  72 ++-
 modules/aggregator/aggregator.info            |   6 +-
 modules/aggregator/aggregator.module          |  58 +-
 modules/aggregator/aggregator.pages.inc       |  23 +-
 modules/aggregator/aggregator.parser.inc      |  24 +-
 modules/aggregator/aggregator.processor.inc   |  11 +-
 modules/aggregator/aggregator.test            |  45 +-
 modules/aggregator/tests/aggregator_test.info |   6 +-
 .../block/block-admin-display-form.tpl.php    |   2 +
 modules/block/block.admin.inc                 |  25 +-
 modules/block/block.info                      |   6 +-
 modules/block/block.module                    |  65 ++-
 modules/block/block.test                      |   4 +
 modules/block/block.tpl.php                   |  11 +-
 modules/block/tests/block_test.info           |   6 +-
 modules/block/tests/block_test.module         |   8 +
 .../block_test_theme/block_test_theme.info    |   6 +-
 .../themes}/block_test_theme/page.tpl.php     |   0
 modules/blog/blog.info                        |   6 +-
 modules/book/book.info                        |   6 +-
 modules/color/color-rtl.css                   |   4 +
 modules/color/color.css                       |   4 +
 modules/color/color.info                      |   6 +-
 modules/color/color.js                        |  19 +-
 modules/color/color.module                    |  79 ++-
 modules/color/color.test                      |   8 +-
 modules/color/preview.js                      |   4 +
 modules/comment/comment.info                  |   6 +-
 modules/comment/comment.install               |  15 +-
 modules/comment/comment.module                |  26 +-
 modules/comment/comment.test                  | 216 +++++--
 modules/contact/contact.admin.inc             |  38 +-
 modules/contact/contact.info                  |   6 +-
 modules/contact/contact.module                |  12 +-
 modules/contact/contact.pages.inc             |  19 +-
 modules/contact/contact.test                  |  74 ++-
 modules/contextual/contextual.info            |   6 +-
 modules/dashboard/dashboard.info              |   6 +-
 modules/dblog/dblog.info                      |   6 +-
 modules/field/field.api.php                   |  26 +-
 modules/field/field.attach.inc                |  18 +-
 modules/field/field.crud.inc                  |  18 +-
 modules/field/field.info                      |   6 +-
 modules/field/field.info.inc                  |  11 +-
 modules/field/field.multilingual.inc          |   3 +
 .../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/options/options.info    |   6 +-
 modules/field/modules/text/text.info          |   6 +-
 modules/field/tests/field.test                | 120 +++-
 modules/field/tests/field_test.entity.inc     |   4 +-
 modules/field/tests/field_test.field.inc      |  40 +-
 modules/field/tests/field_test.info           |   6 +-
 modules/field/tests/field_test.module         |  59 +-
 modules/field_ui/field_ui-rtl.css             |   4 +
 modules/field_ui/field_ui.admin.inc           | 126 ++--
 modules/field_ui/field_ui.api.php             |   4 +-
 modules/field_ui/field_ui.css                 |   6 +-
 modules/field_ui/field_ui.info                |   6 +-
 modules/field_ui/field_ui.js                  |   8 +-
 modules/field_ui/field_ui.module              |  26 +-
 modules/field_ui/field_ui.test                | 129 ++++-
 modules/file/file.api.php                     |  16 +-
 modules/file/file.css                         |   4 +
 modules/file/file.field.inc                   |  30 +-
 modules/file/file.info                        |   6 +-
 modules/file/file.module                      |  47 +-
 modules/file/tests/file.test                  |  95 +--
 modules/file/tests/file_module_test.info      |   6 +-
 modules/file/tests/file_module_test.module    |   5 +-
 modules/filter/filter.info                    |   6 +-
 modules/forum/forum.info                      |   6 +-
 modules/help/help.admin.inc                   |  11 +-
 modules/help/help.api.php                     |   1 +
 modules/help/help.info                        |   6 +-
 modules/help/help.test                        |  32 +-
 modules/image/image.effects.inc               |   6 +-
 modules/image/image.field.inc                 |   5 +-
 modules/image/image.info                      |   6 +-
 modules/image/image.install                   |  49 +-
 modules/image/image.test                      | 166 +++++-
 modules/image/tests/image_module_test.info    |   6 +-
 modules/locale/locale.info                    |   6 +-
 modules/locale/locale.module                  |  20 +-
 modules/locale/locale.test                    |  28 +
 modules/locale/tests/locale_test.info         |   6 +-
 modules/menu/menu.admin.js                    |  75 ++-
 modules/menu/menu.info                        |   6 +-
 modules/menu/menu.install                     |  22 +
 modules/menu/menu.js                          |   1 -
 modules/menu/menu.module                      |  20 +-
 modules/menu/menu.test                        |  12 +-
 modules/node/node.api.php                     |  16 +-
 modules/node/node.info                        |   6 +-
 modules/node/node.module                      |  20 +-
 modules/node/tests/node_access_test.info      |   6 +-
 modules/node/tests/node_access_test.module    |   2 +-
 modules/node/tests/node_test.info             |   6 +-
 modules/node/tests/node_test_exception.info   |   6 +-
 modules/openid/openid.inc                     |  23 +-
 modules/openid/openid.info                    |   6 +-
 modules/openid/openid.module                  |  13 +-
 modules/openid/openid.test                    |  77 ++-
 modules/openid/tests/openid_test.info         |   6 +-
 modules/openid/tests/openid_test.module       |  23 +-
 modules/overlay/overlay-parent.js             |   4 +-
 modules/overlay/overlay.info                  |   6 +-
 modules/path/path.info                        |   6 +-
 modules/php/php.info                          |   6 +-
 modules/php/php.module                        |  25 +-
 modules/php/php.test                          |   8 +-
 modules/poll/poll.info                        |   6 +-
 modules/poll/poll.module                      |  14 +-
 modules/poll/poll.test                        |  36 +-
 modules/profile/profile.info                  |   6 +-
 modules/rdf/rdf.info                          |   6 +-
 modules/rdf/rdf.module                        |   3 +
 modules/rdf/tests/rdf_test.info               |   6 +-
 modules/search/search.api.php                 |  12 +-
 modules/search/search.extender.inc            |  25 +
 modules/search/search.info                    |   6 +-
 modules/search/search.module                  |   2 +-
 modules/search/search.test                    |  20 +
 .../search/tests/search_embedded_form.info    |   6 +-
 modules/search/tests/search_extra_type.info   |   6 +-
 modules/shortcut/shortcut.admin.js            |  28 +-
 modules/shortcut/shortcut.info                |   6 +-
 modules/simpletest/drupal_web_test_case.php   | 103 +++-
 modules/simpletest/simpletest.info            |   6 +-
 modules/simpletest/simpletest.module          |  13 +
 modules/simpletest/simpletest.pages.inc       |   2 +-
 modules/simpletest/simpletest.test            |  72 ++-
 .../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.info      |   6 +-
 modules/simpletest/tests/common.test          |  48 +-
 modules/simpletest/tests/common_test.info     |   6 +-
 .../tests/common_test_cron_helper.info        |   6 +-
 modules/simpletest/tests/database_test.info   |   6 +-
 modules/simpletest/tests/database_test.test   | 155 +++--
 ...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_cache_test_dependency.module |   2 +-
 .../tests/entity_crud_hook_test.info          |   6 +-
 modules/simpletest/tests/entity_query.test    |  10 +-
 modules/simpletest/tests/error_test.info      |   6 +-
 modules/simpletest/tests/file.test            |  40 +-
 modules/simpletest/tests/file_test.info       |   6 +-
 modules/simpletest/tests/file_test.module     |   2 +-
 modules/simpletest/tests/filter_test.info     |   6 +-
 modules/simpletest/tests/form.test            |   8 +
 modules/simpletest/tests/form_test.info       |   6 +-
 modules/simpletest/tests/form_test.module     |   2 +
 modules/simpletest/tests/image_test.info      |   6 +-
 modules/simpletest/tests/mail.test            |  24 +-
 modules/simpletest/tests/menu_test.info       |   6 +-
 modules/simpletest/tests/module_test.info     |   6 +-
 .../simpletest/tests/requirements1_test.info  |   6 +-
 .../simpletest/tests/requirements2_test.info  |   6 +-
 modules/simpletest/tests/session_test.info    |   6 +-
 .../tests/system_dependencies_test.info       |   6 +-
 ...atible_core_version_dependencies_test.info |   6 +-
 ...system_incompatible_core_version_test.info |   6 +-
 ...ible_module_version_dependencies_test.info |   6 +-
 ...stem_incompatible_module_version_test.info |   6 +-
 modules/simpletest/tests/system_test.info     |   6 +-
 modules/simpletest/tests/taxonomy_test.info   |   6 +-
 modules/simpletest/tests/theme.test           |  53 ++
 modules/simpletest/tests/theme_test.info      |   6 +-
 modules/simpletest/tests/theme_test.module    |  22 +
 .../tests/theme_test.template_test.tpl.php    |   2 +
 .../tests/themes}/test_theme/template.php     |   0
 .../tests/themes}/test_theme/test_theme.info  |   6 +-
 modules/simpletest/tests/unicode.test         |   2 +-
 .../simpletest/tests/update_script_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 +-
 .../drupal-6.node_type_broken.database.php    |  34 ++
 .../tests/upgrade/upgrade.node.test           |  32 +
 modules/simpletest/tests/upgrade/upgrade.test |   1 +
 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/syslog/syslog.module                  |   9 +
 modules/system/system.admin.inc               |   2 +-
 modules/system/system.api.php                 | 120 +++-
 modules/system/system.info                    |   6 +-
 modules/system/system.install                 |  13 +-
 modules/system/system.mail.inc                |  65 ++-
 modules/system/system.module                  |  51 +-
 modules/system/system.queue.inc               |  14 +-
 modules/system/system.test                    |  40 +-
 modules/taxonomy/taxonomy.info                |   6 +-
 modules/taxonomy/taxonomy.module              | 133 +++--
 modules/taxonomy/taxonomy.test                | 313 +++++++++-
 modules/toolbar/toolbar.info                  |   6 +-
 modules/toolbar/toolbar.module                |  19 +-
 modules/tracker/tracker.info                  |   6 +-
 modules/tracker/tracker.test                  |   1 -
 .../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 +-
 .../update_test_basetheme.info                |   6 +-
 .../update_test_subtheme.info                 |   6 +-
 modules/update/tests/update_test.info         |   6 +-
 modules/update/tests/update_test.module       |   9 +
 modules/update/update.info                    |   6 +-
 modules/update/update.manager.inc             |   2 +-
 modules/update/update.module                  |   4 +-
 modules/user/tests/user_form_test.info        |   6 +-
 modules/user/user.info                        |   6 +-
 modules/user/user.install                     |   2 +-
 modules/user/user.js                          |   2 +-
 modules/user/user.module                      |  30 +-
 profiles/minimal/minimal.info                 |   6 +-
 profiles/standard/standard.info               |   6 +-
 profiles/standard/standard.install            |   6 +-
 ...drupal_system_listing_compatible_test.info |   6 +-
 ...upal_system_listing_incompatible_test.info |   6 +-
 profiles/testing/testing.info                 |   6 +-
 scripts/generate-d7-content.sh                |   5 +-
 scripts/run-tests.sh                          |  13 +-
 sites/default/default.settings.php            |  23 +
 themes/bartik/bartik.info                     |   6 +-
 themes/bartik/css/style-rtl.css               |   1 +
 themes/garland/garland.info                   |   6 +-
 themes/seven/maintenance-page.tpl.php         |   3 +-
 themes/seven/page.tpl.php                     |   3 +-
 themes/seven/seven.info                       |   6 +-
 themes/seven/style.css                        |   1 +
 themes/stark/stark.info                       |   6 +-
 themes/tests/README.txt                       |   4 -
 291 files changed, 4626 insertions(+), 1908 deletions(-)
 create mode 100644 includes/json-encode.inc
 rename {themes/tests => modules/block/tests/themes}/block_test_theme/block_test_theme.info (79%)
 rename {themes/tests => modules/block/tests/themes}/block_test_theme/page.tpl.php (100%)
 create mode 100644 modules/simpletest/tests/theme_test.template_test.tpl.php
 rename {themes/tests => modules/simpletest/tests/themes}/test_theme/template.php (100%)
 rename {themes/tests => modules/simpletest/tests/themes}/test_theme/test_theme.info (89%)
 create mode 100644 modules/simpletest/tests/upgrade/drupal-6.node_type_broken.database.php
 rename {themes/tests => modules/update/tests/themes}/update_test_basetheme/update_test_basetheme.info (59%)
 rename {themes/tests => modules/update/tests/themes}/update_test_subtheme/update_test_subtheme.info (63%)
 delete mode 100644 themes/tests/README.txt

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 2313c111..b68b7fa9 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,4 +1,45 @@
 
+Drupal 7.13 xxxx-xx-xx (development version)
+----------------------
+
+Drupal 7.12, 2012-02-01
+----------------------
+- Fixed bug preventing custom menus from receiving an active trail.
+- Fixed hook_field_delete() no longer invoked during field_purge_data().
+- Fixed bug causing entity info cache to not be cleared with the rest of caches.
+- Fixed file_unmanaged_copy() fails with Drupal 7.7+ and safe_mode() or
+  open_basedir().
+- Fixed Nested transactions throw exceptions when they got out of scope.
+- Fixed bugs with the Return-Path when sending mail on both Windows and
+  non-Windows systems.
+- Fixed bug with DrupalCacheArray property visibility preventing others from
+  extending it (API change: http://drupal.org/node/1422264).
+- Fixed bug with handling of non-ASCII characters in file names (API change:
+  http://drupal.org/node/1424840).
+- Reconciled field maximum length with database column size in image and
+  aggregator modules.
+- Fixes to various core JavaScript files to allow for minification and
+  aggregation.
+- Fixed Prevent tests from deleting main installation's tables when
+  parent::setUp() is not called.
+- Fixed several Poll module bugs.
+- Fixed several Shortcut module bugs.
+- Added new hook_system_theme_info() to provide ability for contributed modules
+  to test theme functionality.
+- Added ability to cancel mail sending from hook_mail_alter().
+- Added support for configurable PDO connection options, enabling master-master
+  database replication.
+- Numerous improvements to tests and test runner to pave the way for faster test
+  runs.
+- Expanded test coverage.
+- Numerous API documentation improvements.
+- Numerous performance improvements, including token replacement and render
+  cache.
+
+Drupal 7.11, 2012-02-01
+----------------------
+- Fixed security issues (Multiple vulnerabilities), see SA-CORE-2012-001.
+
 Drupal 7.10, 2011-12-05
 ----------------------
 - Fixed Content-Language HTTP header to not cause issues with Drush 5.x.
@@ -18,7 +59,6 @@ Drupal 7.10, 2011-12-05
 - Numerous documentation improvements.
 - Additional automated test coverage.
 
-
 Drupal 7.9, 2011-10-26
 ----------------------
 - Critical fixes to OpenID to spec violations that could allow for
diff --git a/INSTALL.mysql.txt b/INSTALL.mysql.txt
index a7c292e3..bee58110 100644
--- a/INSTALL.mysql.txt
+++ b/INSTALL.mysql.txt
@@ -18,7 +18,7 @@ initial database files. Next you must log in and set the access database rights:
   mysql -u username -p
 
 Again, you will be asked for the 'username' database password. At the MySQL
-prompt, enter following command:
+prompt, enter the following command:
 
   GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER
   ON databasename.*
diff --git a/MAINTAINERS.txt b/MAINTAINERS.txt
index 103eb5a6..35eecf83 100644
--- a/MAINTAINERS.txt
+++ b/MAINTAINERS.txt
@@ -7,7 +7,7 @@ Branch maintainers
 ------------------
 
 The Drupal Core branch maintainers oversee the development of Drupal as a whole.
-The branch mainainers for Drupal 7 are:
+The branch maintainers for Drupal 7 are:
 
 - Dries Buytaert 'dries' <http://drupal.org/user/1>
 - Angela Byron 'webchick' <http://drupal.org/user/24967>
@@ -133,7 +133,6 @@ Accessibility
 - Brandon Bowersox 'brandonojc' <http://drupal.org/user/186415> 
 
 Documentation
-- Ariane Khachatourians 'arianek' <http://drupal.org/user/158886>
 - Jennifer Hodgdon 'jhodgdon' <http://drupal.org/user/155601>
 
 Security
@@ -257,6 +256,7 @@ System module
 - ?
 
 Taxonomy module
+- Jess Myrbo 'xjm' <http://drupal.org/user/65776>
 - Nathaniel Catchpole 'catch' <http://drupal.org/user/35733>
 - Benjamin Doherty 'bangpound' <http://drupal.org/user/100456>
 
diff --git a/UPGRADE.txt b/UPGRADE.txt
index c6fee987..c993df7e 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -141,15 +141,19 @@ following the instructions in the INTRODUCTION section at the top of this file:
    download Drupal 6.x and follow the instructions in its UPGRADE.txt. This
    document only applies for upgrades from 6.x to 7.x.
 
-3. Log in as user ID 1 (the site maintenance user).
+3. In addition to updating to the latest available version of Drupal 7.x core,
+   you must also upgrade all of your contributed modules for Drupal to their
+   latest Drupal 6.x versions.
 
-4. Go to Administer > Site configuration > Site maintenance. Select
+4. Log in as user ID 1 (the site maintenance user).
+
+5. Go to Administer > Site configuration > Site maintenance. Select
    "Off-line" and save the configuration.
 
-5. Go to Administer > Site building > Themes. Enable "Garland" and select it as
+6. Go to Administer > Site building > Themes. Enable "Garland" and select it as
    the default theme.
 
-6. Go to Administer > Site building > Modules. Disable all modules that are not
+7. Go to Administer > Site building > Modules. Disable all modules that are not
    listed under "Core - required" or "Core - optional". It is possible that some
    modules cannot be disabled, because others depend on them. Repeat this step
    until all non-core modules are disabled.
@@ -158,21 +162,21 @@ following the instructions in the INTRODUCTION section at the top of this file:
    no longer need their data, then you can uninstall them under the Uninstall
    tab after disabling them.
 
-7. On the command line or in your FTP client, remove the file
+8. On the command line or in your FTP client, remove the file
 
      sites/default/default.settings.php
 
-8. Remove all old core files and directories, except for the 'sites' directory
+9. Remove all old core files and directories, except for the 'sites' directory
    and any custom files you added elsewhere.
 
    If you made modifications to files like .htaccess or robots.txt, you will
    need to re-apply them from your backup, after the new files are in place.
 
-9. If you uninstalled any modules, remove them from the sites/all/modules and
+10. If you uninstalled any modules, remove them from the sites/all/modules and
    other sites/*/modules directories. Leave other modules in place, even though
    they are incompatible with Drupal 7.x.
 
-10. Download the latest Drupal 7.x release from http://drupal.org to a
+11. Download the latest Drupal 7.x release from http://drupal.org to a
    directory outside of your web root. Extract the archive and copy the files
    into your Drupal directory.
 
@@ -191,14 +195,14 @@ following the instructions in the INTRODUCTION section at the top of this file:
    from http://drupal.org using your web browser, extract it, and then use an
    FTP client to upload the files to your web root.
 
-11. Re-apply any modifications to files such as .htaccess or robots.txt.
+12. Re-apply any modifications to files such as .htaccess or robots.txt.
 
-12. Make your settings.php file writeable, so that the update process can
+13. Make your settings.php file writeable, so that the update process can
    convert it to the format of Drupal 7.x. settings.php is usually located in
 
      sites/default/settings.php
 
-13. Run update.php by visiting http://www.example.com/update.php (replace
+14. Run update.php by visiting http://www.example.com/update.php (replace
    www.example.com with your domain name). This will update the core database
    tables.
 
@@ -214,17 +218,17 @@ following the instructions in the INTRODUCTION section at the top of this file:
 
    - Once the upgrade is done, $update_free_access must be reverted to FALSE.
 
-14. Backup your database after the core upgrade has run.
+15. Backup your database after the core upgrade has run.
 
-15. Replace and update your non-core modules and themes, following the
+16. Replace and update your non-core modules and themes, following the
    procedures at http://drupal.org/node/948216
 
-16. Go to Administration > Reports > Status report. Verify that everything is
+17. Go to Administration > Reports > Status report. Verify that everything is
    working as expected.
 
-17. Ensure that $update_free_access is FALSE in settings.php.
+18. Ensure that $update_free_access is FALSE in settings.php.
 
-18. Go to Administration > Configuration > Development > Maintenance mode.
+19. Go to Administration > Configuration > Development > Maintenance mode.
    Disable the "Put site into maintenance mode" checkbox and save the
    configuration.
 
diff --git a/includes/actions.inc b/includes/actions.inc
index 760de830..ed43af4f 100644
--- a/includes/actions.inc
+++ b/includes/actions.inc
@@ -22,7 +22,7 @@
  * - $a1, $a2: Optional additional information, which can be passed into
  *   actions_do() and will be passed along to the action function.
  *
- * @} End of "defgroup actions".
+ * @}
  */
 
 /**
@@ -48,6 +48,7 @@
  *   Passed along to the callback.
  * @param $a2
  *   Passed along to the callback.
+ *
  * @return
  *   An associative array containing the results of the functions that
  *   perform the actions, keyed on action ID.
@@ -149,6 +150,7 @@ function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a
  *
  * @param $reset
  *   Reset the action info static cache.
+ *
  * @return
  *   An associative array keyed on action function name, with the same format
  *   as the return value of hook_action_info(), containing all
@@ -176,9 +178,9 @@ function actions_list($reset = FALSE) {
  * function and the actions returned by actions_list() are partially
  * synchronized. Non-configurable actions from hook_action_info()
  * implementations are put into the database when actions_synchronize() is
- * called, which happens when admin/config/system/actions is visited. Configurable
- * actions are not added to the database until they are configured in the
- * user interface, in which case a database row is created for each
+ * called, which happens when admin/config/system/actions is visited.
+ * Configurable actions are not added to the database until they are configured
+ * in the user interface, in which case a database row is created for each
  * configuration of each action.
  *
  * @return
@@ -205,6 +207,7 @@ function actions_get_all_actions() {
  *   An associative array with function names or action IDs as keys
  *   and associative arrays with keys 'label', 'type', etc. as values.
  *   This is usually the output of actions_list() or actions_get_all_actions().
+ *
  * @return
  *   An associative array whose keys are hashes of the input array keys, and
  *   whose corresponding values are associative arrays with components
@@ -223,7 +226,7 @@ function actions_actions_map($actions) {
 }
 
 /**
- * Given a hash of an action array key, returns the key (function or ID).
+ * Returns an action array key (function or ID), given its hash.
  *
  * Faster than actions_actions_map() when you only need the function name or ID.
  *
@@ -231,6 +234,7 @@ function actions_actions_map($actions) {
  *   Hash of a function name or action ID array key. The array key
  *   is a key into the return value of actions_list() (array key is the action
  *   function name) or actions_get_all_actions() (array key is the action ID).
+ *
  * @return
  *   The corresponding array key, or FALSE if no match is found.
  */
@@ -332,6 +336,7 @@ function actions_synchronize($delete_orphans = FALSE) {
  *   to Jim'.
  * @param $aid
  *   The ID of this action. If omitted, a new action is created.
+ *
  * @return
  *   The ID of the action.
  */
@@ -361,6 +366,7 @@ function actions_save($function, $type, $params, $label, $aid = NULL) {
  *
  * @param $aid
  *   The ID of the action to retrieve.
+ *
  * @return
  *   The appropriate action row from the database as an object.
  */
@@ -380,4 +386,3 @@ function actions_delete($aid) {
     ->execute();
   module_invoke_all('actions_delete', $aid);
 }
-
diff --git a/includes/ajax.inc b/includes/ajax.inc
index cda55b42..fb07477d 100644
--- a/includes/ajax.inc
+++ b/includes/ajax.inc
@@ -24,7 +24,8 @@
  * ajax_form_callback() and a defined #ajax['callback'] function.
  * However, you may optionally specify a different path to request or a
  * different callback function to invoke, which can return updated HTML or can
- * also return a richer set of @link ajax_commands Ajax framework commands @endlink.
+ * also return a richer set of
+ * @link ajax_commands Ajax framework commands @endlink.
  *
  * Standard form handling is as follows:
  *   - A form element has a #ajax property that includes #ajax['callback'] and
@@ -101,7 +102,7 @@
  * In the above example, the 'changethis' element is Ajax-enabled. The default
  * #ajax['event'] is 'change', so when the 'changethis' element changes,
  * an Ajax call is made. The form is submitted and reprocessed, and then the
- * callback is called.  In this case, the form has been automatically
+ * callback is called. In this case, the form has been automatically
  * built changing $form['replace_textfield']['#description'], so the callback
  * just returns that part of the form.
  *
@@ -188,11 +189,11 @@
  * be converted to a JSON object and returned to the client, which will then
  * iterate over the array and process it like a macro language.
  *
- * Each command item is an associative array which will be converted to a command
- * object on the JavaScript side. $command_item['command'] is the type of
- * command, e.g. 'alert' or 'replace', and will correspond to a method in the
- * Drupal.ajax[command] space. The command array may contain any other data
- * that the command needs to process, e.g. 'method', 'selector', 'settings', etc.
+ * Each command item is an associative array which will be converted to a
+ * command object on the JavaScript side. $command_item['command'] is the type
+ * of command, e.g. 'alert' or 'replace', and will correspond to a method in the
+ * Drupal.ajax[command] space. The command array may contain any other data that
+ * the command needs to process, e.g. 'method', 'selector', 'settings', etc.
  *
  * Commands are usually created with a couple of helper functions, so they
  * look like this:
@@ -222,7 +223,7 @@
  */
 
 /**
- * Render a commands array into JSON.
+ * Renders a commands array into JSON.
  *
  * @param $commands
  *   A list of macro commands generated by the use of ajax_command_*()
@@ -301,7 +302,7 @@ function ajax_render($commands = array()) {
 }
 
 /**
- * Get a form submitted via #ajax during an Ajax callback.
+ * Gets a form submitted via #ajax during an Ajax callback.
  *
  * This will load a form from the form cache used during Ajax operations. It
  * pulls the form info from $_POST.
@@ -361,6 +362,8 @@ function ajax_get_form() {
  * #ajax['path']. If processing is required that cannot be accomplished with
  * a callback, re-implement this function and set #ajax['path'] to the
  * enhanced function.
+ *
+ * @see system_menu()
  */
 function ajax_form_callback() {
   list($form, $form_state) = ajax_get_form();
@@ -396,6 +399,9 @@ function ajax_form_callback() {
  * of the page. Therefore, system_menu() sets the 'theme callback' for
  * 'system/ajax' to this function, and it is recommended that modules
  * implementing other generic Ajax paths do the same.
+ *
+ * @see system_menu()
+ * @see file_menu()
  */
 function ajax_base_page_theme() {
   if (!empty($_POST['ajax_page_state']['theme']) && !empty($_POST['ajax_page_state']['theme_token'])) {
@@ -414,7 +420,7 @@ function ajax_base_page_theme() {
 }
 
 /**
- * Package and send the result of a page callback to the browser as an Ajax response.
+ * Packages and sends the result of a page callback as an Ajax response.
  *
  * This function is the equivalent of drupal_deliver_html_page(), but for Ajax
  * requests. Like that function, it:
@@ -547,7 +553,7 @@ function ajax_prepare_response($page_callback_result) {
 }
 
 /**
- * Perform end-of-Ajax-request tasks.
+ * Performs end-of-Ajax-request tasks.
  *
  * This function is the equivalent of drupal_page_footer(), but for Ajax
  * requests.
@@ -570,7 +576,7 @@ function ajax_footer() {
 }
 
 /**
- * Form element process callback to handle #ajax.
+ * Form element processing handler for the #ajax form property.
  *
  * @param $element
  *   An associative array containing the properties of the element.
@@ -589,7 +595,7 @@ function ajax_process_form($element, &$form_state) {
 }
 
 /**
- * Add Ajax information about an element to the page to communicate with JavaScript.
+ * Adds Ajax information about an element to communicate with JavaScript.
  *
  * If #ajax['path'] is set on an element, this additional JavaScript is added
  * to the page header to attach the Ajax behaviors. See ajax.js for more
@@ -1203,4 +1209,3 @@ function ajax_command_restripe($selector) {
     'selector' => $selector,
   );
 }
-
diff --git a/includes/archiver.inc b/includes/archiver.inc
index fec053be..3ce11739 100644
--- a/includes/archiver.inc
+++ b/includes/archiver.inc
@@ -6,61 +6,63 @@
  */
 
 /**
- * Common interface for all Archiver classes.
+ * Defines the common interface for all Archiver classes.
  */
 interface ArchiverInterface {
 
   /**
-   * Constructor for a new archiver instance.
+   * Constructs a new archiver instance.
    *
    * @param $file_path
-   *   The full system path of the archive to manipulate.  Only local files
-   *   are supported.  If the file does not yet exist, it will be created if
+   *   The full system path of the archive to manipulate. Only local files
+   *   are supported. If the file does not yet exist, it will be created if
    *   appropriate.
    */
   public function __construct($file_path);
 
   /**
-   * Add the specified file or directory to the archive.
+   * Adds the specified file or directory to the archive.
    *
    * @param $file_path
    *   The full system path of the file or directory to add. Only local files
    *   and directories are supported.
+   *
    * @return ArchiverInterface
    *   The called object.
    */
   public function add($file_path);
 
   /**
-   * Remove the specified file from the archive.
+   * Removes the specified file from the archive.
    *
    * @param $path
    *   The file name relative to the root of the archive to remove.
+   *
    * @return ArchiverInterface
    *   The called object.
    */
   public function remove($path);
 
   /**
-   * Extract multiple files in the archive to the specified path.
+   * Extracts multiple files in the archive to the specified path.
    *
    * @param $path
    *   A full system path of the directory to which to extract files.
    * @param $files
    *   Optionally specify a list of files to be extracted. Files are
    *   relative to the root of the archive. If not specified, all files
-   *   in the archive will be extracted
+   *   in the archive will be extracted.
+   *
    * @return ArchiverInterface
    *   The called object.
    */
-  public function extract($path, Array $files = array());
+  public function extract($path, array $files = array());
 
   /**
-   * List all files in the archive.
+   * Lists all files in the archive.
    *
    * @return
    *   An array of file names relative to the root of the archive.
    */
   public function listContents();
 }
-
diff --git a/includes/authorize.inc b/includes/authorize.inc
index 85286041..da6918ca 100644
--- a/includes/authorize.inc
+++ b/includes/authorize.inc
@@ -6,7 +6,13 @@
  */
 
 /**
- * Build the form for choosing a FileTransfer type and supplying credentials.
+ * Form constructor for the file transfer authorization form.
+ *
+ * Allows the user to choose a FileTransfer type and supply credentials.
+ *
+ * @see authorize_filetransfer_form_validate()
+ * @see authorize_filetransfer_form_submit()
+ * @ingroup forms
  */
 function authorize_filetransfer_form($form, &$form_state) {
   global $base_url, $is_https;
@@ -127,10 +133,11 @@ function authorize_filetransfer_form($form, &$form_state) {
 }
 
 /**
- * Generate the Form API array for the settings for a given connection backend.
+ * Generates the Form API array for a given connection backend's settings.
  *
  * @param $backend
  *   The name of the backend (e.g. 'ftp', 'ssh', etc).
+ *
  * @return
  *   Form API array of connection settings for the given backend.
  *
@@ -151,7 +158,7 @@ function _authorize_filetransfer_connection_settings($backend) {
 }
 
 /**
- * Recursively fill in the default settings on a file transfer connection form.
+ * Sets the default settings on a file transfer connection form recursively.
  *
  * The default settings for the file transfer connection forms are saved in
  * the database. The settings are stored as a nested array in the case of a
@@ -165,8 +172,6 @@ function _authorize_filetransfer_connection_settings($backend) {
  *   The key for our current form element, if any.
  * @param array $defaults
  *   The default settings for the file transfer backend we're operating on.
- * @return
- *   Nothing, this function just sets $element['#default_value'] if needed.
  */
 function _authorize_filetransfer_connection_settings_set_defaults(&$element, $key, array $defaults) {
   // If we're operating on a form element which isn't a fieldset, and we have
@@ -186,9 +191,10 @@ function _authorize_filetransfer_connection_settings_set_defaults(&$element, $ke
 }
 
 /**
- * Validate callback for the filetransfer authorization form.
+ * Form validation handler for authorize_filetransfer_form().
  *
  * @see authorize_filetransfer_form()
+ * @see authorize_filetransfer_submit()
  */
 function authorize_filetransfer_form_validate($form, &$form_state) {
   // Only validate the form if we have collected all of the user input and are
@@ -218,9 +224,10 @@ function authorize_filetransfer_form_validate($form, &$form_state) {
 }
 
 /**
- * Submit callback when a file transfer is being authorized.
+ * Form submission handler for authorize_filetransfer_form().
  *
  * @see authorize_filetransfer_form()
+ * @see authorize_filetransfer_validate()
  */
 function authorize_filetransfer_form_submit($form, &$form_state) {
   global $base_url;
@@ -280,7 +287,7 @@ function authorize_filetransfer_form_submit($form, &$form_state) {
 }
 
 /**
- * Run the operation specified in $_SESSION['authorize_operation']
+ * Runs the operation specified in $_SESSION['authorize_operation'].
  *
  * @param $filetransfer
  *   The FileTransfer object to use for running the operation.
@@ -298,12 +305,13 @@ function authorize_run_operation($filetransfer) {
 }
 
 /**
- * Get a FileTransfer class for a specific transfer method and settings.
+ * Gets a FileTransfer class for a specific transfer method and settings.
  *
  * @param $backend
  *   The FileTransfer backend to get the class for.
  * @param $settings
  *   Array of settings for the FileTransfer.
+ *
  * @return
  *   An instantiated FileTransfer object for the requested method and settings,
  *   or FALSE if there was an error finding or instantiating it.
diff --git a/includes/batch.inc b/includes/batch.inc
index 727c6256..061acd4c 100644
--- a/includes/batch.inc
+++ b/includes/batch.inc
@@ -1,6 +1,5 @@
 <?php
 
-
 /**
  * @file
  * Batch processing API for processes to run in multiple HTTP requests.
@@ -21,6 +20,7 @@
  * @param $id
  *   The ID of the batch to load. When a progressive batch is being processed,
  *   the relevant ID is found in $_REQUEST['id'].
+ *
  * @return
  *   An array representing the batch, or FALSE if no batch was found.
  */
@@ -36,7 +36,7 @@ function batch_load($id) {
 }
 
 /**
- * State-based dispatcher for the batch processing page.
+ * Renders the batch processing page based on the current state of the batch.
  *
  * @see _batch_shutdown()
  */
@@ -94,7 +94,7 @@ function _batch_page() {
 }
 
 /**
- * Initialize the batch processing.
+ * Initializes the batch processing.
  *
  * JavaScript-enabled clients are identified by the 'has_js' cookie set in
  * drupal.js. If no JavaScript-enabled page has been visited during the current
@@ -110,7 +110,7 @@ function _batch_start() {
 }
 
 /**
- * Output a batch processing page with JavaScript support.
+ * Outputs a batch processing page with JavaScript support.
  *
  * This initializes the batch and error messages. Note that in JavaScript-based
  * processing, the batch processing page is displayed only once and updated via
@@ -144,7 +144,7 @@ function _batch_progress_page_js() {
 }
 
 /**
- * Do one execution pass in JavaScript-mode and return progress to the browser.
+ * Does one execution pass with JavaScript and returns progress to the browser.
  *
  * @see _batch_progress_page_js()
  * @see _batch_process()
@@ -164,7 +164,7 @@ function _batch_do() {
 }
 
 /**
- * Output a batch processing page without JavaScript support.
+ * Outputs a batch processing page without JavaScript support.
  *
  * @see _batch_process()
  */
@@ -228,7 +228,7 @@ function _batch_progress_page_nojs() {
 }
 
 /**
- * Process sets in a batch.
+ * Processes sets in a batch.
  *
  * If the batch was marked for progressive execution (default), this executes as
  * many operations in batch sets until an execution time of 1 second has been
@@ -370,7 +370,7 @@ function _batch_process() {
 }
 
 /**
- * Helper function for _batch_process(): returns the formatted percentage.
+ * Formats the percent completion for a batch set.
  *
  * @param $total
  *   The total number of operations.
@@ -379,11 +379,14 @@ function _batch_process() {
  *   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%"
  *   until we are finished, but we also never print more decimal places than
  *   are meaningful.
+ *
+ * @see _batch_process()
  */
 function _batch_api_percentage($total, $current) {
   if (!$total || $total == $current) {
@@ -410,7 +413,7 @@ function _batch_api_percentage($total, $current) {
 }
 
 /**
- * Return the batch set being currently processed.
+ * Returns the batch set being currently processed.
  */
 function &_batch_current_set() {
   $batch = &batch_get();
@@ -418,7 +421,7 @@ function &_batch_current_set() {
 }
 
 /**
- * Retrieve the next set in a batch.
+ * Retrieves the next set in a batch.
  *
  * If there is a subsequent set in this batch, assign it as the new set to
  * process and execute its form submit handler (if defined), which may add
@@ -442,7 +445,7 @@ function _batch_next_set() {
 }
 
 /**
- * End the batch processing.
+ * Ends the batch processing.
  *
  * Call the 'finished' callback of each batch set to allow custom handling of
  * the results and resolve page redirection.
@@ -521,7 +524,10 @@ function _batch_finished() {
 }
 
 /**
- * Shutdown function; store the current batch data for the next request.
+ * Shutdown function: Stores the current batch data for the next request.
+ *
+ * @see _batch_page()
+ * @see drupal_register_shutdown_function()
  */
 function _batch_shutdown() {
   if ($batch = batch_get()) {
@@ -531,4 +537,3 @@ function _batch_shutdown() {
       ->execute();
   }
 }
-
diff --git a/includes/batch.queue.inc b/includes/batch.queue.inc
index 84648369..ed290ee7 100644
--- a/includes/batch.queue.inc
+++ b/includes/batch.queue.inc
@@ -1,24 +1,30 @@
 <?php
 
-
 /**
  * @file
  * Queue handlers used by the Batch API.
  *
- * Those implementations:
- * - ensure FIFO ordering,
- * - let an item be repeatedly claimed until it is actually deleted (no notion
- *   of lease time or 'expire' date), to allow multipass operations.
+ * These implementations:
+ * - Ensure FIFO ordering.
+ * - Allow an item to be repeatedly claimed until it is actually deleted (no
+ *   notion of lease time or 'expire' date), to allow multipass operations.
  */
 
 /**
- * Batch queue implementation.
+ * Defines a batch queue.
  *
  * Stale items from failed batches are cleaned from the {queue} table on cron
  * using the 'created' date.
  */
 class BatchQueue extends SystemQueue {
 
+  /**
+   * Overrides SystemQueue::claimItem().
+   *
+   * Unlike SystemQueue::claimItem(), this method provides a default lease
+   * time of 0 (no expiration) instead of 30. This allows the item to be
+   * claimed repeatedly until it is deleted.
+   */
   public function claimItem($lease_time = 0) {
     $item = db_query_range('SELECT data, item_id FROM {queue} q WHERE name = :name ORDER BY item_id ASC', 0, 1, array(':name' => $this->name))->fetchObject();
     if ($item) {
@@ -29,9 +35,9 @@ class BatchQueue extends SystemQueue {
   }
 
   /**
-   * Retrieve all remaining items in the queue.
+   * Retrieves all remaining items in the queue.
    *
-   * This is specific to Batch API and is not part of the DrupalQueueInterface,
+   * This is specific to Batch API and is not part of the DrupalQueueInterface.
    */
   public function getAllItems() {
     $result = array();
@@ -44,10 +50,17 @@ class BatchQueue extends SystemQueue {
 }
 
 /**
- * Batch queue implementation used for non-progressive batches.
+ * Defines a batch queue for non-progressive batches.
  */
 class BatchMemoryQueue extends MemoryQueue {
 
+  /**
+   * Overrides MemoryQueue::claimItem().
+   *
+   * Unlike MemoryQueue::claimItem(), this method provides a default lease
+   * time of 0 (no expiration) instead of 30. This allows the item to be
+   * claimed repeatedly until it is deleted.
+   */
   public function claimItem($lease_time = 0) {
     if (!empty($this->queue)) {
       reset($this->queue);
@@ -57,9 +70,9 @@ class BatchMemoryQueue extends MemoryQueue {
   }
 
   /**
-   * Retrieve all remaining items in the queue.
+   * Retrieves all remaining items in the queue.
    *
-   * This is specific to Batch API and is not part of the DrupalQueueInterface,
+   * This is specific to Batch API and is not part of the DrupalQueueInterface.
    */
   public function getAllItems() {
     $result = array();
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 2e6e7d5a..d60bf296 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
 /**
  * The current system version.
  */
-define('VERSION', '7.10');
+define('VERSION', '7.12');
 
 /**
  * Core API compatibility.
@@ -43,9 +43,9 @@ define('CACHE_TEMPORARY', -1);
  * Logging severity levels as defined in RFC 3164.
  *
  * The WATCHDOG_* constant definitions correspond to the logging severity levels
- * defined in RFC 3164, section 4.1.1.  PHP supplies predefined LOG_* constants
+ * defined in RFC 3164, section 4.1.1. PHP supplies predefined LOG_* constants
  * for use in the syslog() function, but their values on Windows builds do not
- * correspond to RFC 3164.  The associated PHP bug report was closed with the
+ * correspond to RFC 3164. The associated PHP bug report was closed with the
  * comment, "And it's also not a bug, as Windows just have less log levels,"
  * and "So the behavior you're seeing is perfectly normal."
  *
@@ -137,8 +137,7 @@ define('DRUPAL_BOOTSTRAP_PAGE_HEADER', 5);
 define('DRUPAL_BOOTSTRAP_LANGUAGE', 6);
 
 /**
- * Final bootstrap phase: Drupal is fully loaded; validate and fix
- * input data.
+ * Final bootstrap phase: Drupal is fully loaded; validate and fix input data.
  */
 define('DRUPAL_BOOTSTRAP_FULL', 7);
 
@@ -153,8 +152,9 @@ define('DRUPAL_ANONYMOUS_RID', 1);
 define('DRUPAL_AUTHENTICATED_RID', 2);
 
 /**
- * The number of bytes in a kilobyte. For more information, visit
- * http://en.wikipedia.org/wiki/Kilobyte.
+ * The number of bytes in a kilobyte.
+ *
+ * For more information, visit http://en.wikipedia.org/wiki/Kilobyte.
  */
 define('DRUPAL_KILOBYTE', 1024);
 
@@ -289,12 +289,12 @@ abstract class DrupalCacheArray implements ArrayAccess {
   /**
    * A cid to pass to cache_set() and cache_get().
    */
-  private $cid;
+  protected $cid;
 
   /**
    * A bin to pass to cache_set() and cache_get().
    */
-  private $bin;
+  protected $bin;
 
   /**
    * An array of keys to add to the cache at the end of the request.
@@ -307,7 +307,7 @@ abstract class DrupalCacheArray implements ArrayAccess {
   protected $storage = array();
 
   /**
-   * Constructor.
+   * Constructs a DrupalCacheArray object.
    *
    * @param $cid
    *   The cid for the array being cached.
@@ -323,10 +323,16 @@ abstract class DrupalCacheArray implements ArrayAccess {
     }
   }
 
+  /**
+   * Implements ArrayAccess::offsetExists().
+   */
   public function offsetExists($offset) {
     return $this->offsetGet($offset) !== NULL;
   }
 
+  /**
+   * Implements ArrayAccess::offsetGet().
+   */
   public function offsetGet($offset) {
     if (isset($this->storage[$offset]) || array_key_exists($offset, $this->storage)) {
       return $this->storage[$offset];
@@ -336,10 +342,16 @@ abstract class DrupalCacheArray implements ArrayAccess {
     }
   }
 
+  /**
+   * Implements ArrayAccess::offsetSet().
+   */
   public function offsetSet($offset, $value) {
     $this->storage[$offset] = $value;
   }
 
+  /**
+   * Implements ArrayAccess::offsetUnset().
+   */
   public function offsetUnset($offset) {
     unset($this->storage[$offset]);
   }
@@ -379,32 +391,31 @@ abstract class DrupalCacheArray implements ArrayAccess {
   abstract protected function resolveCacheMiss($offset);
 
   /**
-   * Immediately write a value to the persistent cache.
+   * Writes a value to the persistent cache immediately.
    *
-   * @param $cid
-   *   The cache ID.
-   * @param $bin
-   *   The cache bin.
    * @param $data
    *   The data to write to the persistent cache.
    * @param $lock
    *   Whether to acquire a lock before writing to cache.
    */
-  protected function set($cid, $data, $bin, $lock = TRUE) {
+  protected function set($data, $lock = TRUE) {
     // Lock cache writes to help avoid stampedes.
     // To implement locking for cache misses, override __construct().
-    $lock_name = $cid . ':' . $bin;
+    $lock_name = $this->cid . ':' . $this->bin;
     if (!$lock || lock_acquire($lock_name)) {
-      if ($cached = cache_get($cid, $bin)) {
+      if ($cached = cache_get($this->cid, $this->bin)) {
         $data = $cached->data + $data;
       }
-      cache_set($cid, $data, $bin);
+      cache_set($this->cid, $data, $this->bin);
       if ($lock) {
         lock_release($lock_name);
       }
     }
   }
 
+  /**
+   * Destructs the DrupalCacheArray object.
+   */
   public function __destruct() {
     $data = array();
     foreach ($this->keysToPersist as $offset => $persist) {
@@ -413,14 +424,16 @@ abstract class DrupalCacheArray implements ArrayAccess {
       }
     }
     if (!empty($data)) {
-      $this->set($this->cid, $data, $this->bin);
+      $this->set($data);
     }
   }
 }
 
 /**
- * Start the timer with the specified name. If you start and stop the same
- * timer multiple times, the measured intervals will be accumulated.
+ * Starts the timer with the specified name.
+ *
+ * If you start and stop the same timer multiple times, the measured intervals
+ * will be accumulated.
  *
  * @param $name
  *   The name of the timer.
@@ -433,7 +446,7 @@ function timer_start($name) {
 }
 
 /**
- * Read the current timer value without stopping the timer.
+ * Reads the current timer value without stopping the timer.
  *
  * @param $name
  *   The name of the timer.
@@ -457,7 +470,7 @@ function timer_read($name) {
 }
 
 /**
- * Stop the timer with the specified name.
+ * Stops the timer with the specified name.
  *
  * @param $name
  *   The name of the timer.
@@ -600,7 +613,7 @@ function conf_path($require_settings = TRUE, $reset = FALSE) {
 }
 
 /**
- * Set appropriate server variables needed for command line scripts to work.
+ * Sets appropriate server variables needed for command line scripts to work.
  *
  * This function can be called by command line scripts before bootstrapping
  * Drupal, to ensure that the page loads with the desired server parameters.
@@ -662,7 +675,7 @@ function drupal_override_server_variables($variables = array()) {
 }
 
 /**
- * Initialize PHP environment.
+ * Initializes the PHP environment.
  */
 function drupal_environment_initialize() {
   if (!isset($_SERVER['HTTP_REFERER'])) {
@@ -721,7 +734,7 @@ function drupal_environment_initialize() {
 }
 
 /**
- * Validate that a hostname (for example $_SERVER['HTTP_HOST']) is safe.
+ * Validates that a hostname (for example $_SERVER['HTTP_HOST']) is safe.
  *
  * @return
  *  TRUE if only containing valid characters, or FALSE otherwise.
@@ -731,8 +744,7 @@ function drupal_valid_http_host($host) {
 }
 
 /**
- * Loads the configuration and sets the base URL, cookie domain, and
- * session name correctly.
+ * Sets the base URL, cookie domain, and session name from configuration.
  */
 function drupal_settings_initialize() {
   global $base_url, $base_path, $base_root;
@@ -824,9 +836,10 @@ function drupal_settings_initialize() {
 }
 
 /**
- * Returns and optionally sets the filename for a system item (module,
- * theme, etc.). The filename, whether provided, cached, or retrieved
- * from the database, is only returned if the file exists.
+ * Returns and optionally sets the filename for a system resource.
+ *
+ * The filename, whether provided, cached, or retrieved from the database, is
+ * only returned if the file exists.
  *
  * This function plays a key role in allowing Drupal's resources (modules
  * and themes) to be located in different places depending on a site's
@@ -928,11 +941,11 @@ function drupal_get_filename($type, $name, $filename = NULL) {
 }
 
 /**
- * Load the persistent variable table.
+ * Loads the persistent variable table.
  *
  * The variable table is composed of values that have been saved in the table
- * with variable_set() as well as those explicitly specified in the configuration
- * file.
+ * with variable_set() as well as those explicitly specified in the
+ * configuration file.
  */
 function variable_initialize($conf = array()) {
   // NOTE: caching the variables improves performance by 20% when serving
@@ -1039,7 +1052,7 @@ function variable_del($name) {
 }
 
 /**
- * Retrieve the current page from the cache.
+ * Retrieves the current page from the cache.
  *
  * Note: we do not serve cached pages to authenticated users, or to anonymous
  * users when $_SESSION is non-empty. $_SESSION may contain status messages
@@ -1071,7 +1084,7 @@ function drupal_page_get_cache($check_only = FALSE) {
 }
 
 /**
- * Determine the cacheability of the current page.
+ * Determines the cacheability of the current page.
  *
  * @param $allow_caching
  *   Set to FALSE if you want to prevent this page to get cached.
@@ -1090,7 +1103,7 @@ function drupal_page_is_cacheable($allow_caching = NULL) {
 }
 
 /**
- * Invoke a bootstrap hook in all bootstrap modules that implement it.
+ * Invokes a bootstrap hook in all bootstrap modules that implement it.
  *
  * @param $hook
  *   The name of the bootstrap hook to invoke.
@@ -1112,8 +1125,9 @@ function bootstrap_invoke_all($hook) {
 }
 
 /**
- * Includes a file with the provided type and name. This prevents
- * including a theme, engine, module, etc., more than once.
+ * Includes a file with the provided type and name.
+ *
+ * This prevents including a theme, engine, module, etc., more than once.
  *
  * @param $type
  *   The type of item to load (i.e. theme, theme_engine, module).
@@ -1145,7 +1159,7 @@ function drupal_load($type, $name) {
 }
 
 /**
- * Set an HTTP response header for the current page.
+ * Sets an HTTP response header for the current page.
  *
  * Note: When sending a Content-Type header, always include a 'charset' type,
  * too. This is necessary to avoid security bugs (e.g. UTF-7 XSS).
@@ -1181,11 +1195,12 @@ function drupal_add_http_header($name, $value, $append = FALSE) {
 }
 
 /**
- * Get the HTTP response headers for the current page.
+ * Gets the HTTP response headers for the current page.
  *
  * @param $name
  *   An HTTP header name. If omitted, all headers are returned as name/value
  *   pairs. If an array value is FALSE, the header has been unset.
+ *
  * @return
  *   A string containing the header value, or FALSE if the header has been set,
  *   or NULL if the header has not been set.
@@ -1202,6 +1217,8 @@ function drupal_get_http_header($name = NULL) {
 }
 
 /**
+ * Sets the preferred name for the HTTP header.
+ *
  * Header names are case-insensitive, but for maximum compatibility they should
  * follow "common form" (see RFC 2617, section 4.2).
  */
@@ -1215,9 +1232,10 @@ function _drupal_set_preferred_header_name($name = NULL) {
 }
 
 /**
- * Send the HTTP response headers previously set using drupal_add_http_header().
- * Add default headers, unless they have been replaced or unset using
- * drupal_add_http_header().
+ * Sends the HTTP response headers that were previously set, adding defaults.
+ *
+ * Headers are set in drupal_add_http_header(). Default headers are not set
+ * if they have been replaced or unset using drupal_add_http_header().
  *
  * @param $default_headers
  *   An array of headers as name/value pairs.
@@ -1252,7 +1270,7 @@ function drupal_send_headers($default_headers = array(), $only_default = FALSE)
 }
 
 /**
- * Set HTTP headers in preparation for a page response.
+ * Sets HTTP headers in preparation for a page response.
  *
  * Authenticated users are always given a 'no-cache' header, and will fetch a
  * fresh page on every request. This prevents authenticated users from seeing
@@ -1295,7 +1313,7 @@ function drupal_page_header() {
 }
 
 /**
- * Set HTTP headers in preparation for a cached page response.
+ * Sets HTTP headers in preparation for a cached page response.
  *
  * The headers allow as much as possible in proxies and browsers without any
  * particular knowledge about the pages. Modules can override these headers
@@ -1400,7 +1418,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
 }
 
 /**
- * Define the critical hooks that force modules to always be loaded.
+ * Defines the critical hooks that force modules to always be loaded.
  */
 function bootstrap_hooks() {
   return array('boot', 'exit', 'watchdog', 'language_init');
@@ -1453,10 +1471,10 @@ function drupal_unpack($obj, $field = 'data') {
  * $text = t("@name's blog", array('@name' => format_username($account)));
  * @endcode
  * Basically, you can put variables like @name into your string, and t() will
- * substitute their sanitized values at translation time (see $args below or
- * the Localization API pages referenced above for details). Translators can
- * then rearrange the string as necessary for the language (e.g., in Spanish,
- * it might be "blog de @name").
+ * substitute their sanitized values at translation time. (See the
+ * Localization API pages referenced above and the documentation of
+ * format_string() for details.) Translators can then rearrange the string as
+ * necessary for the language (e.g., in Spanish, it might be "blog de @name").
  *
  * During the Drupal installation phase, some resources used by t() wil not be
  * available to code that needs localization. See st() and get_t() for
@@ -1465,8 +1483,9 @@ function drupal_unpack($obj, $field = 'data') {
  * @param $string
  *   A string containing the English string to translate.
  * @param $args
- *   An associative array of replacements to make after translation.
- *   See format_string().
+ *   An associative array of replacements to make after translation. Based
+ *   on the first character of the key, the value is escaped and/or themed.
+ *   See format_string() for details.
  * @param $options
  *   An associative array of additional options, with the following elements:
  *   - 'langcode' (defaults to the current language): The language code to
@@ -1479,6 +1498,7 @@ function drupal_unpack($obj, $field = 'data') {
  *
  * @see st()
  * @see get_t()
+ * @see format_string()
  * @ingroup sanitization
  */
 function t($string, array $args = array(), array $options = array()) {
@@ -1517,7 +1537,7 @@ function t($string, array $args = array(), array $options = array()) {
 }
 
 /**
- * Replace placeholders with sanitized values in a string.
+ * Replaces placeholders with sanitized values in a string.
  *
  * @param $string
  *   A string containing placeholders.
@@ -1559,7 +1579,7 @@ function format_string($string, array $args = array()) {
 }
 
 /**
- * Encode special characters in a plain-text string for display as HTML.
+ * Encodes special characters in a plain-text string for display as HTML.
  *
  * Also validates strings as UTF-8 to prevent cross site scripting attacks on
  * Internet Explorer 6.
@@ -1598,6 +1618,7 @@ function check_plain($text) {
  *
  * @param $text
  *   The text to check.
+ *
  * @return
  *   TRUE if the text is valid UTF-8, FALSE if not.
  */
@@ -1639,7 +1660,7 @@ function request_uri() {
 }
 
 /**
- * Log an exception.
+ * Logs an exception.
  *
  * This is a wrapper function for watchdog() which automatically decodes an
  * exception.
@@ -1680,7 +1701,7 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
 }
 
 /**
- * Log a system message.
+ * Logs a system message.
  *
  * @param $type
  *   The category to which this message belongs. Can be any string, but the
@@ -1740,7 +1761,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO
 }
 
 /**
- * Set a message which reflects the status of the performed operation.
+ * Sets a message which reflects the status of the performed operation.
  *
  * If the function is called with no arguments, this function returns all set
  * messages without clearing them.
@@ -1776,12 +1797,13 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) {
 }
 
 /**
- * Return all messages that have been set.
+ * Returns all messages that have been set.
  *
  * @param $type
  *   (optional) Only return messages of this type.
  * @param $clear_queue
  *   (optional) Set to FALSE if you do not want to clear the messages queue
+ *
  * @return
  *   An associative array, the key is the message type, the value an array
  *   of messages. If the $type parameter is passed, you get only that type,
@@ -1809,7 +1831,9 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
 }
 
 /**
- * Get the title of the current page, for display on the page and in the title bar.
+ * Gets the title of the current page.
+ *
+ * The title is displayed on the page and in the title bar.
  *
  * @return
  *   The current page's title.
@@ -1826,7 +1850,9 @@ function drupal_get_title() {
 }
 
 /**
- * Set the title of the current page, for display on the page and in the title bar.
+ * Sets the title of the current page.
+ *
+ * The title is displayed on the page and in the title bar.
  *
  * @param $title
  *   Optional string value to assign to the page title; or if set to NULL
@@ -1851,7 +1877,7 @@ function drupal_set_title($title = NULL, $output = CHECK_PLAIN) {
 }
 
 /**
- * Check to see if an IP address has been blocked.
+ * Checks to see if an IP address has been blocked.
  *
  * Blocked IP addresses are stored in the database by default. However for
  * performance reasons we allow an override in settings.php. This allows us
@@ -1860,6 +1886,7 @@ function drupal_set_title($title = NULL, $output = CHECK_PLAIN) {
  *
  * @param $ip
  *   IP address to check.
+ *
  * @return bool
  *   TRUE if access is denied, FALSE if access is allowed.
  */
@@ -1885,7 +1912,7 @@ function drupal_is_denied($ip) {
 }
 
 /**
- * Handle denied users.
+ * Handles denied users.
  *
  * @param $ip
  *   IP address to check. Prints a message and exits if access is denied.
@@ -1904,7 +1931,8 @@ function drupal_block_denied($ip) {
  *
  * This function is better than simply calling mt_rand() or any other built-in
  * PHP function because it can return a long string of bytes (compared to < 4
- * bytes normally from mt_rand()) and uses the best available pseudo-random source.
+ * bytes normally from mt_rand()) and uses the best available pseudo-random
+ * source.
  *
  * @param $count
  *   The number of characters (bytes) to return in the string.
@@ -1951,7 +1979,7 @@ function drupal_random_bytes($count)  {
 }
 
 /**
- * Calculate a base-64 encoded, URL-safe sha-256 hmac.
+ * Calculates a base-64 encoded, URL-safe sha-256 hmac.
  *
  * @param $data
  *   String to be validated with the hmac.
@@ -1969,7 +1997,7 @@ function drupal_hmac_base64($data, $key) {
 }
 
 /**
- * Calculate a base-64 encoded, URL-safe sha-256 hash.
+ * Calculates a base-64 encoded, URL-safe sha-256 hash.
  *
  * @param $data
  *   String to be hashed.
@@ -2012,7 +2040,8 @@ function drupal_hash_base64($data) {
  * @see drupal_array_merge_deep_array()
  */
 function drupal_array_merge_deep() {
-  return drupal_array_merge_deep_array(func_get_args());
+  $args = func_get_args();
+  return drupal_array_merge_deep_array($args);
 }
 
 /**
@@ -2073,20 +2102,22 @@ function drupal_anonymous_user() {
 }
 
 /**
- * A string describing a phase of Drupal to load. Each phase adds to the
- * previous one, so invoking a later phase automatically runs the earlier
- * phases too. The most important usage is that if you want to access the
- * Drupal database from a script without loading anything else, you can
- * include bootstrap.inc, and call drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE).
+ * Ensures Drupal is bootstrapped to the specified phase.
+ *
+ * The bootstrap phase is an integer constant identifying a phase of Drupal
+ * to load. Each phase adds to the previous one, so invoking a later phase
+ * automatically runs the earlier phases as well. To access the Drupal
+ * database from a script without loading anything else, include bootstrap.inc
+ * and call drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE).
  *
  * @param $phase
  *   A constant. Allowed values are the DRUPAL_BOOTSTRAP_* constants.
  * @param $new_phase
  *   A boolean, set to FALSE if calling drupal_bootstrap from inside a
  *   function called from drupal_bootstrap (recursion).
+ *
  * @return
  *   The most recently completed phase.
- *
  */
 function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
   // Not drupal_static(), because does not depend on any run-time information.
@@ -2165,7 +2196,7 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
 }
 
 /**
- * Return the time zone of the current user.
+ * Returns the time zone of the current user.
  */
 function drupal_get_user_timezone() {
   global $user;
@@ -2180,7 +2211,7 @@ function drupal_get_user_timezone() {
 }
 
 /**
- * Custom PHP error handler.
+ * Provides custom PHP error handling.
  *
  * @param $error_level
  *   The level of the error raised.
@@ -2191,7 +2222,8 @@ function drupal_get_user_timezone() {
  * @param $line
  *   The line number the error was raised at.
  * @param $context
- *   An array that points to the active symbol table at the point the error occurred.
+ *   An array that points to the active symbol table at the point the error
+ *   occurred.
  */
 function _drupal_error_handler($error_level, $message, $filename, $line, $context) {
   require_once DRUPAL_ROOT . '/includes/errors.inc';
@@ -2199,7 +2231,7 @@ function _drupal_error_handler($error_level, $message, $filename, $line, $contex
 }
 
 /**
- * Custom PHP exception handler.
+ * Provides custom PHP exception handling.
  *
  * Uncaught exceptions are those not enclosed in a try/catch block. They are
  * always fatal: the execution of the script will stop as soon as the exception
@@ -2227,7 +2259,7 @@ function _drupal_exception_handler($exception) {
 }
 
 /**
- * Bootstrap configuration: Setup script environment and load settings.php.
+ * Sets up the script environment and loads settings.php.
  */
 function _drupal_bootstrap_configuration() {
   // Set the Drupal custom error handler.
@@ -2242,7 +2274,7 @@ function _drupal_bootstrap_configuration() {
 }
 
 /**
- * Bootstrap page cache: Try to serve a page from cache.
+ * Attempts to serve a page from the cache.
  */
 function _drupal_bootstrap_page_cache() {
   global $user;
@@ -2298,7 +2330,7 @@ function _drupal_bootstrap_page_cache() {
 }
 
 /**
- * Bootstrap database: Initialize database system and register autoload functions.
+ * Initializes the database system and registers autoload functions.
  */
 function _drupal_bootstrap_database() {
   // Redirect the user to the installation script if Drupal has not been
@@ -2350,7 +2382,7 @@ function _drupal_bootstrap_database() {
 }
 
 /**
- * Bootstrap variables: Load system variables and all enabled bootstrap modules.
+ * Loads system variables and all enabled bootstrap modules.
  */
 function _drupal_bootstrap_variables() {
   global $conf;
@@ -2367,7 +2399,7 @@ function _drupal_bootstrap_variables() {
 }
 
 /**
- * Bootstrap page header: Invoke hook_boot(), initialize locking system, and send default HTTP headers.
+ * Invokes hook_boot(), initializes locking system, and sends HTTP headers.
  */
 function _drupal_bootstrap_page_header() {
   bootstrap_invoke_all('boot');
@@ -2390,8 +2422,7 @@ function drupal_get_bootstrap_phase() {
 }
 
 /**
- * Checks the current User-Agent string to see if this is an internal request
- * from SimpleTest. If so, returns the test prefix for this test.
+ * Returns the test prefix if this is an internal request from SimpleTest.
  *
  * @return
  *   Either the simpletest prefix (the string "simpletest" followed by any
@@ -2427,7 +2458,7 @@ function drupal_valid_test_ua() {
 }
 
 /**
- * Generate a user agent string with a HMAC and timestamp for simpletest.
+ * Generates a user agent string with a HMAC and timestamp for simpletest.
  */
 function drupal_generate_test_ua($prefix) {
   global $drupal_hash_salt;
@@ -2487,7 +2518,7 @@ function drupal_fast_404() {
 }
 
 /**
- * Return TRUE if a Drupal installation is currently being attempted.
+ * Returns TRUE if a Drupal installation is currently being attempted.
  */
 function drupal_installation_attempted() {
   return defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'install';
@@ -2530,7 +2561,7 @@ function get_t() {
 }
 
 /**
- * Initialize all the defined language types.
+ * Initializes all the defined language types.
  */
 function drupal_language_initialize() {
   $types = language_types();
@@ -2555,7 +2586,7 @@ function drupal_language_initialize() {
 }
 
 /**
- * The built-in language types.
+ * Returns a list of the built-in language types.
  *
  * @return
  *   An array of key-values pairs where the key is the language type and the
@@ -2570,7 +2601,7 @@ function drupal_language_types() {
 }
 
 /**
- * Return true if there is more than one language enabled.
+ * Returns TRUE if there is more than one language enabled.
  */
 function drupal_multilingual() {
   // The "language_count" variable stores the number of enabled languages to
@@ -2580,7 +2611,7 @@ function drupal_multilingual() {
 }
 
 /**
- * Return an array of the available language types.
+ * Returns an array of the available language types.
  */
 function language_types() {
   return array_keys(variable_get('language_types', drupal_language_types()));
@@ -2637,7 +2668,7 @@ function language_list($field = 'language') {
 }
 
 /**
- * Default language used on the site
+ * Returns the default language used on the site
  *
  * @param $property
  *   Optional property of the language object to return
@@ -2707,16 +2738,16 @@ function request_path() {
 }
 
 /**
- * Return a component of the current Drupal path.
+ * Returns a component of the current Drupal path.
  *
  * When viewing a page at the path "admin/structure/types", for example, arg(0)
  * returns "admin", arg(1) returns "structure", and arg(2) returns "types".
  *
- * Avoid use of this function where possible, as resulting code is hard to read.
- * In menu callback functions, attempt to use named arguments. See the explanation
- * in menu.inc for how to construct callbacks that take arguments. When attempting
- * to use this function to load an element from the current path, e.g. loading the
- * node on a node page, please use menu_get_object() instead.
+ * Avoid use of this function where possible, as resulting code is hard to
+ * read. In menu callback functions, attempt to use named arguments. See the
+ * explanation in menu.inc for how to construct callbacks that take arguments.
+ * When attempting to use this function to load an element from the current
+ * path, e.g. loading the node on a node page, use menu_get_object() instead.
  *
  * @param $index
  *   The index of the component, where each component is separated by a '/'
@@ -2756,6 +2787,8 @@ function arg($index = NULL, $path = NULL) {
 }
 
 /**
+ * Returns the IP address of the client machine.
+ *
  * If Drupal is behind a reverse proxy, we use the X-Forwarded-For header
  * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of
  * the proxy server, and not the client's. The actual header name can be
@@ -2805,7 +2838,7 @@ function ip_address() {
  */
 
 /**
- * Get the schema definition of a table, or the whole database schema.
+ * Gets the schema definition of a table, or the whole database schema.
  *
  * The returned schema will include any modifications made by any
  * module that implements hook_schema_alter().
@@ -2841,11 +2874,17 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
  */
 class SchemaCache extends DrupalCacheArray {
 
+  /**
+   * Constructs a SchemaCache object.
+   */
   public function __construct() {
     // Cache by request method.
     parent::__construct('schema:runtime:' . ($_SERVER['REQUEST_METHOD'] == 'GET'), 'cache');
   }
 
+  /**
+   * Overrides DrupalCacheArray::resolveCacheMiss().
+   */
   protected function resolveCacheMiss($offset) {
     $complete_schema = drupal_get_complete_schema();
     $value = isset($complete_schema[$offset]) ? $complete_schema[$offset] :  NULL;
@@ -2856,7 +2895,7 @@ class SchemaCache extends DrupalCacheArray {
 }
 
 /**
- * Get the whole database schema.
+ * Gets the whole database schema.
  *
  * The returned schema will include any modifications made by any
  * module that implements hook_schema_alter().
@@ -2926,13 +2965,14 @@ function drupal_get_complete_schema($rebuild = FALSE) {
  */
 
 /**
- * Confirm that an interface is available.
+ * Confirms that an interface is available.
  *
  * This function is rarely called directly. Instead, it is registered as an
  * spl_autoload()  handler, and PHP calls it for us when necessary.
  *
  * @param $interface
  *   The name of the interface to check or load.
+ *
  * @return
  *   TRUE if the interface is currently available, FALSE otherwise.
  */
@@ -2941,13 +2981,14 @@ function drupal_autoload_interface($interface) {
 }
 
 /**
- * Confirm that a class is available.
+ * Confirms that a class is available.
  *
  * This function is rarely called directly. Instead, it is registered as an
  * spl_autoload()  handler, and PHP calls it for us when necessary.
  *
  * @param $class
  *   The name of the class to check or load.
+ *
  * @return
  *   TRUE if the class is currently available, FALSE otherwise.
  */
@@ -2956,7 +2997,7 @@ function drupal_autoload_class($class) {
 }
 
 /**
- * Helper to check for a resource in the registry.
+ * Checks for a resource in the registry.
  *
  * @param $type
  *   The type of resource we are looking up, or one of the constants
@@ -2965,6 +3006,7 @@ function drupal_autoload_class($class) {
  * @param $name
  *   The name of the resource, or NULL if either of the REGISTRY_* constants
  *   is passed in.
+ *
  * @return
  *   TRUE if the resource was found, FALSE if not.
  *   NULL if either of the REGISTRY_* constants is passed in as $type.
@@ -3036,7 +3078,7 @@ function _registry_check_code($type, $name = NULL) {
 }
 
 /**
- * Rescan all enabled modules and rebuild the registry.
+ * Rescans all enabled modules and rebuilds the registry.
  *
  * Rescans all code in modules or includes directories, storing the location of
  * each interface or class in the database.
@@ -3047,7 +3089,7 @@ function registry_rebuild() {
 }
 
 /**
- * Update the registry based on the latest files listed in the database.
+ * Updates the registry based on the latest files listed in the database.
  *
  * This function should be used when system_rebuild_module_data() does not need
  * to be called, because it is already known that the list of files in the
@@ -3065,7 +3107,7 @@ function registry_update() {
  */
 
 /**
- * Central static variable storage.
+ * Provides central static variable storage.
  *
  * All functions requiring a static variable to persist or cache data within
  * a single page request are encouraged to use this function unless it is
@@ -3216,7 +3258,7 @@ function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
 }
 
 /**
- * Reset one or all centrally stored static variable(s).
+ * Resets one or all centrally stored static variable(s).
  *
  * @param $name
  *   Name of the static variable to reset. Omit to reset all variables.
@@ -3226,7 +3268,7 @@ function drupal_static_reset($name = NULL) {
 }
 
 /**
- * Detect whether the current script is running in a command-line environment.
+ * Detects whether the current script is running in a command-line environment.
  */
 function drupal_is_cli() {
   return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
@@ -3234,7 +3276,8 @@ function drupal_is_cli() {
 
 /**
  * Formats text for emphasized display in a placeholder inside a sentence.
- * Used automatically by t().
+ *
+ * Used automatically by format_string().
  *
  * @param $text
  *   The text to format (plain-text).
@@ -3247,7 +3290,7 @@ function drupal_placeholder($text) {
 }
 
 /**
- * Register a function for execution on shutdown.
+ * Registers a function for execution on shutdown.
  *
  * Wrapper for register_shutdown_function() that catches thrown exceptions to
  * avoid "Exception thrown without a stack frame in Unknown".
@@ -3282,7 +3325,7 @@ function &drupal_register_shutdown_function($callback = NULL) {
 }
 
 /**
- * Internal function used to execute registered shutdown functions.
+ * Executes registered shutdown functions.
  */
 function _drupal_shutdown_function() {
   $callbacks = &drupal_register_shutdown_function();
diff --git a/includes/cache-install.inc b/includes/cache-install.inc
index d9bb0f92..9e0dd01d 100644
--- a/includes/cache-install.inc
+++ b/includes/cache-install.inc
@@ -6,7 +6,7 @@
  */
 
 /**
- * A stub cache implementation to be used during the installation process.
+ * Defines a stub cache implementation to be used during installation.
  *
  * The stub implementation is needed when database access is not yet available.
  * Because Drupal's caching system never requires that cached data be present,
@@ -15,17 +15,30 @@
  * normal operations would have a negative impact on performance.
  */
 class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterface {
+
+  /**
+   * Overrides DrupalDatabaseCache::get().
+   */
   function get($cid) {
     return FALSE;
   }
 
+  /**
+   * Overrides DrupalDatabaseCache::getMultiple().
+   */
   function getMultiple(&$cids) {
     return array();
   }
 
+  /**
+   * Overrides DrupalDatabaseCache::set().
+   */
   function set($cid, $data, $expire = CACHE_PERMANENT) {
   }
 
+  /**
+   * Overrides DrupalDatabaseCache::clear().
+   */
   function clear($cid = NULL, $wildcard = FALSE) {
     // If there is a database cache, attempt to clear it whenever possible. The
     // reason for doing this is that the database cache can accumulate data
@@ -52,6 +65,9 @@ class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterfac
     }
   }
 
+  /**
+   * Overrides DrupalDatabaseCache::isEmpty().
+   */
   function isEmpty() {
     return TRUE;
   }
diff --git a/includes/cache.inc b/includes/cache.inc
index 8666874a..eb7f0904 100644
--- a/includes/cache.inc
+++ b/includes/cache.inc
@@ -1,18 +1,23 @@
 <?php
 
 /**
- * Get the cache object for a cache bin.
+ * @file
+ * Functions and interfaces for cache handling.
+ */
+
+/**
+ * Gets the cache object for a cache bin.
  *
  * By default, this returns an instance of the DrupalDatabaseCache class.
  * Classes implementing DrupalCacheInterface can register themselves both as a
  * default implementation and for specific bins.
  *
- * @see DrupalCacheInterface
- *
  * @param $bin
  *   The cache bin for which the cache object should be returned.
  * @return DrupalCacheInterface
  *   The cache object associated with the specified bin.
+ *
+ * @see DrupalCacheInterface
  */
 function _cache_get_object($bin) {
   // We do not use drupal_static() here because we do not want to change the
@@ -29,7 +34,7 @@ function _cache_get_object($bin) {
 }
 
 /**
- * Return data from the persistent cache
+ * Returns data from the persistent cache.
  *
  * Data may be stored as either plain text or as serialized data. cache_get
  * will automatically return unserialized objects and arrays.
@@ -44,19 +49,22 @@ function _cache_get_object($bin) {
  *
  * @return
  *   The cache or FALSE on failure.
+ *
+ * @see cache_set()
  */
 function cache_get($cid, $bin = 'cache') {
   return _cache_get_object($bin)->get($cid);
 }
 
 /**
- * Return data from the persistent cache when given an array of cache IDs.
+ * Returns data from the persistent cache when given an array of cache IDs.
  *
  * @param $cids
  *   An array of cache IDs for the data to retrieve. This is passed by
  *   reference, and will have the IDs successfully returned from cache removed.
  * @param $bin
  *   The cache bin where the data is stored.
+ *
  * @return
  *   An array of the items successfully returned from cache indexed by cid.
  */
@@ -65,7 +73,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
 }
 
 /**
- * Store data in the persistent cache.
+ * Stores data in the persistent cache.
  *
  * The persistent cache is split up into several cache bins. In the default
  * cache implementation, each cache bin corresponds to a database table by the
@@ -132,13 +140,15 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
  *     general cache wipe.
  *   - A Unix timestamp: Indicates that the item should be kept at least until
  *     the given time, after which it behaves like CACHE_TEMPORARY.
+ *
+ * @see cache_get()
  */
 function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
   return _cache_get_object($bin)->set($cid, $data, $expire);
 }
 
 /**
- * Expire data from the cache.
+ * Expires data from the cache.
  *
  * If called without arguments, expirable entries will be cleared from the
  * cache_page and cache_block bins.
@@ -146,15 +156,12 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
  * @param $cid
  *   If set, the cache ID to delete. Otherwise, all cache entries that can
  *   expire are deleted.
- *
  * @param $bin
- *   If set, the bin $bin to delete from. Mandatory
- *   argument if $cid is set.
- *
+ *   If set, the cache bin to delete from. Mandatory argument if $cid is set.
  * @param $wildcard
- *   If $wildcard is TRUE, cache IDs starting with $cid are deleted in
- *   addition to the exact cache ID specified by $cid.  If $wildcard is
- *   TRUE and $cid is '*' then the entire bin $bin is emptied.
+ *   If TRUE, cache IDs starting with $cid are deleted in addition to the
+ *   exact cache ID specified by $cid. If $wildcard is TRUE and $cid is '*',
+ *   the entire cache bin is emptied.
  */
 function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
   if (!isset($cid) && !isset($bin)) {
@@ -170,13 +177,14 @@ function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
 }
 
 /**
- * Check if a cache bin is empty.
+ * Checks if a cache bin is empty.
  *
  * A cache bin is considered empty if it does not contain any valid data for any
  * cache ID.
  *
  * @param $bin
  *   The cache bin to check.
+ *
  * @return
  *   TRUE if the cache bin specified is empty.
  */
@@ -185,7 +193,7 @@ function cache_is_empty($bin) {
 }
 
 /**
- * Interface for cache implementations.
+ * Defines an interface for cache implementations.
  *
  * All cache implementations have to implement this interface.
  * DrupalDatabaseCache provides the default implementation, which can be
@@ -223,7 +231,7 @@ function cache_is_empty($bin) {
  */
 interface DrupalCacheInterface {
   /**
-   * Constructor.
+   * Constructs a new cache interface.
    *
    * @param $bin
    *   The cache bin for which the object is created.
@@ -231,31 +239,34 @@ interface DrupalCacheInterface {
   function __construct($bin);
 
   /**
-   * Return data from the persistent cache. Data may be stored as either plain
-   * text or as serialized data. cache_get will automatically return
-   * unserialized objects and arrays.
+   * Returns data from the persistent cache.
+   *
+   * Data may be stored as either plain text or as serialized data. cache_get()
+   * will automatically return unserialized objects and arrays.
    *
    * @param $cid
    *   The cache ID of the data to retrieve.
+   *
    * @return
    *   The cache or FALSE on failure.
    */
   function get($cid);
 
   /**
-   * Return data from the persistent cache when given an array of cache IDs.
+   * Returns data from the persistent cache when given an array of cache IDs.
    *
    * @param $cids
    *   An array of cache IDs for the data to retrieve. This is passed by
    *   reference, and will have the IDs successfully returned from cache
    *   removed.
+   *
    * @return
    *   An array of the items successfully returned from cache indexed by cid.
    */
    function getMultiple(&$cids);
 
   /**
-   * Store data in the persistent cache.
+   * Stores data in the persistent cache.
    *
    * @param $cid
    *   The cache ID of the data to store.
@@ -276,8 +287,10 @@ interface DrupalCacheInterface {
 
 
   /**
-   * Expire data from the cache. If called without arguments, expirable
-   * entries will be cleared from the cache_page and cache_block bins.
+   * Expires data from the cache.
+   *
+   * If called without arguments, expirable entries will be cleared from the
+   * cache_page and cache_block bins.
    *
    * @param $cid
    *   If set, the cache ID to delete. Otherwise, all cache entries that can
@@ -290,7 +303,7 @@ interface DrupalCacheInterface {
   function clear($cid = NULL, $wildcard = FALSE);
 
   /**
-   * Check if a cache bin is empty.
+   * Checks if a cache bin is empty.
    *
    * A cache bin is considered empty if it does not contain any valid data for
    * any cache ID.
@@ -302,7 +315,7 @@ interface DrupalCacheInterface {
 }
 
 /**
- * Default cache implementation.
+ * Defines a default cache implementation.
  *
  * This is Drupal's default cache implementation. It uses the database to store
  * cached data. Each cache bin corresponds to a database table by the same name.
@@ -310,16 +323,25 @@ interface DrupalCacheInterface {
 class DrupalDatabaseCache implements DrupalCacheInterface {
   protected $bin;
 
+  /**
+   * Constructs a new DrupalDatabaseCache object.
+   */
   function __construct($bin) {
     $this->bin = $bin;
   }
 
+  /**
+   * Implements DrupalCacheInterface::get().
+   */
   function get($cid) {
     $cids = array($cid);
     $cache = $this->getMultiple($cids);
     return reset($cache);
   }
 
+  /**
+   * Implements DrupalCacheInterface::getMultiple().
+   */
   function getMultiple(&$cids) {
     try {
       // Garbage collection necessary when enforcing a minimum cache lifetime.
@@ -373,13 +395,14 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
   }
 
   /**
-   * Prepare a cached item.
+   * Prepares a cached item.
    *
    * Checks that items are either permanent or did not expire, and unserializes
    * data as appropriate.
    *
    * @param $cache
    *   An item loaded from cache_get() or cache_get_multiple().
+   *
    * @return
    *   The item with data unserialized as appropriate or FALSE if there is no
    *   valid item to load.
@@ -408,6 +431,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     return $cache;
   }
 
+  /**
+   * Implements DrupalCacheInterface::set().
+   */
   function set($cid, $data, $expire = CACHE_PERMANENT) {
     $fields = array(
       'serialized' => 0,
@@ -434,6 +460,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     }
   }
 
+  /**
+   * Implements DrupalCacheInterface::clear().
+   */
   function clear($cid = NULL, $wildcard = FALSE) {
     global $user;
 
@@ -496,6 +525,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     }
   }
 
+  /**
+   * Implements DrupalCacheInterface::isEmpty().
+   */
   function isEmpty() {
     $this->garbageCollection();
     $query = db_select($this->bin);
diff --git a/includes/common.inc b/includes/common.inc
index 9d6bd3c0..1ad97c4e 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -70,8 +70,7 @@ define('CSS_DEFAULT', 0);
 define('CSS_THEME', 100);
 
 /**
- * The default group for JavaScript libraries, settings or jQuery plugins added
- * to the page.
+ * The default group for JavaScript and jQuery libraries added to the page.
  */
 define('JS_LIBRARY', -100);
 
@@ -86,8 +85,9 @@ define('JS_DEFAULT', 0);
 define('JS_THEME', 100);
 
 /**
- * Error code indicating that the request made by drupal_http_request() exceeded
- * the specified timeout.
+ * Error code indicating that the request exceeded the specified timeout.
+ *
+ * @see drupal_http_request()
  */
 define('HTTP_REQUEST_TIMEOUT', -1);
 
@@ -110,31 +110,36 @@ define('HTTP_REQUEST_TIMEOUT', -1);
  */
 
 /**
- * The block should not get cached. This setting should be used:
- * - for simple blocks (notably those that do not perform any db query),
- * where querying the db cache would be more expensive than directly generating
- * the content.
- * - for blocks that change too frequently.
+ * The block should not get cached.
+ *
+ * This setting should be used:
+ * - For simple blocks (notably those that do not perform any db query), where
+ *   querying the db cache would be more expensive than directly generating the
+ *   content.
+ * - For blocks that change too frequently.
  */
 define('DRUPAL_NO_CACHE', -1);
 
 /**
- * The block is handling its own caching in its hook_block_view(). From the
- * perspective of the block cache system, this is equivalent to DRUPAL_NO_CACHE.
- * Useful when time based expiration is needed or a site uses a node access
- * which invalidates standard block cache.
+ * The block is handling its own caching in its hook_block_view().
+ *
+ * From the perspective of the block cache system, this is equivalent to
+ * DRUPAL_NO_CACHE. Useful when time based expiration is needed or a site uses
+ * a node access which invalidates standard block cache.
  */
 define('DRUPAL_CACHE_CUSTOM', -2);
 
 /**
- * The block or element can change depending on the roles the user viewing the
- * page belongs to. This is the default setting for blocks, used when the block
- * does not specify anything.
+ * The block or element can change depending on the user's roles.
+ *
+ * This is the default setting for blocks, used when the block does not specify
+ * anything.
  */
 define('DRUPAL_CACHE_PER_ROLE', 0x0001);
 
 /**
- * The block or element can change depending on the user viewing the page.
+ * The block or element can change depending on the user.
+ *
  * This setting can be resource-consuming for sites with large number of users,
  * and thus should only be used when DRUPAL_CACHE_PER_ROLE is not sufficient.
  */
@@ -146,12 +151,12 @@ define('DRUPAL_CACHE_PER_USER', 0x0002);
 define('DRUPAL_CACHE_PER_PAGE', 0x0004);
 
 /**
- * The block or element is the same for every user on every page where it is visible.
+ * The block or element is the same for every user and page that it is visible.
  */
 define('DRUPAL_CACHE_GLOBAL', 0x0008);
 
 /**
- * Add content to a specified region.
+ * Adds content to a specified region.
  *
  * @param $region
  *   Page region the content is added to.
@@ -168,7 +173,7 @@ function drupal_add_region_content($region = NULL, $data = NULL) {
 }
 
 /**
- * Get assigned content for a given region.
+ * Gets assigned content for a given region.
  *
  * @param $region
  *   A specified region to fetch content for. If NULL, all regions will be
@@ -194,13 +199,13 @@ function drupal_get_region_content($region = NULL, $delimiter = ' ') {
 }
 
 /**
- * Get the name of the currently active install profile.
+ * Gets the name of the currently active install profile.
  *
  * When this function is called during Drupal's initial installation process,
  * the name of the profile that's about to be installed is stored in the global
  * installation state. At all other times, the standard Drupal systems variable
- * table contains the name of the current profile, and we can call variable_get()
- * to determine what one is active.
+ * table contains the name of the current profile, and we can call
+ * variable_get() to determine what one is active.
  *
  * @return $profile
  *   The name of the install profile.
@@ -220,7 +225,7 @@ function drupal_get_profile() {
 
 
 /**
- * Set the breadcrumb trail for the current page.
+ * Sets the breadcrumb trail for the current page.
  *
  * @param $breadcrumb
  *   Array of links, starting with "home" and proceeding up to but not including
@@ -236,7 +241,7 @@ function drupal_set_breadcrumb($breadcrumb = NULL) {
 }
 
 /**
- * Get the breadcrumb trail for the current page.
+ * Gets the breadcrumb trail for the current page.
  */
 function drupal_get_breadcrumb() {
   $breadcrumb = drupal_set_breadcrumb();
@@ -265,7 +270,7 @@ function drupal_get_rdf_namespaces() {
 }
 
 /**
- * Add output to the head tag of the HTML page.
+ * Adds output to the HEAD tag of the HTML page.
  *
  * This function can be called as long the headers aren't sent. Pass no
  * arguments (or NULL for both) to retrieve the currently stored elements.
@@ -333,7 +338,7 @@ function _drupal_default_html_head() {
 }
 
 /**
- * Retrieve output to be displayed in the HEAD tag of the HTML page.
+ * Retrieves output to be displayed in the HEAD tag of the HTML page.
  */
 function drupal_get_html_head() {
   $elements = drupal_add_html_head();
@@ -342,7 +347,7 @@ function drupal_get_html_head() {
 }
 
 /**
- * Add a feed URL for the current page.
+ * Adds a feed URL for the current page.
  *
  * This function can be called as long the HTML header hasn't been sent.
  *
@@ -370,7 +375,7 @@ function drupal_add_feed($url = NULL, $title = '') {
 }
 
 /**
- * Get the feed URLs for the current page.
+ * Gets the feed URLs for the current page.
  *
  * @param $delimiter
  *   A delimiter to split feeds by.
@@ -387,7 +392,7 @@ function drupal_get_feeds($delimiter = "\n") {
  */
 
 /**
- * Process a URL query parameter array to remove unwanted elements.
+ * Processes a URL query parameter array to remove unwanted elements.
  *
  * @param $query
  *   (optional) An array to be processed. Defaults to $_GET.
@@ -432,7 +437,7 @@ function drupal_get_query_parameters(array $query = NULL, array $exclude = array
 }
 
 /**
- * Split an URL-encoded query string into an array.
+ * Splits a URL-encoded query string into an array.
  *
  * @param $query
  *   The query string to split.
@@ -452,7 +457,7 @@ function drupal_get_query_array($query) {
 }
 
 /**
- * Parse an array into a valid, rawurlencoded query string.
+ * Parses an array into a valid, rawurlencoded query string.
  *
  * This differs from http_build_query() as we need to rawurlencode() (instead of
  * urlencode()) all query parameters.
@@ -493,7 +498,7 @@ function drupal_http_build_query(array $query, $parent = '') {
 }
 
 /**
- * Prepare a 'destination' URL query parameter for use in combination with drupal_goto().
+ * Prepares a 'destination' URL query parameter for use with drupal_goto().
  *
  * Used to direct the user back to the referring page after completing a form.
  * By default the current URL is returned. If a destination exists in the
@@ -524,7 +529,7 @@ function drupal_get_destination() {
 }
 
 /**
- * Wrapper around parse_url() to parse a system URL string into an associative array, suitable for url().
+ * Parses a system URL string into an associative array suitable for url().
  *
  * This function should only be used for URLs that have been generated by the
  * system, resp. url(). It should not be used for URLs that come from external
@@ -621,7 +626,7 @@ function drupal_encode_path($path) {
 }
 
 /**
- * Send the user to a different Drupal page.
+ * Sends the user to a different Drupal page.
  *
  * This issues an on-site HTTP redirect. The function makes sure the redirected
  * URL is formatted correctly.
@@ -686,7 +691,7 @@ function drupal_goto($path = '', array $options = array(), $http_response_code =
 }
 
 /**
- * Deliver a "site is under maintenance" message to the browser.
+ * Delivers a "site is under maintenance" message to the browser.
  *
  * Page callback functions wanting to report a "site offline" message should
  * return MENU_SITE_OFFLINE instead of calling drupal_site_offline(). However,
@@ -698,7 +703,7 @@ function drupal_site_offline() {
 }
 
 /**
- * Deliver a "page not found" error to the browser.
+ * Delivers a "page not found" error to the browser.
  *
  * Page callback functions wanting to report a "page not found" message should
  * return MENU_NOT_FOUND instead of calling drupal_not_found(). However,
@@ -710,19 +715,20 @@ function drupal_not_found() {
 }
 
 /**
- * Deliver a "access denied" error to the browser.
+ * Delivers an "access denied" error to the browser.
  *
  * Page callback functions wanting to report an "access denied" message should
  * return MENU_ACCESS_DENIED instead of calling drupal_access_denied(). However,
  * functions that are invoked in contexts where that return value might not
- * bubble up to menu_execute_active_handler() should call drupal_access_denied().
+ * bubble up to menu_execute_active_handler() should call
+ * drupal_access_denied().
  */
 function drupal_access_denied() {
   drupal_deliver_page(MENU_ACCESS_DENIED);
 }
 
 /**
- * Perform an HTTP request.
+ * Performs an HTTP request.
  *
  * This is a flexible and powerful HTTP client implementation. Correctly
  * handles GET, POST, PUT or any other HTTP requests. Handles redirects.
@@ -1023,6 +1029,14 @@ function drupal_http_request($url, array $options = array()) {
  * @} End of "HTTP handling".
  */
 
+/**
+ * Strips slashes from a string or array of strings.
+ *
+ * Callback for array_walk() within fix_gpx_magic().
+ *
+ * @param $item
+ *   An individual string or array of strings from superglobals.
+ */
 function _fix_gpc_magic(&$item) {
   if (is_array($item)) {
     array_walk($item, '_fix_gpc_magic');
@@ -1033,11 +1047,19 @@ function _fix_gpc_magic(&$item) {
 }
 
 /**
- * Helper function to strip slashes from $_FILES skipping over the tmp_name keys
- * since PHP generates single backslashes for file paths on Windows systems.
+ * Strips slashes from $_FILES items.
+ *
+ * Callback for array_walk() within fix_gpc_magic().
  *
- * tmp_name does not have backslashes added see
- * http://php.net/manual/en/features.file-upload.php#42280
+ * The tmp_name key is skipped keys since PHP generates single backslashes for
+ * file paths on Windows systems.
+ *
+ * @param $item
+ *   An item from $_FILES.
+ * @param $key
+ *   The key for the item within $_FILES.
+ *
+ * @see http://php.net/manual/en/features.file-upload.php#42280
  */
 function _fix_gpc_magic_files(&$item, $key) {
   if ($key != 'tmp_name') {
@@ -1051,7 +1073,10 @@ function _fix_gpc_magic_files(&$item, $key) {
 }
 
 /**
- * Fix double-escaping problems caused by "magic quotes" in some PHP installations.
+ * Fixes double-escaping caused by "magic quotes" in some PHP installations.
+ *
+ * @see _fix_gpc_magic()
+ * @see _fix_gpc_magic_files()
  */
 function fix_gpc_magic() {
   static $fixed = FALSE;
@@ -1072,12 +1097,13 @@ function fix_gpc_magic() {
  */
 
 /**
- * Verify the syntax of the given e-mail address.
+ * Verifies the syntax of the given e-mail address.
  *
  * Empty e-mail addresses are allowed. See RFC 2822 for details.
  *
  * @param $mail
  *   A string containing an e-mail address.
+ *
  * @return
  *   TRUE if the address is in a valid format.
  */
@@ -1086,7 +1112,7 @@ function valid_email_address($mail) {
 }
 
 /**
- * Verify the syntax of the given URL.
+ * Verifies the syntax of the given URL.
  *
  * This function should only be used on actual URLs. It should not be used for
  * Drupal menu paths, which can contain arbitrary characters.
@@ -1095,6 +1121,7 @@ function valid_email_address($mail) {
  *   The URL to verify.
  * @param $absolute
  *   Whether the URL is absolute (beginning with a scheme such as "http:").
+ *
  * @return
  *   TRUE if the URL is in a valid format.
  */
@@ -1127,7 +1154,7 @@ function valid_url($url, $absolute = FALSE) {
  */
 
 /**
- * Register an event for the current visitor to the flood control mechanism.
+ * Registers an event for the current visitor to the flood control mechanism.
  *
  * @param $name
  *   The name of an event.
@@ -1154,7 +1181,7 @@ function flood_register_event($name, $window = 3600, $identifier = NULL) {
 }
 
 /**
- * Make the flood control mechanism forget about an event for the current visitor.
+ * Makes the flood control mechanism forget an event for the current visitor.
  *
  * @param $name
  *   The name of an event.
@@ -1172,7 +1199,7 @@ function flood_clear_event($name, $identifier = NULL) {
 }
 
 /**
- * Checks whether user is allowed to proceed with the specified event.
+ * Checks whether a user is allowed to proceed with the specified event.
  *
  * Events can have thresholds saying that each user can only do that event
  * a certain number of times in a time window. This function verifies that the
@@ -1266,7 +1293,7 @@ function drupal_strip_dangerous_protocols($uri) {
 }
 
 /**
- * Strips dangerous protocols (e.g. 'javascript:') from a URI and encodes it for output to an HTML attribute value.
+ * Strips dangerous protocols from a URI and encodes it for output to HTML.
  *
  * @param $uri
  *   A plain-text URI that might contain dangerous protocols.
@@ -1286,7 +1313,7 @@ function check_url($uri) {
 }
 
 /**
- * Very permissive XSS/HTML filter for admin-only use.
+ * Applies a very permissive XSS/HTML filter for admin-only use.
  *
  * Use only for fields where it is impractical to use the
  * whole filter system, but where some (mainly inline) mark-up
@@ -1300,7 +1327,7 @@ function filter_xss_admin($string) {
 }
 
 /**
- * Filters an HTML string to prevent cross-site-scripting (XSS) vulnerabilities.
+ * Filters HTML to prevent cross-site-scripting (XSS) vulnerabilities.
  *
  * Based on kses by Ulf Harnhammar, see http://sourceforge.net/projects/kses.
  * For examples of various XSS attacks, see: http://ha.ckers.org/xss.html.
@@ -1369,6 +1396,7 @@ function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite',
  *   If $store is FALSE then the array has one element, the HTML tag to process.
  * @param $store
  *   Whether to store $m.
+ *
  * @return
  *   If the element isn't allowed, an empty string. Otherwise, the cleaned up
  *   version of the HTML element.
@@ -1536,15 +1564,16 @@ function _filter_xss_attributes($attr) {
 }
 
 /**
- * Processes an HTML attribute value and ensures it does not contain an URL with a disallowed protocol (e.g. javascript:).
+ * Processes an HTML attribute value and strips dangerous protocols from URLs.
  *
  * @param $string
  *   The string with the attribute value.
  * @param $decode
- *   (Deprecated) Whether to decode entities in the $string. Set to FALSE if the
+ *   (deprecated) Whether to decode entities in the $string. Set to FALSE if the
  *   $string is in plain text, TRUE otherwise. Defaults to TRUE. This parameter
  *   is deprecated and will be removed in Drupal 8. To process a plain-text URI,
  *   call drupal_strip_dangerous_protocols() or check_url() instead.
+ *
  * @return
  *   Cleaned up and HTML-escaped version of $string.
  */
@@ -1598,7 +1627,7 @@ function format_rss_channel($title, $link, $description, $items, $langcode = NUL
 }
 
 /**
- * Format a single RSS item.
+ * Formats a single RSS item.
  *
  * Arbitrary elements may be added using the $args associative array.
  */
@@ -1614,7 +1643,7 @@ function format_rss_item($title, $link, $description, $args = array()) {
 }
 
 /**
- * Format XML elements.
+ * Formats XML elements.
  *
  * @param $array
  *   An array where each item represents an element and is either a:
@@ -1653,7 +1682,7 @@ function format_xml_elements($array) {
 }
 
 /**
- * Format a string containing a count of items.
+ * Formats a string containing a count of items.
  *
  * This function ensures that the string is pluralized correctly. Since t() is
  * called by this function, make sure not to pass already-localized strings to
@@ -1675,31 +1704,27 @@ function format_xml_elements($array) {
  * @param $count
  *   The item count to display.
  * @param $singular
- *   The string for the singular case. Please make sure it is clear this is
- *   singular, to ease translation (e.g. use "1 new comment" instead of "1 new").
- *   Do not use @count in the singular string.
+ *   The string for the singular case. Make sure it is clear this is singular,
+ *   to ease translation (e.g. use "1 new comment" instead of "1 new"). Do not
+ *   use @count in the singular string.
  * @param $plural
- *   The string for the plural case. Please make sure it is clear this is plural,
- *   to ease translation. Use @count in place of the item count, as in "@count
- *   new comments".
+ *   The string for the plural case. Make sure it is clear this is plural, to
+ *   ease translation. Use @count in place of the item count, as in
+ *   "@count new comments".
  * @param $args
- *   An associative array of replacements to make after translation. Incidences
+ *   An associative array of replacements to make after translation. Instances
  *   of any key in this array are replaced with the corresponding value.
- *   Based on the first character of the key, the value is escaped and/or themed:
- *    - !variable: inserted as is
- *    - @variable: escape plain text to HTML (check_plain)
- *    - %variable: escape text and theme as a placeholder for user-submitted
- *      content (check_plain + drupal_placeholder)
- *   Note that you do not need to include @count in this array.
- *   This replacement is done automatically for the plural case.
+ *   Based on the first character of the key, the value is escaped and/or
+ *   themed. See format_string(). Note that you do not need to include @count
+ *   in this array; this replacement is done automatically for the plural case.
  * @param $options
- *   An associative array of additional options, with the following keys:
- *     - 'langcode' (default to the current language) The language code to
- *       translate to a language other than what is used to display the page.
- *     - 'context' (default to the empty context) The context the source string
- *       belongs to.
+ *   An associative array of additional options. See t() for allowed keys.
+ *
  * @return
  *   A translated string.
+ *
+ * @see t()
+ * @see format_string()
  */
 function format_plural($count, $singular, $plural, array $args = array(), array $options = array()) {
   $args['@count'] = $count;
@@ -1728,11 +1753,12 @@ function format_plural($count, $singular, $plural, array $args = array(), array
 }
 
 /**
- * Parse a given byte count.
+ * Parses a given byte count.
  *
  * @param $size
  *   A size expressed as a number of bytes with optional SI or IEC binary unit
  *   prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes).
+ *
  * @return
  *   An integer representation of the size in bytes.
  */
@@ -1749,13 +1775,14 @@ function parse_size($size) {
 }
 
 /**
- * Generate a string representation for the given byte count.
+ * Generates a string representation for the given byte count.
  *
  * @param $size
  *   A size in bytes.
  * @param $langcode
  *   Optional language code to translate to a language other than what is used
  *   to display the page.
+ *
  * @return
  *   A translated string representation of the size.
  */
@@ -1788,19 +1815,20 @@ function format_size($size, $langcode = NULL) {
 }
 
 /**
- * Format a time interval with the requested granularity.
+ * Formats a time interval with the requested granularity.
  *
- * @param $timestamp
+ * @param $interval
  *   The length of the interval in seconds.
  * @param $granularity
  *   How many different units to display in the string.
  * @param $langcode
  *   Optional language code to translate to a language other than
  *   what is used to display the page.
+ *
  * @return
  *   A translated string representation of the interval.
  */
-function format_interval($timestamp, $granularity = 2, $langcode = NULL) {
+function format_interval($interval, $granularity = 2, $langcode = NULL) {
   $units = array(
     '1 year|@count years' => 31536000,
     '1 month|@count months' => 2592000,
@@ -1813,9 +1841,9 @@ function format_interval($timestamp, $granularity = 2, $langcode = NULL) {
   $output = '';
   foreach ($units as $key => $value) {
     $key = explode('|', $key);
-    if ($timestamp >= $value) {
-      $output .= ($output ? ' ' : '') . format_plural(floor($timestamp / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
-      $timestamp %= $value;
+    if ($interval >= $value) {
+      $output .= ($output ? ' ' : '') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
+      $interval %= $value;
       $granularity--;
     }
 
@@ -1928,10 +1956,11 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
 /**
  * Returns an ISO8601 formatted date based on the given date.
  *
- * Can be used as a callback for RDF mappings.
+ * Callback for use within hook_rdf_mapping() implementations.
  *
  * @param $date
  *   A UNIX timestamp.
+ *
  * @return string
  *   An ISO8601 formatted date.
  */
@@ -1942,7 +1971,9 @@ function date_iso8601($date) {
 }
 
 /**
- * Callback function for preg_replace_callback().
+ * Translates a formatted date string.
+ *
+ * Callback for preg_replace_callback() within format_date().
  */
 function _format_date_callback(array $matches = NULL, $new_langcode = NULL) {
   // We cache translations to avoid redundant and rather costly calls to t().
@@ -2057,8 +2088,8 @@ function format_username($account) {
  *     Drupal on a web server that cannot be configured to automatically find
  *     index.php, then hook_url_outbound_alter() can be implemented to force
  *     this value to 'index.php'.
- *   - 'entity_type': The entity type of the object that called url(). Only set if
- *     url() is invoked by entity_uri().
+ *   - 'entity_type': The entity type of the object that called url(). Only
+ *     set if url() is invoked by entity_uri().
  *   - 'entity': The entity object (such as a node) for which the URL is being
  *     generated. Only set if url() is invoked by entity_uri().
  *
@@ -2186,7 +2217,7 @@ function url($path = NULL, array $options = array()) {
 }
 
 /**
- * Return TRUE if a path is external to Drupal (e.g. http://example.com).
+ * Returns TRUE if a path is external to Drupal (e.g. http://example.com).
  *
  * If a path cannot be assessed by Drupal's menu handler, then we must
  * treat it as potentially insecure.
@@ -2194,6 +2225,7 @@ function url($path = NULL, array $options = array()) {
  * @param $path
  *   The internal path or external URL being linked to, such as "node/34" or
  *   "http://example.com/foo".
+ *
  * @return
  *   Boolean TRUE or FALSE, where TRUE indicates an external path.
  */
@@ -2206,7 +2238,7 @@ function url_is_external($path) {
 }
 
 /**
- * Format an attribute string for a HTTP header.
+ * Formats an attribute string for an HTTP header.
  *
  * @param $attributes
  *   An associative array of attributes such as 'rel'.
@@ -2228,7 +2260,7 @@ function drupal_http_header_attributes(array $attributes = array()) {
 }
 
 /**
- * Converts an associative array to an attribute string for use in XML/HTML tags.
+ * Converts an associative array to an XML/HTML tag attribute string.
  *
  * Each array key and its value will be formatted into an attribute string.
  * If a value is itself an array, then its elements are concatenated to a single
@@ -2341,7 +2373,7 @@ function l($text, $path, array $options = array()) {
     // rendering.
     if (variable_get('theme_link', TRUE)) {
       drupal_theme_initialize();
-      $registry = theme_get_registry();
+      $registry = theme_get_registry(FALSE);
       // We don't want to duplicate functionality that's in theme(), so any
       // hint of a module or theme doing anything at all special with the 'link'
       // theme hook should simply result in theme() being called. This includes
@@ -2449,7 +2481,7 @@ function drupal_deliver_page($page_callback_result, $default_delivery_callback =
 }
 
 /**
- * Package and send the result of a page callback to the browser as HTML.
+ * Packages and sends the result of a page callback to the browser as HTML.
  *
  * @param $page_callback_result
  *   The result of a page callback. Can be one of:
@@ -2558,7 +2590,7 @@ function drupal_deliver_html_page($page_callback_result) {
 }
 
 /**
- * Perform end-of-request tasks.
+ * Performs end-of-request tasks.
  *
  * This function sets the page cache if appropriate, and allows modules to
  * react to the closing of the page by calling hook_exit().
@@ -2585,7 +2617,7 @@ function drupal_page_footer() {
 }
 
 /**
- * Perform end-of-request tasks.
+ * Performs end-of-request tasks.
  *
  * In some cases page requests need to end without calling drupal_page_footer().
  * In these cases, call drupal_exit() instead. There should rarely be a reason
@@ -2607,7 +2639,7 @@ function drupal_exit($destination = NULL) {
 }
 
 /**
- * Form an associative array from a linear array.
+ * Forms an associative array from a linear array.
  *
  * This function walks through the provided array and constructs an associative
  * array out of it. The keys of the resulting array will be the values of the
@@ -2683,10 +2715,10 @@ function drupal_get_path($type, $name) {
 }
 
 /**
- * Return the base URL path (i.e., directory) of the Drupal installation.
+ * Returns the base URL path (i.e., directory) of the Drupal installation.
  *
- * base_path() prefixes and suffixes a "/" onto the returned path if the path is
- * not empty. At the very least, this will return "/".
+ * base_path() adds a "/" to the beginning and end of the returned path if the
+ * path is not empty. At the very least, this will return "/".
  *
  * Examples:
  * - http://example.com returns "/" because the path is empty.
@@ -2697,12 +2729,12 @@ function base_path() {
 }
 
 /**
- * Add a LINK tag with a distinct 'rel' attribute to the page's HEAD.
+ * Adds a LINK tag with a distinct 'rel' attribute to the page's HEAD.
  *
- * This function can be called as long the HTML header hasn't been sent,
- * which on normal pages is up through the preprocess step of theme('html').
- * Adding a link will overwrite a prior link with the exact same 'rel' and
- * 'href' attributes.
+ * This function can be called as long the HTML header hasn't been sent, which
+ * on normal pages is up through the preprocess step of theme('html'). Adding
+ * a link will overwrite a prior link with the exact same 'rel' and 'href'
+ * attributes.
  *
  * @param $attributes
  *   Associative array of element attributes including 'href' and 'rel'.
@@ -2766,8 +2798,8 @@ function drupal_add_html_head_link($attributes, $header = FALSE) {
  *     See drupal_get_css() where the overrides are performed. Also, if the
  *     direction of the current language is right-to-left (Hebrew, Arabic,
  *     etc.), the function will also look for an RTL CSS file and append it to
- *     the list. The name of this file should have an '-rtl.css' suffix.  For
- *     example a CSS file called 'mymodule-name.css' will have a
+ *     the list. The name of this file should have an '-rtl.css' suffix. For
+ *     example, a CSS file called 'mymodule-name.css' will have a
  *     'mymodule-name-rtl.css' file added to the list, if exists in the same
  *     directory. This CSS file should contain overrides for properties which
  *     should be reversed or otherwise different in a right-to-left display.
@@ -2899,7 +2931,7 @@ function drupal_add_css($data = NULL, $options = NULL) {
 }
 
 /**
- * Returns a themed representation of all stylesheets that should be attached to the page.
+ * Returns a themed representation of all stylesheets to attach to the page.
  *
  * It loads the CSS in order, with 'module' first, then 'theme' afterwards.
  * This ensures proper cascading of styles so themes can easily override
@@ -2945,7 +2977,7 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
   foreach ($css as $key => $item) {
     if ($item['type'] == 'file') {
       // If defined, force a unique basename for this file.
-      $basename = isset($item['basename']) ? $item['basename'] : basename($item['data']);
+      $basename = isset($item['basename']) ? $item['basename'] : drupal_basename($item['data']);
       if (isset($previous_item[$basename])) {
         // Remove the previous item that shared the same base name.
         unset($css[$previous_item[$basename]]);
@@ -2969,11 +3001,24 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
 }
 
 /**
- * Function used by uasort to sort the array structures returned by drupal_add_css() and drupal_add_js().
+ * Sorts CSS and JavaScript resources.
+ *
+ * Callback for uasort() within:
+ * - drupal_get_css()
+ * - drupal_get_js()
  *
  * This sort order helps optimize front-end performance while providing modules
  * and themes with the necessary control for ordering the CSS and JavaScript
  * appearing on a page.
+ *
+ * @param $a
+ *   First item for comparison. The compared items should be associative arrays
+ *   of member items from drupal_add_css() or drupal_add_js().
+ * @param $b
+ *   Second item for comparison.
+ *
+ * @see drupal_add_css()
+ * @see drupal_add_js()
  */
 function drupal_sort_css_js($a, $b) {
   // First order by group, so that, for example, all items in the CSS_SYSTEM
@@ -3040,6 +3085,7 @@ function drupal_sort_css_js($a, $b) {
  *   'items' key, which is the subset of items from $css that are in the group.
  *
  * @see drupal_pre_render_styles()
+ * @see system_element_info()
  */
 function drupal_group_css($css) {
   $groups = array();
@@ -3122,6 +3168,7 @@ function drupal_group_css($css) {
  *
  * @see drupal_group_css()
  * @see drupal_pre_render_styles()
+ * @see system_element_info()
  */
 function drupal_aggregate_css(&$css_groups) {
   $preprocess_css = (variable_get('preprocess_css', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
@@ -3383,8 +3430,8 @@ function drupal_pre_render_styles($elements) {
  * in $css while the value is the cache file name. The cache file is generated
  * in two cases. First, if there is no file name value for the key, which will
  * happen if a new file name has been added to $css or after the lookup
- * variable is emptied to force a rebuild of the cache.  Second, the cache
- * file is generated if it is missing on disk. Old cache files are not deleted
+ * variable is emptied to force a rebuild of the cache. Second, the cache file
+ * is generated if it is missing on disk. Old cache files are not deleted
  * immediately when the lookup variable is emptied, but are deleted after a set
  * period by drupal_delete_file_if_stale(). This ensures that files referenced
  * by a cached page will still be available.
@@ -3462,9 +3509,7 @@ function drupal_build_css_cache($css) {
 }
 
 /**
- * Helper function for drupal_build_css_cache().
- *
- * This function will prefix all paths within a CSS file.
+ * Prefixes all paths within a CSS file for drupal_build_css_cache().
  */
 function _drupal_build_css_path($matches, $base = NULL) {
   $_base = &drupal_static(__FUNCTION__);
@@ -3535,13 +3580,14 @@ function drupal_load_stylesheet($file, $optimize = NULL, $reset_basepath = TRUE)
 }
 
 /**
- * Process the contents of a stylesheet for aggregation.
+ * Processes the contents of a stylesheet for aggregation.
  *
  * @param $contents
  *   The contents of the stylesheet.
  * @param $optimize
  *   (optional) Boolean whether CSS contents should be minified. Defaults to
  *   FALSE.
+ *
  * @return
  *   Contents of the stylesheet including the imported stylesheets.
  */
@@ -3637,7 +3683,7 @@ function drupal_delete_file_if_stale($uri) {
 }
 
 /**
- * Prepare a string for use as a valid CSS identifier (element, class or ID name).
+ * Prepares a string for use as a CSS identifier (element, class, or ID name).
  *
  * http://www.w3.org/TR/CSS21/syndata.html#characters shows the syntax for valid
  * CSS identifiers (including element names, classes, and IDs in selectors.)
@@ -3646,6 +3692,7 @@ function drupal_delete_file_if_stale($uri) {
  *   The identifier to clean.
  * @param $filter
  *   An array of string replacements to use on the identifier.
+ *
  * @return
  *   The cleaned identifier.
  */
@@ -3667,13 +3714,14 @@ function drupal_clean_css_identifier($identifier, $filter = array(' ' => '-', '_
 }
 
 /**
- * Prepare a string for use as a valid class name.
+ * Prepares a string for use as a valid class name.
  *
  * Do not pass one string containing multiple classes as they will be
  * incorrectly concatenated with dashes, i.e. "one two" will become "one-two".
  *
  * @param $class
  *   The class name to clean.
+ *
  * @return
  *   The cleaned class name.
  */
@@ -3682,7 +3730,7 @@ function drupal_html_class($class) {
 }
 
 /**
- * Prepare a string for use as a valid HTML ID and guarantee uniqueness.
+ * Prepares a string for use as a valid HTML ID and guarantees uniqueness.
  *
  * This function ensures that each passed HTML ID value only exists once on the
  * page. By tracking the already returned ids, this function enables forms,
@@ -3813,7 +3861,7 @@ function drupal_region_class($region) {
  *   to tell the user that a new message arrived, by opening a pop up, alert
  *   box, etc.). This should only be used for JavaScript that cannot be executed
  *   from a file. When adding inline code, make sure that you are not relying on
- *   $() being the jQuery function.  Wrap your code in
+ *   $() being the jQuery function. Wrap your code in
  *   @code (function ($) {... })(jQuery); @endcode
  *   or use jQuery() instead of $().
  * - Add external JavaScript ('external'): Allows the inclusion of external
@@ -3933,7 +3981,7 @@ function drupal_region_class($region) {
  *       happened later in the page request gets added to the page after one for
  *       which drupal_add_js() happened earlier in the page request.
  *   - defer: If set to TRUE, the defer attribute is set on the &lt;script&gt;
- *     tag.  Defaults to FALSE.
+ *     tag. Defaults to FALSE.
  *   - cache: If set to FALSE, the JavaScript file is loaded anew on every page
  *     call; in other words, it is not cached. Used only when 'type' references
  *     a JavaScript file. Defaults to TRUE.
@@ -4030,6 +4078,7 @@ function drupal_add_js($data = NULL, $options = NULL) {
  *
  * @param $data
  *   (optional) The default data parameter for the JavaScript item array.
+ *
  * @see drupal_get_js()
  * @see drupal_add_js()
  */
@@ -4073,8 +4122,10 @@ function drupal_js_defaults($data = NULL) {
  *   (optional) If set to TRUE, this function skips calling drupal_alter() on
  *   $javascript, useful when the calling function passes a $javascript array
  *   that has already been altered.
+ *
  * @return
  *   All JavaScript code segments and includes for the scope as HTML tags.
+ *
  * @see drupal_add_js()
  * @see locale_js_alter()
  * @see drupal_js_defaults()
@@ -4246,7 +4297,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
  * );
  * @endcode
  *
- * 'js', 'css', and 'library' are types that get special handling.  For any
+ * 'js', 'css', and 'library' are types that get special handling. For any
  * other kind of attached data, the array key must be the full name of the
  * callback function and each value an array of arguments. For example:
  * @code
@@ -4597,16 +4648,16 @@ function drupal_get_library($module, $name = NULL) {
 }
 
 /**
- * Assist in adding the tableDrag JavaScript behavior to a themed table.
+ * Assists in adding the tableDrag JavaScript behavior to a themed table.
  *
  * Draggable tables should be used wherever an outline or list of sortable items
  * needs to be arranged by an end-user. Draggable tables are very flexible and
  * can manipulate the value of form elements placed within individual columns.
  *
- * To set up a table to use drag and drop in place of weight select-lists or
- * in place of a form that contains parent relationships, the form must be
- * themed into a table. The table must have an id attribute set. If using
- * theme_table(), the id may be set as such:
+ * To set up a table to use drag and drop in place of weight select-lists or in
+ * place of a form that contains parent relationships, the form must be themed
+ * into a table. The table must have an ID attribute set. If using
+ * theme_table(), the ID may be set as follows:
  * @code
  * $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'my-module-table')));
  * return $output;
@@ -4621,8 +4672,8 @@ function drupal_get_library($module, $name = NULL) {
  * $form['my_elements'][$delta]['weight']['#attributes']['class'] = array('my-elements-weight');
  * @endcode
  *
- * Each row of the table must also have a class of "draggable" in order to enable the
- * drag handles:
+ * Each row of the table must also have a class of "draggable" in order to
+ * enable the drag handles:
  * @code
  * $row = array(...);
  * $rows[] = array(
@@ -4642,8 +4693,8 @@ function drupal_get_library($module, $name = NULL) {
  * @endcode
  *
  * In a more complex case where there are several groups in one column (such as
- * the block regions on the admin/structure/block page), a separate subgroup class
- * must also be added to differentiate the groups.
+ * the block regions on the admin/structure/block page), a separate subgroup
+ * class must also be added to differentiate the groups.
  * @code
  * $form['my_elements'][$region][$delta]['weight']['#attributes']['class'] = array('my-elements-weight', 'my-elements-weight-' . $region);
  * @endcode
@@ -4660,14 +4711,14 @@ function drupal_get_library($module, $name = NULL) {
  *
  * In a situation where tree relationships are present, adding multiple
  * subgroups is not necessary, because the table will contain indentations that
- * provide enough information about the sibling and parent relationships.
- * See theme_menu_overview_form() for an example creating a table containing
- * parent relationships.
- *
- * Please note that this function should be called from the theme layer, such as
- * in a .tpl.php file, theme_ function, or in a template_preprocess function,
- * not in a form declaration. Though the same JavaScript could be added to the
- * page using drupal_add_js() directly, this function helps keep template files
+ * provide enough information about the sibling and parent relationships. See
+ * theme_menu_overview_form() for an example creating a table containing parent
+ * relationships.
+ *
+ * Note that this function should be called from the theme layer, such as in a
+ * .tpl.php file, theme_ function, or in a template_preprocess function, not in
+ * a form declaration. Though the same JavaScript could be added to the page
+ * using drupal_add_js() directly, this function helps keep template files
  * clean and readable. It also prevents tabledrag.js from being added twice
  * accidentally.
  *
@@ -4740,8 +4791,8 @@ function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgro
  * $files while the value is the cache file name. The cache file is generated
  * in two cases. First, if there is no file name value for the key, which will
  * happen if a new file name has been added to $files or after the lookup
- * variable is emptied to force a rebuild of the cache.  Second, the cache
- * file is generated if it is missing on disk. Old cache files are not deleted
+ * variable is emptied to force a rebuild of the cache. Second, the cache file
+ * is generated if it is missing on disk. Old cache files are not deleted
  * immediately when the lookup variable is emptied, but are deleted after a set
  * period by drupal_delete_file_if_stale(). This ensures that files referenced
  * by a cached page will still be available.
@@ -4807,14 +4858,29 @@ function drupal_clear_js_cache() {
 /**
  * Converts a PHP variable into its JavaScript equivalent.
  *
- * We use HTML-safe strings, i.e. with <, > and & escaped.
+ * We use HTML-safe strings, with several characters escaped.
  *
  * @see drupal_json_decode()
+ * @see drupal_json_encode_helper()
  * @ingroup php_wrappers
  */
 function drupal_json_encode($var) {
-  // json_encode() does not escape <, > and &, so we do it with str_replace().
-  return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
+  // The PHP version cannot change within a request.
+  static $php530;
+
+  if (!isset($php530)) {
+    $php530 = version_compare(PHP_VERSION, '5.3.0', '>=');
+  }
+
+  if ($php530) {
+    // Encode <, >, ', &, and " using the json_encode() options parameter.
+    return json_encode($var, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
+  }
+
+  // json_encode() escapes <, >, ', &, and " using its options parameter, but
+  // does not support this parameter prior to PHP 5.3.0.  Use a helper instead.
+  include_once DRUPAL_ROOT . '/includes/json-encode.inc';
+  return drupal_json_encode_helper($var);
 }
 
 /**
@@ -4828,7 +4894,7 @@ function drupal_json_decode($var) {
 }
 
 /**
- * Return data in JSON format.
+ * Returns data in JSON format.
  *
  * This function should be used for JavaScript callback functions returning
  * data in JSON format. It sets the header for JavaScript output.
@@ -4846,7 +4912,7 @@ function drupal_json_output($var = NULL) {
 }
 
 /**
- * Get a salt useful for hardening against SQL injection.
+ * Gets a salt useful for hardening against SQL injection.
  *
  * @return
  *   A salt based on information in settings.php, not in the database.
@@ -4859,7 +4925,7 @@ function drupal_get_hash_salt() {
 }
 
 /**
- * Ensure the private key variable used to generate tokens is set.
+ * Ensures the private key variable used to generate tokens is set.
  *
  * @return
  *   The private key.
@@ -4873,7 +4939,7 @@ function drupal_get_private_key() {
 }
 
 /**
- * Generate a token based on $value, the current user session and private key.
+ * Generates a token based on $value, the user session, and the private key.
  *
  * @param $value
  *   An additional value to base the token on.
@@ -4883,7 +4949,7 @@ function drupal_get_token($value = '') {
 }
 
 /**
- * Validate a token based on $value, the current user session and private key.
+ * Validates a token based on $value, the user session, and the private key.
  *
  * @param $token
  *   The token to be validated.
@@ -4891,6 +4957,7 @@ function drupal_get_token($value = '') {
  *   An additional value to base the token on.
  * @param $skip_anonymous
  *   Set to true to skip token validation for anonymous users.
+ *
  * @return
  *   True for a valid token, false for an invalid token. When $skip_anonymous
  *   is true, the return value will always be true for anonymous users.
@@ -4959,7 +5026,7 @@ function _drupal_bootstrap_full() {
 }
 
 /**
- * Store the current page in the cache.
+ * Stores the current page in the cache.
  *
  * If page_compression is enabled, a gzipped version of the page is stored in
  * the cache to avoid compressing the output on each request. The cache entry
@@ -5011,10 +5078,10 @@ function drupal_page_set_cache() {
 /**
  * Executes a cron run when called.
  *
- * Do not call this function from test, use $this->cronRun() instead.
+ * Do not call this function from a test. Use $this->cronRun() instead.
  *
  * @return
- *   Returns TRUE if ran successfully
+ *   TRUE if cron ran successfully.
  */
 function drupal_cron_run() {
   // Allow execution to continue even if the request gets canceled.
@@ -5089,7 +5156,10 @@ function drupal_cron_run() {
 }
 
 /**
- * Shutdown function for cron cleanup.
+ * Shutdown function: Performs cron cleanup.
+ *
+ * @see drupal_cron_run()
+ * @see drupal_register_shutdown_function()
  */
 function drupal_cron_cleanup() {
   // See if the semaphore is still locked.
@@ -5208,7 +5278,7 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
 }
 
 /**
- * Set the main page content value for later use.
+ * Sets the main page content value for later use.
  *
  * Given the nature of the Drupal page handling, this will be called once with
  * a string or array. We store that and return it later as the block is being
@@ -5216,6 +5286,7 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
  *
  * @param $content
  *   A string or renderable array representing the body of the page.
+ *
  * @return
  *   If called without $content, a renderable array representing the body of
  *   the page.
@@ -5466,13 +5537,13 @@ function drupal_pre_render_links($element) {
  * Note that if also a #theme is defined for the element, then the result of
  * the theme callback will override #children.
  *
- * @see drupal_render()
- *
  * @param $elements
  *   A structured array using the #markup key.
  *
  * @return
  *   The passed-in elements, but #markup appended to #children.
+ *
+ * @see drupal_render()
  */
 function drupal_pre_render_markup($elements) {
   $elements['#children'] = $elements['#markup'];
@@ -5485,8 +5556,10 @@ function drupal_pre_render_markup($elements) {
  * @param $page
  *   A string or array representing the content of a page. The array consists of
  *   the following keys:
- *   - #type: Value is always 'page'. This pushes the theming through page.tpl.php (required).
- *   - #show_messages: Suppress drupal_get_message() items. Used by Batch API (optional).
+ *   - #type: Value is always 'page'. This pushes the theming through
+ *     page.tpl.php (required).
+ *   - #show_messages: Suppress drupal_get_message() items. Used by Batch
+ *     API (optional).
  *
  * @see hook_page_alter()
  * @see element_info()
@@ -5563,20 +5636,20 @@ function drupal_render_page($page) {
  * drupal_render() can optionally cache the rendered output of elements to
  * improve performance. To use drupal_render() caching, set the element's #cache
  * property to an associative array with one or several of the following keys:
- *    - 'keys': An array of one or more keys that identify the element. If 'keys'
- *       is set, the cache ID is created automatically from these keys. See
- *       drupal_render_cid_create().
- *    - 'granularity' (optional): Define the cache granularity using binary
- *       combinations of the cache granularity constants, e.g. DRUPAL_CACHE_PER_USER
- *       to cache for each user separately or
- *       DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE to cache separately for each
- *       page and role. If not specified the element is cached globally for each
- *       theme and language.
- *    - 'cid': Specify the cache ID directly. Either 'keys' or 'cid' is required.
- *       If 'cid' is set, 'keys' and 'granularity' are ignored. Use only if you
- *       have special requirements.
- *    - 'expire': Set to one of the cache lifetime constants.
- *    - 'bin': Specify a cache bin to cache the element in. Defaults to 'cache'.
+ * - 'keys': An array of one or more keys that identify the element. If 'keys'
+ *   is set, the cache ID is created automatically from these keys. See
+ *   drupal_render_cid_create().
+ * - 'granularity' (optional): Define the cache granularity using binary
+ *   combinations of the cache granularity constants, e.g.
+ *   DRUPAL_CACHE_PER_USER to cache for each user separately or
+ *   DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE to cache separately for each
+ *   page and role. If not specified the element is cached globally for each
+ *   theme and language.
+ * - 'cid': Specify the cache ID directly. Either 'keys' or 'cid' is required.
+ *   If 'cid' is set, 'keys' and 'granularity' are ignored. Use only if you
+ *   have special requirements.
+ * - 'expire': Set to one of the cache lifetime constants.
+ * - 'bin': Specify a cache bin to cache the element in. Defaults to 'cache'.
  *
  * This function is usually called from within another function, like
  * drupal_get_form() or a theme function. Elements are sorted internally
@@ -5593,6 +5666,7 @@ function drupal_render_page($page) {
  *
  * @param $elements
  *   The structured array describing the data to be rendered.
+ *
  * @return
  *   The rendered HTML.
  */
@@ -5608,8 +5682,11 @@ function drupal_render(&$elements) {
   }
 
   // Try to fetch the element's markup from cache and return.
-  if (isset($elements['#cache']) && $cached_output = drupal_render_cache_get($elements)) {
-    return $cached_output;
+  if (isset($elements['#cache'])) {
+    $cached_output = drupal_render_cache_get($elements);
+    if ($cached_output !== FALSE) {
+      return $cached_output;
+    }
   }
 
   // If #markup is set, ensure #type is set. This allows to specify just #markup
@@ -5706,7 +5783,7 @@ function drupal_render(&$elements) {
 }
 
 /**
- * Render children of an element and concatenate them.
+ * Renders children of an element and concatenates them.
  *
  * This renders all children of an element using drupal_render() and then
  * joins them together into a single string.
@@ -5731,7 +5808,7 @@ function drupal_render_children(&$element, $children_keys = NULL) {
 }
 
 /**
- * Render an element.
+ * Renders an element.
  *
  * This function renders an element using drupal_render(). The top level
  * element is shown with show() before rendering, so it will always be rendered
@@ -5760,7 +5837,7 @@ function render(&$element) {
 }
 
 /**
- * Hide an element from later rendering.
+ * Hides an element from later rendering.
  *
  * The first time render() or drupal_render() is called on an element tree,
  * as each element in the tree is rendered, it is marked with a #printed flag
@@ -5786,7 +5863,7 @@ function hide(&$element) {
 }
 
 /**
- * Show a hidden element for later rendering.
+ * Shows a hidden element for later rendering.
  *
  * You can also use render($element), which shows the element while rendering
  * it.
@@ -5815,16 +5892,17 @@ function show(&$element) {
 }
 
 /**
- * Get the rendered output of a renderable element from cache.
- *
- * @see drupal_render()
- * @see drupal_render_cache_set()
+ * Gets the rendered output of a renderable element from the cache.
  *
  * @param $elements
  *   A renderable array.
+ *
  * @return
  *   A markup string containing the rendered content of the element, or FALSE
  *   if no cached copy of the element is available.
+ *
+ * @see drupal_render()
+ * @see drupal_render_cache_set()
  */
 function drupal_render_cache_get($elements) {
   if (!in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) || !$cid = drupal_render_cid_create($elements)) {
@@ -5845,17 +5923,17 @@ function drupal_render_cache_get($elements) {
 }
 
 /**
- * Cache the rendered output of a renderable element.
- *
- * This is called by drupal_render() if the #cache property is set on an element.
+ * Caches the rendered output of a renderable element.
  *
- * @see drupal_render()
- * @see drupal_render_cache_get()
+ * This is called by drupal_render() if the #cache property is set on an
+ * element.
  *
  * @param $markup
  *   The rendered output string of $elements.
  * @param $elements
  *   A renderable array.
+ *
+ * @see drupal_render_cache_get()
  */
 function drupal_render_cache_set(&$markup, $elements) {
   // Create the cache ID for the element.
@@ -5881,7 +5959,7 @@ function drupal_render_cache_set(&$markup, $elements) {
 }
 
 /**
- * Collect #attached for an element and all child elements into a single array.
+ * Collects #attached for an element and its children into a single array.
  *
  * When caching elements, it is necessary to collect all libraries, JavaScript
  * and CSS into a single array, from both the element itself and all child
@@ -5924,9 +6002,10 @@ function drupal_render_collect_attached($elements, $return = FALSE) {
 }
 
 /**
- * Prepare an element for caching based on a query. This smart caching strategy
- * saves Drupal from querying and rendering to HTML when the underlying query is
- * unchanged.
+ * Prepares an element for caching based on a query.
+ *
+ * This smart caching strategy saves Drupal from querying and rendering to HTML
+ * when the underlying query is unchanged.
  *
  * Expensive queries should use the query builder to create the query and then
  * call this function. Executing the query and formatting results should happen
@@ -5964,12 +6043,15 @@ function drupal_render_cache_by_query($query, $function, $expire = CACHE_TEMPORA
 }
 
 /**
- * Helper function for building cache ids.
+ * Returns cache ID parts for building a cache ID.
  *
  * @param $granularity
- *   One or more cache granularity constants, e.g. DRUPAL_CACHE_PER_USER to cache
- *   for each user separately or DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE to
- *   cache separately for each page and role.
+ *   One or more cache granularity constants. For example, to cache separately
+ *   for each user, use DRUPAL_CACHE_PER_USER. To cache separately for each
+ *   page and role, use the expression:
+ *   @code
+ *   DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE
+ *   @endcode
  *
  * @return
  *   An array of cache ID parts, always containing the active theme. If the
@@ -6008,7 +6090,7 @@ function drupal_render_cid_parts($granularity = NULL) {
 }
 
 /**
- * Create the cache ID for a renderable element.
+ * Creates the cache ID for a renderable element.
  *
  * This creates the cache ID string, either by returning the #cache['cid']
  * property if present or by building the cache ID out of the #cache['keys']
@@ -6055,7 +6137,7 @@ function element_sort_by_title($a, $b) {
 }
 
 /**
- * Retrieve the default properties for the defined element type.
+ * Retrieves the default properties for the defined element type.
  *
  * @param $type
  *   An element type as defined by hook_element_info().
@@ -6081,7 +6163,7 @@ function element_info($type) {
 }
 
 /**
- * Retrieve a single property for the defined element type.
+ * Retrieves a single property for the defined element type.
  *
  * @param $type
  *   An element type as defined by hook_element_info().
@@ -6121,21 +6203,21 @@ function drupal_sort_title($a, $b) {
 }
 
 /**
- * Check if the key is a property.
+ * Checks if the key is a property.
  */
 function element_property($key) {
   return $key[0] == '#';
 }
 
 /**
- * Get properties of a structured array element. Properties begin with '#'.
+ * Gets properties of a structured array element (keys beginning with '#').
  */
 function element_properties($element) {
   return array_filter(array_keys((array) $element), 'element_property');
 }
 
 /**
- * Check if the key is a child.
+ * Checks if the key is a child.
  */
 function element_child($key) {
   return !isset($key[0]) || $key[0] != '#';
@@ -6151,6 +6233,7 @@ function element_child($key) {
  *   The element array whose children are to be identified.
  * @param $sort
  *   Boolean to indicate whether the children should be sorted by weight.
+ *
  * @return
  *   The array keys of the element's children.
  */
@@ -6190,6 +6273,7 @@ function element_children(&$elements, $sort = FALSE) {
  *
  * @param $elements
  *   The parent element.
+ *
  * @return
  *   The array keys of the element's visible children.
  */
@@ -6384,7 +6468,7 @@ function drupal_array_get_nested_value(array &$array, array $parents, &$key_exis
 }
 
 /**
- * Determines whether a nested array with variable depth contains all of the requested keys.
+ * Determines whether a nested array contains the requested keys.
  *
  * This helper function should be used when the depth of the array element to be
  * checked may vary (that is, the number of parent keys is variable). See
@@ -6420,7 +6504,7 @@ function drupal_array_nested_key_exists(array $array, array $parents) {
 }
 
 /**
- * Provide theme registration for themes across .inc files.
+ * Provides theme registration for themes across .inc files.
  */
 function drupal_common_theme() {
   return array(
@@ -6631,7 +6715,7 @@ function drupal_common_theme() {
  */
 
 /**
- * Creates all tables in a module's hook_schema() implementation.
+ * Creates all tables defined in a module's hook_schema().
  *
  * Note: This function does not pass the module's schema through
  * hook_schema_alter(). The module's tables will be created exactly as the
@@ -6650,7 +6734,7 @@ function drupal_install_schema($module) {
 }
 
 /**
- * Remove all tables that a module defines in its hook_schema().
+ * Removes all tables defined in a module's hook_schema().
  *
  * Note: This function does not pass the module's schema through
  * hook_schema_alter(). The module's tables will be created exactly as the
@@ -6658,6 +6742,7 @@ function drupal_install_schema($module) {
  *
  * @param $module
  *   The module for which the tables will be removed.
+ *
  * @return
  *   An array of arrays with the following key/value pairs:
  *    - success: a boolean indicating whether the query succeeded.
@@ -6713,7 +6798,7 @@ function drupal_get_schema_unprocessed($module, $table = NULL) {
 }
 
 /**
- * Fill in required default values for table definitions returned by hook_schema().
+ * Fills in required default values for table definitions from hook_schema().
  *
  * @param $schema
  *   The schema definition array as it was returned by the module's
@@ -6744,7 +6829,9 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
 }
 
 /**
- * Retrieve a list of fields from a table schema. The list is suitable for use in a SQL query.
+ * Retrieves a list of fields from a table schema.
+ *
+ * The returned list is suitable for use in an SQL query.
  *
  * @param $table
  *   The name of the table from which to retrieve fields.
@@ -6752,7 +6839,7 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
  *   An optional prefix to to all fields.
  *
  * @return An array of fields.
- **/
+ */
 function drupal_schema_fields_sql($table, $prefix = NULL) {
   $schema = drupal_get_schema($table);
   $fields = array_keys($schema['fields']);
@@ -6980,7 +7067,7 @@ function drupal_parse_info_file($filename) {
 }
 
 /**
- * Parse data in Drupal's .info format.
+ * Parses data in Drupal's .info format.
  *
  * Data should be in an .ini-like format to specify values. White-space
  * generally doesn't matter, except inside values:
@@ -7010,6 +7097,7 @@ function drupal_parse_info_file($filename) {
  *
  * @param $data
  *   A string to parse.
+ *
  * @return
  *   The info array.
  *
@@ -7073,11 +7161,12 @@ function drupal_parse_info_format($data) {
 }
 
 /**
- * Severity levels, as defined in RFC 3164: http://www.ietf.org/rfc/rfc3164.txt.
+ * Returns a list of severity levels, as defined in RFC 3164.
  *
  * @return
  *   Array of the possible severity levels for log messages.
  *
+ * @see http://www.ietf.org/rfc/rfc3164.txt
  * @see watchdog()
  * @ingroup logging_severity_levels
  */
@@ -7096,7 +7185,7 @@ function watchdog_severity_levels() {
 
 
 /**
- * Explode a string of given tags into an array.
+ * Explodes a string of tags into an array.
  *
  * @see drupal_implode_tags()
  */
@@ -7122,7 +7211,7 @@ function drupal_explode_tags($tags) {
 }
 
 /**
- * Implode an array of tags into a string.
+ * Implodes an array of tags into a string.
  *
  * @see drupal_explode_tags()
  */
@@ -7140,7 +7229,7 @@ function drupal_implode_tags($tags) {
 }
 
 /**
- * Flush all cached data on the site.
+ * Flushes all cached data on the site.
  *
  * Empties cache tables, rebuilds the menu cache and theme registries, and
  * invokes a hook so that other modules' cache data can be cleared as well.
@@ -7158,6 +7247,7 @@ function drupal_flush_all_caches() {
   system_rebuild_theme_data();
   drupal_theme_rebuild();
 
+  entity_info_cache_clear();
   node_types_rebuild();
   // node_menu() defines menu items based on node types so it needs to come
   // after node types are rebuilt.
@@ -7181,10 +7271,10 @@ function drupal_flush_all_caches() {
 }
 
 /**
- * Helper function to change query-strings on css/js files.
+ * Changes the dummy query string added to all CSS and JavaScript files.
  *
- * Changes the character added to all css/js files as dummy query-string, so
- * that all browsers are forced to reload fresh files.
+ * Changing the dummy query string appended to CSS and JavaScript files forces
+ * all browsers to reload fresh files.
  */
 function _drupal_flush_css_js() {
   // The timestamp is converted to base 36 in order to make it more compact.
@@ -7192,7 +7282,7 @@ function _drupal_flush_css_js() {
 }
 
 /**
- * Debug function used for outputting debug information.
+ * Outputs debug information.
  *
  * The debug information is passed on to trigger_error() after being converted
  * to a string using _drupal_debug_message().
@@ -7217,10 +7307,11 @@ function debug($data, $label = NULL, $print_r = FALSE) {
 }
 
 /**
- * Parse a dependency for comparison by drupal_check_incompatibility().
+ * Parses a dependency for comparison by drupal_check_incompatibility().
  *
  * @param $dependency
  *   A dependency string, for example 'foo (>=7.x-4.5-beta5, 3.x)'.
+ *
  * @return
  *   An associative array with three keys:
  *   - 'name' includes the name of the thing to depend on (e.g. 'foo').
@@ -7274,12 +7365,13 @@ function drupal_parse_dependency($dependency) {
 }
 
 /**
- * Check whether a version is compatible with a given dependency.
+ * Checks whether a version is compatible with a given dependency.
  *
  * @param $v
  *   The parsed dependency structure from drupal_parse_dependency().
  * @param $current_version
  *   The version to check against (like 4.2).
+ *
  * @return
  *   NULL if compatible, otherwise the original dependency version string that
  *   caused the incompatibility.
@@ -7784,11 +7876,12 @@ function archiver_get_extensions() {
 }
 
 /**
- * Create the appropriate archiver for the specified file.
+ * Creates the appropriate archiver for the specified file.
  *
  * @param $file
- *   The full path of the archive file.  Note that stream wrapper
- *   paths are supported, but not remote ones.
+ *   The full path of the archive file. Note that stream wrapper paths are
+ *   supported, but not remote ones.
+ *
  * @return
  *   A newly created instance of the archiver class appropriate
  *   for the specified file, already bound to that file.
@@ -7817,14 +7910,14 @@ function archiver_get_archiver($file) {
 }
 
 /**
- * Drupal Updater registry.
+ * Assembles the Drupal Updater registry.
  *
  * An Updater is a class that knows how to update various parts of the Drupal
  * file system, for example to update modules that have newer releases, or to
  * install a new theme.
  *
  * @return
- *   Returns the Drupal Updater class registry.
+ *   The Drupal Updater class registry.
  *
  * @see hook_updater_info()
  * @see hook_updater_info_alter()
@@ -7840,10 +7933,10 @@ function drupal_get_updaters() {
 }
 
 /**
- * Drupal FileTransfer registry.
+ * Assembles the Drupal FileTransfer registry.
  *
  * @return
- *   Returns the Drupal FileTransfer class registry.
+ *   The Drupal FileTransfer class registry.
  *
  * @see FileTransfer
  * @see hook_filetransfer_info()
diff --git a/includes/database/database.inc b/includes/database/database.inc
index 33000aa7..6e40b276 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -1016,9 +1016,9 @@ abstract class DatabaseConnection extends PDO {
       throw new DatabaseTransactionNoActiveException();
     }
     // A previous rollback to an earlier savepoint may mean that the savepoint
-    // in question has already been rolled back.
-    if (!in_array($savepoint_name, $this->transactionLayers)) {
-      return;
+    // in question has already been accidentally committed.
+    if (!isset($this->transactionLayers[$savepoint_name])) {
+      throw new DatabaseTransactionNoActiveException();
     }
 
     // We need to find the point we're rolling back to, all other savepoints
@@ -1096,8 +1096,12 @@ abstract class DatabaseConnection extends PDO {
     if (!$this->supportsTransactions()) {
       return;
     }
+    // The transaction has already been committed earlier. There is nothing we
+    // need to do. If this transaction was part of an earlier out-of-order
+    // rollback, an exception would already have been thrown by
+    // Database::rollback().
     if (!isset($this->transactionLayers[$name])) {
-      throw new DatabaseTransactionNoActiveException();
+      return;
     }
 
     // Mark this layer as committable.
diff --git a/includes/database/mysql/database.inc b/includes/database/mysql/database.inc
index 7d5d8599..e024a7f3 100644
--- a/includes/database/mysql/database.inc
+++ b/includes/database/mysql/database.inc
@@ -37,14 +37,20 @@ class DatabaseConnection_mysql extends DatabaseConnection {
       $dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']);
     }
     $dsn .= ';dbname=' . $connection_options['database'];
-    parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(
+    // Allow PDO options to be overridden.
+    $connection_options += array(
+      'pdo' => array(),
+    );
+    $connection_options['pdo'] += array(
       // So we don't have to mess around with cursors and unbuffered queries by default.
       PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE,
       // Because MySQL's prepared statements skip the query cache, because it's dumb.
       PDO::ATTR_EMULATE_PREPARES => TRUE,
       // Force column names to lower case.
       PDO::ATTR_CASE => PDO::CASE_LOWER,
-    ));
+    );
+
+    parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
 
     // Force MySQL to use the UTF-8 character set. Also set the collation, if a
     // certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
@@ -56,14 +62,22 @@ class DatabaseConnection_mysql extends DatabaseConnection {
       $this->exec('SET NAMES utf8');
     }
 
-    // Force MySQL's behavior to conform more closely to SQL standards.
-    // This allows Drupal to run almost seamlessly on many different
-    // kinds of database systems. These settings force MySQL to behave
-    // the same as postgresql, or sqlite in regards to syntax interpretation
-    // and invalid data handling. See http://drupal.org/node/344575 for
-    // further discussion. Also, as MySQL 5.5 changed the meaning of
-    // TRADITIONAL we need to spell out the modes one by one.
-    $this->exec("SET sql_mode='ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'");
+    // Set MySQL init_commands if not already defined.  Default Drupal's MySQL
+    // behavior to conform more closely to SQL standards.  This allows Drupal
+    // to run almost seamlessly on many different kinds of database systems.
+    // These settings force MySQL to behave the same as postgresql, or sqlite
+    // in regards to syntax interpretation and invalid data handling.  See
+    // http://drupal.org/node/344575 for further discussion. Also, as MySQL 5.5
+    // changed the meaning of TRADITIONAL we need to spell out the modes one by
+    // one.
+    $connection_options += array(
+      'init_commands' => array(),
+    );
+    $connection_options['init_commands'] += array(
+      'sql_mode' => "SET sql_mode = 'ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'",
+    );
+    // Set connection options.
+    $this->exec(implode('; ', $connection_options['init_commands']));
   }
 
   public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
@@ -169,8 +183,11 @@ class DatabaseConnection_mysql extends DatabaseConnection {
           // succeed for MySQL error code 1305 ("SAVEPOINT does not exist").
           if ($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' => 'drupal_transaction');
+            // Therefore, clean the transaction stack.
+            $this->transactionLayers = array();
+            // We also have to explain to PDO that the transaction stack has
+            // been cleaned-up.
+            PDO::commit();
           }
           else {
             throw $e;
diff --git a/includes/database/pgsql/database.inc b/includes/database/pgsql/database.inc
index 39b4e9b6..d42a1cc3 100644
--- a/includes/database/pgsql/database.inc
+++ b/includes/database/pgsql/database.inc
@@ -47,7 +47,12 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
     $this->connectionOptions = $connection_options;
 
     $dsn = 'pgsql:host=' . $connection_options['host'] . ' dbname=' . $connection_options['database'] . ' port=' . $connection_options['port'];
-    parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(
+
+    // Allow PDO options to be overridden.
+    $connection_options += array(
+      'pdo' => array(),
+    );
+    $connection_options['pdo'] += array(
       // Prepared statements are most effective for performance when queries
       // are recycled (used several times). However, if they are not re-used,
       // prepared statements become ineffecient. Since most of Drupal's
@@ -59,10 +64,16 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
       PDO::ATTR_STRINGIFY_FETCHES => TRUE,
       // Force column names to lower case.
       PDO::ATTR_CASE => PDO::CASE_LOWER,
-    ));
+    );
+    parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
 
     // Force PostgreSQL to use the UTF-8 character set by default.
     $this->exec("SET NAMES 'UTF8'");
+
+    // Execute PostgreSQL init_commands.
+    if (isset($connection_options['init_commands'])) {
+      $this->exec(implode('; ', $connection_options['init_commands']));
+    }
   }
 
   public function query($query, array $args = array(), $options = array()) {
diff --git a/includes/database/query.inc b/includes/database/query.inc
index c7796876..6020b0ea 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -22,6 +22,9 @@ interface QueryConditionInterface {
    * parameters, they are taken as $field and $value with $operator having a
    * value of IN if $value is an array and = otherwise.
    *
+   * Do not use this method to test for NULL values. Instead, use
+   * QueryConditionInterface::isNull() or QueryConditionInterface::isNotNull().
+   *
    * @param $field
    *   The name of the field to check. If you would like to add a more complex
    *   condition involving operators or functions, use where().
@@ -36,6 +39,9 @@ interface QueryConditionInterface {
    *
    * @return QueryConditionInterface
    *   The called object.
+   *
+   * @see QueryConditionInterface::isNull()
+   * @see QueryConditionInterface::isNotNull()
    */
   public function condition($field, $value = NULL, $operator = NULL);
 
diff --git a/includes/database/select.inc b/includes/database/select.inc
index 9b587aeb..7e2af85e 100644
--- a/includes/database/select.inc
+++ b/includes/database/select.inc
@@ -590,11 +590,13 @@ class SelectQueryExtender implements SelectQueryInterface {
   }
 
   public function hasAllTags() {
-    return call_user_func_array(array($this->query, 'hasAllTags'), func_get_args());
+    $args = func_get_args();
+    return call_user_func_array(array($this->query, 'hasAllTags'), $args);
   }
 
   public function hasAnyTag() {
-    return call_user_func_array(array($this->query, 'hasAnyTags'), func_get_args());
+    $args = func_get_args();
+    return call_user_func_array(array($this->query, 'hasAnyTags'), $args);
   }
 
   public function addMetaData($key, $object) {
@@ -637,16 +639,16 @@ class SelectQueryExtender implements SelectQueryInterface {
   /* Implementations of QueryConditionInterface for the HAVING clause. */
 
   public function havingCondition($field, $value = NULL, $operator = '=') {
-    $this->query->condition($field, $value, $operator, $num_args);
+    $this->query->havingCondition($field, $value, $operator);
     return $this;
   }
 
   public function &havingConditions() {
-    return $this->having->conditions();
+    return $this->query->havingConditions();
   }
 
   public function havingArguments() {
-    return $this->having->arguments();
+    return $this->query->havingArguments();
   }
 
   public function having($snippet, $args = array()) {
@@ -790,31 +792,7 @@ class SelectQueryExtender implements SelectQueryInterface {
   }
 
   public function countQuery() {
-    // Create our new query object that we will mutate into a count query.
-    $count = clone($this);
-
-    // Zero-out existing fields and expressions.
-    $fields =& $count->getFields();
-    $fields = array();
-    $expressions =& $count->getExpressions();
-    $expressions = array();
-
-    // Also remove 'all_fields' statements, which are expanded into tablename.*
-    // when the query is executed.
-    $tables = &$count->getTables();
-    foreach ($tables as $alias => &$table) {
-      unset($table['all_fields']);
-    }
-
-    // Ordering a count query is a waste of cycles, and breaks on some
-    // databases anyway.
-    $orders = &$count->getOrderBy();
-    $orders = array();
-
-    // COUNT() is an expression, so we add that back in.
-    $count->addExpression('COUNT(*)');
-
-    return $count;
+    return $this->query->countQuery();
   }
 
   function isNull($field) {
@@ -836,7 +814,7 @@ class SelectQueryExtender implements SelectQueryInterface {
     $this->query->notExists($select);
     return $this;
   }
-  
+
   public function __toString() {
     return (string) $this->query;
   }
@@ -1005,11 +983,13 @@ class SelectQuery extends Query implements SelectQueryInterface {
   }
 
   public function hasAllTags() {
-    return !(boolean)array_diff(func_get_args(), array_keys($this->alterTags));
+    $args = func_get_args();
+    return !(boolean)array_diff($args, array_keys($this->alterTags));
   }
 
   public function hasAnyTag() {
-    return (boolean)array_intersect(func_get_args(), array_keys($this->alterTags));
+    $args = func_get_args();
+    return (boolean)array_intersect($args, array_keys($this->alterTags));
   }
 
   public function addMetaData($key, $object) {
@@ -1088,7 +1068,7 @@ class SelectQuery extends Query implements SelectQueryInterface {
     $this->where->notExists($select);
     return $this;
   }
-  
+
   public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder) {
     $this->where->compile($connection, $queryPlaceholder);
     $this->having->compile($connection, $queryPlaceholder);
@@ -1172,17 +1152,17 @@ class SelectQuery extends Query implements SelectQueryInterface {
     $this->having->isNotNull($field);
     return $this;
   }
-  
+
   public function havingExists(SelectQueryInterface $select) {
     $this->having->exists($select);
     return $this;
   }
-  
+
   public function havingNotExists(SelectQueryInterface $select) {
     $this->having->notExists($select);
     return $this;
   }
-  
+
   public function forUpdate($set = TRUE) {
     if (isset($set)) {
       $this->forUpdate = $set;
@@ -1451,17 +1431,20 @@ class SelectQuery extends Query implements SelectQueryInterface {
     $count = clone($this);
 
     $group_by = $count->getGroupBy();
+    $having = $count->havingConditions();
 
-    if (!$count->distinct) {
+    if (!$count->distinct && !isset($having[0])) {
       // When not executing a distinct query, we can zero-out existing fields
-      // and expressions that are not used by a GROUP BY.  Fields listed in
-      // the GROUP BY clause need to be present in the query.
+      // and expressions that are not used by a GROUP BY or HAVING. Fields
+      // listed in a GROUP BY or HAVING clause need to be present in the
+      // query.
       $fields =& $count->getFields();
       foreach (array_keys($fields) as $field) {
         if (empty($group_by[$field])) {
           unset($fields[$field]);
         }
       }
+
       $expressions =& $count->getExpressions();
       foreach (array_keys($expressions) as $field) {
         if (empty($group_by[$field])) {
diff --git a/includes/database/sqlite/database.inc b/includes/database/sqlite/database.inc
index 3e2490b0..b4e41b52 100644
--- a/includes/database/sqlite/database.inc
+++ b/includes/database/sqlite/database.inc
@@ -59,16 +59,21 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
     $this->statementClass = NULL;
 
     // This driver defaults to transaction support, except if explicitly passed FALSE.
-    $this->transactionSupport = !isset($connection_options['transactions']) || $connection_options['transactions'] !== FALSE;
+    $this->transactionSupport = $this->transactionalDDLSupport = !isset($connection_options['transactions']) || $connection_options['transactions'] !== FALSE;
 
     $this->connectionOptions = $connection_options;
 
-    parent::__construct('sqlite:' . $connection_options['database'], '', '', array(
+    // Allow PDO options to be overridden.
+    $connection_options += array(
+      'pdo' => array(),
+    );
+    $connection_options['pdo'] += array(
       // Force column names to lower case.
       PDO::ATTR_CASE => PDO::CASE_LOWER,
       // Convert numeric values to strings when fetching.
       PDO::ATTR_STRINGIFY_FETCHES => TRUE,
-    ));
+    );
+    parent::__construct('sqlite:' . $connection_options['database'], '', '', $connection_options['pdo']);
 
     // Attach one database for each registered prefix.
     $prefixes = $this->prefixes;
@@ -103,6 +108,11 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
     $this->sqliteCreateFunction('substring', array($this, 'sqlFunctionSubstring'), 3);
     $this->sqliteCreateFunction('substring_index', array($this, 'sqlFunctionSubstringIndex'), 3);
     $this->sqliteCreateFunction('rand', array($this, 'sqlFunctionRand'));
+
+    // Execute sqlite init_commands.
+    if (isset($connection_options['init_commands'])) {
+      $this->exec(implode('; ', $connection_options['init_commands']));
+    }
   }
 
   /**
diff --git a/includes/file.inc b/includes/file.inc
index 40e8349a..7fd6c71c 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -770,7 +770,7 @@ function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS
     $file = clone $source;
     $file->fid = NULL;
     $file->uri = $uri;
-    $file->filename = basename($uri);
+    $file->filename = drupal_basename($uri);
     // If we are replacing an existing file re-use its database record.
     if ($replace == FILE_EXISTS_REPLACE) {
       $existing_files = file_load_multiple(array(), array('uri' => $uri));
@@ -783,7 +783,7 @@ function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS
     // If we are renaming around an existing file (rather than a directory),
     // use its basename for the filename.
     elseif ($replace == FILE_EXISTS_RENAME && is_file($destination)) {
-      $file->filename = basename($destination);
+      $file->filename = drupal_basename($destination);
     }
 
     $file = file_save($file);
@@ -828,6 +828,10 @@ function file_valid_uri($uri) {
  *   is reported.
  * - If file already exists in $destination either the call will error out,
  *   replace the file or rename the file based on the $replace parameter.
+ * - Provides a fallback using realpaths if the move fails using stream
+ *   wrappers. This can occur because PHP's copy() function does not properly
+ *   support streams if safe_mode or open_basedir are enabled. See
+ *   https://bugs.php.net/bug.php?id=60456
  *
  * @param $source
  *   A string specifying the filepath or URI of the source file.
@@ -867,14 +871,14 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST
 
   // Build a destination URI if necessary.
   if (!isset($destination)) {
-    $destination = file_build_uri(basename($source));
+    $destination = file_build_uri(drupal_basename($source));
   }
 
 
   // Prepare the destination directory.
   if (file_prepare_directory($destination)) {
     // The destination is already a directory, so append the source basename.
-    $destination = file_stream_wrapper_uri_normalize($destination . '/' . basename($source));
+    $destination = file_stream_wrapper_uri_normalize($destination . '/' . drupal_basename($source));
   }
   else {
     // Perhaps $destination is a dir/file?
@@ -907,8 +911,12 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST
   file_ensure_htaccess();
   // Perform the copy operation.
   if (!@copy($source, $destination)) {
-    watchdog('file', 'The specified file %file could not be copied to %destination.', array('%file' => $source, '%destination' => $destination), WATCHDOG_ERROR);
-    return FALSE;
+    // If the copy failed and realpaths exist, retry the operation using them
+    // instead.
+    if ($real_source === FALSE || $real_destination === FALSE || !@copy($real_source, $real_destination)) {
+      watchdog('file', 'The specified file %file could not be copied to %destination.', array('%file' => $source, '%destination' => $destination), WATCHDOG_ERROR);
+      return FALSE;
+    }
   }
 
   // Set the permissions on the new file.
@@ -950,7 +958,7 @@ function file_destination($destination, $replace) {
         break;
 
       case FILE_EXISTS_RENAME:
-        $basename = basename($destination);
+        $basename = drupal_basename($destination);
         $directory = drupal_dirname($destination);
         $destination = file_create_filename($basename, $directory);
         break;
@@ -1025,7 +1033,7 @@ function file_move(stdClass $source, $destination = NULL, $replace = FILE_EXISTS
     // If we are renaming around an existing file (rather than a directory),
     // use its basename for the filename.
     elseif ($replace == FILE_EXISTS_RENAME && is_file($destination)) {
-      $file->filename = basename($destination);
+      $file->filename = drupal_basename($destination);
     }
 
     $file = file_save($file);
@@ -1138,7 +1146,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
 }
 
 /**
- * Undo the effect of upload_munge_filename().
+ * Undo the effect of file_munge_filename().
  *
  * @param $filename
  *   String with the filename to be unmunged.
@@ -1443,7 +1451,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
   $file = new stdClass();
   $file->uid      = $user->uid;
   $file->status   = 0;
-  $file->filename = trim(basename($_FILES['files']['name'][$source]), '.');
+  $file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
   $file->uri      = $_FILES['files']['tmp_name'][$source];
   $file->filemime = file_get_mimetype($file->filename);
   $file->filesize = $_FILES['files']['size'][$source];
@@ -1841,7 +1849,7 @@ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAM
     $file = new stdClass();
     $file->fid = NULL;
     $file->uri = $uri;
-    $file->filename = basename($uri);
+    $file->filename = drupal_basename($uri);
     $file->filemime = file_get_mimetype($file->uri);
     $file->uid      = $user->uid;
     $file->status   = FILE_STATUS_PERMANENT;
@@ -1857,7 +1865,7 @@ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAM
     // If we are renaming around an existing file (rather than a directory),
     // use its basename for the filename.
     elseif ($replace == FILE_EXISTS_RENAME && is_file($destination)) {
-      $file->filename = basename($destination);
+      $file->filename = drupal_basename($destination);
     }
 
     return file_save($file);
@@ -2266,6 +2274,35 @@ function drupal_dirname($uri) {
   }
 }
 
+/**
+ * Gets the filename from a given path.
+ *
+ * PHP's basename() does not properly support streams or filenames beginning
+ * with a non-US-ASCII character.
+ *
+ * @see http://bugs.php.net/bug.php?id=37738
+ * @see basename()
+ *
+ * @ingroup php_wrappers
+ */
+function drupal_basename($uri, $suffix = NULL) {
+  $separators = '/';
+  if (DIRECTORY_SEPARATOR != '/') {
+    // For Windows OS add special separator.
+    $separators .= DIRECTORY_SEPARATOR;
+  }
+  // Remove right-most slashes when $uri points to directory.
+  $uri = rtrim($uri, $separators);
+  // Returns the trailing part of the $uri starting after one of the directory
+  // separators.
+  $filename = preg_match('@[^' . preg_quote($separators, '@') . ']+$@', $uri, $matches) ? $matches[0] : '';
+  // Cuts off a suffix from the filename.
+  if ($suffix) {
+    $filename = preg_replace('@' . preg_quote($suffix, '@') . '$@', '', $filename);
+  }
+  return $filename;
+}
+
 /**
  * Creates a directory using Drupal's default mode.
  *
@@ -2362,7 +2399,7 @@ function drupal_tempnam($directory, $prefix) {
     $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
 
     if ($filename = tempnam($wrapper->getDirectoryPath(), $prefix)) {
-      return $scheme . '://' . basename($filename);
+      return $scheme . '://' . drupal_basename($filename);
     }
     else {
       return FALSE;
diff --git a/includes/filetransfer/filetransfer.inc b/includes/filetransfer/filetransfer.inc
index 2083da9d..bd2057cd 100644
--- a/includes/filetransfer/filetransfer.inc
+++ b/includes/filetransfer/filetransfer.inc
@@ -211,7 +211,7 @@ abstract class FileTransfer {
    */
   protected function copyDirectoryJailed($source, $destination) {
     if ($this->isDirectory($destination)) {
-      $destination = $destination . '/' . basename($source);
+      $destination = $destination . '/' . drupal_basename($source);
     }
     $this->createDirectory($destination);
     foreach (new RecursiveIteratorIterator(new SkipDotsRecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST) as $filename => $file) {
@@ -302,9 +302,9 @@ abstract class FileTransfer {
     $chroot = '';
     while (count($parts)) {
       $check = implode($parts, '/');
-      if ($this->isFile($check . '/' . basename(__FILE__))) {
+      if ($this->isFile($check . '/' . drupal_basename(__FILE__))) {
         // Remove the trailing slash.
-        return substr($chroot,0,-1);
+        return substr($chroot, 0, -1);
       }
       $chroot .= array_shift($parts) . '/';
     }
diff --git a/includes/form.inc b/includes/form.inc
index e0bc9cba..3d5f6f22 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -16,7 +16,7 @@
  * \@see user_pass_validate().
  * \@see user_pass_submit().
  *
- * @} End of "defgroup forms".
+ * @}
  */
 
 /**
@@ -156,6 +156,8 @@ function drupal_get_form($form_id) {
  *       automatically loaded by form_get_cache(). By default the current menu
  *       router item's 'file' definition is added, if any. Use
  *       form_load_include() to add include files from a form constructor.
+ *     - base_form_id: Identification for a base form, as declared in a
+ *       hook_forms() implementation.
  *   - rebuild_info: Internal. Similar to 'build_info', but pertaining to
  *     drupal_rebuild_form().
  *   - rebuild: Normally, after the entire form processing is completed and
@@ -3349,6 +3351,13 @@ function form_process_machine_name($element, &$form_state) {
     'replace' => '_',
   );
 
+  // By default, machine names are restricted to Latin alphanumeric characters.
+  // So, default to LTR directionality.
+  if (!isset($element['#attributes'])) {
+    $element['#attributes'] = array();
+  }
+  $element['#attributes'] += array('dir' => 'ltr');
+
   // The source element defaults to array('name'), but may have been overidden.
   if (empty($element['#machine_name']['source'])) {
     return $element;
@@ -3786,13 +3795,27 @@ function theme_password($variables) {
  * Expand weight elements into selects.
  */
 function form_process_weight($element) {
-  for ($n = (-1 * $element['#delta']); $n <= $element['#delta']; $n++) {
-    $weights[$n] = $n;
-  }
-  $element['#options'] = $weights;
-  $element['#type'] = 'select';
   $element['#is_weight'] = TRUE;
-  $element += element_info('select');
+
+  // If the number of options is small enough, use a select field.
+  $max_elements = variable_get('drupal_weight_select_max', DRUPAL_WEIGHT_SELECT_MAX);
+  if ($element['#delta'] <= $max_elements) {
+    $element['#type'] = 'select';
+    for ($n = (-1 * $element['#delta']); $n <= $element['#delta']; $n++) {
+      $weights[$n] = $n;
+    }
+    $element['#options'] = $weights;
+    $element += element_info('select');
+  }
+  // Otherwise, use a text field.
+  else {
+    $element['#type'] = 'textfield';
+    // Use a field big enough to fit most weights.
+    $element['#size'] = 10;
+    $element['#element_validate'] = array('element_validate_integer');
+    $element += element_info('textfield');
+  }
+
   return $element;
 }
 
@@ -3976,7 +3999,7 @@ function theme_form_element_label($variables) {
   $t = get_t();
 
   // If title and required marker are both empty, output no label.
-  if (empty($element['#title']) && empty($element['#required'])) {
+  if ((!isset($element['#title']) || $element['#title'] === '') && empty($element['#required'])) {
     return '';
   }
 
diff --git a/includes/graph.inc b/includes/graph.inc
index 416fad6d..7fcc57a4 100644
--- a/includes/graph.inc
+++ b/includes/graph.inc
@@ -143,4 +143,3 @@ function _drupal_depth_first_search(&$graph, &$state, $start, &$component = NULL
   // topological order if the graph is acyclic.
   $state['last_visit_order'][] = $start;
 }
-
diff --git a/includes/image.inc b/includes/image.inc
index 8dc36b99..f6ae7f19 100644
--- a/includes/image.inc
+++ b/includes/image.inc
@@ -186,14 +186,14 @@ function image_scale_and_crop(stdClass $image, $width, $height) {
  *   Dimensions to be modified - an array with components width and height, in
  *   pixels.
  * @param $width
- *   The target width, in pixels. This value is omitted then the scaling will
+ *   The target width, in pixels. If this value is NULL then the scaling will be
  *   based only on the height value.
  * @param $height
- *   The target height, in pixels. This value is omitted then the scaling will
- *   based only on the width value.
+ *   The target height, in pixels. If this value is NULL then the scaling will
+ *   be based only on the width value.
  * @param $upscale
- *   Boolean indicating that files smaller than the dimensions will be scaled
- *   up. This generally results in a low quality image.
+ *   Boolean indicating that images smaller than the target dimensions will be
+ *   scaled up. This generally results in a low quality image.
  *
  * @return
  *   TRUE if $dimensions was modified, FALSE otherwise.
@@ -203,31 +203,25 @@ function image_scale_and_crop(stdClass $image, $width, $height) {
 function image_dimensions_scale(array &$dimensions, $width = NULL, $height = NULL, $upscale = FALSE) {
   $aspect = $dimensions['height'] / $dimensions['width'];
 
-  if ($upscale) {
-    // Set width/height according to aspect ratio if either is empty.
-    $width = !empty($width) ? $width : $height / $aspect;
-    $height = !empty($height) ? $height : $width / $aspect;
+  // Calculate one of the dimensions from the other target dimension,
+  // ensuring the same aspect ratio as the source dimensions. If one of the
+  // target dimensions is missing, that is the one that is calculated. If both
+  // are specified then the dimension calculated is the one that would not be
+  // calculated to be bigger than its target.
+  if (($width && !$height) || ($width && $height && $aspect < $height / $width)) {
+    $height = (int) round($width * $aspect);
   }
   else {
-    // Set impossibly large values if the width and height aren't set.
-    $width = !empty($width) ? $width : 9999999;
-    $height = !empty($height) ? $height : 9999999;
-
-    // Don't scale up.
-    if (round($width) >= $dimensions['width'] && round($height) >= $dimensions['height']) {
-      return FALSE;
-    }
+    $width = (int) round($height / $aspect);
   }
 
-  if ($aspect < $height / $width) {
-    $dimensions['width'] = $width;
-    $dimensions['height'] = (int) round($width * $aspect);
-  }
-  else {
-    $dimensions['width'] = (int) round($height / $aspect);
-    $dimensions['height'] = $height;
+  // Don't upscale if the option isn't enabled.
+  if (!$upscale && ($width >= $dimensions['width'] || $height >= $dimensions['height'])) {
+    return FALSE;
   }
 
+  $dimensions['width'] = $width;
+  $dimensions['height'] = $height;
   return TRUE;
 }
 
diff --git a/includes/json-encode.inc b/includes/json-encode.inc
new file mode 100644
index 00000000..1efd6ddb
--- /dev/null
+++ b/includes/json-encode.inc
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * @file
+ * Provides a helper to properly encode HTML-safe JSON prior to PHP 5.3.0.
+ */
+
+/**
+ * Encodes a PHP variable to HTML-safe JSON for PHP versions below 5.3.0.
+ *
+ * @see drupal_json_encode()
+ */
+function drupal_json_encode_helper($var) {
+  switch (gettype($var)) {
+    case 'boolean':
+      return $var ? 'true' : 'false'; // Lowercase necessary!
+
+    case 'integer':
+    case 'double':
+      return $var;
+
+    case 'resource':
+    case 'string':
+      // Always use Unicode escape sequences (\u0022) over JSON escape
+      // sequences (\") to prevent browsers interpreting these as
+      // special characters.
+      $replace_pairs = array(
+        // ", \ and U+0000 - U+001F must be escaped according to RFC 4627.
+        '\\' => '\u005C',
+        '"' => '\u0022',
+        "\x00" => '\u0000',
+        "\x01" => '\u0001',
+        "\x02" => '\u0002',
+        "\x03" => '\u0003',
+        "\x04" => '\u0004',
+        "\x05" => '\u0005',
+        "\x06" => '\u0006',
+        "\x07" => '\u0007',
+        "\x08" => '\u0008',
+        "\x09" => '\u0009',
+        "\x0a" => '\u000A',
+        "\x0b" => '\u000B',
+        "\x0c" => '\u000C',
+        "\x0d" => '\u000D',
+        "\x0e" => '\u000E',
+        "\x0f" => '\u000F',
+        "\x10" => '\u0010',
+        "\x11" => '\u0011',
+        "\x12" => '\u0012',
+        "\x13" => '\u0013',
+        "\x14" => '\u0014',
+        "\x15" => '\u0015',
+        "\x16" => '\u0016',
+        "\x17" => '\u0017',
+        "\x18" => '\u0018',
+        "\x19" => '\u0019',
+        "\x1a" => '\u001A',
+        "\x1b" => '\u001B',
+        "\x1c" => '\u001C',
+        "\x1d" => '\u001D',
+        "\x1e" => '\u001E',
+        "\x1f" => '\u001F',
+        // Prevent browsers from interpreting these as as special.
+        "'" => '\u0027',
+        '<' => '\u003C',
+        '>' => '\u003E',
+        '&' => '\u0026',
+        // Prevent browsers from interpreting the solidus as special and
+        // non-compliant JSON parsers from interpreting // as a comment.
+        '/' => '\u002F',
+        // While these are allowed unescaped according to ECMA-262, section
+        // 15.12.2, they cause problems in some JSON parsers.
+        "\xe2\x80\xa8" => '\u2028', // U+2028, Line Separator.
+        "\xe2\x80\xa9" => '\u2029', // U+2029, Paragraph Separator.
+      );
+
+      return '"' . strtr($var, $replace_pairs) . '"';
+
+    case 'array':
+      // Arrays in JSON can't be associative. If the array is empty or if it
+      // has sequential whole number keys starting with 0, it's not associative
+      // so we can go ahead and convert it as an array.
+      if (empty($var) || array_keys($var) === range(0, sizeof($var) - 1)) {
+        $output = array();
+        foreach ($var as $v) {
+          $output[] = drupal_json_encode_helper($v);
+        }
+        return '[ ' . implode(', ', $output) . ' ]';
+      }
+      // Otherwise, fall through to convert the array as an object.
+
+    case 'object':
+      $output = array();
+      foreach ($var as $k => $v) {
+        $output[] = drupal_json_encode_helper(strval($k)) . ':' . drupal_json_encode_helper($v);
+      }
+      return '{' . implode(', ', $output) . '}';
+
+    default:
+      return 'null';
+  }
+}
diff --git a/includes/locale.inc b/includes/locale.inc
index a00887d2..0db4d4a0 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -2293,7 +2293,7 @@ function _locale_batch_import($filepath, &$context) {
   // The filename is either {langcode}.po or {prefix}.{langcode}.po, so
   // we can extract the language code to use for the import from the end.
   if (preg_match('!(/|\.)([^\./]+)\.po$!', $filepath, $langcode)) {
-    $file = (object) array('filename' => basename($filepath), 'uri' => $filepath);
+    $file = (object) array('filename' => drupal_basename($filepath), 'uri' => $filepath);
     _locale_import_read_po('db-store', $file, LOCALE_IMPORT_KEEP, $langcode[2]);
     $context['results'][] = $filepath;
   }
diff --git a/includes/mail.inc b/includes/mail.inc
index 7272df97..13a6f464 100644
--- a/includes/mail.inc
+++ b/includes/mail.inc
@@ -57,6 +57,12 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
  *     user_mail_tokens($variables, $data, $options);
  *     switch($key) {
  *       case 'notice':
+ *         // If the recipient can receive such notices by instant-message, do
+ *         // not send by email.
+ *         if (example_im_send($key, $message, $params)) {
+ *           $message['send'] = FALSE;
+ *           break;
+ *         }
  *         $langcode = $message['language']->language;
  *         $message['subject'] = t('Notification from !site', $variables, array('langcode' => $langcode));
  *         $message['body'][] = t("Dear !username\n\nThere is new content available on the site.", $variables, array('langcode' => $langcode));
@@ -65,6 +71,19 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
  *   }
  * @endcode
  *
+ * Another example, which uses drupal_mail() to format a message for sending
+ * later:
+ *
+ * @code
+ *   $params = array('current_conditions' => $data);
+ *   $to = 'user@example.com';
+ *   $message = drupal_mail('example', 'notice', $to, $language, $params, FALSE);
+ *   // Only add to the spool if sending was not canceled.
+ *   if ($message['send']) {
+ *     example_spool_message($message);
+ *   }
+ * @endcode
+ *
  * @param $module
  *   A module name to invoke hook_mail() on. The {$module}_mail() hook will be
  *   called to complete the $message structure which will already contain common
@@ -86,8 +105,10 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
  * @param $from
  *   Sets From to this value, if given.
  * @param $send
- *   Send the message directly, without calling drupal_mail_system()->mail()
- *   manually.
+ *   If TRUE, drupal_mail() will call drupal_mail_system()->mail() to deliver
+ *   the message, and store the result in $message['result']. Modules
+ *   implementing hook_mail_alter() may cancel sending by setting
+ *   $message['send'] to FALSE.
  *
  * @return
  *   The $message array structure containing all details of the
@@ -108,6 +129,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
     'from'     => isset($from) ? $from : $default_from,
     'language' => $language,
     'params'   => $params,
+    'send'     => TRUE,
     'subject'  => '',
     'body'     => array()
   );
@@ -148,12 +170,20 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
 
   // Optionally send e-mail.
   if ($send) {
-    $message['result'] = $system->mail($message);
-
-    // Log errors
-    if (!$message['result']) {
-      watchdog('mail', 'Error sending e-mail (from %from to %to).', array('%from' => $message['from'], '%to' => $message['to']), WATCHDOG_ERROR);
-      drupal_set_message(t('Unable to send e-mail. Contact the site administrator if the problem persists.'), 'error');
+    // The original caller requested sending. Sending was canceled by one or
+    // more hook_mail_alter() implementations. We set 'result' to NULL, because
+    // FALSE indicates an error in sending.
+    if (empty($message['send'])) {
+      $message['result'] = NULL;
+    }
+    // Sending was originally requested and was not canceled.
+    else {
+      $message['result'] = $system->mail($message);
+      // Log errors.
+      if (!$message['result']) {
+        watchdog('mail', 'Error sending e-mail (from %from to %to).', array('%from' => $message['from'], '%to' => $message['to']), WATCHDOG_ERROR);
+        drupal_set_message(t('Unable to send e-mail. Contact the site administrator if the problem persists.'), 'error');
+      }
     }
   }
 
diff --git a/includes/menu.inc b/includes/menu.inc
index dad65d72..25a87af1 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -274,6 +274,20 @@ define('MENU_MAX_DEPTH', 9);
  * @} End of "Menu tree parameters".
  */
 
+/**
+ * Reserved key to identify the most specific menu link for a given path.
+ *
+ * The value of this constant is a hash of the constant name. We use the hash
+ * so that the reserved key is over 32 characters in length and will not
+ * collide with allowed menu names:
+ * @code
+ * sha1('MENU_PREFERRED_LINK') = 1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91
+ * @endcode
+ *
+ * @see menu_link_get_preferred()
+ */
+define('MENU_PREFERRED_LINK', '1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91');
+
 /**
  * Returns the ancestors (and relevant placeholders) for any given path.
  *
@@ -1241,7 +1255,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
         if ($item['access']) {
           // Find a menu link corresponding to the current path. If $active_path
           // is NULL, let menu_link_get_preferred() determine the path.
-          if ($active_link = menu_link_get_preferred($active_path)) {
+          if ($active_link = menu_link_get_preferred($active_path, $menu_name)) {
             // The active link may only be taken into account to build the
             // active trail, if it resides in the requested menu. Otherwise,
             // we'd needlessly re-run _menu_build_tree() queries for every menu
@@ -1325,6 +1339,8 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
  *     Defaults to 1, which is the default to build a whole tree for a menu, i.e.
  *     excluding menu container itself.
  *   - max_depth: The maximum depth of menu links in the resulting tree.
+ *   - conditions: An associative array of custom database select query
+ *     condition key/value pairs; see _menu_build_tree() for the actual query.
  *
  * @return
  *   A fully built menu tree.
@@ -1408,6 +1424,12 @@ function _menu_build_tree($menu_name, array $parameters = array()) {
     if (isset($parameters['max_depth'])) {
       $query->condition('ml.depth', $parameters['max_depth'], '<=');
     }
+    // Add custom query conditions, if any were passed.
+    if (isset($parameters['conditions'])) {
+      foreach ($parameters['conditions'] as $column => $value) {
+        $query->condition($column, $value);
+      }
+    }
 
     // Build an ordered array of links using the query result object.
     $links = array();
@@ -2260,6 +2282,13 @@ function theme_menu_local_tasks(&$variables) {
 
 /**
  * Set (or get) the active menu for the current page - determines the active trail.
+ *
+ * @return
+ *   An array of menu machine names, in order of preference. The
+ *   'menu_default_active_menus' variable may be used to assert a menu order
+ *   different from the order of creation, or to prevent a particular menu from
+ *   being used at all in the active trail.
+ *   E.g., $conf['menu_default_active_menus'] = array('navigation', 'main-menu')
  */
 function menu_set_active_menu_names($menu_names = NULL) {
   $active = &drupal_static(__FUNCTION__);
@@ -2390,23 +2419,30 @@ function menu_set_active_trail($new_trail = NULL) {
  * @param $path
  *   The path, for example 'node/5'. The function will find the corresponding
  *   menu link ('node/5' if it exists, or fallback to 'node/%').
+ * @param $selected_menu
+ *   The name of a menu used to restrict the search for a preferred menu link.
+ *   If not specified, all the menus returned by menu_get_active_menu_names()
+ *   will be used.
  *
  * @return
- *   A fully translated menu link, or NULL if no matching menu link was
+ *   A fully translated menu link, or FALSE if no matching menu link was
  *   found. The most specific menu link ('node/5' preferred over 'node/%') in
  *   the most preferred menu (as defined by menu_get_active_menu_names()) is
  *   returned.
  */
-function menu_link_get_preferred($path = NULL) {
+function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
   $preferred_links = &drupal_static(__FUNCTION__);
 
   if (!isset($path)) {
     $path = $_GET['q'];
   }
 
-  if (!isset($preferred_links[$path])) {
-    $preferred_links[$path] = FALSE;
+  if (empty($selected_menu)) {
+    // Use an illegal menu name as the key for the preferred menu link.
+    $selected_menu = MENU_PREFERRED_LINK;
+  }
 
+  if (!isset($preferred_links[$path])) {
     // Look for the correct menu link by building a list of candidate paths,
     // which are ordered by priority (translated hrefs are preferred over
     // untranslated paths). Afterwards, the most relevant path is picked from
@@ -2428,6 +2464,8 @@ function menu_link_get_preferred($path = NULL) {
 
     // Retrieve a list of menu names, ordered by preference.
     $menu_names = menu_get_active_menu_names();
+    // Put the selected menu at the front of the list.
+    array_unshift($menu_names, $selected_menu);
 
     $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
     $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
@@ -2435,7 +2473,6 @@ function menu_link_get_preferred($path = NULL) {
     // Weight must be taken from {menu_links}, not {menu_router}.
     $query->addField('ml', 'weight', 'link_weight');
     $query->fields('m');
-    $query->condition('ml.menu_name', $menu_names, 'IN');
     $query->condition('ml.link_path', $path_candidates, 'IN');
 
     // Sort candidates by link path and menu name.
@@ -2443,29 +2480,35 @@ function menu_link_get_preferred($path = NULL) {
     foreach ($query->execute() as $candidate) {
       $candidate['weight'] = $candidate['link_weight'];
       $candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;
+      // Add any menus not already in the menu name search list.
+      if (!in_array($candidate['menu_name'], $menu_names)) {
+        $menu_names[] = $candidate['menu_name'];
+      }
     }
 
-    // Pick the most specific link, in the most preferred menu.
+    // Store the most specific link for each menu. Also save the most specific
+    // link of the most preferred menu in $preferred_link.
     foreach ($path_candidates as $link_path) {
-      if (!isset($candidates[$link_path])) {
-        continue;
-      }
-      foreach ($menu_names as $menu_name) {
-        if (!isset($candidates[$link_path][$menu_name])) {
-          continue;
-        }
-        $candidate_item = $candidates[$link_path][$menu_name];
-        $map = explode('/', $path);
-        _menu_translate($candidate_item, $map);
-        if ($candidate_item['access']) {
-          $preferred_links[$path] = $candidate_item;
+      if (isset($candidates[$link_path])) {
+        foreach ($menu_names as $menu_name) {
+          if (empty($preferred_links[$path][$menu_name]) && isset($candidates[$link_path][$menu_name])) {
+            $candidate_item = $candidates[$link_path][$menu_name];
+            $map = explode('/', $path);
+            _menu_translate($candidate_item, $map);
+            if ($candidate_item['access']) {
+              $preferred_links[$path][$menu_name] = $candidate_item;
+              if (empty($preferred_links[$path][MENU_PREFERRED_LINK])) {
+                // Store the most specific link.
+                $preferred_links[$path][MENU_PREFERRED_LINK] = $candidate_item;
+              }
+            }
+          }
         }
-        break 2;
       }
     }
   }
 
-  return $preferred_links[$path];
+  return isset($preferred_links[$path][$selected_menu]) ? $preferred_links[$path][$selected_menu] : FALSE;
 }
 
 /**
diff --git a/includes/module.inc b/includes/module.inc
index 3a019f26..77e35b7b 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -539,6 +539,7 @@ function module_disable($module_list, $disable_dependents = TRUE) {
     system_list_reset();
     module_list(TRUE);
     module_implements('', FALSE, TRUE);
+    entity_info_cache_clear();
     // Invoke hook_modules_disabled before disabling modules,
     // so we can still call module hooks to get information.
     module_invoke_all('modules_disabled', $invoke_modules);
@@ -1017,4 +1018,3 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
     $function($data, $context1, $context2);
   }
 }
-
diff --git a/includes/password.inc b/includes/password.inc
index c0761da6..d4f5f738 100644
--- a/includes/password.inc
+++ b/includes/password.inc
@@ -285,4 +285,3 @@ function user_needs_new_hash($account) {
   // Check whether the iteration count used differs from the standard number.
   return (_password_get_count_log2($account->pass) !== $count_log2);
 }
-
diff --git a/includes/registry.inc b/includes/registry.inc
index 3fb14fb3..c7b8702c 100644
--- a/includes/registry.inc
+++ b/includes/registry.inc
@@ -183,4 +183,3 @@ function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
 /**
  * @} End of "defgroup registry".
  */
-
diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc
index e47668e3..2af8c9e9 100644
--- a/includes/stream_wrappers.inc
+++ b/includes/stream_wrappers.inc
@@ -317,7 +317,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
     }
 
     $extension = '';
-    $file_parts = explode('.', basename($uri));
+    $file_parts = explode('.', drupal_basename($uri));
 
     // Remove the first part: a full filename should not match an extension.
     array_shift($file_parts);
@@ -377,7 +377,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
     $realpath = realpath($path);
     if (!$realpath) {
       // This file does not yet exist.
-      $realpath = realpath(dirname($path)) . '/' . basename($path);
+      $realpath = realpath(dirname($path)) . '/' . drupal_basename($path);
     }
     $directory = realpath($this->getDirectoryPath());
     if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
diff --git a/includes/theme.inc b/includes/theme.inc
index 3868334a..da4200e5 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -372,23 +372,31 @@ class ThemeRegistry Extends DrupalCacheArray {
       $data = $cached->data;
     }
     else {
-      $complete_registry = theme_get_registry();
+      // If there is no runtime cache stored, fetch the full theme registry,
+      // but then initialize each value to NULL. This allows offsetExists()
+      // to function correctly on non-registered theme hooks without triggering
+      // a call to resolveCacheMiss().
+      $data = $this->initializeRegistry();
       if ($this->persistable) {
-        // If there is no runtime cache stored, fetch the full theme registry,
-        // but then initialize each value to NULL. This allows
-        // offsetExists() to function correctly on non-registered theme hooks
-        // without triggering a call to resolveCacheMiss().
-        $data = array_fill_keys(array_keys($complete_registry), NULL);
-        $this->set($this->cid, $data, $this->bin);
-        $this->completeRegistry = $complete_registry;
-      }
-      else {
-        $data = $complete_registry;
+        $this->set($data);
       }
     }
     $this->storage = $data;
   }
 
+  /**
+   * Initializes the full theme registry.
+   *
+   * @return
+   *   An array with the keys of the full theme registry, but the values
+   *   initialized to NULL.
+   */
+  function initializeRegistry() {
+    $this->completeRegistry = theme_get_registry();
+
+    return array_fill_keys(array_keys($this->completeRegistry), NULL);
+  }
+
   public function offsetExists($offset) {
     // Since the theme registry allows for theme hooks to be requested that
     // are not registered, just check the existence of the key in the registry.
@@ -420,15 +428,19 @@ class ThemeRegistry Extends DrupalCacheArray {
     return $this->storage[$offset];
   }
 
-  public function set($cid, $data, $bin, $lock = TRUE) {
-    $lock_name = $cid . ':' . $bin;
+  public function set($data, $lock = TRUE) {
+    $lock_name = $this->cid . ':' . $this->bin;
     if (!$lock || lock_acquire($lock_name)) {
-      if ($cached = cache_get($cid, $this->bin)) {
+      if ($cached = cache_get($this->cid, $this->bin)) {
         // Use array merge instead of union so that filled in values in $data
         // overwrite empty values in the current cache.
         $data = array_merge($cached->data, $data);
       }
-      cache_set($cid, $data, $bin);
+      else {
+        $registry = $this->initializeRegistry();
+        $data = array_merge($registry, $data);
+      }
+      cache_set($this->cid, $data, $this->bin);
       if ($lock) {
         lock_release($lock_name);
       }
@@ -781,8 +793,9 @@ function list_themes($refresh = FALSE) {
  * Generates themed output.
  *
  * All requests for themed output must go through this function. It examines
- * the request and routes it to the appropriate theme function or template, by
- * checking the theme registry.
+ * the request and routes it to the appropriate
+ * @link themeable theme function or template @endlink, by checking the theme
+ * registry.
  *
  * The first argument to this function is the name of the theme hook. For
  * instance, to theme a table, the theme hook name is 'table'. By default, this
@@ -882,6 +895,8 @@ function list_themes($refresh = FALSE) {
  *
  * @return
  *   An HTML string representing the themed output.
+ *
+ * @see themeable
  */
 function theme($hook, $variables = array()) {
   static $hooks = NULL;
@@ -1515,7 +1530,7 @@ function theme_link($variables) {
  * @param $variables
  *   An associative array containing:
  *   - links: An associative array of links to be themed. The key for each link
- *     is used as its css class. Each link should be itself an array, with the
+ *     is used as its CSS class. Each link should be itself an array, with the
  *     following elements:
  *     - title: The link text.
  *     - href: The link URL. If omitted, the 'title' is shown as a plain text
@@ -2105,6 +2120,8 @@ function theme_username($variables) {
 /**
  * Returns HTML for a progress bar.
  *
+ * Note that the core Batch API uses this only for non-JavaScript batch jobs.
+ *
  * @param $variables
  *   An associative array containing:
  *   - percent: The percentage of the progress.
diff --git a/includes/token.inc b/includes/token.inc
index edc8a962..0b05c68f 100644
--- a/includes/token.inc
+++ b/includes/token.inc
@@ -77,8 +77,13 @@
  *   Text with tokens replaced.
  */
 function token_replace($text, array $data = array(), array $options = array()) {
+  $text_tokens = token_scan($text);
+  if (empty($text_tokens)) {
+    return $text;
+  }
+
   $replacements = array();
-  foreach (token_scan($text) as $type => $tokens) {
+  foreach ($text_tokens as $type => $tokens) {
     $replacements += token_generate($type, $tokens, $data, $options);
     if (!empty($options['clear'])) {
       $replacements += array_fill_keys($tokens, '');
diff --git a/includes/update.inc b/includes/update.inc
index f23ff1b1..048e7a5c 100644
--- a/includes/update.inc
+++ b/includes/update.inc
@@ -748,7 +748,7 @@ function update_fix_d7_requirements() {
     // Rename 'site_offline_message' variable to 'maintenance_mode_message'
     // and 'site_offline' variable to 'maintenance_mode'.
     // Old variable is removed in update for system.module, see
-    // system_update_7036().
+    // system_update_7072().
     if ($message = variable_get('site_offline_message', NULL)) {
       variable_set('maintenance_mode_message', $message);
     }
diff --git a/includes/updater.inc b/includes/updater.inc
index 363c6ebf..9801629b 100644
--- a/includes/updater.inc
+++ b/includes/updater.inc
@@ -141,7 +141,7 @@ class Updater {
       return FALSE;
     }
     foreach ($info_files as $info_file) {
-      if (drupal_substr($info_file->filename, 0, -5) == basename($directory)) {
+      if (drupal_substr($info_file->filename, 0, -5) == drupal_basename($directory)) {
         // Info file Has the same name as the directory, return it.
         return $info_file->uri;
       }
@@ -163,7 +163,7 @@ class Updater {
    *   The name of the project.
    */
   public static function getProjectName($directory) {
-    return basename($directory);
+    return drupal_basename($directory);
   }
 
   /**
diff --git a/includes/xmlrpc.inc b/includes/xmlrpc.inc
index 92e5d14f..b1c6f39c 100644
--- a/includes/xmlrpc.inc
+++ b/includes/xmlrpc.inc
@@ -622,4 +622,3 @@ function xmlrpc_error_msg() {
 function xmlrpc_clear_error() {
   xmlrpc_error(NULL, NULL, TRUE);
 }
-
diff --git a/includes/xmlrpcs.inc b/includes/xmlrpcs.inc
index 70c7cdac..118f652d 100644
--- a/includes/xmlrpcs.inc
+++ b/includes/xmlrpcs.inc
@@ -382,4 +382,3 @@ function xmlrpc_server_method_help($method) {
   $xmlrpc_server = xmlrpc_server_get();
   return $xmlrpc_server->help[$method];
 }
-
diff --git a/misc/ajax.js b/misc/ajax.js
index 830c8aa1..900ca1d2 100644
--- a/misc/ajax.js
+++ b/misc/ajax.js
@@ -318,7 +318,7 @@ Drupal.ajax.prototype.beforeSerialize = function (element, options) {
 Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) {
   // This function is left empty to make it simple to override for modules
   // that wish to add functionality here.
-}
+};
 
 /**
  * Prepare the Ajax request before it is sent.
diff --git a/misc/autocomplete.js b/misc/autocomplete.js
index 5e85be44..02a886c2 100644
--- a/misc/autocomplete.js
+++ b/misc/autocomplete.js
@@ -41,7 +41,7 @@ Drupal.autocompleteSubmit = function () {
 Drupal.jsAC = function ($input, db) {
   var ac = this;
   this.input = $input[0];
-  this.ariaLive = $('#' + $input.attr('id') + '-autocomplete-aria-live');
+  this.ariaLive = $('#' + this.input.id + '-autocomplete-aria-live');
   this.db = db;
 
   $input
diff --git a/misc/drupal.js b/misc/drupal.js
index 7ae737c6..83b08842 100644
--- a/misc/drupal.js
+++ b/misc/drupal.js
@@ -164,7 +164,7 @@ Drupal.formatString = function(str, args) {
     str = str.replace(key, args[key]);
   }
   return str;
-}
+};
 
 /**
  * Translate strings to the page language or a given language.
diff --git a/modules/aggregator/aggregator-feed-source.tpl.php b/modules/aggregator/aggregator-feed-source.tpl.php
index 6a684bdb..f9cfa555 100644
--- a/modules/aggregator/aggregator-feed-source.tpl.php
+++ b/modules/aggregator/aggregator-feed-source.tpl.php
@@ -17,6 +17,8 @@
  *
  * @see template_preprocess()
  * @see template_preprocess_aggregator_feed_source()
+ *
+ * @ingroup themeable
  */
 ?>
 <div class="feed-source">
diff --git a/modules/aggregator/aggregator-item.tpl.php b/modules/aggregator/aggregator-item.tpl.php
index e9ad1e0d..74b2284c 100644
--- a/modules/aggregator/aggregator-item.tpl.php
+++ b/modules/aggregator/aggregator-item.tpl.php
@@ -16,6 +16,8 @@
  *
  * @see template_preprocess()
  * @see template_preprocess_aggregator_item()
+ *
+ * @ingroup themeable
  */
 ?>
 <div class="feed-item">
diff --git a/modules/aggregator/aggregator-summary-item.tpl.php b/modules/aggregator/aggregator-summary-item.tpl.php
index fcd57c7a..f9199a52 100644
--- a/modules/aggregator/aggregator-summary-item.tpl.php
+++ b/modules/aggregator/aggregator-summary-item.tpl.php
@@ -13,6 +13,8 @@
  *
  * @see template_preprocess()
  * @see template_preprocess_aggregator_summary_item()
+ *
+ * @ingroup themeable
  */
 ?>
 <a href="<?php print $feed_url; ?>"><?php print $feed_title; ?></a>
diff --git a/modules/aggregator/aggregator-summary-items.tpl.php b/modules/aggregator/aggregator-summary-items.tpl.php
index 0e2133a1..4a0551d7 100644
--- a/modules/aggregator/aggregator-summary-items.tpl.php
+++ b/modules/aggregator/aggregator-summary-items.tpl.php
@@ -14,6 +14,8 @@
  *
  * @see template_preprocess()
  * @see template_preprocess_aggregator_summary_items()
+ *
+ * @ingroup themeable
  */
 ?>
 <h3><?php print $title; ?></h3>
diff --git a/modules/aggregator/aggregator-wrapper.tpl.php b/modules/aggregator/aggregator-wrapper.tpl.php
index 80b90327..2fa51a70 100644
--- a/modules/aggregator/aggregator-wrapper.tpl.php
+++ b/modules/aggregator/aggregator-wrapper.tpl.php
@@ -10,6 +10,8 @@
  *
  * @see template_preprocess()
  * @see template_preprocess_aggregator_wrapper()
+ *
+ * @ingroup themeable
  */
 ?>
 <div id="aggregator">
diff --git a/modules/aggregator/aggregator.admin.inc b/modules/aggregator/aggregator.admin.inc
index 08087afb..9f92a670 100644
--- a/modules/aggregator/aggregator.admin.inc
+++ b/modules/aggregator/aggregator.admin.inc
@@ -33,7 +33,7 @@ function aggregator_view() {
       ($feed->checked && $feed->refresh ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - REQUEST_TIME))) : t('never')),
       l(t('edit'), "admin/config/services/aggregator/edit/feed/$feed->fid"),
       l(t('remove items'), "admin/config/services/aggregator/remove/$feed->fid"),
-      l(t('update items'), "admin/config/services/aggregator/update/$feed->fid"),
+      l(t('update items'), "admin/config/services/aggregator/update/$feed->fid", array('query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")))),
     );
   }
   $output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => url('admin/config/services/aggregator/add/feed')))));
@@ -53,7 +53,11 @@ function aggregator_view() {
 }
 
 /**
- * Form builder; Generate a form to add/edit feed sources.
+ * Form constructor for adding and editing feed sources.
+ *
+ * @param $feed
+ *   If editing a feed, the feed to edit as a PHP stdClass value; if adding a
+ *   new feed, NULL.
  *
  * @ingroup forms
  * @see aggregator_form_feed_validate()
@@ -129,7 +133,9 @@ function aggregator_form_feed($form, &$form_state, stdClass $feed = NULL) {
 }
 
 /**
- * Validate aggregator_form_feed() form submissions.
+ * Form validation handler for aggregator_form_feed().
+ *
+ * @see aggregator_form_feed_submit()
  */
 function aggregator_form_feed_validate($form, &$form_state) {
   if ($form_state['values']['op'] == t('Save')) {
@@ -156,8 +162,9 @@ function aggregator_form_feed_validate($form, &$form_state) {
 }
 
 /**
- * Process aggregator_form_feed() form submissions.
+ * Form submission handler for aggregator_form_feed().
  *
+ * @see aggregator_form_feed_validate()
  * @todo Add delete confirmation dialog.
  */
 function aggregator_form_feed_submit($form, &$form_state) {
@@ -198,6 +205,14 @@ function aggregator_form_feed_submit($form, &$form_state) {
   }
 }
 
+/**
+ * Deletes a feed.
+ *
+ * @param $feed
+ *   An associative array describing the feed to be cleared.
+ *
+ * @see aggregator_admin_remove_feed_submit()
+ */
 function aggregator_admin_remove_feed($form, $form_state, $feed) {
   return confirm_form(
     array(
@@ -215,10 +230,9 @@ function aggregator_admin_remove_feed($form, $form_state, $feed) {
 }
 
 /**
- * Remove all items from a feed and redirect to the overview page.
+ * Form submission handler for aggregator_admin_remove_feed().
  *
- * @param $feed
- *   An associative array describing the feed to be cleared.
+ * Removes all items from a feed and redirects to the overview page.
  */
 function aggregator_admin_remove_feed_submit($form, &$form_state) {
   aggregator_remove($form_state['values']['feed']);
@@ -226,7 +240,7 @@ function aggregator_admin_remove_feed_submit($form, &$form_state) {
 }
 
 /**
- * Form builder; Generate a form to import feeds from OPML.
+ * Form constructor for importing feeds from OPML.
  *
  * @ingroup forms
  * @see aggregator_form_opml_validate()
@@ -280,7 +294,9 @@ function aggregator_form_opml($form, &$form_state) {
 }
 
 /**
- * Validate aggregator_form_opml form submissions.
+ * Form validation handler for aggregator_form_opml().
+ *
+ * @see aggregator_form_opml_submit()
  */
 function aggregator_form_opml_validate($form, &$form_state) {
   // If both fields are empty or filled, cancel.
@@ -295,7 +311,9 @@ function aggregator_form_opml_validate($form, &$form_state) {
 }
 
 /**
- * Process aggregator_form_opml form submissions.
+ * Form submission handler for aggregator_form_opml().
+ *
+ * @see aggregator_form_opml_validate()
  */
 function aggregator_form_opml_submit($form, &$form_state) {
   $data = '';
@@ -347,7 +365,7 @@ function aggregator_form_opml_submit($form, &$form_state) {
 }
 
 /**
- * Parse an OPML file.
+ * Parses an OPML file.
  *
  * Feeds are recognized as <outline> elements with the attributes "text" and
  * "xmlurl" set.
@@ -357,9 +375,9 @@ function aggregator_form_opml_submit($form, &$form_state) {
  *
  * @return
  *   An array of feeds, each an associative array with a "title" and a "url"
- *   element, or NULL if the OPML document failed to be parsed. An empty
- *   array will be returned if the document is valid but contains no feeds, as
- *   some OPML documents do.
+ *   element, or NULL if the OPML document failed to be parsed. An empty array
+ *   will be returned if the document is valid but contains no feeds, as some
+ *   OPML documents do.
  */
 function _aggregator_parse_opml($opml) {
   $feeds = array();
@@ -386,13 +404,17 @@ function _aggregator_parse_opml($opml) {
  *   An object describing the feed to be refreshed.
  */
 function aggregator_admin_refresh_feed($feed) {
+  if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'aggregator/update/' . $feed->fid)) {
+    return MENU_ACCESS_DENIED;
+  }
   aggregator_refresh($feed);
   drupal_goto('admin/config/services/aggregator');
 }
 
 /**
- * Form builder; Configure the aggregator system.
+ * Form constructor for the aggregator system settings.
  *
+ * @see aggregator_admin_form_submit()
  * @ingroup forms
  */
 function aggregator_admin_form($form, $form_state) {
@@ -500,6 +522,9 @@ function aggregator_admin_form($form, $form_state) {
   return $form;
 }
 
+/**
+ * Form submission handler for aggregator_admin_form().
+ */
 function aggregator_admin_form_submit($form, &$form_state) {
   if (isset($form_state['values']['aggregator_processors'])) {
     $form_state['values']['aggregator_processors'] = array_filter($form_state['values']['aggregator_processors']);
@@ -508,7 +533,13 @@ function aggregator_admin_form_submit($form, &$form_state) {
 }
 
 /**
- * Form builder; Generate a form to add/edit/delete aggregator categories.
+ * Form constructor to add/edit/delete aggregator categories.
+ *
+ * @param $edit
+ *   An associative array containing:
+ *   - title: A string to use for the category title.
+ *   - description: A string to use for the category description.
+ *   - cid: The category ID.
  *
  * @ingroup forms
  * @see aggregator_form_category_validate()
@@ -536,7 +567,9 @@ function aggregator_form_category($form, &$form_state, $edit = array('title' =>
 }
 
 /**
- * Validate aggregator_form_feed form submissions.
+ * Form validation handler for aggregator_form_category().
+ *
+ * @see aggregator_form_category_submit()
  */
 function aggregator_form_category_validate($form, &$form_state) {
   if ($form_state['values']['op'] == t('Save')) {
@@ -554,8 +587,9 @@ function aggregator_form_category_validate($form, &$form_state) {
 }
 
 /**
- * Process aggregator_form_category form submissions.
+ * Form submission handler for aggregator_form_category().
  *
+ * @see aggregator_form_category_validate()
  * @todo Add delete confirmation dialog.
  */
 function aggregator_form_category_submit($form, &$form_state) {
diff --git a/modules/aggregator/aggregator.api.php b/modules/aggregator/aggregator.api.php
index ea119276..0f708eb8 100644
--- a/modules/aggregator/aggregator.api.php
+++ b/modules/aggregator/aggregator.api.php
@@ -11,21 +11,21 @@
  */
 
 /**
- * Implement this hook to create an alternative fetcher for aggregator module.
+ * Create an alternative fetcher for aggregator.module.
  *
- * A fetcher downloads feed data to a Drupal site. The fetcher is called
- * at the first of the three aggregation stages: data is downloaded by the
- * active fetcher, it is converted to a common format by the active parser and
- * finally, it is passed to all active processors which manipulate or store the
- * data.
+ * A fetcher downloads feed data to a Drupal site. The fetcher is called at the
+ * first of the three aggregation stages: first, data is downloaded by the
+ * active fetcher; second, it is converted to a common format by the active
+ * parser; and finally, it is passed to all active processors, which manipulate
+ * or store the data.
  *
  * Modules that define this hook can be set as active fetcher on
  * admin/config/services/aggregator. Only one fetcher can be active at a time.
  *
  * @param $feed
- *   The $feed object that describes the resource to be downloaded.
- *   $feed->url contains the link to the feed. Download the data at the URL
- *   and expose it to other modules by attaching it to $feed->source_string.
+ *   A feed object representing the resource to be downloaded. $feed->url
+ *   contains the link to the feed. Download the data at the URL and expose it
+ *   to other modules by attaching it to $feed->source_string.
  *
  * @return
  *   TRUE if fetching was successful, FALSE otherwise.
@@ -41,8 +41,7 @@ function hook_aggregator_fetch($feed) {
 }
 
 /**
- * Implement this hook to expose the title and a short description of your
- * fetcher.
+ * Specify the title and short description of your fetcher.
  *
  * The title and the description provided are shown on
  * admin/config/services/aggregator among other places. Use as title the human
@@ -68,19 +67,19 @@ function hook_aggregator_fetch_info() {
 }
 
 /**
- * Implement this hook to create an alternative parser for aggregator module.
+ * Create an alternative parser for aggregator module.
  *
  * A parser converts feed item data to a common format. The parser is called
- * at the second of the three aggregation stages: data is downloaded by the
- * active fetcher, it is converted to a common format by the active parser and
- * finally, it is passed to all active processors which manipulate or store the
- * data.
+ * at the second of the three aggregation stages: first, data is downloaded
+ * by the active fetcher; second, it is converted to a common format by the
+ * active parser; and finally, it is passed to all active processors which
+ * manipulate or store the data.
  *
  * Modules that define this hook can be set as the active parser on
  * admin/config/services/aggregator. Only one parser can be active at a time.
  *
  * @param $feed
- *   An object describing the resource to be parsed: $feed->source_string
+ *   An object describing the resource to be parsed. $feed->source_string
  *   contains the raw feed data. The hook implementation should parse this data
  *   and add the following properties to the $feed object:
  *   - description: The human-readable description of the feed.
@@ -118,8 +117,7 @@ function hook_aggregator_parse($feed) {
 }
 
 /**
- * Implement this hook to expose the title and a short description of your
- * parser.
+ * Specify the title and short description of your parser.
  *
  * The title and the description provided are shown on
  * admin/config/services/aggregator among other places. Use as title the human
@@ -145,23 +143,23 @@ function hook_aggregator_parse_info() {
 }
 
 /**
- * Implement this hook to create a processor for aggregator module.
+ * Create a processor for aggregator.module.
  *
  * A processor acts on parsed feed data. Active processors are called at the
- * third and last of the aggregation stages: data is downloaded by the active
- * fetcher, it is converted to a common format by the active parser and
- * finally, it is passed to all active processors which manipulate or store the
- * data.
+ * third and last of the aggregation stages: first, data is downloaded by the
+ * active fetcher; second, it is converted to a common format by the active
+ * parser; and finally, it is passed to all active processors that manipulate or
+ * store the data.
  *
  * Modules that define this hook can be activated as processor on
  * admin/config/services/aggregator.
  *
  * @param $feed
- *   The $feed object that describes the resource to be processed. $feed->items
- *   contains an array of feed items downloaded and parsed at the parsing
- *   stage. See hook_aggregator_parse() for the basic format of a single item
- *   in the $feed->items array. For the exact format refer to the particular
- *   parser in use.
+ *   A feed object representing the resource to be processed. $feed->items
+ *   contains an array of feed items downloaded and parsed at the parsing stage.
+ *   See hook_aggregator_parse() for the basic format of a single item in the
+ *   $feed->items array. For the exact format refer to the particular parser in
+ *   use.
  *
  * @see hook_aggregator_process_info()
  * @see hook_aggregator_fetch()
@@ -176,17 +174,16 @@ function hook_aggregator_process($feed) {
 }
 
 /**
- * Implement this hook to expose the title and a short description of your
- * processor.
+ * Specify the title and short description of your processor.
  *
  * The title and the description provided are shown most importantly on
  * admin/config/services/aggregator. Use as title the natural name of the
- * processor and as description a brief (40 to 80 characters) explanation of
- * the functionality.
+ * processor and as description a brief (40 to 80 characters) explanation of the
+ * functionality.
  *
- * This hook is only called if your module implements
- * hook_aggregator_process(). If this hook is not implemented aggregator
- * will use your module's file name as title and there will be no description.
+ * This hook is only called if your module implements hook_aggregator_process().
+ * If this hook is not implemented aggregator will use your module's file name
+ * as title and there will be no description.
  *
  * @return
  *   An associative array defining a title and a description string.
@@ -203,8 +200,7 @@ function hook_aggregator_process_info($feed) {
 }
 
 /**
- * Implement this hook to remove stored data if a feed is being deleted or a
- * feed's items are being removed.
+ * Remove stored feed data.
  *
  * Aggregator calls this hook if either a feed is deleted or a user clicks on
  * "remove items".
diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info
index 3b083729..087a526b 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module
index eafb61ed..9319ad9b 100644
--- a/modules/aggregator/aggregator.module
+++ b/modules/aggregator/aggregator.module
@@ -266,7 +266,10 @@ function aggregator_menu() {
 }
 
 /**
- * Title callback for aggregatory category pages.
+ * Title callback: Returns a title for aggregatory category pages.
+ *
+ * @param $category
+ *   An aggregator category.
  *
  * @return
  *   An aggregator category title.
@@ -276,11 +279,11 @@ function _aggregator_category_title($category) {
 }
 
 /**
- * Find out whether there are any aggregator categories.
+ * Determines whether there are any aggregator categories.
  *
  * @return
- *   TRUE if there is at least one category and the user has access to them, FALSE
- *   otherwise.
+ *   TRUE if there is at least one category and the user has access to them;
+ *   FALSE otherwise.
  */
 function _aggregator_has_categories() {
   return user_access('access news feeds') && (bool) db_query_range('SELECT 1 FROM {aggregator_category}', 0, 1)->fetchField();
@@ -425,7 +428,7 @@ function aggregator_block_view($delta = '') {
 }
 
 /**
- * Add/edit/delete aggregator categories.
+ * Adds/edits/deletes aggregator categories.
  *
  * @param $edit
  *   An associative array describing the category to be added/edited/deleted.
@@ -449,10 +452,12 @@ function aggregator_save_category($edit) {
         ->condition('cid', $edit['cid'])
         ->execute();
       // Make sure there is no active block for this category.
-      db_delete('block')
-        ->condition('module', 'aggregator')
-        ->condition('delta', 'category-' . $edit['cid'])
-        ->execute();
+      if (module_exists('block')) {
+        db_delete('block')
+          ->condition('module', 'aggregator')
+          ->condition('delta', 'category-' . $edit['cid'])
+          ->execute();
+      }
       $edit['title'] = '';
       $op = 'delete';
     }
@@ -511,10 +516,12 @@ function aggregator_save_feed($edit) {
       ->condition('fid', $edit['fid'])
       ->execute();
     // Make sure there is no active block for this feed.
-    db_delete('block')
-      ->condition('module', 'aggregator')
-      ->condition('delta', 'feed-' . $edit['fid'])
-      ->execute();
+    if (module_exists('block')) {
+      db_delete('block')
+        ->condition('module', 'aggregator')
+        ->condition('delta', 'feed-' . $edit['fid'])
+        ->execute();
+    }
   }
   elseif (!empty($edit['title'])) {
     $edit['fid'] = db_insert('aggregator_feed')
@@ -570,6 +577,12 @@ function aggregator_remove($feed) {
     ->execute();
 }
 
+/**
+ * Gets the fetcher, parser, and processors.
+ *
+ * @return
+ *   An array containing the fetcher, parser, and processors.
+ */
 function _aggregator_get_variables() {
   // Fetch the feed.
   $fetcher = variable_get('aggregator_fetcher', 'aggregator');
@@ -656,10 +669,11 @@ function aggregator_refresh($feed) {
 }
 
 /**
- * Load an aggregator feed.
+ * Loads an aggregator feed.
  *
  * @param $fid
  *   The feed id.
+ *
  * @return
  *   An object describing the feed.
  */
@@ -673,10 +687,11 @@ function aggregator_feed_load($fid) {
 }
 
 /**
- * Load an aggregator category.
+ * Loads an aggregator category.
  *
  * @param $cid
  *   The category id.
+ *
  * @return
  *   An associative array describing the category.
  */
@@ -705,10 +720,11 @@ function theme_aggregator_block_item($variables) {
 }
 
 /**
- * Safely render HTML content, as allowed.
+ * Safely renders HTML content, as allowed.
  *
  * @param $value
  *   The content to be filtered.
+ *
  * @return
  *   The filtered content.
  */
@@ -717,14 +733,13 @@ function aggregator_filter_xss($value) {
 }
 
 /**
- * Check and sanitize aggregator configuration.
+ * Checks and sanitizes the aggregator configuration.
  *
- * Goes through all fetchers, parsers and processors and checks whether they are
- * available.
- * If one is missing resets to standard configuration.
+ * Goes through all fetchers, parsers and processors and checks whether they
+ * are available. If one is missing resets to standard configuration.
  *
  * @return
- *   TRUE if this function reset the configuration FALSE if not.
+ *   TRUE if this function resets the configuration; FALSE if not.
  */
 function aggregator_sanitize_configuration() {
   $reset = FALSE;
@@ -755,6 +770,7 @@ function aggregator_sanitize_configuration() {
  *
  * @param $count
  *   Items count.
+ *
  * @return
  *   Plural-formatted "@count items"
  */
diff --git a/modules/aggregator/aggregator.pages.inc b/modules/aggregator/aggregator.pages.inc
index 8074ae82..cd1c4cb2 100644
--- a/modules/aggregator/aggregator.pages.inc
+++ b/modules/aggregator/aggregator.pages.inc
@@ -160,11 +160,13 @@ function aggregator_feed_items_load($type, $data = NULL) {
  * @param $items
  *   The items to be listed.
  * @param $op
- *   Which form should be added to the items. Only 'categorize' is now recognized.
+ *   Which form should be added to the items. Only 'categorize' is now
+ *   recognized.
  * @param $feed_source
  *   The feed source URL.
+ *
  * @return
- *   The items HTML.
+ *   The rendered list of items for a feed.
  */
 function _aggregator_page_list($items, $op, $feed_source = '') {
   if (user_access('administer news feeds') && ($op == 'categorize')) {
@@ -184,14 +186,13 @@ function _aggregator_page_list($items, $op, $feed_source = '') {
 }
 
 /**
- * Form builder; build the page list form.
+ * Form constructor to build the page list form.
  *
  * @param $items
  *   An array of the feed items.
  * @param $feed_source
  *   The feed source URL.
- * @return
- *   The form structure.
+ *
  * @ingroup forms
  * @see aggregator_categorize_items_submit()
  */
@@ -236,7 +237,7 @@ function aggregator_categorize_items($items, $feed_source = '') {
 }
 
 /**
- * Process aggregator_categorize_items() form submissions.
+ * Form submission handler for aggregator_categorize_items().
  */
 function aggregator_categorize_items_submit($form, &$form_state) {
   if (!empty($form_state['values']['categories'])) {
@@ -293,7 +294,7 @@ function theme_aggregator_categorize_items($variables) {
 }
 
 /**
- * Process variables for aggregator-wrapper.tpl.php.
+ * Processes variables for aggregator-wrapper.tpl.php.
  *
  * @see aggregator-wrapper.tpl.php
  */
@@ -302,7 +303,7 @@ function template_preprocess_aggregator_wrapper(&$variables) {
 }
 
 /**
- * Process variables for aggregator-item.tpl.php.
+ * Processes variables for aggregator-item.tpl.php.
  *
  * @see aggregator-item.tpl.php
  */
@@ -499,7 +500,7 @@ function theme_aggregator_page_opml($variables) {
 }
 
 /**
- * Process variables for aggregator-summary-items.tpl.php.
+ * Processes variables for aggregator-summary-items.tpl.php.
  *
  * @see aggregator-summary-items.tpl.php
  */
@@ -510,7 +511,7 @@ function template_preprocess_aggregator_summary_items(&$variables) {
 }
 
 /**
- * Process variables for aggregator-summary-item.tpl.php.
+ * Processes variables for aggregator-summary-item.tpl.php.
  *
  * @see aggregator-summary-item.tpl.php
  */
@@ -530,7 +531,7 @@ function template_preprocess_aggregator_summary_item(&$variables) {
 }
 
 /**
- * Process variables for aggregator-feed-source.tpl.php.
+ * Processes variables for aggregator-feed-source.tpl.php.
  *
  * @see aggregator-feed-source.tpl.php
  */
diff --git a/modules/aggregator/aggregator.parser.inc b/modules/aggregator/aggregator.parser.inc
index e9f1d2e8..91fbe3aa 100644
--- a/modules/aggregator/aggregator.parser.inc
+++ b/modules/aggregator/aggregator.parser.inc
@@ -54,12 +54,13 @@ function aggregator_aggregator_parse($feed) {
 }
 
 /**
- * Parse a feed and store its items.
+ * Parses a feed and stores its items.
  *
  * @param $data
  *   The feed data.
  * @param $feed
  *   An object describing the feed to be parsed.
+ *
  * @return
  *   FALSE on error, TRUE otherwise.
  */
@@ -164,7 +165,9 @@ function aggregator_parse_feed(&$data, $feed) {
 }
 
 /**
- * Callback function used by the XML parser.
+ * Performs an action when an opening tag is encountered.
+ *
+ * Callback function used by xml_parse() within aggregator_parse_feed().
  */
 function aggregator_element_start($parser, $name, $attributes) {
   global $item, $element, $tag, $items, $channel;
@@ -212,7 +215,9 @@ function aggregator_element_start($parser, $name, $attributes) {
 }
 
 /**
- * Call-back function used by the XML parser.
+ * Performs an action when a closing tag is encountered.
+ *
+ * Callback function used by xml_parse() within aggregator_parse_feed().
  */
 function aggregator_element_end($parser, $name) {
   global $element;
@@ -234,7 +239,9 @@ function aggregator_element_end($parser, $name) {
 }
 
 /**
- * Callback function used by the XML parser.
+ * Performs an action when data is encountered.
+ *
+ * Callback function used by xml_parse() within aggregator_parse_feed().
  */
 function aggregator_element_data($parser, $data) {
   global $channel, $element, $items, $item, $image, $tag;
@@ -281,14 +288,15 @@ function aggregator_element_data($parser, $data) {
 }
 
 /**
- * Parse the W3C date/time format, a subset of ISO 8601.
+ * Parses the W3C date/time format, a subset of ISO 8601.
  *
- * PHP date parsing functions do not handle this format.
- * See http://www.w3.org/TR/NOTE-datetime for more information.
- * Originally from MagpieRSS (http://magpierss.sourceforge.net/).
+ * PHP date parsing functions do not handle this format. See
+ * http://www.w3.org/TR/NOTE-datetime for more information. Originally from
+ * MagpieRSS (http://magpierss.sourceforge.net/).
  *
  * @param $date_str
  *   A string with a potentially W3C DTF date.
+ *
  * @return
  *   A timestamp if parsed successfully or FALSE if not.
  */
diff --git a/modules/aggregator/aggregator.processor.inc b/modules/aggregator/aggregator.processor.inc
index 79261b61..7fa86a9a 100644
--- a/modules/aggregator/aggregator.processor.inc
+++ b/modules/aggregator/aggregator.processor.inc
@@ -117,7 +117,7 @@ function aggregator_form_aggregator_admin_form_alter(&$form, $form_state) {
     $form['modules']['aggregator']['aggregator_teaser_length'] = array(
       '#type' => 'select',
       '#title' => t('Length of trimmed description'),
-      '#default_value' => 600,
+      '#default_value' => variable_get('aggregator_teaser_length', 600),
       '#options' => drupal_map_assoc(array(0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000), '_aggregator_characters'),
       '#description' => t("The maximum number of characters used in the trimmed version of content.")
     );
@@ -126,14 +126,17 @@ function aggregator_form_aggregator_admin_form_alter(&$form, $form_state) {
 }
 
 /**
- * Helper function for teaser length choices.
+ * Creates display text for teaser length option values.
+ *
+ * Callback for drupal_map_assoc() within
+ * aggregator_form_aggregator_admin_form_alter().
  */
 function _aggregator_characters($length) {
   return ($length == 0) ? t('Unlimited') : format_plural($length, '1 character', '@count characters');
 }
 
 /**
- * Add/edit/delete an aggregator item.
+ * Adds/edits/deletes an aggregator item.
  *
  * @param $edit
  *   An associative array describing the item to be added/edited/deleted.
@@ -175,7 +178,7 @@ function aggregator_save_item($edit) {
 }
 
 /**
- * Expire feed items on $feed that are older than aggregator_clear.
+ * Expires items from a feed depending on expiration settings.
  *
  * @param $feed
  *   Object describing feed.
diff --git a/modules/aggregator/aggregator.test b/modules/aggregator/aggregator.test
index 0d1e31ba..5609d68a 100644
--- a/modules/aggregator/aggregator.test
+++ b/modules/aggregator/aggregator.test
@@ -92,8 +92,13 @@ class AggregatorTestCase extends DrupalWebTestCase {
     $this->drupalGet($feed->url);
     $this->assertResponse(200, t('!url is reachable.', array('!url' => $feed->url)));
 
-    // Refresh the feed (simulated link click).
+    // Attempt to access the update link directly without an access token.
     $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
+    $this->assertResponse(403);
+
+    // Refresh the feed (simulated link click).
+    $this->drupalGet('admin/config/services/aggregator');
+    $this->clickLink('update items');
 
     // Ensure we have the right number of items.
     $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid));
@@ -284,6 +289,38 @@ EOF;
   }
 }
 
+/**
+ * Tests aggregator configuration settings.
+ */
+class AggregatorConfigurationTestCase extends AggregatorTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Aggregator configuration',
+      'description' => 'Test aggregator settings page.',
+      'group' => 'Aggregator',
+    );
+  }
+
+  /**
+   * Tests the settings form to ensure the correct default values are used.
+   */
+  function testSettingsPage() {
+    $edit = array(
+      'aggregator_allowed_html_tags' => '<a>',
+      'aggregator_summary_items' => 10,
+      'aggregator_clear' => 3600,
+      'aggregator_category_selector' => 'select',
+      'aggregator_teaser_length' => 200,
+    );
+    $this->drupalPost('admin/config/services/aggregator/settings', $edit, t('Save configuration'));
+    $this->assertText(t('The configuration options have been saved.'));
+
+    foreach ($edit as $name => $value) {
+      $this->assertFieldByName($name, $value, t('"@name" has correct default value.', array('@name' => $name)));
+    }
+  }
+}
+
 class AddFeedTestCase extends AggregatorTestCase {
   public static function getInfo() {
     return array(
@@ -466,8 +503,8 @@ class UpdateFeedItemTestCase extends AggregatorTestCase {
     $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title'])));
 
     $feed = db_query("SELECT * FROM {aggregator_feed} WHERE url = :url", array(':url' => $edit['url']))->fetchObject();
-    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
 
+    aggregator_refresh($feed);
     $before = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
 
     // Sleep for 3 second.
@@ -481,10 +518,9 @@ class UpdateFeedItemTestCase extends AggregatorTestCase {
         'modified' => 0,
       ))
       ->execute();
-    $this->drupalGet('admin/config/services/aggregator/update/' . $feed->fid);
+    aggregator_refresh($feed);
 
     $after = db_query('SELECT timestamp FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchField();
-
     $this->assertTrue($before === $after, t('Publish timestamp of feed item was not updated (!before === !after)', array('!before' => $before, '!after' => $after)));
   }
 }
@@ -884,4 +920,3 @@ class FeedParserTestCase extends AggregatorTestCase {
     $this->assertEqual('urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', db_query('SELECT guid FROM {aggregator_item} WHERE link = :link', array(':link' => 'http://example.org/2003/12/13/atom03'))->fetchField(), 'Atom entry id element is parsed correctly.');
   }
 }
-
diff --git a/modules/aggregator/tests/aggregator_test.info b/modules/aggregator/tests/aggregator_test.info
index bc4ec71d..a7fc5532 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/block/block-admin-display-form.tpl.php b/modules/block/block-admin-display-form.tpl.php
index 94b61041..17a15e40 100644
--- a/modules/block/block-admin-display-form.tpl.php
+++ b/modules/block/block-admin-display-form.tpl.php
@@ -21,6 +21,8 @@
  *
  * @see template_preprocess_block_admin_display_form()
  * @see theme_block_admin_display()
+ *
+ * @ingroup themeable
  */
 ?>
 <?php
diff --git a/modules/block/block.admin.inc b/modules/block/block.admin.inc
index f86fe96b..bd617906 100644
--- a/modules/block/block.admin.inc
+++ b/modules/block/block.admin.inc
@@ -57,7 +57,7 @@ function block_admin_display_prepare_blocks($theme) {
 }
 
 /**
- * Form builder for the main blocks administration form.
+ * Form constructor for the main block administration form.
  *
  * @param $blocks
  *   An array of blocks, as returned by block_admin_display_prepare_blocks().
@@ -165,7 +165,7 @@ function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_r
 }
 
 /**
- * Form submission handler for the main blocks administration form.
+ * Form submission handler for block_admin_display_form().
  *
  * @see block_admin_display_form()
  */
@@ -197,10 +197,9 @@ function block_admin_display_form_submit($form, &$form_state) {
 }
 
 /**
- * Helper function for sorting blocks on admin/structure/block.
+ * Sorts active blocks by region, then by weight; sorts inactive blocks by name.
  *
- * Active blocks are sorted by region, then by weight.
- * Disabled blocks are sorted by name.
+ * Callback for usort() in block_admin_display_prepare_blocks().
  */
 function _block_compare($a, $b) {
   global $theme_key;
@@ -240,7 +239,7 @@ function _block_compare($a, $b) {
 }
 
 /**
- * Form builder for the block configuration form.
+ * Form constructor for the block configuration form.
  *
  * Also used by block_add_block_form() for adding a new custom block.
  *
@@ -441,7 +440,7 @@ function block_admin_configure($form, &$form_state, $module, $delta) {
 }
 
 /**
- * Form validation handler for the block configuration form.
+ * Form validation handler for block_admin_configure().
  *
  * @see block_admin_configure()
  * @see block_admin_configure_submit()
@@ -459,7 +458,7 @@ function block_admin_configure_validate($form, &$form_state) {
 }
 
 /**
- * Form submission handler for the block configuration form.
+ * Form submission handler for block_admin_configure().
  *
  * @see block_admin_configure()
  * @see block_admin_configure_validate()
@@ -519,7 +518,7 @@ function block_admin_configure_submit($form, &$form_state) {
 }
 
 /**
- * Form builder for the add block form.
+ * Form constructor for the add block form.
  *
  * @see block_add_block_form_validate()
  * @see block_add_block_form_submit()
@@ -530,7 +529,7 @@ function block_add_block_form($form, &$form_state) {
 }
 
 /**
- * Form validation handler for the add block form.
+ * Form validation handler for block_add_block_form().
  *
  * @see block_add_block_form()
  * @see block_add_block_form_submit()
@@ -544,7 +543,7 @@ function block_add_block_form_validate($form, &$form_state) {
 }
 
 /**
- * Form submission handler for the add block form.
+ * Form submission handler for block_add_block_form().
  *
  * Saves the new custom block.
  *
@@ -609,7 +608,7 @@ function block_add_block_form_submit($form, &$form_state) {
 }
 
 /**
- * Form builder for the custom block deletion form.
+ * Form constructor for the custom block deletion form.
  *
  * @param $module
  *   The name of the module that implements the block to be deleted. This should
@@ -629,7 +628,7 @@ function block_custom_block_delete($form, &$form_state, $module, $delta) {
 }
 
 /**
- * Form submission handler for the custom block deletion form.
+ * Form submission handler for block_custom_block_delete().
  *
  * @see block_custom_block_delete()
  */
diff --git a/modules/block/block.info b/modules/block/block.info
index a15bc9a6..2ad2a71a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/block/block.module b/modules/block/block.module
index 754febd2..24319089 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -16,27 +16,27 @@ define('BLOCK_REGION_NONE', -1);
 define('BLOCK_CUSTOM_FIXED', 0);
 
 /**
- *  Show this block by default, but let individual users hide it.
+ *  Shows this block by default, but lets individual users hide it.
  */
 define('BLOCK_CUSTOM_ENABLED', 1);
 
 /**
- * Hide this block by default but let individual users show it.
+ * Hides this block by default but lets individual users show it.
  */
 define('BLOCK_CUSTOM_DISABLED', 2);
 
 /**
- * Show this block on every page except the listed pages.
+ * Shows this block on every page except the listed pages.
  */
 define('BLOCK_VISIBILITY_NOTLISTED', 0);
 
 /**
- * Show this block on only the listed pages.
+ * Shows this block on only the listed pages.
  */
 define('BLOCK_VISIBILITY_LISTED', 1);
 
 /**
- * Show this block if the associated PHP code returns TRUE.
+ * Shows this block if the associated PHP code returns TRUE.
  */
 define('BLOCK_VISIBILITY_PHP', 2);
 
@@ -249,7 +249,7 @@ function block_block_view($delta = '') {
 /**
  * Implements hook_page_build().
  *
- * Render blocks into their regions.
+ * Renders blocks into their regions.
  */
 function block_page_build(&$page) {
   global $theme;
@@ -305,10 +305,13 @@ function block_page_build(&$page) {
 }
 
 /**
- * Get a renderable array of a region containing all enabled blocks.
+ * Gets a renderable array of a region containing all enabled blocks.
  *
  * @param $region
  *   The requested region.
+ *
+ * @return
+ *   A renderable array of a region containing all enabled blocks.
  */
 function block_get_blocks_by_region($region) {
   $build = array();
@@ -319,10 +322,11 @@ function block_get_blocks_by_region($region) {
 }
 
 /**
- * Get an array of blocks suitable for drupal_render().
+ * Gets an array of blocks suitable for drupal_render().
  *
  * @param $list
  *   A list of blocks such as that returned by block_list().
+ *
  * @return
  *   A renderable array.
  */
@@ -353,7 +357,7 @@ function _block_get_renderable_array($list = array()) {
 }
 
 /**
- * Update the 'block' DB table with the blocks currently exported by modules.
+ * Updates the 'block' DB table with the blocks currently exported by modules.
  *
  * @param $theme
  *   The theme to rehash blocks for. If not provided, defaults to the currently
@@ -473,6 +477,7 @@ function _block_rehash($theme = NULL) {
  *
  * @param $bid
  *   ID of the block to get information for.
+ *
  * @return
  *   Associative array of information stored in the database for this block.
  *   Array keys:
@@ -486,7 +491,14 @@ function block_custom_block_get($bid) {
 }
 
 /**
- * Define the custom block form.
+ * Form constructor for the custom block form.
+ *
+ * @param $edit
+ *   (optional) An associative array of information retrieved by
+ *   block_custom_get_block() if an existing block is being edited, or an empty
+ *   array otherwise. Defaults to array().
+ *
+ * @ingroup forms
  */
 function block_custom_block_form($edit = array()) {
   $edit += array(
@@ -528,6 +540,7 @@ function block_custom_block_form($edit = array()) {
  *     - format: Filter ID of the filter format for the body.
  * @param $delta
  *   Block ID of the block to save.
+ *
  * @return
  *   Always returns TRUE.
  */
@@ -544,7 +557,7 @@ function block_custom_block_save($edit, $delta) {
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for user_profile_form().
  */
 function block_form_user_profile_form_alter(&$form, &$form_state) {
   if ($form['#user_category'] == 'account') {
@@ -588,7 +601,10 @@ function block_user_presave(&$edit, $account, $category) {
 }
 
 /**
- * Initialize blocks for enabled themes.
+ * Initializes blocks for enabled themes.
+ *
+ * @param $theme_list
+ *   An array of theme names.
  */
 function block_themes_enabled($theme_list) {
   foreach ($theme_list as $theme) {
@@ -597,7 +613,7 @@ function block_themes_enabled($theme_list) {
 }
 
 /**
- * Assign an initial, default set of blocks for a theme.
+ * Assigns an initial, default set of blocks for a theme.
  *
  * This function is called the first time a new theme is enabled. The new theme
  * gets a copy of the default theme's blocks, with the difference that if a
@@ -628,7 +644,7 @@ function block_theme_initialize($theme) {
 }
 
 /**
- * Return all blocks in the specified region for the current user.
+ * Returns all blocks in the specified region for the current user.
  *
  * @param $region
  *   The name of a region.
@@ -640,7 +656,7 @@ function block_theme_initialize($theme) {
  *   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
+ *   Now that the block table has a primary key, we should use that as the
  *   array key instead of MODULE_DELTA.
  */
 function block_list($region) {
@@ -662,7 +678,7 @@ function block_list($region) {
 }
 
 /**
- * Load a block object from the database.
+ * Loads a block object from the database.
  *
  * @param $module
  *   Name of the module that implements the block to load.
@@ -690,7 +706,10 @@ function block_load($module, $delta) {
 }
 
 /**
- * Load blocks information from the database.
+ * Loads blocks' information from the database.
+ *
+ * @return
+ *   An array of blocks grouped by region.
  */
 function _block_load_blocks() {
   global $theme_key;
@@ -721,8 +740,8 @@ function _block_load_blocks() {
 /**
  * Implements hook_block_list_alter().
  *
- * Check the page, user role and user specific visibilty settings.
- * Remove the block if the visibility conditions are not met.
+ * Checks the page, user role, and user-specific visibilty settings.
+ * Removes the block if the visibility conditions are not met.
  */
 function block_block_list_alter(&$blocks) {
   global $user, $theme_key;
@@ -916,9 +935,9 @@ function block_flush_caches() {
 }
 
 /**
- * Process variables for block.tpl.php
+ * Processes variables for block.tpl.php.
  *
- * Prepare the values passed to the theme_block function to be passed
+ * Prepares the values passed to the theme_block function to be passed
  * into a pluggable template engine. Uses block properties to generate a
  * series of template file suggestions. If none are found, the default
  * block.tpl.php is used.
@@ -967,7 +986,7 @@ function template_preprocess_block(&$variables) {
 /**
  * Implements hook_user_role_delete().
  *
- * Remove deleted role from blocks that use it.
+ * Removes deleted role from blocks that use it.
  */
 function block_user_role_delete($role) {
   db_delete('block_role')
@@ -1019,7 +1038,7 @@ function block_admin_paths() {
 /**
  * Implements hook_modules_uninstalled().
  *
- * Cleanup {block} and {block_role} tables from modules' blocks.
+ * Cleans up {block} and {block_role} tables from modules' blocks.
  */
 function block_modules_uninstalled($modules) {
   db_delete('block')
diff --git a/modules/block/block.test b/modules/block/block.test
index 9639b2c1..32303406 100644
--- a/modules/block/block.test
+++ b/modules/block/block.test
@@ -764,6 +764,10 @@ class BlockHiddenRegionTestCase extends DrupalWebTestCase {
     );
   }
 
+  function setUp() {
+    parent::setUp(array('block_test'));
+  }
+
   /**
    * Tests that hidden regions do not inherit blocks when a theme is enabled.
    */
diff --git a/modules/block/block.tpl.php b/modules/block/block.tpl.php
index b1946374..f0bfa5ca 100644
--- a/modules/block/block.tpl.php
+++ b/modules/block/block.tpl.php
@@ -12,11 +12,12 @@
  * - $block->region: The block region embedding the current block.
  * - $classes: String of classes that can be used to style contextually through
  *   CSS. It can be manipulated through the variable $classes_array from
- *   preprocess functions. The default values can be one or more of the following:
+ *   preprocess functions. The default values can be one or more of the
+ *   following:
  *   - block: The current template type, i.e., "theming hook".
- *   - block-[module]: The module generating the block. For example, the user module
- *     is responsible for handling the default user navigation block. In that case
- *     the class would be "block-user".
+ *   - block-[module]: The module generating the block. For example, the user
+ *     module is responsible for handling the default user navigation block. In
+ *     that case the class would be 'block-user'.
  * - $title_prefix (array): An array containing additional output populated by
  *   modules, intended to be displayed in front of the main title tag that
  *   appears in the template.
@@ -39,6 +40,8 @@
  * @see template_preprocess()
  * @see template_preprocess_block()
  * @see template_process()
+ *
+ * @ingroup themeable
  */
 ?>
 <div id="<?php print $block_html_id; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>
diff --git a/modules/block/tests/block_test.info b/modules/block/tests/block_test.info
index 69aeec27..084bd835 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/block/tests/block_test.module b/modules/block/tests/block_test.module
index 2abc433c..5e06d5cf 100644
--- a/modules/block/tests/block_test.module
+++ b/modules/block/tests/block_test.module
@@ -5,6 +5,14 @@
  *   Provide test blocks.
  */
 
+/**
+ * Implements hook_system_theme_info().
+ */
+function block_test_system_theme_info() {
+  $themes['block_test_theme'] = drupal_get_path('module', 'block_test') . '/themes/block_test_theme/block_test_theme.info';
+  return $themes;
+}
+
 /**
  * Implements hook_block_info().
  */
diff --git a/themes/tests/block_test_theme/block_test_theme.info b/modules/block/tests/themes/block_test_theme/block_test_theme.info
similarity index 79%
rename from themes/tests/block_test_theme/block_test_theme.info
rename to modules/block/tests/themes/block_test_theme/block_test_theme.info
index 65d2580e..e05bf02f 100644
--- a/themes/tests/block_test_theme/block_test_theme.info
+++ b/modules/block/tests/themes/block_test_theme/block_test_theme.info
@@ -13,8 +13,8 @@ regions[footer] = Footer
 regions[highlighted] = Highlighted
 regions[help] = Help
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/tests/block_test_theme/page.tpl.php b/modules/block/tests/themes/block_test_theme/page.tpl.php
similarity index 100%
rename from themes/tests/block_test_theme/page.tpl.php
rename to modules/block/tests/themes/block_test_theme/page.tpl.php
diff --git a/modules/blog/blog.info b/modules/blog/blog.info
index 91ef6b1c..7e3a98f6 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/book/book.info b/modules/book/book.info
index 653d6fc2..a68563a5 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/color/color-rtl.css b/modules/color/color-rtl.css
index bfbcd499..07b754ea 100644
--- a/modules/color/color-rtl.css
+++ b/modules/color/color-rtl.css
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Right-to-left specific stylesheet for the Color module.
+ */
 
 #placeholder {
   left: 0;
diff --git a/modules/color/color.css b/modules/color/color.css
index e513dadf..981cff85 100644
--- a/modules/color/color.css
+++ b/modules/color/color.css
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Stylesheet for the administration pages of the Color module.
+ */
 
 /* Farbtastic placement */
 .color-form {
diff --git a/modules/color/color.info b/modules/color/color.info
index 203467fc..df5b93c9 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/color/color.js b/modules/color/color.js
index 43099adc..d7e06645 100644
--- a/modules/color/color.js
+++ b/modules/color/color.js
@@ -1,3 +1,8 @@
+/**
+ * @file
+ * Attaches the behaviors for the Color module.
+ */
+
 (function ($) {
 
 Drupal.behaviors.color = {
@@ -65,20 +70,20 @@ Drupal.behaviors.color = {
     });
 
     /**
-     * Render the preview.
+     * Renders the preview.
      */
     function preview() {
       Drupal.color.callback(context, settings, form, farb, height, width);
     }
 
     /**
-     * Shift a given color, using a reference pair (ref in HSL).
+     * Shifts a given color, using a reference pair (ref in HSL).
      *
      * This algorithm ensures relative ordering on the saturation and luminance
      * axes is preserved, and performs a simple hue shift.
      *
-     * It is also symmetrical. If: shift_color(c, a, b) == d,
-     *                        then shift_color(d, b, a) == c.
+     * It is also symmetrical. If: shift_color(c, a, b) == d, then
+     * shift_color(d, b, a) == c.
      */
     function shift_color(given, ref1, ref2) {
       // Convert to HSL.
@@ -159,7 +164,7 @@ Drupal.behaviors.color = {
     }
 
     /**
-     * Reset the color scheme selector.
+     * Resets the color scheme selector.
      */
     function resetScheme() {
       $('#edit-scheme', form).each(function () {
@@ -167,7 +172,9 @@ Drupal.behaviors.color = {
       });
     }
 
-    // Focus the Farbtastic on a particular field.
+    /**
+     * Focuses Farbtastic on a particular field.
+     */
     function focus() {
       var input = this;
       // Remove old bindings.
diff --git a/modules/color/color.module b/modules/color/color.module
index be25c2d7..c58d6ecc 100644
--- a/modules/color/color.module
+++ b/modules/color/color.module
@@ -1,4 +1,8 @@
 <?php
+/**
+ * @file
+ * Allows users to change the color scheme of themes.
+ */
 
 /**
  * Implements hook_help().
@@ -70,7 +74,13 @@ function _color_theme_select_form_alter(&$form, &$form_state) {
 }
 
 /**
- * Callback for the theme to alter the resources used.
+ * Replaces style sheets with color-altered style sheets.
+ *
+ * A theme that supports the color module should call this function from its
+ * THEME_process_html() function, so that the correct style sheets are
+ * included when html.tpl.php is rendered.
+ *
+ * @see theme()
  */
 function _color_html_alter(&$vars) {
   global $theme_key;
@@ -86,7 +96,7 @@ function _color_html_alter(&$vars) {
       foreach ($color_paths as $color_path) {
         // Color module currently requires unique file names to be used,
         // which allows us to compare different file paths.
-        if (basename($old_path) == basename($color_path)) {
+        if (drupal_basename($old_path) == drupal_basename($color_path)) {
           // Replace the path to the new css file.
           // This keeps the order of the stylesheets intact.
           $vars['css'][$old_path]['data'] = $color_path;
@@ -99,7 +109,13 @@ function _color_html_alter(&$vars) {
 }
 
 /**
- * Callback for the theme to alter the resources used.
+ * Replaces the logo with a color-altered logo.
+ *
+ * A theme that supports the color module should call this function from its
+ * THEME_process_page() function, so that the correct logo is included when
+ * page.tpl.php is rendered.
+ *
+ * @see theme()
  */
 function _color_page_alter(&$vars) {
   global $theme_key;
@@ -112,7 +128,7 @@ function _color_page_alter(&$vars) {
 }
 
 /**
- * Retrieve the color.module info for a particular theme.
+ * Retrieves the Color module information for a particular theme.
  */
 function color_get_info($theme) {
   static $theme_info = array();
@@ -131,7 +147,7 @@ function color_get_info($theme) {
 }
 
 /**
- * Helper function to retrieve the color palette for a particular theme.
+ * Retrieves the color palette for a particular theme.
  */
 function color_get_palette($theme, $default = FALSE) {
   // Fetch and expand default palette.
@@ -143,7 +159,14 @@ function color_get_palette($theme, $default = FALSE) {
 }
 
 /**
- * Form callback. Returns the configuration form.
+ * Form constructor for the color configuration form for a particular theme.
+ *
+ * @param $theme
+ *   The machine name of the theme whose color settings are being configured.
+ *
+ * @see color_scheme_form_validate()
+ * @see color_scheme_form_submit()
+ * @ingroup forms
  */
 function color_scheme_form($complete_form, &$form_state, $theme) {
   $base = drupal_get_path('module', 'color');
@@ -244,11 +267,11 @@ function theme_color_scheme_form($variables) {
   $info = $form['info']['#value'];
   $path = drupal_get_path('theme', $theme) . '/';
   drupal_add_css($path . $info['preview_css']);
-  
+
   $preview_js_path = isset($info['preview_js']) ? $path . $info['preview_js'] : drupal_get_path('module', 'color') . '/' . 'preview.js';
   // Add the JS at a weight below color.js.
   drupal_add_js($preview_js_path, array('weight' => -1));
-    
+
   $output  = '';
   $output .= '<div class="color-form clearfix">';
   // Color schemes
@@ -272,7 +295,9 @@ function theme_color_scheme_form($variables) {
 }
 
 /**
- * Validation handler for color change form.
+ * Form validation handler for color_scheme_form().
+ *
+ * @see color_scheme_form_submit()
  */
 function color_scheme_form_validate($form, &$form_state) {
   // Only accept hexadecimal CSS color strings to avoid XSS upon use.
@@ -284,7 +309,9 @@ function color_scheme_form_validate($form, &$form_state) {
 }
 
 /**
- * Submit handler for color change form.
+ * Form submission handler for color_scheme_form().
+ *
+ * @see color_scheme_form_validate()
  */
 function color_scheme_form_submit($form, &$form_state) {
   // Get theme coloring info.
@@ -362,7 +389,7 @@ function color_scheme_form_submit($form, &$form_state) {
 
   // Copy over neutral images.
   foreach ($info['copy'] as $file) {
-    $base = basename($file);
+    $base = drupal_basename($file);
     $source = $paths['source'] . $file;
     $filepath = file_unmanaged_copy($source, $paths['target'] . $base);
     $paths['map'][$file] = $base;
@@ -404,7 +431,7 @@ function color_scheme_form_submit($form, &$form_state) {
 
       // Rewrite stylesheet with new colors.
       $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
-      $base_file = basename($file);
+      $base_file = drupal_basename($file);
       $css[] = $paths['target'] . $base_file;
       _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
     }
@@ -416,7 +443,7 @@ function color_scheme_form_submit($form, &$form_state) {
 }
 
 /**
- * Rewrite the stylesheet to match the colors in the palette.
+ * Rewrites the stylesheet to match the colors in the palette.
  */
 function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
   $themes = list_themes();
@@ -487,7 +514,7 @@ function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
 }
 
 /**
- * Save the rewritten stylesheet to disk.
+ * Saves the rewritten stylesheet to disk.
  */
 function _color_save_stylesheet($file, $style, &$paths) {
   $filepath = file_unmanaged_save_data($style, $file, FILE_EXISTS_REPLACE);
@@ -498,7 +525,7 @@ function _color_save_stylesheet($file, $style, &$paths) {
 }
 
 /**
- * Render images that match a given palette.
+ * Renders images that match a given palette.
  */
 function _color_render_images($theme, &$info, &$paths, $palette) {
   // Prepare template image.
@@ -544,7 +571,7 @@ function _color_render_images($theme, &$info, &$paths, $palette) {
   // Cut out slices.
   foreach ($info['slices'] as $file => $coord) {
     list($x, $y, $width, $height) = $coord;
-    $base = basename($file);
+    $base = drupal_basename($file);
     $image = drupal_realpath($paths['target'] . $base);
 
     // Cut out slice.
@@ -575,16 +602,16 @@ function _color_render_images($theme, &$info, &$paths, $palette) {
 }
 
 /**
- * Shift a given color, using a reference pair and a target blend color.
+ * Shifts a given color, using a reference pair and a target blend color.
  *
  * Note: this function is significantly different from the JS version, as it
  * is written to match the blended images perfectly.
  *
- * Constraint: if (ref2 == target + (ref1 - target) * delta) for some fraction delta
- *              then (return == target + (given - target) * delta)
+ * Constraint: if (ref2 == target + (ref1 - target) * delta) for some fraction
+ * delta then (return == target + (given - target) * delta).
  *
  * Loose constraint: Preserve relative positions in saturation and luminance
- *                   space.
+ * space.
  */
 function _color_shift($given, $ref1, $ref2, $target) {
   // We assume that ref2 is a blend of ref1 and target and find
@@ -634,7 +661,7 @@ function _color_shift($given, $ref1, $ref2, $target) {
 }
 
 /**
- * Convert a hex triplet into a GD color.
+ * Converts a hex triplet into a GD color.
  */
 function _color_gd($img, $hex) {
   $c = array_merge(array($img), _color_unpack($hex));
@@ -642,7 +669,7 @@ function _color_gd($img, $hex) {
 }
 
 /**
- * Blend two hex colors and return the GD color.
+ * Blends two hex colors and returns the GD color.
  */
 function _color_blend($img, $hex1, $hex2, $alpha) {
   $in1 = _color_unpack($hex1);
@@ -656,7 +683,7 @@ function _color_blend($img, $hex1, $hex2, $alpha) {
 }
 
 /**
- * Convert a hex color into an RGB triplet.
+ * Converts a hex color into an RGB triplet.
  */
 function _color_unpack($hex, $normalize = FALSE) {
   if (strlen($hex) == 4) {
@@ -671,7 +698,7 @@ function _color_unpack($hex, $normalize = FALSE) {
 }
 
 /**
- * Convert an RGB triplet to a hex color.
+ * Converts an RGB triplet to a hex color.
  */
 function _color_pack($rgb, $normalize = FALSE) {
   $out = 0;
@@ -683,7 +710,7 @@ function _color_pack($rgb, $normalize = FALSE) {
 }
 
 /**
- * Convert a HSL triplet into RGB.
+ * Converts an HSL triplet into RGB.
  */
 function _color_hsl2rgb($hsl) {
   $h = $hsl[0];
@@ -712,7 +739,7 @@ function _color_hue2rgb($m1, $m2, $h) {
 }
 
 /**
- * Convert an RGB triplet to HSL.
+ * Converts an RGB triplet to HSL.
  */
 function _color_rgb2hsl($rgb) {
   $r = $rgb[0];
diff --git a/modules/color/color.test b/modules/color/color.test
index 0a8e78f4..09043250 100644
--- a/modules/color/color.test
+++ b/modules/color/color.test
@@ -6,7 +6,7 @@
  */
 
 /**
- * Test color functionality.
+ * Tests the Color module functionality.
  */
 class ColorTestCase extends DrupalWebTestCase {
   protected $big_user;
@@ -57,7 +57,7 @@ class ColorTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Test color module functionality.
+   * Tests the Color module functionality.
    */
   function testColor() {
     foreach ($this->themes as $theme => $test_values) {
@@ -66,7 +66,7 @@ class ColorTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Tests color module functionality using the given theme.
+   * Tests the Color module functionality using the given theme.
    */
   function _testColor($theme, $test_values) {
     variable_set('theme_default', $theme);
@@ -109,7 +109,7 @@ class ColorTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Test to see if the provided color is valid
+   * Tests whether the provided color is valid.
    */
   function testValidColor() {
     variable_set('theme_default', 'bartik');
diff --git a/modules/color/preview.js b/modules/color/preview.js
index 88ae95fb..67eef0b0 100644
--- a/modules/color/preview.js
+++ b/modules/color/preview.js
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Attaches preview-related behavior for the Color module.
+ */
 
 (function ($) {
   Drupal.color = {
diff --git a/modules/comment/comment.info b/modules/comment/comment.info
index d5b62664..d150d000 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/comment/comment.install b/modules/comment/comment.install
index 121ec22a..7312e2a3 100644
--- a/modules/comment/comment.install
+++ b/modules/comment/comment.install
@@ -165,9 +165,11 @@ function comment_update_7001() {
 function comment_update_7002() {
   db_rename_table('comments', 'comment');
 
-  // Add user-related indexes.
-  db_add_index('comment', 'comment_uid', array('uid'));
-  db_add_index('node_comment_statistics', 'last_comment_uid', array('last_comment_uid'));
+  // Add user-related indexes. These may already exist from Drupal 6.
+  if (!db_index_exists('comment', 'comment_uid')) {
+    db_add_index('comment', 'comment_uid', array('uid'));
+    db_add_index('node_comment_statistics', 'last_comment_uid', array('last_comment_uid'));
+  }
 
   // Create a language column.
   db_add_field('comment', 'language', array(
@@ -224,8 +226,11 @@ function comment_update_7004() {
   ));
   db_add_index('node_comment_statistics', 'cid', array('cid'));
 
-  // Add an index on the comment_count.
-  db_add_index('node_comment_statistics', 'comment_count', array('comment_count'));
+  // The comment_count index may have been added in Drupal 6.
+  if (!db_index_exists('node_comment_statistics', 'comment_count')) {
+    // Add an index on the comment_count.
+    db_add_index('node_comment_statistics', 'comment_count', array('comment_count'));
+  }
 }
 
 /**
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index 239cd5be..2793ea3b 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -1232,8 +1232,8 @@ function comment_form_node_form_alter(&$form, $form_state) {
   // If the node doesn't have any comments, the "hidden" option makes no
   // sense, so don't even bother presenting it to the user.
   if (empty($comment_count)) {
-    unset($form['comment_settings']['comment']['#options'][COMMENT_NODE_HIDDEN]);
-    unset($form['comment_settings']['comment'][COMMENT_NODE_HIDDEN]);
+    $form['comment_settings']['comment'][COMMENT_NODE_HIDDEN]['#access'] = FALSE;
+    // Also adjust the description of the "closed" option.
     $form['comment_settings']['comment'][COMMENT_NODE_CLOSED]['#description'] = t('Users cannot post comments.');
   }
 }
@@ -2294,24 +2294,26 @@ function template_preprocess_comment(&$variables) {
   else {
     $variables['status'] = ($comment->status == COMMENT_NOT_PUBLISHED) ? 'comment-unpublished' : 'comment-published';
   }
+
   // Gather comment classes.
-  if ($comment->uid == 0) {
+  // 'comment-published' class is not needed, it is either 'comment-preview' or
+  // 'comment-unpublished'.
+  if ($variables['status'] != 'comment-published') {
+    $variables['classes_array'][] = $variables['status'];
+  }
+  if ($variables['new']) {
+    $variables['classes_array'][] = 'comment-new';
+  }
+  if (!$comment->uid) {
     $variables['classes_array'][] = 'comment-by-anonymous';
   }
   else {
-    // Published class is not needed. It is either 'comment-preview' or 'comment-unpublished'.
-    if ($variables['status'] != 'comment-published') {
-      $variables['classes_array'][] = $variables['status'];
-    }
-    if ($comment->uid === $variables['node']->uid) {
+    if ($comment->uid == $variables['node']->uid) {
       $variables['classes_array'][] = 'comment-by-node-author';
     }
-    if ($comment->uid === $variables['user']->uid) {
+    if ($comment->uid == $variables['user']->uid) {
       $variables['classes_array'][] = 'comment-by-viewer';
     }
-    if ($variables['new']) {
-      $variables['classes_array'][] = 'comment-new';
-    }
   }
 }
 
diff --git a/modules/comment/comment.test b/modules/comment/comment.test
index f4e57c11..970cc83a 100644
--- a/modules/comment/comment.test
+++ b/modules/comment/comment.test
@@ -251,56 +251,6 @@ class CommentHelperCase extends DrupalWebTestCase {
 
     return $match[2];
   }
-
-  /**
-   * Tests new comment marker.
-   */
-  public function testCommentNewCommentsIndicator() {
-    // Test if the right links are displayed when no comment is present for the
-    // node.
-    $this->drupalLogin($this->admin_user);
-    $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN));
-    $this->drupalGet('node');
-    $this->assertNoLink(t('@count comments', array('@count' => 0)));
-    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
-    $this->assertLink(t('Read more'));
-    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
-    $this->assertTrue(count($count) == 1, t('One child found'));
-
-    // Create a new comment. This helper function may be run with different
-    // comment settings so use comment_save() to avoid complex setup.
-    $comment = (object) array(
-      'cid' => NULL,
-      'nid' => $this->node->nid,
-      'node_type' => $this->node->type,
-      'pid' => 0,
-      'uid' => $this->loggedInUser->uid,
-      'status' => COMMENT_PUBLISHED,
-      'subject' => $this->randomName(),
-      'hostname' => ip_address(),
-      'language' => LANGUAGE_NONE,
-      'comment_body' => array(LANGUAGE_NONE => array($this->randomName())),
-    );
-    comment_save($comment);
-    $this->drupalLogout();
-
-    // Log in with 'web user' and check comment links.
-    $this->drupalLogin($this->web_user);
-    $this->drupalGet('node');
-    $this->assertLink(t('1 new comment'));
-    $this->clickLink(t('1 new comment'));
-    $this->assertRaw('<a id="new"></a>', t('Found "new" marker.'));
-    $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), t('The "new" anchor is positioned at the right comment.'));
-
-    // Test if "new comment" link is correctly removed.
-    $this->drupalGet('node');
-    $this->assertLink(t('1 comment'));
-    $this->assertLink(t('Read more'));
-    $this->assertNoLink(t('1 new comment'));
-    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
-    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
-    $this->assertTrue(count($count) == 2, print_r($count, TRUE));
-  }
 }
 
 class CommentInterfaceTest extends CommentHelperCase {
@@ -331,8 +281,6 @@ class CommentInterfaceTest extends CommentHelperCase {
     $comment = $this->postComment($this->node, $comment_text);
     $comment_loaded = comment_load($comment->id);
     $this->assertTrue($this->commentExists($comment), t('Comment found.'));
-    $by_viewer_class = $this->xpath('//a[@id=:comment_id]/following-sibling::div[1][contains(@class, "comment-by-viewer")]', array(':comment_id' => 'comment-' . $comment->id));
-    $this->assertTrue(!empty($by_viewer_class), t('HTML class for comments by viewer found.'));
 
     // Set comments to have subject and preview to required.
     $this->drupalLogout();
@@ -419,11 +367,6 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->assertTrue($this->commentExists($reply, TRUE), t('Page two exists. %s'));
     $this->setCommentsPerPage(50);
 
-    // Create comment #5 to assert HTML class.
-    $comment = $this->postComment($this->node, $this->randomName(), $this->randomName());
-    $by_node_author_class = $this->xpath('//a[@id=:comment_id]/following-sibling::div[1][contains(@class, "comment-by-node-author")]', array(':comment_id' => 'comment-' . $comment->id));
-    $this->assertTrue(!empty($by_node_author_class), t('HTML class for node author found.'));
-
     // Attempt to post to node with comments disabled.
     $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_HIDDEN));
     $this->assertTrue($this->node, t('Article node created.'));
@@ -472,6 +415,163 @@ class CommentInterfaceTest extends CommentHelperCase {
     $this->setCommentForm(FALSE);
   }
 
+  /**
+   * Tests new comment marker.
+   */
+  public function testCommentNewCommentsIndicator() {
+    // Test if the right links are displayed when no comment is present for the
+    // node.
+    $this->drupalLogin($this->admin_user);
+    $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN));
+    $this->drupalGet('node');
+    $this->assertNoLink(t('@count comments', array('@count' => 0)));
+    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
+    $this->assertLink(t('Read more'));
+    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
+    $this->assertTrue(count($count) == 1, t('One child found'));
+
+    // Create a new comment. This helper function may be run with different
+    // comment settings so use comment_save() to avoid complex setup.
+    $comment = (object) array(
+      'cid' => NULL,
+      'nid' => $this->node->nid,
+      'node_type' => $this->node->type,
+      'pid' => 0,
+      'uid' => $this->loggedInUser->uid,
+      'status' => COMMENT_PUBLISHED,
+      'subject' => $this->randomName(),
+      'hostname' => ip_address(),
+      'language' => LANGUAGE_NONE,
+      'comment_body' => array(LANGUAGE_NONE => array($this->randomName())),
+    );
+    comment_save($comment);
+    $this->drupalLogout();
+
+    // Log in with 'web user' and check comment links.
+    $this->drupalLogin($this->web_user);
+    $this->drupalGet('node');
+    $this->assertLink(t('1 new comment'));
+    $this->clickLink(t('1 new comment'));
+    $this->assertRaw('<a id="new"></a>', t('Found "new" marker.'));
+    $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), t('The "new" anchor is positioned at the right comment.'));
+
+    // Test if "new comment" link is correctly removed.
+    $this->drupalGet('node');
+    $this->assertLink(t('1 comment'));
+    $this->assertLink(t('Read more'));
+    $this->assertNoLink(t('1 new comment'));
+    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
+    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
+    $this->assertTrue(count($count) == 2, print_r($count, TRUE));
+  }
+
+  /**
+   * Tests CSS classes on comments.
+   */
+  function testCommentClasses() {
+    // Create all permutations for comments, users, and nodes.
+    $parameters = array(
+      'node_uid' => array(0, $this->web_user->uid),
+      'comment_uid' => array(0, $this->web_user->uid, $this->admin_user->uid),
+      'comment_status' => array(COMMENT_PUBLISHED, COMMENT_NOT_PUBLISHED),
+      'user' => array('anonymous', 'authenticated', 'admin'),
+    );
+    $permutations = $this->generatePermutations($parameters);
+
+    foreach ($permutations as $case) {
+      // Create a new node.
+      $node = $this->drupalCreateNode(array('type' => 'article', 'uid' => $case['node_uid']));
+
+      // Add a comment.
+      $comment = (object) array(
+        'cid' => NULL,
+        'nid' => $node->nid,
+        'pid' => 0,
+        'uid' => $case['comment_uid'],
+        'status' => $case['comment_status'],
+        'subject' => $this->randomName(),
+        'language' => LANGUAGE_NONE,
+        'comment_body' => array(LANGUAGE_NONE => array($this->randomName())),
+      );
+      comment_save($comment);
+
+      // Adjust the current/viewing user.
+      switch ($case['user']) {
+        case 'anonymous':
+          $this->drupalLogout();
+          $case['user_uid'] = 0;
+          break;
+
+        case 'authenticated':
+          $this->drupalLogin($this->web_user);
+          $case['user_uid'] = $this->web_user->uid;
+          break;
+
+        case 'admin':
+          $this->drupalLogin($this->admin_user);
+          $case['user_uid'] = $this->admin_user->uid;
+          break;
+      }
+      // Request the node with the comment.
+      $this->drupalGet('node/' . $node->nid);
+
+      // Verify classes if the comment is visible for the current user.
+      if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
+        // Verify the comment-by-anonymous class.
+        $comments = $this->xpath('//*[contains(@class, "comment-by-anonymous")]');
+        if ($case['comment_uid'] == 0) {
+          $this->assertTrue(count($comments) == 1, 'comment-by-anonymous class found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'comment-by-anonymous class not found.');
+        }
+
+        // Verify the comment-by-node-author class.
+        $comments = $this->xpath('//*[contains(@class, "comment-by-node-author")]');
+        if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['node_uid']) {
+          $this->assertTrue(count($comments) == 1, 'comment-by-node-author class found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'comment-by-node-author class not found.');
+        }
+
+        // Verify the comment-by-viewer class.
+        $comments = $this->xpath('//*[contains(@class, "comment-by-viewer")]');
+        if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['user_uid']) {
+          $this->assertTrue(count($comments) == 1, 'comment-by-viewer class found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'comment-by-viewer class not found.');
+        }
+      }
+
+      // Verify the comment-unpublished class.
+      $comments = $this->xpath('//*[contains(@class, "comment-unpublished")]');
+      if ($case['comment_status'] == COMMENT_NOT_PUBLISHED && $case['user'] == 'admin') {
+        $this->assertTrue(count($comments) == 1, 'comment-unpublished class found.');
+      }
+      else {
+        $this->assertFalse(count($comments), 'comment-unpublished class not found.');
+      }
+
+      // Verify the comment-new class.
+      if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
+        $comments = $this->xpath('//*[contains(@class, "comment-new")]');
+        if ($case['user'] != 'anonymous') {
+          $this->assertTrue(count($comments) == 1, 'comment-new class found.');
+
+          // Request the node again. The comment-new class should disappear.
+          $this->drupalGet('node/' . $node->nid);
+          $comments = $this->xpath('//*[contains(@class, "comment-new")]');
+          $this->assertFalse(count($comments), 'comment-new class not found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'comment-new class not found.');
+        }
+      }
+    }
+  }
+
   /**
    * Tests the node comment statistics.
    */
@@ -970,8 +1070,6 @@ class CommentAnonymous extends CommentHelperCase {
     // Post anonymous comment without contact info.
     $anonymous_comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName());
     $this->assertTrue($this->commentExists($anonymous_comment1), t('Anonymous comment without contact info found.'));
-    $anonymous_class = $this->xpath('//a[@id=:comment_id]/following-sibling::div[1][contains(@class, "comment-by-anonymous")]', array(':comment_id' => 'comment-' . $anonymous_comment1->id));
-    $this->assertTrue(!empty($anonymous_class), t('HTML class for anonymous comments found.'));
 
     // Allow contact info.
     $this->drupalLogin($this->admin_user);
diff --git a/modules/contact/contact.admin.inc b/modules/contact/contact.admin.inc
index 9fde037d..4648fd3d 100644
--- a/modules/contact/contact.admin.inc
+++ b/modules/contact/contact.admin.inc
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Admin page callbacks for the contact module.
+ * Admin page callbacks for the Contact module.
  */
 
 /**
@@ -53,7 +53,22 @@ function contact_category_list() {
 }
 
 /**
- * Category edit page.
+ * Form constructor for the category edit form.
+ *
+ * @param $category
+ *   An array describing the category to be edited. May be empty for new
+ *   categories. Recognized array keys are:
+ *   - category: The name of the category.
+ *   - recipients: A comma-separated list of recipients.
+ *   - reply: (optional) The body of the auto-reply message.
+ *   - weight: The weight of the category.
+ *   - selected: Boolean indicating whether the category should be selected by
+ *     default.
+ *   - cid: The category ID for which the form is to be displayed.
+ *
+ * @see contact_category_edit_form_validate()
+ * @see contact_category_edit_form_submit()
+ * @ingroup forms
  */
 function contact_category_edit_form($form, &$form_state, array $category = array()) {
   // If this is a new category, add the default values.
@@ -117,7 +132,9 @@ function contact_category_edit_form($form, &$form_state, array $category = array
 }
 
 /**
- * Validate the contact category edit page form submission.
+ * Form validation handler for contact_category_edit_form().
+ *
+ * @see contact_category_edit_form_submit()
  */
 function contact_category_edit_form_validate($form, &$form_state) {
   // Validate and each e-mail recipient.
@@ -144,7 +161,9 @@ function contact_category_edit_form_validate($form, &$form_state) {
 }
 
 /**
- * Process the contact category edit page form submission.
+ * Form submission handler for contact_category_edit_form().
+ *
+ * @see contact_category_edit_form_validate()
  */
 function contact_category_edit_form_submit($form, &$form_state) {
   if ($form_state['values']['selected']) {
@@ -167,8 +186,13 @@ function contact_category_edit_form_submit($form, &$form_state) {
 }
 
 /**
- * Form builder for deleting a contact category.
+ * Form constructor for the contact category deletion form.
+ *
+ * @param $contact
+ *   Array describing the contact category to be deleted. See the documentation
+ *   of contact_category_edit_form() for the recognized keys.
  *
+ * @see contact_menu()
  * @see contact_category_delete_form_submit()
  */
 function contact_category_delete_form($form, &$form_state, array $contact) {
@@ -188,9 +212,7 @@ function contact_category_delete_form($form, &$form_state, array $contact) {
 }
 
 /**
- * Submit handler for the confirm delete category form.
- *
- * @see contact_category_delete_form()
+ * Form submission handler for contact_category_delete_form().
  */
 function contact_category_delete_form_submit($form, &$form_state) {
   $contact = $form['contact']['#value'];
diff --git a/modules/contact/contact.info b/modules/contact/contact.info
index 4efaed93..fd41564f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/contact/contact.module b/modules/contact/contact.module
index eaae9c62..a8701827 100644
--- a/modules/contact/contact.module
+++ b/modules/contact/contact.module
@@ -110,10 +110,7 @@ function contact_menu() {
  * Menu access callback for a user's personal contact form.
  *
  * @param $account
- *   A user account object.
- * @return
- *   TRUE if the current user has access to the requested user's contact form,
- *   or FALSE otherwise.
+ *   The user object of the user whose contact form is being requested.
  */
 function _contact_personal_tab_access($account) {
   global $user;
@@ -148,10 +145,11 @@ function _contact_personal_tab_access($account) {
 }
 
 /**
- * Load a contact category.
+ * Loads a contact category.
  *
  * @param $cid
  *   The contact category ID.
+ *
  * @return
  *   An array with the contact category's data.
  */
@@ -211,6 +209,8 @@ function contact_mail($key, &$message, $params) {
  * Implements hook_form_FORM_ID_alter().
  *
  * Add the enable personal contact form to an individual user's account page.
+ *
+ * @see user_profile_form()
  */
 function contact_form_user_profile_form_alter(&$form, &$form_state) {
   if ($form['#user_category'] == 'account') {
@@ -241,6 +241,8 @@ function contact_user_presave(&$edit, $account, $category) {
  * Implements hook_form_FORM_ID_alter().
  *
  * Add the default personal contact setting on the user settings page.
+ *
+ * @see user_admin_settings()
  */
 function contact_form_user_admin_settings_alter(&$form, &$form_state) {
   $form['contact'] = array(
diff --git a/modules/contact/contact.pages.inc b/modules/contact/contact.pages.inc
index 30b28250..ba8918bf 100644
--- a/modules/contact/contact.pages.inc
+++ b/modules/contact/contact.pages.inc
@@ -2,14 +2,15 @@
 
 /**
  * @file
- * User page callbacks for the contact module.
+ * Page callbacks for the Contact module.
  */
 
 /**
- * Form builder; the site-wide contact form.
+ * Form constructor for the site-wide contact form.
  *
  * @see contact_site_form_validate()
  * @see contact_site_form_submit()
+ * @ingroup forms
  */
 function contact_site_form($form, &$form_state) {
   global $user;
@@ -112,6 +113,8 @@ function contact_site_form($form, &$form_state) {
 
 /**
  * Form validation handler for contact_site_form().
+ *
+ * @see contact_site_form_submit()
  */
 function contact_site_form_validate($form, &$form_state) {
   if (!$form_state['values']['cid']) {
@@ -124,6 +127,8 @@ function contact_site_form_validate($form, &$form_state) {
 
 /**
  * Form submission handler for contact_site_form().
+ *
+ * @see contact_site_form_validate()
  */
 function contact_site_form_submit($form, &$form_state) {
   global $user, $language;
@@ -166,10 +171,14 @@ function contact_site_form_submit($form, &$form_state) {
 }
 
 /**
- * Form builder; the personal contact form.
+ * Form constructor for the personal contact form.
  *
+ * Path: user/%user/contact
+ *
+ * @see contact_menu()
  * @see contact_personal_form_validate()
  * @see contact_personal_form_submit()
+ * @ingroup forms
  */
 function contact_personal_form($form, &$form_state, $recipient) {
   global $user;
@@ -244,7 +253,7 @@ function contact_personal_form($form, &$form_state, $recipient) {
 /**
  * Form validation handler for contact_personal_form().
  *
- * @see contact_personal_form()
+ * @see contact_personal_form_submit()
  */
 function contact_personal_form_validate($form, &$form_state) {
   if (!valid_email_address($form_state['values']['mail'])) {
@@ -255,7 +264,7 @@ function contact_personal_form_validate($form, &$form_state) {
 /**
  * Form submission handler for contact_personal_form().
  *
- * @see contact_personal_form()
+ * @see contact_personal_form_validate()
  */
 function contact_personal_form_submit($form, &$form_state) {
   global $user, $language;
diff --git a/modules/contact/contact.test b/modules/contact/contact.test
index 129eb30c..48c8bb01 100644
--- a/modules/contact/contact.test
+++ b/modules/contact/contact.test
@@ -1,10 +1,12 @@
 <?php
-
 /**
- * @file 
- * Tests for contact.module.
+ * @file
+ * Tests for the Contact module.
  */
 
+/**
+ * Tests the site-wide contact form.
+ */
 class ContactSitewideTestCase extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
@@ -19,7 +21,7 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Test configuration options and site-wide contact form.
+   * Tests configuration options and the site-wide contact form.
    */
   function testSiteWideContact() {
     // Create and login administrative user.
@@ -159,7 +161,7 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-  * Test auto-reply on the site-wide contact form.
+  * Tests auto-reply on the site-wide contact form.
   */
   function testAutoReply() {
     // Create and login administrative user.
@@ -200,12 +202,17 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Add a category.
+   * Adds a category.
    *
-   * @param string $category Name of category.
-   * @param string $recipients List of recipient e-mail addresses.
-   * @param string $reply Auto-reply text.
-   * @param boolean $selected Defautly selected.
+   * @param string $category
+   *   The category name.
+   * @param string $recipients
+   *   The list of recipient e-mail addresses.
+   * @param string $reply
+   *   The auto-reply text that is sent to a user upon completing the contact
+   *   form.
+   * @param boolean $selected
+   *   Boolean indicating whether the category should be selected by default.
    */
   function addCategory($category, $recipients, $reply, $selected) {
     $edit = array();
@@ -217,12 +224,17 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Update a category.
+   * Updates a category.
    *
-   * @param string $category Name of category.
-   * @param string $recipients List of recipient e-mail addresses.
-   * @param string $reply Auto-reply text.
-   * @param boolean $selected Defautly selected.
+   * @param string $category
+   *   The category name.
+   * @param string $recipients
+   *   The list of recipient e-mail addresses.
+   * @param string $reply
+   *   The auto-reply text that is sent to a user upon completing the contact
+   *   form.
+   * @param boolean $selected
+   *   Boolean indicating whether the category should be selected by default.
    */
   function updateCategory($categories, $category, $recipients, $reply, $selected) {
     $category_id = $categories[array_rand($categories)];
@@ -236,13 +248,18 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Submit contact form.
+   * Submits the contact form.
    *
-   * @param string $name Name.
-   * @param string $mail E-mail address.
-   * @param string $subject Subject.
-   * @param integer $cid Category id.
-   * @param string $message Message.
+   * @param string $name
+   *   The name of the sender.
+   * @param string $mail
+   *   The e-mail address of the sender.
+   * @param string $subject
+   *   The subject of the message.
+   * @param integer $cid
+   *   The category ID of the message.
+   * @param string $message
+   *   The message body.
    */
   function submitContact($name, $mail, $subject, $cid, $message) {
     $edit = array();
@@ -255,7 +272,7 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Delete all categories.
+   * Deletes all categories.
    */
   function deleteCategories() {
     $categories = $this->getCategories();
@@ -267,9 +284,10 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Get list category ids.
+   * Gets a list of all category IDs.
    *
-   * @return array Category ids.
+   * @return array
+   *   A list of the category IDs.
    */
   function getCategories() {
     $categories = db_query('SELECT cid FROM {contact}')->fetchCol();
@@ -278,7 +296,7 @@ class ContactSitewideTestCase extends DrupalWebTestCase {
 }
 
 /**
- * Test the personal contact form.
+ * Tests the personal contact form.
  */
 class ContactPersonalTestCase extends DrupalWebTestCase {
   private $admin_user;
@@ -306,7 +324,7 @@ class ContactPersonalTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Test personal contact form access.
+   * Tests access to the personal contact form.
    */
   function testPersonalContactAccess() {
     // Test allowed access to user with contact form enabled.
@@ -369,7 +387,7 @@ class ContactPersonalTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Test the personal contact form flood protection.
+   * Tests the personal contact form flood protection.
    */
   function testPersonalContactFlood() {
     $flood_limit = 3;
@@ -399,7 +417,7 @@ class ContactPersonalTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Fill out a user's personal contact form and submit.
+   * Fills out a user's personal contact form and submits it.
    *
    * @param $account
    *   A user object of the user being contacted.
diff --git a/modules/contextual/contextual.info b/modules/contextual/contextual.info
index e6fdace0..c4c8418f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/dashboard/dashboard.info b/modules/dashboard/dashboard.info
index 294c0257..43227ad0 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/dblog/dblog.info b/modules/dblog/dblog.info
index 7fa0931a..cde11a86 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/field.api.php b/modules/field/field.api.php
index d0d5da9c..329cf16d 100644
--- a/modules/field/field.api.php
+++ b/modules/field/field.api.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @ingroup field_fieldable_type
+ * @ingroup hooks
  * @{
  */
 
@@ -80,10 +80,6 @@ function hook_field_extra_fields_alter(&$info) {
   }
 }
 
-/**
- * @} End of "ingroup field_fieldable_type"
- */
-
 /**
  * @defgroup field_types Field Types API
  * @{
@@ -119,6 +115,9 @@ function hook_field_extra_fields_alter(&$info) {
  *
  * A third kind of pluggable handlers, storage backends, is defined by the
  * @link field_storage Field Storage API @endlink.
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
@@ -706,6 +705,7 @@ function hook_field_is_empty($item, $field) {
  * @see hook_field_widget_form_alter()
  * @see hook_field_widget_WIDGET_TYPE_form_alter()
  * @see hook_field_widget_error()
+ * @see hook_field_widget_settings_form()
  */
 function hook_field_widget_info() {
     return array(
@@ -1505,10 +1505,6 @@ function hook_field_attach_delete_bundle($entity_type, $bundle, $instances) {
  * @} End of "ingroup field_attach"
  */
 
-/**********************************************************************
- * Field Storage API
- **********************************************************************/
-
 /**
  * @ingroup field_storage
  * @{
@@ -2346,10 +2342,6 @@ function hook_field_widget_properties_ENTITY_TYPE_alter(&$widget, $context) {
  * @} End of "ingroup field_storage"
  */
 
-/**********************************************************************
- * Field CRUD API
- **********************************************************************/
-
 /**
  * @ingroup field_crud
  * @{
@@ -2603,10 +2595,6 @@ function hook_field_storage_purge($entity_type, $entity, $field, $instance) {
  * @} End of "ingroup field_crud"
  */
 
-/**********************************************************************
- * TODO: I'm not sure where these belong yet.
- **********************************************************************/
-
 /**
  * Determine whether the user has access to a given field.
  *
@@ -2633,3 +2621,7 @@ function hook_field_access($op, $field, $entity_type, $entity, $account) {
   }
   return TRUE;
 }
+
+/**
+ * @} End of "ingroup hooks"
+ */
diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc
index 2419201d..bd2934b4 100644
--- a/modules/field/field.attach.inc
+++ b/modules/field/field.attach.inc
@@ -44,6 +44,9 @@ class FieldValidationException extends FieldException {
  *
  * Each field defines which storage backend it uses. The Drupal system variable
  * 'field_storage_default' identifies the storage backend used by default.
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
@@ -117,6 +120,12 @@ define('FIELD_STORAGE_INSERT', 'insert');
  * The pre-operation hooks do not make the Field Storage API irrelevant. The
  * Field Storage API is essentially the "fallback mechanism" for any fields
  * that aren't being intercepted explicitly by pre-operation hooks.
+ *
+ * @link field_language Field Language API @endlink provides information about
+ * the structure of field objects.
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
@@ -185,8 +194,10 @@ function _field_invoke($op, $entity_type, $entity, &$a = NULL, &$b = NULL, $opti
   // Iterate through the instances and collect results.
   $return = array();
   foreach ($instances as $instance) {
-    $field_name = $instance['field_name'];
-    $field = field_info_field($field_name);
+    // field_info_field() is not available for deleted fields, so use
+    // field_info_field_by_id().
+    $field = field_info_field_by_id($instance['field_id']);
+    $field_name = $field['field_name'];
     $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
     if (function_exists($function)) {
       // Determine the list of languages to iterate on.
@@ -694,7 +705,8 @@ function field_attach_load($entity_type, $entities, $age = FIELD_LOAD_CURRENT, $
     }
 
     // Invoke field-type module's hook_field_load().
-    _field_invoke_multiple('load', $entity_type, $queried_entities, $age, $options);
+    $null = NULL;
+    _field_invoke_multiple('load', $entity_type, $queried_entities, $age, $null, $options);
 
     // Invoke hook_field_attach_load(): let other modules act on loading the
     // entitiy.
diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc
index e34c0c52..6df32352 100644
--- a/modules/field/field.crud.inc
+++ b/modules/field/field.crud.inc
@@ -15,6 +15,9 @@
  *
  * The Field CRUD API uses
  * @link field Field API data structures @endlink.
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
@@ -42,10 +45,11 @@
  *       system variable.
  *     - settings: each omitted setting is given the default value specified in
  *       hook_field_storage_info().
+ *
  * @return
  *   The $field array with the id property filled in.
- * @throw
- *   FieldException
+ *
+ * @throws FieldException
  *
  * See: @link field Field API data structures @endlink.
  */
@@ -442,8 +446,8 @@ function field_delete_field($field_name) {
  *
  * @return
  *   The $instance array with the id property filled in.
- * @throw
- *   FieldException
+ *
+ * @throws FieldException
  *
  * See: @link field Field API data structures @endlink.
  */
@@ -510,8 +514,7 @@ function field_create_instance($instance) {
  *   properties specified in $instance overwrite the existing values for
  *   the instance.
  *
- * @throw
- *   FieldException
+ * @throws FieldException
  *
  * @see field_create_instance()
  */
@@ -824,6 +827,9 @@ function field_delete_instance($instance, $field_cleanup = TRUE) {
  *     ),
  *   );
  * @endcode
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
diff --git a/modules/field/field.info b/modules/field/field.info
index 15cab0e7..3a377477 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/field.info.inc b/modules/field/field.info.inc
index 6b172dd3..3b36c035 100644
--- a/modules/field/field.info.inc
+++ b/modules/field/field.info.inc
@@ -13,6 +13,9 @@
  * The Field Info API exposes information about field types, fields,
  * instances, bundles, widget types, display formatters, behaviors,
  * and settings defined by or with the Field API.
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
@@ -24,6 +27,7 @@
  */
 function field_info_cache_clear() {
   drupal_static_reset('field_view_mode_settings');
+  drupal_static_reset('field_available_languages');
 
   // @todo: Remove this when field_attach_*_bundle() bundle management
   // functions are moved to the entity API.
@@ -602,8 +606,9 @@ function field_info_fields() {
  *
  * @param $field_name
  *   The name of the field to retrieve. $field_name can only refer to a
- *   non-deleted, active field. Use field_read_fields() to retrieve information
- *   on deleted or inactive fields.
+ *   non-deleted, active field. For deleted fields, use
+ *   field_info_field_by_id(). To retrieve information about inactive fields,
+ *   use field_read_fields().
  *
  * @return
  *   The field array, as returned by field_read_fields(), with an
@@ -624,7 +629,7 @@ function field_info_field($field_name) {
  *
  * @param $field_id
  *   The id of the field to retrieve. $field_id can refer to a
- *   deleted field.
+ *   deleted field, but not an inactive one.
  *
  * @return
  *   The field array, as returned by field_read_fields(), with an
diff --git a/modules/field/field.multilingual.inc b/modules/field/field.multilingual.inc
index 5373d970..4b4f01d7 100644
--- a/modules/field/field.multilingual.inc
+++ b/modules/field/field.multilingual.inc
@@ -57,6 +57,9 @@
  *   even disabled by modules implementing hook_field_language_alter(), making
  *   it possible to choose the first approach. The display language for each
  *   field is returned by field_language().
+ *
+ * See @link field Field API @endlink for information about the other parts of
+ * the Field API.
  */
 
 /**
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 dcf342b1..a1a6681b 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/modules/list/list.info b/modules/field/modules/list/list.info
index f470ee2e..285340ac 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/modules/list/tests/list_test.info b/modules/field/modules/list/tests/list_test.info
index 78cd65af..01011b31 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/modules/number/number.info b/modules/field/modules/number/number.info
index 78fa8edc..93c9b880 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/modules/options/options.info b/modules/field/modules/options/options.info
index d39c1864..f51cd1bd 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/modules/text/text.info b/modules/field/modules/text/text.info
index 2460e5cb..1ae0854d 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test
index 669fc37c..657f1f36 100644
--- a/modules/field/tests/field.test
+++ b/modules/field/tests/field.test
@@ -72,12 +72,13 @@ class FieldTestCase extends DrupalWebTestCase {
 }
 
 class FieldAttachTestCase extends FieldTestCase {
-  function setUp($modules = array()) {
+  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.
-    if (!is_array($modules)) {
-      $modules = func_get_args();
+    $modules = func_get_args();
+    if (isset($modules[0]) && is_array($modules[0])) {
+      $modules = $modules[0];
     }
     if (!in_array('field_test', $modules)) {
       $modules[] = 'field_test';
@@ -2674,7 +2675,7 @@ class FieldTranslationsTestCase extends FieldTestCase {
 
     // Test field_available_languages() behavior for untranslatable fields.
     $this->field['translatable'] = FALSE;
-    $this->field_name = $this->field['field_name'] = $this->instance['field_name'] = drupal_strtolower($this->randomName() . '_field_name');
+    field_update_field($this->field);
     $available_languages = field_available_languages($this->entity_type, $this->field);
     $this->assertTrue(count($available_languages) == 1 && $available_languages[0] === LANGUAGE_NONE, t('For untranslatable fields only LANGUAGE_NONE is available.'));
   }
@@ -2989,22 +2990,54 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
    */
   function _generateStubEntities($entity_type, $entities, $field_name = NULL) {
     $stubs = array();
-    foreach ($entities as $entity) {
+    foreach ($entities as $id => $entity) {
       $stub = entity_create_stub_entity($entity_type, entity_extract_ids($entity_type, $entity));
       if (isset($field_name)) {
         $stub->{$field_name} = $entity->{$field_name};
       }
-      $stubs[] = $stub;
+      $stubs[$id] = $stub;
     }
     return $stubs;
   }
 
+  /**
+   * Tests that the expected hooks have been invoked on the expected entities.
+   *
+   * @param $expected_hooks
+   *   An array keyed by hook name, with one entry per expected invocation.
+   *   Each entry is the value of the "$entity" parameter the hook is expected
+   *   to have been passed.
+   * @param $actual_hooks
+   *   The array of actual hook invocations recorded by field_test_memorize().
+   */
+  function checkHooksInvocations($expected_hooks, $actual_hooks) {
+    foreach ($expected_hooks as $hook => $invocations) {
+      $actual_invocations = $actual_hooks[$hook];
+
+      // Check that the number of invocations is correct.
+      $this->assertEqual(count($actual_invocations), count($invocations), "$hook() was called the expected number of times.");
+
+      // Check that the hook was called for each expected argument.
+      foreach ($invocations as $argument) {
+        $found = FALSE;
+        foreach ($actual_invocations as $actual_arguments) {
+          if ($actual_arguments[1] == $argument) {
+            $found = TRUE;
+            break;
+          }
+        }
+        $this->assertTrue($found, "$hook() was called on expected argument");
+      }
+    }
+  }
+
   function setUp() {
     parent::setUp('field_test');
 
-    // Clean up data from previous test cases.
     $this->fields = array();
     $this->instances = array();
+    $this->entities = array();
+    $this->entities_by_bundles = array();
 
     // Create two bundles.
     $this->bundles = array('bb_1' => 'bb_1', 'bb_2' => 'bb_2');
@@ -3040,7 +3073,10 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
         foreach ($this->fields as $field) {
           $entity->{$field['field_name']}[LANGUAGE_NONE] = $this->_generateTestFieldValues($field['cardinality']);
         }
+
         $this->entities[$id] = $entity;
+        // Also keep track of the entities per bundle.
+        $this->entities_by_bundles[$bundle][$id] = $entity;
         field_attach_insert($this->entity_type, $entity);
         $id++;
       }
@@ -3105,6 +3141,7 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
    * instance is deleted.
    */
   function testPurgeInstance() {
+    // Start recording hook invocations.
     field_test_memorize();
 
     $bundle = reset($this->bundles);
@@ -3119,7 +3156,7 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
     $this->assertEqual(count($mem), 0, 'No field hooks were called');
 
     $batch_size = 2;
-    for ($count = 8; $count >= 0; $count -= 2) {
+    for ($count = 8; $count >= 0; $count -= $batch_size) {
       // Purge two entities.
       field_purge_batch($batch_size);
 
@@ -3133,19 +3170,21 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
       $this->assertEqual($count ? count($found['test_entity']) : count($found), $count, 'Correct number of entities found after purging 2');
     }
 
-    // hook_field_delete() was called on a pseudo-entity for each entity. Each
-    // pseudo entity has a $field property that matches the original entity,
-    // but no others.
-    $mem = field_test_memorize();
-    $this->assertEqual(count($mem['field_test_field_delete']), 10, 'hook_field_delete was called for the right number of entities');
-    $stubs = $this->_generateStubEntities($this->entity_type, $this->entities, $field['field_name']);
-    $count = count($stubs);
-    foreach ($mem['field_test_field_delete'] as $args) {
-      $entity = $args[1];
-      $this->assertEqual($stubs[$entity->ftid], $entity, 'hook_field_delete() called with the correct stub');
-      unset($stubs[$entity->ftid]);
+    // Check hooks invocations.
+    // - hook_field_load() (multiple hook) should have been called on all
+    // entities by pairs of two.
+    // - hook_field_delete() should have been called once for each entity in the
+    // bundle.
+    $actual_hooks = field_test_memorize();
+    $hooks = array();
+    $stubs = $this->_generateStubEntities($this->entity_type, $this->entities_by_bundles[$bundle], $field['field_name']);
+    foreach (array_chunk($stubs, $batch_size, TRUE) as $chunk) {
+      $hooks['field_test_field_load'][] = $chunk;
     }
-    $this->assertEqual(count($stubs), $count-10, 'hook_field_delete was called with each entity once');
+    foreach ($stubs as $stub) {
+      $hooks['field_test_field_delete'][] = $stub;
+    }
+    $this->checkHooksInvocations($hooks, $actual_hooks);
 
     // The instance still exists, deleted.
     $instances = field_read_instances(array('field_id' => $field['id'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1));
@@ -3168,15 +3207,37 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
    * instances are deleted and purged.
    */
   function testPurgeField() {
+    // Start recording hook invocations.
+    field_test_memorize();
+
     $field = reset($this->fields);
 
     // Delete the first instance.
-    $instance = field_info_instance($this->entity_type, $field['field_name'], 'bb_1');
+    $bundle = reset($this->bundles);
+    $instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
     field_delete_instance($instance);
 
+    // Assert that hook_field_delete() was not called yet.
+    $mem = field_test_memorize();
+    $this->assertEqual(count($mem), 0, 'No field hooks were called.');
+
     // Purge the data.
     field_purge_batch(10);
 
+    // Check hooks invocations.
+    // - hook_field_load() (multiple hook) should have been called once, for all
+    // entities in the bundle.
+    // - hook_field_delete() should have been called once for each entity in the
+    // bundle.
+    $actual_hooks = field_test_memorize();
+    $hooks = array();
+    $stubs = $this->_generateStubEntities($this->entity_type, $this->entities_by_bundles[$bundle], $field['field_name']);
+    $hooks['field_test_field_load'][] = $stubs;
+    foreach ($stubs as $stub) {
+      $hooks['field_test_field_delete'][] = $stub;
+    }
+    $this->checkHooksInvocations($hooks, $actual_hooks);
+
     // Purge again to purge the instance.
     field_purge_batch(0);
 
@@ -3185,12 +3246,27 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
     $this->assertTrue(isset($fields[$field['id']]) && !$fields[$field['id']]['deleted'], 'The field exists and is not deleted');
 
     // Delete the second instance.
-    $instance = field_info_instance($this->entity_type, $field['field_name'], 'bb_2');
+    $bundle = next($this->bundles);
+    $instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
     field_delete_instance($instance);
 
+    // Assert that hook_field_delete() was not called yet.
+    $mem = field_test_memorize();
+    $this->assertEqual(count($mem), 0, 'No field hooks were called.');
+
     // Purge the data.
     field_purge_batch(10);
 
+    // Check hooks invocations (same as above, for the 2nd bundle).
+    $actual_hooks = field_test_memorize();
+    $hooks = array();
+    $stubs = $this->_generateStubEntities($this->entity_type, $this->entities_by_bundles[$bundle], $field['field_name']);
+    $hooks['field_test_field_load'][] = $stubs;
+    foreach ($stubs as $stub) {
+      $hooks['field_test_field_delete'][] = $stub;
+    }
+    $this->checkHooksInvocations($hooks, $actual_hooks);
+
     // The field still exists, deleted.
     $fields = field_read_fields(array('id' => $field['id']), array('include_deleted' => 1));
     $this->assertTrue(isset($fields[$field['id']]) && $fields[$field['id']]['deleted'], 'The field exists and is deleted');
diff --git a/modules/field/tests/field_test.entity.inc b/modules/field/tests/field_test.entity.inc
index b7c70a67..52ed3fcd 100644
--- a/modules/field/tests/field_test.entity.inc
+++ b/modules/field/tests/field_test.entity.inc
@@ -58,7 +58,7 @@ function field_test_entity_info() {
         'id' => 'ftid',
         'bundle' => 'fttype',
       ),
-      'bundles' => array('bundle1' => array('label' => 'Bundle1'), 'bundle2' => array('label' => 'Bundle2')),
+      'bundles' => array('bundle1' => array('label' => 'Bundle1'), 'bundle2' => array('label' => 'Bundle2')) + $bundles,
       'view modes' => $test_entity_modes,
     ),
     // In this case, the bundle key is not stored in the database.
@@ -72,7 +72,7 @@ function field_test_entity_info() {
         'id' => 'ftid',
         'bundle' => 'fttype',
       ),
-      'bundles' => array('test_entity_2' => array('label' => 'Test entity 2')),
+      'bundles' => array('test_entity_2' => array('label' => 'Test entity 2')) + $bundles,
       'view modes' => $test_entity_modes,
     ),
     // @see EntityPropertiesTestCase::testEntityLabel()
diff --git a/modules/field/tests/field_test.field.inc b/modules/field/tests/field_test.field.inc
index b8a2939d..cc76a998 100644
--- a/modules/field/tests/field_test.field.inc
+++ b/modules/field/tests/field_test.field.inc
@@ -58,6 +58,9 @@ function field_test_field_update_forbid($field, $prior_field, $has_data) {
  * Implements hook_field_load().
  */
 function field_test_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
+  $args = func_get_args();
+  field_test_memorize(__FUNCTION__, $args);
+
   foreach ($items as $id => $item) {
     // To keep the test non-intrusive, only act for instances with the
     // test_hook_field_load setting explicitly set to TRUE.
@@ -72,6 +75,30 @@ function field_test_field_load($entity_type, $entities, $field, $instances, $lan
   }
 }
 
+/**
+ * Implements hook_field_insert().
+ */
+function field_test_field_insert($entity_type, $entity, $field, $instance, $items) {
+  $args = func_get_args();
+  field_test_memorize(__FUNCTION__, $args);
+}
+
+/**
+ * Implements hook_field_update().
+ */
+function field_test_field_update($entity_type, $entity, $field, $instance, $items) {
+  $args = func_get_args();
+  field_test_memorize(__FUNCTION__, $args);
+}
+
+/**
+ * Implements hook_field_delete().
+ */
+function field_test_field_delete($entity_type, $entity, $field, $instance, $items) {
+  $args = func_get_args();
+  field_test_memorize(__FUNCTION__, $args);
+}
+
 /**
  * Implements hook_field_validate().
  *
@@ -79,6 +106,9 @@ function field_test_field_load($entity_type, $entities, $field, $instances, $lan
  * - 'field_test_invalid': The value is invalid.
  */
 function field_test_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
+  $args = func_get_args();
+  field_test_memorize(__FUNCTION__, $args);
+
   foreach ($items as $delta => $item) {
     if ($item['value'] == -1) {
       $errors[$field['field_name']][$langcode][$delta][] = array(
@@ -350,11 +380,13 @@ function field_test_field_formatter_view($entity_type, $entity, $field, $instanc
       break;
 
     case 'field_test_multiple':
-      $array = array();
-      foreach ($items as $delta => $item) {
-        $array[] = $delta . ':' . $item['value'];
+      if (!empty($items)) {
+        $array = array();
+        foreach ($items as $delta => $item) {
+          $array[] = $delta . ':' . $item['value'];
+        }
+        $element[0] = array('#markup' => $settings['test_formatter_setting_multiple'] . '|' . implode('|', $array));
       }
-      $element[0] = array('#markup' => $settings['test_formatter_setting_multiple'] . '|' . implode('|', $array));
       break;
   }
 
diff --git a/modules/field/tests/field_test.info b/modules/field/tests/field_test.info
index 5a408694..6385c992 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field/tests/field_test.module b/modules/field/tests/field_test.module
index 7f43fbf0..0015cd90 100644
--- a/modules/field/tests/field_test.module
+++ b/modules/field/tests/field_test.module
@@ -182,30 +182,6 @@ function field_test_field_create_field($field) {
   field_test_memorize(__FUNCTION__, $args);
 }
 
-/**
- * Memorize calls to hook_field_insert().
- */
-function field_test_field_insert($entity_type, $entity, $field, $instance, $items) {
-  $args = func_get_args();
-  field_test_memorize(__FUNCTION__, $args);
-}
-
-/**
- * Memorize calls to hook_field_update().
- */
-function field_test_field_update($entity_type, $entity, $field, $instance, $items) {
-  $args = func_get_args();
-  field_test_memorize(__FUNCTION__, $args);
-}
-
-/**
- * Memorize calls to hook_field_delete().
- */
-function field_test_field_delete($entity_type, $entity, $field, $instance, $items) {
-  $args = func_get_args();
-  field_test_memorize(__FUNCTION__, $args);
-}
-
 /**
  * Implements hook_entity_query_alter().
  */
@@ -248,3 +224,38 @@ function field_test_field_attach_view_alter(&$output, $context) {
     $output['test_field'][] = array('#markup' => 'field_test_field_attach_view_alter');
   }
 }
+
+/**
+ * Implements hook_field_widget_properties_alter().
+ */
+function field_test_field_widget_properties_alter(&$widget, $context) {
+  // Make the alter_test_text field 42 characters for nodes and comments.
+  if (in_array($context['entity_type'], array('node', 'comment')) && ($context['field']['field_name'] == 'alter_test_text')) {
+    $widget['settings']['size'] = 42;
+  }
+}
+
+/**
+ * Implements hook_field_widget_properties_ENTITY_TYPE_alter().
+ */
+function field_test_field_widget_properties_user_alter(&$widget, $context) {
+  // Always use buttons for the alter_test_options field on user forms.
+  if ($context['field']['field_name'] == 'alter_test_options') {
+    $widget['type'] = 'options_buttons';
+  }
+}
+
+/**
+ * Implements hook_field_widget_form_alter().
+ */
+function field_test_field_widget_form_alter(&$element, &$form_state, $context) {
+  switch ($context['field']['field_name']) {
+    case 'alter_test_text':
+      drupal_set_message('Field size: ' . $context['instance']['widget']['settings']['size']);
+      break;
+
+    case 'alter_test_options':
+      drupal_set_message('Widget type: ' . $context['instance']['widget']['type']);
+      break;
+  }
+}
diff --git a/modules/field_ui/field_ui-rtl.css b/modules/field_ui/field_ui-rtl.css
index 123a840b..1066baa2 100644
--- a/modules/field_ui/field_ui-rtl.css
+++ b/modules/field_ui/field_ui-rtl.css
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Right-to-left specific stylesheet for the Field UI module.
+ */
 
 /* 'Manage fields' overview */
 table.field-ui-overview tr.add-new .label-input {
diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc
index fa19afc0..36c58f60 100644
--- a/modules/field_ui/field_ui.admin.inc
+++ b/modules/field_ui/field_ui.admin.inc
@@ -51,7 +51,7 @@ function field_ui_fields_list() {
 }
 
 /**
- * Helper function to display a message about inactive fields.
+ * Displays a message listing the inactive fields of a given bundle.
  */
 function field_ui_inactive_message($entity_type, $bundle) {
   $inactive_instances = field_ui_inactive_instances($entity_type, $bundle);
@@ -72,9 +72,9 @@ function field_ui_inactive_message($entity_type, $bundle) {
 }
 
 /**
- * Helper function: determines the rendering order of a tree array.
+ * Determines the rendering order of an array representing a tree.
  *
- * This is intended as a callback for array_reduce().
+ * Callback for array_reduce() within field_ui_table_pre_render().
  */
 function _field_ui_reduce_order($array, $a) {
   $array = !isset($array) ? array() : $array;
@@ -91,8 +91,9 @@ function _field_ui_reduce_order($array, $a) {
 /**
  * Returns the region to which a row in the 'Manage fields' screen belongs.
  *
- * This function is used as a #row_callback in field_ui_field_overview_form(),
- * and is called during field_ui_table_pre_render().
+ * This function is used as a #region_callback in
+ * field_ui_field_overview_form(). It is called during
+ * field_ui_table_pre_render().
  */
 function field_ui_field_overview_row_region($row) {
   switch ($row['#row_type']) {
@@ -109,8 +110,9 @@ function field_ui_field_overview_row_region($row) {
 /**
  * Returns the region to which a row in the 'Manage display' screen belongs.
  *
- * This function is used as a #row_callback in field_ui_field_overview_form(),
- * and is called during field_ui_table_pre_render().
+ * This function is used as a #region_callback in
+ * field_ui_field_overview_form(), and is called during
+ * field_ui_table_pre_render().
  */
 function field_ui_display_overview_row_region($row) {
   switch ($row['#row_type']) {
@@ -215,9 +217,9 @@ function theme_field_ui_table($variables) {
 
   // Determine the colspan to use for region rows, by checking the number of
   // columns in the headers.
-  $colums_count = 0;
+  $columns_count = 0;
   foreach ($table['header'] as $header) {
-    $colums_count += (is_array($header) && isset($header['colspan']) ? $header['colspan'] : 1);
+    $columns_count += (is_array($header) && isset($header['colspan']) ? $header['colspan'] : 1);
   }
 
   // Render rows, region by region.
@@ -230,7 +232,7 @@ function theme_field_ui_table($variables) {
         'class' => array('region-title', 'region-' . $region_name_class . '-title'),
         'no_striping' => TRUE,
         'data' => array(
-          array('data' => $region['title'], 'colspan' => $colums_count),
+          array('data' => $region['title'], 'colspan' => $columns_count),
         ),
       );
     }
@@ -240,7 +242,7 @@ function theme_field_ui_table($variables) {
         'class' => array('region-message', 'region-' . $region_name_class . '-message', $class),
         'no_striping' => TRUE,
         'data' => array(
-          array('data' => $region['message'], 'colspan' => $colums_count),
+          array('data' => $region['message'], 'colspan' => $columns_count),
         ),
       );
     }
@@ -274,9 +276,13 @@ function theme_field_ui_table($variables) {
 }
 
 /**
- * Menu callback; listing of fields for a bundle.
+ * Form constructor for the 'Manage fields' form of a bundle.
  *
  * Allows fields and pseudo-fields to be re-ordered.
+ *
+ * @see field_ui_overview_form_validate().
+ * @see field_ui_overview_form_submit().
+ * @ingroup forms
  */
 function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle) {
   $bundle = field_extract_bundle($entity_type, $bundle);
@@ -630,7 +636,9 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
 }
 
 /**
- * Validate handler for the field overview form.
+ * Form validation handler for field_ui_field_overview_form().
+ *
+ * @see field_ui_field_overview_form_submit()
  */
 function field_ui_field_overview_form_validate($form, &$form_state) {
   _field_ui_field_overview_form_validate_add_new($form, $form_state);
@@ -638,9 +646,9 @@ function field_ui_field_overview_form_validate($form, &$form_state) {
 }
 
 /**
- * Helper function for field_ui_field_overview_form_validate.
+ * Validates the 'add new field' row of field_ui_field_overview_form().
  *
- * Validate the 'add new field' row.
+ * @see field_ui_field_overview_form_validate()
  */
 function _field_ui_field_overview_form_validate_add_new($form, &$form_state) {
   $field = $form_state['values']['fields']['_add_new_field'];
@@ -702,9 +710,9 @@ function _field_ui_field_overview_form_validate_add_new($form, &$form_state) {
 }
 
 /**
- * Helper function for field_ui_field_overview_form_validate.
+ * Validates the 'add existing field' row of field_ui_field_overview_form().
  *
- * Validate the 'add existing field' row.
+ * @see field_ui_field_overview_form_validate()
  */
 function _field_ui_field_overview_form_validate_add_existing($form, &$form_state) {
   // The form element might be absent if no existing fields can be added to
@@ -740,7 +748,9 @@ function _field_ui_field_overview_form_validate_add_existing($form, &$form_state
 }
 
 /**
- * Submit handler for the field overview form.
+ * Form submission handler for field_ui_field_overview_form().
+ *
+ * @see field_ui_field_overview_form_validate()
  */
 function field_ui_field_overview_form_submit($form, &$form_state) {
   $form_values = $form_state['values']['fields'];
@@ -846,7 +856,11 @@ function field_ui_field_overview_form_submit($form, &$form_state) {
 }
 
 /**
- * Menu callback; presents field display settings for a given view mode.
+ * Form constructor for the field display settings for a given view mode.
+ *
+ * @see field_ui_display_overview_multistep_submit()
+ * @see field_ui_display_overview_form_submit()
+ * @ingroup forms
  */
 function field_ui_display_overview_form($form, &$form_state, $entity_type, $bundle, $view_mode) {
   $bundle = field_extract_bundle($entity_type, $bundle);
@@ -1198,7 +1212,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
 
 
 /**
- * Form submit handler for multistep buttons on the 'Manage display' screen.
+ * Form submission handler for buttons in field_ui_display_overview_form().
  */
 function field_ui_display_overview_multistep_submit($form, &$form_state) {
   $trigger = $form_state['triggering_element'];
@@ -1244,7 +1258,7 @@ function field_ui_display_overview_multistep_js($form, &$form_state) {
   $trigger = $form_state['triggering_element'];
   $op = $trigger['#op'];
 
-  // Pick the elements that need ro receive the ajax-new-content effect.
+  // Pick the elements that need to receive the ajax-new-content effect.
   switch ($op) {
     case 'edit':
       $updated_rows = array($trigger['#field_name']);
@@ -1276,7 +1290,7 @@ function field_ui_display_overview_multistep_js($form, &$form_state) {
 }
 
 /**
- * Submit handler for the display overview form.
+ * Form submission handler for field_ui_display_overview_form().
  */
 function field_ui_display_overview_form_submit($form, &$form_state) {
   $form_values = $form_state['values'];
@@ -1354,7 +1368,7 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
 }
 
 /**
- * Helper function for field_ui_display_overview_form_submit().
+ * Populates display settings for a new view mode from the default view mode.
  *
  * When an administrator decides to use custom display settings for a view mode,
  * that view mode needs to be initialized with the display settings for the
@@ -1363,8 +1377,6 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
  * them. It also modifies the passed-in $settings array, which the caller can
  * then save using field_bundle_settings().
  *
- * @see field_bundle_settings()
- *
  * @param $entity_type
  *   The bundle's entity type.
  * @param $bundle
@@ -1374,6 +1386,9 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
  * @param $settings
  *   An associative array of bundle settings, as expected by
  *   field_bundle_settings().
+ *
+ * @see field_ui_display_overview_form_submit().
+ * @see field_bundle_settings()
  */
 function _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode, &$settings) {
   // Update display settings for field instances.
@@ -1398,7 +1413,7 @@ function _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_m
 }
 
 /**
- * Return an array of field_type options.
+ * Returns an array of field_type options.
  */
 function field_ui_field_type_options() {
   $options = &drupal_static(__FUNCTION__);
@@ -1420,7 +1435,7 @@ function field_ui_field_type_options() {
 }
 
 /**
- * Return an array of widget type options for a field type.
+ * Returns an array of widget type options for a field type.
  *
  * If no field type is provided, returns a nested array of all widget types,
  * keyed by field type human name.
@@ -1456,7 +1471,7 @@ function field_ui_widget_type_options($field_type = NULL, $by_label = FALSE) {
 }
 
 /**
- * Return an array of formatter options for a field type.
+ * Returns an array of formatter options for a field type.
  *
  * If no field type is provided, returns a nested array of all formatters, keyed
  * by field type.
@@ -1484,7 +1499,7 @@ function field_ui_formatter_options($field_type = NULL) {
 }
 
 /**
- * Return an array of existing field to be added to a bundle.
+ * Returns an array of existing fields to be added to a bundle.
  */
 function field_ui_existing_field_options($entity_type, $bundle) {
   $options = array();
@@ -1522,7 +1537,10 @@ function field_ui_existing_field_options($entity_type, $bundle) {
 }
 
 /**
- * Menu callback; presents the field settings edit page.
+ * Form constructor for the field settings edit page.
+ *
+ * @see field_ui_settings_form_submit()
+ * @ingroups forms
  */
 function field_ui_field_settings_form($form, &$form_state, $instance) {
   $bundle = $instance['bundle'];
@@ -1576,7 +1594,7 @@ function field_ui_field_settings_form($form, &$form_state, $instance) {
 }
 
 /**
- * Save a field's settings after editing.
+ * Form submission handler for field_ui_field_settings_form().
  */
 function field_ui_field_settings_form_submit($form, &$form_state) {
   $form_values = $form_state['values'];
@@ -1603,7 +1621,15 @@ function field_ui_field_settings_form_submit($form, &$form_state) {
 }
 
 /**
- * Menu callback; select a widget for the field.
+ * Form constructor for the widget selection form.
+ *
+ * Path: BUNDLE_ADMIN_PATH/fields/%field/widget-type, where BUNDLE_ADMIN_PATH is
+ * the path stored in the ['admin']['info'] property in the return value of
+ * hook_entity_info().
+ *
+ * @see field_ui_menu()
+ * @see field_ui_widget_type_form_submit()
+ * @ingroup forms
  */
 function field_ui_widget_type_form($form, &$form_state, $instance) {
   drupal_set_title($instance['label']);
@@ -1647,7 +1673,7 @@ function field_ui_widget_type_form($form, &$form_state, $instance) {
 }
 
 /**
- * Submit the change in widget type.
+ * Form submission handler for field_ui_widget_type_form().
  */
 function field_ui_widget_type_form_submit($form, &$form_state) {
   $form_values = $form_state['values'];
@@ -1677,7 +1703,10 @@ function field_ui_widget_type_form_submit($form, &$form_state) {
 }
 
 /**
- * Menu callback; present a form for removing a field instance from a bundle.
+ * Form constructor for removing a field instance from a bundle.
+ *
+ * @see field_ui_delete_form_submit()
+ * @ingroup forms
  */
 function field_ui_field_delete_form($form, &$form_state, $instance) {
   $bundle = $instance['bundle'];
@@ -1707,9 +1736,10 @@ function field_ui_field_delete_form($form, &$form_state, $instance) {
 }
 
 /**
- * Removes a field instance from a bundle.
+ * Form submission handler for field_ui_field_delete_form().
  *
- * If the field has no more instances, it will be marked as deleted too.
+ * Removes a field instance from a bundle. If the field has no more instances,
+ * it will be marked as deleted too.
  */
 function field_ui_field_delete_form_submit($form, &$form_state) {
   $form_values = $form_state['values'];
@@ -1743,7 +1773,11 @@ function field_ui_field_delete_form_submit($form, &$form_state) {
 }
 
 /**
- * Menu callback; presents the field instance edit page.
+ * Form constructor for the field instance settings form.
+ *
+ * @see field_ui_field_edit_form_validate()
+ * @see field_ui_field_edit_form_submit()
+ * @ingroup forms
  */
 function field_ui_field_edit_form($form, &$form_state, $instance) {
   $bundle = $instance['bundle'];
@@ -1924,7 +1958,7 @@ function field_ui_field_edit_instance_pre_render($element) {
 }
 
 /**
- * Build default value fieldset.
+ * Builds the default value fieldset for a given field instance.
  */
 function field_ui_default_value_widget($field, $instance, &$form, &$form_state) {
   $field_name = $field['field_name'];
@@ -1947,13 +1981,15 @@ function field_ui_default_value_widget($field, $instance, &$form, &$form_state)
   $instance['description'] = '';
 
   // @todo Allow multiple values (requires more work on 'add more' JS handler).
-  $element += field_default_form(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $element, $form_state, 0);
+  $element += field_default_form($instance['entity_type'], NULL, $field, $instance, LANGUAGE_NONE, $items, $element, $form_state, 0);
 
   return $element;
 }
 
 /**
- * Form validation handler for field instance settings form.
+ * Form validation handler for field_ui_field_edit_form().
+ *
+ * @see field_ui_field_edit_form_submit().
  */
 function field_ui_field_edit_form_validate($form, &$form_state) {
   // Take the incoming values as the $instance definition, so that the 'default
@@ -1988,7 +2024,9 @@ function field_ui_field_edit_form_validate($form, &$form_state) {
 }
 
 /**
- * Form submit handler for field instance settings form.
+ * Form submission handler for field_ui_field_edit_form().
+ *
+ * @see field_ui_field_edit_form_validate().
  */
 function field_ui_field_edit_form_submit($form, &$form_state) {
   $instance = $form_state['values']['instance'];
@@ -2028,7 +2066,9 @@ function field_ui_field_edit_form_submit($form, &$form_state) {
 }
 
 /**
- * Helper functions to handle multipage redirects.
+ * Extracts next redirect path from an array of multiple destinations.
+ *
+ * @see field_ui_next_destination()
  */
 function field_ui_get_destinations($destinations) {
   $path = array_shift($destinations);
@@ -2040,7 +2080,7 @@ function field_ui_get_destinations($destinations) {
 }
 
 /**
- * Return the next redirect path in a multipage sequence.
+ * Returns the next redirect path in a multipage sequence.
  */
 function field_ui_next_destination($entity_type, $bundle) {
   $destinations = !empty($_REQUEST['destinations']) ? $_REQUEST['destinations'] : array();
diff --git a/modules/field_ui/field_ui.api.php b/modules/field_ui/field_ui.api.php
index 23401251..f903e12f 100644
--- a/modules/field_ui/field_ui.api.php
+++ b/modules/field_ui/field_ui.api.php
@@ -132,7 +132,7 @@ function hook_field_widget_settings_form($field, $instance) {
 
 
 /**
- * Returns form elements for a formatter's settings.
+ * Specify the form elements for a formatter's settings.
  *
  * @param $field
  *   The field structure being configured.
@@ -170,7 +170,7 @@ function hook_field_formatter_settings_form($field, $instance, $view_mode, $form
 }
 
 /**
- * Returns a short summary for the current formatter settings of an instance.
+ * Return a short summary for the current formatter settings of an instance.
  *
  * If an empty result is returned, the formatter is assumed to have no
  * configurable settings, and no UI will be provided to display a settings
diff --git a/modules/field_ui/field_ui.css b/modules/field_ui/field_ui.css
index c25d2a43..ae469e20 100644
--- a/modules/field_ui/field_ui.css
+++ b/modules/field_ui/field_ui.css
@@ -1,4 +1,8 @@
-
+/**
+ * @file
+ * Stylesheet for the Field UI module.
+ */
+ 
 /* 'Manage fields' and 'Manage display' overviews */
 table.field-ui-overview tr.add-new .label-input {
   float: left; /* LTR */
diff --git a/modules/field_ui/field_ui.info b/modules/field_ui/field_ui.info
index 3212c2ae..14165d36 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/field_ui/field_ui.js b/modules/field_ui/field_ui.js
index b63399f3..0a41c4c6 100644
--- a/modules/field_ui/field_ui.js
+++ b/modules/field_ui/field_ui.js
@@ -1,4 +1,8 @@
-
+/**
+ * @file
+ * Attaches the behaviors for the Field UI module.
+ */
+ 
 (function($) {
 
 Drupal.behaviors.fieldUIFieldOverview = {
@@ -118,7 +122,7 @@ Drupal.fieldUIOverview = {
         data.tableDrag = tableDrag;
 
         // Create the row handler, make it accessible from the DOM row element.
-        var rowHandler = eval('new rowHandlers.' + data.rowHandler + '(row, data);');
+        var rowHandler = new rowHandlers[data.rowHandler](row, data);
         $(row).data('fieldUIRowHandler', rowHandler);
       }
     });
diff --git a/modules/field_ui/field_ui.module b/modules/field_ui/field_ui.module
index 3be23c88..7bfb4faa 100644
--- a/modules/field_ui/field_ui.module
+++ b/modules/field_ui/field_ui.module
@@ -1,8 +1,7 @@
 <?php
-
 /**
  * @file
- * Allows administrators to associate custom fields to fieldable types.
+ * Allows administrators to attach custom fields to fieldable types.
  */
 
 /**
@@ -213,6 +212,11 @@ function field_ui_menu() {
  *   The position of $bundle_name in $map.
  * @param $map
  *   The translated menu router path argument map.
+ *
+ * @return
+ *   The field instance array.
+ *
+ * @ingroup field
  */
 function field_ui_menu_load($field_name, $entity_type, $bundle_name, $bundle_pos, $map) {
   // Extract the actual bundle name from the translated argument map.
@@ -261,7 +265,8 @@ function _field_ui_view_mode_menu_access($entity_type, $bundle, $view_mode, $acc
   // part of _menu_check_access().
   if ($visibility) {
     // Grab the variable 'access arguments' part.
-    $args = array_slice(func_get_args(), 4);
+    $all_args = func_get_args();
+    $args = array_slice($all_args, 4);
     $callback = empty($access_callback) ? 0 : trim($access_callback);
     if (is_numeric($callback)) {
       return (bool) $callback;
@@ -313,7 +318,7 @@ function field_ui_field_attach_create_bundle($entity_type, $bundle) {
 }
 
 /**
- * Helper function to create the right administration path for a bundle.
+ * Determines the adminstration path for a bundle.
  */
 function _field_ui_bundle_admin_path($entity_type, $bundle_name) {
   $bundles = field_info_bundles($entity_type);
@@ -324,7 +329,7 @@ function _field_ui_bundle_admin_path($entity_type, $bundle_name) {
 }
 
 /**
- * Helper function to identify inactive fields within a bundle.
+ * Identifies inactive fields within a bundle.
  */
 function field_ui_inactive_instances($entity_type, $bundle_name = NULL) {
   if (!empty($bundle_name)) {
@@ -351,7 +356,12 @@ function field_ui_inactive_instances($entity_type, $bundle_name = NULL) {
 }
 
 /**
- * Add a button Save and add fields to Create content type form.
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Adds a button 'Save and add fields' to the 'Create content type' form.
+ *
+ * @see node_type_form()
+ * @see field_ui_form_node_type_form_submit()
  */
 function field_ui_form_node_type_form_alter(&$form, $form_state) {
   // We want to display the button only on add page.
@@ -366,7 +376,9 @@ function field_ui_form_node_type_form_alter(&$form, $form_state) {
 }
 
 /**
- * Redirect to manage fields form.
+ * Form submission handler for the 'Save and add fields' button.
+ *
+ * @see field_ui_form_node_type_form_alter()
  */
 function field_ui_form_node_type_form_submit($form, &$form_state) {
   if ($form_state['triggering_element']['#parents'][0] === 'save_continue') {
diff --git a/modules/field_ui/field_ui.test b/modules/field_ui/field_ui.test
index e7c5e18e..f1e770ba 100644
--- a/modules/field_ui/field_ui.test
+++ b/modules/field_ui/field_ui.test
@@ -6,7 +6,7 @@
  */
 
 /**
- * Helper class for Field UI test classes.
+ * Provides common functionality for the Field UI test classes.
  */
 class FieldUITestCase extends DrupalWebTestCase {
 
@@ -34,10 +34,10 @@ class FieldUITestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Create a new field through the Field UI.
+   * Creates a new field through the Field UI.
    *
    * @param $bundle_path
-   *   Path of the 'Manage fields' page for the bundle.
+   *   Admin path of the bundle that the new field is to be attached to.
    * @param $initial_edit
    *   $edit parameter for drupalPost() on the first step ('Manage fields'
    *   screen).
@@ -74,10 +74,10 @@ class FieldUITestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Add an existing field through the Field UI.
+   * Adds an existing field through the Field UI.
    *
    * @param $bundle_path
-   *   Path of the 'Manage fields' page for the bundle.
+   *   Admin path of the bundle that the field is to be attached to.
    * @param $initial_edit
    *   $edit parameter for drupalPost() on the first step ('Manage fields'
    *   screen).
@@ -105,10 +105,10 @@ class FieldUITestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Delete a field instance through the Field UI.
+   * Deletes a field instance through the Field UI.
    *
    * @param $bundle_path
-   *   Path of the 'Manage fields' page for the bundle.
+   *   Admin path of the bundle that the field instance is to be deleted from.
    * @param $field_name
    *   The name of the field.
    * @param $label
@@ -131,7 +131,7 @@ class FieldUITestCase extends DrupalWebTestCase {
 }
 
 /**
- * Field UI tests for the 'Manage fields' screen.
+ * Tests the functionality of the 'Manage fields' screen.
  */
 class FieldUIManageFieldsTestCase extends FieldUITestCase {
   public static function getInfo() {
@@ -152,7 +152,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Main entry point for the field CRUD tests.
+   * Runs the field CRUD tests.
    *
    * In order to act on the same fields, and not create the fields over and over
    * again the following tests create, update and delete the same fields.
@@ -165,7 +165,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test the manage fields page.
+   * Tests the manage fields page.
    */
   function manageFieldsPage() {
     $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields');
@@ -190,7 +190,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test adding a new field.
+   * Tests adding a new field.
    *
    * @todo Assert properties can bet set in the form and read back in $field and
    * $instances.
@@ -212,7 +212,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test editing an existing field.
+   * Tests editing an existing field.
    */
   function updateField() {
     // Go to the field edit page.
@@ -235,7 +235,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test adding an existing field in another content type.
+   * Tests adding an existing field in another content type.
    */
   function addExistingField() {
     // Check "Add existing field" appears.
@@ -256,7 +256,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Assert the field settings.
+   * Asserts field settings are as expected.
    *
    * @param $bundle
    *   The bundle name for the instance.
@@ -378,7 +378,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test that Field UI respects the 'no_ui' option in hook_field_info().
+   * Tests that Field UI respects the 'no_ui' option in hook_field_info().
    */
   function testHiddenFields() {
     $bundle_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/';
@@ -429,7 +429,7 @@ class FieldUIManageFieldsTestCase extends FieldUITestCase {
 }
 
 /**
- * Field UI tests for the 'Manage display' screens.
+ * Tests the functionality of the 'Manage display' screens.
  */
 class FieldUIManageDisplayTestCase extends FieldUITestCase {
   public static function getInfo() {
@@ -445,7 +445,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test formatter formatter settings.
+   * Tests formatter settings.
    */
   function testFormatterUI() {
     $manage_fields = 'admin/structure/types/manage/' . $this->hyphen_type;
@@ -493,7 +493,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
   }
 
   /**
-   * Test switching view modes to use custom or 'default' settings'.
+   * Tests switching view modes to use custom or 'default' settings'.
    */
   function testViewModeCustom() {
     // Create a field, and a node with some data for the field.
@@ -565,7 +565,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
   }
 
   /**
-   * Pass if the text is found in the rendered node in a given view mode.
+   * Asserts that a string is found in the rendered node in a view mode.
    *
    * @param $node
    *   The node.
@@ -584,7 +584,7 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
   }
 
   /**
-   * Pass if the text is node found in the rendered node in a given view mode.
+   * Asserts that a string is not found in the rendered node in a view mode.
    *
    * @param $node
    *   The node.
@@ -602,7 +602,10 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
   }
 
   /**
-   * Helper for assertNodeViewText and assertNodeViewNoText.
+   * Asserts that a string is (not) found in the rendered nodein a view mode.
+   *
+   * This helper function is used by assertNodeViewText() and
+   * assertNodeViewNoText().
    *
    * @param $node
    *   The node.
@@ -643,3 +646,87 @@ class FieldUIManageDisplayTestCase extends FieldUITestCase {
     return $return;
   }
 }
+
+/**
+ * Tests custom widget hooks and callbacks on the field administration pages.
+ */
+class FieldUIAlterTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Widget customization',
+      'description' => 'Test custom field widget hooks and callbacks on field administration pages.',
+      'group' => 'Field UI',
+    );
+  }
+
+  function setUp() {
+    parent::setUp(array('field_test'));
+
+    // Create test user.
+    $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer users'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Tests hook_field_widget_properties_alter() on the default field widget.
+   *
+   * @see field_test_field_widget_properties_alter()
+   * @see field_test_field_widget_properties_user_alter()
+   * @see field_test_field_widget_form_alter()
+   */
+  function testDefaultWidgetPropertiesAlter() {
+    // Create the alter_test_text field and an instance on article nodes.
+    field_create_field(array(
+      'field_name' => 'alter_test_text',
+      'type' => 'text',
+    ));
+    field_create_instance(array(
+      'field_name' => 'alter_test_text',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'widget' => array(
+        'type' => 'text_textfield',
+        'size' => 60,
+      ),
+    ));
+
+    // Test that field_test_field_widget_properties_alter() sets the size to
+    // 42 and that field_test_field_widget_form_alter() reports the correct
+    // size when the form is displayed.
+    $this->drupalGet('admin/structure/types/manage/article/fields/alter_test_text');
+    $this->assertText('Field size: 42', 'Altered field size is found in hook_field_widget_form_alter().');
+
+    // Create the alter_test_options field.
+    field_create_field(array(
+      'field_name' => 'alter_test_options',
+      'type' => 'list_text'
+    ));
+    // Create instances on users and page nodes.
+    field_create_instance(array(
+      'field_name' => 'alter_test_options',
+      'entity_type' => 'user',
+      'bundle' => 'user',
+      'widget' => array(
+        'type' => 'options_select',
+      )
+    ));
+    field_create_instance(array(
+      'field_name' => 'alter_test_options',
+      'entity_type' => 'node',
+      'bundle' => 'page',
+      'widget' => array(
+        'type' => 'options_select',
+      )
+    ));
+
+    // Test that field_test_field_widget_properties_user_alter() replaces
+    // the widget and that field_test_field_widget_form_alter() reports the
+    // correct widget name when the form is displayed.
+    $this->drupalGet('admin/config/people/accounts/fields/alter_test_options');
+    $this->assertText('Widget type: options_buttons', 'Widget type is altered for users in hook_field_widget_form_alter().');
+
+    // Test that the widget is not altered on page nodes.
+    $this->drupalGet('admin/structure/types/manage/page/fields/alter_test_options');
+    $this->assertText('Widget type: options_select', 'Widget type is not altered for pages in hook_field_widget_form_alter().');
+  }
+}
diff --git a/modules/file/file.api.php b/modules/file/file.api.php
index 76fb9861..72aae40c 100644
--- a/modules/file/file.api.php
+++ b/modules/file/file.api.php
@@ -12,8 +12,8 @@
  * file is referenced, e.g., only users with access to a node should be allowed
  * to download files attached to that node.
  *
- * @param $field
- *   The field to which the file belongs.
+ * @param array $file_item
+ *   The array of information about the file to check access for.
  * @param $entity_type
  *   The type of $entity; for example, 'node' or 'user'.
  * @param $entity
@@ -26,7 +26,7 @@
  *
  * @see hook_field_access().
  */
-function hook_file_download_access($field, $entity_type, $entity) {
+function hook_file_download_access($file_item, $entity_type, $entity) {
   if ($entity_type == 'node') {
     return node_access('view', $entity);
   }
@@ -45,8 +45,8 @@ function hook_file_download_access($field, $entity_type, $entity) {
  *   An array of grants gathered by hook_file_download_access(). The array is
  *   keyed by the module that defines the entity type's access control; the
  *   values are Boolean grant responses for each module.
- * @param $field
- *   The field to which the file belongs.
+ * @param array $file_item
+ *   The array of information about the file to alter access for.
  * @param $entity_type
  *   The type of $entity; for example, 'node' or 'user'.
  * @param $entity
@@ -55,10 +55,10 @@ function hook_file_download_access($field, $entity_type, $entity) {
  * @return
  *   An array of grants, keyed by module name, each with a Boolean grant value.
  *   Return an empty array to assert FALSE. You may choose to return your own
- *   module's value in addition to other grants or to overwrite the values set by
- *   other modules.
+ *   module's value in addition to other grants or to overwrite the values set
+ *   by other modules.
  */
-function hook_file_download_access_alter(&$grants, $field, $entity_type, $entity) {
+function hook_file_download_access_alter(&$grants, $file_item, $entity_type, $entity) {
   // For our example module, we always enforce the rules set by node module.
   if (isset($grants['node'])) {
     $grants = array('node' => $grants['node']);
diff --git a/modules/file/file.css b/modules/file/file.css
index 40451b8c..bd4a0597 100644
--- a/modules/file/file.css
+++ b/modules/file/file.css
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Admin stylesheet for file module.
+ */
 
 /**
  * Managed file element styles.
diff --git a/modules/file/file.field.inc b/modules/file/file.field.inc
index 7f5906ec..7a5697cc 100644
--- a/modules/file/file.field.inc
+++ b/modules/file/file.field.inc
@@ -312,7 +312,7 @@ function file_field_delete_revision($entity_type, $entity, $field, $instance, $l
 }
 
 /**
- * Decrements a file usage count and attempts to delete it.
+ * Decrements the usage count for a file and attempts to delete it.
  *
  * This function only has an effect if the file being deleted is used only by
  * File module.
@@ -358,12 +358,13 @@ function file_field_is_empty($item, $field) {
 }
 
 /**
- * Determine whether a file should be displayed when outputting field content.
+ * Determines whether a file should be displayed when outputting field content.
  *
  * @param $item
  *   A field item array.
  * @param $field
  *   A field array.
+ *
  * @return
  *   Boolean TRUE if the file will be displayed, FALSE if the file is hidden.
  */
@@ -516,10 +517,11 @@ function file_field_widget_form(&$form, &$form_state, $field, $instance, $langco
 }
 
 /**
- * Get the upload validators for a file field.
+ * Retrieves the upload validators for a file field.
  *
  * @param $field
  *   A field array.
+ *
  * @return
  *   An array suitable for passing to file_save_upload() or the file field
  *   element's '#upload_validators' property.
@@ -545,7 +547,7 @@ function file_field_widget_upload_validators($field, $instance) {
 }
 
 /**
- * Determine the URI for a file field instance.
+ * Determines the URI for a file field instance.
  *
  * @param $field
  *   A field array.
@@ -553,6 +555,7 @@ function file_field_widget_upload_validators($field, $instance) {
  *   A field instance array.
  * @param $data
  *   An array of token objects to pass to token_replace().
+ *
  * @return
  *   A file directory URI with tokens replaced.
  *
@@ -704,10 +707,13 @@ function file_field_widget_process_multiple($element, &$form_state, $form) {
 }
 
 /**
- * Helper function for file_field_widget_process_multiple().
+ * Retrieves the file description from a field field element.
+ *
+ * This helper function is used by file_field_widget_process_multiple().
  *
  * @param $element
  *   The element being processed.
+ *
  * @return
  *   A description of the file suitable for use in the administrative interface.
  */
@@ -725,7 +731,7 @@ function _file_field_get_description_from_element($element) {
 }
 
 /**
- * Submit handler for upload and remove buttons of file_generic fields.
+ * Form submission handler for upload/remove button of file_field_widget_form().
  *
  * This runs in addition to and after file_managed_file_submit().
  *
@@ -970,11 +976,13 @@ function file_field_formatter_view($entity_type, $entity, $field, $instance, $la
       break;
 
     case 'file_table':
-      // Display all values in a single element..
-      $element[0] = array(
-        '#theme' => 'file_formatter_table',
-        '#items' => $items,
-      );
+      if (!empty($items)) {
+        // Display all values in a single element..
+        $element[0] = array(
+          '#theme' => 'file_formatter_table',
+          '#items' => $items,
+        );
+      }
       break;
   }
 
diff --git a/modules/file/file.info b/modules/file/file.info
index 12cb795d..5fd07dd9 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/file/file.module b/modules/file/file.module
index f979a69f..506b0e91 100644
--- a/modules/file/file.module
+++ b/modules/file/file.module
@@ -56,7 +56,7 @@ function file_menu() {
 /**
  * Implements hook_element_info().
  *
- * The managed file element may be used independently anywhere in Drupal.
+ * The managed file element may be used anywhere in Drupal.
  */
 function file_element_info() {
   $file_path = drupal_get_path('module', 'file');
@@ -164,24 +164,27 @@ function file_file_download($uri, $field_type = 'file') {
         // Try to load $entity and $field.
         $entity = entity_load($entity_type, array($id));
         $entity = reset($entity);
-        $field = NULL;
+        $field = field_info_field($field_name);
+
+        // Load the field item that references the file.
+        $field_item = NULL;
         if ($entity) {
-          // Load all fields for that entity.
+          // Load all field items for that entity.
           $field_items = field_get_items($entity_type, $entity, $field_name);
 
           // Find the field item with the matching URI.
-          foreach ($field_items as $field_item) {
-            if ($field_item['uri'] == $uri) {
-              $field = $field_item;
+          foreach ($field_items as $item) {
+            if ($item['uri'] == $uri) {
+              $field_item = $item;
               break;
             }
           }
         }
 
-        // Check that $entity and $field were loaded successfully and check if
-        // access to that field is not disallowed. If any of these checks fail,
-        // stop checking access for this reference.
-        if (empty($entity) || empty($field) || !field_access('view', $field, $entity_type, $entity)) {
+        // Check that $entity, $field and $field_item were loaded successfully
+        // and check if access to that field is not disallowed. If any of these
+        // checks fail, stop checking access for this reference.
+        if (empty($entity) || empty($field) || empty($field_item) || !field_access('view', $field, $entity_type, $entity)) {
           $denied = TRUE;
           break;
         }
@@ -190,10 +193,10 @@ function file_file_download($uri, $field_type = 'file') {
         // Default to FALSE and let entities overrule this ruling.
         $grants = array('system' => FALSE);
         foreach (module_implements('file_download_access') as $module) {
-          $grants = array_merge($grants, array($module => module_invoke($module, 'file_download_access', $field, $entity_type, $entity)));
+          $grants = array_merge($grants, array($module => module_invoke($module, 'file_download_access', $field_item, $entity_type, $entity)));
         }
         // Allow other modules to alter the returned grants/denies.
-        drupal_alter('file_download_access', $grants, $field, $entity_type, $entity);
+        drupal_alter('file_download_access', $grants, $field_item, $entity_type, $entity);
 
         if (in_array(TRUE, $grants)) {
           // If TRUE is returned, access is granted and no further checks are
@@ -317,7 +320,7 @@ function file_ajax_progress($key) {
 }
 
 /**
- * Determine the preferred upload progress implementation.
+ * Determines the preferred upload progress implementation.
  *
  * @return
  *   A string indicating which upload progress system is available. Either "apc"
@@ -570,7 +573,9 @@ function file_managed_file_validate(&$element, &$form_state) {
 }
 
 /**
- * Submit handler for upload and remove buttons of managed_file elements.
+ * Form submission handler for upload / remove buttons of managed_file elements.
+ *
+ * @see file_managed_file_process()
  */
 function file_managed_file_submit($form, &$form_state) {
   // Determine whether it was the upload or the remove button that was clicked,
@@ -611,10 +616,11 @@ function file_managed_file_submit($form, &$form_state) {
 }
 
 /**
- * Given a managed_file element, save any files that have been uploaded into it.
+ * Saves any files that have been uploaded into a managed_file element.
  *
  * @param $element
  *   The FAPI element whose values are being saved.
+ *
  * @return
  *   The file object representing the file that was saved, or FALSE if no file
  *   was saved.
@@ -761,13 +767,14 @@ function theme_file_icon($variables) {
 }
 
 /**
- * Given a file object, create a URL to a matching icon.
+ * Creates a URL to the icon for a file object.
  *
  * @param $file
  *   A file object.
  * @param $icon_directory
  *   (optional) A path to a directory of icons to be used for files. Defaults to
  *   the value of the "file_icon_directory" variable.
+ *
  * @return
  *   A URL string to the icon, or FALSE if an appropriate icon cannot be found.
  */
@@ -779,13 +786,14 @@ function file_icon_url($file, $icon_directory = NULL) {
 }
 
 /**
- * Given a file object, create a path to a matching icon.
+ * Creates a path to the icon for a file object.
  *
  * @param $file
  *   A file object.
  * @param $icon_directory
  *   (optional) A path to a directory of icons to be used for files. Defaults to
  *   the value of the "file_icon_directory" variable.
+ *
  * @return
  *   A string to the icon as a local path, or FALSE if an appropriate icon could
  *   not be found.
@@ -831,10 +839,11 @@ function file_icon_path($file, $icon_directory = NULL) {
 }
 
 /**
- * Determine the generic icon MIME package based on a file's MIME type.
+ * Determines the generic icon MIME package based on a file's MIME type.
  *
  * @param $file
  *   A file object.
+ *
  * @return
  *   The generic icon MIME package expected for this file.
  */
@@ -962,7 +971,7 @@ function file_icon_map($file) {
  */
 
 /**
- * Gets a list of references to a file.
+ * Retrieves a list of references to a file.
  *
  * @param $file
  *   A file object.
diff --git a/modules/file/tests/file.test b/modules/file/tests/file.test
index 59f6e0cb..1b5fdf5c 100644
--- a/modules/file/tests/file.test
+++ b/modules/file/tests/file.test
@@ -6,7 +6,7 @@
  */
 
 /**
- * This class provides methods specifically for testing File's field handling.
+ * Provides methods specifically for testing File module's field handling.
  */
 class FileFieldTestCase extends DrupalWebTestCase {
   protected $admin_user;
@@ -27,7 +27,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Get a sample file of the specified type.
+   * Retrieves a sample file of the specified type.
    */
   function getTestFile($type_name, $size = NULL) {
     // Get a file to upload.
@@ -40,14 +40,14 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Get the fid of the last inserted file.
+   * Retrieves the fid of the last inserted file.
    */
   function getLastFileId() {
     return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField();
   }
 
   /**
-   * Create a new file field.
+   * Creates a new file field.
    *
    * @param $name
    *   The name of the new field (all lowercase), exclude the "field_" prefix.
@@ -74,7 +74,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Attach a file field to an entity.
+   * Attaches a file field to an entity.
    *
    * @param $name
    *   The name of the new field (all lowercase), exclude the "field_" prefix.
@@ -108,7 +108,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Update an existing file field with new settings.
+   * Updates an existing file field with new settings.
    */
   function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) {
     $instance = field_info_instance('node', $name, $type_name);
@@ -119,7 +119,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Upload a file to a node.
+   * Uploads a file to a node.
    */
   function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE, $extras = array()) {
     $langcode = LANGUAGE_NONE;
@@ -150,7 +150,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Remove a file from a node.
+   * Removes a file from a node.
    *
    * Note that if replacing a file, it must first be removed then added again.
    */
@@ -164,7 +164,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Replace a file within a node.
+   * Replaces a file within a node.
    */
   function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE) {
     $edit = array(
@@ -177,7 +177,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Assert that a file exists physically on disk.
+   * Asserts that a file exists physically on disk.
    */
   function assertFileExists($file, $message = NULL) {
     $message = isset($message) ? $message : t('File %file exists on the disk.', array('%file' => $file->uri));
@@ -185,7 +185,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Assert that a file exists in the database.
+   * Asserts that a file exists in the database.
    */
   function assertFileEntryExists($file, $message = NULL) {
     entity_get_controller('file')->resetCache();
@@ -195,7 +195,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Assert that a file does not exist on disk.
+   * Asserts that a file does not exist on disk.
    */
   function assertFileNotExists($file, $message = NULL) {
     $message = isset($message) ? $message : t('File %file exists on the disk.', array('%file' => $file->uri));
@@ -203,7 +203,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Assert that a file does not exist in the database.
+   * Asserts that a file does not exist in the database.
    */
   function assertFileEntryNotExists($file, $message) {
     entity_get_controller('file')->resetCache();
@@ -212,7 +212,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Assert that a file's status is set to permanent in the database.
+   * Asserts that a file's status is set to permanent in the database.
    */
   function assertFileIsPermanent($file, $message = NULL) {
     $message = isset($message) ? $message : t('File %file is permanent.', array('%file' => $file->uri));
@@ -221,7 +221,7 @@ class FileFieldTestCase extends DrupalWebTestCase {
 }
 
 /**
- * Test class for testing the 'managed_file' element type on its own, not as part of a file field.
+ * Tests the 'managed_file' element type.
  *
  * @todo Create a FileTestCase base class and move FileFieldTestCase methods
  *   that aren't related to fields into it.
@@ -311,7 +311,7 @@ class FileManagedFileElementTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test class to test file field widget, single and multi-valued, with and without Ajax, with public and private files.
+ * Tests file field widget.
  */
 class FileFieldWidgetTestCase extends FileFieldTestCase {
   public static function getInfo() {
@@ -323,7 +323,7 @@ class FileFieldWidgetTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Tests upload and remove buttons, with and without Ajax, for a single-valued File field.
+   * Tests upload and remove buttons for a single-valued File field.
    */
   function testSingleValuedWidget() {
     // Use 'page' instead of 'article', so that the 'article' image field does
@@ -380,7 +380,7 @@ class FileFieldWidgetTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Tests upload and remove buttons, with and without Ajax, for multiple multi-valued File field.
+   * Tests upload and remove buttons for multiple multi-valued File fields.
    */
   function testMultiValuedWidget() {
     // Use 'page' instead of 'article', so that the 'article' image field does
@@ -616,7 +616,7 @@ class FileFieldWidgetTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test class to test file handling with node revisions.
+ * Tests file handling with node revisions.
  */
 class FileFieldRevisionTestCase extends FileFieldTestCase {
   public static function getInfo() {
@@ -628,7 +628,7 @@ class FileFieldRevisionTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Test creating multiple revisions of a node and managing the attached files.
+   * Tests creating multiple revisions of a node and managing attached files.
    *
    * Expected behaviors:
    *  - Adding a new revision will make another entry in the field table, but
@@ -731,7 +731,7 @@ class FileFieldRevisionTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test class to check that formatters are working properly.
+ * Tests that formatters are working properly.
  */
 class FileFieldDisplayTestCase extends FileFieldTestCase {
   public static function getInfo() {
@@ -743,7 +743,7 @@ class FileFieldDisplayTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Test normal formatter display on node display.
+   * Tests normal formatter display on node display.
    */
   function testNodeDisplay() {
     $field_name = strtolower($this->randomName());
@@ -760,6 +760,19 @@ class FileFieldDisplayTestCase extends FileFieldTestCase {
     $field = field_info_field($field_name);
     $instance = field_info_instance('node', $field_name, $type_name);
 
+    // Create a new node *without* the file field set, and check that the field
+    // is not shown for each node display.
+    $node = $this->drupalCreateNode(array('type' => $type_name));
+    $file_formatters = array('file_default', 'file_table', 'file_url_plain', 'hidden');
+    foreach ($file_formatters as $formatter) {
+      $edit = array(
+        "fields[$field_name][type]" => $formatter,
+      );
+      $this->drupalPost("admin/structure/types/manage/$type_name/display", $edit, t('Save'));
+      $this->drupalGet('node/' . $node->nid);
+      $this->assertNoText($field_name, t('Field label is hidden when no file attached for formatter %formatter', array('%formatter' => $formatter)));
+    }
+
     $test_file = $this->getTestFile('text');
 
     // Create a new node with the uploaded file.
@@ -782,7 +795,7 @@ class FileFieldDisplayTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test class to check for various validations.
+ * Tests various validations.
  */
 class FileFieldValidateTestCase extends FileFieldTestCase {
   protected $field;
@@ -797,7 +810,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Test required property on file fields.
+   * Tests the required property on file fields.
    */
   function testRequired() {
     $type_name = 'article';
@@ -845,7 +858,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Test the max file size validator.
+   * Tests the max file size validator.
    */
   function testFileMaxSize() {
     $type_name = 'article';
@@ -897,7 +910,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Test the file extension, do additional checks if mimedetect is installed.
+   * Tests file extension checking.
    */
   function testFileExtension() {
     $type_name = 'article';
@@ -943,7 +956,7 @@ class FileFieldValidateTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test class to check that files are uploaded to proper locations.
+ * Tests that files are uploaded to proper locations.
  */
 class FileFieldPathTestCase extends FileFieldTestCase {
   public static function getInfo() {
@@ -955,7 +968,7 @@ class FileFieldPathTestCase extends FileFieldTestCase {
   }
 
   /**
-   * Test normal formatter display on node display.
+   * Tests the normal formatter display on node display.
    */
   function testUploadPath() {
     $field_name = strtolower($this->randomName());
@@ -1000,7 +1013,7 @@ class FileFieldPathTestCase extends FileFieldTestCase {
   }
 
   /**
-   * A loose assertion to check that a file is uploaded to the right location.
+   * Asserts that a file is uploaded to the right location.
    *
    * @param $expected_path
    *   The location where the file is expected to be uploaded. Duplicate file
@@ -1023,7 +1036,7 @@ class FileFieldPathTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test file token replacement in strings.
+ * Tests the file token replacement in strings.
  */
 class FileTokenReplaceTestCase extends FileFieldTestCase {
   public static function getInfo() {
@@ -1052,6 +1065,9 @@ class FileTokenReplaceTestCase extends FileFieldTestCase {
     $instance = field_info_instance('node', $field_name, $type_name);
 
     $test_file = $this->getTestFile('text');
+    // Coping a file to test uploads with non-latin filenames.
+    $filename = drupal_dirname($test_file->uri) . '/текстовый файл.txt';
+    $test_file = file_copy($test_file, $filename);
 
     // Create a new node with the uploaded file.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
@@ -1095,7 +1111,7 @@ class FileTokenReplaceTestCase extends FileFieldTestCase {
 }
 
 /**
- * Test class to test file access on private nodes.
+ * Tests file access on private nodes.
  */
 class FilePrivateTestCase extends FileFieldTestCase {
   public static function getInfo() {
@@ -1107,13 +1123,13 @@ class FilePrivateTestCase extends FileFieldTestCase {
   }
 
   function setUp() {
-    parent::setUp('node_access_test');
+    parent::setUp(array('node_access_test', 'field_test'));
     node_access_rebuild();
     variable_set('node_access_test_private', TRUE);
   }
 
   /**
-   * Uploads a file to a private node, then tests that access is allowed and denied when appropriate.
+   * Tests file access for file uploaded to a private node.
    */
   function testPrivateFile() {
     // Use 'page' instead of 'article', so that the 'article' image field does
@@ -1124,6 +1140,10 @@ class FilePrivateTestCase extends FileFieldTestCase {
     $field_name = strtolower($this->randomName());
     $this->createFileField($field_name, $type_name, array('uri_scheme' => 'private'));
 
+    // Create a field with no view access - see field_test_field_access().
+    $no_access_field_name = 'field_no_view_access';
+    $this->createFileField($no_access_field_name, $type_name, array('uri_scheme' => 'private'));
+
     $test_file = $this->getTestFile('text');
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => TRUE));
     $node = node_load($nid, NULL, TRUE);
@@ -1134,5 +1154,14 @@ class FilePrivateTestCase extends FileFieldTestCase {
     $this->drupalLogOut();
     $this->drupalGet(file_create_url($node_file->uri));
     $this->assertResponse(403, t('Confirmed that access is denied for the file without the needed permission.'));
+
+    // Test with the field that should deny access through field access.
+    $this->drupalLogin($this->admin_user);
+    $nid = $this->uploadNodeFile($test_file, $no_access_field_name, $type_name, TRUE, array('private' => TRUE));
+    $node = node_load($nid, NULL, TRUE);
+    $node_file = (object) $node->{$no_access_field_name}[LANGUAGE_NONE][0];
+    // Ensure the file cannot be downloaded.
+    $this->drupalGet(file_create_url($node_file->uri));
+    $this->assertResponse(403, t('Confirmed that access is denied for the file without view field access permission.'));
   }
 }
diff --git a/modules/file/tests/file_module_test.info b/modules/file/tests/file_module_test.info
index cf503767..5314f21a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/file/tests/file_module_test.module b/modules/file/tests/file_module_test.module
index ea65981c..358c8b01 100644
--- a/modules/file/tests/file_module_test.module
+++ b/modules/file/tests/file_module_test.module
@@ -22,7 +22,10 @@ function file_module_test_menu() {
 }
 
 /**
- * Form builder for testing a 'managed_file' element.
+ * Form constructor for testing a 'managed_file' element.
+ *
+ * @see file_module_test_form_submit()
+ * @ingroup forms
  */
 function file_module_test_form($form, &$form_state, $tree = TRUE, $extended = FALSE, $default_fid = NULL) {
   $form['#tree'] = (bool) $tree;
diff --git a/modules/filter/filter.info b/modules/filter/filter.info
index 3b5d9e58..3621a7a4 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/forum/forum.info b/modules/forum/forum.info
index 9ebb3283..6b266799 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/help/help.admin.inc b/modules/help/help.admin.inc
index 3db06ca1..ec1a18e3 100644
--- a/modules/help/help.admin.inc
+++ b/modules/help/help.admin.inc
@@ -17,6 +17,9 @@ function help_main() {
 
 /**
  * Menu callback; prints a page listing general help for a module.
+ *
+ * @param $name
+ *   A module name to display a help page for.
  */
 function help_page($name) {
   $output = '';
@@ -46,6 +49,12 @@ function help_page($name) {
   return $output;
 }
 
+/**
+ * Provides a formatted list of available help topics.
+ *
+ * @return
+ *   A string containing the formatted list.
+ */
 function help_links_as_list() {
   $empty_arg = drupal_help_arg();
   $module_info = system_rebuild_module_data();
@@ -58,7 +67,7 @@ function help_links_as_list() {
   }
   asort($modules);
 
-  // Output pretty four-column list
+  // Output pretty four-column list.
   $count = count($modules);
   $break = ceil($count / 4);
   $output = '<div class="clearfix"><div class="help-items"><ul>';
diff --git a/modules/help/help.api.php b/modules/help/help.api.php
index ff2f97c6..f7d9c08b 100644
--- a/modules/help/help.api.php
+++ b/modules/help/help.api.php
@@ -42,6 +42,7 @@
  *   the current page's help. Note that depending on which module is invoking
  *   hook_help, $arg may contain only empty strings. Regardless, $arg[0] to
  *   $arg[11] will always be set.
+ *
  * @return
  *   A localized string containing the help text.
  */
diff --git a/modules/help/help.info b/modules/help/help.info
index 2460f0a9..93fcdc27 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/help/help.test b/modules/help/help.test
index 73b4dedc..e72aa4a0 100644
--- a/modules/help/help.test
+++ b/modules/help/help.test
@@ -5,8 +5,18 @@
  * Tests for help.module.
  */
 
+/**
+ * Tests help display and user access for all modules implementing help.
+ */
 class HelpTestCase extends DrupalWebTestCase {
+  /**
+   * The admin user that will be created.
+   */
   protected $big_user;
+
+  /**
+   * The anonymous user that will be created.
+   */
   protected $any_user;
 
   public static function getInfo() {
@@ -17,9 +27,6 @@ class HelpTestCase extends DrupalWebTestCase {
     );
   }
 
-  /**
-   * Enable modules and create users with specific permissions.
-   */
   function setUp() {
     parent::setUp('blog', 'poll');
 
@@ -31,7 +38,7 @@ class HelpTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Login users, create dblog events, and test dblog functionality through the admin and user interfaces.
+   * Logs in users, creates dblog events, and tests dblog functionality.
    */
   function testHelp() {
     // Login the admin user.
@@ -60,9 +67,10 @@ class HelpTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Verify the logged in user has the desired access to the various help nodes and the nodes display help.
+   * Verifies the logged in user has access to the various help nodes.
    *
-   * @param integer $response HTTP response code.
+   * @param integer $response
+   *   An HTTP response code.
    */
   protected function verifyHelp($response = 200) {
     foreach ($this->modules as $module => $name) {
@@ -77,9 +85,10 @@ class HelpTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Get list of enabled modules that implement hook_help().
+   * Gets the list of enabled modules that implement hook_help().
    *
-   * @return array Enabled modules.
+   * @return array
+   *   A list of enabled modules.
    */
   protected function getModuleList() {
     $this->modules = array();
@@ -94,9 +103,12 @@ class HelpTestCase extends DrupalWebTestCase {
 }
 
 /**
- * Tests module without help to verify it is not listed in help page.
+ * Tests a module without help to verify it is not listed in the help page.
  */
 class NoHelpTestCase extends DrupalWebTestCase {
+  /**
+   * The user who will be created.
+   */
   protected $big_user;
 
   public static function getInfo() {
@@ -114,7 +126,7 @@ class NoHelpTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Ensure modules not implementing help do not appear on admin/help.
+   * Ensures modules not implementing help do not appear on admin/help.
    */
   function testMainPageNoHelp() {
     $this->drupalLogin($this->big_user);
diff --git a/modules/image/image.effects.inc b/modules/image/image.effects.inc
index ea898f91..35a6a74c 100644
--- a/modules/image/image.effects.inc
+++ b/modules/image/image.effects.inc
@@ -124,13 +124,11 @@ function image_resize_dimensions(array &$dimensions, array $data) {
 function image_scale_effect(&$image, $data) {
   // Set sane default values.
   $data += array(
+    'width' => NULL,
+    'height' => NULL,
     'upscale' => FALSE,
   );
 
-  // Set impossibly large values if the width and height aren't set.
-  $data['width'] = empty($data['width']) ? PHP_INT_MAX : $data['width'];
-  $data['height'] = empty($data['height']) ? PHP_INT_MAX : $data['height'];
-
   if (!image_scale($image, $data['width'], $data['height'], $data['upscale'])) {
     watchdog('image', 'Image scale failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit, '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
     return FALSE;
diff --git a/modules/image/image.field.inc b/modules/image/image.field.inc
index d08fd5c9..61a72e4c 100644
--- a/modules/image/image.field.inc
+++ b/modules/image/image.field.inc
@@ -403,7 +403,8 @@ function image_field_widget_process($element, &$form_state, $form) {
     '#type' => 'textfield',
     '#default_value' => isset($item['alt']) ? $item['alt'] : '',
     '#description' => t('This text will be used by screen readers, search engines, or when the image cannot be loaded.'),
-    '#maxlength' => variable_get('image_alt_length', 80), // See http://www.gawds.org/show.php?contentid=28.
+    // @see http://www.gawds.org/show.php?contentid=28
+    '#maxlength' => 512,
     '#weight' => -2,
     '#access' => (bool) $item['fid'] && $settings['alt_field'],
   );
@@ -412,7 +413,7 @@ function image_field_widget_process($element, &$form_state, $form) {
     '#title' => t('Title'),
     '#default_value' => isset($item['title']) ? $item['title'] : '',
     '#description' => t('The title is used as a tool tip when the user hovers the mouse over the image.'),
-    '#maxlength' => variable_get('image_title_length', 500),
+    '#maxlength' => 1024,
     '#weight' => -1,
     '#access' => (bool) $item['fid'] && $settings['title_field'],
   );
diff --git a/modules/image/image.info b/modules/image/image.info
index 464a0438..8fa7ac0f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/image/image.install b/modules/image/image.install
index fc326b4e..51655582 100644
--- a/modules/image/image.install
+++ b/modules/image/image.install
@@ -121,13 +121,13 @@ function image_field_schema($field) {
       'alt' => array(
         'description' => "Alternative image text, for the image's 'alt' attribute.",
         'type' => 'varchar',
-        'length' => 128,
+        'length' => 512,
         'not null' => FALSE,
       ),
       'title' => array(
         'description' => "Image title text, for the image's 'title' attribute.",
         'type' => 'varchar',
-        'length' => 128,
+        'length' => 1024,
         'not null' => FALSE,
       ),
       'width' => array(
@@ -385,6 +385,51 @@ function image_update_7002(array &$sandbox) {
   $sandbox['#finished'] = count($sandbox['tables']) ? ($sandbox['processed'] / $sandbox['total']) : 1;
 }
 
+/**
+ * Remove the variables that set alt and title length since they were not
+ * used for database column size and could cause PDO exceptions.
+ */
+function image_update_7003() {
+  variable_del('image_alt_length');
+  variable_del('image_title_length');
+}
+
+/**
+ * Use a large setting (512 and 1024 characters) for the length of the image alt
+ * and title fields.
+ */
+function image_update_7004() {
+  $alt_spec = array(
+    'type' => 'varchar',
+    'length' => 512,
+    'not null' => FALSE,
+  );
+
+  $title_spec = array(
+    'type' => 'varchar',
+    'length' => 1024,
+    'not null' => FALSE,
+  );
+
+  $fields = _update_7000_field_read_fields(array(
+    'module' => 'image',
+    'storage_type' => 'field_sql_storage',
+  ));
+
+  foreach ($fields as $field_name => $field) {
+    $tables = array(
+      _field_sql_storage_tablename($field),
+      _field_sql_storage_revision_tablename($field),
+    );
+    $alt_column = $field['field_name'] . '_alt';
+    $title_column = $field['field_name'] . '_title';
+    foreach ($tables as $table) {
+      db_change_field($table, $alt_column, $alt_column, $alt_spec);
+      db_change_field($table, $title_column, $title_column, $title_spec);
+    }
+  }
+}
+
 /**
  * Implements hook_requirements() to check the PHP GD Library.
  *
diff --git a/modules/image/image.test b/modules/image/image.test
index a29b4f3a..3b7f3e7d 100644
--- a/modules/image/image.test
+++ b/modules/image/image.test
@@ -192,7 +192,7 @@ class ImageStylesPathAndUrlUnitTest extends DrupalWebTestCase {
     $this->assertNotIdentical(FALSE, $original_uri, t('Created the generated image file.'));
 
     // Get the URL of a file that has not been generated and try to create it.
-    $generated_uri = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/'. basename($original_uri);
+    $generated_uri = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/'. drupal_basename($original_uri);
     $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.'));
     $generate_url = image_style_url($this->style_name, $original_uri);
 
@@ -746,7 +746,10 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
     $widget_settings = array(
       'preview_image_style' => 'medium',
     );
-    $this->createImageField($field_name, 'article', array(), $instance_settings, $widget_settings);
+    $field = $this->createImageField($field_name, 'article', array(), $instance_settings, $widget_settings);
+    $field['deleted'] = 0;
+    $table = _field_sql_storage_tablename($field);
+    $schema = drupal_get_schema($table, TRUE);
     $instance = field_info_instance('node', $field_name, 'article');
 
     $this->drupalGet('node/add/article');
@@ -786,6 +789,22 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
     $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save'));
     $default_output = theme('image', $image_info);
     $this->assertRaw($default_output, t('Image displayed using user supplied alt and title attributes.'));
+
+    // Verify that alt/title longer than allowed results in a validation error.
+    $test_size = 2000;
+    $edit = array(
+      $field_name . '[' . LANGUAGE_NONE . '][0][alt]' => $this->randomName($test_size),
+      $field_name . '[' . LANGUAGE_NONE . '][0][title]' => $this->randomName($test_size),
+    );
+    $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save'));
+    $this->assertRaw(t('Alternate text cannot be longer than %max characters but is currently %length characters long.', array(
+      '%max' => $schema['fields'][$field_name .'_alt']['length'],
+      '%length' => $test_size,
+    )));
+    $this->assertRaw(t('Title cannot be longer than %max characters but is currently %length characters long.', array(
+      '%max' => $schema['fields'][$field_name .'_title']['length'],
+      '%length' => $test_size,
+    )));
   }
 
   /**
@@ -940,7 +959,7 @@ class ImageDimensionsUnitTest extends DrupalWebTestCase {
 
     // Create a style.
     $style = image_style_save(array('name' => 'test'));
-    $generated_uri = 'public://styles/test/public/'. basename($original_uri);
+    $generated_uri = 'public://styles/test/public/'. drupal_basename($original_uri);
     $url = image_style_url('test', $original_uri);
 
     $variables = array(
@@ -1129,3 +1148,144 @@ class ImageDimensionsUnitTest extends DrupalWebTestCase {
     $this->assertEqual($img_tag, '<img typeof="foaf:Image" src="' . $url . '" alt="" />', t('Expected img tag was found.'));
   }
 }
+
+/**
+ * Tests image_dimensions_scale().
+ */
+class ImageDimensionsScaleTestCase extends DrupalUnitTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'image_dimensions_scale()',
+      'description' => 'Tests all control flow branches in image_dimensions_scale().',
+      'group' => 'Image',
+    );
+  }
+
+  /**
+   * Tests all control flow branches in image_dimensions_scale().
+   */
+  function testImageDimensionsScale() {
+    // Define input / output datasets to test different branch conditions.
+    $test = array();
+
+    // Test branch conditions:
+    // - No height.
+    // - Upscale, don't need to upscale.
+    $tests[] = array(
+      'input' => array(
+        'dimensions' => array(
+          'width' => 1000,
+          'height' => 2000,
+        ),
+        'width' => 200,
+        'height' => NULL,
+        'upscale' => TRUE,
+      ),
+      'output' => array(
+        'dimensions' => array(
+          'width' => 200,
+          'height' => 400,
+        ),
+        'return_value' => TRUE,
+      ),
+    );
+
+    // Test branch conditions:
+    // - No width.
+    // - Don't upscale, don't need to upscale.
+    $tests[] = array(
+      'input' => array(
+        'dimensions' => array(
+          'width' => 1000,
+          'height' => 800,
+        ),
+        'width' => NULL,
+        'height' => 140,
+        'upscale' => FALSE,
+      ),
+      'output' => array(
+        'dimensions' => array(
+          'width' => 175,
+          'height' => 140,
+        ),
+        'return_value' => TRUE,
+      ),
+    );
+
+    // Test branch conditions:
+    // - Source aspect ratio greater than target.
+    // - Upscale, need to upscale.
+    $tests[] = array(
+      'input' => array(
+        'dimensions' => array(
+          'width' => 8,
+          'height' => 20,
+        ),
+        'width' => 200,
+        'height' => 140,
+        'upscale' => TRUE,
+      ),
+      'output' => array(
+        'dimensions' => array(
+          'width' => 56,
+          'height' => 140,
+        ),
+        'return_value' => TRUE,
+      ),
+    );
+
+    // Test branch condition: target aspect ratio greater than source.
+    $tests[] = array(
+      'input' => array(
+        'dimensions' => array(
+          'width' => 2000,
+          'height' => 800,
+        ),
+        'width' => 200,
+        'height' => 140,
+        'upscale' => FALSE,
+      ),
+      'output' => array(
+        'dimensions' => array(
+          'width' => 200,
+          'height' => 80,
+        ),
+        'return_value' => TRUE,
+      ),
+    );
+
+    // Test branch condition: don't upscale, need to upscale.
+    $tests[] = array(
+      'input' => array(
+        'dimensions' => array(
+          'width' => 100,
+          'height' => 50,
+        ),
+        'width' => 200,
+        'height' => 140,
+        'upscale' => FALSE,
+      ),
+      'output' => array(
+        'dimensions' => array(
+          'width' => 100,
+          'height' => 50,
+        ),
+        'return_value' => FALSE,
+      ),
+    );
+
+    foreach ($tests as $test) {
+      // Process the test dataset.
+      $return_value = image_dimensions_scale($test['input']['dimensions'], $test['input']['width'], $test['input']['height'], $test['input']['upscale']);
+
+      // Check the width.
+      $this->assertEqual($test['output']['dimensions']['width'], $test['input']['dimensions']['width'], t('Computed width (@computed_width) equals expected width (@expected_width)', array('@computed_width' => $test['output']['dimensions']['width'], '@expected_width' => $test['input']['dimensions']['width'])));
+
+      // Check the height.
+      $this->assertEqual($test['output']['dimensions']['height'], $test['input']['dimensions']['height'], t('Computed height (@computed_height) equals expected height (@expected_height)', array('@computed_height' => $test['output']['dimensions']['height'], '@expected_height' => $test['input']['dimensions']['height'])));
+
+      // Check the return value.
+      $this->assertEqual($test['output']['return_value'], $return_value, t('Correct return value.'));
+    }
+  }
+}
diff --git a/modules/image/tests/image_module_test.info b/modules/image/tests/image_module_test.info
index 3088e183..26f46dca 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/locale/locale.info b/modules/locale/locale.info
index 03c6d801..1b305da6 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 07884614..caa01f2f 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -630,7 +630,14 @@ function locale_modules_disabled($modules) {
  */
 function locale($string = NULL, $context = NULL, $langcode = NULL) {
   global $language;
-  $locale_t = &drupal_static(__FUNCTION__);
+
+  // Use the advanced drupal_static() pattern, since this is called very often.
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['locale'] = &drupal_static(__FUNCTION__);
+  }
+  $locale_t = &$drupal_static_fast['locale'];
+
 
   if (!isset($string)) {
     // Return all cached strings if no string was specified
@@ -1000,13 +1007,12 @@ function locale_url_outbound_alter(&$path, &$options, $original_path) {
         $negotiation = variable_get("language_negotiation_$type", array());
 
         foreach ($negotiation as $id => $provider) {
-          if (isset($provider['file'])) {
-            require_once DRUPAL_ROOT . '/' . $provider['file'];
-          }
-
-          // Avoid duplicate callback entries.
           if (isset($provider['callbacks']['url_rewrite'])) {
-            $callbacks[$provider['callbacks']['url_rewrite']] = NULL;
+            if (isset($provider['file'])) {
+              require_once DRUPAL_ROOT . '/' . $provider['file'];
+            }
+            // Avoid duplicate callback entries.
+            $callbacks[$provider['callbacks']['url_rewrite']] = TRUE;
           }
         }
       }
diff --git a/modules/locale/locale.test b/modules/locale/locale.test
index 5eb1cd34..ca945569 100644
--- a/modules/locale/locale.test
+++ b/modules/locale/locale.test
@@ -1880,6 +1880,34 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
     parent::setUp('locale');
   }
 
+  /**
+   * Verifies that machine name fields are always LTR.
+   */
+  function testMachineNameLTR() {
+    // User to add and remove language.
+    $admin_user = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages'));
+
+    // Log in as admin.
+    $this->drupalLogin($admin_user);
+
+    // Verify that the machine name field is LTR for a new content type.
+    $this->drupalGet('admin/structure/types/add');
+    $this->assertFieldByXpath('//input[@name="type" and @dir="ltr"]', NULL, 'The machine name field is LTR when no additional language is configured.');
+
+    // Install the Arabic language (which is RTL) and configure as the default.
+    $edit = array();
+    $edit['langcode'] = 'ar';
+    $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
+
+    $edit = array();
+    $edit['site_default'] = 'ar';
+    $this->drupalPost(NULL, $edit, t('Save configuration'));
+
+    // Verify that the machine name field is still LTR for a new content type.
+    $this->drupalGet('admin/structure/types/add');
+    $this->assertFieldByXpath('//input[@name="type" and @dir="ltr"]', NULL, 'The machine name field is LTR when the default language is RTL.');
+  }
+
   /**
    * Test if a content type can be set to multilingual and language setting is
    * present on node add and edit forms.
diff --git a/modules/locale/tests/locale_test.info b/modules/locale/tests/locale_test.info
index 2dc30579..8f5237e1 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/menu/menu.admin.js b/modules/menu/menu.admin.js
index 15bc2e7c..4fa094e7 100644
--- a/modules/menu/menu.admin.js
+++ b/modules/menu/menu.admin.js
@@ -1,47 +1,46 @@
-
 (function ($) {
 
-  Drupal.behaviors.menuChangeParentItems = {
-    attach: function (context, settings) {
-      $('fieldset#edit-menu input').each(function () {
-        $(this).change(function () {
-          // Update list of available parent menu items.
-          Drupal.menu_update_parent_list();
-        });
+Drupal.behaviors.menuChangeParentItems = {
+  attach: function (context, settings) {
+    $('fieldset#edit-menu input').each(function () {
+      $(this).change(function () {
+        // Update list of available parent menu items.
+        Drupal.menu_update_parent_list();
       });
-    }
+    });
   }
+};
 
-  /**
-   * Function to set the options of the menu parent item dropdown.
-   */
-  Drupal.menu_update_parent_list = function () {
-    var values = [];
+/**
+ * Function to set the options of the menu parent item dropdown.
+ */
+Drupal.menu_update_parent_list = function () {
+  var values = [];
 
-    $('input:checked', $('fieldset#edit-menu')).each(function () {
-      // Get the names of all checked menus.
-      values.push(Drupal.checkPlain($.trim($(this).val())));
-    });
+  $('input:checked', $('fieldset#edit-menu')).each(function () {
+    // Get the names of all checked menus.
+    values.push(Drupal.checkPlain($.trim($(this).val())));
+  });
 
-    var url = Drupal.settings.basePath + 'admin/structure/menu/parents';
-    $.ajax({
-      url: location.protocol + '//' + location.host + url,
-      type: 'POST',
-      data: {'menus[]' : values},
-      dataType: 'json',
-      success: function (options) {
-        // Save key of last selected element.
-        var selected = $('fieldset#edit-menu #edit-menu-parent :selected').val();
-        // Remove all exisiting options from dropdown.
-        $('fieldset#edit-menu #edit-menu-parent').children().remove();
-        // Add new options to dropdown.
-        jQuery.each(options, function(index, value) {
-          $('fieldset#edit-menu #edit-menu-parent').append(
-            $('<option ' + (index == selected ? ' selected="selected"' : '') + '></option>').val(index).text(value)
-          );
-        });
-      }
-    });
-  }
+  var url = Drupal.settings.basePath + 'admin/structure/menu/parents';
+  $.ajax({
+    url: location.protocol + '//' + location.host + url,
+    type: 'POST',
+    data: {'menus[]' : values},
+    dataType: 'json',
+    success: function (options) {
+      // Save key of last selected element.
+      var selected = $('fieldset#edit-menu #edit-menu-parent :selected').val();
+      // Remove all exisiting options from dropdown.
+      $('fieldset#edit-menu #edit-menu-parent').children().remove();
+      // Add new options to dropdown.
+      jQuery.each(options, function(index, value) {
+        $('fieldset#edit-menu #edit-menu-parent').append(
+          $('<option ' + (index == selected ? ' selected="selected"' : '') + '></option>').val(index).text(value)
+        );
+      });
+    }
+  });
+};
 
 })(jQuery);
diff --git a/modules/menu/menu.info b/modules/menu/menu.info
index c1491428..116f232b 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/menu/menu.install b/modules/menu/menu.install
index a7e43379..7877b996 100644
--- a/modules/menu/menu.install
+++ b/modules/menu/menu.install
@@ -182,6 +182,28 @@ function menu_update_7002(&$sandbox) {
     update_fix_d7_block_deltas($sandbox, $renamed_deltas, $moved_deltas);
   }
 }
+/**
+ * Add missing custom menus to active menus list.
+ */
+function menu_update_7003(&$sandbox) {
+  // Make sure all custom menus are present in the active menus variable so that
+  // their items may appear in the active trail.
+  // @see menu_set_active_menu_names()
+  $active_menus = variable_get('menu_default_active_menus', array_keys(menu_list_system_menus()));
+  $update_variable = FALSE;
+  foreach (menu_get_names() as $menu_name) {
+    if (!in_array($menu_name, $active_menus) && (strpos($menu_name, 'menu-') === 0)) {
+      $active_menus[] = $menu_name;
+      $update_variable = TRUE;
+    }
+  }
+  if ($update_variable) {
+    variable_set('menu_default_active_menus', $active_menus);
+  }
+  // Clear the menu cache.
+  cache_clear_all(NULL, 'cache_menu');
+}
+
 /**
  * @} End of "defgroup updates-7.x-extra"
  * The next series of updates should start at 8000.
diff --git a/modules/menu/menu.js b/modules/menu/menu.js
index 40c1bfe9..ff4ef1e1 100644
--- a/modules/menu/menu.js
+++ b/modules/menu/menu.js
@@ -1,4 +1,3 @@
-
 (function ($) {
 
 Drupal.behaviors.menuFieldsetSummaries = {
diff --git a/modules/menu/menu.module b/modules/menu/menu.module
index c9148673..40614a16 100644
--- a/modules/menu/menu.module
+++ b/modules/menu/menu.module
@@ -268,6 +268,15 @@ function menu_save($menu) {
 
   switch ($status) {
     case SAVED_NEW:
+      // Make sure the menu is present in the active menus variable so that its
+      // items may appear in the menu active trail.
+      // @see menu_set_active_menu_names()
+      $active_menus = variable_get('menu_default_active_menus', array_keys(menu_get_menus()));
+      if (!in_array($menu['menu_name'], $active_menus)) {
+        $active_menus[] = $menu['menu_name'];
+        variable_set('menu_default_active_menus', $active_menus);
+      }
+
       module_invoke_all('menu_insert', $menu);
       break;
 
@@ -305,6 +314,15 @@ function menu_delete($menu) {
   // Delete all links from the menu.
   menu_delete_links($menu['menu_name']);
 
+  // Remove menu from active menus variable.
+  $active_menus = variable_get('menu_default_active_menus', array_keys(menu_get_menus()));
+  foreach ($active_menus as $i => $menu_name) {
+    if ($menu['menu_name'] == $menu_name) {
+      unset($active_menus[$i]);
+      variable_set('menu_default_active_menus', $active_menus);
+    }
+  }
+
   // Delete the custom menu.
   db_delete('menu_custom')
     ->condition('menu_name', $menu['menu_name'])
@@ -614,7 +632,7 @@ function menu_form_node_form_alter(&$form, $form_state) {
   // menu_parent_options() is goofy and can actually handle either a menu link
   // or a node type both as second argument. Pick based on whether there is
   // a link already (menu_node_prepare() sets mlid default to 0).
-  $options = menu_parent_options(menu_get_menus(), $link['mlid'] ? $link : $type);
+  $options = menu_parent_options(menu_get_menus(), $link['mlid'] ? $link : $type, $type);
   // If no possible parent menu items were found, there is nothing to display.
   if (empty($options)) {
     return;
diff --git a/modules/menu/menu.test b/modules/menu/menu.test
index 0edfc47b..324ba676 100644
--- a/modules/menu/menu.test
+++ b/modules/menu/menu.test
@@ -205,7 +205,7 @@ class MenuTestCase extends DrupalWebTestCase {
 
     // Add menu links.
     $item1 = $this->addMenuLink(0, 'node/' . $node1->nid, $menu_name);
-    $item2 = $this->addMenuLink($item1['mlid'], 'node/' . $node2->nid, $menu_name);
+    $item2 = $this->addMenuLink($item1['mlid'], 'node/' . $node2->nid, $menu_name, FALSE);
     $item3 = $this->addMenuLink($item2['mlid'], 'node/' . $node3->nid, $menu_name);
     $this->assertMenuLink($item1['mlid'], array('depth' => 1, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => 0));
     $this->assertMenuLink($item2['mlid'], array('depth' => 2, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => $item2['mlid'], 'p3' => 0));
@@ -283,7 +283,7 @@ class MenuTestCase extends DrupalWebTestCase {
    * @param string $menu_name Menu name.
    * @return array Menu link created.
    */
-  function addMenuLink($plid = 0, $link = '<front>', $menu_name = 'navigation') {
+  function addMenuLink($plid = 0, $link = '<front>', $menu_name = 'navigation', $expanded = TRUE) {
     // View add menu link page.
     $this->drupalGet("admin/structure/menu/manage/$menu_name/add");
     $this->assertResponse(200);
@@ -294,7 +294,7 @@ class MenuTestCase extends DrupalWebTestCase {
       'link_title' => $title,
       'description' => '',
       'enabled' => TRUE, // Use this to disable the menu and test.
-      'expanded' => TRUE, // Setting this to true should test whether it works when we do the std_user tests.
+      'expanded' => $expanded, // Setting this to true should test whether it works when we do the std_user tests.
       'parent' =>  $menu_name . ':' . $plid,
       'weight' => '0',
     );
@@ -345,7 +345,7 @@ class MenuTestCase extends DrupalWebTestCase {
     if (isset($parent)) {
       // Verify menu link.
       $title = $parent['link_title'];
-      $this->assertText($title, 'Parent menu link was displayed');
+      $this->assertLink($title, 0, 'Parent menu link was displayed');
 
       // Verify menu link link.
       $this->clickLink($title);
@@ -355,7 +355,7 @@ class MenuTestCase extends DrupalWebTestCase {
 
     // Verify menu link.
     $title = $item['link_title'];
-    $this->assertText($title, 'Menu link was displayed');
+    $this->assertLink($title, 0, 'Menu link was displayed');
 
     // Verify menu link link.
     $this->clickLink($title);
@@ -698,6 +698,8 @@ class MenuNodeTestCase extends DrupalWebTestCase {
     // Assert that it is not possible to set the parent of the first node to itself or the second node.
     $this->assertNoOption('edit-menu-parent', 'navigation:'. $item['mlid']);
     $this->assertNoOption('edit-menu-parent', 'navigation:'. $child_item['mlid']);
+    // Assert that unallowed Management menu is not available in options.
+    $this->assertNoOption('edit-menu-parent', 'management:0');
   }
 
   /**
diff --git a/modules/node/node.api.php b/modules/node/node.api.php
index 7f8e2286..a9881d5e 100644
--- a/modules/node/node.api.php
+++ b/modules/node/node.api.php
@@ -570,6 +570,10 @@ function hook_node_load($nodes, $types) {
  * block access, return NODE_ACCESS_IGNORE or simply return nothing.
  * Blindly returning FALSE will break other node access modules.
  *
+ * Also note that this function isn't called for node listings (e.g., RSS feeds,
+ * the default home page at path 'node', a recent content block, etc.) See
+ * @link node_access Node access rights @endlink for a full explanation.
+ *
  * @param $node
  *   Either a node object or the machine name of the content type on which to
  *   perform the access check.
@@ -972,6 +976,7 @@ function hook_ranking() {
  *   The node type object that is being created.
  */
 function hook_node_type_insert($info) {
+  drupal_set_message(t('You have just created a content type with a machine name %type.', array('%type' => $info->type)));
 }
 
 /**
@@ -1229,9 +1234,12 @@ function hook_validate($node, $form, &$form_state) {
 /**
  * Display a node.
  *
- * This is a hook used by node modules. It allows a module to define a
- * custom method of displaying its nodes, usually by displaying extra
- * information particular to that node type.
+ * This hook is invoked only on the module that defines the node's content type
+ * (use hook_node_view() to act on all node views).
+ *
+ * This hook is invoked during node viewing after the node is fully loaded,
+ * so that the node type module can define a custom method for display, or
+ * add to the default display.
  *
  * @param $node
  *   The node to be displayed, as returned by node_load().
@@ -1249,8 +1257,6 @@ function hook_validate($node, $form, &$form_state) {
  *   view of the node, you might consider implementing one of these hooks
  *   instead.
  *
- * For a detailed usage example, see node_example.module.
- *
  * @ingroup node_api_hooks
  */
 function hook_view($node, $view_mode) {
diff --git a/modules/node/node.info b/modules/node/node.info
index 1d038aaa..b161abf4 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/node/node.module b/modules/node/node.module
index 51ec8c30..fe8ee516 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -919,7 +919,7 @@ function node_load_multiple($nids = array(), $conditions = array(), $reset = FAL
  *   Whether to reset the node_load_multiple cache.
  *
  * @return
- *   A fully-populated node object.
+ *   A fully-populated node object, or FALSE if the node is not found.
  */
 function node_load($nid = NULL, $vid = NULL, $reset = FALSE) {
   $nids = (isset($nid) ? array($nid) : array());
@@ -1396,7 +1396,7 @@ function node_build_content($node, $view_mode = 'full', $langcode = NULL) {
  * @param $message
  *   A flag which sets a page title relevant to the revision being viewed.
  * @return
- *   A $page element suitable for use by drupal_page_render().
+ *   A $page element suitable for use by drupal_render().
  */
 function node_show($node, $message = FALSE) {
   if ($message) {
@@ -2790,13 +2790,14 @@ function node_search_validate($form, &$form_state) {
  * that this table is a list of grants; any matching row is sufficient to
  * grant access to the node.
  *
- * In node listings, the process above is followed except that
- * hook_node_access() is not called on each node for performance reasons and for
- * proper functioning of the pager system. When adding a node listing to your
- * module, be sure to use a dynamic query created by db_select() and add a tag
- * of "node_access". This will allow modules dealing with node access to ensure
- * only nodes to which the user has access are retrieved, through the use of
- * hook_query_TAG_alter().
+ * In node listings (lists of nodes generated from a select query, such as the
+ * default home page at path 'node', an RSS feed, a recent content block, etc.),
+ * the process above is followed except that hook_node_access() is not called on
+ * each node for performance reasons and for proper functioning of the pager
+ * system. When adding a node listing to your module, be sure to use a dynamic
+ * query created by db_select() and add a tag of "node_access". This will allow
+ * modules dealing with node access to ensure only nodes to which the user has
+ * access are retrieved, through the use of hook_query_TAG_alter().
  *
  * Note: Even a single module returning NODE_ACCESS_DENY from hook_node_access()
  * will block access to the node. Therefore, implementers should take care to
@@ -2961,7 +2962,6 @@ function node_node_access($node, $op, $account) {
  */
 function node_list_permissions($type) {
   $info = node_type_get_type($type);
-  $type = check_plain($info->type);
 
   // Build standard list of node permissions for this type.
   $perms = array(
diff --git a/modules/node/tests/node_access_test.info b/modules/node/tests/node_access_test.info
index 56df2148..328362fd 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/node/tests/node_access_test.module b/modules/node/tests/node_access_test.module
index 91c117a6..f2eca2e4 100644
--- a/modules/node/tests/node_access_test.module
+++ b/modules/node/tests/node_access_test.module
@@ -159,7 +159,7 @@ function node_access_entity_test_page() {
 }
 
 /**
- * Implements hook_form_node_form_alter().
+ * Implements hook_form_BASE_FORM_ID_alter().
  */
 function node_access_test_form_node_form_alter(&$form, $form_state) {
   // Only show this checkbox for NodeAccessBaseTableTestCase.
diff --git a/modules/node/tests/node_test.info b/modules/node/tests/node_test.info
index 6088f173..9cf9326f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/node/tests/node_test_exception.info b/modules/node/tests/node_test_exception.info
index 8257e40e..228b9b12 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/openid/openid.inc b/modules/openid/openid.inc
index 98af518c..9b793d36 100644
--- a/modules/openid/openid.inc
+++ b/modules/openid/openid.inc
@@ -617,18 +617,31 @@ function _openid_get_params($str) {
  * @param $fallback_prefix
  *   An optional prefix that will be used in case no prefix is found for the
  *   target extension namespace.
+ * @param $only_signed
+ *   Return only keys that are included in the message signature in openid.sig.
+ *   Unsigned fields may have been modified or added by other parties than the
+ *   OpenID Provider.
+ *
  * @return
  *   An associative array containing all the parameters in the response message
  *   that belong to the extension. The keys are stripped from their namespace
  *   prefix.
+ *
  * @see http://openid.net/specs/openid-authentication-2_0.html#extensions
  */
-function openid_extract_namespace($response, $extension_namespace, $fallback_prefix = NULL) {
+function openid_extract_namespace($response, $extension_namespace, $fallback_prefix = NULL, $only_signed = FALSE) {
+  $signed_keys = explode(',', $response['openid.signed']);
+
   // Find the namespace prefix.
   $prefix = $fallback_prefix;
   foreach ($response as $key => $value) {
     if ($value == $extension_namespace && preg_match('/^openid\.ns\.([^.]+)$/', $key, $matches)) {
       $prefix = $matches[1];
+      if ($only_signed && !in_array('ns.' . $matches[1], $signed_keys)) {
+        // The namespace was defined but was not signed as required. In this
+        // case we do not fall back to $fallback_prefix.
+        $prefix = NULL;
+      }
       break;
     }
   }
@@ -641,7 +654,9 @@ function openid_extract_namespace($response, $extension_namespace, $fallback_pre
   foreach ($response as $key => $value) {
     if (preg_match('/^openid\.' . $prefix . '\.(.+)$/', $key, $matches)) {
       $local_key = $matches[1];
-      $output[$local_key] = $value;
+      if (!$only_signed || in_array($prefix . '.' . $local_key, $signed_keys)) {
+        $output[$local_key] = $value;
+      }
     }
   }
 
@@ -837,8 +852,8 @@ function _openid_invalid_openid_transition($identity, $response) {
     // Try to extract e-mail address from Simple Registration (SREG) or
     // Attribute Exchanges (AX) keys.
     $email = '';
-    $sreg_values = openid_extract_namespace($response, OPENID_NS_SREG, 'sreg');
-    $ax_values = openid_extract_namespace($response, OPENID_NS_AX, 'ax');
+    $sreg_values = openid_extract_namespace($response, OPENID_NS_SREG, 'sreg', TRUE);
+    $ax_values = openid_extract_namespace($response, OPENID_NS_AX, 'ax', TRUE);
     if (!empty($sreg_values['email']) && valid_email_address($sreg_values['email'])) {
       $email = $sreg_values['email'];
     }
diff --git a/modules/openid/openid.info b/modules/openid/openid.info
index 5b881399..1b399918 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/openid/openid.module b/modules/openid/openid.module
index f2847fc0..e08d5571 100644
--- a/modules/openid/openid.module
+++ b/modules/openid/openid.module
@@ -185,10 +185,15 @@ function openid_form_user_register_form_alter(&$form, &$form_state) {
 
     $response = $_SESSION['openid']['response'];
 
-    // Extract Simple Registration keys from the response.
-    $sreg_values = openid_extract_namespace($response, OPENID_NS_SREG, 'sreg');
-    // Extract Attribute Exchanges keys from the response.
-    $ax_values = openid_extract_namespace($response, OPENID_NS_AX, 'ax');
+    // Extract Simple Registration keys from the response. We only include
+    // signed keys as required by OpenID Simple Registration Extension 1.0,
+    // section 4.
+    $sreg_values = openid_extract_namespace($response, OPENID_NS_SREG, 'sreg', TRUE);
+    // Extract Attribute Exchanges keys from the response. We only include
+    // signed keys. This is not required by the specification, but it is
+    // recommended by Google, see
+    // http://googlecode.blogspot.com/2011/05/security-advisory-to-websites-using.html
+    $ax_values = openid_extract_namespace($response, OPENID_NS_AX, 'ax', TRUE);
 
     if (!empty($sreg_values['nickname'])) {
       // Use the nickname returned by Simple Registration if available.
diff --git a/modules/openid/openid.test b/modules/openid/openid.test
index afb9068c..9b6b1ad5 100644
--- a/modules/openid/openid.test
+++ b/modules/openid/openid.test
@@ -343,17 +343,49 @@ class OpenIDFunctionalTestCase extends OpenIDWebTestCase {
     // Use a User-supplied Identity that is the URL of an XRDS document.
     $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE));
 
-    // Do not sign all mandatory fields (e.g. assoc_handle).
+    // Respond with an invalid signature.
+    variable_set('openid_test_response', array('openid.sig' => 'this-is-an-invalid-signature'));
+    $this->submitLoginForm($identity);
+    $this->assertRaw('OpenID login failed.');
+
+    // Do not sign the mandatory field openid.assoc_handle.
     variable_set('openid_test_response', array('openid.signed' => 'op_endpoint,claimed_id,identity,return_to,response_nonce'));
     $this->submitLoginForm($identity);
     $this->assertRaw('OpenID login failed.');
 
-    // Sign all mandatory fields and some custom fields.
-    variable_set('openid_test_response', array('openid.foo' => 'bar', 'openid.signed' => 'op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle,foo'));
+    // Sign all mandatory fields and a custom field.
+    $keys_to_sign = array('op_endpoint', 'claimed_id', 'identity', 'return_to', 'response_nonce', 'assoc_handle', 'foo');
+    $association = new stdClass();
+    $association->mac_key = variable_get('mac_key');
+    $response = array(
+      'openid.op_endpoint' => url('openid-test/endpoint', array('absolute' => TRUE)),
+      'openid.claimed_id' => $identity,
+      'openid.identity' => $identity,
+      'openid.return_to' => url('openid/authenticate', array('absolute' => TRUE)),
+      'openid.response_nonce' => _openid_nonce(),
+      'openid.assoc_handle' => 'openid-test',
+      'openid.foo' => 123,
+      'openid.signed' => implode(',', $keys_to_sign),
+    );
+    $response['openid.sig'] = _openid_signature($association, $response, $keys_to_sign);
+    variable_set('openid_test_response', $response);
     $this->submitLoginForm($identity);
     $this->assertNoRaw('OpenID login failed.');
-  }
+    $this->assertFieldByName('name', '', t('No username was supplied by provider.'));
+    $this->assertFieldByName('mail', '', t('No e-mail address was supplied by provider.'));
 
+    // Check that unsigned SREG fields are ignored.
+    $response = array(
+      'openid.signed' => 'op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle,sreg.nickname',
+      'openid.sreg.nickname' => 'john',
+      'openid.sreg.email' => 'john@example.com',
+    );
+    variable_set('openid_test_response', $response);
+    $this->submitLoginForm($identity);
+    $this->assertNoRaw('OpenID login failed.');
+    $this->assertFieldByName('name', 'john', t('Username was supplied by provider.'));
+    $this->assertFieldByName('mail', '', t('E-mail address supplied by provider was ignored.'));
+  }
 }
 
 /**
@@ -728,4 +760,41 @@ class OpenIDUnitTest extends DrupalWebTestCase {
 
     $this->assertEqual(openid_normalize('http://example.com/path#fragment'), 'http://example.com/path', t('openid_normalize() correctly normalized a URL with a fragment.'));
   }
+
+  /**
+   * Test openid_extract_namespace().
+   */
+  function testOpenidExtractNamespace() {
+    $response = array(
+      'openid.sreg.nickname' => 'john',
+      'openid.ns.ext1' => OPENID_NS_SREG,
+      'openid.ext1.nickname' => 'george',
+      'openid.ext1.email' => 'george@example.com',
+      'openid.ns.ext2' => 'http://example.com/ns/ext2',
+      'openid.ext2.foo' => '123',
+      'openid.ext2.bar' => '456',
+      'openid.signed' => 'sreg.nickname,ns.ext1,ext1.email,ext2.foo',
+    );
+
+    $values = openid_extract_namespace($response, 'http://example.com/ns/dummy', NULL, FALSE);
+    $this->assertEqual($values, array(), t('Nothing found for unused namespace.'));
+
+    $values = openid_extract_namespace($response, 'http://example.com/ns/dummy', 'sreg', FALSE);
+    $this->assertEqual($values, array('nickname' => 'john'), t('Value found for fallback prefix.'));
+
+    $values = openid_extract_namespace($response, OPENID_NS_SREG, 'sreg', FALSE);
+    $this->assertEqual($values, array('nickname' => 'george', 'email' => 'george@example.com'), t('Namespace takes precedence over fallback prefix.'));
+
+    // ext1.email is signed, but ext1.nickname is not.
+    $values = openid_extract_namespace($response, OPENID_NS_SREG, 'sreg', TRUE);
+    $this->assertEqual($values, array('email' => 'george@example.com'), t('Unsigned namespaced fields ignored.'));
+
+    $values = openid_extract_namespace($response, 'http://example.com/ns/ext2', 'sreg', FALSE);
+    $this->assertEqual($values, array('foo' => '123', 'bar' => '456'), t('Unsigned fields found.'));
+
+    // ext2.foo and ext2.bar are ignored, because ns.ext2 is not signed. The
+    // fallback prefix is not used, because the namespace is specified.
+    $values = openid_extract_namespace($response, 'http://example.com/ns/ext2', 'sreg', TRUE);
+    $this->assertEqual($values, array(), t('Unsigned fields ignored.'));
+  }
 }
diff --git a/modules/openid/tests/openid_test.info b/modules/openid/tests/openid_test.info
index cfee2c2b..424b7f14 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/openid/tests/openid_test.module b/modules/openid/tests/openid_test.module
index 629dcd33..1b0de4ec 100644
--- a/modules/openid/tests/openid_test.module
+++ b/modules/openid/tests/openid_test.module
@@ -324,9 +324,7 @@ function _openid_test_endpoint_authenticate() {
   // Generate unique identifier for this authentication.
   $nonce = _openid_nonce();
 
-  // Generate response containing the user's identity. The openid.sreg.xxx
-  // entries contain profile data stored by the OpenID Provider (see OpenID
-  // Simple Registration Extension 1.0).
+  // Generate response containing the user's identity.
   $response = variable_get('openid_test_response', array()) + array(
     'openid.ns' => OPENID_NS_2_0,
     'openid.mode' => 'id_res',
@@ -336,14 +334,27 @@ function _openid_test_endpoint_authenticate() {
     'openid.return_to' => $_REQUEST['openid_return_to'],
     'openid.response_nonce' => $nonce,
     'openid.assoc_handle' => 'openid-test',
-    'openid.signed' => 'op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle',
   );
 
+  if (isset($response['openid.signed'])) {
+    $keys_to_sign = explode(',', $response['openid.signed']);
+  }
+  else {
+    // Unless openid.signed is explicitly defined, all keys are signed.
+    $keys_to_sign = array();
+    foreach ($response as $key => $value) {
+      // Strip off the "openid." prefix.
+      $keys_to_sign[] = substr($key, 7);
+    }
+    $response['openid.signed'] = implode(',', $keys_to_sign);
+  }
+
   // Sign the message using the MAC key that was exchanged during association.
   $association = new stdClass();
   $association->mac_key = variable_get('mac_key');
-  $keys_to_sign = explode(',', $response['openid.signed']);
-  $response['openid.sig'] = _openid_signature($association, $response, $keys_to_sign);
+  if (!isset($response['openid.sig'])) {
+    $response['openid.sig'] = _openid_signature($association, $response, $keys_to_sign);
+  }
 
   // Put the signed message into the query string of a URL supplied by the
   // Relying Party, and redirect the user.
diff --git a/modules/overlay/overlay-parent.js b/modules/overlay/overlay-parent.js
index f9789f14..3519e84f 100644
--- a/modules/overlay/overlay-parent.js
+++ b/modules/overlay/overlay-parent.js
@@ -334,7 +334,7 @@ Drupal.overlay.setFocusBefore = function ($element, document) {
   $placeholder.one('blur', function () {
     $(this).remove();
   });
-}
+};
 
 /**
  * Check if the given link is in the administrative section of the site.
@@ -961,7 +961,7 @@ Drupal.overlay._recordTabindex = function () {
   var $element = $(this);
   var tabindex = $(this).attr('tabindex');
   $element.data('drupalOverlayOriginalTabIndex', tabindex);
-}
+};
 
 /**
  * Restore an element's original tabindex.
diff --git a/modules/overlay/overlay.info b/modules/overlay/overlay.info
index ef0f0948..dbea8e98 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/path/path.info b/modules/path/path.info
index 96a7068e..2f045ddb 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/php/php.info b/modules/php/php.info
index 4995b219..e7858d44 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/php/php.module b/modules/php/php.module
index 37bf9a1f..a30c607b 100644
--- a/modules/php/php.module
+++ b/modules/php/php.module
@@ -36,23 +36,29 @@ function php_permission() {
 }
 
 /**
- * Evaluate a string of PHP code.
+ * Evaluates a string of PHP code.
  *
- * This is a wrapper around PHP's eval(). It uses output buffering to capture both
- * returned and printed text. Unlike eval(), we require code to be surrounded by
- * <?php ?> tags; in other words, we evaluate the code as if it were a stand-alone
- * PHP file.
+ * This is a wrapper around PHP's eval(). It uses output buffering to capture
+ * both returned and printed text. Unlike eval(), we require code to be
+ * surrounded by <?php ?> tags; in other words, we evaluate the code as if it
+ * were a stand-alone PHP file.
  *
  * Using this wrapper also ensures that the PHP code which is evaluated can not
  * overwrite any variables in the calling code, unlike a regular eval() call.
  *
+ * This function is also used as an implementation of
+ * hook_filter_FILTER_process().
+ *
  * @param $code
  *   The code to evaluate.
+ *
  * @return
- *   A string containing the printed output of the code, followed by the returned
- *   output of the code.
+ *   A string containing the printed output of the code, followed by the
+ *   returned output of the code.
  *
  * @ingroup php_wrappers
+ *
+ * @see php_filter_info()
  */
 function php_eval($code) {
   global $theme_path, $theme_info, $conf;
@@ -82,7 +88,9 @@ function php_eval($code) {
 }
 
 /**
- * Tips callback for php filter.
+ * Implements hook_filter_FILTER_tips().
+ *
+ * @see php_filter_info()
  */
 function _php_filter_tips($filter, $format, $long = FALSE) {
   global $base_url;
@@ -137,4 +145,3 @@ function php_filter_info() {
   );
   return $filters;
 }
-
diff --git a/modules/php/php.test b/modules/php/php.test
index 8ead2ac0..50fb5528 100644
--- a/modules/php/php.test
+++ b/modules/php/php.test
@@ -6,7 +6,7 @@
  */
 
 /**
- * Base PHP test case class.
+ * Defines a base PHP test case class.
  */
 class PHPTestCase extends DrupalWebTestCase {
   protected $php_code_format;
@@ -38,7 +38,7 @@ class PHPTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Create a test node with PHP code in the body.
+   * Creates a test node with PHP code in the body.
    *
    * @return stdObject Node object.
    */
@@ -60,7 +60,7 @@ class PHPFilterTestCase extends PHPTestCase {
   }
 
   /**
-   * Make sure that the PHP filter evaluates PHP code when used.
+   * Makes sure that the PHP filter evaluates PHP code when used.
    */
   function testPHPFilter() {
     // Log in as a user with permission to use the PHP code text format.
@@ -101,7 +101,7 @@ class PHPAccessTestCase extends PHPTestCase {
   }
 
   /**
-   * Make sure that user can't use the PHP filter when not given access.
+   * Makes sure that the user can't use the PHP filter when not given access.
    */
   function testNoPrivileges() {
     // Create node with PHP filter enabled.
diff --git a/modules/poll/poll.info b/modules/poll/poll.info
index 2184624d..94f5eeca 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/poll/poll.module b/modules/poll/poll.module
index 13d2606d..614bb924 100644
--- a/modules/poll/poll.module
+++ b/modules/poll/poll.module
@@ -288,9 +288,10 @@ function poll_form($node, &$form_state) {
 
   // Add initial or additional choices.
   $existing_delta = $delta;
-  $weight++;
   for ($delta; $delta < $choice_count; $delta++) {
     $key = 'new:' . ($delta - $existing_delta);
+    // Increase the weight of each new choice.
+    $weight++;
     $form['choice_wrapper']['choice'][$key] = _poll_choice_form($key, NULL, '', 0, $weight, $choice_count);
   }
 
@@ -408,6 +409,7 @@ function _poll_choice_form($key, $chid = NULL, $value = '', $votes = 0, $weight
     '#maxlength' => 7,
     '#parents' => array('choice', $key, 'chvotes'),
     '#access' => user_access('administer nodes'),
+    '#element_validate' => array('element_validate_integer'),
   );
 
   $form['weight'] = array(
@@ -451,10 +453,8 @@ function poll_node_form_submit(&$form, &$form_state) {
  */
 function poll_validate($node, $form) {
   if (isset($node->title)) {
-    // Check for at least two options and validate amount of votes:
+    // Check for at least two options and validate amount of votes.
     $realchoices = 0;
-    // Renumber fields
-    $node->choice = array_values($node->choice);
     foreach ($node->choice as $i => $choice) {
       if ($choice['chtext'] != '') {
         $realchoices++;
@@ -586,8 +586,10 @@ function poll_update($node) {
           'weight' => $choice['weight'],
         ))
         ->insertFields(array(
-           'nid' => $node->nid,
-           'chtext' => $choice['chtext'],
+          'nid' => $node->nid,
+          'chtext' => $choice['chtext'],
+          'chvotes' => (int) $choice['chvotes'],
+          'weight' => $choice['weight'],
         ))
         ->execute();
     }
diff --git a/modules/poll/poll.test b/modules/poll/poll.test
index d7648a6b..f5c93b28 100644
--- a/modules/poll/poll.test
+++ b/modules/poll/poll.test
@@ -24,8 +24,9 @@ class PollTestCase extends DrupalWebTestCase {
   function pollCreate($title, $choices, $preview = TRUE) {
     $this->assertTrue(TRUE, 'Create a poll');
 
+    $admin_user = $this->drupalCreateUser(array('create poll content', 'administer nodes'));
     $web_user = $this->drupalCreateUser(array('create poll content', 'access content', 'edit own poll content'));
-    $this->drupalLogin($web_user);
+    $this->drupalLogin($admin_user);
 
     // Get the form first to initialize the state of the internal browser.
     $this->drupalGet('node/add/poll');
@@ -33,6 +34,18 @@ class PollTestCase extends DrupalWebTestCase {
     // Prepare a form with two choices.
     list($edit, $index) = $this->_pollGenerateEdit($title, $choices);
 
+    // Verify that the vote count element only allows non-negative integers.
+    $edit['choice[new:1][chvotes]'] = -1;
+    $edit['choice[new:0][chvotes]'] = $this->randomString(7);
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('Negative values are not allowed.'));
+    $this->assertText(t('Vote count for new choice must be an integer.'));
+
+    // Repeat steps for initializing the state of the internal browser.
+    $this->drupalLogin($web_user);
+    $this->drupalGet('node/add/poll');
+    list($edit, $index) = $this->_pollGenerateEdit($title, $choices);
+
     // Re-submit the form until all choices are filled in.
     if (count($choices) > 2) {
       while ($index < count($choices)) {
@@ -88,10 +101,6 @@ class PollTestCase extends DrupalWebTestCase {
     }
     foreach ($new_choices as $k => $text) {
       $edit['choice[new:' . $k . '][chtext]'] = $text;
-      // To test poll choice weights, every new choice is sorted in front of
-      // existing choices. Existing/already submitted choices should keep their
-      // weight.
-      $edit['choice[new:' . $k . '][weight]'] = (- $index - $k);
     }
     return array($edit, count($already_submitted_choices) + count($new_choices));
   }
@@ -122,11 +131,11 @@ class PollTestCase extends DrupalWebTestCase {
    */
   function assertPollChoiceOrder(array $choices, $index = 0, $preview = FALSE) {
     $expected = array();
+    $weight = 0;
     foreach ($choices as $id => $label) {
       if ($id < $index) {
-        // The expected weight of each choice is exactly the negated id.
-        // @see PollTestCase::_pollGenerateEdit()
-        $weight = -$id;
+        // The expected weight of each choice is higher than the previous one.
+        $weight++;
         // Directly assert the weight form element value for this choice.
         $this->assertFieldByName('choice[chid:' . $id . '][weight]', $weight, t('Found choice @id with weight @weight.', array(
           '@id' => $id,
@@ -205,11 +214,12 @@ class PollCreateTestCase extends PollTestCase {
 
     $new_option = $this->randomName();
 
+    $vote_count = '2000';
     $node->choice[] = array(
       'chid' => '',
       'chtext' => $new_option,
-      'chvotes' => 0,
-      'weight' => 0,
+      'chvotes' => (int) $vote_count,
+      'weight' => 1000,
     );
 
     node_save($node);
@@ -217,6 +227,12 @@ class PollCreateTestCase extends PollTestCase {
     $this->drupalGet('poll');
     $this->clickLink($title);
     $this->assertText($new_option, 'New option found.');
+
+    $option = $this->xpath('//div[@id="node-1"]//div[@class="poll"]//div[@class="text"]');
+    $this->assertEqual(end($option), $new_option, 'Last item is equal to new option.');
+
+    $votes = $this->xpath('//div[@id="node-1"]//div[@class="poll"]//div[@class="percent"]');
+    $this->assertTrue(strpos(end($votes), $vote_count) > 0, t("Votes saved."));
   }
 
   function testPollClose() {
diff --git a/modules/profile/profile.info b/modules/profile/profile.info
index 0098735c..9e05a67f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/rdf/rdf.info b/modules/rdf/rdf.info
index 17c35251..4973c0f2 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/rdf/rdf.module b/modules/rdf/rdf.module
index ebecd423..70b684c6 100644
--- a/modules/rdf/rdf.module
+++ b/modules/rdf/rdf.module
@@ -769,6 +769,9 @@ function rdf_field_attach_view_alter(&$output, $context) {
  * Implements MODULE_preprocess_HOOK().
  */
 function rdf_preprocess_image(&$variables) {
+  // Adds the RDF type for image. We cannot use the usual entity-based mapping
+  // to get 'foaf:Image' because image does not have its own entity type or
+  // bundle.
   $variables['attributes']['typeof'] = array('foaf:Image');
 }
 
diff --git a/modules/rdf/tests/rdf_test.info b/modules/rdf/tests/rdf_test.info
index c675b7b9..5fe89cee 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/search/search.api.php b/modules/search/search.api.php
index 3f745bfd..534c1e87 100644
--- a/modules/search/search.api.php
+++ b/modules/search/search.api.php
@@ -22,13 +22,11 @@
  * on your module's type of content. If you want to have your content
  * indexed in the standard search index, your module should also implement
  * hook_update_index(). If your search type has settings, you can implement
- * hook_search_admin() to add them to the search settings page. You can also
- * alter the display of your module's search results by implementing
- * hook_search_page(). You can use hook_form_FORM_ID_alter(), with
- * FORM_ID set to 'search', to add fields to the search form (see
- * node_form_search_form_alter() for an example). You can use
- * hook_search_access() to limit access to searching, and hook_search_page() to
- * override how search results are displayed.
+ * hook_search_admin() to add them to the search settings page. You can use
+ * hook_form_FORM_ID_alter(), with FORM_ID set to 'search_form', to add fields
+ * to the search form (see node_form_search_form_alter() for an example).
+ * You can use hook_search_access() to limit access to searching,
+ * and hook_search_page() to override how search results are displayed.
  *
  * @return
  *   Array with optional keys:
diff --git a/modules/search/search.extender.inc b/modules/search/search.extender.inc
index b7af4d06..ad4b86e8 100644
--- a/modules/search/search.extender.inc
+++ b/modules/search/search.extender.inc
@@ -122,6 +122,16 @@ class SearchQuery extends SelectQueryExtender {
    */
   protected $multiply = array();
 
+  /**
+   * Whether or not search expressions were ignored.
+   *
+   * The maximum number of AND/OR combinations exceeded can be configured to
+   * avoid Denial-of-Service attacks. Expressions beyond the limit are ignored.
+   *
+   * @var boolean
+   */
+  protected $expressionsIgnored = FALSE;
+
   /**
    * Sets up the search query expression.
    *
@@ -183,7 +193,17 @@ class SearchQuery extends SelectQueryExtender {
     // Classify tokens.
     $or = FALSE;
     $warning = '';
+    $limit_combinations = variable_get('search_and_or_limit', 7);
+    // The first search expression does not count as AND.
+    $and_count = -1;
+    $or_count = 0;
     foreach ($keywords as $match) {
+      if ($or_count && $and_count + $or_count >= $limit_combinations) {
+        // Ignore all further search expressions to prevent Denial-of-Service
+        // attacks using a high number of AND/OR combinations.
+        $this->expressionsIgnored = TRUE;
+        break;
+      }
       $phrase = FALSE;
       // Strip off phrase quotes.
       if ($match[2]{0} == '"') {
@@ -212,6 +232,7 @@ class SearchQuery extends SelectQueryExtender {
         }
         $this->keys['positive'][] = $last;
         $or = TRUE;
+        $or_count++;
         continue;
       }
       // AND operator: implied, so just ignore it.
@@ -231,6 +252,7 @@ class SearchQuery extends SelectQueryExtender {
         }
         else {
           $this->keys['positive'] = array_merge($this->keys['positive'], $words);
+          $and_count++;
         }
       }
       $or = FALSE;
@@ -323,6 +345,9 @@ class SearchQuery extends SelectQueryExtender {
       form_set_error('keys', format_plural(variable_get('minimum_word_size', 3), 'You must include at least one positive keyword with 1 character or more.', 'You must include at least one positive keyword with @count characters or more.'));
       return FALSE;
     }
+    if ($this->expressionsIgnored) {
+      drupal_set_message(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => variable_get('search_and_or_limit', 7))), 'warning');
+    }
     $this->executedFirstPass = TRUE;
 
     if (!empty($this->words)) {
diff --git a/modules/search/search.info b/modules/search/search.info
index 285d5625..72b42d35 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/search/search.module b/modules/search/search.module
index 518272a0..915c96fb 100644
--- a/modules/search/search.module
+++ b/modules/search/search.module
@@ -1188,7 +1188,7 @@ function search_excerpt($keys, $text) {
           if (($s = strrpos($end, ' ')) !== FALSE) {
             // Account for the added spaces.
             $q = max($q - 1, 0);
-            $s = min($s, drupal_strlen($end) - 1);
+            $s = min($s, strlen($end) - 1);
             $ranges[$q] = $p + $s;
             $length += $p + $s - $q;
             $included[$key] = $p + 1;
diff --git a/modules/search/search.test b/modules/search/search.test
index b1edad62..ca1dd24a 100644
--- a/modules/search/search.test
+++ b/modules/search/search.test
@@ -290,6 +290,20 @@ class SearchPageText extends DrupalWebTestCase {
     $this->drupalGet('search/node/' . $arg);
     $input = $this->xpath("//input[@id='edit-keys' and @value='{$arg}']");
     $this->assertFalse(empty($input), 'Search keys with a / are correctly set as the default value in the search box.');
+
+    // Test a search input exceeding the limit of AND/OR combinations to test
+    // the Denial-of-Service protection.
+    $limit = variable_get('search_and_or_limit', 7);
+    $keys = array();
+    for ($i = 0; $i < $limit + 1; $i++) {
+      $keys[] = $this->randomName(3);
+      if ($i % 2 == 0) {
+        $keys[] = 'OR';
+      }
+    }
+    $edit['keys'] = implode(' ', $keys);
+    $this->drupalPost('search/node', $edit, t('Search'));
+    $this->assertRaw(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => $limit)));
   }
 }
 
@@ -1585,6 +1599,12 @@ class SearchExcerptTestCase extends DrupalUnitTestCase {
     $result = preg_replace('| +|', ' ', search_excerpt('nothing', $entities));
     $this->assertFalse(strpos($result, '&'), 'Entities are not present in excerpt');
     $this->assertTrue(strpos($result, 'í') > 0, 'Entities are converted in excerpt');
+
+    // The node body that will produce this rendered $text is:
+    // 123456789 HTMLTest +123456789+&lsquo;  +&lsquo;  +&lsquo;  +&lsquo;  +12345678  &nbsp;&nbsp;  +&lsquo;  +&lsquo;  +&lsquo;   &lsquo;
+    $text = "<div class=\"field field-name-body field-type-text-with-summary field-label-hidden\"><div class=\"field-items\"><div class=\"field-item even\" property=\"content:encoded\"><p>123456789 HTMLTest +123456789+‘  +‘  +‘  +‘  +12345678      +‘  +‘  +‘   ‘</p>\n</div></div></div> ";
+    $result = search_excerpt('HTMLTest', $text);
+    $this->assertFalse(empty($result),  'Rendered Multi-byte HTML encodings are not corrupted in search excerpts');
   }
 
   /**
diff --git a/modules/search/tests/search_embedded_form.info b/modules/search/tests/search_embedded_form.info
index 64f1ca57..d2493afe 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/search/tests/search_extra_type.info b/modules/search/tests/search_extra_type.info
index 35ae708f..b181d54b 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/shortcut/shortcut.admin.js b/modules/shortcut/shortcut.admin.js
index 5e71e6fb..453a4023 100644
--- a/modules/shortcut/shortcut.admin.js
+++ b/modules/shortcut/shortcut.admin.js
@@ -33,7 +33,7 @@ Drupal.behaviors.shortcutDrag = {
       tableDrag.row.prototype.onSwap = function (swappedRow) {
         var disabledIndex = $(table).find('tr').index($(table).find('tr.shortcut-status-disabled')) - slots - 2,
           count = 0;
-        $(table).find('tr.shortcut-status-enabled').nextAll().filter(':not(.shortcut-slot-empty)').each(function(index) {
+        $(table).find('tr.shortcut-status-enabled').nextAll(':not(.shortcut-slot-empty)').each(function(index) {
           if (index < disabledIndex) {
             count++;
           }
@@ -41,7 +41,19 @@ Drupal.behaviors.shortcutDrag = {
         var total = slots - count;
         if (total == -1) {
           var disabled = $(table).find('tr.shortcut-status-disabled');
-          disabled.after(disabled.prevAll().filter(':not(.shortcut-slot-empty)').get(0));
+          // To maintain the shortcut links limit, we need to move the last
+          // element from the enabled section to the disabled section.
+          var changedRow = disabled.prevAll(':not(.shortcut-slot-empty)').not($(this.element)).get(0);
+          disabled.after(changedRow);
+          if ($(changedRow).hasClass('draggable')) {
+            // The dropped element will automatically be marked as changed by
+            // the tableDrag system. However, the row that swapped with it
+            // has moved to the "disabled" section, so we need to force its
+            // status to be disabled and mark it also as changed.
+            var changedRowObject = new tableDrag.row(changedRow, 'mouse', self.indentEnabled, self.maxDepth, true);
+            changedRowObject.markChanged();
+            rowStatusChange(changedRowObject);
+          }
         }
         else if (total != visibleLength) {
           if (total > visibleLength) {
@@ -59,14 +71,18 @@ Drupal.behaviors.shortcutDrag = {
 
       // Add a handler so when a row is dropped, update fields dropped into new regions.
       tableDrag.onDrop = function () {
+        rowStatusChange(this.rowObject);
+        return true;
+      };
+
+      function rowStatusChange(rowObject) {
         // Use "status-message" row instead of "status" row because
         // "status-{status_name}-message" is less prone to regexp match errors.
-        var statusRow = $(this.rowObject.element).prevAll('tr.shortcut-status').get(0);
+        var statusRow = $(rowObject.element).prevAll('tr.shortcut-status').get(0);
         var statusName = statusRow.className.replace(/([^ ]+[ ]+)*shortcut-status-([^ ]+)([ ]+[^ ]+)*/, '$2');
-        var statusField = $('select.shortcut-status-select', this.rowObject.element);
+        var statusField = $('select.shortcut-status-select', rowObject.element);
         statusField.val(statusName);
-        return true;
-      };
+      }
 
       tableDrag.restripeTable = function () {
         // :even and :odd are reversed because jQuery counts from 0 and
diff --git a/modules/shortcut/shortcut.info b/modules/shortcut/shortcut.info
index 2dd64b90..94fb45e1 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index 04f66ec0..9095e22e 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -73,6 +73,18 @@ abstract class DrupalTestCase {
    */
   protected $skipClasses = array(__CLASS__ => TRUE);
 
+  /**
+   * Flag to indicate whether the test has been set up.
+   *
+   * The setUp() method isolates the test from the parent Drupal site by
+   * creating a random prefix for the database and setting up a clean file
+   * storage directory. The tearDown() method then cleans up this test
+   * environment. We must ensure that setUp() has been run. Otherwise,
+   * tearDown() will act on the parent Drupal site rather than the test
+   * environment, destroying live data.
+   */
+  protected $setup = FALSE;
+
   /**
    * Constructor for DrupalTestCase.
    *
@@ -127,7 +139,15 @@ abstract class DrupalTestCase {
     );
 
     // Store assertion for display after the test has completed.
-    Database::getConnection('default', 'simpletest_original_default')
+    try {
+      $connection = Database::getConnection('default', 'simpletest_original_default');
+    }
+    catch (DatabaseConnectionNotDefinedException $e) {
+      // If the test was not set up, the simpletest_original_default
+      // connection does not exist.
+      $connection = Database::getConnection('default', 'default');
+    }
+    $connection
       ->insert('simpletest')
       ->fields($assertion)
       ->execute();
@@ -474,14 +494,19 @@ abstract class DrupalTestCase {
         );
         $completion_check_id = DrupalTestCase::insertAssert($this->testId, $class, FALSE, t('The test did not complete due to a fatal error.'), 'Completion check', $caller);
         $this->setUp();
-        try {
-          $this->$method();
-          // Finish up.
+        if ($this->setup) {
+          try {
+            $this->$method();
+            // Finish up.
+          }
+          catch (Exception $e) {
+            $this->exceptionHandler($e);
+          }
+          $this->tearDown();
         }
-        catch (Exception $e) {
-          $this->exceptionHandler($e);
+        else {
+          $this->fail(t("The test cannot be executed because it has not been set up properly."));
         }
-        $this->tearDown();
         // Remove the completion check record.
         DrupalTestCase::deleteAssert($completion_check_id);
       }
@@ -691,6 +716,7 @@ class DrupalUnitTestCase extends DrupalTestCase {
       unset($module_list['locale']);
       module_list(TRUE, FALSE, FALSE, $module_list);
     }
+    $this->setup = TRUE;
   }
 
   protected function tearDown() {
@@ -1045,28 +1071,35 @@ class DrupalWebTestCase extends DrupalTestCase {
   }
 
   /**
-   * Create a user with a given set of permissions. The permissions correspond to the
-   * names given on the privileges page.
+   * Create a user with a given set of permissions.
    *
-   * @param $permissions
-   *   Array of permission names to assign to user.
-   * @return
+   * @param array $permissions
+   *   Array of permission names to assign to user. Note that the user always
+   *   has the default permissions derived from the "authenticated users" role.
+   *
+   * @return object|false
    *   A fully loaded user object with pass_raw property, or FALSE if account
    *   creation fails.
    */
-  protected function drupalCreateUser($permissions = array('access comments', 'access content', 'post comments', 'skip comment approval')) {
-    // Create a role with the given permission set.
-    if (!($rid = $this->drupalCreateRole($permissions))) {
-      return FALSE;
+  protected function drupalCreateUser(array $permissions = array()) {
+    // Create a role with the given permission set, if any.
+    $rid = FALSE;
+    if ($permissions) {
+      $rid = $this->drupalCreateRole($permissions);
+      if (!$rid) {
+        return FALSE;
+      }
     }
 
     // Create a user assigned to that role.
     $edit = array();
     $edit['name']   = $this->randomName();
     $edit['mail']   = $edit['name'] . '@example.com';
-    $edit['roles']  = array($rid => $rid);
     $edit['pass']   = user_password();
     $edit['status'] = 1;
+    if ($rid) {
+      $edit['roles'] = array($rid => $rid);
+    }
 
     $account = user_save(drupal_anonymous_user(), $edit);
 
@@ -1294,6 +1327,13 @@ class DrupalWebTestCase extends DrupalTestCase {
     $test_info['test_run_id'] = $this->databasePrefix;
     $test_info['in_child_site'] = FALSE;
 
+    // Preset the 'install_profile' system variable, so the first call into
+    // system_rebuild_module_data() (in drupal_install_system()) will register
+    // the test's profile as a module. Without this, the installation profile of
+    // the parent site (executing the test) is registered, and the test
+    // profile's hook_install() and other hook implementations are never invoked.
+    $conf['install_profile'] = $this->profile;
+
     include_once DRUPAL_ROOT . '/includes/install.inc';
     drupal_install_system();
 
@@ -1357,6 +1397,7 @@ class DrupalWebTestCase extends DrupalTestCase {
     variable_set('mail_system', array('default-system' => 'TestingMailSystem'));
 
     drupal_set_time_limit($this->timeLimit);
+    $this->setup = TRUE;
   }
 
   /**
@@ -1631,7 +1672,16 @@ class DrupalWebTestCase extends DrupalTestCase {
    *   An header.
    */
   protected function curlHeaderCallback($curlHandler, $header) {
-    $this->headers[] = $header;
+    // Header fields can be extended over multiple lines by preceding each
+    // extra line with at least one SP or HT. They should be joined on receive.
+    // Details are in RFC2616 section 4.
+    if ($header[0] == ' ' || $header[0] == "\t") {
+      // Normalize whitespace between chucks.
+      $this->headers[] = array_pop($this->headers) . ' ' . trim($header);
+    }
+    else {
+      $this->headers[] = $header;
+    }
 
     // Errors are being sent via X-Drupal-Assertion-* headers,
     // generated by _drupal_log_error() in the exact form required
@@ -3069,8 +3119,21 @@ class DrupalWebTestCase extends DrupalTestCase {
    * @return
    *   TRUE on pass, FALSE on fail.
    */
-  protected function assertFieldByName($name, $value = '', $message = '') {
-    return $this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value, $message ? $message : t('Found field by name @name', array('@name' => $name)), t('Browser'));
+  protected function assertFieldByName($name, $value = NULL, $message = NULL) {
+    if (!isset($message)) {
+      if (!isset($value)) {
+        $message = t('Found field with name @name', array(
+          '@name' => var_export($name, TRUE),
+        ));
+      }
+      else {
+        $message = t('Found field with name @name and value @value', array(
+          '@name' => var_export($name, TRUE),
+          '@value' => var_export($value, TRUE),
+        ));
+      }
+    }
+    return $this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value, $message, t('Browser'));
   }
 
   /**
diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info
index 0109c99b..ad3c5b39 100644
--- a/modules/simpletest/simpletest.info
+++ b/modules/simpletest/simpletest.info
@@ -49,8 +49,8 @@ files[] = tests/upgrade/upgrade.translatable.test
 files[] = tests/upgrade/upgrade.upload.test
 files[] = tests/upgrade/upgrade.user.test
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module
index b820f530..980bc146 100644
--- a/modules/simpletest/simpletest.module
+++ b/modules/simpletest/simpletest.module
@@ -504,3 +504,16 @@ function simpletest_clean_results_table($test_id = NULL) {
   }
   return 0;
 }
+
+/**
+ * Implements hook_mail_alter().
+ *
+ * Aborts sending of messages with ID 'simpletest_cancel_test'.
+ *
+ * @see MailTestCase::testCancelMessage()
+ */
+function simpletest_mail_alter(&$message) {
+  if ($message['id'] == 'simpletest_cancel_test') {
+    $message['send'] = FALSE;
+  }
+}
diff --git a/modules/simpletest/simpletest.pages.inc b/modules/simpletest/simpletest.pages.inc
index 696d1471..d1a7e4ad 100644
--- a/modules/simpletest/simpletest.pages.inc
+++ b/modules/simpletest/simpletest.pages.inc
@@ -254,7 +254,7 @@ function simpletest_result_form($form, &$form_state, $test_id) {
       $row = array();
       $row[] = $assertion->message;
       $row[] = $assertion->message_group;
-      $row[] = basename($assertion->file);
+      $row[] = drupal_basename($assertion->file);
       $row[] = $assertion->line;
       $row[] = $assertion->function;
       $row[] = simpletest_result_status_image($assertion->status);
diff --git a/modules/simpletest/simpletest.test b/modules/simpletest/simpletest.test
index e5b6042a..dbe2ec0f 100644
--- a/modules/simpletest/simpletest.test
+++ b/modules/simpletest/simpletest.test
@@ -20,10 +20,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
       'name' => 'SimpleTest functionality',
-      'description' => 'Test SimpleTest\'s web interface: check that the intended tests were
-                          run and ensure that test reports display the intended results. Also
-                          test SimpleTest\'s internal browser and API\'s both explicitly and
-                          implicitly.',
+      'description' => "Test SimpleTest's web interface: check that the intended tests were run and ensure that test reports display the intended results. Also test SimpleTest's internal browser and API's both explicitly and implicitly.",
       'group' => 'SimpleTest'
     );
   }
@@ -503,3 +500,70 @@ class SimpleTestMissingDependentModuleUnitTest extends DrupalUnitTestCase {
     $this->fail(t('Running test with missing required module.'));
   }
 }
+
+/**
+ * Tests a test case that does not run parent::setUp() in its setUp() method.
+ *
+ * If a test case does not call parent::setUp(), running
+ * DrupalTestCase::tearDown() would destroy the main site's database tables.
+ * Therefore, we ensure that tests which are not set up properly are skipped.
+ *
+ * @see DrupalTestCase
+ */
+class SimpleTestBrokenSetUp extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Broken SimpleTest method',
+      'description' => 'Tests a test case that does not call parent::setUp().',
+      'group' => 'SimpleTest'
+    );
+  }
+
+  function setUp() {
+    // If the test is being run from the main site, set up normally.
+    if (!drupal_valid_test_ua()) {
+      parent::setUp('simpletest');
+      // Create and log in user.
+      $admin_user = $this->drupalCreateUser(array('administer unit tests'));
+      $this->drupalLogin($admin_user);
+    }
+    // If the test is being run from within simpletest, set up the broken test.
+    else {
+      $this->pass(t('The test setUp() method has been run.'));
+      // Don't call parent::setUp(). This should trigger an error message.
+    }
+  }
+
+  function tearDown() {
+    // If the test is being run from the main site, tear down normally.
+    if (!drupal_valid_test_ua()) {
+      parent::tearDown();
+    }
+    else {
+      // If the test is being run from within simpletest, output a message.
+      $this->pass(t('The tearDown() method has run.'));
+    }
+  }
+
+  /**
+   * Runs this test case from within the simpletest child site.
+   */
+  function testBreakSetUp() {
+    // If the test is being run from the main site, run it again from the web
+    // interface within the simpletest child site.
+    if (!drupal_valid_test_ua()) {
+      $edit['SimpleTestBrokenSetUp'] = TRUE;
+      $this->drupalPost('admin/config/development/testing', $edit, t('Run tests'));
+
+      // Verify that the broken test and its tearDown() method are skipped.
+      $this->assertRaw(t('The test setUp() method has been run.'));
+      $this->assertRaw(t('The test cannot be executed because it has not been set up properly.'));
+      $this->assertNoRaw(t('The test method has run.'));
+      $this->assertNoRaw(t('The tearDown() method has run.'));
+    }
+    // If the test is being run from within simpletest, output a message.
+    else {
+      $this->pass(t('The test method has run.'));
+    }
+  }
+}
diff --git a/modules/simpletest/tests/actions_loop_test.info b/modules/simpletest/tests/actions_loop_test.info
index 65d16158..007ae749 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/ajax_forms_test.info b/modules/simpletest/tests/ajax_forms_test.info
index c0c499bc..aa2fa9b9 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/ajax_test.info b/modules/simpletest/tests/ajax_test.info
index 303eca6b..96d0a7c1 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/batch_test.info b/modules/simpletest/tests/batch_test.info
index 74ca478d..db4efe26 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index a643ff94..5650d8c0 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -524,7 +524,7 @@ class CommonSizeTestCase extends DrupalUnitTestCase {
 /**
  * Test drupal_explode_tags() and drupal_implode_tags().
  */
-class DrupalTagsHandlingTestCase extends DrupalWebTestCase {
+class DrupalTagsHandlingTestCase extends DrupalUnitTestCase {
   var $validTags = array(
     'Drupal' => 'Drupal',
     'Drupal with some spaces' => 'Drupal with some spaces',
@@ -1747,6 +1747,37 @@ class DrupalRenderTestCase extends DrupalWebTestCase {
       '@type' => var_export($element['#type'], TRUE),
     )));
   }
+
+  /**
+   * Tests caching of an empty render item.
+   */
+  function testDrupalRenderCache() {
+    // Force a request via GET.
+    $request_method = $_SERVER['REQUEST_METHOD'];
+    $_SERVER['REQUEST_METHOD'] = 'GET';
+    // Create an empty element.
+    $test_element = array(
+      '#cache' => array(
+        'cid' => 'render_cache_test',
+      ),
+      '#markup' => '',
+    );
+
+    // Render the element and confirm that it goes through the rendering
+    // process (which will set $element['#printed']).
+    $element = $test_element;
+    drupal_render($element);
+    $this->assertTrue(isset($element['#printed']), t('No cache hit'));
+
+    // Render the element again and confirm that it is retrieved from the cache
+    // instead (so $element['#printed'] will not be set).
+    $element = $test_element;
+    drupal_render($element);
+    $this->assertFalse(isset($element['#printed']), t('Cache hit'));
+
+    // Restore the previous request method.
+    $_SERVER['REQUEST_METHOD'] = $request_method;
+  }
 }
 
 /**
@@ -2072,7 +2103,7 @@ class DrupalErrorCollectionUnitTest extends DrupalWebTestCase {
   function assertError($error, $group, $function, $file, $message = NULL) {
     $this->assertEqual($error['group'], $group, t("Group was %group", array('%group' => $group)));
     $this->assertEqual($error['caller']['function'], $function, t("Function was %function", array('%function' => $function)));
-    $this->assertEqual(basename($error['caller']['file']), $file, t("File was %file", array('%file' => $file)));
+    $this->assertEqual(drupal_basename($error['caller']['file']), $file, t("File was %file", array('%file' => $file)));
     if (isset($message)) {
       $this->assertEqual($error['message'], $message, t("Message was %message", array('%message' => $message)));
     }
@@ -2082,7 +2113,7 @@ class DrupalErrorCollectionUnitTest extends DrupalWebTestCase {
 /**
  * Test the drupal_parse_info_file() API function.
  */
-class ParseInfoFilesTestCase extends DrupalWebTestCase {
+class ParseInfoFilesTestCase extends DrupalUnitTestCase {
   public static function getInfo() {
     return array(
       'name' => 'Parsing .info files',
@@ -2341,8 +2372,10 @@ class DrupalJSONTest extends DrupalUnitTestCase {
       $str .= chr($i);
     }
     // Characters that must be escaped.
-    $html_unsafe = array('<', '>', '&');
-    $html_unsafe_escaped = array('\u003c', '\u003e', '\u0026');
+    // We check for unescaped " separately.
+    $html_unsafe = array('<', '>', '\'', '&');
+    // The following are the encoded forms of: < > ' & "
+    $html_unsafe_escaped = array('\u003C', '\u003E', '\u0027', '\u0026', '\u0022');
 
     // Verify there aren't character encoding problems with the source string.
     $this->assertIdentical(strlen($str), 128, t('A string with the full ASCII table has the correct length.'));
@@ -2354,6 +2387,11 @@ class DrupalJSONTest extends DrupalUnitTestCase {
     $json = drupal_json_encode($str);
     $this->assertTrue(strlen($json) > strlen($str), t('A JSON encoded string is larger than the source string.'));
 
+    // The first and last characters should be ", and no others.
+    $this->assertTrue($json[0] == '"', t('A JSON encoded string begins with ".'));
+    $this->assertTrue($json[strlen($json) - 1] == '"', t('A JSON encoded string ends with ".'));
+    $this->assertTrue(substr_count($json, '"') == 2, t('A JSON encoded string contains exactly two ".'));
+
     // Verify that encoding/decoding is reversible.
     $json_decoded = drupal_json_decode($json);
     $this->assertIdentical($str, $json_decoded, t('Encoding a string to JSON and decoding back results in the original string.'));
diff --git a/modules/simpletest/tests/common_test.info b/modules/simpletest/tests/common_test.info
index 665ee019..fa1feb89 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/common_test_cron_helper.info b/modules/simpletest/tests/common_test_cron_helper.info
index 67a0c731..48441b21 100644
--- a/modules/simpletest/tests/common_test_cron_helper.info
+++ b/modules/simpletest/tests/common_test_cron_helper.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/database_test.info b/modules/simpletest/tests/database_test.info
index b9a35895..7e1a3c12 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index 87d386aa..7b15cf3f 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -2062,6 +2062,16 @@ class DatabaseSelectComplexTestCase extends DatabaseTestCase {
     $this->assertEqual($record->$age_field, 27, t('Correct data retrieved.'));
   }
 
+  function testHavingCountQuery() {
+    $query = db_select('test')
+      ->extend('PagerDefault')
+      ->having('age + 1 > 0');
+    $query->addField('test', 'age');
+    $query->addExpression('age + 1');
+    $count = count($query->execute()->fetchCol());
+    $this->assertEqual($count, 4, t('Counted the correct number of records.'));
+  }
+
   /**
    * Test that countQuery properly removes 'all_fields' statements and
    * ordering clauses.
@@ -3426,35 +3436,89 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
    */
   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((string) $e);
-    }
+    $transaction = db_transaction();
+    $this->insertRow('row');
+    $this->executeDDLStatement();
+    unset($transaction);
+    $this->assertRowPresent('row');
 
-    // If we rollback the transaction, an exception might be thrown.
-    try {
-      $this->transactionOuterLayer('E', TRUE, TRUE);
+    // Even in different order.
+    $this->cleanUp();
+    $transaction = db_transaction();
+    $this->executeDDLStatement();
+    $this->insertRow('row');
+    unset($transaction);
+    $this->assertRowPresent('row');
+
+    // Even with stacking.
+    $this->cleanUp();
+    $transaction = db_transaction();
+    $transaction2 = db_transaction();
+    $this->executeDDLStatement();
+    unset($transaction2);
+    $transaction3 = db_transaction();
+    $this->insertRow('row');
+    unset($transaction3);
+    unset($transaction);
+    $this->assertRowPresent('row');
+
+    // A transaction after a DDL statement should still work the same.
+    $this->cleanUp();
+    $transaction = db_transaction();
+    $transaction2 = db_transaction();
+    $this->executeDDLStatement();
+    unset($transaction2);
+    $transaction3 = db_transaction();
+    $this->insertRow('row');
+    $transaction3->rollback();
+    unset($transaction3);
+    unset($transaction);
+    $this->assertRowAbsent('row');
+
+    // The behavior of a rollback depends on the type of database server.
+    if (Database::getConnection()->supportsTransactionalDDL()) {
+      // For database servers that support transactional DDL, a rollback
+      // of a transaction including DDL statements should be possible.
+      $this->cleanUp();
+      $transaction = db_transaction();
+      $this->insertRow('row');
+      $this->executeDDLStatement();
+      $transaction->rollback();
+      unset($transaction);
+      $this->assertRowAbsent('row');
 
-      // 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.'));
+      // Including with stacking.
+      $this->cleanUp();
+      $transaction = db_transaction();
+      $transaction2 = db_transaction();
+      $this->executeDDLStatement();
+      unset($transaction2);
+      $transaction3 = db_transaction();
+      $this->insertRow('row');
+      unset($transaction3);
+      $transaction->rollback();
+      unset($transaction);
+      $this->assertRowAbsent('row');
     }
-    catch (Exception $e) {
-      // An exception also lets the test pass.
-      $this->assertTrue(true, t('Exception thrown on rollback after a DDL statement was executed.'));
+    else {
+      // For database servers that do not support transactional DDL,
+      // the DDL statement should commit the transaction stack.
+      $this->cleanUp();
+      $transaction = db_transaction();
+      $this->insertRow('row');
+      $this->executeDDLStatement();
+      // Rollback the outer transaction.
+      try {
+        $transaction->rollback();
+        unset($transaction);
+        // @TODO: an exception should be triggered here, but is not, because
+        // "ROLLBACK" fails silently in MySQL if there is no transaction active.
+        // $this->fail(t('Rolling back a transaction containing DDL should fail.'));
+      }
+      catch (DatabaseTransactionNoActiveException $e) {
+        $this->pass(t('Rolling back a transaction containing DDL should fail.'));
+      }
+      $this->assertRowPresent('row');
     }
   }
 
@@ -3469,6 +3533,24 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
       ->execute();
   }
 
+  /**
+   * Execute a DDL statement.
+   */
+  protected function executeDDLStatement() {
+    static $count = 0;
+    $table = array(
+      'fields' => array(
+        'id' => array(
+          'type' => 'serial',
+          'unsigned' => TRUE,
+          'not null' => TRUE,
+        ),
+      ),
+      'primary key' => array('id'),
+    );
+    db_create_table('database_test_' . ++$count, $table);
+  }
+
   /**
    * Start over for a new test.
    */
@@ -3513,8 +3595,8 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
    * Test transaction stacking and commit / rollback.
    */
   function testTransactionStacking() {
-    // This test won't work right if transactions are supported.
-    if (Database::getConnection()->supportsTransactions()) {
+    // This test won't work right if transactions are not supported.
+    if (!Database::getConnection()->supportsTransactions()) {
       return;
     }
 
@@ -3593,26 +3675,33 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
     $this->insertRow('outer');
     $transaction2 = db_transaction();
     $this->insertRow('inner');
+    $transaction3 = db_transaction();
+    $this->insertRow('inner2');
     // Rollback the outer transaction.
     try {
       $transaction->rollback();
       unset($transaction);
       $this->fail(t('Rolling back the outer transaction while the inner transaction is active resulted in an exception.'));
     }
-    catch (Exception $e) {
+    catch (DatabaseTransactionOutOfOrderException $e) {
       $this->pass(t('Rolling back the outer transaction while the inner transaction is active resulted in an exception.'));
     }
     $this->assertFalse($database->inTransaction(), t('No more in a transaction after rolling back the outer transaction'));
-    // Try to commit the inner transaction.
+    // Try to commit one inner transaction.
+    unset($transaction3);
+    $this->pass(t('Trying to commit an inner transaction resulted in an exception.'));
+    // Try to rollback one inner transaction.
     try {
+      $transaction->rollback();
       unset($transaction2);
-      $this->fail(t('Trying to commit the inner transaction resulted in an exception.'));
+      $this->fail(t('Trying to commit an inner transaction resulted in an exception.'));
     }
-    catch (Exception $e) {
-      $this->pass(t('Trying to commit the inner transaction resulted in an exception.'));
+    catch (DatabaseTransactionNoActiveException $e) {
+      $this->pass(t('Trying to commit an inner transaction resulted in an exception.'));
     }
     $this->assertRowAbsent('outer');
     $this->assertRowAbsent('inner');
+    $this->assertRowAbsent('inner2');
   }
 }
 
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 82b257c8..82e993aa 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
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 0ce3baae..01ad2979 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/entity_cache_test.info b/modules/simpletest/tests/entity_cache_test.info
index 47bd609a..d7e23251 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/entity_cache_test_dependency.info b/modules/simpletest/tests/entity_cache_test_dependency.info
index 94026d8b..af1ef755 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/entity_cache_test_dependency.module b/modules/simpletest/tests/entity_cache_test_dependency.module
index 73a11495..2d4b3be4 100644
--- a/modules/simpletest/tests/entity_cache_test_dependency.module
+++ b/modules/simpletest/tests/entity_cache_test_dependency.module
@@ -11,7 +11,7 @@
 function entity_cache_test_dependency_entity_info() {
   return array(
     'entity_cache_test' => array(
-      'label' => 'Entity Cache Test',
+      'label' => variable_get('entity_cache_test_label', 'Entity Cache Test'),
     ),
   );
 }
diff --git a/modules/simpletest/tests/entity_crud_hook_test.info b/modules/simpletest/tests/entity_crud_hook_test.info
index 0ed70ecf..c23ac61b 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/entity_query.test b/modules/simpletest/tests/entity_query.test
index ec951f8e..d5e5524f 100644
--- a/modules/simpletest/tests/entity_query.test
+++ b/modules/simpletest/tests/entity_query.test
@@ -22,10 +22,10 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
   function setUp() {
     parent::setUp(array('field_test'));
 
-    field_attach_create_bundle('test_entity_bundle_key', 'bundle1');
-    field_attach_create_bundle('test_entity_bundle_key', 'bundle2');
-    field_attach_create_bundle('test_entity', 'test_bundles');
-    field_attach_create_bundle('test_entity_bundle', 'test_entity_bundle');
+    field_test_create_bundle('bundle1');
+    field_test_create_bundle('bundle2');
+    field_test_create_bundle('test_bundle');
+    field_test_create_bundle('test_entity_bundle');
 
     $instances = array();
     $this->fields = array();
@@ -1084,7 +1084,6 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
     $this->fields[0]['cardinality'] = 1;
     field_update_field($this->fields[0]);
     field_test_entity_info_translatable('test_entity', TRUE);
-    drupal_static_reset('field_available_languages');
 
     // Create more items with different languages.
     $entity = new stdClass();
@@ -1121,7 +1120,6 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
     $this->fields[0]['translatable'] = TRUE;
     field_update_field($this->fields[0]);
     field_test_entity_info_translatable('test_entity', TRUE);
-    drupal_static_reset('field_available_languages');
 
     // Create more items with different languages.
     $entity = new stdClass();
diff --git a/modules/simpletest/tests/error_test.info b/modules/simpletest/tests/error_test.info
index 64a9391c..39e5d237 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test
index 55e3b0aa..4c56bfcc 100644
--- a/modules/simpletest/tests/file.test
+++ b/modules/simpletest/tests/file.test
@@ -198,7 +198,9 @@ class FileTestCase extends DrupalWebTestCase {
    */
   function createFile($filepath = NULL, $contents = NULL, $scheme = NULL) {
     if (!isset($filepath)) {
-      $filepath = $this->randomName();
+      // Prefix with non-latin characters to ensure that all file-related
+      // tests work with international filenames.
+      $filepath = 'Файл для тестирования ' . $this->randomName();
     }
     if (!isset($scheme)) {
       $scheme = file_default_scheme();
@@ -214,7 +216,7 @@ class FileTestCase extends DrupalWebTestCase {
 
     $file = new stdClass();
     $file->uri = $filepath;
-    $file->filename = basename($file->uri);
+    $file->filename = drupal_basename($file->uri);
     $file->filemime = 'text/plain';
     $file->uid = 1;
     $file->timestamp = REQUEST_TIME;
@@ -372,11 +374,11 @@ class FileValidatorTest extends DrupalWebTestCase {
 
     $this->image = new stdClass();
     $this->image->uri = 'misc/druplicon.png';
-    $this->image->filename = basename($this->image->uri);
+    $this->image->filename = drupal_basename($this->image->uri);
 
     $this->non_image = new stdClass();
     $this->non_image->uri = 'misc/jquery.js';
-    $this->non_image->filename = basename($this->non_image->uri);
+    $this->non_image->filename = drupal_basename($this->non_image->uri);
   }
 
   /**
@@ -539,7 +541,7 @@ class FileUnmanagedSaveDataTest extends FileTestCase {
     // Provide a filename.
     $filepath = file_unmanaged_save_data($contents, 'public://asdf.txt', FILE_EXISTS_REPLACE);
     $this->assertTrue($filepath, t('Unnamed file saved correctly.'));
-    $this->assertEqual('asdf.txt', basename($filepath), t('File was named correctly.'));
+    $this->assertEqual('asdf.txt', drupal_basename($filepath), t('File was named correctly.'));
     $this->assertEqual($contents, file_get_contents($filepath), t('Contents of the file are correct.'));
     $this->assertFilePermissions($filepath, variable_get('file_chmod_file', 0664));
   }
@@ -666,7 +668,7 @@ class FileSaveUploadTest extends FileHookTestCase {
     $this->drupalPost('file-test/upload', $edit, t('Submit'));
     $this->assertResponse(200, t('Received a 200 response for posted test file.'));
     $this->assertRaw(t('You WIN!'));
-    $this->assertTrue(is_file('temporary://' . $dir . '/' . trim(basename($image3_realpath))));
+    $this->assertTrue(is_file('temporary://' . $dir . '/' . trim(drupal_basename($image3_realpath))));
 
     // Check that file_load_multiple() with no arguments returns FALSE.
     $this->assertFalse(file_load_multiple(), t('No files were loaded.'));
@@ -2202,7 +2204,7 @@ class FileSaveDataTest extends FileHookTestCase {
     $this->assertTrue($result, t('Unnamed file saved correctly.'));
 
     $this->assertEqual(file_default_scheme(), file_uri_scheme($result->uri), t("File was placed in Drupal's files directory."));
-    $this->assertEqual($result->filename, basename($result->uri), t("Filename was set to the file's basename."));
+    $this->assertEqual($result->filename, drupal_basename($result->uri), t("Filename was set to the file's basename."));
     $this->assertEqual($contents, file_get_contents($result->uri), t('Contents of the file are correct.'));
     $this->assertEqual($result->filemime, 'application/octet-stream', t('A MIME type was set.'));
     $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
@@ -2220,11 +2222,14 @@ class FileSaveDataTest extends FileHookTestCase {
   function testWithFilename() {
     $contents = $this->randomName(8);
 
-    $result = file_save_data($contents, 'public://' . 'asdf.txt');
+    // Using filename with non-latin characters.
+    $filename = 'Текстовый файл.txt';
+
+    $result = file_save_data($contents, 'public://' . $filename);
     $this->assertTrue($result, t('Unnamed file saved correctly.'));
 
     $this->assertEqual('public', file_uri_scheme($result->uri), t("File was placed in Drupal's files directory."));
-    $this->assertEqual('asdf.txt', basename($result->uri), t('File was named correctly.'));
+    $this->assertEqual($filename, drupal_basename($result->uri), t('File was named correctly.'));
     $this->assertEqual($contents, file_get_contents($result->uri), t('Contents of the file are correct.'));
     $this->assertEqual($result->filemime, 'text/plain', t('A MIME type was set.'));
     $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
@@ -2336,7 +2341,10 @@ class FileDownloadTest extends FileTestCase {
     // Test generating an URL to a created file.
     $file = $this->createFile();
     $url = file_create_url($file->uri);
-    $this->assertEqual($GLOBALS['base_url'] . '/' . file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath() . '/' . $file->filename, $url, t('Correctly generated a URL for a created file.'));
+    // URLs can't contain characters outside the ASCII set so $filename has to be
+    // encoded.
+    $filename = $GLOBALS['base_url'] . '/' . file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath() . '/' . rawurlencode($file->filename);
+    $this->assertEqual($filename, $url, t('Correctly generated a URL for a created file.'));
     $this->drupalHead($url);
     $this->assertResponse(200, t('Confirmed that the generated URL is correct by downloading the created file.'));
 
@@ -2356,16 +2364,20 @@ class FileDownloadTest extends FileTestCase {
     // Set file downloads to private so handler functions get called.
 
     // Create a file.
-    $file = $this->createFile(NULL, NULL, 'private');
+    $contents = $this->randomName(8);
+    $file = $this->createFile(NULL, $contents, 'private');
     $url  = file_create_url($file->uri);
 
     // Set file_test access header to allow the download.
     file_test_set_return('download', array('x-foo' => 'Bar'));
-    $this->drupalHead($url);
+    $this->drupalGet($url);
     $headers = $this->drupalGetHeaders();
-    $this->assertEqual($headers['x-foo'] , 'Bar', t('Found header set by file_test module on private download.'));
+    $this->assertEqual($headers['x-foo'], 'Bar', t('Found header set by file_test module on private download.'));
     $this->assertResponse(200, t('Correctly allowed access to a file when file_test provides headers.'));
 
+    // Test that the file transfered correctly.
+    $this->assertEqual($contents, $this->content, t('Contents of the file are correct.'));
+
     // Deny access to all downloads via a -1 header.
     file_test_set_return('download', -1);
     $this->drupalHead($url);
@@ -2602,7 +2614,7 @@ class FileMimeTypeTest extends DrupalWebTestCase {
    * Test mapping of mimetypes from filenames.
    */
   public function testFileMimeTypeDetection() {
-    $prefix = 'simpletest://';
+    $prefix = 'public://';
 
     $test_case = array(
       'test.jar' => 'application/java-archive',
diff --git a/modules/simpletest/tests/file_test.info b/modules/simpletest/tests/file_test.info
index 58baef30..996972c2 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/file_test.module b/modules/simpletest/tests/file_test.module
index b3c43e07..1b11316f 100644
--- a/modules/simpletest/tests/file_test.module
+++ b/modules/simpletest/tests/file_test.module
@@ -138,7 +138,7 @@ function _file_test_form_submit(&$form, &$form_state) {
 /**
  * Reset/initialize the history of calls to the file_* hooks.
  *
- * @see file_test_get_calls() 
+ * @see file_test_get_calls()
  * @see file_test_reset()
  */
 function file_test_reset() {
diff --git a/modules/simpletest/tests/filter_test.info b/modules/simpletest/tests/filter_test.info
index 65b4fa09..7ac51144 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test
index fe2c1bbf..13fdca20 100644
--- a/modules/simpletest/tests/form.test
+++ b/modules/simpletest/tests/form.test
@@ -588,9 +588,17 @@ class FormsElementsLabelsTestCase extends DrupalWebTestCase {
     $elements = $this->xpath('//input[@id="edit-form-checkboxes-test-third-checkbox"]/following-sibling::label[@for="edit-form-checkboxes-test-third-checkbox" and @class="option"]');
     $this->assertTrue(isset($elements[0]), t("Label follows field and label option class correct for regular checkboxes."));
 
+    // Make sure the label is rendered for checkboxes.
+    $elements = $this->xpath('//input[@id="edit-form-checkboxes-test-0"]/following-sibling::label[@for="edit-form-checkboxes-test-0" and @class="option"]');
+    $this->assertTrue(isset($elements[0]), t("Label 0 found checkbox."));
+
     $elements = $this->xpath('//input[@id="edit-form-radios-test-second-radio"]/following-sibling::label[@for="edit-form-radios-test-second-radio" and @class="option"]');
     $this->assertTrue(isset($elements[0]), t("Label follows field and label option class correct for regular radios."));
 
+    // Make sure the label is rendered for radios.
+    $elements = $this->xpath('//input[@id="edit-form-radios-test-0"]/following-sibling::label[@for="edit-form-radios-test-0" and @class="option"]');
+    $this->assertTrue(isset($elements[0]), t("Label 0 found radios."));
+
     // Exercise various defaults for checkboxes and modifications to ensure
     // appropriate override and correct behaviour.
     $elements = $this->xpath('//input[@id="edit-form-checkbox-test"]/following-sibling::label[@for="edit-form-checkbox-test" and @class="option"]');
diff --git a/modules/simpletest/tests/form_test.info b/modules/simpletest/tests/form_test.info
index 4c0b67e7..4df57559 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module
index 23aca244..0a748d2d 100644
--- a/modules/simpletest/tests/form_test.module
+++ b/modules/simpletest/tests/form_test.module
@@ -688,6 +688,7 @@ function form_label_test_form() {
       'first-checkbox' => t('First checkbox'),
       'second-checkbox' => t('Second checkbox'),
       'third-checkbox' => t('Third checkbox'),
+      '0' => t('0'),
     ),
   );
   $form['form_radios_test'] = array(
@@ -697,6 +698,7 @@ function form_label_test_form() {
       'first-radio' => t('First radio'),
       'second-radio' => t('Second radio'),
       'third-radio' => t('Third radio'),
+      '0' => t('0'),
     ),
     // Test #field_prefix and #field_suffix placement.
     '#field_prefix' => '<span id="form-test-radios-field-prefix">' . t('Radios #field_prefix element') . '</span>',
diff --git a/modules/simpletest/tests/image_test.info b/modules/simpletest/tests/image_test.info
index a939da87..046780b8 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/mail.test b/modules/simpletest/tests/mail.test
index a6c7b40e..09dcde60 100644
--- a/modules/simpletest/tests/mail.test
+++ b/modules/simpletest/tests/mail.test
@@ -22,7 +22,7 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
   }
 
   function setUp() {
-    parent::setUp();
+    parent::setUp(array('simpletest'));
 
     // Set MailTestCase (i.e. this class) as the SMTP library
     variable_set('mail_system', array('default-system' => 'MailTestCase'));
@@ -35,10 +35,28 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
     global $language;
 
     // Use MailTestCase for sending a message.
-    $message = drupal_mail('simpletest', 'mail_test', 'testing@drupal.org', $language);
+    $message = drupal_mail('simpletest', 'mail_test', 'testing@example.com', $language);
 
     // Assert whether the message was sent through the send function.
-    $this->assertEqual(self::$sent_message['to'], 'testing@drupal.org', t('Pluggable mail system is extendable.'));
+    $this->assertEqual(self::$sent_message['to'], 'testing@example.com', t('Pluggable mail system is extendable.'));
+  }
+
+  /**
+   * Test that message sending may be canceled.
+   *
+   * @see simpletest_mail_alter()
+   */
+  function testCancelMessage() {
+    global $language;
+
+    // Reset the class variable holding a copy of the last sent message.
+    self::$sent_message = NULL;
+
+    // Send a test message that simpletest_mail_alter should cancel.
+    $message = drupal_mail('simpletest', 'cancel_test', 'cancel@example.com', $language);
+
+    // Assert that the message was not actually sent.
+    $this->assertNull(self::$sent_message, 'Message was canceled.');
   }
 
   /**
diff --git a/modules/simpletest/tests/menu_test.info b/modules/simpletest/tests/menu_test.info
index 17bfba06..7f82eb20 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/module_test.info b/modules/simpletest/tests/module_test.info
index 21e27657..3345c927 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/requirements1_test.info b/modules/simpletest/tests/requirements1_test.info
index 1263643d..fca1c6e5 100644
--- a/modules/simpletest/tests/requirements1_test.info
+++ b/modules/simpletest/tests/requirements1_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/requirements2_test.info b/modules/simpletest/tests/requirements2_test.info
index b2c7b752..fce15e6e 100644
--- a/modules/simpletest/tests/requirements2_test.info
+++ b/modules/simpletest/tests/requirements2_test.info
@@ -7,8 +7,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/session_test.info b/modules/simpletest/tests/session_test.info
index 526498e6..0f0b60cf 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/system_dependencies_test.info b/modules/simpletest/tests/system_dependencies_test.info
index 1882fd70..771cc81a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info b/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info
index 20da4cd2..bab6df46 100644
--- a/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info
+++ b/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info
@@ -6,8 +6,8 @@ core = 7.x
 hidden = TRUE
 dependencies[] = system_incompatible_core_version_test
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/system_incompatible_core_version_test.info b/modules/simpletest/tests/system_incompatible_core_version_test.info
index 59465a91..11ad0318 100644
--- a/modules/simpletest/tests/system_incompatible_core_version_test.info
+++ b/modules/simpletest/tests/system_incompatible_core_version_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 5.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info b/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info
index 3dd555f6..1c71d712 100644
--- a/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info
+++ b/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info
@@ -7,8 +7,8 @@ hidden = TRUE
 ; system_incompatible_module_version_test declares version 1.0
 dependencies[] = system_incompatible_module_version_test (>2.0)
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/system_incompatible_module_version_test.info b/modules/simpletest/tests/system_incompatible_module_version_test.info
index aeac5673..19cdca64 100644
--- a/modules/simpletest/tests/system_incompatible_module_version_test.info
+++ b/modules/simpletest/tests/system_incompatible_module_version_test.info
@@ -5,8 +5,8 @@ version = 1.0
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/system_test.info b/modules/simpletest/tests/system_test.info
index e809e78c..9fbf2ac3 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/taxonomy_test.info b/modules/simpletest/tests/taxonomy_test.info
index e93cbf5f..5f0db291 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/theme.test b/modules/simpletest/tests/theme.test
index ea0f257d..af114112 100644
--- a/modules/simpletest/tests/theme.test
+++ b/modules/simpletest/tests/theme.test
@@ -9,6 +9,8 @@
  * Unit tests for the Theme API.
  */
 class ThemeUnitTest extends DrupalWebTestCase {
+  protected $profile = 'testing';
+
   public static function getInfo() {
     return array(
       'name' => 'Theme API',
@@ -380,3 +382,54 @@ class ThemeHtmlTag extends DrupalUnitTestCase {
     $this->assertEqual('<title>title test</title>'."\n", theme_html_tag($tag), t('Test title tag generation.'));
   }
 }
+
+/**
+ * Tests for the ThemeRegistry class.
+ */
+class ThemeRegistryTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'ThemeRegistry',
+      'description' => 'Tests the behavior of the ThemeRegistry class',
+      'group' => 'Theme',
+    );
+  }
+  function setUp() {
+    parent::setUp('theme_test');
+  }
+
+  /**
+   * Tests the behavior of the theme registry class.
+   */
+  function testRaceCondition() {
+    $_SERVER['REQUEST_METHOD'] = 'GET';
+    $cid = 'test_theme_registry';
+
+    // Directly instantiate the theme registry, this will cause a base cache
+    // entry to be written in __construct().
+    $registry = new ThemeRegistry($cid, 'cache');
+
+    $this->assertTrue(cache_get($cid), 'Cache entry was created.');
+
+    // Trigger a cache miss for an offset.
+    $this->assertTrue($registry['theme_test_template_test'], 'Offset was returned correctly from the theme registry.');
+    // This will cause the ThemeRegistry class to write an updated version of
+    // the cache entry when it is destroyed, usually at the end of the request.
+    // Before that happens, manually delete the cache entry we created earlier
+    // so that the new entry is written from scratch.
+    cache_clear_all($cid, 'cache');
+
+    // Destroy the class so that it triggers a cache write for the offset.
+    unset($registry);
+
+    $this->assertTrue(cache_get($cid), 'Cache entry was created.');
+
+    // Create a new instance of the class. Confirm that both the offset
+    // requested previously, and one that has not yet been requested are both
+    // available.
+    $registry = new ThemeRegistry($cid, 'cache');
+
+    $this->assertTrue($registry['theme_test_template_test'], 'Offset was returned correctly from the theme registry');
+    $this->assertTrue($registry['theme_test_template_test_2'], 'Offset was returned correctly from the theme registry');
+  }
+}
diff --git a/modules/simpletest/tests/theme_test.info b/modules/simpletest/tests/theme_test.info
index ef45abe9..8e24039a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/theme_test.module b/modules/simpletest/tests/theme_test.module
index 160d192d..48e2e83c 100644
--- a/modules/simpletest/tests/theme_test.module
+++ b/modules/simpletest/tests/theme_test.module
@@ -1,5 +1,27 @@
 <?php
 
+/**
+ * Implements hook_theme().
+ */
+function theme_test_theme($existing, $type, $theme, $path) {
+  $items['theme_test_template_test'] = array(
+    'template' => 'theme_test.template_test',
+  );
+  $items['theme_test_template_test_2'] = array(
+    'template' => 'theme_test.template_test',
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_system_theme_info().
+ */
+function theme_test_system_theme_info() {
+  $themes['test_theme'] = drupal_get_path('module', 'theme_test') . '/themes/test_theme/test_theme.info';
+  return $themes;
+}
+
 /**
  * Implements hook_menu().
  */
diff --git a/modules/simpletest/tests/theme_test.template_test.tpl.php b/modules/simpletest/tests/theme_test.template_test.tpl.php
new file mode 100644
index 00000000..cde8faad
--- /dev/null
+++ b/modules/simpletest/tests/theme_test.template_test.tpl.php
@@ -0,0 +1,2 @@
+<!-- Output for Theme API test -->
+Fail: Template not overridden.
diff --git a/themes/tests/test_theme/template.php b/modules/simpletest/tests/themes/test_theme/template.php
similarity index 100%
rename from themes/tests/test_theme/template.php
rename to modules/simpletest/tests/themes/test_theme/template.php
diff --git a/themes/tests/test_theme/test_theme.info b/modules/simpletest/tests/themes/test_theme/test_theme.info
similarity index 89%
rename from themes/tests/test_theme/test_theme.info
rename to modules/simpletest/tests/themes/test_theme/test_theme.info
index 0adb8457..4c5c5151 100644
--- a/themes/tests/test_theme/test_theme.info
+++ b/modules/simpletest/tests/themes/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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/unicode.test b/modules/simpletest/tests/unicode.test
index 47a4938f..cf7991b6 100644
--- a/modules/simpletest/tests/unicode.test
+++ b/modules/simpletest/tests/unicode.test
@@ -8,7 +8,7 @@
 /**
  * Test unicode handling features implemented in unicode.inc.
  */
-class UnicodeUnitTest extends DrupalWebTestCase {
+class UnicodeUnitTest extends DrupalUnitTestCase {
 
   /**
    * Whether to run the extended version of the tests (including non latin1 characters).
diff --git a/modules/simpletest/tests/update_script_test.info b/modules/simpletest/tests/update_script_test.info
index 5dfa1409..59f1c983 100644
--- a/modules/simpletest/tests/update_script_test.info
+++ b/modules/simpletest/tests/update_script_test.info
@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2011-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/update_test_1.info b/modules/simpletest/tests/update_test_1.info
index 8e36bd33..23f6ef1f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/update_test_2.info b/modules/simpletest/tests/update_test_2.info
index 8e36bd33..23f6ef1f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/update_test_3.info b/modules/simpletest/tests/update_test_3.info
index 8e36bd33..23f6ef1f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/upgrade/drupal-6.node_type_broken.database.php b/modules/simpletest/tests/upgrade/drupal-6.node_type_broken.database.php
new file mode 100644
index 00000000..1dc1946b
--- /dev/null
+++ b/modules/simpletest/tests/upgrade/drupal-6.node_type_broken.database.php
@@ -0,0 +1,34 @@
+<?php
+db_insert('comments')->fields(array(
+  'cid',
+  'pid',
+  'nid',
+  'uid',
+  'subject',
+  'comment',
+  'hostname',
+  'timestamp',
+  'status',
+  'format',
+  'thread',
+  'name',
+  'mail',
+  'homepage',
+))
+->values(array(
+  'cid' => 1,
+  'pid' => 0,
+  'nid' => 37,
+  'uid' => 3,
+  'subject' => 'Comment title 1',
+  'comment' => 'Comment body 1 - Comment body 1 - Comment body 1 - Comment body 1 - Comment body 1 - Comment body 1 - Comment body 1 - Comment body 1',
+  'hostname' => '127.0.0.1',
+  'timestamp' => 1008617630,
+  'status' => 0,
+  'format' => 1,
+  'thread' => '01/',
+  'name' => NULL,
+  'mail' => NULL,
+  'homepage' => '',
+))
+->execute();
diff --git a/modules/simpletest/tests/upgrade/upgrade.node.test b/modules/simpletest/tests/upgrade/upgrade.node.test
index cd44790c..b49a40b0 100644
--- a/modules/simpletest/tests/upgrade/upgrade.node.test
+++ b/modules/simpletest/tests/upgrade/upgrade.node.test
@@ -50,6 +50,38 @@ class NodeBodyUpgradePathTestCase extends UpgradePathTestCase {
   }
 }
 
+/**
+ * Tests the upgrade path for node disabled node types.
+ *
+ * Load a filled installation of Drupal 6 and run the upgrade process on it.
+ */
+class DisabledNodeTypeTestCase extends UpgradePathTestCase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'Disabled node type upgrade path',
+      'description'  => 'Disabled node type upgrade path tests.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.filled.database.php',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.node_type_broken.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Tests a successful upgrade.
+   */
+  public function testDisabledNodeTypeUpgrade() {
+    $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
+    $this->assertTrue(field_info_instance('comment', 'comment_body', 'comment_node_broken'), 'Comment body field instance was created for comments attached to the disabled broken node type');
+  }
+}
+
 /**
  * Upgrade test for node type poll.
  *
diff --git a/modules/simpletest/tests/upgrade/upgrade.test b/modules/simpletest/tests/upgrade/upgrade.test
index 01e1806c..2602b09a 100644
--- a/modules/simpletest/tests/upgrade/upgrade.test
+++ b/modules/simpletest/tests/upgrade/upgrade.test
@@ -171,6 +171,7 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
     $this->variable_set('site_mail', 'simpletest@example.com');
 
     drupal_set_time_limit($this->timeLimit);
+    $this->setup = TRUE;
   }
 
   /**
diff --git a/modules/simpletest/tests/url_alter_test.info b/modules/simpletest/tests/url_alter_test.info
index b266c3b4..5ae57a77 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/simpletest/tests/xmlrpc_test.info b/modules/simpletest/tests/xmlrpc_test.info
index 96c02f1c..9a5093bf 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/statistics/statistics.info b/modules/statistics/statistics.info
index 60841f6a..f7205015 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/syslog/syslog.info b/modules/syslog/syslog.info
index 8a97ef00..2e8384b4 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/syslog/syslog.module b/modules/syslog/syslog.module
index c4ee3825..7c7bf40b 100644
--- a/modules/syslog/syslog.module
+++ b/modules/syslog/syslog.module
@@ -6,6 +6,15 @@
  */
 
 if (defined('LOG_LOCAL0')) {
+  /**
+   * Sets the proper logging facility.
+   *
+   * Note that LOG_LOCAL0 through LOG_LOCAL7 are not available on Windows, so we
+   * check for availability. If LOG_LOCAL0 is defined by the PHP environment, we
+   * set that as the default; if not, we use LOG_USER.
+   *
+   * @see http://php.net/manual/function.syslog.php
+   */
   define('DEFAULT_SYSLOG_FACILITY', LOG_LOCAL0);
 }
 else {
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index 63685906..7ed232a5 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -622,7 +622,7 @@ function system_theme_settings_validate($form, &$form_state) {
     }
     else {
       // File upload failed.
-      form_set_error('logo_upload', t('The favicon could not be uploaded.'));
+      form_set_error('favicon_upload', t('The favicon could not be uploaded.'));
     }
   }
 
diff --git a/modules/system/system.api.php b/modules/system/system.api.php
index f241eea7..cb67268c 100644
--- a/modules/system/system.api.php
+++ b/modules/system/system.api.php
@@ -1019,7 +1019,11 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
  * @endcode
  * This 'abc' object will then be passed into the callback functions defined
  * for the menu item, such as the page callback function mymodule_abc_edit()
- * to replace the integer 1 in the argument array.
+ * to replace the integer 1 in the argument array. Note that a load function
+ * should return FALSE when it is unable to provide a loadable object. For 
+ * example, the node_load() function for the 'node/%node/edit' menu item will
+ * return FALSE for the path 'node/999/edit' if a node with a node ID of 999
+ * does not exist. The menu routing system will return a 404 error in this case.
  *
  * You can also define a %wildcard_to_arg() function (for the example menu
  * entry above this would be 'mymodule_abc_to_arg()'). The _to_arg() function
@@ -1579,12 +1583,21 @@ function hook_page_alter(&$page) {
  * One popular use of this hook is to add form elements to the node form. When
  * altering a node form, the node object can be accessed at $form['#node'].
  *
- * Note that instead of hook_form_alter(), which is called for all forms, you
- * can also use hook_form_FORM_ID_alter() to alter a specific form. For each
- * module (in system weight order) the general form alter hook implementation
- * is invoked first, then the form ID specific alter implementation is called.
- * After all module hook implementations are invoked, the hook_form_alter()
- * implementations from themes are invoked in the same manner.
+ * In addition to hook_form_alter(), which is called for all forms, there are
+ * two more specific form hooks available. The first,
+ * hook_form_BASE_FORM_ID_alter(), allows targeting of a form/forms via a base
+ * form (if one exists). The second, hook_form_FORM_ID_alter(), can be used to
+ * target a specific form directly.
+ *
+ * The call order is as follows: all existing form alter functions are called
+ * for module A, then all for module B, etc., followed by all for any base
+ * theme(s), and finally for the theme itself. The module order is determined
+ * by system weight, then by module name.
+ *
+ * Within each module, form alter hooks are called in the following order:
+ * first, hook_form_alter(); second, hook_form_BASE_FORM_ID_alter(); third,
+ * hook_form_FORM_ID_alter(). So, for each module, the more general hooks are
+ * called first followed by the more specific.
  *
  * @param $form
  *   Nested array of form elements that comprise the form.
@@ -1596,6 +1609,7 @@ function hook_page_alter(&$page) {
  *   String representing the name of the form itself. Typically this is the
  *   name of the function that generated the form.
  *
+ * @see hook_form_BASE_FORM_ID_alter()
  * @see hook_form_FORM_ID_alter()
  */
 function hook_form_alter(&$form, &$form_state, $form_id) {
@@ -1616,6 +1630,10 @@ function hook_form_alter(&$form, &$form_state, $form_id) {
  * rather than implementing hook_form_alter() and checking the form ID, or
  * using long switch statements to alter multiple forms.
  *
+ * Form alter hooks are called in the following order: hook_form_alter(),
+ * hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See
+ * hook_form_alter() for more details.
+ *
  * @param $form
  *   Nested array of form elements that comprise the form.
  * @param $form_state
@@ -1627,6 +1645,7 @@ function hook_form_alter(&$form, &$form_state, $form_id) {
  *   name of the function that generated the form.
  *
  * @see hook_form_alter()
+ * @see hook_form_BASE_FORM_ID_alter()
  * @see drupal_prepare_form()
  */
 function hook_form_FORM_ID_alter(&$form, &$form_state, $form_id) {
@@ -1643,17 +1662,27 @@ function hook_form_FORM_ID_alter(&$form, &$form_state, $form_id) {
 }
 
 /**
- * Provide a form-specific alteration for shared forms.
+ * Provide a form-specific alteration for shared ('base') forms.
+ *
+ * By default, when drupal_get_form() is called, Drupal looks for a function
+ * with the same name as the form ID, and uses that function to build the form.
+ * In contrast, base forms allow multiple form IDs to be mapped to a single base
+ * (also called 'factory') form function.
  *
  * Modules can implement hook_form_BASE_FORM_ID_alter() to modify a specific
- * form belonging to multiple form_ids, rather than implementing
- * hook_form_alter() and checking for conditions that would identify the
- * shared form constructor.
+ * base form, rather than implementing hook_form_alter() and checking for
+ * conditions that would identify the shared form constructor.
+ *
+ * To identify the base form ID for a particular form (or to determine whether
+ * one exists) check the $form_state. The base form ID is stored under
+ * $form_state['build_info']['base_form_id'].
  *
- * Examples for such forms are node_form() or comment_form().
+ * See hook_forms() for more information on how to implement base forms in
+ * Drupal.
  *
- * Note that this hook fires after hook_form_FORM_ID_alter() and before
- * hook_form_alter().
+ * Form alter hooks are called in the following order: hook_form_alter(),
+ * hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See
+ * hook_form_alter() for more details.
  *
  * @param $form
  *   Nested array of form elements that comprise the form.
@@ -1663,8 +1692,10 @@ function hook_form_FORM_ID_alter(&$form, &$form_state, $form_id) {
  *   String representing the name of the form itself. Typically this is the
  *   name of the function that generated the form.
  *
+ * @see hook_form_alter()
  * @see hook_form_FORM_ID_alter()
  * @see drupal_prepare_form()
+ * @see hook_forms()
  */
 function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
   // Modification for the form with the given BASE_FORM_ID goes here. For
@@ -1684,13 +1715,25 @@ function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
  *
  * By default, when drupal_get_form() is called, the system will look for a
  * function with the same name as the form ID, and use that function to build
- * the form. This hook allows you to override that behavior in two ways.
+ * the form. If no such function is found, Drupal calls this hook. Modules
+ * implementing this hook can then provide their own instructions for mapping
+ * form IDs to constructor functions. As a result, you can easily map multiple
+ * form IDs to a single form constructor (referred to as a 'base' form).
+ *
+ * Using a base form can help to avoid code duplication, by allowing many
+ * similar forms to use the same code base. Another benefit is that it becomes
+ * much easier for other modules to apply a general change to the group of
+ * forms; hook_form_BASE_FORM_ID_alter() can be used to easily alter multiple
+ * forms at once by directly targeting the shared base form.
+ *
+ * Two example use cases where base forms may be useful are given below.
  *
  * First, you can use this hook to tell the form system to use a different
  * function to build certain forms in your module; this is often used to define
  * a form "factory" function that is used to build several similar forms. In
  * this case, your hook implementation will likely ignore all of the input
- * arguments. See node_forms() for an example of this.
+ * arguments. See node_forms() for an example of this. Note, node_forms() is the
+ * hook_forms() implementation; the base form itself is defined in node_form().
  *
  * Second, you could use this hook to define how to build a form with a
  * dynamically-generated form ID. In this case, you would need to verify that
@@ -1707,7 +1750,9 @@ function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
  * @return
  *   An associative array whose keys define form_ids and whose values are an
  *   associative array defining the following keys:
- *   - callback: The name of the form builder function to invoke.
+ *   - callback: The name of the form builder function to invoke. This will be
+ *     used for the base form ID, for example, to target a base form using
+ *     hook_form_BASE_FORM_ID_alter().
  *   - callback arguments: (optional) Additional arguments to pass to the
  *     function defined in 'callback', which are prepended to $args.
  *   - wrapper_callback: (optional) The name of a form builder function to
@@ -1862,12 +1907,20 @@ function hook_image_toolkits() {
  *  - 'language':
  *     The language object used to build the message before hook_mail_alter()
  *     is invoked.
+ *  - 'send':
+ *     Set to FALSE to abort sending this email message.
  *
  * @see drupal_mail()
  */
 function hook_mail_alter(&$message) {
   if ($message['id'] == 'modulename_messagekey') {
-    $message['body'][] = "--\nMail sent out from " . variable_get('sitename', t('Drupal'));
+    if (!example_notifications_optin($message['to'], $message['id'])) {
+      // If the recipient has opted to not receive such messages, cancel
+      // sending.
+      $message['send'] = FALSE;
+      return;
+    }
+    $message['body'][] = "--\nMail sent out from " . variable_get('site_name', t('Drupal'));
   }
 }
 
@@ -1906,6 +1959,25 @@ function hook_module_implements_alter(&$implementations, $hook) {
   }
 }
 
+/**
+ * Return additional themes provided by modules.
+ *
+ * Only use this hook for testing purposes. Use a hidden MYMODULE_test.module
+ * to implement this hook. Testing themes should be hidden, too.
+ *
+ * This hook is invoked from _system_rebuild_theme_data() and allows modules to
+ * register additional themes outside of the regular 'themes' directories of a
+ * Drupal installation.
+ *
+ * @return
+ *   An associative array. Each key is the system name of a theme and each value
+ *   is the corresponding path to the theme's .info file.
+ */
+function hook_system_theme_info() {
+  $themes['mymodule_test_theme'] = drupal_get_path('module', 'mymodule') . '/mymodule_test_theme/mymodule_test_theme.info';
+  return $themes;
+}
+
 /**
  * Alter the information parsed from module and theme .info files
  *
@@ -2593,7 +2665,7 @@ function hook_stream_wrappers_alter(&$wrappers) {
  *   An array of file objects, indexed by fid.
  *
  * @see file_load_multiple()
- * @see upload_file_load()
+ * @see file_load()
  */
 function hook_file_load($files) {
   // Add the upload specific data into the file object.
@@ -2718,7 +2790,6 @@ function hook_file_move($file, $source) {
  *   The file that has just been deleted.
  *
  * @see file_delete()
- * @see upload_file_delete()
  */
 function hook_file_delete($file) {
   // Delete all information associated with the file.
@@ -3171,14 +3242,11 @@ function hook_install() {
  *
  * A good rule of thumb is to remove updates older than two major releases of
  * Drupal. See hook_update_last_removed() to notify Drupal about the removals.
+ * For further information about releases and release numbers see:
+ * @link http://drupal.org/node/711070 Maintaining a drupal.org project with Git @endlink
  *
  * Never renumber update functions.
  *
- * Further information about releases and release numbers:
- * - @link http://drupal.org/handbook/version-info http://drupal.org/handbook/version-info @endlink
- * - @link http://drupal.org/node/93999 http://drupal.org/node/93999 @endlink (Overview of contributions branches and tags)
- * - @link http://drupal.org/handbook/cvs/releases http://drupal.org/handbook/cvs/releases @endlink
- *
  * Implementations of this hook should be placed in a mymodule.install file in
  * the same directory as mymodule.module. Drupal core's updates are implemented
  * using the system module as a name and stored in database/updates.inc.
@@ -4044,7 +4112,7 @@ function hook_url_inbound_alter(&$path, $original_path, $path_language) {
  * @param $path
  *   The outbound path to alter, not adjusted for path aliases yet. It won't be
  *   adjusted for path aliases until all modules are finished altering it, thus
- *   being consistent with hook_url_alter_inbound(), which adjusts for all path
+ *   being consistent with hook_url_inbound_alter(), which adjusts for all path
  *   aliases before allowing modules to alter it. This may have been altered by
  *   other modules before this one.
  * @param $options
diff --git a/modules/system/system.info b/modules/system/system.info
index 6fb99b68..b119521e 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/system/system.install b/modules/system/system.install
index 95ee8c5d..aed7cc48 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -2242,10 +2242,6 @@ function system_update_7036() {
     ));
   }
   $insert->execute();
-
-  // Remove obsolete variable 'site_offline_message'. See
-  // update_fix_d7_requirements().
-  variable_del('site_offline_message');
 }
 
 /**
@@ -2973,6 +2969,15 @@ function system_update_7071() {
   ));
 }
 
+/**
+ * Remove the obsolete 'site_offline_message' variable.
+ *
+ * @see update_fix_d7_requirements()
+ */
+function system_update_7072() {
+  variable_del('site_offline_message');
+}
+
 /**
  * @} End of "defgroup updates-6.x-to-7.x"
  * The next series of updates should start at 8000.
diff --git a/modules/system/system.mail.inc b/modules/system/system.mail.inc
index ef50642c..4e754400 100644
--- a/modules/system/system.mail.inc
+++ b/modules/system/system.mail.inc
@@ -65,28 +65,49 @@ class DefaultMailSystem implements MailSystemInterface {
     // For headers, PHP's API suggests that we use CRLF normally,
     // but some MTAs incorrectly replace LF with CRLF. See #234403.
     $mail_headers = join("\n", $mimeheaders);
-    if (isset($message['Return-Path']) && !ini_get('safe_mode')) {
-      $mail_result = mail(
-        $message['to'],
-        $mail_subject,
-        $mail_body,
-        $mail_headers,
-        // Pass the Return-Path via sendmail's -f command.
-        '-f ' . $message['Return-Path']
-      );
-    }
-    else {
-      // The optional $additional_parameters argument to mail() is not allowed
-      // if safe_mode is enabled. Passing any value throws a PHP warning and
-      // makes mail() return FALSE.
-      $mail_result = mail(
-        $message['to'],
-        $mail_subject,
-        $mail_body,
-        $mail_headers
-      );
-    }
-    return $mail_result;
+
+    // We suppress warnings and notices from mail() because of issues on some
+    // hosts. The return value of this method will still indicate whether mail
+    // was sent successfully.
+    if (!isset($_SERVER['WINDIR']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') === FALSE) {
+      if (isset($message['Return-Path']) && !ini_get('safe_mode')) {
+        // On most non-Windows systems, the "-f" option to the sendmail command
+        // is used to set the Return-Path. There is no space between -f and
+        // the value of the return path.
+        $mail_result = @mail(
+          $message['to'],
+          $mail_subject,
+          $mail_body,
+          $mail_headers,
+          '-f' . $message['Return-Path']
+        );
+      }
+      else {
+        // The optional $additional_parameters argument to mail() is not
+        // allowed if safe_mode is enabled. Passing any value throws a PHP
+        // warning and makes mail() return FALSE.
+        $mail_result = @mail(
+          $message['to'],
+          $mail_subject,
+          $mail_body,
+          $mail_headers
+        );
+      }
+     }
+     else {
+      // On Windows, PHP will use the value of sendmail_from for the
+      // Return-Path header.
+      $old_from = ini_get('sendmail_from');
+      ini_set('sendmail_from', $message['Return-Path']);
+      $mail_result = @mail(
+         $message['to'],
+         $mail_subject,
+         $mail_body,
+         $mail_headers
+       );
+      ini_set('sendmail_from', $old_from);
+     }
+     return $mail_result;
   }
 }
 
diff --git a/modules/system/system.module b/modules/system/system.module
index d0a542ef..086a298e 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -45,6 +45,13 @@ define('DRUPAL_OPTIONAL', 1);
  */
 define('DRUPAL_REQUIRED', 2);
 
+/**
+ * Maximum number of values in a weight select element.
+ *
+ * If the number of values is over the maximum, a text field is used instead.
+ */
+define('DRUPAL_WEIGHT_SELECT_MAX', 100);
+
 /**
  * Return only visible regions.
  *
@@ -969,7 +976,7 @@ function system_menu() {
   );
   $items['admin/config/system/site-information'] = array(
     'title' => 'Site information',
-    'description' => t('Change site name, e-mail address, slogan, default front page, and number of posts per page, error pages.'),
+    'description' => 'Change site name, e-mail address, slogan, default front page, and number of posts per page, error pages.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('system_site_information_settings'),
     'access arguments' => array('administer site configuration'),
@@ -977,8 +984,8 @@ function system_menu() {
     'weight' => -20,
   );
   $items['admin/config/system/cron'] = array(
-    'title' => t('Cron'),
-    'description' => t('Manage automatic site maintenance tasks.'),
+    'title' => 'Cron',
+    'description' => 'Manage automatic site maintenance tasks.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('system_cron_settings'),
     'access arguments' => array('administer site configuration'),
@@ -1108,7 +1115,7 @@ function system_library() {
     'title' => 'Drupal progress indicator',
     'version' => VERSION,
     'js' => array(
-      'misc/progress.js' => array('group' => JS_DEFAULT, 'cache' => FALSE),
+      'misc/progress.js' => array('group' => JS_DEFAULT),
     ),
   );
 
@@ -2465,6 +2472,18 @@ function _system_update_bootstrap_status() {
 function _system_rebuild_theme_data() {
   // Find themes
   $themes = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'themes');
+  // Allow modules to add further themes.
+  if ($module_themes = module_invoke_all('system_theme_info')) {
+    foreach ($module_themes as $name => $uri) {
+      // @see file_scan_directory()
+      $themes[$name] = (object) array(
+        'uri' => $uri,
+        'filename' => pathinfo($uri, PATHINFO_FILENAME),
+        'name' => $name,
+      );
+    }
+  }
+
   // Find theme engines
   $engines = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines');
 
@@ -2700,8 +2719,8 @@ function system_region_list($theme_key, $show = REGIONS_ALL) {
  * Implements hook_system_info_alter().
  */
 function system_system_info_alter(&$info, $file, $type) {
-  // Remove page-top from the blocks UI since it is reserved for modules to
-  // populate from outside the blocks system.
+  // Remove page-top and page-bottom from the blocks UI since they are reserved for
+  // modules to populate from outside the blocks system.
   if ($type == 'theme') {
     $info['regions_hidden'][] = 'page_top';
     $info['regions_hidden'][] = 'page_bottom';
@@ -2864,7 +2883,18 @@ function confirm_form($form, $question, $path, $description = NULL, $yes = NULL,
 }
 
 /**
- * Determines if the current user is in compact mode.
+ * Determines whether the current user is in compact mode.
+ *
+ * Compact mode shows certain administration pages with less description text,
+ * such as the configuration page and the permissions page.
+ *
+ * Whether the user is in compact mode is determined by a cookie, which is set
+ * for the user by system_admin_compact_page().
+ *
+ * If the user does not have the cookie, the default value is given by the
+ * system variable 'admin_compact_mode', which itself defaults to FALSE. This
+ * does not have a user interface to set it: it is a hidden variable which can
+ * be set in the settings.php file.
  *
  * @return
  *   TRUE when in compact mode, FALSE when in expanded mode.
@@ -3420,12 +3450,12 @@ function system_image_toolkits() {
 function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $replace = FILE_EXISTS_RENAME) {
   $parsed_url = parse_url($url);
   if (!isset($destination)) {
-    $path = file_build_uri(basename($parsed_url['path']));
+    $path = file_build_uri(drupal_basename($parsed_url['path']));
   }
   else {
     if (is_dir(drupal_realpath($destination))) {
       // Prevent URIs with triple slashes when glueing parts together.
-      $path = str_replace('///', '//', "$destination/") . basename($parsed_url['path']);
+      $path = str_replace('///', '//', "$destination/") . drupal_basename($parsed_url['path']);
     }
     else {
       $path = $destination;
@@ -3860,7 +3890,10 @@ function system_date_format_save($date_format, $dfid = 0) {
     drupal_write_record('date_formats', $info, $keys);
   }
 
+  // Retrieve an array of language objects for enabled languages.
   $languages = language_list('enabled');
+  // This list is keyed off the value of $language->enabled; we want the ones
+  // that are enabled (value of 1).
   $languages = $languages[1];
 
   $locale_format = array();
diff --git a/modules/system/system.queue.inc b/modules/system/system.queue.inc
index 806015c2..47d8e7cc 100644
--- a/modules/system/system.queue.inc
+++ b/modules/system/system.queue.inc
@@ -45,13 +45,13 @@
  * would be an in-memory queue backend which might lose items if it crashes.
  * However, such a backend would be able to deal with significantly more writes
  * than a reliable queue and for many tasks this is more important. See
- * aggregator_cron() for an example of how can this not be a problem. Another
- * example is doing Twitter statistics -- the small possibility of losing a few
- * items is insignificant next to power of the queue being able to keep up with
- * writes. As described in the processing section, regardless of the queue
- * being reliable or not, the processing code should be aware that an item
- * might be handed over for processing more than once (because the processing
- * code might time out before it finishes).
+ * aggregator_cron() for an example of how to effectively utilize a
+ * non-reliable queue. Another example is doing Twitter statistics -- the small
+ * possibility of losing a few items is insignificant next to power of the
+ * queue being able to keep up with writes. As described in the processing
+ * section, regardless of the queue being reliable or not, the processing code
+ * should be aware that an item might be handed over for processing more than
+ * once (because the processing code might time out before it finishes).
  */
 
 /**
diff --git a/modules/system/system.test b/modules/system/system.test
index 8b305bc6..f40bd686 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -272,12 +272,32 @@ class EnableDisableTestCase extends ModuleTestCase {
   }
 
   /**
-   * Tests entity cache after enabling a module with a dependency on an enitity
-   * providing module.
+   * Ensures entity info cache is updated after changes.
+   */
+  function testEntityInfoChanges() {
+    module_enable(array('entity_cache_test'));
+    $entity_info = entity_get_info();
+    $this->assertTrue(isset($entity_info['entity_cache_test']), 'Test entity type found.');
+
+    // Change the label of the test entity type and make sure changes appear
+    // after flushing caches.
+    variable_set('entity_cache_test_label', 'New label.');
+    drupal_flush_all_caches();
+    $info = entity_get_info('entity_cache_test');
+    $this->assertEqual($info['label'], 'New label.', 'New label appears in entity info.');
+
+    // Disable the providing module and make sure the entity type is gone.
+    module_disable(array('entity_cache_test', 'entity_cache_test_dependency'));
+    $entity_info = entity_get_info();
+    $this->assertFalse(isset($entity_info['entity_cache_test']), 'Entity type of the providing module is gone.');
+  }
+
+  /**
+   * Tests entity info cache after enabling a module with a dependency on an entity providing module.
    *
    * @see entity_cache_test_watchdog()
    */
-  function testEntityCache() {
+  function testEntityInfoCacheWatchdog() {
     module_enable(array('entity_cache_test'));
     $info = variable_get('entity_cache_test');
     $this->assertEqual($info['label'], 'Entity Cache Test', 'Entity info label is correct.');
@@ -1861,6 +1881,9 @@ class TokenReplaceTestCase extends DrupalWebTestCase {
 
     $generated = token_generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE));
     $this->assertEqual($generated['[node:title]'], $node->title, t('Unsanitized token generated properly.'));
+
+    // Test token replacement when the string contains no tokens.
+    $this->assertEqual(token_replace('No tokens here.'), 'No tokens here.');
   }
 
   /**
@@ -2274,7 +2297,7 @@ class RetrieveFileTestCase extends DrupalWebTestCase {
   function testFileRetrieving() {
     // Test 404 handling by trying to fetch a randomly named file.
     drupal_mkdir($sourcedir = 'public://' . $this->randomName());
-    $filename = $this->randomName();
+    $filename = 'Файл для тестирования ' . $this->randomName();
     $url = file_create_url($sourcedir . '/' . $filename);
     $retrieved_file = system_retrieve_file($url);
     $this->assertFalse($retrieved_file, t('Non-existent file not fetched.'));
@@ -2282,7 +2305,12 @@ class RetrieveFileTestCase extends DrupalWebTestCase {
     // Actually create that file, download it via HTTP and test the returned path.
     file_put_contents($sourcedir . '/' . $filename, 'testing');
     $retrieved_file = system_retrieve_file($url);
-    $this->assertEqual($retrieved_file, 'public://' . $filename, t('Sane path for downloaded file returned (public:// scheme).'));
+
+    // URLs could not contains characters outside the ASCII set so $filename
+    // has to be encoded.
+    $encoded_filename = rawurlencode($filename);
+
+    $this->assertEqual($retrieved_file, 'public://' . $encoded_filename, t('Sane path for downloaded file returned (public:// scheme).'));
     $this->assertTrue(is_file($retrieved_file), t('Downloaded file does exist (public:// scheme).'));
     $this->assertEqual(filesize($retrieved_file), 7, t('File size of downloaded file is correct (public:// scheme).'));
     file_unmanaged_delete($retrieved_file);
@@ -2290,7 +2318,7 @@ class RetrieveFileTestCase extends DrupalWebTestCase {
     // Test downloading file to a different location.
     drupal_mkdir($targetdir = 'temporary://' . $this->randomName());
     $retrieved_file = system_retrieve_file($url, $targetdir);
-    $this->assertEqual($retrieved_file, "$targetdir/$filename", t('Sane path for downloaded file returned (temporary:// scheme).'));
+    $this->assertEqual($retrieved_file, "$targetdir/$encoded_filename", t('Sane path for downloaded file returned (temporary:// scheme).'));
     $this->assertTrue(is_file($retrieved_file), t('Downloaded file does exist (temporary:// scheme).'));
     $this->assertEqual(filesize($retrieved_file), 7, t('File size of downloaded file is correct (temporary:// scheme).'));
     file_unmanaged_delete($retrieved_file);
diff --git a/modules/taxonomy/taxonomy.info b/modules/taxonomy/taxonomy.info
index b7c13d6a..206f5515 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 379de71c..ccbd7c52 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -295,7 +295,9 @@ function taxonomy_menu() {
   $items['taxonomy/term/%taxonomy_term/edit'] = array(
     'title' => 'Edit',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('taxonomy_form_term', 2),
+    // Pass a NULL argument to ensure that additional path components are not
+    // passed to taxonomy_form_term() as the vocabulary machine name argument.
+    'page arguments' => array('taxonomy_form_term', 2, NULL),
     'access callback' => 'taxonomy_term_edit_access',
     'access arguments' => array(2),
     'type' => MENU_LOCAL_TASK,
@@ -426,6 +428,7 @@ function taxonomy_vocabulary_save($vocabulary) {
 
   if (!empty($vocabulary->vid) && !empty($vocabulary->name)) {
     $status = drupal_write_record('taxonomy_vocabulary', $vocabulary, 'vid');
+    taxonomy_vocabulary_static_reset(array($vocabulary->vid));
     if ($vocabulary->old_machine_name != $vocabulary->machine_name) {
       field_attach_rename_bundle('taxonomy_term', $vocabulary->old_machine_name, $vocabulary->machine_name);
     }
@@ -434,6 +437,7 @@ function taxonomy_vocabulary_save($vocabulary) {
   }
   elseif (empty($vocabulary->vid)) {
     $status = drupal_write_record('taxonomy_vocabulary', $vocabulary);
+    taxonomy_vocabulary_static_reset();
     field_attach_create_bundle('taxonomy_term', $vocabulary->machine_name);
     module_invoke_all('taxonomy_vocabulary_insert', $vocabulary);
     module_invoke_all('entity_insert', $vocabulary, 'taxonomy_vocabulary');
@@ -441,7 +445,6 @@ function taxonomy_vocabulary_save($vocabulary) {
 
   unset($vocabulary->original);
   cache_clear_all();
-  taxonomy_vocabulary_static_reset(array($vocabulary->vid));
 
   return $status;
 }
@@ -1023,9 +1026,9 @@ function taxonomy_get_tree($vid, $parent = 0, $max_depth = NULL, $load_entities
           break;
         }
         $term = $load_entities ? $term_entities[$child] : $terms[$vid][$child];
-        if (count($parents[$vid][$term->tid]) > 1) {
-          // We have a term with multi parents here. Clone the term,
-          // so that the depth attribute remains correct.
+        if (isset($parents[$vid][$term->tid])) {
+          // Clone the term so that the depth attribute remains correct
+          // in the event of multiple parents.
           $term = clone $term;
         }
         $term->depth = $depth;
@@ -1194,6 +1197,8 @@ function taxonomy_vocabulary_load_multiple($vids = array(), $conditions = array(
  * @return
  *   The vocabulary object with all of its metadata, if exists, FALSE otherwise.
  *   Results are statically cached.
+ *
+ * @see taxonomy_vocabulary_machine_name_load()
  */
 function taxonomy_vocabulary_load($vid) {
   $vocabularies = taxonomy_vocabulary_load_multiple(array($vid));
@@ -1209,6 +1214,8 @@ function taxonomy_vocabulary_load($vid) {
  * @return
  *   The vocabulary object with all of its metadata, if exists, FALSE otherwise.
  *   Results are statically cached.
+ *
+ * @see taxonomy_vocabulary_load()
  */
 function taxonomy_vocabulary_machine_name_load($name) {
   $vocabularies = taxonomy_vocabulary_load_multiple(NULL, array('machine_name' => $name));
@@ -1724,48 +1731,75 @@ function taxonomy_field_presave($entity_type, $entity, $field, $instance, $langc
 }
 
 /**
- * Implements hook_field_insert().
+ * Implements hook_node_insert().
  */
-function taxonomy_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  // We maintain a denormalized table of term/node relationships, containing
-  // only data for current, published nodes.
-  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node' && $entity->status) {
-    $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', ));
-    foreach ($items as $item) {
-      $query->values(array(
-        'nid' => $entity->nid,
-        'tid' => $item['tid'],
-        'sticky' => $entity->sticky,
-        'created' => $entity->created,
-      ));
-    }
-    $query->execute();
-  }
+function taxonomy_node_insert($node) {
+  // Add taxonomy index entries for the node.
+  taxonomy_build_node_index($node);
 }
 
 /**
- * Implements hook_field_update().
+ * Builds and inserts taxonomy index entries for a given node.
+ *
+ * The index lists all terms that are related to a given node entity, and is
+ * therefore maintained at the entity level.
+ *
+ * @param $node
+ *   The node object.
  */
-function taxonomy_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node') {
-    $first_call = &drupal_static(__FUNCTION__, array());
-
-    // We don't maintain data for old revisions, so clear all previous values
-    // from the table. Since this hook runs once per field, per object, make
-    // sure we only wipe values once.
-    if (!isset($first_call[$entity->nid])) {
-      $first_call[$entity->nid] = FALSE;
-      db_delete('taxonomy_index')->condition('nid', $entity->nid)->execute();
+function taxonomy_build_node_index($node) {
+  // We maintain a denormalized table of term/node relationships, containing
+  // only data for current, published nodes.
+  $status = NULL;
+  if (variable_get('taxonomy_maintain_index_table', TRUE)) {
+    // If a node property is not set in the node object when node_save() is
+    // called, the old value from $node->original is used.
+    if (!empty($node->original)) {
+      $status = (int)(!empty($node->status) || (!isset($node->status) && !empty($node->original->status)));
+      $sticky = (int)(!empty($node->sticky) || (!isset($node->sticky) && !empty($node->original->sticky)));
+    }
+    else {
+      $status = (int)(!empty($node->status));
+      $sticky = (int)(!empty($node->sticky));
+    }
+  }
+  // We only maintain the taxonomy index for published nodes.
+  if ($status) {
+    // Collect a unique list of all the term IDs from all node fields.
+    $tid_all = array();
+    foreach (field_info_instances('node', $node->type) as $instance) {
+      $field_name = $instance['field_name'];
+      $field = field_info_field($field_name);
+      if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') {
+        // If a field value is not set in the node object when node_save() is
+        // called, the old value from $node->original is used.
+        if (isset($node->{$field_name})) {
+          $items = $node->{$field_name};
+        }
+        elseif (isset($node->original->{$field_name})) {
+          $items = $node->original->{$field_name};
+        }
+        else {
+          continue;
+        }
+        foreach (field_available_languages('node', $field) as $langcode) {
+          if (!empty($items[$langcode])) {
+            foreach ($items[$langcode] as $item) {
+              $tid_all[$item['tid']] = $item['tid'];
+            }
+          }
+        }
+      }
     }
-    // Only save data to the table if the node is published.
-    if ($entity->status) {
+    // Insert index entries for all the node's terms.
+    if (!empty($tid_all)) {
       $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created'));
-      foreach ($items as $item) {
+      foreach ($tid_all as $tid) {
         $query->values(array(
-          'nid' => $entity->nid,
-          'tid' => $item['tid'],
-          'sticky' => $entity->sticky,
-          'created' => $entity->created,
+          'nid' => $node->nid,
+          'tid' => $tid,
+          'sticky' => $sticky,
+          'created' => $node->created,
         ));
       }
       $query->execute();
@@ -1773,12 +1807,31 @@ function taxonomy_field_update($entity_type, $entity, $field, $instance, $langco
   }
 }
 
+/**
+ * Implements hook_node_update().
+ */
+function taxonomy_node_update($node) {
+  // Always rebuild the node's taxonomy index entries on node save.
+  taxonomy_delete_node_index($node);
+  taxonomy_build_node_index($node);
+}
+
 /**
  * Implements hook_node_delete().
  */
 function taxonomy_node_delete($node) {
+  // Clean up the {taxonomy_index} table when nodes are deleted.
+  taxonomy_delete_node_index($node);
+}
+
+/**
+ * Deletes taxonomy index entries for a given node.
+ *
+ * @param $node
+ *   The node object.
+ */
+function taxonomy_delete_node_index($node) {
   if (variable_get('taxonomy_maintain_index_table', TRUE)) {
-    // Clean up the {taxonomy_index} table when nodes are deleted.
     db_delete('taxonomy_index')->condition('nid', $node->nid)->execute();
   }
 }
diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test
index 9a89b9c9..25743bfe 100644
--- a/modules/taxonomy/taxonomy.test
+++ b/modules/taxonomy/taxonomy.test
@@ -410,6 +410,60 @@ class TaxonomyTermUnitTest extends TaxonomyWebTestCase {
     // Delete an invalid term. Should not throw any notices.
     taxonomy_term_delete(42);
   }
+
+  /**
+   * Test a taxonomy with terms that have multiple parents of different depths.
+   */
+  function testTaxonomyVocabularyTree() {
+    // Create a new vocabulary with 6 terms.
+    $vocabulary = $this->createVocabulary();
+    $term = array();
+    for ($i = 0; $i < 6; $i++) {
+      $term[$i] = $this->createTerm($vocabulary);
+    }
+
+    // $term[2] is a child of 1 and 5.
+    $term[2]->parent = array($term[1]->tid, $term[5]->tid);
+    taxonomy_term_save($term[2]);
+    // $term[3] is a child of 2.
+    $term[3]->parent = array($term[2]->tid);
+    taxonomy_term_save($term[3]);
+    // $term[5] is a child of 4.
+    $term[5]->parent = array($term[4]->tid);
+    taxonomy_term_save($term[5]);
+
+    /**
+     * Expected tree:
+     * term[0] | depth: 0
+     * term[1] | depth: 0
+     * -- term[2] | depth: 1
+     * ---- term[3] | depth: 2
+     * term[4] | depth: 0
+     * -- term[5] | depth: 1
+     * ---- term[2] | depth: 2
+     * ------ term[3] | depth: 3
+     */
+
+    // Count $term[1] parents with $max_depth = 1.
+    $tree = taxonomy_get_tree($vocabulary->vid, $term[1]->tid, 1);
+    $this->assertEqual(1, count($tree), 'We have one parent with depth 1.');
+
+    // Count all vocabulary tree elements.
+    $tree = taxonomy_get_tree($vocabulary->vid);
+    $this->assertEqual(8, count($tree), 'We have all vocabulary tree elements.');
+
+    // Count elements in every tree depth.
+    foreach($tree as $element) {
+      if (!isset($depth_count[$element->depth])) {
+        $depth_count[$element->depth] = 0;
+      }
+      $depth_count[$element->depth]++;
+    }
+    $this->assertEqual(3, $depth_count[0], 'Three elements in taxonomy tree depth 0.');
+    $this->assertEqual(2, $depth_count[1], 'Two elements in taxonomy tree depth 1.');
+    $this->assertEqual(2, $depth_count[2], 'Two elements in taxonomy tree depth 2.');
+    $this->assertEqual(1, $depth_count[3], 'One element in taxonomy tree depth 3.');
+   }
 }
 
 /**
@@ -579,9 +633,9 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
     $instance['bundle'] = 'page';
     field_create_instance($instance);
     $terms = array(
-      $this->randomName(),
-      $this->randomName() . ', ' . $this->randomName(),
-      $this->randomName(),
+      'term1' => $this->randomName(),
+      'term2' => $this->randomName() . ', ' . $this->randomName(),
+      'term3' => $this->randomName(),
     );
 
     $edit = array();
@@ -611,33 +665,37 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
     }
 
     // Get the created terms.
-    list($term1, $term2, $term3) = array_values(taxonomy_term_load_multiple(FALSE));
+    $term_objects = array();
+    foreach ($terms as $key => $term) {
+      $term_objects[$key] = taxonomy_get_term_by_name($term);
+      $term_objects[$key] = reset($term_objects[$key]);
+    }
 
     // Delete term 1.
-    $this->drupalPost('taxonomy/term/' . $term1->tid . '/edit', array(), t('Delete'));
+    $this->drupalPost('taxonomy/term/' . $term_objects['term1']->tid . '/edit', array(), t('Delete'));
     $this->drupalPost(NULL, NULL, t('Delete'));
-    $term_names = array($term2->name, $term3->name);
+    $term_names = array($term_objects['term2']->name, $term_objects['term3']->name);
 
     // Get the node.
     $node = $this->drupalGetNodeByTitle($edit["title"]);
     $this->drupalGet('node/' . $node->nid);
 
     foreach ($term_names as $term_name) {
-      $this->assertText($term_name, t('The term %name appears on the node page after one term %deleted was deleted', array('%name' => $term_name, '%deleted' => $term1->name)));
+      $this->assertText($term_name, t('The term %name appears on the node page after one term %deleted was deleted', array('%name' => $term_name, '%deleted' => $term_objects['term1']->name)));
     }
-    $this->assertNoText($term1->name, t('The deleted term %name does not appear on the node page.', array('%name' => $term1->name)));
+    $this->assertNoText($term_objects['term1']->name, t('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->name)));
 
-    // Test autocomplete on term 2 - it contains a comma, so expect the key to
-    // be quoted.
-    $input = substr($term2->name, 0, 3);
+    // Test autocomplete on term 2, which contains a comma.
+    // The term will be quoted, and the " will be encoded in unicode (\u0022).
+    $input = substr($term_objects['term2']->name, 0, 3);
     $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input);
-    $this->assertRaw('{"\"' . $term2->name . '\"":"' . $term2->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term2->name)));
+    $this->assertRaw('{"\u0022' . $term_objects['term2']->name . '\u0022":"' . $term_objects['term2']->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term2']->name)));
 
     // Test autocomplete on term 3 - it is alphanumeric only, so no extra
     // quoting.
-    $input = substr($term3->name, 0, 3);
+    $input = substr($term_objects['term3']->name, 0, 3);
     $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input);
-    $this->assertRaw('{"' . $term3->name . '":"' . $term3->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term3->name)));
+    $this->assertRaw('{"' . $term_objects['term3']->name . '":"' . $term_objects['term3']->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term3']->name)));
   }
 
   /**
@@ -699,6 +757,10 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
     // Check that the term feed page is working.
     $this->drupalGet('taxonomy/term/' . $term->tid . '/feed');
 
+    // Check that the term edit page does not try to interpret additional path
+    // components as arguments for taxonomy_form_term().
+    $this->drupalGet('taxonomy/term/' . $term->tid . '/edit/' . $this->randomName());
+
     // Delete the term.
     $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', array(), t('Delete'));
     $this->drupalPost(NULL, NULL, t('Delete'));
@@ -828,6 +890,223 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
   }
 }
 
+/**
+ * Tests the hook implementations that maintain the taxonomy index.
+ */
+class TaxonomyTermIndexTestCase extends TaxonomyWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Taxonomy term index',
+      'description' => 'Tests the hook implementations that maintain the taxonomy index.',
+      'group' => 'Taxonomy',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('taxonomy');
+
+    // Create an administrative user.
+    $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
+    $this->drupalLogin($this->admin_user);
+
+    // Create a vocabulary and add two term reference fields to article nodes.
+    $this->vocabulary = $this->createVocabulary();
+
+    $this->field_name_1 = drupal_strtolower($this->randomName());
+    $this->field_1 = array(
+      'field_name' => $this->field_name_1,
+      'type' => 'taxonomy_term_reference',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    field_create_field($this->field_1);
+    $this->instance_1 = array(
+      'field_name' => $this->field_name_1,
+      'bundle' => 'article',
+      'entity_type' => 'node',
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+      'display' => array(
+        'default' => array(
+          'type' => 'taxonomy_term_reference_link',
+        ),
+      ),
+    );
+    field_create_instance($this->instance_1);
+
+    $this->field_name_2 = drupal_strtolower($this->randomName());
+    $this->field_2 = array(
+      'field_name' => $this->field_name_2,
+      'type' => 'taxonomy_term_reference',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    field_create_field($this->field_2);
+    $this->instance_2 = array(
+      'field_name' => $this->field_name_2,
+      'bundle' => 'article',
+      'entity_type' => 'node',
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+      'display' => array(
+        'default' => array(
+          'type' => 'taxonomy_term_reference_link',
+        ),
+      ),
+    );
+    field_create_instance($this->instance_2);
+  }
+
+  /**
+   * Tests that the taxonomy index is maintained properly.
+   */
+  function testTaxonomyIndex() {
+    // Create terms in the vocabulary.
+    $term_1 = $this->createTerm($this->vocabulary);
+    $term_2 = $this->createTerm($this->vocabulary);
+
+    // Post an article.
+    $edit = array();
+    $langcode = LANGUAGE_NONE;
+    $edit["title"] = $this->randomName();
+    $edit["body[$langcode][0][value]"] = $this->randomName();
+    $edit["{$this->field_name_1}[$langcode][]"] = $term_1->tid;
+    $edit["{$this->field_name_2}[$langcode][]"] = $term_1->tid;
+    $this->drupalPost('node/add/article', $edit, t('Save'));
+
+    // Check that the term is indexed, and only once.
+    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 1 is indexed once.'));
+
+    // Update the article to change one term.
+    $edit["{$this->field_name_1}[$langcode][]"] = $term_2->tid;
+    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
+
+    // Check that both terms are indexed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 1 is indexed.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 2 is indexed.'));
+
+    // Update the article to change another term.
+    $edit["{$this->field_name_2}[$langcode][]"] = $term_2->tid;
+    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
+
+    // Check that only one term is indexed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(0, $index_count, t('Term 1 is not indexed.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 2 is indexed once.'));
+
+    // Redo the above tests without interface.
+    $update_node = array(
+      'nid' => $node->nid,
+      'vid' => $node->vid,
+      'uid' => $node->uid,
+      'type' => $node->type,
+      'title' => $this->randomName(),
+    );
+
+    // Update the article with no term changed.
+    $updated_node = (object) $update_node;
+    node_save($updated_node);
+
+    // Check that the index was not changed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(0, $index_count, t('Term 1 is not indexed.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 2 is indexed once.'));
+
+    // Update the article to change one term.
+    $update_node[$this->field_name_1][$langcode] = array(array('tid' => $term_1->tid));
+    $updated_node = (object) $update_node;
+    node_save($updated_node);
+
+    // Check that both terms are indexed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 1 is indexed.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 2 is indexed.'));
+
+    // Update the article to change another term.
+    $update_node[$this->field_name_2][$langcode] = array(array('tid' => $term_1->tid));
+    $updated_node = (object) $update_node;
+    node_save($updated_node);
+
+    // Check that only one term is indexed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 1 is indexed once.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(0, $index_count, t('Term 2 is not indexed.'));
+  }
+
+  /**
+   * Tests that there is a link to the parent term on the child term page.
+   */
+  function testTaxonomyTermHierarchyBreadcrumbs() {
+    // Create two taxonomy terms and set term2 as the parent of term1.
+    $term1 = $this->createTerm($this->vocabulary);
+    $term2 = $this->createTerm($this->vocabulary);
+    $term1->parent = array($term2->tid);
+    taxonomy_term_save($term1);
+
+    // Verify that the page breadcrumbs include a link to the parent term.
+    $this->drupalGet('taxonomy/term/' . $term1->tid);
+    $this->assertRaw(l($term2->name, 'taxonomy/term/' . $term2->tid), t('Parent term link is displayed when viewing the node.'));
+  }
+}
+
 /**
  * Test the taxonomy_term_load_multiple() function.
  */
@@ -1080,10 +1359,16 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase {
     );
     field_update_field($this->field);
     // Change the machine name.
+    $old_name = $this->vocabulary->machine_name;
     $new_name = drupal_strtolower($this->randomName());
     $this->vocabulary->machine_name = $new_name;
     taxonomy_vocabulary_save($this->vocabulary);
 
+    // Check that entity bundles are properly updated.
+    $info = entity_get_info('taxonomy_term');
+    $this->assertFalse(isset($info['bundles'][$old_name]), t('The old bundle name does not appear in entity_get_info().'));
+    $this->assertTrue(isset($info['bundles'][$new_name]), t('The new bundle name appears in entity_get_info().'));
+
     // Check that the field instance is still attached to the vocabulary.
     $field = field_info_field($this->field_name);
     $allowed_values = $field['settings']['allowed_values'];
diff --git a/modules/toolbar/toolbar.info b/modules/toolbar/toolbar.info
index adc9eba5..fd1d6a1a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/toolbar/toolbar.module b/modules/toolbar/toolbar.module
index 61ae648a..de2d2619 100644
--- a/modules/toolbar/toolbar.module
+++ b/modules/toolbar/toolbar.module
@@ -82,6 +82,7 @@ function toolbar_toggle_page() {
  *   An associative array containing:
  *   - collapsed: A boolean value representing the toolbar drawer's visibility.
  *   - attributes: An associative array of HTML attributes.
+ *
  * @return
  *   An HTML string representing the element for toggling.
  *
@@ -175,7 +176,10 @@ function toolbar_system_info_alter(&$info, $file, $type) {
 }
 
 /**
- * Build the admin menu as a structured array ready for drupal_render().
+ * Builds the admin menu as a structured array ready for drupal_render().
+ *
+ * @return
+ *   Array of links and settings relating to the admin menu.
  */
 function toolbar_view() {
   global $user;
@@ -272,7 +276,10 @@ function toolbar_view() {
 }
 
 /**
- * Get only the top level items below the 'admin' path.
+ * Gets only the top level items below the 'admin' path.
+ *
+ * @return
+ *   An array containing a menu tree of top level items below the 'admin' path.
  */
 function toolbar_get_menu_tree() {
   $tree = array();
@@ -289,10 +296,13 @@ function toolbar_get_menu_tree() {
 }
 
 /**
- * Generate a links array from a menu tree array.
+ * Generates a links array from a menu tree array.
  *
  * Based on menu_navigation_links(). Adds path based IDs and icon placeholders
  * to the links.
+ *
+ * @return
+ *   An array of links as defined above.
  */
 function toolbar_menu_navigation_links($tree) {
   $links = array();
@@ -330,6 +340,9 @@ function toolbar_menu_navigation_links($tree) {
  * Useful when using a menu generated by menu_tree_all_data() which does
  * not set the 'in_active_trail' flag on items.
  *
+ * @return
+ *   TRUE when path is in the active trail, FALSE if not.
+ *
  * @todo
  *   Look at migrating to a menu system level function.
  */
diff --git a/modules/tracker/tracker.info b/modules/tracker/tracker.info
index a0d821d6..056b1215 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/tracker/tracker.test b/modules/tracker/tracker.test
index 3cc227ea..a559f1b6 100644
--- a/modules/tracker/tracker.test
+++ b/modules/tracker/tracker.test
@@ -8,7 +8,6 @@
 class TrackerTest extends DrupalWebTestCase {
   protected $user;
   protected $other_user;
-  protected $new_node;
 
   public static function getInfo() {
     return array(
diff --git a/modules/translation/tests/translation_test.info b/modules/translation/tests/translation_test.info
index d252b74c..3da9476d 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/translation/translation.info b/modules/translation/translation.info
index 0c850e85..3040c76a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/trigger/tests/trigger_test.info b/modules/trigger/tests/trigger_test.info
index 3aea92f7..6478e078 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/trigger/trigger.info b/modules/trigger/trigger.info
index b2ee810a..0990bc2b 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/update/tests/aaa_update_test.info b/modules/update/tests/aaa_update_test.info
index 755a4ee9..cfd1fec1 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/update/tests/bbb_update_test.info b/modules/update/tests/bbb_update_test.info
index 5c6227b2..40ad68e4 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/update/tests/ccc_update_test.info b/modules/update/tests/ccc_update_test.info
index 9b3312dd..b78a3b62 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/tests/update_test_basetheme/update_test_basetheme.info b/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info
similarity index 59%
rename from themes/tests/update_test_basetheme/update_test_basetheme.info
rename to modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info
index a079e934..f60c1400 100644
--- a/themes/tests/update_test_basetheme/update_test_basetheme.info
+++ b/modules/update/tests/themes/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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/tests/update_test_subtheme/update_test_subtheme.info b/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info
similarity index 63%
rename from themes/tests/update_test_subtheme/update_test_subtheme.info
rename to modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info
index c69ec81d..cc7cb539 100644
--- a/themes/tests/update_test_subtheme/update_test_subtheme.info
+++ b/modules/update/tests/themes/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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/update/tests/update_test.info b/modules/update/tests/update_test.info
index 7626a96c..1e58d53f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/update/tests/update_test.module b/modules/update/tests/update_test.module
index 4acb6ef8..e7ee43ee 100644
--- a/modules/update/tests/update_test.module
+++ b/modules/update/tests/update_test.module
@@ -1,5 +1,14 @@
 <?php
 
+/**
+ * Implements hook_system_theme_info().
+ */
+function update_test_system_theme_info() {
+  $themes['update_test_basetheme'] = drupal_get_path('module', 'update_test') . '/themes/update_test_basetheme/update_test_basetheme.info';
+  $themes['update_test_subtheme'] = drupal_get_path('module', 'update_test') . '/themes/update_test_subtheme/update_test_subtheme.info';
+  return $themes;
+}
+
 /**
  * Implements hook_menu().
  */
diff --git a/modules/update/update.info b/modules/update/update.info
index c3d5c345..92d10d88 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/update/update.manager.inc b/modules/update/update.manager.inc
index 59858ebe..d9fd86ff 100644
--- a/modules/update/update.manager.inc
+++ b/modules/update/update.manager.inc
@@ -816,7 +816,7 @@ function update_manager_file_get($url) {
 
   // Check the cache and download the file if needed.
   $cache_directory = _update_manager_cache_directory();
-  $local = $cache_directory . '/' . basename($parsed_url['path']);
+  $local = $cache_directory . '/' . drupal_basename($parsed_url['path']);
 
   if (!file_exists($local) || update_delete_file_if_stale($local)) {
     return system_retrieve_file($url, $local, FALSE, FILE_EXISTS_REPLACE);
diff --git a/modules/update/update.module b/modules/update/update.module
index a2d705a0..293a53d9 100644
--- a/modules/update/update.module
+++ b/modules/update/update.module
@@ -695,14 +695,14 @@ function update_verify_update_archive($project, $archive_file, $directory) {
   }
 
   if (empty($files)) {
-    $errors[] = t('%archive_file does not contain any .info files.', array('%archive_file' => basename($archive_file)));
+    $errors[] = t('%archive_file does not contain any .info files.', array('%archive_file' => drupal_basename($archive_file)));
   }
   elseif (!$compatible_project) {
     $errors[] = format_plural(
       count($incompatible),
       '%archive_file contains a version of %names that is not compatible with Drupal !version.',
       '%archive_file contains versions of modules or themes that are not compatible with Drupal !version: %names',
-      array('!version' => DRUPAL_CORE_COMPATIBILITY, '%archive_file' => basename($archive_file), '%names' => implode(', ', $incompatible))
+      array('!version' => DRUPAL_CORE_COMPATIBILITY, '%archive_file' => drupal_basename($archive_file), '%names' => implode(', ', $incompatible))
     );
   }
 
diff --git a/modules/user/tests/user_form_test.info b/modules/user/tests/user_form_test.info
index 30d2f3f8..50a5a263 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/user/user.info b/modules/user/user.info
index 00b2db3e..22a5154a 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/modules/user/user.install b/modules/user/user.install
index 9119aac0..a48feb5f 100644
--- a/modules/user/user.install
+++ b/modules/user/user.install
@@ -743,7 +743,7 @@ function user_update_7012(&$sandbox) {
         // Create a file object.
         $file = new stdClass();
         $file->uri      = $user->picture;
-        $file->filename = basename($file->uri);
+        $file->filename = drupal_basename($file->uri);
         $file->filemime = file_get_mimetype($file->uri);
         $file->uid      = $user->uid;
         $file->status   = FILE_STATUS_PERMANENT;
diff --git a/modules/user/user.js b/modules/user/user.js
index 44c00f34..73af27e5 100644
--- a/modules/user/user.js
+++ b/modules/user/user.js
@@ -168,7 +168,7 @@ Drupal.evaluatePasswordStrength = function (password, translate) {
 
   // Assemble the final message.
   msg = translate.hasWeaknesses + '<ul><li>' + msg.join('</li><li>') + '</li></ul>';
-  return { strength: strength, message: msg, indicatorText: indicatorText }
+  return { strength: strength, message: msg, indicatorText: indicatorText };
 
 };
 
diff --git a/modules/user/user.module b/modules/user/user.module
index 48b17af9..da61f44d 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -3466,23 +3466,27 @@ function user_preferred_language($account, $default = NULL) {
  * @see drupal_mail()
  *
  * @param $op
- *  The operation being performed on the account. Possible values:
- *  'register_admin_created': Welcome message for user created by the admin
- *  'register_no_approval_required': Welcome message when user self-registers
- *  'register_pending_approval': Welcome message, user pending admin approval
- *  'password_reset': Password recovery request
- *  'status_activated': Account activated
- *  'status_blocked': Account blocked
- *  'cancel_confirm': Account cancellation request
- *  'status_canceled': Account canceled
+ *   The operation being performed on the account. Possible values:
+ *   - 'register_admin_created': Welcome message for user created by the admin.
+ *   - 'register_no_approval_required': Welcome message when user
+ *     self-registers.
+ *   - 'register_pending_approval': Welcome message, user pending admin
+ *     approval.
+ *   - 'password_reset': Password recovery request.
+ *   - 'status_activated': Account activated.
+ *   - 'status_blocked': Account blocked.
+ *   - 'cancel_confirm': Account cancellation request.
+ *   - 'status_canceled': Account canceled.
  *
  * @param $account
- *  The user object of the account being notified. Must contain at
- *  least the fields 'uid', 'name', and 'mail'.
+ *   The user object of the account being notified. Must contain at
+ *   least the fields 'uid', 'name', and 'mail'.
  * @param $language
- *  Optional language to use for the notification, overriding account language.
+ *   Optional language to use for the notification, overriding account language.
+ *
  * @return
- *  The return value from drupal_mail_system()->mail(), if ends up being called.
+ *   The return value from drupal_mail_system()->mail(), if ends up being
+ *   called.
  */
 function _user_mail_notify($op, $account, $language = NULL) {
   // By default, we always notify except for canceled and blocked.
diff --git a/profiles/minimal/minimal.info b/profiles/minimal/minimal.info
index e5d1cc53..5464aa77 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/profiles/standard/standard.info b/profiles/standard/standard.info
index 2ff24a7a..bdb3d840 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/profiles/standard/standard.install b/profiles/standard/standard.install
index 5d447177..ccc70443 100644
--- a/profiles/standard/standard.install
+++ b/profiles/standard/standard.install
@@ -65,7 +65,7 @@ function standard_install() {
   // Enable some standard blocks.
   $default_theme = variable_get('theme_default', 'bartik');
   $admin_theme = 'seven';
-  $values = array(
+  $blocks = array(
     array(
       'module' => 'system',
       'delta' => 'main',
@@ -188,8 +188,8 @@ function standard_install() {
     ),
   );
   $query = db_insert('block')->fields(array('module', 'delta', 'theme', 'status', 'weight', 'region', 'pages', 'cache'));
-  foreach ($values as $record) {
-    $query->values($record);
+  foreach ($blocks as $block) {
+    $query->values($block);
   }
   $query->execute();
 
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 82b257c8..82e993aa 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
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 3c1a631b..e4b602f3 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/profiles/testing/testing.info b/profiles/testing/testing.info
index e4deb306..a7925857 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/scripts/generate-d7-content.sh b/scripts/generate-d7-content.sh
index 2ad9e528..364a25c9 100644
--- a/scripts/generate-d7-content.sh
+++ b/scripts/generate-d7-content.sh
@@ -269,11 +269,14 @@ if (module_exists('poll')) {
 }
 
 // Test that upgrade works even on a bundle whose parent module was disabled.
+// This is simulated by creating an existing content type and changing the
+// bundle to another type through direct database update queries.
+$node_type = 'broken';
 $uid = 6;
 $user = user_load($uid);
 $node = new stdClass();
 $node->uid = $uid;
-$node->type = 'broken';
+$node->type = 'article';
 $body_text = str_repeat("node body ($node_type) - 37", 100);
 $node->sticky = 0;
 $node->title = "node title 24";
diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh
index 429b28b2..b7d81830 100755
--- a/scripts/run-tests.sh
+++ b/scripts/run-tests.sh
@@ -585,9 +585,8 @@ function simpletest_script_reporter_display_results() {
 
   if ($args['verbose']) {
     // Report results.
-    echo "Detailed test results:\n";
-    echo "----------------------\n";
-    echo "\n";
+    echo "Detailed test results\n";
+    echo "---------------------\n";
 
     $results = db_query("SELECT * FROM {simpletest} WHERE test_id = :test_id ORDER BY test_class, message_id", array(':test_id' => $test_id));
     $test_class = '';
@@ -597,6 +596,10 @@ function simpletest_script_reporter_display_results() {
           // Display test class every time results are for new test class.
           echo "\n\n---- $result->test_class ----\n\n\n";
           $test_class = $result->test_class;
+
+  // Print table header.
+  echo "Status    Group      Filename          Line Function                            \n";
+  echo "--------------------------------------------------------------------------------\n";
         }
 
         simpletest_script_format_result($result);
@@ -614,8 +617,8 @@ function simpletest_script_reporter_display_results() {
 function simpletest_script_format_result($result) {
   global $results_map, $color;
 
-  $summary = sprintf("%-10.10s %-10.10s %-30.30s %-5.5s %-20.20s\n",
-    $results_map[$result->status], $result->message_group, basename($result->file), $result->line, $result->caller);
+  $summary = sprintf("%-9.9s %-10.10s %-17.17s %4.4s %-35.35s\n",
+    $results_map[$result->status], $result->message_group, basename($result->file), $result->line, $result->function);
 
   simpletest_script_print($summary, simpletest_script_color_code($result->status));
 
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index f8894aaf..d8ab0e62 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -153,6 +153,29 @@
  * @endcode
  * NOTE: MySQL and SQLite's definition of a schema is a database.
  *
+ * Advanced users can add or override initial commands to execute when
+ * connecting to the database server, as well as PDO connection settings. For
+ * example, to enable MySQL SELECT queries to exceed the max_join_size system
+ * variable, and to reduce the database connection timeout to 5 seconds:
+ *
+ * @code
+ * $databases['default']['default'] = array(
+ *   'init_commands' => array(
+ *     'big_selects' => 'SET SQL_BIG_SELECTS=1',
+ *   ),
+ *   'pdo' => array(
+ *     PDO::ATTR_TIMEOUT => 5,
+ *   ),
+ * );
+ * @endcode
+ *
+ * WARNING: These defaults are designed for database portability. Changing them
+ * may cause unexpected behavior, including potential data loss.
+ *
+ * @see DatabaseConnection_mysql::__construct
+ * @see DatabaseConnection_pgsql::__construct
+ * @see DatabaseConnection_sqlite::__construct
+ *
  * Database configuration format:
  * @code
  *   $databases['default']['default'] = array(
diff --git a/themes/bartik/bartik.info b/themes/bartik/bartik.info
index 7af315a7..d898a73f 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/bartik/css/style-rtl.css b/themes/bartik/css/style-rtl.css
index d25006fa..1a6b17b1 100644
--- a/themes/bartik/css/style-rtl.css
+++ b/themes/bartik/css/style-rtl.css
@@ -96,6 +96,7 @@ ul.tips {
   float: right;
 }
 .link-wrapper {
+  text-align: left;
   margin-right: 236px;
   margin-left: 0;
 }
diff --git a/themes/garland/garland.info b/themes/garland/garland.info
index dc48613d..c5adc9ab 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/seven/maintenance-page.tpl.php b/themes/seven/maintenance-page.tpl.php
index aeef310d..a158dde3 100644
--- a/themes/seven/maintenance-page.tpl.php
+++ b/themes/seven/maintenance-page.tpl.php
@@ -1,5 +1,4 @@
-<?php
-?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
   <head>
diff --git a/themes/seven/page.tpl.php b/themes/seven/page.tpl.php
index b9d0ad55..4d40cf89 100644
--- a/themes/seven/page.tpl.php
+++ b/themes/seven/page.tpl.php
@@ -1,5 +1,4 @@
-<?php
-?>
+
   <div id="branding" class="clearfix">
     <?php print $breadcrumb; ?>
     <?php print render($title_prefix); ?>
diff --git a/themes/seven/seven.info b/themes/seven/seven.info
index d4dcda2b..708da9e3 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/seven/style.css b/themes/seven/style.css
index d2da561e..8bb80265 100644
--- a/themes/seven/style.css
+++ b/themes/seven/style.css
@@ -835,6 +835,7 @@ body.in-maintenance .form-submit {
 }
 body.in-maintenance #logo {
   margin-bottom: 1.5em;
+  max-width: 180px;
 }
 ol.task-list {
   margin-left: 0; /* LTR */
diff --git a/themes/stark/stark.info b/themes/stark/stark.info
index 8eb875e7..f6f8ae94 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-12-05
-version = "7.10"
+; Information added by drupal.org packaging script on 2012-02-01
+version = "7.12"
 project = "drupal"
-datestamp = "1323125439"
+datestamp = "1328134560"
 
diff --git a/themes/tests/README.txt b/themes/tests/README.txt
deleted file mode 100644
index 5ddaa8ca..00000000
--- a/themes/tests/README.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
-The themes in this subdirectory are all used by the Drupal core testing
-framework. They are not functioning themes that could be used on a real site
-and are hidden in the administrative user interface.
-- 
GitLab