diff --git a/D6-core-simpletest.patch b/D6-core-simpletest.patch
index b9d5057..793fb21 100644
--- a/D6-core-simpletest.patch
+++ b/D6-core-simpletest.patch
@@ -1,119 +1,167 @@
-? sites/all/modules
-? sites/default/files
-? sites/default/settings.php
-Index: install.php
-===================================================================
-RCS file: /cvs/drupal/drupal/install.php,v
-retrieving revision 1.113.2.12
-diff -u -p -r1.113.2.12 install.php
---- install.php	9 May 2010 14:13:31 -0000	1.113.2.12
-+++ install.php	7 Oct 2010 21:55:51 -0000
-@@ -20,6 +20,14 @@ function install_main() {
-   require_once './includes/bootstrap.inc';
-   drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
+index 92e0c0f..fcbadab 100644
+--- a/includes/bootstrap.inc
++++ b/includes/bootstrap.inc
+@@ -6,6 +6,16 @@
+  */
  
-+  // The user agent header is used to pass a database prefix in the request when
-+  // running tests. However, for security reasons, it is imperative that no
-+  // installation be permitted using such a prefix.
-+  if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], "simpletest") !== FALSE) {
-+    header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
-+    exit;
-+  }
+ /**
++ * Indicates the version of SimpleTest patch installed.
++ */
++define('SIMPLETEST_PATCH_VERSION', '6.2.12');
 +
