diff --git a/core.php b/core.php
index b2a248e..23a7297 100644
--- a/core.php
+++ b/core.php
@@ -149,6 +149,8 @@
 	require_once( $t_core_path.'html_api.php' );
 	require_once( $t_core_path.'gpc_api.php' );
 	require_once( $t_core_path.'print_api.php' );
+	require_once( $t_core_path.'collapse_api.php' );
+	collapse_cache_token();
 
 	# custom functions (in main directory)
 	# @@@ Move all such files to core/
diff --git a/core/collapse_api.php b/core/collapse_api.php
index c32ec8a..49d7ec4 100644
--- a/core/collapse_api.php
+++ b/core/collapse_api.php
@@ -22,6 +22,7 @@
 	# --------------------------------------------------------
 
 	$t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
+	require_once( $t_core_dir . 'tokens_api.php' );
 
 	### Collapse API ###
 
@@ -36,39 +37,52 @@
 	#	:
 	#	collapse_end( 'xyz' );		# marks the end of the whole section
 	#
-	# In javascript/common.js, add the g_div_xyz constants.
-	#
 
 	$g_current_collapse_section = null;
 	$g_open_collapse_section = false;
 
-	# ---------------
-	# Use at the top of the section that should be visible when the section is expanded.
-	# sections can not be nested
-	function collapse_open( $p_name ) {
+	$g_collapse_cache_token = null;
+
+	/**
+	 * Marks the beginning of a collapse block's open phase.
+	 * This will be visible if the block is expanded, or if
+	 * javascript is disabled.
+	 * @param string Collapse block name
+	 * @param string Collapse block section
+	 */
+	function collapse_open( $p_name, $p_section = '' ) {
 		global $g_current_collapse_section, $g_open_collapse_section;
 
+		$t_block = ( is_blank( $p_section ) ? $p_name : $p_section . '_' . $p_name );
+		$t_display = collapse_display( $t_block );
+
 		# make sure no other collapse section is started
 		if ( $g_current_collapse_section !== null ) {
 			trigger_error( ERROR_GENERIC, ERROR );
 		}
 
 		$g_open_collapse_section = true;
-		$g_current_collapse_section = $p_name;
+		$g_current_collapse_section = $t_block;
 
-		$t_div_id = $p_name . '_open';
-		echo "<div id=\"$t_div_id\">";
+		$t_div_id = $t_block . '_open';
+		echo '<div id="', $t_div_id, '"', ( $t_display ? '' : ' style="display: none"' ) ,'>';
 	}
 
-	# ---------------
-	# Use to mark the end of the expanded section and the beginning of the closed section
-	# the closed section will not be sent to the browser if $g_Use_javascript is OFF.
-	# This is achieved using output buffering.
-	function collapse_closed( $p_name ) {
+	/**
+	 * Marks the end of a collapse block's open phase and the beginning
+	 * of the block's closed phase.  Thi will only be visible if the
+	 * block have been collapsed and javascript is enabled.
+	 * @param string Collapse block name
+	 * @param string Collapse block section
+	 */
+	function collapse_closed( $p_name, $p_section = '' ) {
 		global $g_current_collapse_section, $g_open_collapse_section;
 
+		$t_block = ( is_blank( $p_section ) ? $p_name : $p_section . '_' . $p_name );
+		$t_display = !collapse_display( $t_block );
+
 		# Make sure a section is opened, and it is the same section.
-		if ( $p_name !== $g_current_collapse_section ) {
+		if ( $t_block !== $g_current_collapse_section ) {
 			trigger_error( ERROR_GENERIC, ERROR );
 		}
 
@@ -78,17 +92,24 @@
 
 		ob_start();
 
-		echo '<div id="', $p_name, '_closed" style="display: none;">';
+		$t_div_id = $t_block . '_closed';
+		echo '<div id="', $t_div_id, '"', ( $t_display ? '' : ' style="display: none"' ) ,'>';
 	}
 
-	# ---------------
-	# This is used within both the open and closed section to identify the location where the
-	# '+'/'-' icon should be placed.
-	function collapse_icon( $p_name ) {
+	/**
+	 * Marks the location where a +/- icon is placed in output
+	 * for the user to toggle the collapse block status.
+	 * This should appear in both the open and closed phase of a block.
+	 * @param string Collapse block name
+	 * @param string Collapse block section
+	 */
+	function collapse_icon( $p_name, $p_section = '' ) {
 		if ( OFF == config_get( 'use_javascript' ) ) {
 			return;
 		}
 
+		$t_block = ( is_blank( $p_section ) ? $p_name : $p_section . '_' . $p_name );
+
 		global $g_open_collapse_section;
 
 		if ( $g_open_collapse_section === true ) {
@@ -99,18 +120,24 @@
 			$t_alt  = '+';
 		}
 
-		echo "<a href=\"\" onclick=\"ToggleDiv( '$p_name', g_div_$p_name ); return false;\"
+		echo "<a href=\"\" onclick=\"ToggleDiv( '$t_block' ); return false;\"
 			><img border=\"0\" src=\"images/$t_icon\" alt=\"$t_alt\" /></a>&nbsp;";
 	}
 
-	# ---------------
-	# Mark the end of the collapsible section
-	function collapse_end( $p_name ) {
+	/**
+	 * Marks the end of a collaps block's closed phase.
+	 * Closed phase output is discarded if javascript is disabled.
+	 * @param string Collapse block name
+	 * @param string Collapse block section
+	 */
+	function collapse_end( $p_name, $p_section = '' ) {
 		global $g_current_collapse_section, $g_open_collapse_section;
 
+		$t_block = ( is_blank( $p_section ) ? $p_name : $p_section . '_' . $p_name );
+		$t_display = collapse_display( $t_block );
 
 		# Make sure a section is opened, and it is the same section.
-		if ( $p_name !== $g_current_collapse_section ) {
+		if ( $t_block !== $g_current_collapse_section ) {
 			ob_end_clean();
 			trigger_error( ERROR_GENERIC, ERROR );
 		}
@@ -120,10 +147,6 @@
 		$g_open_collapse_section = false;
 
 		if ( ON == config_get( 'use_javascript' ) ) {
-			echo '<script type="text/javascript" language="JavaScript"><!--' . "\n";
-			echo '	SetDiv( "', $p_name, '", g_div_', $p_name, ' );' . "\n";
-			echo '--></script>';
-
 			ob_end_flush();
 		} else {
 			ob_end_clean();
@@ -131,4 +154,72 @@
 
 		$g_current_collapse_section = null;
 	}
+
+	/**
+	 * Determine if a block should be displayed open by default.
+	 * @param string Collapse block
+	 */
+	function collapse_display( $p_block ) {
+		global $g_collapse_cache_token;
+
+		if ( !isset( $g_collapse_cache_token[$p_block] ) || OFF == config_get( 'use_javascript' ) ) {
+			return true;
+		}
+
+		return ( true == $g_collapse_cache_token[$p_block] );
+	}
+
+	/**
+	 * Cache collapse API data from the database for the current user.
+	 * If the collapse cookie has been set, grab the changes and resave
+	 * the token, or touch it otherwise.
+	 */
+	function collapse_cache_token() {
+		global $g_collapse_cache_token;
+
+		if ( current_user_is_anonymous() ) {
+			$g_collapse_cache_token = array();
+			return;
+		}
+
+		if ( isset( $g_collapse_cache_token ) ) {
+			return;
+		}
+
+		$t_user_id = auth_get_current_user_id();
+		$t_token = token_get_value( TOKEN_COLLAPSE );
+
+		if ( !is_null( $t_token ) ) {
+			$t_data = unserialize( $t_token );
+		} else {
+			$t_data = array();
+		}
+
+		$g_collapse_cache_token = $t_data;
+
+		$t_cookie = gpc_get_cookie( 'MANTIS_collapse_settings', '' );
+
+		if ( false !== $t_cookie && !is_blank( $t_cookie ) ) {
+			$t_update = false;
+			$t_data = explode( '|', $t_cookie );
+
+			foreach ( $t_data as $t_pair ) {
+				$t_pair = explode( ',', $t_pair );
+
+				if ( false !== $t_pair && count( $t_pair ) == 2 ) {
+					$g_collapse_cache_token[$t_pair[0]] = ( true == $t_pair[1] );
+					$t_update = true;
+				}
+			}
+
+			if ( $t_update ) {
+				$t_token = serialize( $g_collapse_cache_token );
+				token_set( TOKEN_COLLAPSE, $t_token, TOKEN_EXPIRY_COLLAPSE );
+			} else {
+				token_touch( TOKEN_COLLAPSE );
+			}
+		}
+
+	}
+
 ?>
diff --git a/core/constant_inc.php b/core/constant_inc.php
index 412bc30..3ea6263 100644
--- a/core/constant_inc.php
+++ b/core/constant_inc.php
@@ -389,12 +389,14 @@
 	define( 'TOKEN_GRAPH',			2 );
 	define( 'TOKEN_LAST_VISITED',	3 );
 	define( 'TOKEN_AUTHENTICATED',	4 );
+	define( 'TOKEN_COLLAPSE',		5 );
 	define( 'TOKEN_USER',			1000 );
 
 	# token expirations
 	define( 'TOKEN_EXPIRY', 		60*60 ); # Default expiration of 60 minutes ( 3600 seconds )
 	define( 'TOKEN_EXPIRY_LAST_VISITED', 24*60*60 );
 	define( 'TOKEN_EXPIRY_AUTHENTICATED', 5*60 );
+	define( 'TOKEN_EXPIRY_COLLAPSE', 365*24*60*60 );
 
 	# config types
 	define( 'CONFIG_TYPE_INT', 1 );
diff --git a/javascript/common.js b/javascript/common.js
index 2375f97..10030bb 100644
--- a/javascript/common.js
+++ b/javascript/common.js
@@ -94,61 +94,29 @@ function SetCookie( p_cookie, p_value ) {
  * Collapsible element functions
  */
 
-var g_div_history       = 0x0001;
-var g_div_bugnotes      = 0x0002;
-var g_div_bugnote_add   = 0x0004;
-var g_div_bugnotestats  = 0x0008;
-var g_div_upload_form   = 0x0010;
-var g_div_monitoring    = 0x0020;
-var g_div_sponsorship   = 0x0040;
-var g_div_relationships = 0x0080;
-var g_div_filter        = 0x0100;
-
-var g_div_plugin		= 0x8000;
-
-/* List here the sections open by default */
-var g_default_view_settings = 
-	g_div_history | 
-	g_div_bugnotes |
-	g_div_bugnote_add |
-	g_div_bugnotestats |
-	g_div_upload_form |
-	g_div_monitoring |
-	g_div_sponsorship |
-	g_div_relationships;
-
-
-function GetViewSettings() {
-	var t_cookie = GetCookie( "VIEW_SETTINGS" );
-
-	if ( -1 == t_cookie ) {
-		t_cookie = g_default_view_settings;
-	} else {
-		t_cookie = parseInt( t_cookie );
-	}
+var g_collapse_clear = 1;
 
-	return t_cookie;
-}
+function ToggleDiv( p_div ) {
+	t_open_div = document.getElementById( p_div + "_open" )
+	t_closed_div = document.getElementById( p_div + "_closed" )
 
-function SetDiv( p_div, p_cookie_bit ) {
-	var t_view_settings = GetViewSettings();
+	t_cookie = GetCookie( "collapse_settings" );
+	if ( 1 == g_collapse_new ) {
+		t_cookie = "";
+		g_collapse_clear = 0;
+	}
 
-	if( t_view_settings & p_cookie_bit ) {
-		document.getElementById( p_div + "_open" ).style.display = "";
-		document.getElementById( p_div + "_closed" ).style.display = "none";
+	if ( t_open_div.style.display == "none" ) {
+		t_open_div.style.display = "";
+		t_closed_div.style.display = "none";
+		t_cookie = t_cookie + "|" + p_div + ",1"
 	} else {
-		document.getElementById( p_div + "_open" ).style.display = "none";
-		document.getElementById( p_div + "_closed" ).style.display = "";
+		t_closed_div.style.display = "";
+		t_open_div.style.display = "none";
+		t_cookie = t_cookie + "|" + p_div + ",0"
 	}
-}
-
-function ToggleDiv( p_div, p_cookie_bit ) {
-	var t_view_settings = GetViewSettings();
-
-	t_view_settings ^= p_cookie_bit;
-	SetCookie( "VIEW_SETTINGS", t_view_settings );
 
-	SetDiv( p_div, p_cookie_bit );
+	SetCookie( "collapse_settings", t_cookie );
 }
 
 /* Check checkboxes */
