diff --git a/CHANGELOG b/CHANGELOG
index 124d4090661afae2ccd51f3c473b9fcbefa8cd95..753132c35e747e4e50a05dcadd50f6e8b452c373 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@ Drupal x.x.x, xxxx-xx-xx
 ------------------------
 
 - added support for the MetaWeblog API and MoveableType extensions.
+- performance:
+    * improved module loading when serving cached pages.
 - theme system:
     * made all theme functions start with 'theme_'.
     * made all theme functions return their output.
diff --git a/cron.php b/cron.php
index a65351ae106cd51605890eff1fb5fa1bea63994a..d7e17082017f1bd4eccfcc039e4603a84a6ab4dd 100644
--- a/cron.php
+++ b/cron.php
@@ -1,6 +1,7 @@
 <?php
 // $Id$
 
+include_once "includes/bootstrap.inc";
 include_once "includes/common.inc";
 
 /*
diff --git a/database/database.mssql b/database/database.mssql
index 353f4ecce8fb3025b355fdf0571a30fb5acefc20..d944effa5f3bb65561a8d744360d322b647bd344 100644
--- a/database/database.mssql
+++ b/database/database.mssql
@@ -299,6 +299,7 @@ CREATE TABLE [dbo].[system] (
   [type] [varchar] (255) NOT NULL ,
   [description] [varchar] (255) NOT NULL ,
   [status] [int] NOT NULL
+  [bootstrap] [int] NOT NULL
 ) ON [PRIMARY]
 GO
 
diff --git a/database/database.mysql b/database/database.mysql
index 19c31faddc9ed964b4dc73ff45e157a5178244fb..75b6d0ff2d72a6fc0e882b9479dbc34d16b54af8 100644
--- a/database/database.mysql
+++ b/database/database.mysql
@@ -426,6 +426,7 @@ CREATE TABLE system (
   type varchar(255) NOT NULL default '',
   description varchar(255) NOT NULL default '',
   status int(2) NOT NULL default '0',
+  bootstrap int(2) NOT NULL default '0',
   PRIMARY KEY  (filename)
 ) TYPE=MyISAM;
 
diff --git a/database/database.pgsql b/database/database.pgsql
index ec541ccb09168a8351f8c6ce64f23f34efe0a8e0..be0193d3659c6fbabcccc687f0a1541aac174e88 100644
--- a/database/database.pgsql
+++ b/database/database.pgsql
@@ -422,6 +422,7 @@ CREATE TABLE system (
   type varchar(255) NOT NULL default '',
   description varchar(255) NOT NULL default '',
   status integer NOT NULL default '0',
+  bootstrap integer NOT NULL default '0',
   PRIMARY KEY  (filename)
 );
 
diff --git a/error.php b/error.php
index 0433593d595bf7847af97a292876370e5f575332..072f7b1265cba0df75fa19500af38b93dbc7a98d 100644
--- a/error.php
+++ b/error.php
@@ -1,6 +1,7 @@
 <?php
 // $Id$
 
+include_once "includes/bootstrap.inc";
 include_once "includes/common.inc";
 
 $errors = array(
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
new file mode 100644
index 0000000000000000000000000000000000000000..c13f1b8b7d23c63a32b7ed084614ebc8309e8e6d
--- /dev/null
+++ b/includes/bootstrap.inc
@@ -0,0 +1,226 @@
+<?php
+
+function conf_init() {
+
+  /*
+  ** Try finding a matching configuration file by stripping the website's
+  ** URI from left to right.  If no configuration file is found, return a
+  ** default value 'conf'.
+  */
+
+  $uri = $_SERVER["PHP_SELF"];
+
+  $file = strtolower(strtr($_SERVER["HTTP_HOST"] . substr($uri, 0, strrpos($uri, "/")), "/:", ".."));
+
+  while (strlen($file) > 4) {
+    if (file_exists("includes/$file.php")) {
+      return $file;
+    }
+    else {
+      $file = substr($file, strpos($file, ".") + 1);
+    }
+  }
+
+  return "conf";
+}
+
+function variable_init($conf = array()) {
+  $result = db_query("SELECT * FROM {variable} ");
+  while ($variable = db_fetch_object($result)) {
+    if (!isset($conf[$variable->name])) {
+      $conf[$variable->name] = unserialize($variable->value);
+    }
+  }
+
+  return $conf;
+}
+
+function variable_get($name, $default) {
+  global $conf;
+
+  return isset($conf[$name]) ? $conf[$name] : $default;
+}
+
+function variable_set($name, $value) {
+  global $conf;
+
+  db_query("DELETE FROM {variable} WHERE name = '%s'", $name);
+  db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, serialize($value));
+
+  $conf[$name] = $value;
+}
+
+function variable_del($name) {
+  global $conf;
+
+  db_query("DELETE FROM {variable} WHERE name = '%s'", $name);
+
+  unset($conf[$name]);
+}
+
+function cache_get($key) {
+  $cache = db_fetch_object(db_query("SELECT data, created FROM {cache} WHERE cid = '%s'", $key));
+  return $cache->data ? $cache : 0;
+}
+
+function cache_set($cid, $data, $expire = 0) {
+  db_query("UPDATE {cache} SET data = '%s', created = %d, expire = %d WHERE cid = '%s'", $data, time(), $expire, $cid);
+  if (!db_affected_rows()) {
+    db_query("INSERT INTO {cache} (cid, data, created, expire) VALUES('%s', '%s', %d, %d)", $cid, $data, time(), $expire);
+  }
+}
+
+function cache_clear_all($cid = NULL) {
+  if (empty($cid)) {
+    db_query("DELETE FROM {cache} WHERE expire <> 0");
+  }
+  else {
+    db_query("DELETE FROM {cache} WHERE cid = '%s'", $cid);
+  }
+}
+
+function page_set_cache() {
+  global $user;
+
+  if (!$user->uid && $_SERVER["REQUEST_METHOD"] == "GET") {
+    if ($data = ob_get_contents()) {
+      cache_set(request_uri(), $data, 1);
+    }
+  }
+}
+
+function page_get_cache() {
+  global $user;
+
+  $cache = NULL;
+
+  if (!$user->uid && $_SERVER["REQUEST_METHOD"] == "GET") {
+    $cache = cache_get(request_uri());
+
+    if (empty($cache)) {
+      ob_start();
+    }
+  }
+
+  return $cache;
+}
+
+function drupal_page_header() {
+
+  if (variable_get("dev_timer", 0)) {
+    timer_start();
+  }
+
+  if (variable_get("cache", 0)) {
+    if ($cache = page_get_cache()) {
+
+      // Set default values:
+      $date = gmdate("D, d M Y H:i:s", $cache->created) ." GMT";
+      $etag = '"'. md5($date) .'"';
+
+      // Check http headers:
+      $modified_since = isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) ? $_SERVER["HTTP_IF_MODIFIED_SINCE"] == $date : NULL;
+      $none_match = isset($_SERVER["HTTP_IF_NONE_MATCH"]) ? $_SERVER["HTTP_IF_NONE_MATCH"] == $etag : NULL;
+
+      // The type checking here is very important, be careful when changing entries.
+      if (($modified_since !== NULL || $none_match !== NULL) && $modified_since !== false && $none_match !== false) {
+        header("HTTP/1.0 304 Not Modified");
+        exit();
+      }
+
+      // Send appropriate response:
+      header("Last-Modified: $date");
+      header("ETag: $etag");
+      print $cache->data;
+
+      /*
+      ** call all init() and exit() hooks without including all modules
+      ** only use those hooks for critical operations
+      */
+      foreach (module_list(0, 1) as $module) {
+        if (is_array($module) && $module['bootstrap']) {
+          include_once $module['filename'];
+          foreach (bootstrap_hooks() as $hook) {
+            module_invoke($module['name'], $hook);
+          }
+        }
+      }
+      exit();
+    }
+  }
+}
+
+// critical hooks called even when serving a cached page
+function bootstrap_hooks() {
+  return array('init', 'exit');
+}
+
+function referer_uri() {
+
+  if (isset($_SERVER["HTTP_REFERER"])) {
+    $uri = $_SERVER["HTTP_REFERER"];
+
+    return check_url($uri);
+  }
+}
+
+function arg($index) {
+
+  static $arguments;
+
+  if (empty($arguments)) {
+    $arguments = explode("/", $_GET["q"]);
+  }
+
+  return $arguments[$index];
+}
+
+function check_query($text) {
+  return addslashes($text);
+}
+
+function check_url($uri) {
+  $uri = htmlspecialchars($uri, ENT_QUOTES);
+
+  /*
+  ** We replace ( and ) with their entity equivalents to prevent XSS
+  ** attacks.
+  */
+
+  $uri = strtr($uri, array("(" => "&040;", ")" => "&041;"));
+
+  return $uri;
+}
+
+function request_uri() {
+  /*
+  ** Since request_uri() is only available on Apache, we generate
+  ** equivalent using other environment vars.
+  */
+
+  if (isset($_SERVER["REQUEST_URI"])) {
+    $uri = $_SERVER["REQUEST_URI"];
+  }
+  else {
+    $uri = $_SERVER["PHP_SELF"] ."?". $_SERVER["QUERY_STRING"];
+  }
+
+  return check_url($uri);
+}
+function timer_start() {
+  global $timer;
+  list($usec, $sec) = explode(" ", microtime());
+  $timer = (float)$usec + (float)$sec;
+}
+
+unset($conf);
+$config = conf_init();
+
+include_once "includes/$config.php";
+include_once "includes/database.inc";
+include_once "includes/session.inc";
+include_once "includes/module.inc";
+
+// initialize configuration variables, using values from conf.php if available:
+$conf = variable_init(isset($conf) ? $conf : array());
+?>
diff --git a/includes/common.inc b/includes/common.inc
index 5c4835b197b62c814e5c5b2caead47bc302dbf5b..2a67db247411cfacc64d9c5578a4769e62b7b7c0 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -1,30 +1,6 @@
 <?php
 // $Id$
 