-   // This must go after drupal_bootstrap(), which unsets globals!
-   global $profile, $install_locale, $conf;
- 
-Index: includes/bootstrap.inc
-===================================================================
-RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
-retrieving revision 1.206.2.29
-diff -u -p -r1.206.2.29 bootstrap.inc
---- includes/bootstrap.inc	6 Aug 2010 11:50:24 -0000	1.206.2.29
-+++ includes/bootstrap.inc	7 Oct 2010 21:55:51 -0000
-@@ -1112,7 +1112,7 @@ function drupal_bootstrap($phase) {
- }
- 
- function _drupal_bootstrap($phase) {
--  global $conf;
-+  global $conf, $db_prefix;
- 
-   switch ($phase) {
- 
-@@ -1138,6 +1138,19 @@ function _drupal_bootstrap($phase) {
++/**
++ * For convenience, define a short form of the request time global.
++ */
++define('REQUEST_TIME', isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time());
++
++/**
+  * Indicates that the item should never be removed unless explicitly told to
+  * using cache_clear_all() with a cache ID.
+  */
+@@ -1137,6 +1147,9 @@ function _drupal_bootstrap($phase) {
        break;
  
      case DRUPAL_BOOTSTRAP_DATABASE:
-+      // The user agent header is used to pass a database prefix in the request when
-+      // running tests. However, for security reasons, it is imperative that we
-+      // validate we ourselves made the request.
-+      $GLOBALS['simpletest_installed'] = TRUE;
-+      if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);/", $_SERVER['HTTP_USER_AGENT'], $matches)) {
-+        if (!drupal_valid_test_ua($_SERVER['HTTP_USER_AGENT'])) {
-+          header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
-+          exit;
-+        }
-+        $db_prefix_string = is_array($db_prefix) ? $db_prefix['default'] : $db_prefix;
-+        $db_prefix = $db_prefix_string . $matches[1];
-+      }
++      // Intialize SimpleTest.
++      _drupal_bootstrap_simpletest();
 +
        // Initialize the default database.
        require_once './includes/database.inc';
        db_set_active();
-@@ -1331,3 +1344,46 @@ function ip_address() {
+@@ -1330,3 +1343,127 @@ function ip_address() {
  
    return $ip_address;
  }
 +
 +/**
-+ * Validate the HMAC and timestamp of a user agent header from simpletest.
++ * Calculate a base-64 encoded, URL-safe sha-256 hmac.
++ *
++ * @param $data
++ *   String to be validated with the hmac.
++ * @param $key
++ *   A secret string key.
++ *
++ * @return
++ *   A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
++ *   any = padding characters removed.
++ */
++function drupal_hmac_base64($data, $key) {
++  $hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
++  // Modify the hmac so it's safe to use in URLs.
++  return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
++}
++
++/**
++ * Calculate a base-64 encoded, URL-safe sha-256 hash.
++ *
++ * @param $data
++ *   String to be hashed.
++ *
++ * @return
++ *   A base-64 encoded sha-256 hash, with + replaced with -, / with _ and
++ *   any = padding characters removed.
++ */
++function drupal_hash_base64($data) {
++  $hash = base64_encode(hash('sha256', $data, TRUE));
++  // Modify the hash so it's safe to use in URLs.
++  return strtr($hash, array('+' => '-', '/' => '_', '=' => ''));
++}
++
++/**
++ * 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.
++ *
++ * @return
++ *   Either the simpletest prefix (the string "simpletest" followed by any
++ *   number of digits) or FALSE if the user agent does not contain a valid
++ *   HMAC and timestamp.
 + */
-+function drupal_valid_test_ua($user_agent) {
-+//  global $dbatabases;
-+  global $db_url;
-+
-+  list($prefix, $time, $salt, $hmac) = explode(';', $user_agent);
-+  $check_string =  $prefix . ';' . $time . ';' . $salt;
-+  // We use the database credentials from settings.php to make the HMAC key, since
-+  // the database is not yet initialized and we can't access any Drupal variables.
-+  // The file properties add more entropy not easily accessible to others.
-+//  $filepath = DRUPAL_ROOT . '/includes/bootstrap.inc';
-+  $filepath = './includes/bootstrap.inc';
-+//  $key = sha1(serialize($databases) . filectime($filepath) . fileinode($filepath), TRUE);
-+  $key = sha1(serialize($db_url) . filectime($filepath) . fileinode($filepath), TRUE);
-+  // The HMAC must match.
-+  return $hmac == base64_encode(hash_hmac('sha1', $check_string, $key, TRUE));
++function drupal_valid_test_ua() {
++  // No reason to reset this.
++  static $test_prefix;
++
++  if (isset($test_prefix)) {
++    return $test_prefix;
++  }
++
++  if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);(.+);(.+);(.+)$/", $_SERVER['HTTP_USER_AGENT'], $matches)) {
++    list(, $prefix, $time, $salt, $hmac) = $matches;
++    $check_string =  $prefix . ';' . $time . ';' . $salt;
++    // We use the salt from settings.php to make the HMAC key, since
++    // the database is not yet initialized and we can't access any Drupal variables.
++    // The file properties add more entropy not easily accessible to others.
++    $key = drupal_get_hash_salt() . filectime(__FILE__) . fileinode(__FILE__);
++    $time_diff = REQUEST_TIME - $time;
++    // Since we are making a local request a 5 second time window is allowed,
++    // and the HMAC must match.
++    if ($time_diff >= 0 && $time_diff <= 5 && $hmac == drupal_hmac_base64($check_string, $key)) {
++      $test_prefix = $prefix;
++      return $test_prefix;
++    }
++  }
++
++  return FALSE;
 +}
 +
 +/**
 + * Generate a user agent string with a HMAC and timestamp for simpletest.
 + */
 +function drupal_generate_test_ua($prefix) {
-+//  global $dbatabases;
-+  global $db_url;
 +  static $key;
 +
 +  if (!isset($key)) {
-+    // We use the database credentials to make the HMAC key, since we
-+    // check the HMAC before the database is initialized. filectime()
-+    // and fileinode() are not easily determined from remote.
-+//    $filepath = DRUPAL_ROOT . '/includes/bootstrap.inc';
-+    $filepath = './includes/bootstrap.inc';
-+//    $key = sha1(serialize($databases) . filectime($filepath) . fileinode($filepath), TRUE);
-+    $key = sha1(serialize($db_url) . filectime($filepath) . fileinode($filepath), TRUE);
++    // We use the salt from settings.php to make the HMAC key, since
++    // the database is not yet initialized and we can't access any Drupal variables.
++    // The file properties add more entropy not easily accessible to others.
++    $key = drupal_get_hash_salt() . filectime(__FILE__) . fileinode(__FILE__);
 +  }
-+   // Generate a moderately secure HMAC based on the database credentials.
-+   $salt = uniqid('', TRUE);
-+   $check_string = $prefix . ';' . time() . ';' . $salt;
-+   return  $check_string . ';' . base64_encode(hash_hmac('sha1', $check_string, $key, TRUE));
++  // Generate a moderately secure HMAC based on the database credentials.
++  $salt = uniqid('', TRUE);
++  $check_string = $prefix . ';' . time() . ';' . $salt;
++  return $check_string . ';' . drupal_hmac_base64($check_string, $key);
++}
++
++function _drupal_bootstrap_simpletest() {
++  // The user agent header is used to pass a database prefix in the request when
++  // running tests. However, for security reasons, it is imperative that we
++  // validate we ourselves made the request.
++  if ($test_prefix = drupal_valid_test_ua()) {
++    // Set the test run id for use in other parts of Drupal.
++    $test_info = &$GLOBALS['drupal_test_info'];
++    $test_info['test_run_id'] = $test_prefix;
++    $test_info['in_child_site'] = TRUE;
++
++    // Extract the current default database prefix.
++    $current_prefix = $GLOBALS['db_prefix'];
++    if (is_array($current_prefix)) {
++      $current_prefix = $current_prefix['default'];
++    }
++
++    // Remove the current database prefix and replace it by our own.
++    $GLOBALS['db_prefix'] = array(
++      'default' => $current_prefix . $test_prefix,
++    );
++  }
++}
++
++/**
++ * Get a salt useful for hardening against SQL injection.
++ *
++ * @return
++ *   A salt based on information in settings.php, not in the database.
++ */
++function drupal_get_hash_salt() {
++  global $drupal_hash_salt, $db_url;
++  // If the $drupal_hash_salt variable is empty, a hash of the serialized
++  // database credentials is used as a fallback salt.
++  return empty($drupal_hash_salt) ? hash('sha256', serialize($db_url)) : $drupal_hash_salt;
 +}
-Index: includes/common.inc
-===================================================================
-RCS file: /cvs/drupal/drupal/includes/common.inc,v
-retrieving revision 1.756.2.98
-diff -u -p -r1.756.2.98 common.inc
---- includes/common.inc	6 Sep 2010 11:13:27 -0000	1.756.2.98
-+++ includes/common.inc	7 Oct 2010 21:55:51 -0000
-@@ -531,7 +531,7 @@ function drupal_http_request($url, $head
+diff --git a/includes/common.inc b/includes/common.inc
+index 3d73784..a3400f6 100644
+--- a/includes/common.inc
++++ b/includes/common.inc
+@@ -530,7 +530,7 @@ function drupal_http_request($url, $headers = array(), $method = 'GET', $data =
    // same time won't interfere with each other as they would if the database
    // prefix were stored statically in a file or database variable.
    if (is_string($db_prefix) && preg_match("/^simpletest\d+$/", $db_prefix, $matches)) {
@@ -122,7 +170,7 @@ diff -u -p -r1.756.2.98 common.inc
    }
  
    foreach ($headers as $header => $value) {
-@@ -2661,14 +2661,24 @@ function _drupal_bootstrap_full() {
+@@ -2662,13 +2662,23 @@ function _drupal_bootstrap_full() {
    require_once './includes/mail.inc';
    require_once './includes/actions.inc';
    // Set the Drupal custom error handler.
@@ -135,21 +183,19 @@ diff -u -p -r1.756.2.98 common.inc
    unicode_check();
    // Undo magic quotes
    fix_gpc_magic();
--  // Load all enabled modules
 +
-+  if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'simpletest') !== FALSE) {
-+    // Valid SimpleTest user-agent, log fatal errors to test specific file
-+    // directory. The user-agent is validated in DRUPAL_BOOTSTRAP_DATABASE
-+    // phase so as long as it is a SimpleTest user-agent it is valid.
++  $test_info = &$GLOBALS['drupal_test_info'];
++  if (!empty($test_info['in_child_site'])) {
++    // Running inside the simpletest child site, log fatal errors to test
++    // specific file directory.
 +    ini_set('log_errors', 1);
-+    ini_set('error_log', file_directory_path() . '/error.log');
++    ini_set('error_log', 'public://error.log');
 +  }
 +
-+// Load all enabled modules
+   // Load all enabled modules
    module_load_all();
    // Let all modules take action before menu system handles the request
-   // We do not want this while running update.php.
-@@ -3789,3 +3799,264 @@ function _drupal_flush_css_js() {
+@@ -3797,3 +3807,268 @@ function _drupal_flush_css_js() {
    }
    variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19));
  }
@@ -411,6 +457,29 @@ diff -u -p -r1.756.2.98 common.inc
 + */
 +function debug($data, $label = NULL, $print_r = FALSE) {
 +  // Print $data contents to string.
-+  $string = $print_r ? print_r($data, TRUE) : var_export($data, TRUE);
++  $string = check_plain($print_r ? print_r($data, TRUE) : var_export($data, TRUE));
++
++  // Display values with pre-formatting to increase readability.
++  $string = '<pre>' . $string . '</pre>';
++
 +  trigger_error(trim($label ? "$label: $string" : $string));
 +}
+diff --git a/install.php b/install.php
+index 8cac289..fd0d48e 100644
+--- a/install.php
++++ b/install.php
+@@ -19,6 +19,14 @@ function install_main() {
+   require_once './includes/bootstrap.inc';
+   drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+ 
++  // The user agent header is used to pass a database prefix in the request when
++  // running tests. However, for security reasons, it is imperative that no
++  // installation be permitted using such a prefix.
++  if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], "simpletest") !== FALSE) {
++    header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
++    exit;
++  }
++
+   // This must go after drupal_bootstrap(), which unsets globals!
+   global $profile, $install_locale, $conf;
+ 
diff --git a/drupal_web_test_case.php b/drupal_web_test_case.php
index f28c3b9..65467d1 100644
--- a/drupal_web_test_case.php
+++ b/drupal_web_test_case.php
@@ -665,11 +665,10 @@ class DrupalUnitTestCase extends DrupalTestCase {
     global $conf;
 
     // Store necessary current values before switching to the test environment.
-    $this->originalPrefix = $GLOBALS['db_prefix'];
     $this->originalFileDirectory =  variable_get('file_directory_path', conf_path() . '/files');
 
     // Generate temporary prefixed database to ensure that tests have a clean starting point.
-    $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000);
+    $this->databasePrefix = db_prefix_tables('{simpletest' . mt_rand(1000, 1000000) . '}');
 
     // Create test directory.
     $public_files_directory = $this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10);
@@ -677,7 +676,17 @@ class DrupalUnitTestCase extends DrupalTestCase {
     $conf['file_directory_path'] = $public_files_directory;
 
     // Clone the current connection and replace the current prefix.
-    $GLOBALS['db_prefix'] = is_array($GLOBALS['db_prefix']) ? $GLOBALS['db_prefix']['default'] : $GLOBALS['db_prefix'] . $this->databasePrefix;
+    $this->originalPrefix = $GLOBALS['db_prefix'];
+    $current_prefix = $GLOBALS['db_prefix'];
+    if (is_array($current_prefix)) {
+      $current_prefix = $current_prefix['default'];
+    }
+    $GLOBALS['db_prefix'] = array(
+      'default' => $current_prefix . $this->databasePrefix,
+    );
+
+    // Set user agent to be consistent with web test case.
+    $_SERVER['HTTP_USER_AGENT'] = $this->databasePrefix;
 
     // If locale is enabled then t() will try to access the database and
     // subsequently will fail as the database is not accessible.
@@ -1205,11 +1214,9 @@ class DrupalWebTestCase extends DrupalTestCase {
 
     // Generate a temporary prefixed database to ensure that tests have a clean starting point.
     $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000);
-    $db_prefix_new = is_array($GLOBALS['db_prefix']) ? $GLOBALS['db_prefix']['default'] : $GLOBALS['db_prefix'] . $this->databasePrefix;
-    db_query("UPDATE {simpletest_test_id} SET last_prefix = '%s' WHERE test_id = %d", $db_prefix_new, $this->testId);
+    db_query("UPDATE {simpletest_test_id} SET last_prefix = '%s' WHERE test_id = %d", $this->databasePrefix, $this->testId);
 
     // Store necessary current values before switching to prefixed database.
-    $this->originalPrefix = $GLOBALS['db_prefix'];
     $this->originalLanguage = $language;
     $this->originalLanguageDefault = variable_get('language_default', (object) array('language' => 'en', 'name' => 'English', 'native' => 'English', 'direction' => 0, 'enabled' => 1, 'plurals' => 0, 'formula' => '', 'domain' => '', 'prefix' => '', 'weight' => 0, 'javascript' => ''));
     $this->originalFileDirectory = variable_get('file_directory_path', conf_path() . '/files');
@@ -1224,10 +1231,17 @@ class DrupalWebTestCase extends DrupalTestCase {
 
     // Workaround to insure we init the theme layer before going into prefixed
     // environment. (Drupal 6)
-    $this->pass(t('Starting run with db_prefix %prefix', array('%prefix' => $db_prefix_new)), 'System');
+    $this->pass(t('Starting run with db_prefix %prefix', array('%prefix' => $this->databasePrefix)), 'System');
 
     // Clone the current connection and replace the current prefix.
-    $GLOBALS['db_prefix'] = $db_prefix_new;
+    $this->originalPrefix = $GLOBALS['db_prefix'];
+    $current_prefix = $GLOBALS['db_prefix'];
+    if (is_array($current_prefix)) {
+      $current_prefix = $current_prefix['default'];
+    }
+    $GLOBALS['db_prefix'] = array(
+      'default' => $current_prefix . $this->databasePrefix,
+    );
 
     // Create test directory ahead of installation so fatal errors and debug
     // information can be logged during installation process.
diff --git a/simpletest.info b/simpletest.info
index 88469ce..d329de4 100644
--- a/simpletest.info
+++ b/simpletest.info
@@ -3,9 +3,6 @@ description = Provides a framework for unit and functional testing.
 package = Development
 core = 6.x
 php = 5.2
-files[] = simpletest.module
-files[] = simpletest.pages.inc
-files[] = simpletest.install
 files[] = simpletest.test
 files[] = drupal_web_test_case.php
 configure = admin/build/testing/settings
diff --git a/simpletest.install b/simpletest.install
index 6c21315..137712f 100644
--- a/simpletest.install
+++ b/simpletest.install
@@ -11,6 +11,11 @@
 define('SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT', '64M');
 
 /**
+ * The current version of the required core patch that must be applied.
+ */
+define('SIMPLETEST_REQUIRED_PATCH_VERSION', '6.2.12');
+
+/**
  * Implements hook_requirements().
  */
 function simpletest_requirements($phase) {
@@ -21,7 +26,6 @@ function simpletest_requirements($phase) {
   $has_hash = function_exists('hash_hmac');
   $has_domdocument = method_exists('DOMDocument', 'loadHTML');
   $open_basedir = ini_get('open_basedir');
-  $patch_installed = isset($GLOBALS['simpletest_installed']);
 
   $requirements['curl'] = array(
     'title' => $t('cURL'),
@@ -66,18 +70,28 @@ function simpletest_requirements($phase) {
   $memory_limit = ini_get('memory_limit');
   if ($memory_limit && $memory_limit != -1 && parse_size($memory_limit) < parse_size(SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT)) {
     $requirements['php_memory_limit']['severity'] = REQUIREMENT_ERROR;
-    $requirements['php_memory_limit']['description'] = t('The testing framework requires the PHP memory limit to be at least %memory_minimum_limit. The current value is %memory_limit. <a href="@url">Follow these steps to continue</a>.', array('%memory_limit' => $memory_limit, '%memory_minimum_limit' => SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT, '@url' => 'http://drupal.org/node/207036'));
+    $requirements['php_memory_limit']['description'] = $t('The testing framework requires the PHP memory limit to be at least %memory_minimum_limit. The current value is %memory_limit. <a href="@url">Follow these steps to continue</a>.', array('%memory_limit' => $memory_limit, '%memory_minimum_limit' => SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT, '@url' => 'http://drupal.org/node/207036'));
   }
 
   // Check that the global variable is defined signifying that the patch
   // was correctly applied to the Drupal 6 core.
-  $requirements['simpletest_patch'] = array(
-    'title' => $t('SimpleTest code addition'),
-    'value' => $patch_installed ? $t('Found') : $t('Not found'),
-  );
-  if (!$patch_installed) {
-    $requirements['simpletest_patch']['severity'] = REQUIREMENT_ERROR;
-    $requirements['simpletest_patch']['description'] = $t('SimpleTest could not be installed. The required core patch must be applied. See the included <a href="@install">INSTALL.txt</a>.', array('@install' => base_path() . drupal_get_path('module', 'simpletest') . '/INSTALL.txt'));
+  if ($phase == 'runtime') {
+    $requirements['simpletest_patch'] = array(
+      'title' => $t('SimpleTest core patch'),
+    );
+    if (!defined('SIMPLETEST_PATCH_VERSION') && !isset($GLOBALS['simpletest_installed'])) {
+      $requirements['simpletest_patch']['value'] = $t('Not applied');
+      $requirements['simpletest_patch']['severity'] = REQUIREMENT_ERROR;
+      $requirements['simpletest_patch']['description'] = $t('The required SimpleTest core patch must be applied. See the included <a href="@install">INSTALL.txt</a>.', array('@install' => base_path() . drupal_get_path('module', 'simpletest') . '/INSTALL.txt'));
+    }
+    elseif (isset($GLOBALS['simpletest_installed']) || SIMPLETEST_PATCH_VERSION !== SIMPLETEST_REQUIRED_PATCH_VERSION) {
+      $requirements['simpletest_patch']['value'] = $t('Needs updating');
+      $requirements['simpletest_patch']['severity'] = REQUIREMENT_ERROR;
+      $requirements['simpletest_patch']['description'] = $t('The required SimpleTest core patch has been changed and needs to be re-applied to core. See the included <a href="@install">INSTALL.txt</a>.', array('@install' => base_path() . drupal_get_path('module', 'simpletest') . '/INSTALL.txt'));
+    }
+    else {
+      $requirements['simpletest_patch']['value'] = $t('Applied (version @version)', array('@version' => SIMPLETEST_PATCH_VERSION));
+    }
   }
 
   return $requirements;
diff --git a/simpletest.module b/simpletest.module
index da3af75..8eeccab 100644
--- a/simpletest.module
+++ b/simpletest.module
@@ -21,9 +21,25 @@ function simpletest_help($path, $arg) {
       $output .= '<dd>' . t('After the tests run, a message will be displayed next to each test group indicating whether tests within it passed, failed, or had exceptions. A pass means that the test returned the expected results, while fail means that it did not. An exception normally indicates an error outside of the test, such as a PHP warning or notice. If there were failures or exceptions, the results will be expanded to show details, and the tests that had failures or exceptions will be indicated in red or pink rows. You can then use these results to refine your code and tests, until all tests pass.') . '</dd>';
       $output .= '</dl>';
       return $output;
+    case 'admin/build/testing':
+      // Check for status report errors.
+      if (simpletest_check_status() && user_access('administer site configuration')) {
+        drupal_set_message(t('One or more problems were detected with your Drupal installation and SimpleTest module. Check the <a href="@status">status report</a> for more information.', array('@status' => url('admin/reports/status'))), 'error');
+      }
+      return;
   }
 }
 
+function simpletest_check_status() {
+  // Load .install files
+  module_load_install('simpletest');
+
+  // Check run-time requirements and status information.
+  $requirements = module_invoke('simpletest', 'requirements', 'runtime');
+  usort($requirements, '_system_sort_requirements');
+  return drupal_requirements_severity($requirements) == REQUIREMENT_ERROR;
+}
+
 /**
  * Implements hook_menu().
  */
diff --git a/simpletest.test b/simpletest.test
index aa9a76e..c097c06 100644
--- a/simpletest.test
+++ b/simpletest.test
@@ -1,5 +1,10 @@
 <?php
 
+/**
+ * @file
+ * Tests for simpletest.module.
+ */
+
 class SimpleTestFunctionalTest extends DrupalWebTestCase {
   /**
    * The results array that has been parsed by getTestResults().
@@ -77,6 +82,43 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
   }
 
   /**
+   * Test validation of the User-Agent header we use to perform test requests.
+   */
+  /*function testUserAgentValidation() {
+    if (!$this->inCURL()) {
+      global $base_url;
+      $simpletest_path = $base_url . '/' . drupal_get_path('module', 'simpletest');
+      $HTTP_path = $simpletest_path .'/tests/http.php?q=node';
+      $https_path = $simpletest_path .'/tests/https.php?q=node';
+      // Generate a valid simpletest User-Agent to pass validation.
+      $this->assertTrue(preg_match('/simpletest\d+/', $this->databasePrefix, $matches), t('Database prefix contains simpletest prefix.'));
+      $test_ua = drupal_generate_test_ua($matches[0]);
+      $this->additionalCurlOptions = array(CURLOPT_USERAGENT => $test_ua);
+
+      // Test pages only available for testing.
+      $this->drupalGet($HTTP_path);
+      $this->assertResponse(200, t('Requesting http.php with a legitimate simpletest User-Agent returns OK.'));
+      $this->drupalGet($https_path);
+      $this->assertResponse(200, t('Requesting https.php with a legitimate simpletest User-Agent returns OK.'));
+
+      // Now slightly modify the HMAC on the header, which should not validate.
+      $this->additionalCurlOptions = array(CURLOPT_USERAGENT => $test_ua . 'X');
+      $this->drupalGet($HTTP_path);
+      $this->assertResponse(403, t('Requesting http.php with a bad simpletest User-Agent fails.'));
+      $this->drupalGet($https_path);
+      $this->assertResponse(403, t('Requesting https.php with a bad simpletest User-Agent fails.'));
+
+      // Use a real User-Agent and verify that the special files http.php and
+      // https.php can't be accessed.
+      $this->additionalCurlOptions = array(CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12');
+      $this->drupalGet($HTTP_path);
+      $this->assertResponse(403, t('Requesting http.php with a normal User-Agent fails.'));
+      $this->drupalGet($https_path);
+      $this->assertResponse(403, t('Requesting https.php with a normal User-Agent fails.'));
+    }
+  }*/
+
+  /**
    * Make sure that tests selected through the web interface are run and
    * that the results are displayed correctly.
    */
@@ -166,7 +208,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
 
     $this->assertAssertion("Debug: 'Foo'", 'Debug', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
 
-    $this->assertEqual('8 passes, 2 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct');
+    $this->assertEqual('7 passes, 2 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct');
 
     $this->test_ids[] = $test_id = $this->getTestIdFromResults();
     $this->assertTrue($test_id, t('Found test ID in results.'));
@@ -273,10 +315,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
    * Check if the test is being run from inside a CURL request.
    */
   function inCURL() {
-    // We cannot rely on drupal_static('drupal_test_info') here, because
-    // 'in_child_site' would be FALSE for the parent site when we are
-    // executing the tests. Default to direct detection of the HTTP headers.
-    return isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^simpletest\d+/", $_SERVER['HTTP_USER_AGENT']);
+    return (bool) drupal_valid_test_ua();
   }
 }
 
