diff -urp --strip-trailing-cr ../drupal-6.x-dev/includes/common.inc ./includes/common.inc
--- ../drupal-6.x-dev/includes/common.inc	2007-12-23 00:24:24.000000000 +0100
+++ ./includes/common.inc	2007-12-26 17:53:46.000000000 +0100
@@ -294,7 +294,6 @@ function drupal_get_destination() {
  * @see drupal_get_destination()
  */
 function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
-  global $update_mode;
 
   if (isset($_REQUEST['destination'])) {
     extract(parse_url(urldecode($_REQUEST['destination'])));
@@ -309,7 +308,7 @@ function drupal_goto($path = '', $query 
 
   // Allow modules to react to the end of the page request before redirecting.
   // We do not want this while running update.php.
-  if (empty($update_mode)) {
+  if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
     module_invoke_all('exit', $url);
   }
 
@@ -1707,10 +1706,16 @@ function drupal_get_css($css = NULL) {
   $no_module_preprocess = '';
   $no_theme_preprocess = '';
 
-  $preprocess_css = variable_get('preprocess_css', FALSE);
+  $preprocess_css = (variable_get('preprocess_css', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
   $directory = file_directory_path();
   $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);
 
+  // A dummy query-string is added to filenames, to gain control over
+  // browser-caching. The string changes on every update or full cache
+  // flush, forcing browsers to load a new copy of the files, as the
+  // URL changed.
+  $query_string = '?'. variable_get('css_js_flush_counter', 0);
+
   foreach ($css as $media => $types) {
     // If CSS preprocessing is off, we still need to output the styles.
     // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones.
@@ -1720,22 +1725,22 @@ function drupal_get_css($css = NULL) {
           // If a CSS file is not to be preprocessed and it's a module CSS file, it needs to *always* appear at the *top*,
           // regardless of whether preprocessing is on or off.
           if (!$preprocess && $type == 'module') {
-            $no_module_preprocess .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file .'" />'."\n";
+            $no_module_preprocess .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . $query_string .'" />'."\n";
           }
           // If a CSS file is not to be preprocessed and it's a theme CSS file, it needs to *always* appear at the *bottom*,
           // regardless of whether preprocessing is on or off.
           else if (!$preprocess && $type == 'theme') {
-            $no_theme_preprocess .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file .'" />'."\n";
+            $no_theme_preprocess .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . $query_string .'" />'."\n";
           }
           else {
-            $output .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file .'" />'."\n";
+            $output .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . $query_string .'" />'."\n";
           }
         }
       }
     }
 
     if ($is_writable && $preprocess_css) {
-      $filename = md5(serialize($types)) .'.css';
+      $filename = md5(serialize($types) . $query_string) .'.css';
       $preprocess_file = drupal_build_css_cache($types, $filename);
       $output .= '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $preprocess_file .'" />'."\n";
     }
@@ -2020,8 +2025,7 @@ function drupal_add_js($data = NULL, $ty
  *   All JavaScript code segments and includes for the scope as HTML tags.
  */
 function drupal_get_js($scope = 'header', $javascript = NULL) {
-  global $update_mode;
-  if (empty($update_mode) && function_exists('locale_update_js_files')) {
+  if ((!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') && function_exists('locale_update_js_files')) {
     locale_update_js_files();
   }
 
@@ -2037,10 +2041,18 @@ function drupal_get_js($scope = 'header'
   $preprocessed = '';
   $no_preprocess = array('core' => '', 'module' => '', 'theme' => '');
   $files = array();
-  $preprocess_js = (variable_get('preprocess_js', FALSE) && empty($update_mode));
+  $preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
   $directory = file_directory_path();
   $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);
 
+  // A dummy query-string is added to filenames, to gain control over
+  // browser-caching. The string changes on every update or full cache
+  // flush, forcing browsers to load a new copy of the files, as the
+  // URL changed. Files that should not be cached (see drupal_add_js())
+  // get time() as query-string instead, to enforce reload on every
+  // page request.
+  $query_string = '?'. variable_get('css_js_flush_counter', 0);
+
   foreach ($javascript as $type => $data) {
 
     if (!$data) continue;
@@ -2059,7 +2071,7 @@ function drupal_get_js($scope = 'header'
         // Additionally, go through any remaining scripts if JS preprocessing is on and output the non-cached ones.
         foreach ($data as $path => $info) {
           if (!$info['preprocess'] || !$is_writable || !$preprocess_js) {
-            $no_preprocess[$type] .= '<script type="text/javascript"'. ($info['defer'] ? ' defer="defer"' : '') .' src="'. base_path() . $path . ($info['cache'] ? '' : '?'. time()) ."\"></script>\n";
+            $no_preprocess[$type] .= '<script type="text/javascript"'. ($info['defer'] ? ' defer="defer"' : '') .' src="'. base_path() . $path . ($info['cache'] ? $query_string : '?'. time()) ."\"></script>\n";
           }
           else {
             $files[$path] = $info;
@@ -2070,7 +2082,7 @@ function drupal_get_js($scope = 'header'
 
   // Aggregate any remaining JS files that haven't already been output.
   if ($is_writable && $preprocess_js && count($files) > 0) {
-    $filename = md5(serialize($files)) .'.js';
+    $filename = md5(serialize($files) . $query_string) .'.js';
     $preprocess_file = drupal_build_js_cache($files, $filename);
     $preprocessed .= '<script type="text/javascript" src="'. base_path() . $preprocess_file .'"></script>'."\n";
   }
@@ -2412,7 +2424,6 @@ function xmlrpc($url) {
 
 function _drupal_bootstrap_full() {
   static $called;
-  global $update_mode;
 
   if ($called) {
     return;
@@ -2440,7 +2451,7 @@ function _drupal_bootstrap_full() {
   module_load_all();
   // Let all modules take action before menu system handles the request
   // We do not want this while running update.php.
-  if (empty($update_mode)) {
+  if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
     module_invoke_all('init');
   }
 }
@@ -3500,6 +3511,11 @@ function drupal_implode_tags($tags) {
  * exposes a hook for other modules to clear their own cache data as well.
  */
 function drupal_flush_all_caches() {
+
+  // Change query-strings on css/js files to enforce reload for all users.
+  $css_js_counter = variable_get('css_js_flush_counter', 0);
+  variable_set('css_js_flush_counter', (++$css_js_counter > 9) ? 0 : $css_js_counter);
+
   drupal_clear_css_cache();
   drupal_clear_js_cache();
   drupal_rebuild_theme_registry();
diff -urp --strip-trailing-cr ../drupal-6.x-dev/update.php ./update.php
--- ../drupal-6.x-dev/update.php	2007-12-26 11:23:59.000000000 +0100
+++ ./update.php	2007-12-26 17:53:46.000000000 +0100
@@ -13,6 +13,12 @@
  * be sure to open settings.php again, and change it back to its original state!
  */
 
+/**
+ * Global flag to identify update.php run, and so avoid various unwanted
+ * operations, such as hook_init() and hook_exit() invokes, css/js preprocessing
+ * and translation, and solve some theming issues. This flag is checked on several
+ * places in Drupal code (not just update.php).
+ */
 define('MAINTENANCE_MODE', 'update');
 
 /**
@@ -264,11 +270,7 @@ function update_batch() {
 
 function update_finished($success, $results, $operations) {
   // clear the caches in case the data has been updated.
-  cache_clear_all('*', 'cache', TRUE);
-  cache_clear_all('*', 'cache_page', TRUE);
-  cache_clear_all('*', 'cache_filter', TRUE);
-  drupal_clear_css_cache();
-  drupal_clear_js_cache();
+  drupal_flush_all_caches();
 
   $_SESSION['update_results'] = $results;
   $_SESSION['update_success'] = $success;
@@ -340,6 +342,10 @@ function update_results_page() {
 }
 
 function update_info_page() {
+  // Change query-strings on css/js files to enforce reload.
+  $css_js_counter = variable_get('css_js_flush_counter', 0);
+  variable_set('css_js_flush_counter', (++$css_js_counter > 9) ? 0 : $css_js_counter);
+
   update_task_list('info');
   drupal_set_title('Drupal database update');
   $output = '<p>Use this utility to update your database whenever a new release of Drupal or a module is installed.</p><p>For more detailed information, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>';
@@ -516,11 +522,6 @@ ini_set('display_errors', FALSE);
 
 include_once './includes/bootstrap.inc';
 
-// Bootstrap Drupal in a safe way, without calling hook_init() and hook_exit(),
-// to avoid possible warnings. We need to set the global variable after
-// DRUPAL_BOOTSTRAP_CONFIGURATION, which unsets globals, but before the rest.
-drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
-$update_mode = TRUE;
 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 drupal_maintenance_theme();
 