-function conf_init() {
-
-  /*
-  ** Try finding a matching configuration file by stripping the website's
-  ** URI from left to right.  If no configuration file is found, return a
-  ** default value 'conf'.
-  */
-
-  $uri = $_SERVER["PHP_SELF"];
-
-  $file = strtolower(strtr($_SERVER["HTTP_HOST"] . substr($uri, 0, strrpos($uri, "/")), "/:", ".."));
-
-  while (strlen($file) > 4) {
-    if (file_exists("includes/$file.php")) {
-      return $file;
-    }
-    else {
-      $file = substr($file, strpos($file, ".") + 1);
-    }
-  }
-
-  return "conf";
-}
-
 /**
  * Build the alias/path array
  */
@@ -100,17 +76,6 @@ function fix_gpc_magic() {
   $fixed = true;
 }
 
-function arg($index) {
-
-  static $arguments;
-
-  if (empty($arguments)) {
-    $arguments = explode("/", $_GET["q"]);
-  }
-
-  return $arguments[$index];
-}
-
 function array2object($node) {
 
   if (is_array($node)) {
@@ -139,31 +104,6 @@ function object2array($node) {
   return $array;
 }
 
-function referer_uri() {
-
-  if (isset($_SERVER["HTTP_REFERER"])) {
-    $uri = $_SERVER["HTTP_REFERER"];
-
-    return check_url($uri);
-  }
-}
-
-function request_uri() {
-  /*
-  ** Since request_uri() is only available on Apache, we generate
-  ** equivalent using other environment vars.
-  */
-
-  if (isset($_SERVER["REQUEST_URI"])) {
-    $uri = $_SERVER["REQUEST_URI"];
-  }
-  else {
-    $uri = $_SERVER["PHP_SELF"] ."?". $_SERVER["QUERY_STRING"];
-  }
-
-  return check_url($uri);
-}
-
 function message_access() {
   return t("You are not authorized to access this page.");
 }
@@ -210,40 +150,6 @@ function t($string, $args = 0) {
   }
 }
 
-function variable_init($conf = array()) {
-  $result = db_query("SELECT * FROM {variable} ");
-  while ($variable = db_fetch_object($result)) {
-    if (!isset($conf[$variable->name])) {
-      $conf[$variable->name] = unserialize($variable->value);
-    }
-  }
-
-  return $conf;
-}
-
-function variable_get($name, $default) {
-  global $conf;
-
-  return isset($conf[$name]) ? $conf[$name] : $default;
-}
-
-function variable_set($name, $value) {
-  global $conf;
-
-  db_query("DELETE FROM {variable} WHERE name = '%s'", $name);
-  db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, serialize($value));
-
-  $conf[$name] = $value;
-}
-
-function variable_del($name) {
-  global $conf;
-
-  db_query("DELETE FROM {variable} WHERE name = '%s'", $name);
-
-  unset($conf[$name]);
-}
-
 function drupal_specialchars($input, $quotes = ENT_NOQUOTES) {
 
   /*
@@ -476,27 +382,10 @@ function valid_input_data($data) {
   return 1;
 }
 
-function check_url($uri) {
-  $uri = htmlspecialchars($uri, ENT_QUOTES);
-
-  /*
-  ** We replace ( and ) with their entity equivalents to prevent XSS
-  ** attacks.
-  */
-
-  $uri = strtr($uri, array("(" => "&040;", ")" => "&041;"));
-
-  return $uri;
-}
-
 function check_form($text) {
   return drupal_specialchars($text, ENT_QUOTES);
 }
 
-function check_query($text) {
-  return addslashes($text);
-}
-
 function filter($text) {
 
   $modules = module_list();
@@ -672,53 +561,6 @@ function format_size($size) {
   return t("%size %suffix", array("%size" => $size, "%suffix" => $suffix));
 }
 
-function cache_get($key) {
-  $cache = db_fetch_object(db_query("SELECT data, created FROM {cache} WHERE cid = '%s'", $key));
-  return $cache->data ? $cache : 0;
-}
-
-function cache_set($cid, $data, $expire = 0) {
-  db_query("UPDATE {cache} SET data = '%s', created = %d, expire = %d WHERE cid = '%s'", $data, time(), $expire, $cid);
-  if (!db_affected_rows()) {
-    db_query("INSERT INTO {cache} (cid, data, created, expire) VALUES('%s', '%s', %d, %d)", $cid, $data, time(), $expire);
-  }
-}
-
-function cache_clear_all($cid = NULL) {
-  if (empty($cid)) {
-    db_query("DELETE FROM {cache} WHERE expire <> 0");
-  }
-  else {
-    db_query("DELETE FROM {cache} WHERE cid = '%s'", $cid);
-  }
-}
-
-function page_set_cache() {
-  global $user;
-
-  if (!$user->uid && $_SERVER["REQUEST_METHOD"] == "GET") {
-    if ($data = ob_get_contents()) {
-      cache_set(request_uri(), $data, 1);
-    }
-  }
-}
-
-function page_get_cache() {
-  global $user;
-
-  $cache = NULL;
-
-  if (!$user->uid && $_SERVER["REQUEST_METHOD"] == "GET") {
-    $cache = cache_get(request_uri());
-
-    if (empty($cache)) {
-      ob_start();
-    }
-  }
-
-  return $cache;
-}
-
 function format_interval($timestamp) {
   $units = array("1 year|%count years" => 31536000, "1 week|%count weeks" => 604800, "1 day|%count days" => 86400, "1 hour|%count hours" => 3600, "1 min|%count min" => 60, "1 sec|%count sec" => 1);
   foreach ($units as $key=>$value) {
@@ -1005,64 +847,6 @@ function link_node($node, $main = 0) {
   return module_invoke_all("link", "node", $node, $main);
 }
 
-function timer_start() {
-  global $timer;
-  list($usec, $sec) = explode(" ", microtime());
-  $timer = (float)$usec + (float)$sec;
-}
-
-function drupal_page_header() {
-
-  if (variable_get("dev_timer", 0)) {
-    timer_start();
-  }
-
-  if (variable_get("cache", 0)) {
-    if ($cache = page_get_cache()) {
-
-      // Set default values:
-      $date = gmdate("D, d M Y H:i:s", $cache->created) ." GMT";
-      $etag = '"'. md5($date) .'"';
-
-      // Check http headers:
-      $modified_since = isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) ? $_SERVER["HTTP_IF_MODIFIED_SINCE"] == $date : NULL;
-      $none_match = isset($_SERVER["HTTP_IF_NONE_MATCH"]) ? $_SERVER["HTTP_IF_NONE_MATCH"] == $etag : NULL;
-
-      // The type checking here is very important, be careful when changing entries.
-      if (($modified_since !== NULL || $none_match !== NULL) && $modified_since !== false && $none_match !== false) {
-        header("HTTP/1.0 304 Not Modified");
-        exit();
-      }
-
-      // Send appropriate response:
-      header("Last-Modified: $date");
-      header("ETag: $etag");
-      print $cache->data;
-
-      /*
-      ** A hook for modules where modules may take action at the end of a
-      ** request good uses include setting a cache, page logging, etc.
-      */
-
-      module_invoke_all("exit");
-
-      exit();
-    }
-  }
-
-  /*
-  ** Putting the check here avoids SQL query overhead in case we are
-  ** serving cached pages.  The downside, however, is that the init
-  ** hooks might use unchecked data.
-  */
-
-  if (!user_access("bypass input data check")) {
-    if (!valid_input_data($_REQUEST)) {
-      die("terminated request because of suspicious input data");
-    }
-  }
-}
-
 function drupal_page_footer() {
   if (variable_get("cache", 0)) {
     page_set_cache();
@@ -1076,22 +860,12 @@ function drupal_page_footer() {
   module_invoke_all("exit");
 }
 
-unset($conf);
-
-$config = conf_init();
-
-include_once "includes/$config.php";
-include_once "includes/database.inc";
-include_once "includes/module.inc";
 include_once "includes/theme.inc";
 include_once "includes/pager.inc";
 include_once "includes/menu.inc";
 include_once "includes/xmlrpc.inc";
 include_once "includes/tablesort.inc";
 
-// initialize configuration variables, using values from conf.php if available:
-$conf = variable_init(isset($conf) ? $conf : array());
-
 // set error handler:
 set_error_handler("error_handler");
 
@@ -1116,9 +890,16 @@ function drupal_page_footer() {
 // initialize installed modules:
 module_init();
 
+if (!user_access("bypass input data check")) {
+  if (!valid_input_data($_REQUEST)) {
+    die("terminated request because of suspicious input data");
+  }
+}
+
 // initialize localization system:
 $locale = locale_init();
 
 // initialize theme:
 $theme = init_theme();
+
 ?>
diff --git a/includes/module.inc b/includes/module.inc
index e80384343e615e43cfd3f0fca2387c06ff8a3c52..787f072f26b479b274f1d567b5721edcdc2881b8 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -40,8 +40,8 @@ function module_invoke_all($hook, $a1 = NULL, $a2 = NULL, $a3 = NULL, $a4 = NULL
   return $return;
 }
 
-// return array of module names (includes lazy module loading):
-function module_list($refresh = 0) {
+// return array of module names (includes lazy module loading if not in bootstrap mode)
+function module_list($refresh = 0, $bootstrap = 0) {
   static $list;
 
   if ($refresh) {
@@ -50,16 +50,20 @@ function module_list($refresh = 0) {
 
   if (!$list) {
     $list = array("admin" => "admin", "system" => "system", "user" => "user", "watchdog" => "watchdog");
-    $result = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = '1' ORDER BY name");
+    $result = db_query("SELECT name, filename, bootstrap FROM {system} WHERE type = 'module' AND status = '1' ORDER BY name");
     while ($module = db_fetch_object($result)) {
       if (file_exists($module->filename)) {
-        $list[$module->name] = $module->name;
-        include_once $module->filename;
+        if ($bootstrap) {
+          $list[$module->name] = array("name"=> $module->name, "bootstrap" => $module->bootstrap, "filename" => $module->filename);
+        }
+        else {
+          $list[$module->name] = $module->name;
+          include_once $module->filename;
+        }
       }
     }
     natcasesort($list);
   }
-
   return $list;
 }
 
diff --git a/includes/session.inc b/includes/session.inc
new file mode 100644
index 0000000000000000000000000000000000000000..5b1389a2322557ae46dca703e97c12a41571854d
--- /dev/null
+++ b/includes/session.inc
@@ -0,0 +1,66 @@
+<?php
+
+session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
+session_start();
+
+/*** Session functions *****************************************************/
+
+function sess_open($save_path, $session_name) {
+  return 1;
+}
+
+function sess_close() {
+  return 1;
+}
+
+function sess_read($key) {
+  global $user;
+
+  $result = db_query_range("SELECT u.*, s.*, r.name AS role FROM {users} u INNER JOIN {role} r ON u.rid = r.rid INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '". check_query($key) ."' AND u.status < 3", 0, 1);
+  $user = db_fetch_object($result);
+  if ($user->data && $data = unserialize($user->data)) {
+    foreach ($data as $key => $value) {
+      if (!isset($user->$key)) {
+        $user->$key = $value;
+      }
+    }
+  }
+
+  return !empty($user->session) ? $user->session : '';
+}
+
+function sess_write($key, $value) {
+  global $user;
+
+  db_query("UPDATE {sessions} SET uid = %d, hostname = '%s', session = '%s', timestamp = %d WHERE sid = '$key'", $user->uid, $_SERVER["REMOTE_ADDR"], $value, time());
+
+  if (!db_affected_rows()) {
+    db_query("INSERT INTO {sessions} (uid, sid, hostname, session, timestamp) values(%d, '%s', '%s', '%s', %d)", $user->uid, $key, $_SERVER["REMOTE_ADDR"], $value, time());
+  }
+
+  return '';
+}
+
+function sess_destroy($key) {
+
+  db_query("DELETE FROM {sessions} WHERE sid = '$key'");
+
+}
+
+function sess_gc($lifetime) {
+
+  /*
+  **  Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
+  **   value.  For example, if you want user sessions to stay in your database
+  **   for three weeks before deleting them, you need to set gc_maxlifetime
+  **   to '1814400'.  At that value, only after a user doesn't log in after
+  **   three weeks (1814400 seconds) will his/her session be removed.
+  */
+  db_query("DELETE FROM {sessions} WHERE timestamp < %d", time() - $lifetime);
+
+  return 1;
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/index.php b/index.php
index f75d50b7ad69e018ef0f1394f9ede7357b07a904..6493bdfd040c14399cbb3064e517dc917608fb4a 100644
--- a/index.php
+++ b/index.php
@@ -1,6 +1,8 @@
 <?php
 // $Id$
 
+include_once "includes/bootstrap.inc";
+drupal_page_header();
 include_once "includes/common.inc";
 
 drupal_page_header();
diff --git a/misc/drupal.css b/misc/drupal.css
index 4c478e5beedc23018f80c4c270b13f00e23c30b7..f40610a9ddd735090d946ccabd98535232c1c627 100644
--- a/misc/drupal.css
+++ b/misc/drupal.css
@@ -10,7 +10,7 @@ th {
   border-bottom: 1px solid #ccc;
 }
 fieldset {
-  display: inline;
+  margin-bottom: 1em;
 }
 #tracker table {
   border-collapse: collapse;
diff --git a/modules/system.module b/modules/system.module
index c67722ad2f4e6148e09c59331e341ecb2f2e6d2d..67533f1d60cd678087b2a671a4c9d2c9acb40fd6 100644
--- a/modules/system.module
+++ b/modules/system.module
@@ -57,7 +57,8 @@ function system_link($type) {
       menu("admin/system", t("configuration"), "system_admin", 3);
       menu("admin/system/themes", t("themes"), "system_admin", 2);
 
-      foreach (list_themes(1) as $theme) {
+      foreach (list_themes() as $theme) {
+        // TODO: reenable 'forced refresh' once we move the menu_build() later in the request. it added overhead with no benefit
         // NOTE: refresh the list because some themes might have been enabled/disabled.
         include_once "$theme->filename";
         $function = $theme->name ."_settings";
@@ -67,7 +68,8 @@ function system_link($type) {
       }
 
       menu("admin/system/modules", t("modules"), "system_admin", 3);
-      foreach (module_list(1) as $name) {
+      foreach (module_list() as $name) {
+        // TODO: reenable 'forced refresh' once we move the menu_build() later in the request.  it added overhead with no benefit
         // NOTE: refresh the list because some modules might have been enabled/disabled.
         if (module_hook($name, "settings")) {
           menu("admin/system/modules/$name", t($name), "system_admin");
@@ -103,32 +105,31 @@ function system_view_general() {
   global $conf;
 
   // general settings:
-  $output .= "<h3>". t("General settings") ."</h3>\n";
-  $output .= form_textfield(t("Name"), "site_name", variable_get("site_name", "drupal"), 70, 70, t("The name of this web site."));
-  $output .= form_textfield(t("E-mail address"), "site_mail", variable_get("site_mail", ini_get("sendmail_from")), 70, 128, t("A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc."));
-  $output .= form_textfield(t("Slogan"), "site_slogan", variable_get("site_slogan", ""), 70, 128, t("The slogan of this website. Some themes display a slogan when available."));
-  $output .= form_textarea(t("Mission"), "site_mission", variable_get("site_mission", ""), 70, 5, t("Your site's mission statement or focus."));
-  $output .= form_textarea(t("Footer message"), "site_footer", variable_get("site_footer", ""), 70, 5, t("This text will be displayed at the bottom of each page.  Useful for adding a copyright notice to your pages."));
-  $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 70, 70, t("The name used to indicate anonymous users."));
-  $output .= form_textfield(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), 70, 70, t("The home page displays content from this relative URL.  If you are not using clean URLs, specify the part after '?q='.  If unsure, specify 'node'."));
-  $output .= form_radios(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs.  If enabled, you'll need <code>ModRewrite</code> support.  See also the <code>.htaccess</code> file in Drupal's top-level directory."));
-  $output .= "<hr />\n";
+  $group  = form_textfield(t("Name"), "site_name", variable_get("site_name", "drupal"), 70, 70, t("The name of this web site."));
+  $group .= form_textfield(t("E-mail address"), "site_mail", variable_get("site_mail", ini_get("sendmail_from")), 70, 128, t("A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc."));
+  $group .= form_textfield(t("Slogan"), "site_slogan", variable_get("site_slogan", ""), 70, 128, t("The slogan of this website. Some themes display a slogan when available."));
+  $group .= form_textarea(t("Mission"), "site_mission", variable_get("site_mission", ""), 70, 5, t("Your site's mission statement or focus."));
+  $group .= form_textarea(t("Footer message"), "site_footer", variable_get("site_footer", ""), 70, 5, t("This text will be displayed at the bottom of each page.  Useful for adding a copyright notice to your pages."));
+  $group .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 70, 70, t("The name used to indicate anonymous users."));
+  $group .= form_textfield(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), 70, 70, t("The home page displays content from this relative URL.  If you are not using clean URLs, specify the part after '?q='.  If unsure, specify 'node'."));
+  $group .= form_radios(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs.  If enabled, you'll need <code>ModRewrite</code> support.  See also the <code>.htaccess</code> file in Drupal's top-level directory."));
+
+  $output = form_group(t("General settings"), $group);
 
   // caching:
-  $output .= "<h3>". t("Cache settings") ."</h3>\n";
-  $output .= form_radios(t("Cache support"), "cache", variable_get("cache", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable the caching of rendered pages.  When caching is enabled, Drupal will flush the cache when required to make sure updates take effect immediately.  Check the %documentation for information on Drupal's cache system.", array("%documentation" => l(t("cache documentation"), "admin/system/help#cache"))));
-  $output .= "<hr />\n";
+  $group  = form_radios(t("Cache support"), "cache", variable_get("cache", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable the caching of rendered pages.  When caching is enabled, Drupal will flush the cache when required to make sure updates take effect immediately.  Check the %documentation for information on Drupal's cache system.", array("%documentation" => l(t("cache documentation"), "admin/system/help#cache"))));
+
+  $output .= form_group(t("Cache settings"), $group);
 
 
   // submission settings:
-  $output .= "<h3>". t("Submission settings") ."</h3>\n";
   $rate = array(-10000 => t("Disabled"), 1 => t("Maximum 1 every second"), 5 => t("Maximum 1 every 5 seconds"), 15 => t("Maximum 1 every 15 seconds"), 30 => t("Maximum 1 every 30 seconds"), 60 => t("Maximum 1 every minute"), 300 => t("Maximum 1 every 5 minutes"), 900 => t("Maximum 1 every 15 minutes"), 1800 => t("Maximum 1 every 30 minutes"), 3600 => t("Maximum 1 every hour"), 21600 => t("Maximum 1 every 6 hours"), 43200 => t("Maximum 1 every 12 hours"));
-  $output .= form_select(t("Maximum node rate"), "max_node_rate", variable_get("max_node_rate", 900), $rate, t("The maximum submission rate for nodes.  Its purpose is to stop potential abuse or denial of service attacks."));
-  $output .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get("max_comment_rate", 120), $rate, t("The maximum submission rate for comments.  Its purpose is to stop potential abuse or denial of service attacks."));
-  $output .= "<hr />\n";
+  $group  = form_select(t("Maximum node rate"), "max_node_rate", variable_get("max_node_rate", 900), $rate, t("The maximum submission rate for nodes.  Its purpose is to stop potential abuse or denial of service attacks."));
+  $group .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get("max_comment_rate", 120), $rate, t("The maximum submission rate for comments.  Its purpose is to stop potential abuse or denial of service attacks."));
+
+  $output .= form_group(t("Submission settings"), $group);
 
   // date settings:
-  $output .= "<h3>". t("Date format settings") ."</h3>\n";
 
   // date settings: possible date formats
   $dateshort = array("m/d/Y - H:i", "d/m/Y - H:i", "Y/m/d - H:i",
@@ -153,17 +154,12 @@ function system_view_general() {
     $datelongchoices[$f] = format_date(time(), "custom", $f);
   }
 
-  $output .= form_select(t("Date format (short)"), "date_format_short", variable_get("date_format_short", $dateshort[0]), $dateshortchoices, t("The short format of date display."));
-  $output .= form_select(t("Date format (medium)"), "date_format_medium", variable_get("date_format_medium", $datemedium[0]), $datemediumchoices, t("The medium sized date display."));
-  $output .= form_select(t("Date format (long)"), "date_format_long", variable_get("date_format_long", $datelong[0]), $datelongchoices, t("Longer date format used for detailed display."));
+  $group  = form_select(t("Date format (short)"), "date_format_short", variable_get("date_format_short", $dateshort[0]), $dateshortchoices, t("The short format of date display."));
+  $group .= form_select(t("Date format (medium)"), "date_format_medium", variable_get("date_format_medium", $datemedium[0]), $datemediumchoices, t("The medium sized date display."));
+  $group .= form_select(t("Date format (long)"), "date_format_long", variable_get("date_format_long", $datelong[0]), $datelongchoices, t("Longer date format used for detailed display."));
 
-  return $output;
-}
+  $output .= form_group(t("Date format settings"), $group);
 
-function system_view_module($name) {
-  if (module_hook($name, "settings")) {
-      $output .= "<h3><a id=\"$name\">". ucfirst(t("$name")) ." ". t("settings") ."</a></h3>". module_invoke($name, "settings") ."<hr />\n";
-  }
   return $output;
 }
 
@@ -228,7 +224,7 @@ function system_view($type, $arg = "") {
       break;
     case "modules":
       if ($arg) {
-        $form = system_view_module($arg);
+        $form = module_invoke($arg, "settings");
       }
       else {
         $form = system_listing("module", "modules", $required);
@@ -299,6 +295,14 @@ function system_listing($type, $directory, $required = array()) {
     if ($type == "module") {
       $info->name = module_invoke($file->name, "help", "admin/system/modules#name") ? module_invoke($file->name, "help", "admin/system/modules#name") : module_invoke($file->name, "system", "name") ? module_invoke($file->name, "system", "name") : $file->name;
       $info->description = module_invoke($file->name, "help", "admin/system/modules#description") ? module_invoke($file->name, "help", "admin/system/modules#description") : module_invoke($file->name, "system", "description");
+      // log the critical hooks implemented by this module
+      $bootstrap = 0;
+      foreach (bootstrap_hooks() as $hook) {
+        if (module_hook($file->name, $hook)) {
+          $bootstrap = 1;
+          break;
+        }
+      }
     }
     elseif ($type == "theme") {
         $info->name = $file->name;
@@ -308,7 +312,7 @@ function system_listing($type, $directory, $required = array()) {
 
     // Update the contents of the system table:
     db_query("DELETE FROM {system} WHERE filename = '%s' AND type = '%s'", $filename, $type);
-    db_query("INSERT INTO {system} (name, description, type, filename, status) VALUES ('%s', '%s', '%s', '%s', %d)", $info->name, $info->description, $type, $filename, $file->status);
+    db_query("INSERT INTO {system} (name, description, type, filename, status, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d)", $info->name, $info->description, $type, $filename, $file->status, $bootstrap);
 
     $rows[] = array($info->name, $info->description, array("data" => (in_array($filename, $required) ? form_hidden("status][$filename", 1) . t("required") : form_checkbox("", "status][$filename", 1, $file->status)), "align" => "center"));
   }
diff --git a/modules/system/system.module b/modules/system/system.module
index c67722ad2f4e6148e09c59331e341ecb2f2e6d2d..67533f1d60cd678087b2a671a4c9d2c9acb40fd6 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -57,7 +57,8 @@ function system_link($type) {
       menu("admin/system", t("configuration"), "system_admin", 3);
       menu("admin/system/themes", t("themes"), "system_admin", 2);
 
-      foreach (list_themes(1) as $theme) {
+      foreach (list_themes() as $theme) {
+        // TODO: reenable 'forced refresh' once we move the menu_build() later in the request. it added overhead with no benefit
         // NOTE: refresh the list because some themes might have been enabled/disabled.
         include_once "$theme->filename";
         $function = $theme->name ."_settings";
@@ -67,7 +68,8 @@ function system_link($type) {
       }
 
       menu("admin/system/modules", t("modules"), "system_admin", 3);
-      foreach (module_list(1) as $name) {
+      foreach (module_list() as $name) {
+        // TODO: reenable 'forced refresh' once we move the menu_build() later in the request.  it added overhead with no benefit
         // NOTE: refresh the list because some modules might have been enabled/disabled.
         if (module_hook($name, "settings")) {
           menu("admin/system/modules/$name", t($name), "system_admin");
@@ -103,32 +105,31 @@ function system_view_general() {
   global $conf;
 
   // general settings:
-  $output .= "<h3>". t("General settings") ."</h3>\n";
-  $output .= form_textfield(t("Name"), "site_name", variable_get("site_name", "drupal"), 70, 70, t("The name of this web site."));
-  $output .= form_textfield(t("E-mail address"), "site_mail", variable_get("site_mail", ini_get("sendmail_from")), 70, 128, t("A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc."));
-  $output .= form_textfield(t("Slogan"), "site_slogan", variable_get("site_slogan", ""), 70, 128, t("The slogan of this website. Some themes display a slogan when available."));
-  $output .= form_textarea(t("Mission"), "site_mission", variable_get("site_mission", ""), 70, 5, t("Your site's mission statement or focus."));
-  $output .= form_textarea(t("Footer message"), "site_footer", variable_get("site_footer", ""), 70, 5, t("This text will be displayed at the bottom of each page.  Useful for adding a copyright notice to your pages."));
-  $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 70, 70, t("The name used to indicate anonymous users."));
-  $output .= form_textfield(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), 70, 70, t("The home page displays content from this relative URL.  If you are not using clean URLs, specify the part after '?q='.  If unsure, specify 'node'."));
-  $output .= form_radios(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs.  If enabled, you'll need <code>ModRewrite</code> support.  See also the <code>.htaccess</code> file in Drupal's top-level directory."));
-  $output .= "<hr />\n";
+  $group  = form_textfield(t("Name"), "site_name", variable_get("site_name", "drupal"), 70, 70, t("The name of this web site."));
+  $group .= form_textfield(t("E-mail address"), "site_mail", variable_get("site_mail", ini_get("sendmail_from")), 70, 128, t("A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc."));
+  $group .= form_textfield(t("Slogan"), "site_slogan", variable_get("site_slogan", ""), 70, 128, t("The slogan of this website. Some themes display a slogan when available."));
+  $group .= form_textarea(t("Mission"), "site_mission", variable_get("site_mission", ""), 70, 5, t("Your site's mission statement or focus."));
+  $group .= form_textarea(t("Footer message"), "site_footer", variable_get("site_footer", ""), 70, 5, t("This text will be displayed at the bottom of each page.  Useful for adding a copyright notice to your pages."));
+  $group .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 70, 70, t("The name used to indicate anonymous users."));
+  $group .= form_textfield(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), 70, 70, t("The home page displays content from this relative URL.  If you are not using clean URLs, specify the part after '?q='.  If unsure, specify 'node'."));
+  $group .= form_radios(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs.  If enabled, you'll need <code>ModRewrite</code> support.  See also the <code>.htaccess</code> file in Drupal's top-level directory."));
+
+  $output = form_group(t("General settings"), $group);
 
   // caching:
-  $output .= "<h3>". t("Cache settings") ."</h3>\n";
-  $output .= form_radios(t("Cache support"), "cache", variable_get("cache", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable the caching of rendered pages.  When caching is enabled, Drupal will flush the cache when required to make sure updates take effect immediately.  Check the %documentation for information on Drupal's cache system.", array("%documentation" => l(t("cache documentation"), "admin/system/help#cache"))));
-  $output .= "<hr />\n";
+  $group  = form_radios(t("Cache support"), "cache", variable_get("cache", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable the caching of rendered pages.  When caching is enabled, Drupal will flush the cache when required to make sure updates take effect immediately.  Check the %documentation for information on Drupal's cache system.", array("%documentation" => l(t("cache documentation"), "admin/system/help#cache"))));
+
+  $output .= form_group(t("Cache settings"), $group);
 
 
   // submission settings:
-  $output .= "<h3>". t("Submission settings") ."</h3>\n";
   $rate = array(-10000 => t("Disabled"), 1 => t("Maximum 1 every second"), 5 => t("Maximum 1 every 5 seconds"), 15 => t("Maximum 1 every 15 seconds"), 30 => t("Maximum 1 every 30 seconds"), 60 => t("Maximum 1 every minute"), 300 => t("Maximum 1 every 5 minutes"), 900 => t("Maximum 1 every 15 minutes"), 1800 => t("Maximum 1 every 30 minutes"), 3600 => t("Maximum 1 every hour"), 21600 => t("Maximum 1 every 6 hours"), 43200 => t("Maximum 1 every 12 hours"));
-  $output .= form_select(t("Maximum node rate"), "max_node_rate", variable_get("max_node_rate", 900), $rate, t("The maximum submission rate for nodes.  Its purpose is to stop potential abuse or denial of service attacks."));
-  $output .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get("max_comment_rate", 120), $rate, t("The maximum submission rate for comments.  Its purpose is to stop potential abuse or denial of service attacks."));
-  $output .= "<hr />\n";
+  $group  = form_select(t("Maximum node rate"), "max_node_rate", variable_get("max_node_rate", 900), $rate, t("The maximum submission rate for nodes.  Its purpose is to stop potential abuse or denial of service attacks."));
+  $group .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get("max_comment_rate", 120), $rate, t("The maximum submission rate for comments.  Its purpose is to stop potential abuse or denial of service attacks."));
+
+  $output .= form_group(t("Submission settings"), $group);
 
   // date settings:
-  $output .= "<h3>". t("Date format settings") ."</h3>\n";
 
   // date settings: possible date formats
   $dateshort = array("m/d/Y - H:i", "d/m/Y - H:i", "Y/m/d - H:i",
@@ -153,17 +154,12 @@ function system_view_general() {
     $datelongchoices[$f] = format_date(time(), "custom", $f);
   }
 
-  $output .= form_select(t("Date format (short)"), "date_format_short", variable_get("date_format_short", $dateshort[0]), $dateshortchoices, t("The short format of date display."));
-  $output .= form_select(t("Date format (medium)"), "date_format_medium", variable_get("date_format_medium", $datemedium[0]), $datemediumchoices, t("The medium sized date display."));
-  $output .= form_select(t("Date format (long)"), "date_format_long", variable_get("date_format_long", $datelong[0]), $datelongchoices, t("Longer date format used for detailed display."));
+  $group  = form_select(t("Date format (short)"), "date_format_short", variable_get("date_format_short", $dateshort[0]), $dateshortchoices, t("The short format of date display."));
+  $group .= form_select(t("Date format (medium)"), "date_format_medium", variable_get("date_format_medium", $datemedium[0]), $datemediumchoices, t("The medium sized date display."));
+  $group .= form_select(t("Date format (long)"), "date_format_long", variable_get("date_format_long", $datelong[0]), $datelongchoices, t("Longer date format used for detailed display."));
 
-  return $output;
-}
+  $output .= form_group(t("Date format settings"), $group);
 
-function system_view_module($name) {
-  if (module_hook($name, "settings")) {
-      $output .= "<h3><a id=\"$name\">". ucfirst(t("$name")) ." ". t("settings") ."</a></h3>". module_invoke($name, "settings") ."<hr />\n";
-  }
   return $output;
 }
 
@@ -228,7 +224,7 @@ function system_view($type, $arg = "") {
       break;
     case "modules":
       if ($arg) {
-        $form = system_view_module($arg);
+        $form = module_invoke($arg, "settings");
       }
       else {
         $form = system_listing("module", "modules", $required);
@@ -299,6 +295,14 @@ function system_listing($type, $directory, $required = array()) {
     if ($type == "module") {
       $info->name = module_invoke($file->name, "help", "admin/system/modules#name") ? module_invoke($file->name, "help", "admin/system/modules#name") : module_invoke($file->name, "system", "name") ? module_invoke($file->name, "system", "name") : $file->name;
       $info->description = module_invoke($file->name, "help", "admin/system/modules#description") ? module_invoke($file->name, "help", "admin/system/modules#description") : module_invoke($file->name, "system", "description");
+      // log the critical hooks implemented by this module
+      $bootstrap = 0;
+      foreach (bootstrap_hooks() as $hook) {
+        if (module_hook($file->name, $hook)) {
+          $bootstrap = 1;
+          break;
+        }
+      }
     }
     elseif ($type == "theme") {
         $info->name = $file->name;
@@ -308,7 +312,7 @@ function system_listing($type, $directory, $required = array()) {
 
     // Update the contents of the system table:
     db_query("DELETE FROM {system} WHERE filename = '%s' AND type = '%s'", $filename, $type);
-    db_query("INSERT INTO {system} (name, description, type, filename, status) VALUES ('%s', '%s', '%s', '%s', %d)", $info->name, $info->description, $type, $filename, $file->status);
+    db_query("INSERT INTO {system} (name, description, type, filename, status, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d)", $info->name, $info->description, $type, $filename, $file->status, $bootstrap);
 
     $rows[] = array($info->name, $info->description, array("data" => (in_array($filename, $required) ? form_hidden("status][$filename", 1) . t("required") : form_checkbox("", "status][$filename", 1, $file->status)), "align" => "center"));
   }
diff --git a/modules/user.module b/modules/user.module
index 7a218635bcbbe5c793917d3d888be6fb225e5401..6b7909f6d1204a4cb720a7698ecfc8c5782c76c4 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -1,68 +1,6 @@
 <?php
 // $Id$
 
-session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
-session_start();
-
-/*** Session functions *****************************************************/
-
-function sess_open($save_path, $session_name) {
-  return 1;
-}
-
-function sess_close() {
-  return 1;
-}
-
-function sess_read($key) {
-  global $user;
-
-  $result = db_query_range("SELECT u.*, s.*, r.name AS role FROM {users} u INNER JOIN {role} r ON u.rid = r.rid INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '". check_query($key) ."' AND u.status < 3", 0, 1);
-  $user = db_fetch_object($result);
-  if ($user->data && $data = unserialize($user->data)) {
-    foreach ($data as $key => $value) {
-      if (!isset($user->$key)) {
-        $user->$key = $value;
-      }
-    }
-  }
-
-  return !empty($user->session) ? $user->session : '';
-}
-
-function sess_write($key, $value) {
-  global $user;
-
-  db_query("UPDATE {sessions} SET uid = %d, hostname = '%s', session = '%s', timestamp = %d WHERE sid = '$key'", $user->uid, $_SERVER["REMOTE_ADDR"], $value, time());
-
-  if (!db_affected_rows()) {
-    db_query("INSERT INTO {sessions} (uid, sid, hostname, session, timestamp) values(%d, '%s', '%s', '%s', %d)", $user->uid, $key, $_SERVER["REMOTE_ADDR"], $value, time());
-  }
-
-  return '';
-}
-
-function sess_destroy($key) {
-
-  db_query("DELETE FROM {sessions} WHERE sid = '$key'");
-
-}
-
-function sess_gc($lifetime) {
-
-  /*
-  **  Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
-  **   value.  For example, if you want user sessions to stay in your database
-  **   for three weeks before deleting them, you need to set gc_maxlifetime
-  **   to '1814400'.  At that value, only after a user doesn't log in after
-  **   three weeks (1814400 seconds) will his/her session be removed.
-  */
-  db_query("DELETE FROM {sessions} WHERE timestamp < %d", time() - $lifetime);
-
-  return 1;
-
-}
-
 /*** Common functions ******************************************************/
 
 function user_external_load($authname) {
diff --git a/modules/user/user.module b/modules/user/user.module
index 7a218635bcbbe5c793917d3d888be6fb225e5401..6b7909f6d1204a4cb720a7698ecfc8c5782c76c4 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -1,68 +1,6 @@
 <?php
 // $Id$
 
-session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
-session_start();
-
-/*** Session functions *****************************************************/
-
-function sess_open($save_path, $session_name) {
-  return 1;
-}
-
-function sess_close() {
-  return 1;
-}
-
-function sess_read($key) {
-  global $user;
-
-  $result = db_query_range("SELECT u.*, s.*, r.name AS role FROM {users} u INNER JOIN {role} r ON u.rid = r.rid INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '". check_query($key) ."' AND u.status < 3", 0, 1);
-  $user = db_fetch_object($result);
-  if ($user->data && $data = unserialize($user->data)) {
-    foreach ($data as $key => $value) {
-      if (!isset($user->$key)) {
-        $user->$key = $value;
-      }
-    }
-  }
-
-  return !empty($user->session) ? $user->session : '';
-}
-
-function sess_write($key, $value) {
-  global $user;
-
-  db_query("UPDATE {sessions} SET uid = %d, hostname = '%s', session = '%s', timestamp = %d WHERE sid = '$key'", $user->uid, $_SERVER["REMOTE_ADDR"], $value, time());
-
-  if (!db_affected_rows()) {
-    db_query("INSERT INTO {sessions} (uid, sid, hostname, session, timestamp) values(%d, '%s', '%s', '%s', %d)", $user->uid, $key, $_SERVER["REMOTE_ADDR"], $value, time());
-  }
-
-  return '';
-}
-
-function sess_destroy($key) {
-
-  db_query("DELETE FROM {sessions} WHERE sid = '$key'");
-
-}
-
-function sess_gc($lifetime) {
-
-  /*
-  **  Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
-  **   value.  For example, if you want user sessions to stay in your database
-  **   for three weeks before deleting them, you need to set gc_maxlifetime
-  **   to '1814400'.  At that value, only after a user doesn't log in after
-  **   three weeks (1814400 seconds) will his/her session be removed.
-  */
-  db_query("DELETE FROM {sessions} WHERE timestamp < %d", time() - $lifetime);
-
-  return 1;
-
-}
-
 /*** Common functions ******************************************************/
 
 function user_external_load($authname) {
diff --git a/themes/xtemplate/xtemplate.css b/themes/xtemplate/xtemplate.css
index 5d3c2cc9adc13fd5fd4c5d639976cd024f11eb9e..36b09efa46712012a94d3083cab842d5eaa3505b 100644
--- a/themes/xtemplate/xtemplate.css
+++ b/themes/xtemplate/xtemplate.css
@@ -37,6 +37,9 @@ a:hover {
   color: #39c;
   text-decoration: underline;
 }
+fieldset {
+  border: 1px solid #ccc;
+}
 p {
   margin: 0 0 1em 0;
   padding: 0;
diff --git a/update.php b/update.php
index fb44352de6e05f25178ce47b646539c7bf83fa63..acedf0054246412bae0d2fc7f840a528866f3651 100644
--- a/update.php
+++ b/update.php
@@ -59,7 +59,8 @@
   "2003-10-11" => "update_67",
   "2003-10-20" => "update_68",
   "2003-10-22" => "update_69",
-  "2003-10-27" => "update_70"
+  "2003-10-27" => "update_70",
+  "2003-11-17" => "update_71"
 );
 
 function update_32() {
@@ -547,6 +548,10 @@ function update_70() {
   update_sql("ALTER TABLE {variable} CHANGE name name varchar(48) NOT NULL");
 }
 
+function update_71() {
+  update_sql("ALTER TABLE {system} ADD bootstrap int(2)");
+}
+
 /*
 ** System functions
 */
@@ -603,8 +608,9 @@ function update_page() {
     case "Update":
       // make sure we have updates to run.
       print update_page_header("Drupal database update");
-      print "<b>&raquo; <a href=\"index.php\">main page</a></b><br />\n";
-      print "<b>&raquo; <a href=\"index.php?q=admin\">administration pages</a></b><br />\n";
+      $links[] = "<a href=\"index.php\">main page</a>";
+      $links[] = "<a href=\"index.php?q=admin\">administration pages</a>";
+      print theme("item_list", $links);
         // NOTE: we can't use l() here because the URL would point to 'update.php?q=admin'.
       if ($edit["start"] == -1) {
         print "No updates to perform.";
@@ -662,6 +668,7 @@ function update_info() {
 }
 
 if (isset($_GET["op"])) {
+  include_once "includes/bootstrap.inc";
   include_once "includes/common.inc";
 
   // Access check:
diff --git a/xmlrpc.php b/xmlrpc.php
index 41538a98ba1a0c683806f4f7604edf1777bdabb7..69430d803010164519bdb0cd79d4d8725b3856bd 100644
--- a/xmlrpc.php
+++ b/xmlrpc.php
@@ -2,6 +2,7 @@
 // $Id$
 
 include_once "includes/xmlrpcs.inc";
+include_once "includes/bootstrap.inc";
 include_once "includes/common.inc";
 
 $functions = module_invoke_all("xmlrpc");