<?php
/**
 * This file implements upgrading of DB tables
 *
 * b2evolution - {@link http://b2evolution.net/}
 * Released under GNU GPL License - {@link http://b2evolution.net/about/gnu-gpl-license}
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}
 *
 * @package install
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

load_funcs( '_core/_param.funcs.php' );
load_funcs( 'widgets/_widgets.funcs.php' );


/**
 * Create a DB version checkpoint
 *
 * This is useful when the next operation might timeout or fail!
 * The checkpoint will allow to restart the script and continue where it stopped
 *
 * @param string version of DB at checkpoint
 */
function set_upgrade_checkpoint( $version )
{
	global $DB, $script_start_time, $locale, $action;

	global $recreate_autogenerated_excerpts;

	echo get_install_format_text_and_log( '<span class="text-muted">Creating DB schema version checkpoint at '.$version.'... ' );

	if( $version < 8060 )
	{
		$query = 'UPDATE T_settings SET db_version = '.$version;
	}
	else
	{
		$query = "UPDATE T_settings
								SET set_value = '$version'
								WHERE set_name = 'db_version'";
	}
	$DB->query( $query );


	$elapsed_time = time() - $script_start_time;

	echo get_install_format_text_and_log( "OK. (Elapsed upgrade time: $elapsed_time seconds)</span><br />\n", 'br' );

	// Update the progress bar status
	update_install_progress_bar();

	evo_flush();

	$max_exe_time = ini_get( 'max_execution_time' );
	if( $max_exe_time && ( $elapsed_time > ( $max_exe_time - 20 ) ) )
	{ // Max exe time not disabled and we're recahing the end
		$upgrade_action = ( $action == 'auto_upgrade' ) ? $action : 'evoupgrade';
		$recreate_excerpts = $recreate_autogenerated_excerpts ? '&amp;recreate_excerpts=1' : '';
		echo get_install_format_text_and_log( 'We are reaching the time limit for this script. Please click <a href="index.php?locale='.$locale.'&amp;action='.$upgrade_action.$recreate_excerpts.'">continue</a>...' );
		// Dirty temporary solution:
		exit(0);
	}
}


/**
 * Start upgrade task
 *
 * @param integer Version of DB at checkpoint
 * @param string Task title
 * @return boolean TRUE if task has been started
 */
function upg_task_start( $version, $title = '' )
{
	global $old_db_version, $upgrade_db_version;

	if( $old_db_version < $version )
	{	// Only if current DB version is older than current requested

		// Set upgrade version to use this in function upg_task_end():
		$upgrade_db_version = $version;

		if( ! empty( $title ) )
		{	// Start task (Display a title):
			task_begin( $title );
		}

		// Begin a transaction for the upgrade block:
		global $DB;
		$DB->begin();

		return true;
	}
	else
	{
		return false;
	}
}


/**
 * End upgrade task
 *
 * @param boolean TRUE to print out a result of task ending
 */
function upg_task_end( $print_result = true )
{
	global $upgrade_db_version;

	if( ! empty( $upgrade_db_version ) )
	{	// Only if the upgrade task is not ended yet:

		// End current transaction of the upgrade block:
		global $DB;
		$DB->commit();

		if( $print_result )
		{	// Print out the end of task:
			task_end();
		}

		// Create a DB version checkpoint:
		set_upgrade_checkpoint( $upgrade_db_version );

		// Unset the current version because task is ended:
		unset( $upgrade_db_version );
	}
}


/**
 * Create DB table
 *
 * @param string Table name
 * @param string Fields
 * @param string Options
 */
function db_create_table( $table, $fields, $options = 'ENGINE = innodb' )
{
	global $DB, $db_config;

	if( isset( $db_config, $db_config['aliases'], $db_config['aliases'][ $table ] ) )
	{	// Use table name with real prefix instead of T_:
		$table = $db_config['aliases'][ $table ];
	}

	// Check if the creating table doesn't exist in DB:
	$unique_table = $table;
	$next_table_index = 1;
	while( $DB->get_var( 'SHOW TABLES LIKE '.$DB->quote( $unique_table ) ) )
	{	// This table already exists in DB, try to find what next table name is free:
		$unique_table = $table.'_'.$next_table_index;
		$next_table_index++;
	}
	if( $unique_table != $table )
	{	// Backup the existing table, in order to create the requeired table without error:
		$DB->query( 'RENAME TABLE '.$table.' TO '.$unique_table );
	}

	// Create new table with requested table:
	$DB->query( 'CREATE TABLE '.$table.' ( '.$fields.' ) '.$options );
}


/**
 * @return boolean Does a given index key name exist in DB?
 */
function db_index_exists( $table, $index_name )
{
	global $DB;

	$index_name = strtolower($index_name);

	$DB->query('SHOW INDEX FROM '.$table);
	while( $row = $DB->get_row() )
	{
		if( strtolower($row->Key_name) == $index_name )
		{
			return true;
		}
	}

	return false;
}


/**
 * @param string Table name
 * @param array Column names
 * @return boolean Does a list of given column names exist in DB?
 */
function db_cols_exist( $table, $col_names )
{
	global $DB;

	foreach( $col_names as $k => $v )
		$col_names[$k] = strtolower($v);

	foreach( $DB->get_results('SHOW COLUMNS FROM '.$table) as $row )
		if( ($key = array_search(strtolower($row->Field), $col_names)) !== false )
			unset( $col_names[$key] );

	return count($col_names) == 0;
}

/**
 * Drops a column, if it exists.
 */
function db_drop_col( $table, $col_name )
{
	global $DB;

	if( ! db_col_exists($table, $col_name) )
		return false;

	$DB->query( 'ALTER TABLE '.$table.' DROP COLUMN '.$col_name );
}

/**
 * Add a column, if it does not already exist.
 * If it exists already, a "ALTER TABLE" statement will get executed instead.
 *
 * @return boolean True if the column has been added, False if not.
 */
function db_add_col( $table, $col_name, $col_desc )
{
	global $DB;

	if( db_col_exists( $table, $col_name ) )
	{ // Column exists already, make sure it's the same.
		db_modify_col( $table, $col_name, $col_desc );
		return false;
	}

	$DB->query( 'ALTER TABLE '.$table.' ADD COLUMN '.$col_name.' '.$col_desc );
}

/**
 * Modify a column
 */
function db_modify_col( $table, $col_name, $col_desc )
{
	global $DB;
	$DB->query( 'ALTER TABLE '.$table.' MODIFY COLUMN '.$col_name.' '.$col_desc );
}


/**
 * ADD/MODIFY/DROP columns by single SQL query
 *
 * @param string Table name
 * @param array Array: key - action('ADD','MODIFY','DROP'),
 *                     value is array of columns: key - column name, value - column description or column name for DROP action
 */
function db_upgrade_cols( $table, $cols )
{
	global $DB;

	if( empty( $cols ) )
	{	// No columns
		return;
	}

	// Get existing columns of the given db table in order to avoid errors on add duplicated column or on drop unexisting column:
	$existing_columns = $DB->get_results( 'SHOW COLUMNS FROM '.$table );
	foreach( $existing_columns as $c => $col )
	{
		$existing_columns[ $c ] = strtolower( $col->Field );
	}

	$upgrade_sql_query = '';
	foreach( $cols as $action => $cols_data )
	{
		foreach( $cols_data as $col_name => $col_desc )
		{
			switch( $action )
			{
				case 'ADD':
				case 'MODIFY':
				case 'CHANGE':
					if( in_array( strtolower( $col_name ), $existing_columns ) )
					{	// Modify the existing column:
						if( $action == 'CHANGE' )
						{	// Change a column, e-g rename it:
							$upgrade_sql_query .= ' CHANGE COLUMN ';
						}
						else
						{	// Modify a column, update only
							$upgrade_sql_query .= ' MODIFY COLUMN ';
						}
					}
					else
					{	// Add new column:
						$upgrade_sql_query .= ' ADD COLUMN ';
					}
					$upgrade_sql_query .= '`'.$col_name.'` '.$col_desc.',';
					break;

				case 'DROP':
					$col_name = $col_desc;
					if( in_array( strtolower( $col_name ), $existing_columns ) )
					{	// Allow to drop only really existing column:
						$upgrade_sql_query .= ' DROP COLUMN `'.$col_name.'`,';
					}
					// ELSE skip not existing column
					break;

				default:
					debug_die( 'Invalid DB upgrade action "'.$action.'"' );
			}
		}
	}

	if( ! empty( $upgrade_sql_query ) )
	{	// Run upgrade SQL query only if at least one column should be upgraded:
		$DB->query( 'ALTER TABLE '.$table.substr( $upgrade_sql_query, 0, -1 ) );
	}
}


/**
 * Add an INDEX. If another index with the same name already exists, it will
 * get dropped before.
 */
function db_add_index( $table, $name, $def, $type = 'INDEX' )
{
	global $DB;
	if( db_index_exists($table, $name) )
	{
		$DB->query( 'ALTER TABLE '.$table.' DROP INDEX '.$name );
	}
	$DB->query( 'ALTER TABLE '.$table.' ADD '.$type.' '.$name.' ('.$def.')' );
}


/**
 * Drops an INDEX, if it exists
 *
 * @param string Table name
 * @param string Index name
 */
function db_drop_index( $table, $index )
{
	global $DB;

	if( ! db_index_exists( $table, $index ) )
	{	// No index is detected, Stop it:
		return;
	}

	$DB->query( 'ALTER TABLE '.$table.' DROP INDEX '.$index );
}


/**
 * Check if a key item value already exists on database
 */
function db_key_exists( $table, $field_name, $field_value )
{
	global $DB;
	return $DB->get_var( '
		SELECT COUNT('.$field_name.')
		FROM '.$table.'
		WHERE '.$field_name.' = '.$field_value );
}

/**
 * Add a Foreign Key constraint.
 * If another foreign key exists between these two fields then the old FK will be deleted and a new will be created.
 * If the table engine is not InnoDB, then it will be changed automatically.
 * If the FK table contains data which would prevent foreign key creation then these records will be deleted.
 *
 * @param string foreign key table
 * @param string foreing key column name
 * @param string foreign key refrence table name
 * @param string reference column name in the reference table
 * @param string foreign key definition ( e.g. "ON DELETE CASCADE" or "ON UPDATE RESTRICT" )
 */
function db_add_foreign_key( $table, $field_name, $reference_table, $reference_field_name, $definition )
{
	global $DB;
	$table = preg_replace( $DB->dbaliases, $DB->dbreplaces, $table );
	$reference_table = preg_replace( $DB->dbaliases, $DB->dbreplaces, $reference_table );
	$foreign_key_fields = array( array(
			'fk_fields' => $field_name,
			'reference_table' => $reference_table,
			'reference_columns' => $reference_field_name,
			'fk_definition' => $definition,
			'create' => true, // This FK should be created if not exists
		) );
	db_delta_foreign_keys( $foreign_key_fields, $table, true, 'add' );
}

/**
 * Drop a Foreign Key constraint.
 * If this foreign key not exists the function won't give error.
 *
 * @param string foreign key table
 * @param string foreing key column name
 * @param string foreign key refrence table name
 * @param string reference column name in the reference table
 */
function db_drop_foreign_key( $table, $field_name, $reference_table, $reference_field_name )
{
	global $DB;
	$table = preg_replace( $DB->dbaliases, $DB->dbreplaces, $table );
	$reference_table = preg_replace( $DB->dbaliases, $DB->dbreplaces, $reference_table );
	$foreign_key_fields = array( array(
			'fk_fields' => $field_name,
			'reference_table' => $reference_table,
			'reference_columns' => $reference_field_name,
			'fk_definition' => '',
			'create' => false, // This FK shouldn't be created if not exists
		) );
	db_delta_foreign_keys( $foreign_key_fields, $table, true, 'drop' );
}


/**
 * Upgrade DB columns from utf8_general_ci to utf8mb4_unicode_ci
 *
 * @param array Key is table name, Value is array of columns which should be converted
 */
function db_convert_cols_to_utf8mb4( $table_columns )
{
	global $DB;

	foreach( $table_columns as $table => $columns )
	{
		$columns = $DB->get_results( 'SHOW FULL COLUMNS FROM `'.$table.'` WHERE field IN ( "'.implode( '", "', $columns ).'" )' );
		$col_definitions = array();
		foreach( $columns as $col )
		{	// Update a column character set explicitly to utf8mb4:
			$col_definition = $col->Field.
				' '.$col->Type.' COLLATE utf8mb4_unicode_ci'.
				( ( $col->Null == 'NO' ) ? ' NOT' : '' ).' NULL'.
				( isset( $col->Default ) ? ' DEFAULT "'.$col->Default.'"' : '' ).
				( isset( $col->Extra ) ? ' '.$col->Extra : '' ).
				( isset( $col->Comment ) ? ' COMMENT "'.$col->Comment.'"' : '' );
			$col_definitions[] = 'MODIFY '.$col_definition;
		}
		$DB->query( 'ALTER TABLE `'.$table.'` '.implode( ', ', $col_definitions ) );
	}
}


/**
 * Converts languages in a given table into according locales
 *
 * @param string name of the table
 * @param string name of the column where lang is stored
 * @param string name of the table's ID column
 */
function convert_lang_to_locale( $table, $columnlang, $columnID )
{
	global $DB, $locales, $default_locale;

	if( !preg_match('/[a-z]{2}-[A-Z]{2}(-.{1,14})?/', $default_locale) )
	{ // we want a valid locale
		$default_locale = 'en-EU';
	}

	echo get_install_format_text_and_log( 'Converting langs to locales for '. $table. '...<br />', 'br' );

	// query given languages in $table
	$query = "SELECT $columnID, $columnlang FROM $table";
	$languagestoconvert = array();
	foreach( $DB->get_results( $query, ARRAY_A ) as $row )
	{
		// remember the ID for that locale
		$languagestoconvert[ $row[ $columnlang ] ][] = $row[ $columnID ];
	}

	foreach( $languagestoconvert as $lkey => $lIDs)
	{ // converting the languages we've found
		$converted = false;
		echo get_install_format_text_and_log( '&nbsp; Converting lang \''. $lkey. '\' ' ); // (with IDs: '. implode( ', ', $lIDs ). ').. ';

		if( preg_match('/[a-z]{2}-[A-Z]{2}(-.{1,14})?/', $lkey) )
		{ // Already valid
			echo get_install_format_text_and_log( 'nothing to update, already valid!<br />', 'br' );
			continue;
		}

		if( (strlen($lkey) == 2) && ( substr( $default_locale, 0, 2 ) != $lkey ) )
		{ // we have an old two letter lang code to convert
			// and it doesn't match the default locale
			foreach( $locales as $newlkey => $v )
			{  // loop given locales
				if( substr($newlkey, 0, 2) == strtolower($lkey) ) # TODO: check if valid/suitable
				{  // if language matches, update
					$converted = $DB->query( "
						UPDATE $table
						   SET $columnlang = '$newlkey'
						 WHERE $columnlang = '$lkey'" );
					echo get_install_format_text_and_log( 'to locale \''. $newlkey. '\'<br />', 'br' );
					break;
				}
			}
		}

		if( !$converted )
		{ // we have nothing converted yet, setting default:
			$DB->query( "UPDATE $table
											SET $columnlang = '$default_locale'
										WHERE $columnlang = '$lkey'" );
			echo get_install_format_text_and_log( 'forced to default locale \''. $default_locale. '\'<br />', 'br' );
		}
	}
	echo "\n";
}  // convert_lang_to_locale(-)


/**
 * Initialize some environment global variables like $Setting, $Plugins and etc.
 * which are used to work with objects like Blog, Item, ItemType and etc.
 *
 * @param string Name of environment global variables separated by comma, possible values: 'Settings', 'Plugins', 'Plugins_admin'
 */
function upg_init_environment( $env_vars = 'Settings' )
{
	global $upg_initialized_env_vars;

	if( ! is_array( $upg_initialized_env_vars ) )
	{	// Initialize array to know what objects were already initialized:
		$upg_initialized_env_vars = array();
	}

	$env_vars = explode( ',', $env_vars );

	foreach( $env_vars as $env_var )
	{
		if( in_array( $env_var, $upg_initialized_env_vars ) ||
		    ( isset( $GLOBALS[ $env_var ] ) && is_object( $GLOBALS[ $env_var ] ) ) )
		{	// Don't initialize same environment global variable twice:
			continue;
		}

		switch( $env_var )
		{
			case 'Settings':
				global $Settings;
				load_class( 'settings/model/_generalsettings.class.php', 'GeneralSettings' );
				// Create Settings object WITHOUT version checking:
				$Settings = new GeneralSettings( false/* Do NOT check version*/ );
				break;

			case 'Plugins':
				// Create Plugins object:
				global $Plugins;
				load_class( 'plugins/model/_plugins.class.php', 'Plugins' );
				$Plugins = new Plugins();
				break;

			case 'Plugins_admin':
				// Create Plugins object:
				global $Plugins_admin;
				$Plugins_admin = & get_Plugins_admin();
				break;
		}

		// Store the initialized object so we don't initialize it twice:
		$upg_initialized_env_vars[] = $env_var;
	}
}


/**
 * Clear all environment global variables which were temporary initialized for upgrade process
 */
function upg_clear_environment()
{
	global $upg_initialized_env_vars;

	if( empty( $upg_initialized_env_vars ) )
	{	// No temp environment global variables:
		return;
	}

	foreach( $upg_initialized_env_vars as $env_var )
	{	// Reset each temporary initialized environment global variable:
		$GLOBALS[ $env_var ] = NULL;
	}

	// Clear the initialized object:
	$upg_initialized_env_vars = array();
}


/**
 * upgrade_b2evo_tables(-)
 *
 * @param string the action param value corresponding the current upgrade process ( evoupgrade, auto_upgrade )
 */
function upgrade_b2evo_tables( $upgrade_action = 'evoupgrade' )
{
	global $db_config, $tableprefix;
	global $baseurl, $old_db_version, $new_db_version;
	global $Group_Admins, $Group_Privileged, $Group_Bloggers, $Group_Users;
	global $locales, $locale;
	global $DB;
	global $admin_url;
	global $Settings, $Plugins;

	// used for defaults, when upgrading to 1.6
	global $use_fileupload, $fileupload_allowedtypes, $fileupload_maxk, $doubleCheckReferers;

	// new DB-delta functionality
	global $schema_queries, $inc_path;

	// used to check script time before starting to create db delta
	global $script_start_time;

	// Create an option which can be turned on if we need to regenerate the autogenerated excerpts in the end of the upgrade script
	global $recreate_autogenerated_excerpts;
	$recreate_autogenerated_excerpts = param( 'recreate_excerpts', 'boolean', 0 );

	// Load DB schema from modules
	load_db_schema();

	// Update the progress bar status
	update_install_progress_bar();

	load_funcs('_core/model/db/_upgrade.funcs.php');

	// Force MySQL strict mode:
	$DB->query( 'SET sql_mode = ""', 'REMOVE MySQL "strict" mode in order not to worry about missing defaults until the end of the upgrade.' );

	echo get_install_format_text_and_log( '<p><span class="text-muted">'.T_('Checking DB schema version...').' ', 'p-start' );
	$old_db_version = get_db_version();

	if( empty($old_db_version) )
	{
		echo get_install_format_text_and_log( '<p><strong>OOPS! b2evolution doesn\'t seem to be installed yet.</strong></p>', 'p' );
		return false;
	}

	echo $old_db_version, ' : ';

	if( $old_db_version < 8000 ) debug_die( T_('This version is too old!') );
	if( $old_db_version > $new_db_version ) debug_die( T_('This version is too recent! We cannot downgrade to the version you are trying to install...') );
	echo get_install_format_text_and_log( "OK.</span><br />\n", 'br' );

	if( $old_db_version < 8010 )
	{
		echo 'Upgrading users table... ';
		$query = "ALTER TABLE T_users
							MODIFY COLUMN user_pass CHAR(32) NOT NULL";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading blogs table... ';
		$query = "ALTER TABLE T_blogs
							MODIFY COLUMN blog_lang VARCHAR(20) NOT NULL DEFAULT 'en_US',
							MODIFY COLUMN blog_longdesc TEXT NULL DEFAULT NULL";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading categories table... ';
		$query = "ALTER TABLE T_categories
							ADD COLUMN cat_description VARCHAR(250) NULL DEFAULT NULL,
							ADD COLUMN cat_longdesc TEXT NULL DEFAULT NULL,
							ADD COLUMN cat_icon VARCHAR(30) NULL DEFAULT NULL";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading posts table... ';
		$query = "ALTER TABLE {$tableprefix}posts
							MODIFY COLUMN post_lang VARCHAR(20) NOT NULL DEFAULT 'en_US',
							ADD COLUMN post_urltitle VARCHAR(50) NULL DEFAULT NULL AFTER post_title,
							ADD COLUMN post_url VARCHAR(250) NULL DEFAULT NULL AFTER post_urltitle,
							ADD COLUMN post_comments ENUM('disabled', 'open', 'closed') NOT NULL DEFAULT 'open' AFTER post_wordcount";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Generating wordcounts... ';
		load_funcs('items/model/_item.funcs.php');
		$query = "SELECT ID, post_content FROM {$tableprefix}posts WHERE post_wordcount IS NULL";
		$i = 0;
		foreach( $DB->get_results( $query, ARRAY_A ) as $row )
		{
			$query_update_wordcount = "UPDATE {$tableprefix}posts
																SET post_wordcount = " . bpost_count_words($row['post_content']) . "
																WHERE ID = " . $row['ID'];
			$DB->query($query_update_wordcount);
			$i++;
		}
		echo "OK. ($i rows updated)<br />\n";

		set_upgrade_checkpoint( '8010' );
	}


	if( $old_db_version < 8020 )
	{
		echo 'Encoding passwords... ';
		$query = "UPDATE T_users
							SET user_pass = MD5(user_pass)";
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8020' );
	}


	if( $old_db_version < 8030 )
	{
		echo 'Deleting unecessary logs... ';
		$query = "DELETE FROM T_hitlog
							WHERE hit_ignore = 'badchar'";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Updating blog urls... ';
		$query = "SELECT blog_ID, blog_siteurl FROM T_blogs";
		$i = 0;
		foreach( $DB->get_results( $query, ARRAY_A ) as $row )
		{
			$blog_ID = $row['blog_ID'];
			$blog_siteurl = $row['blog_siteurl'];
			// echo $blog_ID.':'.$blog_siteurl;
			if( strpos( $blog_siteurl.'/', $baseurl ) !== 0 )
			{ // If not found at position 0
				echo ' <strong>WARNING: please check blog #', $blog_ID, ' manually.</strong><br /> ';
				continue;
			}
			// crop off the baseurl:
			$blog_siteurl = utf8_substr( $blog_siteurl.'/', utf8_strlen($baseurl) );
			// echo ' -> ', $blog_siteurl,'<br />';

			$query_update_blog = "UPDATE T_blogs SET blog_siteurl = '$blog_siteurl' WHERE blog_ID = $blog_ID";
			// echo $query_update_blog, '<br />';
			$DB->query( $query_update_blog );
			$i++;
		}
		echo "OK. ($i rows updated)<br />\n";

		set_upgrade_checkpoint( '8030' );
	}


	if( $old_db_version < 8040 )
	{ // upgrade to 0.8.7
		echo 'Creating table for Antispam Blackist... ';
		$query = "CREATE TABLE {$tableprefix}antispam (
			aspm_ID bigint(11) NOT NULL auto_increment,
			aspm_string varchar(80) NOT NULL,
			aspm_source enum( 'local','reported','central' ) NOT NULL default 'reported',
			PRIMARY KEY aspm_ID (aspm_ID),
			UNIQUE aspm_string (aspm_string)
		)";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Creating default blacklist entries... ';
		// This string contains antispam information that is obfuscated because some hosting
		// companies prevent uploading PHP files containing "spam" strings.
		// pre_dump(get_antispam_query());
		$query = get_antispam_query();
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading Settings table... ';
		$query = "ALTER TABLE T_settings
							ADD COLUMN last_antispam_update datetime NOT NULL default '2000-01-01 00:00:00'";
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8040' );
	}


	if( $old_db_version < 8050 )
	{ // upgrade to 0.8.9
		echo 'Upgrading blogs table... ';
		$query = "ALTER TABLE T_blogs
							ADD COLUMN blog_allowtrackbacks tinyint(1) NOT NULL default 1,
							ADD COLUMN blog_allowpingbacks tinyint(1) NOT NULL default 0,
							ADD COLUMN blog_pingb2evonet tinyint(1) NOT NULL default 0,
							ADD COLUMN blog_pingtechnorati tinyint(1) NOT NULL default 0,
							ADD COLUMN blog_pingweblogs tinyint(1) NOT NULL default 0,
							ADD COLUMN blog_pingblodotgs tinyint(1) NOT NULL default 0,
							ADD COLUMN blog_disp_bloglist tinyint NOT NULL DEFAULT 1";
		$DB->query( $query );
		echo "OK.<br />\n";

		// Create User Groups
		global $Group_Admins, $Group_Privileged, $Group_Bloggers, $Group_Users;
		echo 'Creating table for Groups... ';
		$query = "CREATE TABLE T_groups (
			grp_ID int(11) NOT NULL auto_increment,
			grp_name varchar(50) NOT NULL default '',
			grp_perm_admin enum('none','hidden','visible') NOT NULL default 'visible',
			grp_perm_blogs enum('user','viewall','editall') NOT NULL default 'user',
			grp_perm_stats enum('none','view','edit') NOT NULL default 'none',
			grp_perm_spamblacklist enum('none','view','edit') NOT NULL default 'none',
			grp_perm_options enum('none','view','edit') NOT NULL default 'none',
			grp_perm_users enum('none','view','edit') NOT NULL default 'none',
			grp_perm_templates TINYINT NOT NULL DEFAULT 0,
			grp_perm_files enum('none','view','add','edit','all') NOT NULL default 'none',
			PRIMARY KEY grp_ID (grp_ID)
		)";
		$DB->query( $query );
		echo "OK.<br />\n";

		// This table needs to be created here for proper group insertion
		task_begin( 'Creating table for Group Settings... ' );
		$DB->query( "CREATE TABLE T_groups__groupsettings (
			gset_grp_ID INT(11) UNSIGNED NOT NULL,
			gset_name VARCHAR(30) NOT NULL,
			gset_value VARCHAR(255) NULL,
			PRIMARY KEY (gset_grp_ID, gset_name)
		) ENGINE = innodb" );
		task_end();

		echo 'Creating default groups... ';
		$Group_Admins = new Group(); // COPY !
		$Group_Admins->set( 'name', 'Administrators' );
		$Group_Admins->set( 'perm_admin', 'visible' );
		$Group_Admins->set( 'perm_blogs', 'editall' );
		$Group_Admins->set( 'perm_stats', 'edit' );
		$Group_Admins->set( 'perm_spamblacklist', 'edit' );
		$Group_Admins->set( 'perm_files', 'all' );
		$Group_Admins->set( 'perm_options', 'edit' );
		$Group_Admins->set( 'perm_templates', 1 );
		$Group_Admins->set( 'perm_users', 'edit' );
		$Group_Admins->dbinsert();

		$Group_Privileged = new Group(); // COPY !
		$Group_Privileged->set( 'name', 'Privileged Bloggers' );
		$Group_Privileged->set( 'perm_admin', 'visible' );
		$Group_Privileged->set( 'perm_blogs', 'viewall' );
		$Group_Privileged->set( 'perm_stats', 'view' );
		$Group_Privileged->set( 'perm_spamblacklist', 'edit' );
		$Group_Privileged->set( 'perm_files', 'add' );
		$Group_Privileged->set( 'perm_options', 'view' );
		$Group_Privileged->set( 'perm_templates', 0 );
		$Group_Privileged->set( 'perm_users', 'view' );
		$Group_Privileged->dbinsert();

		$Group_Bloggers = new Group(); // COPY !
		$Group_Bloggers->set( 'name', 'Bloggers' );
		$Group_Bloggers->set( 'perm_admin', 'visible' );
		$Group_Bloggers->set( 'perm_blogs', 'user' );
		$Group_Bloggers->set( 'perm_stats', 'none' );
		$Group_Bloggers->set( 'perm_spamblacklist', 'view' );
		$Group_Bloggers->set( 'perm_files', 'view' );
		$Group_Bloggers->set( 'perm_options', 'none' );
		$Group_Bloggers->set( 'perm_templates', 0 );
		$Group_Bloggers->set( 'perm_users', 'none' );
		$Group_Bloggers->dbinsert();

		$Group_Users = new Group(); // COPY !
		$Group_Users->set( 'name', 'Basic Users' );
		$Group_Users->set( 'perm_admin', 'none' );
		$Group_Users->set( 'perm_blogs', 'user' );
		$Group_Users->set( 'perm_stats', 'none' );
		$Group_Users->set( 'perm_spamblacklist', 'none' );
		$Group_Users->set( 'perm_files', 'none' );
		$Group_Users->set( 'perm_options', 'none' );
		$Group_Users->set( 'perm_templates', 0 );
		$Group_Users->set( 'perm_users', 'none' );
		$Group_Users->dbinsert();
		echo "OK.<br />\n";


		echo 'Creating table for Blog-User permissions... ';
		$query = "CREATE TABLE T_coll_user_perms (
			bloguser_blog_ID int(11) unsigned NOT NULL default 0,
			bloguser_user_ID int(11) unsigned NOT NULL default 0,
			bloguser_ismember tinyint NOT NULL default 0,
			bloguser_perm_poststatuses set('published','deprecated','protected','private','draft') NOT NULL default '',
			bloguser_perm_delpost tinyint NOT NULL default 0,
			bloguser_perm_comments tinyint NOT NULL default 0,
			bloguser_perm_cats tinyint NOT NULL default 0,
			bloguser_perm_properties tinyint NOT NULL default 0,
			bloguser_perm_media_upload tinyint NOT NULL default 0,
			bloguser_perm_media_browse tinyint NOT NULL default 0,
			bloguser_perm_media_change tinyint NOT NULL default 0,
			PRIMARY KEY bloguser_pk (bloguser_blog_ID,bloguser_user_ID)
		)";
		$DB->query( $query );
		echo "OK.<br />\n";
		$tablegroups_isuptodate = true;
		$tableblogusers_isuptodate = true;

		echo 'Creating user blog permissions... ';
		// Admin: full rights for all blogs (look 'ma, doing a natural join! :>)
		$query = "INSERT INTO T_coll_user_perms( bloguser_blog_ID, bloguser_user_ID, bloguser_ismember,
								bloguser_perm_poststatuses, bloguser_perm_delpost, bloguser_perm_comments,
								bloguser_perm_cats, bloguser_perm_properties)
							SELECT blog_ID, ID, 1, 'published,deprecated,protected,private,draft', 1, 1, 1, 1
							FROM T_users, T_blogs
							WHERE user_level = 10";
		$DB->query( $query );

		// Normal users: basic rights for all blogs (can't stop doing joins :P)
		$query = "INSERT INTO T_coll_user_perms( bloguser_blog_ID, bloguser_user_ID, bloguser_ismember,
								bloguser_perm_poststatuses, bloguser_perm_delpost, bloguser_perm_comments,
								bloguser_perm_cats, bloguser_perm_properties)
							SELECT blog_ID, ID, 1, 'published,protected,private,draft', 0, 1, 0, 0
							FROM T_users, T_blogs
							WHERE user_level > 0 AND user_level < 10";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading users table... ';
		$DB->query( 'UPDATE T_users
									  SET dateYMDhour = \'2000-01-01 00:00:00\'
									WHERE ( dateYMDhour = \'0000-00-00 00:00:00\' OR dateYMDhour = \'2000-00-00 00:00:01\' )' );
		$DB->query( 'ALTER TABLE T_users
							MODIFY COLUMN dateYMDhour DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$query = "ALTER TABLE T_users
							ADD COLUMN user_notify tinyint(1) NOT NULL default 1,
							ADD COLUMN user_grp_ID int(4) NOT NULL default 1,
							MODIFY COLUMN user_idmode varchar(20) NOT NULL DEFAULT 'login'";
		$DB->query( $query );

		$query = "ALTER TABLE T_users
							ADD KEY user_grp_ID (user_grp_ID)";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Assigning user groups... ';

		// Default is 1, so admins are already set.

		// Basic Users:
		$query = "UPDATE T_users
							SET user_grp_ID = $Group_Users->ID
							WHERE user_level = 0";
		$DB->query( $query );

		// Bloggers:
		$query = "UPDATE T_users
							SET user_grp_ID = $Group_Bloggers->ID
							WHERE user_level > 0 AND user_level < 10";
		$DB->query( $query );

		echo "OK.<br />\n";

		echo 'Upgrading settings table... ';
		$query = "ALTER TABLE T_settings
							DROP COLUMN time_format,
							DROP COLUMN date_format,
							ADD COLUMN pref_newusers_grp_ID int unsigned DEFAULT 4 NOT NULL,
							ADD COLUMN pref_newusers_level tinyint unsigned DEFAULT 1 NOT NULL,
							ADD COLUMN pref_newusers_canregister tinyint unsigned DEFAULT 0 NOT NULL";
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8050' );
	}


	if( $old_db_version < 8060 )
	{ // upgrade to 0.9
		// Important check:
		$stub_list = $DB->get_col( "
			SELECT blog_stub
			  FROM T_blogs
			 GROUP BY blog_stub
			HAVING COUNT(*) > 1" );
		if( !empty($stub_list) )
		{
			echo '<div class="error"><p class="error">';
			printf( T_("It appears that the following blog stub names are used more than once: ['%s']" ), implode( "','", $stub_list ) );
			echo '</p><p>';
			printf( T_("I can't upgrade until you make them unique. DB field: [%s]" ), $db_config['aliases']['T_blogs'].'.blog_stub' );
			echo '</p></div>';
			return false;
		}

		// Create locales
		echo 'Creating table for Locales... ';
		$query = "CREATE TABLE T_locales (
				loc_locale varchar(20) NOT NULL default '',
				loc_charset varchar(15) NOT NULL default 'iso-8859-1',
				loc_datefmt varchar(10) NOT NULL default 'y-m-d',
				loc_timefmt varchar(10) NOT NULL default 'H:i:s',
				loc_name varchar(40) NOT NULL default '',
				loc_messages varchar(20) NOT NULL default '',
				loc_priority tinyint(4) UNSIGNED NOT NULL default '0',
				loc_enabled tinyint(4) NOT NULL default '1',
				PRIMARY KEY loc_locale( loc_locale )
			) COMMENT='saves available locales'";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading posts table... ';
		$query = "UPDATE {$tableprefix}posts
							SET post_urltitle = NULL";
		$DB->query( $query );

		$query = "ALTER TABLE {$tableprefix}posts
							CHANGE COLUMN post_date post_issue_date datetime NOT NULL default '1000-01-01 00:00:00',
							ADD COLUMN post_mod_date datetime NOT NULL default '1000-01-01 00:00:00'
										AFTER post_issue_date,
							CHANGE COLUMN post_lang post_locale varchar(20) NOT NULL default 'en-EU',
							DROP COLUMN post_url,
							CHANGE COLUMN post_trackbacks post_url varchar(250) NULL default NULL,
							ADD COLUMN post_renderers VARCHAR(179) NOT NULL default 'default'";
		$DB->query( $query );

		$query = "ALTER TABLE {$tableprefix}posts
							ADD INDEX post_issue_date( post_issue_date ),
							ADD UNIQUE post_urltitle( post_urltitle )";
		$DB->query( $query );

		$query = "ALTER TABLE {$tableprefix}posts
					DROP INDEX post_date";
		$DB->query( $query );

		$query = "UPDATE {$tableprefix}posts
							SET post_mod_date = post_issue_date";
		$DB->query( $query );
		echo "OK.<br />\n";

		// convert given languages to locales
		convert_lang_to_locale( "{$tableprefix}posts", 'post_locale', 'ID' );

		echo 'Upgrading blogs table... ';
		$query = "ALTER TABLE T_blogs
							CHANGE blog_lang blog_locale varchar(20) NOT NULL default 'en-EU',
							CHANGE blog_roll blog_notes TEXT NULL,
							MODIFY COLUMN blog_default_skin VARCHAR(30) NOT NULL DEFAULT 'custom',
							DROP COLUMN blog_filename,
							ADD COLUMN blog_access_type VARCHAR(10) NOT NULL DEFAULT 'index.php' AFTER blog_locale,
							ADD COLUMN blog_force_skin tinyint(1) NOT NULL default 0 AFTER blog_default_skin,
							ADD COLUMN blog_in_bloglist tinyint(1) NOT NULL DEFAULT 1 AFTER blog_disp_bloglist,
							ADD COLUMN blog_links_blog_ID INT(4) NOT NULL DEFAULT 0";
		$DB->query( $query );
		// Use this query separately from above because MariaDB versions 10+ create an error:
		$DB->query( 'ALTER TABLE T_blogs
			ADD UNIQUE KEY blog_stub (blog_stub)' );

		$query = "UPDATE T_blogs
							SET blog_access_type = 'stub',
									blog_default_skin = 'custom'";
		$DB->query( $query );

		echo "OK.<br />\n";

		// convert given languages to locales
		convert_lang_to_locale( 'T_blogs', 'blog_locale', 'blog_ID' );


		echo 'Converting settings table... ';

		// get old settings
		$query = 'SELECT * FROM T_settings';
		$row = $DB->get_row( $query, ARRAY_A );

		#echo 'oldrow:<br />'; pre_dump($row);
		$transform = array(
			'posts_per_page' => array(5),      // note: moved to blogsettings in 2.0
			'what_to_show' => array('posts'),  // note: moved to blogsettings in 2.0
			'archive_mode' => array('monthly'),// note: moved to blogsettings in 2.0
			'time_difference' => array(0),
			'AutoBR' => array(0),
			'last_antispam_update' => array('2000-01-01 00:00:00', 'antispam_last_update'),
			'pref_newusers_grp_ID' => array($Group_Users->ID, 'newusers_grp_ID'),
			'pref_newusers_level'  => array(1, 'newusers_level'),
			'pref_newusers_canregister' => array(0, 'newusers_canregister'),
		);

		$_trans = array();
		foreach( $transform as $oldkey => $newarr )
		{
			$newname = ( isset($newarr[1]) ? $newarr[1] : $oldkey );
			if( !isset( $row[$oldkey] ) )
			{
				echo '&nbsp;&middot;Setting '.$oldkey.' not found, using defaults.<br />';
				$_trans[ $newname ] = $newarr[0];
			}
			else
			{
				$_trans[ $newname ] = $row[$oldkey];
			}
		}

		// drop old table
		$DB->query( 'DROP TABLE IF EXISTS T_settings' );

		// create new table
		$DB->query(
			'CREATE TABLE T_settings (
				set_name VARCHAR( 30 ) NOT NULL ,
				set_value VARCHAR( 255 ) NULL ,
				PRIMARY KEY ( set_name )
			)');

		// insert defaults and use transformed settings
		create_default_settings( $_trans );

		if( !isset( $tableblogusers_isuptodate ) )
		{
			echo 'Upgrading Blog-User permissions table... ';
			$query = "ALTER TABLE T_coll_user_perms
								ADD COLUMN bloguser_ismember tinyint NOT NULL default 0 AFTER bloguser_user_ID";
			$DB->query( $query );

			// Any row that is created holds at least one permission,
			// minimum permsission is to be a member, so we add that one too, to all existing rows.
			$DB->query( "UPDATE T_coll_user_perms
											SET bloguser_ismember = 1" );
			echo "OK.<br />\n";
		}

		echo 'Upgrading Comments table... ';
		$DB->query( 'UPDATE T_comments
									  SET comment_date = \'2000-01-01 00:00:00\'
									WHERE comment_date = \'0000-00-00 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_comments
							MODIFY COLUMN comment_date DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$query = "ALTER TABLE T_comments
							ADD COLUMN comment_author_ID int unsigned NULL default NULL AFTER comment_status,
							MODIFY COLUMN comment_author varchar(100) NULL,
							MODIFY COLUMN comment_author_email varchar(100) NULL,
							MODIFY COLUMN comment_author_url varchar(100) NULL,
							MODIFY COLUMN comment_author_IP varchar(23) NOT NULL default ''";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading Users table... ';
		$query = "ALTER TABLE T_users ADD user_locale VARCHAR( 20 ) DEFAULT 'en-EU' NOT NULL AFTER user_yim";
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8060' );
	}


	if( $old_db_version < 8062 )
	{ // upgrade to 0.9.0.4
		echo "Checking for extra quote escaping in posts... ";
		$query = "SELECT ID, post_title, post_content
								FROM {$tableprefix}posts
							 WHERE post_title LIKE '%\\\\\\\\\'%'
									OR post_title LIKE '%\\\\\\\\\"%'
									OR post_content LIKE '%\\\\\\\\\'%'
									OR post_content LIKE '%\\\\\\\\\"%' ";
		/* FP: the above looks overkill, but MySQL is really full of surprises...
						tested on 4.0.14-nt */
		// echo $query;
		$rows = $DB->get_results( $query, ARRAY_A );
		if( $DB->num_rows )
		{
			echo 'Updating '.$DB->num_rows.' posts... ';
			foreach( $rows as $row )
			{
				// echo '<br />'.$row['post_title'];
				$query = "UPDATE {$tableprefix}posts
									SET post_title = ".$DB->quote( stripslashes( $row['post_title'] ) ).",
											post_content = ".$DB->quote( stripslashes( $row['post_content'] ) )."
									WHERE ID = ".$row['ID'];
				// echo '<br />'.$query;
				$DB->query( $query );
			}
		}
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8062' );
	}


	if( $old_db_version < 8064 )
	{ // upgrade to 0.9.0.6
		cleanup_comment_quotes();

		set_upgrade_checkpoint( '8064' );
	}


	if( $old_db_version < 8066 )
	{	// upgrade to 0.9.1
		echo 'Adding catpost index... ';
		$DB->query( 'ALTER TABLE T_postcats ADD UNIQUE catpost ( postcat_cat_ID, postcat_post_ID )' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8066' );
	}


	if( $old_db_version < 8800 )
	{ // ---------------------------------- upgrade to 1.6 "phoenix ALPHA"

		echo 'Dropping old Hitlog table... ';
		$DB->query( 'DROP TABLE IF EXISTS T_hitlog' );
		echo "OK.<br />\n";

		// New tables:
			echo 'Creating table for active sessions... ';
			$DB->query( "CREATE TABLE T_sessions (
											sess_ID        INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
											sess_key       CHAR(32) NULL,
											sess_lastseen  DATETIME NOT NULL,
											sess_ipaddress VARCHAR(15) NOT NULL DEFAULT '',
											sess_user_ID   INT(10) DEFAULT NULL,
											sess_agnt_ID   INT UNSIGNED NULL,
											sess_data      TEXT DEFAULT NULL,
											PRIMARY KEY( sess_ID )
										)" );
			echo "OK.<br />\n";


			echo 'Creating user settings table... ';
			$DB->query( "CREATE TABLE {$tableprefix}usersettings (
											uset_user_ID INT(11) UNSIGNED NOT NULL,
											uset_name    VARCHAR( 30 ) NOT NULL,
											uset_value   VARCHAR( 255 ) NULL,
											PRIMARY KEY ( uset_user_ID, uset_name )
										)");
			echo "OK.<br />\n";


			echo 'Creating plugins table... ';
			$DB->query( "CREATE TABLE T_plugins (
											plug_ID        INT(11) UNSIGNED NOT NULL auto_increment,
											plug_priority  INT(11) NOT NULL default 50,
											plug_classname VARCHAR(40) NOT NULL default '',
											PRIMARY KEY ( plug_ID )
										)");
			echo "OK.<br />\n";


			echo 'Creating table for Post Statuses... ';
			$query="CREATE TABLE {$tableprefix}poststatuses (
											pst_ID   int(11) unsigned not null AUTO_INCREMENT,
											pst_name varchar(30)      not null,
											primary key ( pst_ID )
										)";
			$DB->query( $query );
			echo "OK.<br />\n";


			echo 'Creating table for Post Types... ';
			$query="CREATE TABLE {$tableprefix}posttypes (
											ptyp_ID   int(11) unsigned not null AUTO_INCREMENT,
											ptyp_name varchar(30)      not null,
											primary key (ptyp_ID)
										)";
			$DB->query( $query );
			echo "OK.<br />\n";


			echo 'Creating table for File Meta Data... ';
			$DB->query( "CREATE TABLE T_files (
										 file_ID        int(11) unsigned  not null AUTO_INCREMENT,
										 file_root_type enum('absolute','user','group','collection') not null default 'absolute',
										 file_root_ID   int(11) unsigned  not null default 0,
										 file_path      varchar(255)      not null default '',
										 file_title     varchar(255),
										 file_alt       varchar(255),
										 file_desc      text,
										 primary key (file_ID),
										 unique file (file_root_type, file_root_ID, file_path)
									)" );
			echo "OK.<br />\n";


			echo 'Creating table for base domains... ';
			$DB->query( "CREATE TABLE T_basedomains (
										dom_ID     INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
										dom_name   VARCHAR(250) NOT NULL DEFAULT '',
										dom_status ENUM('unknown','whitelist','blacklist') NOT NULL DEFAULT 'unknown',
										dom_type   ENUM('unknown','normal','searcheng','aggregator') NOT NULL DEFAULT 'unknown',
										PRIMARY KEY (dom_ID),
										UNIQUE dom_name (dom_name)
									)" );	// fp> the unique key was only named in version 1.9. Crap. Put the name back here to save as many souls as possible. bulk has not upgraded from 0.9 yet :/
			echo "OK.<br />\n";

		set_upgrade_checkpoint( '8820' );
	}


	if( $old_db_version < 8840 )
	{

			echo 'Creating table for user agents... ';
			$DB->query( "CREATE TABLE {$tableprefix}useragents (
										agnt_ID        INT UNSIGNED NOT NULL AUTO_INCREMENT,
										agnt_signature VARCHAR(250) NOT NULL,
										agnt_type      ENUM('rss','robot','browser','unknown') DEFAULT 'unknown' NOT NULL,
										PRIMARY KEY (agnt_ID) )" );
			echo "OK.<br />\n";


			echo 'Creating table for Hit-Logs... ';
			$query = "CREATE TABLE T_hitlog (
									hit_ID             INT(11) NOT NULL AUTO_INCREMENT,
									hit_sess_ID        INT UNSIGNED,
									hit_datetime       DATETIME NOT NULL,
									hit_uri            VARCHAR(250) DEFAULT NULL,
									hit_referer_type   ENUM('search','blacklist','referer','direct','spam') NOT NULL,
									hit_referer        VARCHAR(250) DEFAULT NULL,
									hit_referer_dom_ID INT UNSIGNED DEFAULT NULL,
									hit_blog_ID        int(11) UNSIGNED NULL DEFAULT NULL,
									hit_remote_addr    VARCHAR(40) DEFAULT NULL,
									PRIMARY KEY (hit_ID),
									INDEX hit_datetime ( hit_datetime ),
									INDEX hit_blog_ID (hit_blog_ID)
								)";
			$DB->query( $query );
			echo "OK.<br />\n";


			echo 'Creating table for subscriptions... ';
			$DB->query( "CREATE TABLE T_subscriptions (
										 sub_coll_ID     int(11) unsigned    not null,
										 sub_user_ID     int(11) unsigned    not null,
										 sub_items       tinyint(1)          not null,
										 sub_comments    tinyint(1)          not null,
										 primary key (sub_coll_ID, sub_user_ID)
										)" );
			echo "OK.<br />\n";


			echo 'Creating table for blog-group permissions... ';
			$DB->query( "CREATE TABLE T_coll_group_perms (
											bloggroup_blog_ID int(11) unsigned NOT NULL default 0,
											bloggroup_group_ID int(11) unsigned NOT NULL default 0,
											bloggroup_ismember tinyint NOT NULL default 0,
											bloggroup_perm_poststatuses set('published','deprecated','protected','private','draft') NOT NULL default '',
											bloggroup_perm_delpost tinyint NOT NULL default 0,
											bloggroup_perm_comments tinyint NOT NULL default 0,
											bloggroup_perm_cats tinyint NOT NULL default 0,
											bloggroup_perm_properties tinyint NOT NULL default 0,
											bloggroup_perm_media_upload tinyint NOT NULL default 0,
											bloggroup_perm_media_browse tinyint NOT NULL default 0,
											bloggroup_perm_media_change tinyint NOT NULL default 0,
											PRIMARY KEY bloggroup_pk (bloggroup_blog_ID,bloggroup_group_ID) )" );
			echo "OK.<br />\n";


		echo 'Upgrading blogs table... ';
		$query = "ALTER TABLE T_blogs
							MODIFY COLUMN blog_ID int(11) unsigned NOT NULL auto_increment,
							MODIFY COLUMN blog_links_blog_ID INT(11) NULL DEFAULT NULL,
							CHANGE COLUMN blog_stub blog_urlname VARCHAR(255) NOT NULL DEFAULT 'urlname',
							ADD COLUMN blog_allowcomments VARCHAR(20) NOT NULL default 'post_by_post' AFTER blog_keywords,
							ADD COLUMN blog_allowblogcss TINYINT(1) NOT NULL default 1 AFTER blog_allowpingbacks,
							ADD COLUMN blog_allowusercss TINYINT(1) NOT NULL default 1 AFTER blog_allowblogcss,
							ADD COLUMN blog_stub VARCHAR(255) NOT NULL DEFAULT 'stub' AFTER blog_staticfilename,
							ADD COLUMN blog_commentsexpire INT(4) NOT NULL DEFAULT 0 AFTER blog_links_blog_ID,
							ADD COLUMN blog_media_location ENUM( 'default', 'subdir', 'custom', 'none' ) DEFAULT 'default' NOT NULL AFTER blog_commentsexpire,
							ADD COLUMN blog_media_subdir VARCHAR( 255 ) NOT NULL AFTER blog_media_location,
							ADD COLUMN blog_media_fullpath VARCHAR( 255 ) NOT NULL AFTER blog_media_subdir,
							ADD COLUMN blog_media_url VARCHAR(255) NOT NULL AFTER blog_media_fullpath";
		$DB->query( $query );
		// Use this query separately from above because MariaDB versions 10+ create an error:
		$DB->query( 'ALTER TABLE T_blogs
							DROP INDEX blog_stub' );

		$query = "ALTER TABLE T_blogs
							ADD UNIQUE blog_urlname ( blog_urlname )";
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8840' );
	}


	// sam2kb>fp: We need to make sure there are no values like "blog_a.php" in blog_urlname,
	//			after this upgrade blog URLs look like $baseurl.'blog_a.php' which might be OK in 0.x version,
	//			but this config will not work in b2evo 4. Blog URLs will be broken!
	if( $old_db_version < 8850 )
	{
		echo 'Updating relative URLs... ';
		// We need to move the slashes to the end:
		$query = "UPDATE T_blogs
								 SET blog_siteurl = CONCAT( SUBSTRING(blog_siteurl,2) , '/' )
							 WHERE blog_siteurl LIKE '/%'";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Copying urlnames to stub names... ';
		$query = 'UPDATE T_blogs
							SET blog_stub = blog_urlname';
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8850' );
	}


	if( $old_db_version < 8855 )
	{
		echo 'Upgrading posts table... ';
		$query = "ALTER TABLE {$tableprefix}posts
							DROP INDEX post_author,
							DROP INDEX post_issue_date,
							DROP INDEX post_category";
		$DB->query( $query );

		$query = "ALTER TABLE {$tableprefix}posts
							DROP COLUMN post_karma,
							DROP COLUMN post_autobr,
							CHANGE COLUMN ID post_ID int(11) unsigned NOT NULL auto_increment,
							CHANGE COLUMN post_author	post_creator_user_ID int(11) unsigned NOT NULL,
							CHANGE COLUMN post_issue_date	post_datestart datetime NOT NULL,
							CHANGE COLUMN post_mod_date	post_datemodified datetime NOT NULL,
							CHANGE COLUMN post_category post_main_cat_ID int(11) unsigned NOT NULL,
							ADD post_parent_ID				int(11) unsigned NULL AFTER post_ID,
							ADD post_lastedit_user_ID	int(11) unsigned NULL AFTER post_creator_user_ID,
							ADD post_assigned_user_ID	int(11) unsigned NULL AFTER post_lastedit_user_ID,
							ADD post_datedeadline 		datetime NULL AFTER post_datestart,
							ADD post_datecreated			datetime NULL AFTER post_datedeadline,
							ADD post_pst_ID						int(11) unsigned NULL AFTER post_status,
							ADD post_ptyp_ID					int(11) unsigned NULL AFTER post_pst_ID,
							ADD post_views						int(11) unsigned NOT NULL DEFAULT 0 AFTER post_flags,
							ADD post_commentsexpire		datetime DEFAULT NULL AFTER post_comments,
							ADD post_priority					int(11) unsigned null";
		$DB->query( $query );

		$query = "ALTER TABLE {$tableprefix}posts
							ADD INDEX post_creator_user_ID( post_creator_user_ID ),
							ADD INDEX post_parent_ID( post_parent_ID ),
							ADD INDEX post_assigned_user_ID( post_assigned_user_ID ),
							ADD INDEX post_datestart( post_datestart ),
							ADD INDEX post_main_cat_ID( post_main_cat_ID ),
							ADD INDEX post_ptyp_ID( post_ptyp_ID ),
							ADD INDEX post_pst_ID( post_pst_ID ) ";
		$DB->query( $query );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '8855' );
	}


	if( $old_db_version < 8860 )
	{
		echo 'Updating post data... ';
		$query = "UPDATE {$tableprefix}posts
							SET post_lastedit_user_ID = post_creator_user_ID,
									post_datecreated = post_datestart";
		$DB->query( $query );
		echo "OK.<br />\n";


		task_begin( 'Upgrading users table... ' );
		$DB->query( 'UPDATE T_users
									  SET dateYMDhour = \'2000-01-01 00:00:00\'
									WHERE dateYMDhour = \'0000-00-00 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_users
							MODIFY COLUMN dateYMDhour DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
							CHANGE COLUMN ID user_ID int(11) unsigned NOT NULL auto_increment,
							MODIFY COLUMN user_icq int(11) unsigned DEFAULT 0 NOT NULL,
							ADD COLUMN user_showonline tinyint(1) NOT NULL default 1 AFTER user_notify' );
		task_end();


		set_upgrade_checkpoint( '8860' );
	}


	if( $old_db_version < 8900 )
	{

		echo 'Setting new defaults... ';
		$query = 'INSERT INTO T_settings (set_name, set_value)
							VALUES
								( "reloadpage_timeout", "300" ),
								( "upload_enabled", "'.(isset($use_fileupload) ? (int)$use_fileupload : '1').'" ),
								( "upload_allowedext", "'.(isset($fileupload_allowedtypes) ? $fileupload_allowedtypes : 'jpg gif png').'" ),
								( "upload_maxkb", "'.(isset($fileupload_maxk) ? (int)$fileupload_maxk : '96').'" )
							';
		$DB->query( $query );
		// Replace "paged" mode with "posts" // note: moved to blogsettings in 2.0
		$DB->query( 'UPDATE T_settings
										SET set_value = "posts"
									WHERE set_name = "what_to_show"
									  AND set_value = "paged"' );
		echo "OK.<br />\n";


		if( !isset( $tableblogusers_isuptodate ) )
		{	// We have created the blogusers table before and it's already clean!
			echo 'Altering table for Blog-User permissions... ';
			$DB->query( 'ALTER TABLE T_coll_user_perms
										MODIFY COLUMN bloguser_blog_ID int(11) unsigned NOT NULL default 0,
										MODIFY COLUMN bloguser_user_ID int(11) unsigned NOT NULL default 0,
										ADD COLUMN bloguser_perm_media_upload tinyint NOT NULL default 0,
										ADD COLUMN bloguser_perm_media_browse tinyint NOT NULL default 0,
										ADD COLUMN bloguser_perm_media_change tinyint NOT NULL default 0' );
			echo "OK.<br />\n";
		}


		task_begin( 'Altering comments table...' );
		$DB->query( 'UPDATE T_comments
									  SET comment_date = \'2000-01-01 00:00:00\'
									WHERE comment_date = \'0000-00-00 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_comments
									MODIFY COLUMN comment_date DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
									MODIFY COLUMN comment_post_ID		int(11) unsigned NOT NULL default 0' );
		task_end();

		set_upgrade_checkpoint( '8900' );
	}

	if( $old_db_version < 9000 )
	{
		echo 'Altering Posts to Categories table... ';
		$DB->query( "ALTER TABLE T_postcats
									MODIFY COLUMN postcat_post_ID int(11) unsigned NOT NULL,
									MODIFY COLUMN postcat_cat_ID int(11) unsigned NOT NULL" );
		echo "OK.<br />\n";


		echo 'Altering Categories table... ';
		$DB->query( "ALTER TABLE T_categories
									MODIFY COLUMN cat_ID int(11) unsigned NOT NULL auto_increment,
									MODIFY COLUMN cat_parent_ID int(11) unsigned NULL,
									MODIFY COLUMN cat_blog_ID int(11) unsigned NOT NULL default 2" );
		echo "OK.<br />\n";


		echo 'Altering Locales table... ';
		$DB->query( 'ALTER TABLE T_locales
									ADD loc_startofweek TINYINT UNSIGNED NOT NULL DEFAULT 1 AFTER loc_timefmt' );
		echo "OK.<br />\n";


		if( !isset( $tablegroups_isuptodate ) )
		{	// We have created the groups table before and it's already clean!
			echo 'Altering Groups table... ';
			$DB->query( "ALTER TABLE T_groups
										ADD COLUMN grp_perm_admin enum('none','hidden','visible') NOT NULL default 'visible' AFTER grp_name,
										ADD COLUMN grp_perm_files enum('none','view','add','edit') NOT NULL default 'none'" );
			echo "OK.<br />\n";
		}


		echo 'Creating table for Post Links... ';
		$DB->query( "CREATE TABLE T_links (
									link_ID               int(11) unsigned  not null AUTO_INCREMENT,
									link_datecreated      datetime          not null,
									link_datemodified     datetime          not null,
									link_creator_user_ID  int(11) unsigned  not null,
									link_lastedit_user_ID int(11) unsigned  not null,
									link_item_ID          int(11) unsigned  NOT NULL,
									link_dest_item_ID     int(11) unsigned  NULL,
									link_file_ID          int(11) unsigned  NULL,
									link_ltype_ID         int(11) unsigned  NOT NULL default 1,
									link_external_url     VARCHAR(255)      NULL,
									link_title            TEXT              NULL,
									PRIMARY KEY (link_ID),
									INDEX link_item_ID( link_item_ID ),
									INDEX link_dest_item_ID (link_dest_item_ID),
									INDEX link_file_ID (link_file_ID)
								)" );
		echo "OK.<br />\n";


		echo 'Creating default Post Types... ';
		$DB->query( "
			INSERT INTO {$tableprefix}posttypes ( ptyp_ID, ptyp_name )
			VALUES ( 1, 'Post' ),
			       ( 2, 'Link' )" );
		echo "OK.<br />\n";


		set_upgrade_checkpoint( '9000' );
	}


	if( $old_db_version < 9100 )
	{	// 1.8 ALPHA

		echo 'Creating table for plugin events... ';
		$DB->query( '
			CREATE TABLE T_pluginevents(
					pevt_plug_ID INT(11) UNSIGNED NOT NULL,
					pevt_event VARCHAR(40) NOT NULL,
					pevt_enabled TINYINT NOT NULL DEFAULT 1,
					PRIMARY KEY( pevt_plug_ID, pevt_event )
				)' );
		echo "OK.<br />\n";


		echo 'Altering Links table... ';
		$DB->query( 'ALTER TABLE T_links
		             CHANGE link_item_ID link_itm_ID INT( 11 ) UNSIGNED NOT NULL,
		             CHANGE link_dest_item_ID link_dest_itm_ID INT( 11 ) UNSIGNED NULL' );
		echo "OK.<br />\n";


		if( $old_db_version >= 9000 )
		{ // sess_agnt_ID used in Phoenix-Alpha
			echo 'Altering sessions table... ';
			$query = "
					ALTER TABLE T_sessions
					 DROP COLUMN sess_agnt_ID";
			$DB->query( $query );
			echo "OK.<br />\n";
		}

		echo 'Creating table for file types... ';
		$DB->query( '
				CREATE TABLE T_filetypes (
					ftyp_ID int(11) unsigned NOT NULL auto_increment,
					ftyp_extensions varchar(30) NOT NULL,
					ftyp_name varchar(30) NOT NULL,
					ftyp_mimetype varchar(50) NOT NULL,
					ftyp_icon varchar(20) default NULL,
					ftyp_viewtype varchar(10) NOT NULL,
					ftyp_allowed tinyint(1) NOT NULL default 0,
					PRIMARY KEY (ftyp_ID)
				)' );
		echo "OK.<br />\n";

		echo 'Creating default file types... ';
		$DB->query( "INSERT INTO T_filetypes
				(ftyp_ID, ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
			VALUES
				(1, 'gif', 'GIF image', 'image/gif', 'image2.png', 'image', 1),
				(2, 'png', 'PNG image', 'image/png', 'image2.png', 'image', 1),
				(3, 'jpg jpeg', 'JPEG image', 'image/jpeg', 'image2.png', 'image', 1),
				(4, 'txt', 'Text file', 'text/plain', 'document.png', 'text', 1),
				(5, 'htm html', 'HTML file', 'text/html', 'html.png', 'browser', 0),
				(6, 'pdf', 'PDF file', 'application/pdf', 'pdf.png', 'browser', 1),
				(7, 'doc', 'Microsoft Word file', 'application/msword', 'doc.gif', 'external', 1),
				(8, 'xls', 'Microsoft Excel file', 'application/vnd.ms-excel', 'xls.gif', 'external', 1),
				(9, 'ppt', 'Powerpoint', 'application/vnd.ms-powerpoint', 'ppt.gif', 'external', 1),
				(10, 'pps', 'Slideshow', 'pps', 'pps.gif', 'external', 1),
				(11, 'zip', 'ZIP archive', 'application/zip', 'zip.gif', 'external', 1),
				(12, 'php php3 php4 php5 php6', 'PHP script', 'application/x-httpd-php', 'php.gif', 'text', 0),
				(13, 'css', 'Style sheet', 'text/css', '', 'text', 1)
			" );
		echo "OK.<br />\n";

		echo 'Giving Administrator Group edit perms on files... ';
		$DB->query( 'UPDATE T_groups
		             SET grp_perm_files = "edit"
		             WHERE grp_ID = 1' );
	 	// Later versions give 'all' on install, but we won't upgrade to that for security.
		echo "OK.<br />\n";

		echo 'Giving Administrator Group full perms on media for all blogs... ';
		$DB->query( 'UPDATE T_coll_group_perms
		             SET bloggroup_perm_media_upload = 1,
		                 bloggroup_perm_media_browse = 1,
		                 bloggroup_perm_media_change = 1
		             WHERE bloggroup_group_ID = 1' );
		echo "OK.<br />\n";


		if( $old_db_version >= 9000 )
		{ // Uninstall all ALPHA (potentially incompatible) plugins
			echo 'Uninstalling all existing plugins... ';
			$DB->query( 'DELETE FROM T_plugins WHERE 1=1' );
			echo "OK.<br />\n";
		}

		// NOTE: basic plugins get installed separatly for upgrade and install..


		set_upgrade_checkpoint( '9100' );
	}


	if( $old_db_version < 9190 ) // Note: changed from 9200, to include the block below, if DB is not yet on 1.8
	{	// 1.8 ALPHA (block #2)
		echo 'Altering Posts table... ';
		$DB->query( "ALTER TABLE {$tableprefix}posts
		             CHANGE post_comments post_comment_status ENUM('disabled', 'open', 'closed') NOT NULL DEFAULT 'open'" );
		echo "OK.<br />\n";


		set_upgrade_checkpoint( '9190' );
	}


	if( $old_db_version < 9192 )
	{ // 1.8 ALPHA (block #3) - The payload that db_delta() handled before

		// This is a fix, which broke upgrade to 1.8 (from 1.6) in MySQL strict mode (inserted after 1.8 got released!):
		if( $DB->get_row( 'SHOW COLUMNS FROM T_hitlog LIKE "hit_referer_type"' ) )
		{ // a niiiiiiiice extra check :p
			task_begin( 'Deleting all "spam" hitlog entries... ' );
			$DB->query( '
					DELETE FROM T_hitlog
					 WHERE hit_referer_type = "spam"' );
			task_end();
		}

		task_begin( 'Upgrading users table... ' );
		$DB->query( 'ALTER TABLE T_users
										CHANGE COLUMN user_firstname user_firstname varchar(50) NULL,
										CHANGE COLUMN user_lastname user_lastname varchar(50) NULL,
										CHANGE COLUMN user_nickname user_nickname varchar(50) NULL,
										CHANGE COLUMN user_icq user_icq int(11) unsigned NULL,
										CHANGE COLUMN user_email user_email varchar(255) NOT NULL,
										CHANGE COLUMN user_url user_url varchar(255) NULL,
										CHANGE COLUMN user_ip user_ip varchar(15) NULL,
										CHANGE COLUMN user_domain user_domain varchar(200) NULL,
										CHANGE COLUMN user_browser user_browser varchar(200) NULL,
										CHANGE COLUMN user_aim user_aim varchar(50) NULL,
										CHANGE COLUMN user_msn user_msn varchar(100) NULL,
										CHANGE COLUMN user_yim user_yim varchar(50) NULL,
										ADD COLUMN user_allow_msgform TINYINT NOT NULL DEFAULT \'1\' AFTER user_idmode,
										ADD COLUMN user_validated TINYINT(1) NOT NULL DEFAULT 0 AFTER user_grp_ID' );
		task_end();

		task_begin( 'Creating blog settings...' );
		$DB->query( 'CREATE TABLE T_coll_settings (
															cset_coll_ID INT(11) UNSIGNED NOT NULL,
															cset_name    VARCHAR( 30 ) NOT NULL,
															cset_value   VARCHAR( 255 ) NULL,
															PRIMARY KEY ( cset_coll_ID, cset_name )
											)' );
		task_end();
		set_upgrade_checkpoint( '9192' );
	}


	if( $old_db_version < 9195 )
	{
		task_begin( 'Upgrading posts table... ' );
		$DB->query( 'ALTER TABLE '.$tableprefix.'posts
										CHANGE COLUMN post_content post_content         text NULL,
										CHANGE COLUMN post_url post_url              		VARCHAR(255) NULL DEFAULT NULL,
										CHANGE COLUMN post_renderers post_renderers     TEXT NOT NULL' );
		task_end();

		task_begin( 'Upgrading comments table... ' );
		$DB->query( 'ALTER TABLE T_comments
										CHANGE COLUMN comment_author_email comment_author_email varchar(255) NULL,
										CHANGE COLUMN comment_author_url comment_author_url varchar(255) NULL,
										ADD COLUMN comment_spam_karma TINYINT NULL AFTER comment_karma,
										ADD COLUMN comment_allow_msgform TINYINT NOT NULL DEFAULT 0 AFTER comment_spam_karma' );
		task_end();

		set_upgrade_checkpoint( '9195' );
	}


	if( $old_db_version < 9200 )
	{
		task_begin( 'Upgrading hitlog table... ' );
		$DB->query( 'ALTER TABLE T_hitlog
										CHANGE COLUMN hit_referer_type hit_referer_type   ENUM(\'search\',\'blacklist\',\'referer\',\'direct\') NOT NULL,
										ADD COLUMN hit_agnt_ID        INT UNSIGNED NULL AFTER hit_remote_addr' );
		task_end();

		task_begin( 'Upgrading post links table... ' );
		$DB->query( 'ALTER TABLE T_links
										ADD INDEX link_itm_ID( link_itm_ID ),
										ADD INDEX link_dest_itm_ID (link_dest_itm_ID)' );
		task_end();

		task_begin( 'Upgrading plugins table... ' );
		$DB->query( 'ALTER TABLE T_plugins
										CHANGE COLUMN plug_priority plug_priority        TINYINT NOT NULL default 50,
										ADD COLUMN plug_code            VARCHAR(32) NULL AFTER plug_classname,
										ADD COLUMN plug_apply_rendering ENUM( \'stealth\', \'always\', \'opt-out\', \'opt-in\', \'lazy\', \'never\' ) NOT NULL DEFAULT \'never\' AFTER plug_code,
										ADD COLUMN plug_version         VARCHAR(42) NOT NULL default \'0\' AFTER plug_apply_rendering,
										ADD COLUMN plug_status          ENUM( \'enabled\', \'disabled\', \'needs_config\', \'broken\' ) NOT NULL AFTER plug_version,
										ADD COLUMN plug_spam_weight     TINYINT UNSIGNED NOT NULL DEFAULT 1 AFTER plug_status');
		$DB->query( 'ALTER TABLE T_plugins
										ADD UNIQUE plug_code( plug_code ),
										ADD INDEX plug_status( plug_status )' );
		task_end();

		task_begin( 'Creating plugin settings table... ' );
		$DB->query( 'CREATE TABLE T_pluginsettings (
															pset_plug_ID INT(11) UNSIGNED NOT NULL,
															pset_name VARCHAR( 30 ) NOT NULL,
															pset_value TEXT NULL,
															PRIMARY KEY ( pset_plug_ID, pset_name )
											)' );
		task_end();

		task_begin( 'Creating plugin user settings table... ' );
		$DB->query( 'CREATE TABLE T_pluginusersettings (
															puset_plug_ID INT(11) UNSIGNED NOT NULL,
															puset_user_ID INT(11) UNSIGNED NOT NULL,
															puset_name VARCHAR( 30 ) NOT NULL,
															puset_value TEXT NULL,
															PRIMARY KEY ( puset_plug_ID, puset_user_ID, puset_name )
											)' );
		task_end();

		task_begin( 'Creating scheduled tasks table... ' );
		$DB->query( 'CREATE TABLE T_cron__task(
												 ctsk_ID              int(10) unsigned      not null AUTO_INCREMENT,
												 ctsk_start_datetime  datetime              not null,
												 ctsk_repeat_after    int(10) unsigned,
												 ctsk_name            varchar(50)           not null,
												 ctsk_controller      varchar(50)           not null,
												 ctsk_params          text,
												 primary key (ctsk_ID)
											)' );
		task_end();

		task_begin( 'Creating cron log table... ' );
		$DB->query( 'CREATE TABLE T_cron__log(
															 clog_ctsk_ID              int(10) unsigned   not null,
															 clog_realstart_datetime   datetime           not null,
															 clog_realstop_datetime    datetime,
															 clog_status               enum(\'started\',\'finished\',\'error\',\'timeout\') not null default \'started\',
															 clog_messages             text,
															 primary key (clog_ctsk_ID)
											)' );
		task_end();

		task_begin( 'Upgrading blogs table... ' );
		// blog_allowpingbacks is "DEFAULT 1" in the 0.9.0.11 dump.. - changed in 0.9.2?!
		$DB->query( 'ALTER TABLE T_blogs
										ALTER COLUMN blog_allowpingbacks SET DEFAULT 0,
    								CHANGE COLUMN blog_media_subdir blog_media_subdir VARCHAR( 255 ) NULL,
										CHANGE COLUMN blog_media_fullpath blog_media_fullpath VARCHAR( 255 ) NULL,
										CHANGE COLUMN blog_media_url blog_media_url VARCHAR( 255 ) NULL' );
		task_end();


		set_upgrade_checkpoint( '9200' ); // at 1.8 "Summer Beta" release
	}


	// ____________________________ 1.9: ____________________________

	if( $old_db_version < 9290 )
	{
		echo 'Post-fix hit_referer_type == NULL... ';
		// If you've upgraded from 1.6 to 1.8 and it did not break because of strict mode, there are now NULL values for what "spam" was:
		$DB->query( '
					DELETE FROM T_hitlog
					 WHERE hit_referer_type IS NULL' );
		echo "OK.<br />\n";

		echo 'Marking administrator accounts as validated... ';
		$DB->query( '
				UPDATE T_users
				   SET user_validated = 1
				 WHERE user_grp_ID = 1' );
		echo "OK.<br />\n";

		echo 'Converting auto_prune_stats setting... ';
		$old_auto_prune_stats = $DB->get_var( '
				SELECT set_value
				  FROM T_settings
				 WHERE set_name = "auto_prune_stats"' );
		if( ! is_null($old_auto_prune_stats) && $old_auto_prune_stats < 1 )
		{ // This means it has been disabled before, so set auto_prune_stats_mode to "off"!
			$DB->query( '
					REPLACE INTO T_settings ( set_name, set_value )
					 VALUES ( "auto_prune_stats_mode", "off" )' );
		}
		echo "OK.<br />\n";

		echo 'Converting time_difference from hours to seconds... ';
		$DB->query( 'UPDATE T_settings SET set_value = set_value*3600 WHERE set_name = "time_difference"' );
		echo "OK.<br />\n";


		echo 'Updating hitlog capabilities... ';
		$DB->query( '
				ALTER TABLE '.$tableprefix.'useragents ADD INDEX agnt_type ( agnt_type )' );
		$DB->query( '
				ALTER TABLE T_hitlog
				  CHANGE COLUMN hit_referer_type hit_referer_type ENUM(\'search\',\'blacklist\',\'referer\',\'direct\',\'self\',\'admin\') NOT NULL' );
		echo "OK.<br />\n";

		echo 'Updating plugin capabilities... ';
		$DB->query( '
				ALTER TABLE T_plugins
					MODIFY COLUMN plug_status ENUM( \'enabled\', \'disabled\', \'needs_config\', \'broken\' ) NOT NULL' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9290' );
	}


	if( $old_db_version < 9300 )
	{
		// This can be so long, it needs its own checkpoint protected block in case of failure
		echo 'Updating hitlog indexes... ';
		$DB->query( '
				ALTER TABLE T_hitlog
				  ADD INDEX hit_agnt_ID        ( hit_agnt_ID ),
				  ADD INDEX hit_uri            ( hit_uri ),
				  ADD INDEX hit_referer_dom_ID ( hit_referer_dom_ID )
				' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9300' );
	}


	if( $old_db_version < 9310 )
	{
		echo 'Updating basedomains... ';
		$DB->query( '
				UPDATE T_basedomains
				   SET dom_status = "unknown"' );		// someone has filled this up with junk blacklists before
		$DB->query( '
				ALTER TABLE T_basedomains  ADD INDEX dom_type (dom_type)' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9310' );
	}


	if( $old_db_version < 9315 )
	{
		echo 'Altering locales table... ';
		$DB->query( "ALTER TABLE T_locales CHANGE COLUMN loc_datefmt loc_datefmt varchar(20) NOT NULL default 'y-m-d'" );
		$DB->query( "ALTER TABLE T_locales CHANGE COLUMN loc_timefmt loc_timefmt varchar(20) NOT NULL default 'H:i:s'" );
		echo "OK.<br />\n";

		echo 'Creating item prerendering cache table... ';
		$DB->query( "
				CREATE TABLE {$tableprefix}item__prerendering(
					itpr_itm_ID                   INT(11) UNSIGNED NOT NULL,
					itpr_format                   ENUM('htmlbody', 'entityencoded', 'xml', 'text') NOT NULL,
					itpr_renderers                TEXT NOT NULL,
					itpr_content_prerendered      TEXT NULL,
					itpr_datemodified             TIMESTAMP NOT NULL,
					PRIMARY KEY (itpr_itm_ID, itpr_format)
				)" );
		echo "OK.<br />\n";

		echo 'Altering plugins table... ';
		$DB->query( "ALTER TABLE T_plugins ADD COLUMN plug_name            VARCHAR(255) NULL default NULL AFTER plug_version" );
		$DB->query( "ALTER TABLE T_plugins ADD COLUMN plug_shortdesc       VARCHAR(255) NULL default NULL AFTER plug_name" );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9315' );
	}


	if( $old_db_version < 9320 )
	{ // Dropping hit_datetime because it's very slow on INSERT (dh)
		// This can be so long, it needs its own checkpoint protected block in case of failure
		if( db_index_exists( 'T_hitlog', 'hit_datetime' ) )
		{ // only drop, if it still exists (may have been removed manually)
			echo 'Updating hitlog indexes... ';
			$DB->query( '
					ALTER TABLE T_hitlog
						DROP INDEX hit_datetime
					' );
			echo "OK.<br />\n";
		}

		set_upgrade_checkpoint( '9320' );
	}


	if( $old_db_version < 9326 )
	{
		echo 'Removing obsolete settings... ';
		$DB->query( 'DELETE FROM T_settings WHERE set_name = "upload_allowedext"' );
		echo "OK.<br />\n";

		echo 'Updating blogs... ';
		db_drop_col( 'T_blogs', 'blog_allowpingbacks' );

		// Remove and transform obsolete fields blog_pingb2evonet, blog_pingtechnorati, blog_pingweblogs, blog_pingblodotgs
		if( db_cols_exist( 'T_blogs', array('blog_pingb2evonet', 'blog_pingtechnorati', 'blog_pingweblogs', 'blog_pingblodotgs') ) )
		{
			foreach( $DB->get_results( '
					SELECT blog_ID, blog_pingb2evonet, blog_pingtechnorati, blog_pingweblogs, blog_pingblodotgs
						FROM T_blogs' ) as $row )
			{
				$ping_plugins = $DB->get_var( 'SELECT cset_value FROM T_coll_settings WHERE cset_coll_ID = '.$row->blog_ID.' AND cset_name = "ping_plugins"' );
				$ping_plugins = explode(',', $ping_plugins);
				if( $row->blog_pingb2evonet )
				{
					$ping_plugins[] = 'ping_b2evonet';
				}
				if( $row->blog_pingtechnorati || $row->blog_pingweblogs || $row->blog_pingblodotgs )
				{ // if either one of the previous pingers was enabled, add ping-o-matic:
					$ping_plugins[] = 'ping_pingomatic';
				}

				// Insert transformed/generated ping plugins collection setting:
				$ping_plugins = array_unique($ping_plugins);
				$DB->query( 'REPLACE INTO T_coll_settings
						( cset_coll_ID, cset_name, cset_value )
						VALUES ( '.$row->blog_ID.', "ping_plugins", "'.implode( ',', $ping_plugins ).'" )' );
			}
			$DB->query( 'ALTER TABLE T_blogs
					DROP COLUMN blog_pingb2evonet,
					DROP COLUMN blog_pingtechnorati,
					DROP COLUMN blog_pingweblogs,
					DROP COLUMN blog_pingblodotgs' );
		}
		echo "OK.<br />\n";


		set_upgrade_checkpoint( '9326' );
	}


	if( $old_db_version < 9328 )
	{
		echo 'Updating posts... ';
		db_add_col( "{$tableprefix}posts", 'post_notifications_status',  'ENUM("noreq","todo","started","finished") NOT NULL DEFAULT "noreq" AFTER post_flags' );
		db_add_col( "{$tableprefix}posts", 'post_notifications_ctsk_ID', 'INT(10) unsigned NULL DEFAULT NULL AFTER post_notifications_status' );
		echo "OK.<br />\n";
		set_upgrade_checkpoint( '9328' );
	}


	if( $old_db_version < 9330 )
	{
		if( db_col_exists( "{$tableprefix}posts", 'post_flags') )
		{
			echo 'Updating post notifications... ';
			$DB->query( "
				UPDATE {$tableprefix}posts
					 SET post_notifications_status = 'finished'
				 WHERE post_flags LIKE '%pingsdone%'" );
			db_drop_col( "{$tableprefix}posts", 'post_flags' );
			echo "OK.<br />\n";
		}
		set_upgrade_checkpoint( '9330' );
	}


	if( $old_db_version < 9340 )
	{
		echo 'Removing duplicate post link indexes... ';
		if( db_index_exists( 'T_links', 'link_item_ID' ) )
		{ // only drop, if it still exists (may have been removed manually)
			$DB->query( '
					ALTER TABLE T_links
						DROP INDEX link_item_ID
					' );
		}
		if( db_index_exists( 'T_links', 'link_dest_item_ID' ) )
		{ // only drop, if it still exists (may have been removed manually)
			$DB->query( '
					ALTER TABLE T_links
						DROP INDEX link_dest_item_ID
					' );
		}
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9340' );
	}

	// ____________________________ 1.10: ____________________________

	if( $old_db_version < 9345 )
	{
		echo 'Updating post table... ';
		$DB->query( "ALTER TABLE {$tableprefix}posts CHANGE COLUMN post_content post_content MEDIUMTEXT NULL" );
		echo "OK.<br />\n";
		set_upgrade_checkpoint( '9345' );
	}

	if( $old_db_version < 9346 )
	{
		echo 'Updating prerendering table... ';
		$DB->query( "ALTER TABLE {$tableprefix}item__prerendering CHANGE COLUMN itpr_content_prerendered itpr_content_prerendered MEDIUMTEXT NULL" );
		echo "OK.<br />\n";
		set_upgrade_checkpoint( '9346' );
	}

	if( $old_db_version < 9348 )
	{
		echo 'Updating sessions table... ';
		$DB->query( 'ALTER TABLE T_sessions CHANGE COLUMN sess_data sess_data MEDIUMBLOB DEFAULT NULL' );
		echo "OK.<br />\n";
		set_upgrade_checkpoint( '9348' );
	}

	if( $old_db_version < 9350 )
	{
		echo 'Updating hitlog table... ';
		$DB->query( 'ALTER TABLE T_hitlog CHANGE COLUMN hit_referer_type hit_referer_type   ENUM(\'search\',\'blacklist\',\'spam\',\'referer\',\'direct\',\'self\',\'admin\') NOT NULL' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9350' );
	}


	// TODO: "If a user has permission to edit a blog, he should be able to put files in the media folder for that blog." - see http://forums.b2evolution.net/viewtopic.php?p=36417#36417
	/*
	// blueyed>> I've came up with the following, but it's too generic IMHO
	if( $old_db_version < 9300 )
	{
		echo 'Setting automatic media perms on blogs (members can upload)... ';
		$users = $DB->query( '
				UPDATE T_users
				   SET bloguser_perm_media_upload = 1
				 WHERE bloguser_ismember = 1' );
		echo "OK.<br />\n";
	}
	*/


	// ____________________________ 2.0: ____________________________

	if( $old_db_version < 9406 )
	{
		echo 'Updating chapter url names... ';
		$DB->query( '
			ALTER TABLE T_categories
				ADD COLUMN cat_urlname VARCHAR(255) NOT NULL' );

		// Create cat_urlname from cat_name:
		// TODO: Also use it for cafelog upgrade.
		load_funcs('locales/_charset.funcs.php');
		foreach( $DB->get_results('SELECT cat_ID, cat_name FROM T_categories') as $cat )
		{
			$cat_name = trim($cat->cat_name);
			if( strlen($cat_name) )
			{
				// TODO: dh> pass locale (useful for transliteration). From main blog?
				$cat_urlname = urltitle_validate('', $cat_name, $cat->cat_ID, false, 'cat_urlname', 'cat_ID', 'T_categories');
			}
			else
			{
				$cat_urlname = 'c'.$cat->cat_ID;
			}

			$DB->query( '
				UPDATE T_categories
					 SET cat_urlname = '.$DB->quote($cat_urlname).'
				 WHERE cat_ID = '.$cat->cat_ID );
		}

		$DB->query( '
			ALTER TABLE T_categories
				ADD UNIQUE cat_urlname ( cat_urlname )' );
		echo "OK.<br />\n";

		echo 'Updating Settings... ';
		$DB->query( '
      UPDATE T_settings
         SET set_value = "disabled"
       WHERE set_name = "links_extrapath"
         AND set_value = 0' );
		$DB->query( '
      UPDATE T_settings
         SET set_value = "ymd"
       WHERE set_name = "links_extrapath"
         AND set_value <> 0' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9406' );
	}


	if( $old_db_version < 9407 )
	{
		echo 'Moving general settings to blog settings... ';
		$DB->query( 'REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
		             SELECT blog_ID, set_name, set_value
									 FROM T_blogs, T_settings
									WHERE set_name = "posts_per_page"
									   OR set_name = "what_to_show"
									   OR set_name = "archive_mode"' );
		$DB->query( 'DELETE FROM T_settings
									WHERE set_name = "posts_per_page"
									   OR set_name = "what_to_show"
									   OR set_name = "archive_mode"' );
		echo "OK.<br />\n";

		echo 'Upgrading blogs table... ';
		$query = "ALTER TABLE T_blogs
							DROP COLUMN blog_force_skin";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading groups table... ';
		$query = "ALTER TABLE T_groups
							CHANGE COLUMN grp_perm_files grp_perm_files enum('none','view','add','edit','all') NOT NULL default 'none'";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading files table... ';
		$query = "ALTER TABLE T_files
							CHANGE COLUMN file_root_type file_root_type enum('absolute','user','group','collection','skins') not null default 'absolute'";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Updating file types... ';
		// Only change this if it's close enough to a default install (non customized)
		$DB->query( "UPDATE T_filetypes
										SET ftyp_viewtype = 'text'
									WHERE ftyp_ID = 12
										AND ftyp_extensions = 'php php3 php4 php5 php6'
										AND ftyp_mimetype ='application/x-httpd-php'
										AND ftyp_icon = 'php.gif'" );
		echo "OK.<br />\n";

		echo 'Remove obsolete user settings... ';
		$DB->query( 'DELETE FROM '.$tableprefix.'usersettings
									WHERE uset_name = "plugins_disp_avail"' );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9407' );
	}


	if( $old_db_version < 9408 )
	{
		echo 'Creating skins table... ';
		$DB->query( 'CREATE TABLE T_skins__skin (
              skin_ID      int(10) unsigned      NOT NULL auto_increment,
              skin_name    varchar(32)           NOT NULL,
              skin_type    enum(\'normal\',\'feed\') NOT NULL default \'normal\',
              skin_folder  varchar(32)           NOT NULL,
              PRIMARY KEY skin_ID (skin_ID),
              UNIQUE skin_folder( skin_folder ),
              KEY skin_name( skin_name )
            )' );
		echo "OK.<br />\n";

		echo 'Creating skin containers table... ';
		$DB->query( 'CREATE TABLE T_skins__container (
              sco_skin_ID   int(10) unsigned      NOT NULL,
              sco_name      varchar(40)           NOT NULL,
              PRIMARY KEY (sco_skin_ID, sco_name)
            )' );
		echo "OK.<br />\n";

		echo 'Creating widgets table... ';
		$DB->query( 'CREATE TABLE '.$tableprefix.'widget (
 						wi_ID					INT(10) UNSIGNED auto_increment,
						wi_coll_ID    INT(11) UNSIGNED NOT NULL,
						wi_sco_name   VARCHAR( 40 ) NOT NULL,
						wi_order			INT(10) UNSIGNED NOT NULL,
						wi_type       ENUM( \'core\', \'plugin\' ) NOT NULL DEFAULT \'core\',
						wi_code       VARCHAR(32) NOT NULL,
						wi_params     TEXT NULL,
						PRIMARY KEY ( wi_ID ),
						UNIQUE wi_order( wi_coll_ID, wi_sco_name, wi_order )
          )' );
		echo "OK.<br />\n";

		install_basic_skins( false );

		echo 'Updating blogs table... ';
		$DB->query( 'ALTER TABLE T_blogs
								 ALTER COLUMN blog_allowtrackbacks SET DEFAULT 0,
									DROP COLUMN blog_default_skin,
									 ADD COLUMN blog_owner_user_ID   int(11) unsigned NOT NULL default 1 AFTER blog_name,
									 ADD COLUMN blog_skin_ID INT(10) UNSIGNED NOT NULL DEFAULT 1 AFTER blog_allowusercss' );
		echo "OK.<br />\n";


		/**
		* Install basic widgets.
		*/
		function install_basic_widgets_9408()
		{
			/**
			* @var DB
			*/
			global $DB;

			$blog_ids = $DB->get_assoc( 'SELECT blog_ID, "std" FROM T_blogs' );

			foreach( $blog_ids as $blog_id => $blog_type )
			{
				task_begin( 'Installing default widgets for blog #'.$blog_id.'... ' );
				insert_basic_widgets_9408( $blog_id, true, $blog_type );
				task_end();
			}
		}
		/**
		 * Add a widget to global array in order to insert it in DB by single SQL query later
		 *
		 * @param integer Blog ID
		 * @param string Container name
		 * @param string Type
		 * @param string Code
		 * @param integer Order
		 * @param array|string|NULL Widget params
		 */
		function add_basic_widget_9408( $blog_ID, $container_name, $code, $type, $order, $params = NULL )
		{
			global $basic_widgets_insert_sql_rows, $DB;

			if( is_null( $params ) )
			{ // NULL
				$params = 'NULL';
			}
			elseif( is_array( $params ) )
			{ // array
				$params = $DB->quote( serialize( $params ) );
			}
			else
			{ // string
				$params = $DB->quote( $params );
			}

			$basic_widgets_insert_sql_rows[] = '( '
				.$blog_ID.', '
				.$DB->quote( $container_name ).', '
				.$order.', '
				.$DB->quote( $type ).', '
				.$DB->quote( $code ).', '
				.$params.' )';
		}
		/**
		 * Insert the widgets for the blog
		 *
		 * @param integer should never be 0
		 * @param boolean should be true only when it's called after initial install
		 * @param string Kind of blog ( 'std', 'photo', 'group', 'forum' )
		 */
		function insert_basic_widgets_9408( $blog_id, $initial_install = false, $kind = '' )
		{
			global $DB, $install_test_features, $basic_widgets_insert_sql_rows;

			// Initialize this array first time and clear after previous call of this function
			$basic_widgets_insert_sql_rows = array();

			// Handle all blog IDs which can go from function create_demo_contents()
			global $blog_home_ID, $blog_a_ID, $blog_b_ID, $blog_photoblog_ID, $blog_forums_ID, $blog_manual_ID, $events_blog_ID;
			$blog_home_ID = intval( $blog_home_ID );
			$blog_a_ID = intval( $blog_a_ID );
			$blog_b_ID = intval( $blog_b_ID );
			$blog_photoblog_ID = intval( $blog_photoblog_ID );
			$blog_forums_ID = intval( $blog_forums_ID );
			$blog_manual_ID = intval( $blog_manual_ID );
			$events_blog_ID = intval( $events_blog_ID );

			$default_blog_param = 's:7:"blog_ID";s:0:"";';
			if( $initial_install && ! empty( $blog_photoblog_ID ) )
			{ // In the case of initial install, we grab photos out of the photoblog (Blog #4)
				$default_blog_param = 's:7:"blog_ID";s:1:"'.intval( $blog_photoblog_ID ).'";';
			}


			/* Header */
			add_basic_widget_9408( $blog_id, 'Header', 'coll_title', 'core', 1 );
			add_basic_widget_9408( $blog_id, 'Header', 'coll_tagline', 'core', 2 );


			/* Menu */
			if( $kind != 'main' )
			{ // Don't add widgets to Menu container for Main collections
				// Home page
				add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 5, array( 'link_type' => 'home' ) );
				if( $blog_id == $blog_b_ID )
				{ // Recent Posts
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 10, array( 'link_type' => 'recentposts', 'link_text' => T_('News') ) );
				}
				if( $kind == 'forum' )
				{ // Latest Topics and Replies ONLY for forum
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 13, array( 'link_type' => 'recentposts', 'link_text' => T_('Latest topics') ) );
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 15, array( 'link_type' => 'latestcomments', 'link_text' => T_('Latest replies') ) );
				}
				if( $kind == 'manual' )
				{ // Latest Topics and Replies ONLY for forum
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 13, array( 'link_type' => 'recentposts', 'link_text' => T_('Latest pages') ) );
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 15, array( 'link_type' => 'latestcomments', 'link_text' => T_('Latest comments') ) );
				}
				if( $kind == 'photo' )
				{ // Add menu with Photo index
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 18, array( 'link_type' => 'mediaidx', 'link_text' => T_('Index') ) );
				}
				if( $kind == 'forum' )
				{ // Add menu with User Directory
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 20, array( 'link_type' => 'users' ) );
				}
				// Pages list:
				add_basic_widget_9408( $blog_id, 'Menu', 'coll_page_list', 'core', 25 );
				if( $kind == 'forum' )
				{ // My Profile
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 30, array( 'link_type' => 'myprofile' ) );
				}
				if( $kind == 'std' )
				{ // Categories
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 33, array( 'link_type' => 'catdir' ) );
					// Archives
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 35, array( 'link_type' => 'arcdir' ) );
					// Latest comments
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 37, array( 'link_type' => 'latestcomments' ) );
				}
				add_basic_widget_9408( $blog_id, 'Menu', 'msg_menu_link', 'core', 50, array( 'link_type' => 'messages' ) );
				add_basic_widget_9408( $blog_id, 'Menu', 'msg_menu_link', 'core', 60, array( 'link_type' => 'contacts', 'show_badge' => 0 ) );
				add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 70, array( 'link_type' => 'login' ) );
				if( $kind == 'forum' )
				{ // Register
					add_basic_widget_9408( $blog_id, 'Menu', 'menu_link', 'core', 80, array( 'link_type' => 'register' ) );
				}
			}


			/* Item Single */
			add_basic_widget_9408( $blog_id, 'Item Single', 'item_content', 'core', 10 );
			if( $blog_id != $blog_a_ID && $kind != 'forum' && ( empty( $events_blog_ID ) || $blog_id != $events_blog_ID ) )
			{ // Item Tags
				add_basic_widget_9408( $blog_id, 'Item Single', 'item_tags', 'core', 20 );
			}
			if( $blog_id == $blog_b_ID )
			{ // About Author
				add_basic_widget_9408( $blog_id, 'Item Single', 'item_about_author', 'core', 25 );
			}
			if( ( $blog_id == $blog_a_ID || ( ! empty( $events_blog_ID ) && $blog_id == $events_blog_ID ) ) && ! empty( $install_test_features ) )
			{ // Google Maps
				add_basic_widget_9408( $blog_id, 'Item Single', 'evo_Gmaps', 'plugin', 30 );
			}
			if( $blog_id == $blog_a_ID || $kind == 'manual' )
			{ // Small Print
				add_basic_widget_9408( $blog_id, 'Item Single', 'item_small_print', 'core', 40, array( 'format' => ( $blog_id == $blog_a_ID ? 'standard' : 'revision' ) ) );
			}


			/* Page Top */
			add_basic_widget_9408( $blog_id, 'Page Top', 'user_links', 'core', 10 );


			/* Sidebar */
			if( $kind == 'manual' )
			{
				$search_form_params = array( 'title' => T_('Search this manual:') );
				add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_search_form', 'core', 10, $search_form_params );
				add_basic_widget_9408( $blog_id, 'Sidebar', 'content_hierarchy', 'core', 20 );
			}
			else
			{
				if( ! empty( $install_test_features ) )
				{
					if( $kind != 'forum' && $kind != 'manual' )
					{ // Current filters widget
						add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_current_filters', 'core', 5 );
					}
					// User login widget
					add_basic_widget_9408( $blog_id, 'Sidebar', 'user_login', 'core', 10 );
				}
				if( ( !$initial_install || $blog_id != $blog_forums_ID ) && $kind != 'forum' )
				{ // Don't install these Sidebar widgets for blog 'Forums'
					add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_avatar', 'core', 20 );
					if( $blog_id > $blog_a_ID )
					{
						add_basic_widget_9408( $blog_id, 'Sidebar', 'evo_Calr', 'plugin', 30 );
					}
					add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_longdesc', 'core', 40, array( 'title' => '$title$' ) );
					add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_search_form', 'core', 50 );
					add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_category_list', 'core', 60 );

					if( $blog_id == $blog_home_ID )
					{ // Advertisements, Install only for blog #1 home blog
						add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_item_list', 'core', 70, array(
								'title' => 'Advertisement (Demo)',
								'item_type' => 4000,
								'blog_ID' => $blog_id,
								'order_by' => 'RAND',
								'limit' => 1,
								'disp_title' => false,
								'item_title_link_type' => 'linkto_url',
								'attached_pics' => 'first',
								'item_pic_link_type' => 'linkto_url',
								'thumb_size' => 'fit-160x160',
							) );
					}

					if( $blog_id != $blog_b_ID )
					{
						add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_media_index', 'core', 80, 'a:11:{s:5:"title";s:12:"Random photo";s:10:"thumb_size";s:11:"fit-160x120";s:12:"thumb_layout";s:4:"grid";s:12:"grid_nb_cols";s:1:"1";s:5:"limit";s:1:"1";s:8:"order_by";s:4:"RAND";s:9:"order_dir";s:3:"ASC";'.$default_blog_param.'s:11:"widget_name";s:12:"Random photo";s:16:"widget_css_class";s:0:"";s:9:"widget_ID";s:0:"";}' );
					}
					if( ! empty( $blog_home_ID ) && ( $blog_id == $blog_a_ID || $blog_id == $blog_b_ID ) )
					{
						add_basic_widget_9408( $blog_id, 'Sidebar', 'linkblog', 'core', 90, array( 'blog_ID' => $blog_home_ID, 'item_type' => '3000' ) );
					}
				}
				add_basic_widget_9408( $blog_id, 'Sidebar', 'coll_xml_feeds', 'core', 100 );
				add_basic_widget_9408( $blog_id, 'Sidebar', 'mobile_skin_switcher', 'core', 110 );
			}


			/* Sidebar 2 */
			add_basic_widget_9408( $blog_id, 'Sidebar 2', 'coll_post_list', 'core', 1 );
			if( $blog_id == $blog_b_ID )
			{
				add_basic_widget_9408( $blog_id, 'Sidebar 2', 'coll_link_list', 'core', 5, array( 'title' => 'Sidebar links', 'order_by' => 'RAND' ) );
			}
			add_basic_widget_9408( $blog_id, 'Sidebar 2', 'coll_comment_list', 'core', 10 );
			add_basic_widget_9408( $blog_id, 'Sidebar 2', 'coll_media_index', 'core', 15, 'a:11:{s:5:"title";s:13:"Recent photos";s:10:"thumb_size";s:10:"crop-80x80";s:12:"thumb_layout";s:4:"flow";s:12:"grid_nb_cols";s:1:"3";s:5:"limit";s:1:"9";s:8:"order_by";s:9:"datestart";s:9:"order_dir";s:4:"DESC";'.$default_blog_param.'s:11:"widget_name";s:11:"Photo index";s:16:"widget_css_class";s:0:"";s:9:"widget_ID";s:0:"";}' );
			add_basic_widget_9408( $blog_id, 'Sidebar 2', 'free_html', 'core', 20, 'a:5:{s:5:"title";s:9:"Sidebar 2";s:7:"content";s:162:"This is the "Sidebar 2" container. You can place any widget you like in here. In the evo toolbar at the top of this page, select "Customize", then "Blog Widgets".";s:11:"widget_name";s:9:"Free HTML";s:16:"widget_css_class";s:0:"";s:9:"widget_ID";s:0:"";}' );


			/* Front Page Main Area */
			if( $kind == 'main' )
			{ // Display blog title and tagline for main blogs
				add_basic_widget_9408( $blog_id, 'Front Page Main Area', 'coll_title', 'core', 1 );
				add_basic_widget_9408( $blog_id, 'Front Page Main Area', 'coll_tagline', 'core', 2 );
			}
			$featured_intro_params = NULL;
			if( $kind == 'main' )
			{ // Hide a title of the front intro post
				$featured_intro_params = array( 'disp_title' => 0 );
			}
			add_basic_widget_9408( $blog_id, 'Front Page Main Area', 'coll_featured_intro', 'core', 10, $featured_intro_params );
			if( $kind == 'main' )
			{ // Add user links widget only for main kind blogs
				add_basic_widget_9408( $blog_id, 'Front Page Main Area', 'user_links', 'core', 15 );
			}
			$post_list_params = NULL;
			if( $kind == 'main' )
			{ // Display the posts from all other blogs if it is allowed by blogs setting "Collections to aggregate"
				$post_list_params = array(
						'blog_ID'          => '',
						'limit'            => 50,
						'attached_pics'    => 'first',
						'disp_first_image' => 'special',
					);
			}
			add_basic_widget_9408( $blog_id, 'Front Page Main Area', 'coll_post_list', 'core', 20, $post_list_params );
			if( $kind != 'main' )
			{ // Don't install the "Recent Commnets" widget for Main blogs
				add_basic_widget_9408( $blog_id, 'Front Page Main Area', 'coll_comment_list', 'core', 30 );
			}


			/* Front Page Secondary Area */
			add_basic_widget_9408( $blog_id, 'Front Page Secondary Area', 'org_members', 'core', 10 );


			/* Mobile Footer */
			add_basic_widget_9408( $blog_id, 'Mobile: Footer', 'coll_longdesc', 'core', 10 );
			add_basic_widget_9408( $blog_id, 'Mobile: Footer', 'mobile_skin_switcher', 'core', 20 );


			/* Mobile Navigation Menu */
			add_basic_widget_9408( $blog_id, 'Mobile: Navigation Menu', 'coll_page_list', 'core', 10 );
			add_basic_widget_9408( $blog_id, 'Mobile: Navigation Menu', 'menu_link', 'core', 20, array( 'link_type' => 'ownercontact' ) );
			add_basic_widget_9408( $blog_id, 'Mobile: Navigation Menu', 'menu_link', 'core', 30, array( 'link_type' => 'home' ) );
			if( $kind == 'forum' )
			{ // Add menu with User Directory
				add_basic_widget_9408( $blog_id, 'Mobile: Navigation Menu', 'menu_link', 'core', 40, array( 'link_type' => 'users' ) );
			}


			/* Mobile Tools Menu */
			add_basic_widget_9408( $blog_id, 'Mobile: Tools Menu', 'menu_link', 'core', 10, array( 'link_type' => 'login' ) );
			add_basic_widget_9408( $blog_id, 'Mobile: Tools Menu', 'msg_menu_link', 'core', 20, array( 'link_type' => 'messages' ) );
			add_basic_widget_9408( $blog_id, 'Mobile: Tools Menu', 'msg_menu_link', 'core', 30, array( 'link_type' => 'contacts', 'show_badge' => 0 ) );
			add_basic_widget_9408( $blog_id, 'Mobile: Tools Menu', 'menu_link', 'core', 50, array( 'link_type' => 'logout' ) );


			// Check if there are widgets to create
			if( ! empty( $basic_widgets_insert_sql_rows ) )
			{ // Insert the widget records by single SQL query
				$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_type, wi_code, wi_params ) '
									 .'VALUES '.implode( ', ', $basic_widgets_insert_sql_rows ) );
			}
		}


		// Install basic widgets:
		install_basic_widgets_9408();

		set_upgrade_checkpoint( '9408' );
	}


	if( $old_db_version < 9409 )
	{
		// Upgrade the blog access types:
		echo 'Updating blogs access types... ';
		$DB->query( 'UPDATE T_blogs
										SET blog_access_type = "absolute"
									WHERE blog_siteurl LIKE "http://%"
									   OR blog_siteurl LIKE "https://%"' );

		$DB->query( 'UPDATE T_blogs
										SET blog_access_type = "relative",
												blog_siteurl = CONCAT( blog_siteurl, blog_stub )
									WHERE blog_access_type = "stub"' );

		db_drop_col( 'T_blogs', 'blog_stub' );

		echo "OK.<br />\n";


 		echo 'Updating columns... ';
		$DB->query( "ALTER TABLE T_groups CHANGE COLUMN grp_perm_stats grp_perm_stats enum('none','user','view','edit') NOT NULL default 'none'" );

		$DB->query( "ALTER TABLE T_coll_user_perms CHANGE COLUMN bloguser_perm_poststatuses bloguser_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default ''" );

		$DB->query( "ALTER TABLE T_coll_group_perms CHANGE COLUMN bloggroup_perm_poststatuses bloggroup_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default ''" );

		$DB->query( "ALTER TABLE {$tableprefix}posts CHANGE COLUMN post_status post_status enum('published','deprecated','protected','private','draft','redirected') NOT NULL default 'published'" );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9409' );
	}


	if( $old_db_version < 9410 )
	{
 		echo 'Updating columns... ';
		$DB->query( "ALTER TABLE T_comments CHANGE COLUMN comment_status comment_status ENUM('published','deprecated','protected','private','draft','redirected') DEFAULT 'published' NOT NULL" );

		$DB->query( "ALTER TABLE T_sessions CHANGE COLUMN sess_data sess_data MEDIUMBLOB DEFAULT NULL" );

		$DB->query( "ALTER TABLE T_hitlog CHANGE COLUMN hit_referer_type hit_referer_type ENUM('search','blacklist','spam','referer','direct','self','admin') NOT NULL" );

		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9410' );
	}


	if( $old_db_version < 9411 )
	{
		echo 'Adding default Post Types... ';
		$DB->query( "
			REPLACE INTO {$tableprefix}posttypes ( ptyp_ID, ptyp_name )
			VALUES ( 1000, 'Page' ),
						 ( 2000, 'Reserved' ),
						 ( 3000, 'Reserved' ),
						 ( 4000, 'Reserved' ),
						 ( 5000, 'Reserved' ) " );
		echo "OK.<br />\n";
		set_upgrade_checkpoint( '9411' );
	}


	if( $old_db_version < 9412 )
	{
		echo 'Adding field for post excerpts... ';
		$DB->query( "ALTER TABLE {$tableprefix}posts ADD COLUMN post_excerpt  text NULL AFTER post_content" );
		echo "OK.<br />\n";
		set_upgrade_checkpoint( '9412' );
	}

	if( $old_db_version < 9414 )
	{
		echo "Renaming tables...";
		$DB->query( "RENAME TABLE {$tableprefix}item__prerendering TO T_items__prerendering" );
		$DB->query( "RENAME TABLE {$tableprefix}poststatuses TO T_items__status" );
		$DB->query( "RENAME TABLE {$tableprefix}posttypes TO T_items__type" );
		$DB->query( "RENAME TABLE {$tableprefix}posts TO T_items__item" );
		echo "OK.<br />\n";

		echo "Creating Tag tables...";
		$DB->query( "CREATE TABLE T_items__tag (
		      tag_ID   int(11) unsigned not null AUTO_INCREMENT,
		      tag_name varchar(50) not null,
		      primary key (tag_ID),
		      UNIQUE tag_name( tag_name )
		    )" );

		$DB->query( "CREATE TABLE T_items__itemtag (
		      itag_itm_ID int(11) unsigned NOT NULL,
		      itag_tag_ID int(11) unsigned NOT NULL,
		      PRIMARY KEY (itag_itm_ID, itag_tag_ID),
		      UNIQUE tagitem ( itag_tag_ID, itag_itm_ID )
		    )" );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9414' );
	}


	if( $old_db_version < 9416 )
	{
		echo "Updating blogs table...";
		$DB->query( "ALTER TABLE T_blogs
									ADD COLUMN blog_advanced_perms  TINYINT(1) NOT NULL default 0 AFTER blog_owner_user_ID,
									DROP COLUMN blog_staticfilename" );
		$DB->query( "UPDATE T_blogs
									  SET blog_advanced_perms = 1" );
		echo "OK.<br />\n";

		echo "Additionnal blog permissions...";
		$DB->query( "ALTER TABLE T_coll_user_perms
									ADD COLUMN bloguser_perm_admin tinyint NOT NULL default 0 AFTER bloguser_perm_properties,
									ADD COLUMN bloguser_perm_edit  ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no' AFTER bloguser_perm_poststatuses" );

		$DB->query( "ALTER TABLE T_coll_group_perms
									ADD COLUMN bloggroup_perm_admin tinyint NOT NULL default 0 AFTER bloggroup_perm_properties,
									ADD COLUMN bloggroup_perm_edit  ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no' AFTER bloggroup_perm_poststatuses" );

		// Preserve full admin perms:
		$DB->query( "UPDATE T_coll_user_perms
										SET bloguser_perm_admin = 1
									WHERE bloguser_perm_properties <> 0" );
		$DB->query( "UPDATE T_coll_group_perms
										SET bloggroup_perm_admin = 1
									WHERE bloggroup_perm_properties <> 0" );

		// Preserve full edit perms:
		$DB->query( "UPDATE T_coll_user_perms
										SET bloguser_perm_edit = 'all'" );
		$DB->query( "UPDATE T_coll_group_perms
										SET bloggroup_perm_edit = 'all'" );

		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9416' );
	}


	if( $old_db_version < 9500 )
	{
		task_begin( 'Normalizing columns...' );
		$DB->query( 'ALTER TABLE T_blogs
										ALTER COLUMN blog_shortname SET DEFAULT \'\',
										ALTER COLUMN blog_tagline SET DEFAULT \'\',
										CHANGE COLUMN blog_description blog_description     varchar(250) NULL default \'\',
										ALTER COLUMN blog_siteurl SET DEFAULT \'\'' );
		task_end();

		task_begin( 'Normalizing dates...' );
		$DB->query( 'UPDATE T_users
										SET dateYMDhour = \'2000-01-01 00:00:00\'
									WHERE dateYMDhour = \'0000-00-00 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_users
									MODIFY COLUMN dateYMDhour DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'UPDATE T_comments
										SET comment_date = \'2000-01-01 00:00:00\'
									WHERE comment_date = \'0000-00-00 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_comments
									MODIFY COLUMN comment_date DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		task_end();

		task_begin( 'Normalizing cron jobs...' );
		$DB->query( 'UPDATE T_cron__task
										SET ctsk_controller = REPLACE(ctsk_controller, "cron/_", "cron/jobs/_" )
									WHERE ctsk_controller LIKE "cron/_%"' );
		task_end();

		task_begin( 'Extending comments table...' );
		$DB->query( 'ALTER TABLE T_comments
									ADD COLUMN comment_rating     TINYINT(1) NULL DEFAULT NULL AFTER comment_content,
									ADD COLUMN comment_featured   TINYINT(1) NOT NULL DEFAULT 0 AFTER comment_rating,
									ADD COLUMN comment_nofollow   TINYINT(1) NOT NULL DEFAULT 1 AFTER comment_featured;');
		task_end();

		set_upgrade_checkpoint( '9500' );
	}


	if( $old_db_version < 9600 )
	{	// 2.2.0
		task_begin( 'Creating global cache table...' );
		$DB->query( 'CREATE TABLE T_global__cache (
							      cach_name VARCHAR( 30 ) NOT NULL ,
							      cach_cache MEDIUMBLOB NULL ,
							      PRIMARY KEY ( cach_name )
							    )' );
		task_end();

		task_begin( 'Altering posts table...' );
		$DB->query( 'ALTER TABLE T_items__item
										MODIFY COLUMN post_datestart DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
										MODIFY COLUMN post_datemodified DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\',
										ADD COLUMN post_order    float NULL AFTER post_priority,
										ADD COLUMN post_featured tinyint(1) NOT NULL DEFAULT 0 AFTER post_order');
		$DB->query( 'ALTER TABLE T_items__item
										ADD INDEX post_order( post_order )' );
		task_end();

		set_upgrade_checkpoint( '9600' );
	}


	if( $old_db_version < 9700 )
	{	// 2.3.2
	  echo 'Creating PodCast Post Type... ';
		$DB->query( "
			REPLACE INTO T_items__type ( ptyp_ID, ptyp_name )
			VALUES ( 2000, 'Podcast' )" );
		echo "OK.<br />\n";

		// 2.4.0
	  echo 'Adding additional group permissions... ';
		$DB->query( "
	      ALTER TABLE T_groups
					ADD COLUMN grp_perm_bypass_antispam         TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_blogs,
					ADD COLUMN grp_perm_xhtmlvalidation         VARCHAR(10) NOT NULL default 'always' AFTER grp_perm_bypass_antispam,
					ADD COLUMN grp_perm_xhtmlvalidation_xmlrpc  VARCHAR(10) NOT NULL default 'always' AFTER grp_perm_xhtmlvalidation,
					ADD COLUMN grp_perm_xhtml_css_tweaks        TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtmlvalidation_xmlrpc,
      		ADD COLUMN grp_perm_xhtml_iframes           TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtml_css_tweaks,
      		ADD COLUMN grp_perm_xhtml_javascript        TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtml_iframes,
					ADD COLUMN grp_perm_xhtml_objects           TINYINT(1)  NOT NULL DEFAULT 0        AFTER grp_perm_xhtml_javascript " );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9700' );
	}


	if( $old_db_version < 9800 )
	{	// 2.5.0
		echo 'Upgrading blogs table... ';
		db_drop_col( 'T_blogs', 'blog_commentsexpire' );
		echo "OK.<br />\n";

		echo 'Upgrading items table... ';
		$DB->query( "ALTER TABLE T_items__item
			CHANGE COLUMN post_urltitle post_urltitle VARCHAR(210) NULL DEFAULT NULL,
			CHANGE COLUMN post_order    post_order DOUBLE NULL,
			ADD COLUMN post_titletag  VARCHAR(255) NULL DEFAULT NULL AFTER post_urltitle,
			ADD COLUMN post_double1   DOUBLE NULL COMMENT 'Custom double value 1' AFTER post_priority,
			ADD COLUMN post_double2   DOUBLE NULL COMMENT 'Custom double value 2' AFTER post_double1,
			ADD COLUMN post_double3   DOUBLE NULL COMMENT 'Custom double value 3' AFTER post_double2,
			ADD COLUMN post_double4   DOUBLE NULL COMMENT 'Custom double value 4' AFTER post_double3,
			ADD COLUMN post_double5   DOUBLE NULL COMMENT 'Custom double value 5' AFTER post_double4,
			ADD COLUMN post_varchar1  VARCHAR(255) NULL COMMENT 'Custom varchar value 1' AFTER post_double5,
			ADD COLUMN post_varchar2  VARCHAR(255) NULL COMMENT 'Custom varchar value 2' AFTER post_varchar1,
			ADD COLUMN post_varchar3  VARCHAR(255) NULL COMMENT 'Custom varchar value 3' AFTER post_varchar2" );
		echo "OK.<br />\n";

		echo 'Creating keyphrase table... ';
		$query = "CREATE TABLE T_track__keyphrase (
            keyp_ID      INT UNSIGNED NOT NULL AUTO_INCREMENT,
            keyp_phrase  VARCHAR( 255 ) NOT NULL,
            PRIMARY KEY        ( keyp_ID ),
            UNIQUE keyp_phrase ( keyp_phrase )
          )";
		$DB->query( $query );
		echo "OK.<br />\n";

		echo 'Upgrading hitlog table... ';
		evo_flush();
		$query = "ALTER TABLE T_hitlog
			 CHANGE COLUMN hit_ID hit_ID              INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			 CHANGE COLUMN hit_datetime hit_datetime  DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
			 ADD COLUMN hit_keyphrase_keyp_ID         INT UNSIGNED DEFAULT NULL AFTER hit_referer_dom_ID";
		$DB->query( $query );
		// Use this query separately from above because MariaDB versions 10+ create an error:
		$DB->query( 'ALTER TABLE T_hitlog
			 ADD INDEX hit_remote_addr ( hit_remote_addr ),
			 ADD INDEX hit_sess_ID     ( hit_sess_ID )' );
		echo "OK.<br />\n";

		echo 'Upgrading sessions table... ';
		$DB->query( "ALTER TABLE T_sessions
			ALTER COLUMN sess_lastseen SET DEFAULT '2000-01-01 00:00:00',
			ADD COLUMN sess_hitcount  INT(10) UNSIGNED NOT NULL DEFAULT 1 AFTER sess_key" );
		// Use this query separately from above because MariaDB versions 10+ create an error:
		$DB->query(	'ALTER TABLE T_sessions
			ADD KEY sess_user_ID (sess_user_ID)' );
		echo "OK.<br />\n";

		echo 'Creating goal tracking table... ';
    $DB->query( "CREATE TABLE T_track__goal(
					  goal_ID int(10) unsigned NOT NULL auto_increment,
					  goal_name varchar(50) default NULL,
					  goal_key varchar(32) default NULL,
					  goal_redir_url varchar(255) default NULL,
					  goal_default_value double default NULL,
					  PRIMARY KEY (goal_ID),
					  UNIQUE KEY goal_key (goal_key)
          )" );

    $DB->query( "CREATE TABLE T_track__goalhit (
					  ghit_ID int(10) unsigned NOT NULL auto_increment,
					  ghit_goal_ID    int(10) unsigned NOT NULL,
					  ghit_hit_ID     int(10) unsigned NOT NULL,
					  ghit_params     TEXT default NULL,
					  PRIMARY KEY  (ghit_ID),
					  KEY ghit_goal_ID (ghit_goal_ID),
					  KEY ghit_hit_ID (ghit_hit_ID)
         )" );
		echo "OK.<br />\n";

		set_upgrade_checkpoint( '9800' );
	}


	if( $old_db_version < 9900 )
	{	// 3.0 part 1
		task_begin( 'Updating keyphrases in hitlog table... ' );
		load_class( 'sessions/model/_hit.class.php', 'Hit' );
		// New Hit object creation was added later, to fix upgrades from very old versions.
		// We create a new temp Hit object to be able to call the Hit::extract_params_from_referer() function which was static when this upgrade block was created.
		$tempHit = new Hit();
		$sql = 'SELECT SQL_NO_CACHE hit_ID, hit_referer
  		          FROM T_hitlog
   		         WHERE hit_referer_type = "search"
		           AND hit_keyphrase_keyp_ID IS NULL'; // this line just in case we crashed in the middle, so we restart where we stopped
		$rows = $DB->get_results( $sql, OBJECT, 'get all search hits' );
		foreach( $rows as $row )
		{
			$params = $tempHit->extract_params_from_referer( $row->hit_referer );
			if( empty( $params['keyphrase'] ) )
			{
				continue;
			}

			$DB->begin();

			$sql = 'SELECT keyp_ID
			          FROM T_track__keyphrase
			         WHERE keyp_phrase = '.$DB->quote($params['keyphrase']);
			$keyp_ID = $DB->get_var( $sql, 0, 0, 'Get keyphrase ID' );

			if( empty( $keyp_ID ) )
			{
				$sql = 'INSERT INTO T_track__keyphrase( keyp_phrase )
				        VALUES ('.$DB->quote($params['keyphrase']).')';
				$DB->query( $sql, 'Add new keyphrase' );
				$keyp_ID = $DB->insert_id;
			}

			$DB->query( 'UPDATE T_hitlog
			                SET hit_keyphrase_keyp_ID = '.$keyp_ID.'
			              WHERE hit_ID = '.$row->hit_ID, 'Update hit' );

			$DB->commit();
			echo ". \n";
		}
		task_end();

		task_begin( 'Upgrading widgets table... ' );
		$DB->query( "ALTER TABLE '.$tableprefix.'widget
			CHANGE COLUMN wi_order wi_order INT(10) NOT NULL" );
		task_end();

		task_begin( 'Upgrading Files table... ' );
		$DB->query( "ALTER TABLE T_files
								CHANGE COLUMN file_root_type file_root_type enum('absolute','user','collection','shared','skins') not null default 'absolute'" );
		task_end();

		set_upgrade_checkpoint( '9900' );
	}

	if( $old_db_version < 9910 )
	{	// 3.0 part 2

		task_begin( 'Upgrading Blogs table... ' );
		$DB->query( "ALTER TABLE T_blogs CHANGE COLUMN blog_name blog_name varchar(255) NOT NULL default ''" );
		task_end();

		task_begin( 'Adding new Post Types...' );
		$DB->query( "
			REPLACE INTO T_items__type( ptyp_ID, ptyp_name )
			VALUES ( 1500, 'Intro-Main' ),
						 ( 1520, 'Intro-Cat' ),
						 ( 1530, 'Intro-Tag' ),
						 ( 1570, 'Intro-Sub' ),
						 ( 1600, 'Intro-All' ) " );
		task_end();

		task_begin( 'Updating User table' );
		$DB->query( "ALTER TABLE T_users
									ADD COLUMN user_avatar_file_ID int(10) unsigned default NULL AFTER user_validated" );
		task_end();

		task_begin( 'Creating table for User field definitions' );
		$DB->query( "CREATE TABLE T_users__fielddefs (
				ufdf_ID int(10) unsigned NOT NULL,
				ufdf_type char(8) NOT NULL,
				ufdf_name varchar(255) collate latin1_general_ci NOT NULL,
				PRIMARY KEY  (ufdf_ID)
			)" );
		task_end();

		task_begin( 'Creating default field definitions...' );
		$DB->query( "
	    INSERT INTO T_users__fielddefs (ufdf_ID, ufdf_type, ufdf_name)
			 VALUES ( 10000, 'email',    'MSN/Live IM'),
							( 10100, 'word',     'Yahoo IM'),
							( 10200, 'word',     'AOL AIM'),
							( 10300, 'number',   'ICQ ID'),
							( 40000, 'phone',    'Skype'),
							( 50000, 'phone',    'Main phone'),
							( 50100, 'phone',    'Cell phone'),
							( 50200, 'phone',    'Office phone'),
							( 50300, 'phone',    'Home phone'),
							( 60000, 'phone',    'Office FAX'),
							( 60100, 'phone',    'Home FAX'),
							(100000, 'url',      'Website'),
							(100100, 'url',      'Blog'),
							(110000, 'url',      'Linkedin'),
							(120000, 'url',      'Twitter'),
							(130100, 'url',      'Facebook'),
							(130200, 'url',      'Myspace'),
							(140000, 'url',      'Flickr'),
							(150000, 'url',      'YouTube'),
							(160000, 'url',      'Digg'),
							(160100, 'url',      'StumbleUpon'),
							(200000, 'text',     'Role'),
							(200100, 'text',     'Company/Org.'),
							(200200, 'text',     'Division'),
							(211000, 'text',     'VAT ID'),
							(300000, 'text',     'Main address'),
							(300300, 'text',     'Home address');" );
		task_end();

		task_begin( 'Creating table for User fields...' );
		$DB->query( "CREATE TABLE {$tableprefix}users_fields (
				uf_ID      int(10) unsigned NOT NULL auto_increment,
			  uf_user_ID int(10) unsigned NOT NULL,
			  uf_ufdf_ID int(10) unsigned NOT NULL,
			  uf_varchar varchar(255) NOT NULL,
			  PRIMARY KEY (uf_ID)
			)" );
		task_end();

		set_upgrade_checkpoint( '9910' );
	}

	if( $old_db_version < 9920 )
	{	// 3.1
		task_begin( 'Upgrading Posts table... ' );
		// This is for old posts that may have a post type of NULL which should never happen. ptyp 1 is for regular posts
		$DB->query( "UPDATE T_items__item
										SET post_ptyp_ID = 1
									WHERE post_ptyp_ID IS NULL" );
		$DB->query( "ALTER TABLE T_items__item
							CHANGE COLUMN post_ptyp_ID post_ptyp_ID int(10) unsigned NOT NULL DEFAULT 1" );
		task_end();

		task_begin( 'Upgrading Categories table... ' );
		$DB->query( "ALTER TABLE T_categories
			CHANGE COLUMN cat_name cat_name varchar(255) NOT NULL,
			CHANGE COLUMN cat_description cat_description varchar(255) NULL DEFAULT NULL" );
		db_add_col( 'T_categories', 'cat_order', 'int(11) NULL DEFAULT NULL AFTER cat_description' );
		db_add_index( 'T_categories', 'cat_order', 'cat_order' );

		$DB->query( "UPDATE T_categories
					SET cat_order = cat_ID" );
		task_end();

		task_begin( 'Upgrading widgets table... ' );
		db_add_col( $tableprefix.'widget', 'wi_enabled', 'tinyint(1) NOT NULL DEFAULT 1 AFTER wi_order' );
		task_end();
	}
	if( $old_db_version < 9930 )
	{	// 3.1 continued
		task_begin( 'Updating Post Types...' );
		$DB->query( "
			REPLACE INTO T_items__type ( ptyp_ID, ptyp_name )
			VALUES ( 3000, 'Sidebar link' )" );
		echo "OK.<br />\n";
		task_end();

		task_begin( 'Updating items table...' );
		$DB->query( "ALTER TABLE T_items__item ENGINE=innodb" );	// fp> hum... this originally was a test :)
		task_end();

		task_begin( 'Creating versions table...' );
		$DB->query( "CREATE TABLE T_items__version (
	            iver_itm_ID        INT UNSIGNED NOT NULL ,
	            iver_edit_user_ID  INT UNSIGNED NOT NULL ,
	            iver_edit_datetime DATETIME NOT NULL ,
	            iver_status        ENUM('published','deprecated','protected','private','draft','redirected') NULL ,
	            iver_title         TEXT NULL ,
	            iver_content       MEDIUMTEXT NULL ,
	            INDEX iver_itm_ID ( iver_itm_ID )
	            ) ENGINE = innodb" );
		task_end();

		task_begin( 'Updating group permissions...' );
		$DB->query( "UPDATE T_groups
										SET grp_perm_xhtml_css_tweaks = 1
									WHERE grp_ID <= 3" );
		task_end();

		set_upgrade_checkpoint( '9930' );
	}

	if( $old_db_version < 9940 )
	{	// 3.2
		task_begin( 'Updating hitlog table...' );
		$DB->query( "ALTER TABLE T_hitlog ADD COLUMN hit_serprank INT UNSIGNED DEFAULT NULL AFTER hit_keyphrase_keyp_ID" );
		task_end();

		task_begin( 'Updating versions table...' );
		$DB->query( "ALTER TABLE T_items__version
								CHANGE COLUMN iver_edit_user_ID iver_edit_user_ID  INT UNSIGNED NULL" );
		task_end();
	}

	if( $old_db_version < 9950 )
	{	// 3.3
		task_begin( 'Altering Blogs table... ' );
		$DB->query( "ALTER TABLE T_blogs CHANGE COLUMN blog_shortname blog_shortname varchar(255) default ''" );
		task_end();

		task_begin( 'Altering default dates... ' );
		$DB->query( "ALTER TABLE T_links
      ALTER COLUMN link_datecreated SET DEFAULT '2000-01-01 00:00:00',
      ALTER COLUMN link_datemodified SET DEFAULT '2000-01-01 00:00:00'" );
		$DB->query( "ALTER TABLE T_cron__task
      ALTER COLUMN ctsk_start_datetime SET DEFAULT '2000-01-01 00:00:00'" );
		$DB->query( "ALTER TABLE T_cron__log
      ALTER COLUMN clog_realstart_datetime SET DEFAULT '2000-01-01 00:00:00'" );
		task_end();

 		task_begin( 'Altering Items table... ' );
		$DB->query( "ALTER TABLE T_items__item
			ADD COLUMN post_metadesc VARCHAR(255) NULL DEFAULT NULL AFTER post_titletag,
			ADD COLUMN post_metakeywords VARCHAR(255) NULL DEFAULT NULL AFTER post_metadesc,
			ADD COLUMN post_editor_code VARCHAR(32) NULL COMMENT 'Plugin code of the editor used to edit this post' AFTER post_varchar3" );
		task_end();

		task_begin( 'Forcing AutoP posts to html editor...' );
		$DB->query( 'UPDATE T_items__item
											SET post_editor_code = "html"
										WHERE post_renderers = "default"
											 OR post_renderers LIKE "%b2WPAutP%"' );
		task_end();

		set_upgrade_checkpoint( '9950' );
	}

	if( $old_db_version < 9960 )
	{	// 3.3

		echo "Renaming tables...";
		$DB->save_error_state();
		$DB->halt_on_error = false;
		$DB->show_errors = false;
		$DB->query( "ALTER TABLE {$tableprefix}users_fields RENAME TO T_users__fields" );
		$DB->restore_error_state();
		echo "OK.<br />\n";

		// fp> The following is more tricky to do with CHARACTER SET. During upgrade, we don't know what the admin actually wants.
		task_begin( 'Making sure all tables use desired storage ENGINE as specified in the b2evo schema...' );
		foreach( $schema_queries as $table_name=>$table_def )
		{
			if( $DB->query( 'SHOW TABLES LIKE \''.$table_name.'\'' )
				&& preg_match( '/\sENGINE\s*=\s*([a-z]+)/is', $table_def[1], $matches ) )
			{	// If the table exists and has an ENGINE definition:
				echo $table_name.':'.$matches[1].'<br />';
				$DB->query( "ALTER TABLE $table_name ENGINE = ".$matches[1] );
			}
		}
		task_end();

		set_upgrade_checkpoint( '9960' );
	}

	if( $old_db_version < 9970 )
	{	// 4.0 part 1

		// For create_default_currencies() and create_default_countries():
		require_once dirname(__FILE__).'/_functions_create.php';

		task_begin( 'Creating table for default currencies... ' );
		$DB->query( 'CREATE TABLE '.$tableprefix.'currency (
				curr_ID int(10) unsigned NOT NULL auto_increment,
				curr_code char(3) NOT NULL,
				curr_shortcut varchar(30) NOT NULL,
				curr_name varchar(40) NOT NULL,
				PRIMARY KEY curr_ID (curr_ID),
				UNIQUE curr_code (curr_code)
			) ENGINE = innodb' );
		task_end();

		create_default_currencies( $tableprefix.'currency' );

		task_begin( 'Creating table for default countries... ' );
		$DB->query( 'CREATE TABLE '.$tableprefix.'country (
				ctry_ID int(10) unsigned NOT NULL auto_increment,
				ctry_code char(2) NOT NULL,
				ctry_name varchar(40) NOT NULL,
				ctry_curr_ID int(10) unsigned,
				PRIMARY KEY ctry_ID (ctry_ID),
				UNIQUE ctry_code (ctry_code)
			) ENGINE = innodb' );
		task_end();

		create_default_countries( $tableprefix.'country', false );

		task_begin( 'Upgrading user permissions table... ' );
		$DB->query( "ALTER TABLE T_coll_user_perms
			ADD COLUMN bloguser_perm_page		tinyint NOT NULL default 0 AFTER bloguser_perm_media_change,
			ADD COLUMN bloguser_perm_intro		tinyint NOT NULL default 0 AFTER bloguser_perm_page,
			ADD COLUMN bloguser_perm_podcast	tinyint NOT NULL default 0 AFTER bloguser_perm_intro,
			ADD COLUMN bloguser_perm_sidebar	tinyint NOT NULL default 0 AFTER bloguser_perm_podcast" );
		task_end();

		task_begin( 'Upgrading group permissions table... ' );
		$DB->query( "ALTER TABLE T_coll_group_perms
			ADD COLUMN bloggroup_perm_page		tinyint NOT NULL default 0 AFTER bloggroup_perm_media_change,
			ADD COLUMN bloggroup_perm_intro		tinyint NOT NULL default 0 AFTER bloggroup_perm_page,
			ADD COLUMN bloggroup_perm_podcast	tinyint NOT NULL default 0 AFTER bloggroup_perm_intro,
			ADD COLUMN bloggroup_perm_sidebar	tinyint NOT NULL default 0 AFTER bloggroup_perm_podcast" );
		task_end();

		task_begin( 'Upgrading users table... ' );
		$DB->query( "ALTER TABLE T_users
			ADD COLUMN user_ctry_ID int(10) unsigned NULL AFTER user_avatar_file_ID" );
		task_end();

		// Creating tables for messaging module

		task_begin( 'Creating table for message threads... ' );
		$DB->query( "CREATE TABLE T_messaging__thread (
			thrd_ID int(10) unsigned NOT NULL auto_increment,
			thrd_title varchar(255) NOT NULL,
			thrd_datemodified datetime NOT NULL,
			PRIMARY KEY thrd_ID (thrd_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Creating table for messagee... ' );
		$DB->query( "CREATE TABLE T_messaging__message (
			msg_ID int(10) unsigned NOT NULL auto_increment,
			msg_author_user_ID int(10) unsigned NOT NULL,
			msg_datetime datetime NOT NULL,
			msg_thread_ID int(10) unsigned NOT NULL,
			msg_text text NULL,
			PRIMARY KEY msg_ID (msg_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Creating table for message thread statuses... ' );
		$DB->query( "CREATE TABLE T_messaging__threadstatus (
			tsta_thread_ID int(10) unsigned NOT NULL,
			tsta_user_ID int(10) unsigned NOT NULL,
			tsta_first_unread_msg_ID int(10) unsigned NULL,
			INDEX(tsta_user_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Creating table for messaging contacts... ' );
		$DB->query( "CREATE TABLE T_messaging__contact (
			mct_from_user_ID int(10) unsigned NOT NULL,
			mct_to_user_ID int(10) unsigned NOT NULL,
			mct_blocked tinyint(1) default 0,
			mct_last_contact_datetime datetime NOT NULL,
			PRIMARY KEY mct_PK (mct_from_user_ID, mct_to_user_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Upgrading skins table... ' );
		$DB->query( "ALTER TABLE T_skins__skin
						MODIFY skin_type enum('normal','feed','sitemap') NOT NULL default 'normal'" );
		task_end();

		task_begin( 'Setting skin type of sitemap skin to "sitemap"... ' );
		$DB->query( "UPDATE T_skins__skin
						SET skin_type = 'sitemap'
						WHERE skin_folder = '_sitemap'" );
		task_end();

		// Creating table for pluggable permissions

		// This table gets created during upgrade to v0.8.9 at checkpoint 8050
		task_begin( 'Creating table for Group Settings... ' );
		$DB->query( "CREATE TABLE IF NOT EXISTS T_groups__groupsettings (
			gset_grp_ID INT(11) UNSIGNED NOT NULL,
			gset_name VARCHAR(30) NOT NULL,
			gset_value VARCHAR(255) NULL,
			PRIMARY KEY (gset_grp_ID, gset_name)
		) ENGINE = innodb" );
		task_end();

		// Rename T_usersettings table to T_users__usersettings
		task_begin( 'Rename T_usersettings table to T_users__usersettings... ' );
		$DB->query( 'ALTER TABLE '.$tableprefix.'usersettings RENAME TO T_users__usersettings' );
		task_end();

		set_upgrade_checkpoint( '9970' );
	}


	if( $old_db_version < 9980 )
	{	// 4.0 part 2

		task_begin( 'Upgrading posts... ' );
		$DB->query( '
			UPDATE T_items__item
			   SET post_datestart = FROM_UNIXTIME( FLOOR(UNIX_TIMESTAMP(post_datestart)/60)*60 )
			 WHERE post_datestart > NOW()' );
		db_add_col( 'T_items__item', 'post_excerpt_autogenerated', 'TINYINT NULL DEFAULT NULL AFTER post_excerpt' );
		db_add_col( 'T_items__item', 'post_dateset', 'tinyint(1) NOT NULL DEFAULT 1 AFTER post_assigned_user_ID' );
		task_end();

		task_begin( 'Upgrading countries... ' );
		db_add_col( $tableprefix.'country', 'ctry_enabled', 'tinyint(1) NOT NULL DEFAULT 1 AFTER ctry_curr_ID' );
		task_end();


		task_begin( 'Upgrading links... ' );

		// Add link_position. Temporary allow NULL, set compatibility default, then do not allow NULL.
		// TODO: dh> actually, using "teaser" for the first link and "aftermore" for the rest would make more sense (and "aftermore" should get displayed with "no-more" posts anyway).
		//           Opinions? Could be heavy to transform this though..
		// fp> no, don't change past posts unexpectedly.
		db_add_col( 'T_links', 'link_position', "varchar(10) NULL AFTER link_title" );
		$DB->query( "UPDATE T_links SET link_position = 'teaser' WHERE link_position IS NULL" );
		db_add_col( 'T_links', 'link_position', "varchar(10) NOT NULL AFTER link_title" ); // change to NOT NULL

		// Add link_order. Temporary allow NULL, use order from ID, then do not allow NULL and add UNIQUE index.
		db_add_col( 'T_links', 'link_order', 'int(11) unsigned NULL AFTER link_position' );
		$DB->query( "UPDATE T_links SET link_order = link_ID WHERE link_order IS NULL" );
		db_add_col( 'T_links', 'link_order', 'int(11) unsigned NOT NULL AFTER link_position' ); // change to NOT NULL
		db_add_index( 'T_links', 'link_itm_ID_order', 'link_itm_ID, link_order', 'UNIQUE' );

		task_end();

		task_begin( 'Upgrading sessions... ' );
		$DB->query( "ALTER TABLE T_sessions CHANGE COLUMN sess_ipaddress sess_ipaddress VARCHAR(39) NOT NULL DEFAULT ''" );
		task_end();

		set_upgrade_checkpoint( '9980' );
	}

	if( $old_db_version < 9990 )
	{	// 4.0 part 3

		task_begin( 'Upgrading hitlog... ' );

		db_add_col( 'T_hitlog', 'hit_agent_type', "ENUM('rss','robot','browser','unknown') DEFAULT 'unknown' NOT NULL AFTER hit_remote_addr" );

		if( db_col_exists('T_hitlog', 'hit_agnt_ID') )
		{
			$DB->query( 'UPDATE T_hitlog, '.$tableprefix.'useragents
			                SET hit_agent_type = agnt_type
			              WHERE hit_agnt_ID = agnt_ID
			                AND agnt_type <> "unknown"' ); // We already have the unknown as default
			db_drop_col( 'T_hitlog', 'hit_agnt_ID' );
		}
		$DB->query( 'DROP TABLE IF EXISTS '.$tableprefix.'useragents' );

		task_end();

		set_upgrade_checkpoint( '9990' );
	}

	if( $old_db_version < 10000 )
	{	// 4.0 part 4
		// Integrate comment_secret
		task_begin( 'Extending Comment table... ' );
		db_add_col( 'T_comments', 'comment_secret', 'varchar(32) NULL default NULL' );
		task_end();

		// Create T_slug table and, Insert all slugs from T_items
		task_begin( 'Create Slugs table... ' );
		$DB->query( 'CREATE TABLE IF NOT EXISTS T_slug (
						slug_ID int(10) unsigned NOT NULL auto_increment,
						slug_title varchar(255) NOT NULL COLLATE ascii_bin,
						slug_type char(6) NOT NULL DEFAULT "item",
						slug_itm_ID int(11) unsigned,
						PRIMARY KEY slug_ID (slug_ID),
						UNIQUE	slug_title (slug_title)
					) ENGINE = innodb' );
		task_end();

		task_begin( 'Making sure all posts have a slug...' );
		// Get posts with empty urltitle:
		$sql = 'SELECT post_ID, post_title
				      FROM T_items__item
				     WHERE post_urltitle IS NULL OR post_urltitle = ""';
		$rows = $DB->get_results( $sql, OBJECT, 'Get posts with empty urltitle' );
		// Create URL titles when non existent:
		foreach( $rows as $row )
		{
			// TODO: dh> pass locale (useful for transliteration).
			$DB->query( 'UPDATE T_items__item
				              SET post_urltitle = "'.urltitle_validate( '', $row->post_title, 0 ).'"
		                WHERE post_ID = '.$row->post_ID, 'Set posts urltitle' );
		}
		task_end();

		task_begin( 'Populating Slugs table... ' );
		$DB->query( 'REPLACE INTO T_slug( slug_title, slug_type, slug_itm_ID)
		              SELECT post_urltitle, "item", post_ID
							      FROM T_items__item' );
		task_end();

		task_begin( 'Add canonical and tiny slug IDs to post table...' );
		// modify post_urltitle column -> Not allow NULL value
		db_add_col( 'T_items__item', 'post_urltitle', 'VARCHAR(210) NOT NULL' );
		db_add_col( 'T_items__item', 'post_canonical_slug_ID', 'int(10) unsigned NULL default NULL after post_urltitle' );
		db_add_col( 'T_items__item', 'post_tiny_slug_ID', 'int(10) unsigned NULL default NULL after post_canonical_slug_ID' );
		task_end();

		task_begin( 'Upgrading posts...' );
		$DB->query( 'UPDATE T_items__item, T_slug
			              SET post_canonical_slug_ID = slug_ID
			            WHERE CONVERT( post_urltitle USING ASCII ) COLLATE ascii_bin = slug_title' );
		task_end();

		task_begin( 'Adding "help" slug...' );
		if( db_key_exists( 'T_slug', 'slug_title', '"help"' ) )
		{
			echo '<strong>Warning: "help" slug already exists!</strong><br /> ';
		}
		else
		{
			$DB->query( 'INSERT INTO T_slug( slug_title, slug_type )
			             VALUES( "help", "help" )', 'Add "help" slug' );
			task_end();
		}

		// fp> Next time we should use pluggable permissions instead.
		task_begin( 'Updgrading groups: Giving Administrators Group edit perms on slugs...' );
		db_add_col( 'T_groups', 'grp_perm_slugs', "enum('none','view','edit') NOT NULL default 'none'" );
		$DB->query( 'UPDATE T_groups
		             SET grp_perm_slugs = "edit"
		             WHERE grp_ID = 1' );
		task_end();

		task_begin( 'Upgrading settings table... ');
		$DB->query( 'UPDATE T_settings
		                SET set_value = 1
		              WHERE set_name = "fm_enable_roots_user"
		                    AND set_value = 0' );
		task_end();

		// New perms for comment moderation depending on status:
		task_begin( 'Upgrading Blog-User permissions...' );
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_draft_cmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_comments' );
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_publ_cmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_comments' );
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_depr_cmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_comments' );

		if( db_col_exists( 'T_coll_user_perms', 'bloguser_perm_comments' ) )
		{ // if user had perm_comments he now gets all 3 new perms also:
			$DB->query( 'UPDATE T_coll_user_perms
						SET bloguser_perm_draft_cmts = bloguser_perm_comments,
							bloguser_perm_publ_cmts = bloguser_perm_comments,
							bloguser_perm_depr_cmts = bloguser_perm_comments');
			db_drop_col( 'T_coll_user_perms', 'bloguser_perm_comments' );
		}
		task_end();

		task_begin( 'Upgrading Blog-Group permissions...' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_draft_cmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_comments' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_publ_cmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_comments' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_depr_cmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_comments' );

		if( db_col_exists( 'T_coll_group_perms', 'bloggroup_perm_comments' ) )
		{ // if group had perm_comments he now gets all 3 new perms also:
			$DB->query( 'UPDATE T_coll_group_perms
						SET bloggroup_perm_draft_cmts = bloggroup_perm_comments,
							bloggroup_perm_publ_cmts = bloggroup_perm_comments,
							bloggroup_perm_depr_cmts = bloggroup_perm_comments');
			db_drop_col( 'T_coll_group_perms', 'bloggroup_perm_comments' );
		}
		task_end();

		task_begin( 'Upgrading messaging permissions...' );
		$DB->query( 'ALTER TABLE T_users ALTER COLUMN user_allow_msgform SET DEFAULT "2"' );
		$DB->query( 'UPDATE T_users
					SET user_allow_msgform = 3
					WHERE user_allow_msgform = 1');
		task_end();

		task_begin( 'Upgrading currency table...' );
		$DB->query( 'ALTER TABLE '.$tableprefix.'currency ADD COLUMN curr_enabled tinyint(1) NOT NULL DEFAULT 1 AFTER curr_name' );
		task_end();

		task_begin( 'Upgrading default blog access type for new blogs...' );
		$DB->query( 'ALTER TABLE T_blogs ALTER COLUMN blog_access_type SET DEFAULT "extrapath"' );
		task_end();

		task_begin( 'Upgrading tags table...' );
		$DB->query( 'ALTER TABLE T_items__tag CHANGE COLUMN tag_name tag_name varbinary(50) not null' );
		task_end();

		// fp> I don't understand why we need to carry this out "again" but I observed the installer barking on
		// this setting missing when upgrading from older 2.x versions. I figured it would be no big deal to do it twice...
		task_begin( 'Makin sure usersettings table is InnoDB...' );
		$DB->query( 'ALTER TABLE T_users__usersettings ENGINE=innodb' );
		task_end();

		set_upgrade_checkpoint( '10000' );
	}

	if( $old_db_version < 10100 )
	{	// 4.1
		task_begin( 'Convert group permissions to pluggable permissions...' );
		// asimo>This delete query needs just in case if this version of b2evo was used, before upgrade process call
		$DB->query( 'DELETE FROM T_groups__groupsettings
						WHERE gset_name = "perm_files" OR gset_name = "perm_options" OR gset_name = "perm_templates"' );
		// Get current permission values from groups table
		$sql = 'SELECT grp_ID, grp_perm_spamblacklist, grp_perm_slugs, grp_perm_files, grp_perm_options, grp_perm_templates
				      FROM T_groups';
		$rows = $DB->get_results( $sql, OBJECT, 'Get groups converted permissions' );
		// Insert values into groupsettings table
		foreach( $rows as $row )
		{	// "IGNORE" is needed if we already created T_groups__groupsettings during upgrade to v0.8.9 at checkpoint 8050
			$DB->query( 'INSERT IGNORE INTO T_groups__groupsettings( gset_grp_ID, gset_name, gset_value )
							VALUES( '.$row->grp_ID.', "perm_spamblacklist", "'.$row->grp_perm_spamblacklist.'" ),
								( '.$row->grp_ID.', "perm_slugs", "'.$row->grp_perm_slugs.'" ),
								( '.$row->grp_ID.', "perm_files", "'.$row->grp_perm_files.'" ),
								( '.$row->grp_ID.', "perm_options", "'.$row->grp_perm_options.'" ),
								( '.$row->grp_ID.', "perm_templates", "'.$row->grp_perm_templates.'" )' );
		}

		// Drop all converted permissin colums from groups table
		db_drop_col( 'T_groups', 'grp_perm_spamblacklist' );
		db_drop_col( 'T_groups', 'grp_perm_slugs' );
		db_drop_col( 'T_groups', 'grp_perm_files' );
		db_drop_col( 'T_groups', 'grp_perm_options' );
		db_drop_col( 'T_groups', 'grp_perm_templates' );
		task_end();

		task_begin( 'Upgrading users table, adding user gender...' );
		db_add_col( 'T_users', 'user_gender', 'char(1) NULL DEFAULT NULL AFTER user_showonline' );
		task_end();

		task_begin( 'Upgrading edit timpestamp blog-user permission...' );
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_edit_ts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_delpost' );
		$DB->query( 'UPDATE T_coll_user_perms, T_users
							SET bloguser_perm_edit_ts = 1
							WHERE bloguser_user_ID = user_ID  AND user_level > 4' );
		task_end();

		task_begin( 'Upgrading edit timpestamp blog-group permission...' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_edit_ts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_delpost' );
		$DB->query( 'UPDATE T_coll_group_perms
							SET bloggroup_perm_edit_ts = 1
							WHERE bloggroup_group_ID = 1' );
		task_end();

		task_begin( 'Upgrading comments table, add trash status...' );
		$DB->query( "ALTER TABLE T_comments MODIFY COLUMN comment_status ENUM('published','deprecated','draft', 'trash') DEFAULT 'published' NOT NULL");
		task_end();

		task_begin( 'Upgrading groups admin access permission...' );
		$sql = 'SELECT grp_ID, grp_perm_admin
					FROM T_groups';
		$rows = $DB->get_results( $sql, OBJECT, 'Get groups admin perms' );
		foreach( $rows as $row )
		{
			switch( $row->grp_perm_admin )
			{
				case 'visible':
					$value = 'normal';
					break;
				case 'hidden':
					$value = 'restricted';
					break;
				default:
					$value = 'none';
			}
			// "IGNORE" is needed if we already created T_groups__groupsettings during upgrade to v0.8.9 at checkpoint 8050
			$DB->query( 'INSERT IGNORE INTO T_groups__groupsettings( gset_grp_ID, gset_name, gset_value )
							VALUES( '.$row->grp_ID.', "perm_admin", "'.$value.'" )' );
		}
		db_drop_col( 'T_groups', 'grp_perm_admin' );
		task_end();

		task_begin( 'Upgrading users table, add users source...' );
		db_add_col( 'T_users', 'user_source', 'varchar(30) NULL' );
		task_end();

		task_begin( 'Upgrading blogs table: more granularity for comment allowing...' );
		$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT blog_ID, "allow_comments", "never"
							FROM T_blogs
							WHERE blog_allowcomments = "never"' );
		db_drop_col( 'T_blogs', 'blog_allowcomments' );
		task_end();

		task_begin( 'Upgrading blogs table: allow_rating fields...' );
		$DB->query( 'UPDATE T_coll_settings
						SET cset_value = "any"
						WHERE cset_value = "always" AND cset_name = "allow_rating"' );
		task_end();

		task_begin( 'Upgrading links table, add link_cmt_ID...' );
		$DB->query( 'ALTER TABLE T_links
						MODIFY COLUMN link_itm_ID int(11) unsigned NULL,
						MODIFY COLUMN link_creator_user_ID int(11) unsigned NULL,
						MODIFY COLUMN link_lastedit_user_ID int(11) unsigned NULL,
						ADD COLUMN link_cmt_ID int(11) unsigned NULL COMMENT "Used for linking files to comments (comment attachments)" AFTER link_itm_ID');
		$DB->query( 'ALTER TABLE T_links
						ADD INDEX link_cmt_ID ( link_cmt_ID )' );
		task_end();

		task_begin( 'Upgrading filetypes table...' );
		// get allowed filetype ids
		$sql = 'SELECT ftyp_ID
					FROM T_filetypes
					WHERE ftyp_allowed != 0';
		$allowed_ids = implode( ',', $DB->get_col( $sql, 0, 'Get allowed filetypes' ) );

		// update table column  -- this column is about who can edit the filetype: any user, registered users or only admins.
		$DB->query( 'ALTER TABLE T_filetypes
						MODIFY COLUMN ftyp_allowed enum("any","registered","admin") NOT NULL default "admin"' );

		// update ftyp_allowed column content
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_allowed = "registered"
						WHERE ftyp_ID IN ('.$allowed_ids.')' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_allowed = "admin"
						WHERE ftyp_ID NOT IN ('.$allowed_ids.')' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_allowed = "any"
						WHERE ftyp_extensions = "gif" OR ftyp_extensions = "png" OR ftyp_extensions LIKE "%jpg%"' );

		// Add m4v file type if not exists
		if( !db_key_exists( 'T_filetypes', 'ftyp_extensions', '"m4v"' ) )
		{
			$DB->query( 'INSERT INTO T_filetypes (ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
				             VALUES ("m4v", "MPEG video file", "video/x-m4v", "", "browser", "registered")', 'Add "m4v" file type' );
		}
		task_end();

		// The AdSense plugin needs to store quite long strings of data...
		task_begin( 'Upgrading collection settings table, change cset_value type...' );
		$DB->query( 'ALTER TABLE T_coll_settings
								 MODIFY COLUMN cset_name VARCHAR(50) NOT NULL,
								 MODIFY COLUMN cset_value VARCHAR(10000) NULL' );
		task_end();

		set_upgrade_checkpoint( '10100' );
	}

	if( $old_db_version < 10200 )
	{	// 4.1b
		task_begin( 'Creating table for a specific blog post subscriptions...' );
		$DB->query( "CREATE TABLE T_items__subscriptions (
						isub_item_ID  int(11) unsigned NOT NULL,
						isub_user_ID  int(11) unsigned NOT NULL,
						isub_comments tinyint(1) NOT NULL default 0 COMMENT 'The user wants to receive notifications for new comments on this post',
						PRIMARY KEY (isub_item_ID, isub_user_ID )
					) ENGINE = innodb" );
		task_end();

		task_begin( 'Upgrading comments table, add subscription fields...' );
		db_add_col( 'T_comments', 'comment_notif_status', 'ENUM("noreq","todo","started","finished") NOT NULL DEFAULT "noreq" COMMENT "Have notifications been sent for this comment? How far are we in the process?" AFTER comment_secret' );
		db_add_col( 'T_comments', 'comment_notif_ctsk_ID', 'INT(10) unsigned NULL DEFAULT NULL COMMENT "When notifications for this comment are sent through a scheduled job, what is the job ID?" AFTER comment_notif_status' );
		task_end();

		task_begin( 'Upgrading users table...' );
		db_add_col( 'T_users', 'user_notify_moderation', 'tinyint(1) NOT NULL default 0 COMMENT "Notify me by email whenever a comment is awaiting moderation on one of my blogs" AFTER user_notify' );
		db_add_col( 'T_users', 'user_unsubscribe_key', 'varchar(32) NOT NULL default "" COMMENT "A specific key, it is used when a user wants to unsubscribe from a post comments without signing in" AFTER user_notify_moderation' );
		// Set unsubscribe keys for existing users with no unsubscribe key
		$sql = 'SELECT user_ID
							FROM T_users
						 WHERE user_unsubscribe_key = ""';
		$rows = $DB->get_results( $sql, OBJECT, 'Get users with no unsubscribe key' );
		foreach( $rows as $row )
		{
			$DB->query( 'UPDATE T_users
							SET user_unsubscribe_key = "'.generate_random_key().'"
							WHERE user_ID = '.$row->user_ID );
		}
		task_end();

		task_begin( 'Upgrading settings table... ');
		// This query was removed later, to avoid performance issue because of the smart view counting
		/*$DB->query( 'INSERT INTO T_settings (set_name, set_value)
						VALUES ( "smart_hit_count", 1 )' );*/
		$DB->query( 'ALTER TABLE T_coll_settings
									CHANGE COLUMN cset_value cset_value   VARCHAR( 10000 ) NULL COMMENT "The AdSense plugin wants to store very long snippets of HTML"' );
  		task_end();

  		// The following two upgrade task were created subsequently to "Make sure DB schema is up to date".
  		// Note: These queries don't modify the correct databases
		task_begin( 'Upgrading users table, no notification by default...');
		$DB->query( 'ALTER TABLE T_users ALTER COLUMN user_notify SET DEFAULT 0' );
		task_end();

		task_begin( 'Upgrading items table...');
		$DB->query( 'ALTER TABLE T_items__item CHANGE COLUMN post_priority post_priority int(11) unsigned null COMMENT "Task priority in workflow"' );
		task_end();

		set_upgrade_checkpoint( '10200' );
	}


	if( $old_db_version < 10300 )
	{	// 4.2
		task_begin( 'Upgrading user fields...' );
		$DB->query( 'ALTER TABLE T_users__fielddefs
									ADD COLUMN ufdf_required enum("hidden","optional","recommended","require") NOT NULL default "optional"');
		$DB->query( 'UPDATE T_users__fielddefs
										SET ufdf_required = "recommended"
									WHERE ufdf_name in ("Website", "Twitter", "Facebook") ' );
		$DB->query( "REPLACE INTO T_users__fielddefs (ufdf_ID, ufdf_type, ufdf_name, ufdf_required)
			 						VALUES (400000, 'text', 'About me', 'recommended');" );
		task_end();

		task_begin( 'Moving data to user fields...' );
		$DB->query( 'INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10300, user_icq
									 FROM T_users
								  WHERE user_icq IS NOT NULL AND TRIM(user_icq) <> ""' );
		$DB->query( 'INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10200, user_aim
									 FROM T_users
								  WHERE user_aim IS NOT NULL AND TRIM(user_aim) <> ""' );
		$DB->query( 'INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10000, user_msn
									 FROM T_users
								  WHERE user_msn IS NOT NULL AND TRIM(user_msn) <> ""' );
		$DB->query( 'INSERT INTO T_users__fields( uf_user_ID, uf_ufdf_ID, uf_varchar )
								 SELECT user_ID, 10100, user_yim
									 FROM T_users
								  WHERE user_yim IS NOT NULL AND TRIM(user_yim) <> ""' );
		task_end();

		task_begin( 'Dropping obsolete user columns...' );
		$DB->query( 'ALTER TABLE T_users
									DROP COLUMN user_icq,
									DROP COLUMN user_aim,
									DROP COLUMN user_msn,
									DROP COLUMN user_yim' );
		task_end();

		// ---

		task_begin( 'Adding new user columns...' );
		$DB->query( 'ALTER TABLE T_users
									ADD COLUMN user_postcode varchar(12) NULL AFTER user_ID,
									ADD COLUMN user_age_min int unsigned NULL AFTER user_postcode,
									ADD COLUMN user_age_max int unsigned NULL AFTER user_age_min' );
		task_end();

		task_begin( 'Upgrading item table for hide teaser...' );
		$DB->query( 'ALTER TABLE T_items__item
						ADD COLUMN post_hideteaser tinyint(1) NOT NULL DEFAULT 0 AFTER post_featured');
		$DB->query( 'UPDATE T_items__item
										SET post_hideteaser = 1
									WHERE post_content LIKE "%<!--noteaser-->%"' );
		task_end();

		task_begin( 'Creating table for a specific post settings...' );
		$DB->query( "CREATE TABLE T_items__item_settings (
						iset_item_ID  int(10) unsigned NOT NULL,
						iset_name     varchar( 50 ) NOT NULL,
						iset_value    varchar( 2000 ) NULL,
						PRIMARY KEY ( iset_item_ID, iset_name )
					) ENGINE = innodb" );
		task_end();

		task_begin( 'Adding new column to comments...' );
		$DB->query( 'ALTER TABLE T_comments
									ADD COLUMN comment_in_reply_to_cmt_ID INT(10) unsigned NULL AFTER comment_status' );
		task_end();

		task_begin( 'Create table for internal searches...' );
		$DB->query( 'CREATE TABLE T_logs__internal_searches (
						isrch_ID bigint(20) NOT NULL auto_increment,
						isrch_coll_ID bigint(20) NOT NULL,
						isrch_hit_ID bigint(20) NOT NULL,
						isrch_keywords varchar(255) NOT NULL,
						PRIMARY KEY (isrch_ID)
					) ENGINE = MyISAM' );
		task_end();

		task_begin( 'Create table for comments votes...' );
		$DB->query( 'CREATE TABLE T_comments__votes (
						cmvt_cmt_ID  int(10) unsigned NOT NULL,
						cmvt_user_ID int(10) unsigned NOT NULL,
						cmvt_helpful TINYINT(1) NULL DEFAULT NULL,
						cmvt_spam    TINYINT(1) NULL DEFAULT NULL,
						PRIMARY KEY (cmvt_cmt_ID, cmvt_user_ID),
						KEY cmvt_cmt_ID (cmvt_cmt_ID),
						KEY cmvt_user_ID (cmvt_user_ID)
					) ENGINE = innodb' );
		task_end();

		task_begin( 'Adding new comments columns...' );
		$DB->query( 'ALTER TABLE T_comments
									ADD comment_helpful_addvotes INT NOT NULL DEFAULT 0 AFTER comment_nofollow ,
									ADD comment_helpful_countvotes INT UNSIGNED NOT NULL DEFAULT 0 AFTER comment_helpful_addvotes ,
									ADD comment_spam_addvotes INT NOT NULL DEFAULT 0 AFTER comment_helpful_countvotes ,
									ADD comment_spam_countvotes INT UNSIGNED NOT NULL DEFAULT 0 AFTER comment_spam_addvotes ,
									CHANGE COLUMN comment_notif_ctsk_ID comment_notif_ctsk_ID      INT(10) unsigned NULL DEFAULT NULL COMMENT "When notifications for this comment are sent through a scheduled job, what is the job ID?"');
		task_end();

		task_begin( 'Adding new user permission for spam voting...' );
		$DB->query( 'ALTER TABLE T_coll_user_perms
									ADD bloguser_perm_vote_spam_cmts tinyint NOT NULL default 0 AFTER bloguser_perm_edit_ts' );
		task_end();

		task_begin( 'Adding new group permission for spam voting...' );
		$DB->query( 'ALTER TABLE T_coll_group_perms
									ADD bloggroup_perm_vote_spam_cmts tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_ts' );
		task_end();

		task_begin( 'Upgrading countries table...' );
		$DB->query( 'ALTER TABLE '.$tableprefix.'country ADD COLUMN ctry_preferred tinyint(1) NOT NULL DEFAULT 0 AFTER ctry_enabled' );
		task_end();

		$DB->query( 'ALTER TABLE T_items__subscriptions CHANGE COLUMN isub_comments isub_comments   tinyint(1) NOT NULL DEFAULT 0 COMMENT "The user wants to receive notifications for new comments on this post"' );

		set_upgrade_checkpoint( '10300' );
	}


	if( $old_db_version < 10400 )
	{	// 4.2 part 2
		task_begin( 'Updating "Post by Email" settings...' );
		$DB->query( 'UPDATE T_settings SET set_name = "eblog_autobr" WHERE set_name = "AutoBR"' );
		task_end();

		if( $DB->get_var('SELECT set_value FROM T_settings WHERE set_name = "eblog_enabled"') )
		{	// eblog enabled, let's create a scheduled job for it
			task_begin( 'Creating "Post by Email" scheduled job...' );
			$start_date = form_date( date2mysql($GLOBALS['localtimenow'] + 86400), '05:00:00' ); // start tomorrow
			$DB->query( '
				INSERT INTO T_cron__task ( ctsk_start_datetime, ctsk_repeat_after, ctsk_name, ctsk_controller, ctsk_params )
				VALUES ( '.$DB->quote( $start_date ).', 86400, '.$DB->quote( T_('Create posts by email') ).', '.$DB->quote( 'cron/jobs/_post_by_email.job.php' ).', '.$DB->quote( 'N;' ).' )' );
			task_end();
		}

		task_begin( 'Upgrading hitlog table...' );
		$DB->query( 'ALTER TABLE T_hitlog
								ADD COLUMN hit_disp        VARCHAR(30) DEFAULT NULL AFTER hit_uri,
								ADD COLUMN hit_ctrl        VARCHAR(30) DEFAULT NULL AFTER hit_disp,
								ADD COLUMN hit_response_code     INT DEFAULT NULL AFTER hit_agent_type ' );
		task_end();

		task_begin( 'Upgrading file types...' );
		// Update ftyp_icon column
		// Previous versions used a image file name for this field,
		// but from now we should use a icon name from the file /conf/_icons.php
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_image"
						WHERE ftyp_extensions IN ( "gif", "png", "jpg jpeg" )' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_document"
						WHERE ftyp_extensions = "txt"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_www"
						WHERE ftyp_extensions = "htm html"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_pdf"
						WHERE ftyp_extensions = "pdf"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_doc"
						WHERE ftyp_extensions = "doc"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_xls"
						WHERE ftyp_extensions = "xls"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_ppt"
						WHERE ftyp_extensions = "ppt"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_pps"
						WHERE ftyp_extensions = "pps"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_zip"
						WHERE ftyp_extensions = "zip"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_php"
						WHERE ftyp_extensions = "php php3 php4 php5 php6"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = ""
						WHERE ftyp_extensions = "css"' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_sound"
						WHERE ftyp_extensions IN ( "mp3", "m4a" )' );
		$DB->query( 'UPDATE T_filetypes
						SET ftyp_icon = "file_video"
						WHERE ftyp_extensions IN ( "mp4", "mov", "m4v" )' );
		task_end();

		set_upgrade_checkpoint( '10400' );
	}


	if( $old_db_version < 10500 )
	{	//  part 3
		task_begin( 'Upgrading hitlog table...' );
		$DB->query( "ALTER TABLE T_hitlog
								CHANGE COLUMN hit_referer_type  hit_referer_type ENUM(  'search',  'special',  'spam',  'referer',  'direct',  'self',  'admin', 'blacklist' ) NOT NULL,
								ADD COLUMN hit_type ENUM('standard','rss','admin','ajax', 'service') DEFAULT 'standard' NOT NULL AFTER hit_ctrl,
								ADD COLUMN hit_action VARCHAR(30) DEFAULT NULL AFTER hit_ctrl" );
		$DB->query( 'UPDATE T_hitlog SET hit_referer_type = "special" WHERE hit_referer_type = "blacklist"' );
		$DB->query( 'UPDATE T_hitlog SET hit_type = "admin", hit_referer_type = "direct"  WHERE hit_referer_type = "admin"' );
		$DB->query( "ALTER TABLE T_hitlog
								CHANGE COLUMN hit_referer_type  hit_referer_type ENUM(  'search',  'special',  'spam',  'referer',  'direct',  'self' ) NOT NULL");
		task_end();

		task_begin( 'Creating table for Groups of user field definitions...' );
		$DB->query( 'CREATE TABLE T_users__fieldgroups (
				ufgp_ID int(10) unsigned NOT NULL auto_increment,
				ufgp_name varchar(255) NOT NULL,
				ufgp_order int(11) NOT NULL,
				PRIMARY KEY (ufgp_ID)
			) ENGINE = innodb' );
		$DB->query( 'INSERT INTO T_users__fieldgroups ( ufgp_name, ufgp_order )
				VALUES ( "Instant Messaging", "1" ),
							 ( "Phone", "2" ),
							 ( "Web", "3" ),
							 ( "Organization", "4" ),
							 ( "Address", "5" ),
							 ( "Other", "6" ) ' );
		task_end();

		task_begin( 'Upgrading user field definitions...' );
		// Add new fields:
		// 		"ufdf_options" to save a values of the Option list
		// 		"ufdf_duplicated" to add a several instances
		// 		"ufdf_ufgp_ID" - Group ID
		// 		"ufdf_order" - Order number
		// 		"ufdf_suggest" - Suggest values
		$DB->query( 'ALTER TABLE T_users__fielddefs
						ADD ufdf_options    TEXT NOT NULL AFTER ufdf_name,
						ADD ufdf_duplicated enum("forbidden","allowed","list") NOT NULL default "allowed",
						ADD ufdf_ufgp_ID    int(10) unsigned NOT NULL AFTER ufdf_ID,
						ADD ufdf_order      int(11) NOT NULL,
						ADD ufdf_suggest    tinyint(1) NOT NULL DEFAULT 0,
						CHANGE ufdf_ID ufdf_ID int(10) UNSIGNED NOT NULL AUTO_INCREMENT' );
		// Set default values of the field "ufdf_duplicated"
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_duplicated = "allowed"
						WHERE ufdf_ID IN ( 10000, 10100, 10200, 10300, 50100, 50200, 100000, 100100 )' );
		// Group fields by default
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "1"
						WHERE ufdf_ID <= 40000 ' );
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "2"
						WHERE ufdf_ID > 40000 AND ufdf_ID <= 60100' );
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "3"
						WHERE ufdf_ID > 60100 AND ufdf_ID <= 160100' );
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "4"
						WHERE ufdf_ID > 160100 AND ufdf_ID <= 211000' );
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "5"
						WHERE ufdf_ID > 211000 AND ufdf_ID <= 300300' );
		$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_ufgp_ID = "6"
						WHERE ufdf_ID > 300300' );
		// Set order field
		$userfields = $DB->get_results( 'SELECT ufdf_ID, ufdf_ufgp_ID
				FROM T_users__fielddefs
				ORDER BY ufdf_ufgp_ID, ufdf_ID' );
		$userfield_order = 1;
		foreach( $userfields as $uf => $userfield )
		{
			if( $uf > 0 )
			{
				if( $userfields[$uf-1]->ufdf_ufgp_ID != $userfield->ufdf_ufgp_ID )
				{	// New group is starting, reset $userfield_order
					$userfield_order = 1;
				}
			}
			$DB->query( 'UPDATE T_users__fielddefs
						SET ufdf_order = "'.$userfield_order.'"
						WHERE ufdf_ID = '.$userfield->ufdf_ID );
			$userfield_order++;
		}
		// Change field type for Group 'Organization' (group_ID=4)
		$DB->query( 'UPDATE T_users__fielddefs
					SET ufdf_type = "word"
					WHERE ufdf_ufgp_ID = "4"' );
		// Create a default additional info for administrator (user_ID=1)
		$DB->query( 'INSERT INTO T_users__fields ( uf_user_ID, uf_ufdf_ID, uf_varchar )
			VALUES ( 1, 200000, "Site administrator" ),
						 ( 1, 200000, "Moderator" ),
						 ( 1, 100000, "'.$baseurl.'" )' );
		// Add Indexes
		$DB->query( 'ALTER TABLE T_users__fields
						ADD INDEX uf_ufdf_ID ( uf_ufdf_ID ),
						ADD INDEX uf_varchar ( uf_varchar ) ' );
		task_end();

		task_begin( 'Upgrading permissions...' );
		// Group permissions
		$DB->query( 'ALTER TABLE T_coll_group_perms
						ADD bloggroup_perm_own_cmts tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_ts' );
		// Set default values for Administrators & Privileged Bloggers groups
		$DB->query( 'UPDATE T_coll_group_perms
						SET bloggroup_perm_own_cmts = "1"
						WHERE bloggroup_group_ID IN ( 1, 2 )' );
		// User permissions
		$DB->query( 'ALTER TABLE T_coll_user_perms
						ADD bloguser_perm_own_cmts tinyint NOT NULL default 0 AFTER bloguser_perm_edit_ts' );
		task_end();

		set_upgrade_checkpoint( '10500' );
	}


	if( $old_db_version < 10600 )
	{	//  part 4

		// For create_default_regions():
		require_once dirname(__FILE__).'/_functions_create.php';

		task_begin( 'Renaming Countries table...' );
		$DB->query( 'RENAME TABLE '.$tableprefix.'country TO T_regional__country' );
		task_end();

		task_begin( 'Renaming Currencies table...' );
		$DB->query( 'RENAME TABLE '.$tableprefix.'currency TO T_regional__currency' );
		task_end();

		task_begin( 'Creating Regions table...' );
		$DB->query( 'CREATE TABLE T_regional__region (
			rgn_ID        int(10) unsigned NOT NULL auto_increment,
			rgn_ctry_ID   int(10) unsigned NOT NULL,
			rgn_code      char(6) NOT NULL,
			rgn_name      varchar(40) NOT NULL,
			rgn_enabled   tinyint(1) NOT NULL DEFAULT 1,
			rgn_preferred tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY rgn_ID (rgn_ID),
			UNIQUE rgn_ctry_ID_code (rgn_ctry_ID, rgn_code)
		) ENGINE = innodb' );
		task_end();

		create_default_regions();

		task_begin( 'Creating Sub-regions table...' );
		$DB->query( 'CREATE TABLE T_regional__subregion (
			subrg_ID        int(10) unsigned NOT NULL auto_increment,
			subrg_rgn_ID    int(10) unsigned NOT NULL,
			subrg_code      char(6) NOT NULL,
			subrg_name      varchar(40) NOT NULL,
			subrg_enabled   tinyint(1) NOT NULL DEFAULT 1,
			subrg_preferred tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY subrg_ID (subrg_ID),
			UNIQUE subrg_rgn_ID_code (subrg_rgn_ID, subrg_code)
		) ENGINE = innodb' );
		task_end();

		task_begin( 'Creating Cities table...' );
		$DB->query( 'CREATE TABLE T_regional__city (
			city_ID         int(10) unsigned NOT NULL auto_increment,
			city_ctry_ID    int(10) unsigned NOT NULL,
			city_rgn_ID     int(10) unsigned NULL,
			city_subrg_ID   int(10) unsigned NULL,
			city_postcode   char(12) NOT NULL,
			city_name       varchar(40) NOT NULL,
			city_enabled    tinyint(1) NOT NULL DEFAULT 1,
			city_preferred  tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY city_ID (city_ID),
			INDEX city_ctry_ID_postcode ( city_ctry_ID, city_postcode ),
			INDEX city_rgn_ID_postcode ( city_rgn_ID, city_postcode ),
			INDEX city_subrg_ID_postcode ( city_subrg_ID, city_postcode )
		) ENGINE = innodb' );
		task_end();

		task_begin( 'Update Item Settings...' );
		// Admin: full rights for all blogs (look 'ma, doing a natural join! :>)
		$query = "INSERT INTO T_items__item_settings( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, 'hide_teaser', post_hideteaser
							FROM T_items__item";
		$DB->query( $query );

		db_drop_col( 'T_items__item', 'post_hideteaser' );
		task_end();

		task_begin( 'Upgrading hitlog table...' );
		$DB->query( "ALTER TABLE T_hitlog
						ADD COLUMN hit_keyphrase VARCHAR(255) DEFAULT NULL AFTER hit_keyphrase_keyp_ID" );
		task_end();

		task_begin( 'Upgrading track__keyphrase...' );
		$DB->query( "ALTER TABLE T_track__keyphrase
						ADD COLUMN keyp_count_refered_searches INT UNSIGNED DEFAULT 0 AFTER keyp_phrase,
						ADD COLUMN keyp_count_internal_searches INT UNSIGNED DEFAULT 0 AFTER keyp_count_refered_searches" );
		task_end();



		task_begin( 'Droping table internal searches...' );

		$DB->query( "DROP TABLE T_logs__internal_searches" );
		task_end();


		task_begin( 'Upgrading users table...' );
		db_add_col( 'T_users', 'user_rgn_ID', 'int(10) unsigned NULL AFTER user_ctry_ID' );
		db_add_col( 'T_users', 'user_subrg_ID', 'int(10) unsigned NULL AFTER user_rgn_ID' );
		db_add_col( 'T_users', 'user_city_ID', 'int(10) unsigned NULL AFTER user_subrg_ID' );
		task_end();

		task_begin( 'Upgrading hitlog table...' );
		$DB->query( 'UPDATE T_hitlog
						SET hit_type = "rss",
							hit_agent_type = "unknown"
						WHERE hit_agent_type = "rss"' );

		$DB->query( "ALTER TABLE T_hitlog
								CHANGE COLUMN hit_agent_type hit_agent_type ENUM('robot','browser','unknown') DEFAULT 'unknown' NOT NULL" );
		task_end();

		task_begin( 'Creating mail log table...' );
		$DB->query( 'CREATE TABLE '.$tableprefix.'mail__log (
		  emlog_ID        INT(10) UNSIGNED NOT NULL auto_increment,
		  emlog_timestamp TIMESTAMP NOT NULL,
		  emlog_to        VARCHAR(255) DEFAULT NULL,
		  emlog_success   TINYINT(1) NOT NULL DEFAULT 0,
		  emlog_subject   VARCHAR(255) DEFAULT NULL,
		  emlog_headers   TEXT DEFAULT NULL,
		  emlog_message   TEXT DEFAULT NULL,
		  PRIMARY KEY     (emlog_ID)
		) ENGINE = myisam' );
		task_end();

		set_upgrade_checkpoint( '10600' );
	}


	if( $old_db_version < 10700 )
	{	// part 5

		task_begin( 'Upgrading user notifications settings...' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "notify_published_comments", user_notify
							FROM T_users', 'Move notify settings from users to users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "notify_comment_moderation", user_notify_moderation
							FROM T_users', 'Move notify moderation settings from users to users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_PM", 1
							FROM T_users
								WHERE user_allow_msgform = 1 OR user_allow_msgform = 3', 'Set enable PM on users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_PM", 0
							FROM T_users
								WHERE user_allow_msgform = 0 OR user_allow_msgform = 2', 'Set enable PM on users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_email", 1
							FROM T_users
								WHERE user_allow_msgform > 1', 'Set enable email true on users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "enable_email", 0
							FROM T_users
								WHERE user_allow_msgform < 2', 'Set enable email false on users_usersettings' );
		db_drop_col( 'T_users', 'user_notify' );
		db_drop_col( 'T_users', 'user_notify_moderation' );
		db_drop_col( 'T_users', 'user_allow_msgform' );
		task_end();

		task_begin( 'Upgrading Item table...' );
		db_add_col( 'T_items__item', 'post_ctry_ID', 'INT(10) UNSIGNED NULL' );
		db_add_col( 'T_items__item', 'post_rgn_ID', 'INT(10) UNSIGNED NULL' );
		db_add_col( 'T_items__item', 'post_subrg_ID', 'INT(10) UNSIGNED NULL' );
		db_add_col( 'T_items__item', 'post_city_ID', 'INT(10) UNSIGNED NULL' );
		task_end();

		task_begin( 'Upgrading users table...' );
		db_drop_col( 'T_users', 'user_postcode' );	// Previously obsoleted
		db_drop_col( 'T_users', 'user_idmode' );
		task_end();

		task_begin( 'Upgrading users fields table...' );
		db_add_col( 'T_users__fielddefs', 'ufdf_bubbletip', 'varchar(2000) NULL' );
		task_end();


		task_begin( 'Creating table for groups of messaging contacts...' );
		$DB->query( "CREATE TABLE IF NOT EXISTS T_messaging__contact_groups (
			cgr_ID      int(10) unsigned NOT NULL auto_increment,
			cgr_user_ID int(10) unsigned NOT NULL,
			cgr_name    varchar(50) NOT NULL,
			PRIMARY KEY cgr_ID (cgr_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Creating table for group users of messaging contacts...' );
		$DB->query( "CREATE TABLE T_messaging__contact_groupusers (
			cgu_user_ID int(10) unsigned NOT NULL,
			cgu_cgr_ID  int(10) unsigned NOT NULL,
			PRIMARY KEY cgu_PK (cgu_user_ID, cgu_cgr_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Upgrading mail log table...' );
		db_add_col( $tableprefix.'mail__log', 'emlog_user_ID', 'INT(10) UNSIGNED DEFAULT NULL AFTER emlog_timestamp' );
		task_end();

		set_upgrade_checkpoint( '10700' );
	}

	if( $old_db_version < 10800 )
	{	// part 6 aka between "i1-i2" and "i2"

		task_begin( 'Upgrading users table, add user status...' );
		db_add_col( 'T_users', 'user_status', 'enum( "activated", "autoactivated", "closed", "deactivated", "emailchanged", "new" ) NOT NULL default "new" AFTER user_validated' );
		$update_user_status_query = 'UPDATE T_users SET user_status = ';
		// check if new users must activate their account. If users are not required to activate their account, then all existing users will be considerated as activated user.
		$new_users_must_validate = $DB->get_var( 'SELECT set_value FROM T_settings WHERE set_name = '.$DB->quote( 'newusers_mustvalidate' ) );
		if( $new_users_must_validate || ( $new_users_must_validate == NULL ) )
		{ // newusers_mustvalidate setting is set to true, or it is not set at all. If it is not set, we know that the default value is true!
			// set activated status only for validated users
			$update_user_status_query .= $DB->quote( 'activated' );
			$update_user_status_query .= ' WHERE user_validated = 1';
		}
		else
		{
			$update_user_status_query .= $DB->quote( 'autoactivated' );
		}
		// set activated status for corresponding users
		$DB->query( $update_user_status_query );
		db_drop_col( 'T_users', 'user_validated' );
		task_end();

		set_upgrade_checkpoint( '10800' );
	}

	if( $old_db_version < 10900 )
	{	// part 7 aka "i3"

		task_begin( 'Upgrading user settings table...' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "show_online", 0
							FROM T_users
								WHERE user_showonline = 0', 'Set show online on users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "user_ip", user_ip
							FROM T_users
								WHERE user_ip IS NOT NULL', 'Set user ip on users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "user_domain", user_domain
							FROM T_users
								WHERE user_domain IS NOT NULL', 'Set user domain on users_usersettings' );
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
						SELECT user_ID, "user_browser", user_browser
							FROM T_users
								WHERE user_browser IS NOT NULL', 'Set user browser on users_usersettings' );
		db_drop_col( 'T_users', 'user_showonline' );
		db_drop_col( 'T_users', 'user_ip' );
		db_drop_col( 'T_users', 'user_domain' );
		db_drop_col( 'T_users', 'user_browser' );
		task_end();

		task_begin( 'Upgrading user activation settings...' );
		// Remove all last_activation_email timestamps because we will use date instead of them
		$DB->query( 'DELETE FROM T_users__usersettings WHERE uset_name = "last_activation_email"' );
		task_end();

		task_begin( 'Upgrading Users table...' );
		// Update user_status column add 'failedactivation' status
		$DB->query( 'ALTER TABLE T_users CHANGE user_status
					user_status enum( "activated", "autoactivated", "closed", "deactivated", "emailchanged", "failedactivation", "new" ) NOT NULL default "new"' );
		db_add_col( 'T_users', 'user_created_fromIPv4', 'int(10) unsigned NOT NULL' );
		db_add_col( 'T_users', 'user_email_dom_ID', 'int(10) unsigned NULL' );
		$DB->query( 'ALTER TABLE T_users CHANGE dateYMDhour user_created_datetime DATETIME NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		db_add_col( 'T_users', 'user_reg_ctry_ID', 'int(10) unsigned NULL AFTER user_age_max' );
		db_add_col( 'T_users', 'user_profileupdate_ts', 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP' );
		$DB->query( 'ALTER TABLE T_users ADD INDEX user_email ( user_email )' );
		task_end();

		task_begin( 'Renaming Email log table...' );
		$DB->query( 'RENAME TABLE '.$tableprefix.'mail__log TO T_email__log' );
		task_end();

		task_begin( 'Creating email returns table...' );
		$DB->query( "CREATE TABLE T_email__returns (
			  emret_ID        INT(10) UNSIGNED NOT NULL auto_increment,
			  emret_address   VARCHAR(255) DEFAULT NULL,
			  emret_errormsg  VARCHAR(255) DEFAULT NULL,
			  emret_timestamp TIMESTAMP NOT NULL,
			  emret_headers   TEXT DEFAULT NULL,
			  emret_message   TEXT DEFAULT NULL,
			  emret_errtype   CHAR(1) NOT NULL DEFAULT 'U',
			  PRIMARY KEY     (emret_ID)
			) ENGINE = myisam" );
		task_end();

		task_begin( 'Upgrading general settings table...' );
		$DB->query( 'ALTER TABLE T_settings CHANGE set_value set_value VARCHAR( 5000 ) NULL' );
		task_end();

		task_begin( 'Upgrading sessions table...' );
		db_add_col( 'T_sessions', 'sess_device', 'VARCHAR(8) NOT NULL DEFAULT \'\'' );
		task_end();

		task_begin( 'Creating table for Antispam IP Ranges...' );
		$DB->query( "CREATE TABLE T_antispam__iprange (
			aipr_ID         int(10) unsigned NOT NULL auto_increment,
			aipr_IPv4start  int(10) unsigned NOT NULL,
			aipr_IPv4end    int(10) unsigned NOT NULL,
			aipr_user_count int(10) unsigned DEFAULT 0,
			PRIMARY KEY aipr_ID (aipr_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Upgrading base domains table...' );
		$DB->query( "ALTER TABLE T_basedomains CHANGE dom_type dom_type ENUM( 'unknown', 'normal', 'searcheng', 'aggregator', 'email' ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT 'unknown'" );
		$DB->query( 'ALTER TABLE T_basedomains DROP INDEX dom_name' );
		$DB->query( 'ALTER TABLE T_basedomains DROP INDEX dom_type' );
		$DB->query( 'ALTER TABLE T_basedomains ADD UNIQUE dom_type_name ( dom_type, dom_name )' );
		task_end();

		task_begin( 'Upgrading base domains table...' );
		$DB->query( "ALTER TABLE T_basedomains
			MODIFY dom_name VARCHAR(250) COLLATE utf8_bin NOT NULL DEFAULT ''" );
		task_end();

		/*** Update user_email_dom_ID for all already existing users ***/
		task_begin( 'Upgrading users email domains...' );
		$DB->begin();
		// Get the users
		$uemails_SQL = new SQL();
		$uemails_SQL->SELECT( 'user_ID, user_email' );
		$uemails_SQL->FROM( 'T_users' );
		$users_emails = $DB->get_assoc( $uemails_SQL->get() );

		if( count( $users_emails ) > 0 )
		{
			// Get all email domains
			$edoms_SQL = new SQL();
			$edoms_SQL->SELECT( 'dom_ID, dom_name' );
			$edoms_SQL->FROM( 'T_basedomains' );
			$edoms_SQL->WHERE( 'dom_type = \'email\'' );
			$email_domains = $DB->get_assoc( $edoms_SQL->get() );

			foreach( $users_emails as $user_ID => $user_email )
			{
				if( preg_match( '#@(.+)#i', strtolower($user_email), $ematch ) )
				{	// Get email domain from user's email address
					$email_domain = trim( $ematch[1] );
					$dom_ID = array_search( $email_domain, $email_domains );

					if( ! $dom_ID )
					{	// Insert new email domain
						$DB->query( 'INSERT INTO T_basedomains ( dom_type, dom_name )
							VALUES ( \'email\', '.$DB->quote( $email_domain ).' )' );
						$dom_ID = $DB->insert_id;

						// Memorize inserted domain to prevent duplicates
						$email_domains[$dom_ID] = $email_domain;
						// pre_dump( $dom_ID, $email_domain );
					}

					// Update user_email_dom_ID
					$DB->query( 'UPDATE T_users
						SET user_email_dom_ID = '.$DB->quote( $dom_ID ).'
						WHERE user_ID = '.$DB->quote( $user_ID ) );
				}
			}
		}
		$DB->commit();
		task_end();

		task_begin( 'Upgrading users fields table...' );
		// Drop index before increasing a size to avoid an error about "max key length is 767 bytes"
		$DB->query( 'ALTER TABLE T_users__fields DROP INDEX uf_varchar' );
		// Modify field size
		$DB->query( 'ALTER TABLE T_users__fields CHANGE uf_varchar uf_varchar VARCHAR( 10000 ) NOT NULL' );
		// Add index again with limited size in 255 because of utf8 == 765
		$DB->query( 'ALTER TABLE T_users__fields ADD INDEX uf_varchar ( uf_varchar(255) )' );
		task_end();

		task_begin( 'Upgrading cron tasks table...' );
		$DB->query( 'ALTER TABLE T_cron__task CHANGE ctsk_name ctsk_name VARCHAR(255) NOT NULL' );
		task_end();

		task_begin( 'Upgrading comments table...' );
		db_add_col( 'T_comments', 'comment_IP_ctry_ID', 'int(10) unsigned NULL AFTER comment_author_IP' );
		task_end();

		task_begin( 'Creating table for Blocked Email Addreses...' );
		$DB->query( "CREATE TABLE {$tableprefix}email__blocked (
			emblk_ID                    INT(10) UNSIGNED NOT NULL auto_increment,
			emblk_address               VARCHAR(255) DEFAULT NULL,
			emblk_status                ENUM ( 'unknown', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) NOT NULL DEFAULT 'unknown',
			emblk_sent_count            INT(10) UNSIGNED NOT NULL DEFAULT 0,
			emblk_sent_last_returnerror INT(10) UNSIGNED NOT NULL DEFAULT 0,
			emblk_prmerror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,
			emblk_tmperror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,
			emblk_spamerror_count       INT(10) UNSIGNED NOT NULL DEFAULT 0,
			emblk_othererror_count      INT(10) UNSIGNED NOT NULL DEFAULT 0,
			emblk_last_sent_ts          TIMESTAMP NULL,
			emblk_last_error_ts         TIMESTAMP NULL,
			PRIMARY KEY                 (emblk_ID),
			UNIQUE                      emblk_address (emblk_address)
		) ENGINE = myisam" );
		task_end();

		task_begin( 'Upgrading email log table...' );
		// Get old values of emlog_success field
		$SQL = new SQL();
		$SQL->SELECT( 'emlog_ID' );
		$SQL->FROM( 'T_email__log' );
		$SQL->WHERE( 'emlog_success = 0' );
		$email_failed_logs = $DB->get_col( $SQL->get() );
		// Change a field emlog_success to new format
		$DB->query( 'ALTER TABLE T_email__log CHANGE emlog_success emlog_result ENUM ( "ok", "error", "blocked" ) NOT NULL DEFAULT "ok"' );
		if( !empty( $email_failed_logs ) )
		{	// Update only the failed email logs to new values
			// Do NOT update the success email logs, because we already have a result type 'ok' as default
			$DB->query( 'UPDATE T_email__log
					SET emlog_result = '.$DB->quote( 'error' ).'
				WHERE emlog_ID IN ( '.$DB->quote( $email_failed_logs ).' )' );
		}
		task_end();

		set_upgrade_checkpoint( '10900' );
	}

	if( $old_db_version < 10970 )
	{	// part 8/a trunk aka first part of "i4"

		task_begin( 'Upgrading Locales table...' );
		db_add_col( 'T_locales', 'loc_transliteration_map', 'VARCHAR(10000) NOT NULL default \'\' AFTER loc_priority' );
		task_end();

		task_begin( 'Upgrading general settings table...' );
		$DB->query( 'UPDATE T_settings SET set_name = '.$DB->quote( 'smart_view_count' ).' WHERE set_name = '.$DB->quote( 'smart_hit_count' ) );
		// This query below was added later to turn OFF smart view counting on upgrade from v4 to v5 for better performance
		$DB->query( 'DELETE FROM T_settings WHERE set_name = '.$DB->quote( 'smart_view_count' ) );
		task_end();

		task_begin( 'Upgrading sessions table...' );
		$DB->query( "UPDATE T_sessions SET sess_lastseen = concat( '2000-01-01 ', time( sess_lastseen ) )
						WHERE date( sess_lastseen ) = '1970-01-01'" );
		$DB->query( "ALTER TABLE T_sessions CHANGE COLUMN sess_lastseen sess_lastseen_ts TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' COMMENT 'User last logged activation time. Value may be off by up to 60 seconds'" );
		db_add_col( 'T_sessions', 'sess_start_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' AFTER sess_hitcount" );
		$DB->query( 'UPDATE T_sessions SET sess_start_ts = TIMESTAMPADD( SECOND, -1, sess_lastseen_ts )' );
		db_drop_col( 'T_sessions', 'sess_hitcount' );
		task_end();

		task_begin( 'Upgrading users table...' );
		db_add_col( 'T_users', 'user_lastseen_ts', 'TIMESTAMP NULL AFTER user_created_datetime' );
		$DB->query( 'UPDATE T_users SET user_lastseen_ts = ( SELECT MAX( sess_lastseen_ts ) FROM T_sessions WHERE sess_user_ID = user_ID )' );
		$DB->query( 'UPDATE T_users SET user_profileupdate_ts = user_created_datetime WHERE user_profileupdate_ts < user_created_datetime' );
		$DB->query( "ALTER TABLE T_users CHANGE COLUMN user_profileupdate_ts user_profileupdate_date DATE NOT NULL DEFAULT '2000-01-01' COMMENT 'Last day when the user has updated some visible field in his profile.'" );
		task_end();

		task_begin( 'Updating versions table...' );
		db_add_col( 'T_items__version', 'iver_ID', 'INT UNSIGNED NOT NULL FIRST' );
		$DB->query( 'ALTER TABLE T_items__version DROP INDEX iver_itm_ID, ADD INDEX iver_ID_itm_ID ( iver_ID , iver_itm_ID )' );
		task_end();

		task_begin( 'Upgrading messaging contact group users...' );
		db_add_foreign_key( 'T_messaging__contact_groupusers', 'cgu_cgr_ID', 'T_messaging__contact_groups', 'cgr_ID', 'ON DELETE CASCADE' );
		task_end();

		task_begin( 'Creating table for a latest version of the POT file...' );
		$DB->query( "CREATE TABLE T_i18n_original_string (
			iost_ID        int(10) unsigned NOT NULL auto_increment,
			iost_string    varchar(10000) NOT NULL default '',
			iost_inpotfile tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY (iost_ID)
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Creating table for a latest versions of the PO files...' );
		$DB->query( "CREATE TABLE T_i18n_translated_string (
			itst_ID       int(10) unsigned NOT NULL auto_increment,
			itst_iost_ID  int(10) unsigned NOT NULL,
			itst_locale   varchar(20) NOT NULL default '',
			itst_standard varchar(10000) NOT NULL default '',
			itst_custom   varchar(10000) NULL,
			itst_inpofile tinyint(1) NOT NULL DEFAULT 0,
			PRIMARY KEY (itst_ID)
		) ENGINE = innodb DEFAULT CHARSET = utf8" );
		task_end();

		task_begin( 'Updating Antispam IP Ranges table...' );
		db_add_col( 'T_antispam__iprange', 'aipr_status', 'enum( \'trusted\', \'suspect\', \'blocked\' ) NULL DEFAULT NULL' );
		db_add_col( 'T_antispam__iprange', 'aipr_block_count', 'int(10) unsigned DEFAULT 0' );
		$DB->query( "ALTER TABLE T_antispam__iprange CHANGE COLUMN aipr_user_count aipr_user_count int(10) unsigned DEFAULT 0" );
		task_end();

		set_upgrade_checkpoint( '10970' );
	}

	if( $old_db_version < 10975 )
	{	// part 8/b trunk aka first part of "i4"

		task_begin( 'Creating default antispam IP ranges... ' );
		$DB->query( '
			INSERT INTO T_antispam__iprange ( aipr_IPv4start, aipr_IPv4end, aipr_status )
			VALUES ( '.$DB->quote( ip2int( '127.0.0.0' ) ).', '.$DB->quote( ip2int( '127.0.0.255' ) ).', "trusted" ),
				( '.$DB->quote( ip2int( '10.0.0.0' ) ).', '.$DB->quote( ip2int( '10.255.255.255' ) ).', "trusted" ),
				( '.$DB->quote( ip2int( '172.16.0.0' ) ).', '.$DB->quote( ip2int( '172.31.255.255' ) ).', "trusted" ),
				( '.$DB->quote( ip2int( '192.168.0.0' ) ).', '.$DB->quote( ip2int( '192.168.255.255' ) ).', "trusted" )
			' );
		task_end();

		set_upgrade_checkpoint( '10975' );
	}

	if( $old_db_version < 11000 )
	{	// part 8/c trunk aka first part of "i4"

		task_begin( 'Adding new countries...' );
		// IGNORE is needed for upgrades from DB version 9970 or later
		$DB->query( 'INSERT IGNORE INTO T_regional__country ( ctry_code, ctry_name, ctry_curr_ID ) VALUES ( \'ct\', \'Catalonia\', \'2\' )' );
		task_end();

		task_begin( 'Upgrading message thread statuses table...' );
		db_add_col( 'T_messaging__threadstatus', 'tsta_thread_leave_msg_ID', 'int(10) unsigned NULL DEFAULT NULL' );
		task_end();

		task_begin( 'Upgrading Item Settings...' );
		// Convert item custom fields to custom item settings ( move custom fields from T_items__item table to T_items__item_settings table )
		$query = "INSERT INTO T_items__item_settings( iset_item_ID, iset_name, iset_value ) ";
		for( $i = 1; $i <= 8; $i++ )
		{ // For each custom fields:
			if( $i > 1 )
			{
				$query .= ' UNION';
			}
			$field_name = ( $i > 5 ) ? 'varchar'.( $i - 5 ) : 'double'.$i;
			$query .= " SELECT post_ID, 'custom_".$field_name."', post_".$field_name."
							FROM T_items__item WHERE post_".$field_name." IS NOT NULL";
		}
		$DB->query( $query );

		for( $i = 1; $i <= 5; $i++ )
		{ // drop custom double columns from items tabe
			db_drop_col( 'T_items__item', 'post_double'.$i );
		}
		for( $i = 1; $i <= 3; $i++ )
		{ // drop custom varchar columns from items tabe
			db_drop_col( 'T_items__item', 'post_varchar'.$i );
		}

		// Convert post_editor_code item field to item settings
		$DB->query( 'INSERT INTO T_items__item_settings ( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, "editor_code", post_editor_code
							FROM T_items__item
							WHERE post_editor_code IS NOT NULL' );
		db_drop_col( 'T_items__item', 'post_editor_code' );

		// Convert post_metadesc item field to item settings
		$DB->query( 'INSERT INTO T_items__item_settings ( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, "post_metadesc", post_metadesc
							FROM T_items__item
							WHERE post_metadesc IS NOT NULL' );
		db_drop_col( 'T_items__item', 'post_metadesc' );

		// Convert and rename post_metakeywords item field to post_custom_headers item settings
		$DB->query( 'INSERT INTO T_items__item_settings ( iset_item_ID, iset_name, iset_value )
						SELECT post_ID, "post_custom_headers", post_metakeywords
							FROM T_items__item
							WHERE post_metakeywords IS NOT NULL' );
		db_drop_col( 'T_items__item', 'post_metakeywords' );
		task_end();

		task_begin( 'Upgrading items table...' );
		// Drop not used column
		db_drop_col( 'T_items__item', 'post_commentsexpire' );
		task_end();

		task_begin( 'Adding new video file types...' );
		$ftyp = $DB->get_row('SELECT ftyp_ID, ftyp_extensions
									FROM T_filetypes
									WHERE ftyp_mimetype = "video/mp4"
									AND ftyp_extensions NOT LIKE "%f4v%"
									LIMIT 1');

		if( $ftyp )
		{	// Add f4v extension to mp4 file type, if not exists
			$DB->query( 'UPDATE T_filetypes SET ftyp_extensions = "'.$DB->escape($ftyp->ftyp_extensions.' f4v').'"
							WHERE ftyp_ID = '.$DB->quote($ftyp->ftyp_ID) );
		}
		// Add flv file type if not exists
		if( !db_key_exists( 'T_filetypes', 'ftyp_extensions', '"flv"' ) )
		{
			$DB->query( 'INSERT INTO T_filetypes (ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
				             VALUES ("flv", "Flash video file", "video/x-flv", "", "browser", "registered")', 'Add "flv" file type' );
		}
		// Add swf file type if not exists
		if( !db_key_exists( 'T_filetypes', 'ftyp_extensions', '"swf"' ) )
		{
			$DB->query( 'INSERT INTO T_filetypes (ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed)
				             VALUES ("swf", "Flash video file", "application/x-shockwave-flash", "", "browser", "registered")', 'Add "swf" file type' );
		}
		task_end();

		task_begin( 'Upgrading custom item settings...' );
		$DB->begin();
		// Convert latitude and longitude from custom setting to normal item settings
		// Get those blog ids where Latitude and Longitude are both set
		$result = $DB->get_col( 'SELECT cs_left.cset_coll_ID
									FROM T_coll_settings as cs_left
									INNER JOIN T_coll_settings as cs_right ON cs_left.cset_coll_ID = cs_right.cset_coll_ID
									WHERE cs_left.cset_name = "custom_double3" AND cs_left.cset_value = "Latitude" AND
										cs_right.cset_name = "custom_double4" AND cs_right.cset_value = "Longitude"' );
		if( $result )
		{ // blogs were found where Latitude and Longitude custom fields were set for google maps plugin
			// Set "Show location coordinates" on where Latitude and Longitude were set
			$query_values = '( '.implode( ', "show_location_coordinates", 1 ), ( ', $result ).', "show_location_coordinates", 1 )';
			$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES '.$query_values );

			$coll_ids = implode( ', ', $result );
			// Update latitude Item settings
			$DB->query( 'UPDATE T_items__item_settings SET iset_name = "latitude"
							WHERE iset_name = "custom_double3" AND iset_item_ID IN (
								SELECT post_ID FROM T_items__item
								INNER JOIN T_categories ON post_main_cat_ID = cat_ID
								WHERE cat_blog_ID IN ( '.$coll_ids.' )
							)' );
			// Update longitude Item settings
			$DB->query( 'UPDATE T_items__item_settings SET iset_name = "longitude"
							WHERE iset_name = "custom_double4" AND iset_item_ID IN (
								SELECT post_ID FROM T_items__item
								INNER JOIN T_categories ON post_main_cat_ID = cat_ID
								WHERE cat_blog_ID IN ( '.$coll_ids.' )
							)' );
			// Delete proessed latitude & longitude custom fields from collection settings
			$DB->query( 'DELETE FROM T_coll_settings
						WHERE ( cset_name = "custom_double3" OR cset_name = "custom_double4" ) AND
							cset_coll_ID IN ( '.$coll_ids.' )' );
		}
		$DB->commit(); // End convert latitude and longitude

		$DB->begin(); // Convert custom fields
		// Delete not used custom fields
		$DB->query( 'DELETE FROM T_coll_settings WHERE ( cset_value IS NULL OR cset_value = "" ) AND cset_name LIKE "custom\_%"' );
		// Set custom double fields count
		$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT cset_coll_ID, "count_custom_double", COUNT( cset_name )
						FROM T_coll_settings
						WHERE cset_name LIKE "custom\_double%"
						GROUP BY cset_coll_ID' );
		// Set custom varchar fields count
		$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT cset_coll_ID, "count_custom_varchar", COUNT( cset_name )
						FROM T_coll_settings
						WHERE cset_name LIKE "custom\_varchar%"
						GROUP BY cset_coll_ID' );
		// Select all custom fields from all blog, to create converted field values
		$result = $DB->get_results( 'SELECT cset_coll_ID as coll_ID, cset_name as name, cset_value as value
										FROM T_coll_settings
										WHERE cset_name LIKE "custom\_%"
										ORDER BY cset_coll_ID, cset_name' );
		if( !empty( $result ) )
		{ // There are custom fields in blog settings
			$convert_field_values = '';
			$reorder_field_values = '';
			$old_prefix = "";
			$old_coll_ID = "";
			foreach( $result as $row )
			{ // process each custom field
				$custom_id = uniqid( '' );
				$prefix = ( substr( $row->name, 7, 6 ) === 'double' ) ? 'custom_double' : 'custom_varchar';
				// replace custom_double{N} and custom_varchar{N} values with a custom_id where N is number
				$convert_field_values .= '( '.$row->coll_ID.', "'.$row->name.'", "'.$custom_id.'" ), ';
				// add new custom_double_{customid} and custom_varchar_{customid} entries with the old correspinding custom field values
				$convert_field_values .= '( '.$row->coll_ID.', "'.$prefix.'_'.$custom_id.'", "'.$row->value.'" ), ';

				// create reorder values to replace e.g. custom_double2 to custom_double1 if custom_double1 doesn't exists yet
				$index = ( ( $old_prefix == $prefix ) && ( $old_coll_ID == $row->coll_ID ) ) ? $index + 1 : 1;
				$reorder_field_values .= '( '.$row->coll_ID.', "'.$prefix.$index.'", "'.$custom_id.'" ), ';
				$old_prefix = $prefix;
				$old_coll_ID = $row->coll_ID;
			}
			$convert_field_values = substr( $convert_field_values, 0, -2 );
			$reorder_field_values = substr( $reorder_field_values, 0, -2 );
			// Convert custom fields in collection setting
			$DB->query( 'REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES '.$convert_field_values );
			// Update double custom field name_ids in item settings table
			$DB->query( 'UPDATE T_items__item_settings SET iset_name = (
								SELECT CONCAT( "custom_double_", cset_value ) FROM T_coll_settings
									INNER JOIN T_categories ON cset_coll_ID = cat_blog_ID
									INNER JOIN T_items__item ON cat_ID = post_main_cat_ID
									WHERE cset_name = iset_name AND post_ID  = iset_item_ID )
							WHERE iset_name LIKE "custom\_double%"' );
			// Update varchar custom field name_ids in item settings table
			$DB->query( 'UPDATE T_items__item_settings SET iset_name = (
								SELECT CONCAT( "custom_varchar_", cset_value ) FROM T_coll_settings
									INNER JOIN T_categories ON cset_coll_ID = cat_blog_ID
									INNER JOIN T_items__item ON cat_ID = post_main_cat_ID
									WHERE cset_name = iset_name AND post_ID  = iset_item_ID )
							WHERE iset_name LIKE "custom\_varchar%"' );
			// Reorder custom fields in collection settings
			$DB->query( 'REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES '.$reorder_field_values );
		}
		$DB->commit(); // End convert custom fields
		task_end();

		task_begin( 'Convert group users permissions to pluggable permissions...' );
		$DB->query( 'REPLACE INTO T_groups__groupsettings( gset_grp_ID, gset_name, gset_value )
						SELECT grp_ID, "perm_users", grp_perm_users
							FROM T_groups' );
		db_drop_col( 'T_groups', 'grp_perm_users' );
		task_end();

		task_begin( 'Update Post Types... ' );
		$DB->query( "REPLACE INTO T_items__type ( ptyp_ID, ptyp_name )
			VALUES ( 4000, 'Advertisement' )" );
		task_end();

		task_begin( 'Update files table... ' );
		db_add_col( 'T_files', 'file_hash', 'char(32) default NULL' );
		task_end();

		task_begin( 'Create table for files voting...' );
		$DB->query( 'CREATE TABLE '.$tableprefix.'files__vote (
				fvot_file_ID       int(11) UNSIGNED NOT NULL,
				fvot_user_ID       int(11) UNSIGNED NOT NULL,
				fvot_like          tinyint(1),
				fvot_inappropriate tinyint(1),
				fvot_spam          tinyint(1),
				primary key (fvot_file_ID, fvot_user_ID)
			) ENGINE = innodb' );
		task_end();

		task_begin( 'Create table for users reporting...' );
		$DB->query( "CREATE TABLE T_users__reports (
			urep_target_user_ID int(11) unsigned NOT NULL,
			urep_reporter_ID    int(11) unsigned NOT NULL,
			urep_status         enum( 'fake', 'guidelines', 'harass', 'spam', 'other' ),
			urep_info           varchar(240),
			urep_datetime		datetime NOT NULL,
			PRIMARY KEY ( urep_target_user_ID, urep_reporter_ID )
		) ENGINE = innodb" );
		task_end();

		task_begin( 'Upgrading skins type...' );
		$DB->query( "ALTER TABLE T_skins__skin MODIFY COLUMN skin_type enum('normal','feed','sitemap','mobile','tablet') NOT NULL default 'normal'" );
		task_end();

		task_begin( 'Upgrading blogs skins...' );
		// Convert blog skin ID to blog settings
		$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						SELECT blog_ID, "normal_skin_ID", blog_skin_ID
						FROM T_blogs' );
		db_drop_col( 'T_blogs', 'blog_skin_ID' );
		task_end();

		task_begin( 'Update categories table... ' );
		db_add_col( 'T_categories', 'cat_meta', 'tinyint(1) NOT NULL DEFAULT 0' );
		db_add_col( 'T_categories', 'cat_lock', 'tinyint(1) NOT NULL DEFAULT 0' );
		task_end();

		task_begin( 'Plugin settings update...' );
		$all_blog_ids = $DB->get_col( 'SELECT blog_ID FROM T_blogs' );
		$plugin_ids = $DB->get_assoc( 'SELECT pset_plug_ID, pset_value FROM T_pluginsettings WHERE pset_name = "render_comments"' );
		$insert_values = '';
		foreach( $all_blog_ids as $blog_ID )
		{
			foreach( $plugin_ids as $plugin_ID => $setting_value )
			{
				$apply_comment_rendering = $setting_value ? 'stealth' : 'never';
				$insert_values .= '( '.$blog_ID.', "plugin'.$plugin_ID.'_coll_apply_comment_rendering", "'.$apply_comment_rendering.'" ),';
			}
		}
		if( !empty( $insert_values ) )
		{
			$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						VALUES '.substr( $insert_values, 0, strlen( $insert_values ) - 1 ) );
		}
		$DB->query( 'DELETE FROM T_pluginsettings WHERE pset_name = "render_comments"' );
		task_end();

		task_begin( 'Creating comment prerendering cache table...' );
		$DB->query( "CREATE TABLE T_comments__prerendering (
			cmpr_cmt_ID INT(11) UNSIGNED NOT NULL,
			cmpr_format ENUM('htmlbody','entityencoded','xml','text') NOT NULL,
			cmpr_renderers TEXT NOT NULL,
			cmpr_content_prerendered MEDIUMTEXT NULL,
			cmpr_datemodified TIMESTAMP NOT NULL,
			PRIMARY KEY (cmpr_cmt_ID, cmpr_format)
		) ENGINE = innodb" );
		db_add_col( 'T_comments', 'comment_renderers', "TEXT NOT NULL AFTER comment_content" );
		$DB->query( 'UPDATE T_comments SET comment_renderers = "default"' );
		task_end();

		task_begin( 'Upgrading plugins table...' );
		db_drop_col( 'T_plugins', 'plug_apply_rendering' );
		task_end();

		task_begin( 'Upgrading Auto_P plugin...' );
		$blog_settings = $DB->get_assoc( 'SELECT cset_coll_ID, cset_value FROM T_coll_settings WHERE cset_name = "comment_autobr"' );
		$insert_values = array();
		$plugin_ids = $DB->get_col( 'SELECT plug_ID FROM T_plugins WHERE plug_code = "b2WPAutP"' );
		foreach( $blog_settings as $blog_ID => $blog_setting_value )
		{
			foreach( $plugin_ids as $plugin_ID )
			{
				switch( $blog_setting_value )
				{
					case 'never':
						$apply_comment_rendering = 'never';
						break;
					case 'optional':
						$apply_comment_rendering = 'opt-out';
						break;
					case 'always':
						$apply_comment_rendering = 'stealth';
						break;
					default:
						break 2;
				}
				$insert_values[] = '( '.$blog_ID.', "plugin'.$plugin_ID.'_coll_apply_comment_rendering", "'.$apply_comment_rendering.'" )';
			}
		}
		if( count( $insert_values ) > 0 )
		{
			$DB->query( 'REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
						VALUES '.implode( ',', $insert_values ) );
		}
		$DB->query( 'DELETE FROM T_coll_settings WHERE cset_name = "comment_autobr"' );
		$DB->query( 'UPDATE T_comments SET comment_content = REPLACE( REPLACE( comment_content, "<br>\n", "\n" ), "<br />\n", "\n" )' );
		task_end();

		set_upgrade_checkpoint( '11000' );
	}

	if( $old_db_version < 11010 )
	{	// part 9 trunk aka second part of "i4"

		task_begin( 'Upgrading post statuses...' );
		$DB->query( "ALTER TABLE T_items__item CHANGE COLUMN post_status post_status enum('published','community','deprecated','protected','private','review','draft','redirected') NOT NULL default 'published'" );
		$DB->query( "ALTER TABLE T_items__version CHANGE COLUMN iver_status iver_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') NULL" );
		$DB->query( "ALTER TABLE T_coll_user_perms CHANGE COLUMN bloguser_perm_poststatuses bloguser_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') NOT NULL default ''" );
		$DB->query( "ALTER TABLE T_coll_group_perms CHANGE COLUMN bloggroup_perm_poststatuses bloggroup_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') NOT NULL default ''" );
		task_end();

		task_begin( 'Upgrading groups table...' );
		$pbloggers_renamed_to_moderators = $DB->query( 'UPDATE T_groups SET grp_name = "Moderators" WHERE grp_ID = 2 AND grp_name = "Privileged Bloggers"' );
		// Update administrators and moderators users coll setting permissions with new permissions
		// Note we can change moderators permission if the group name and ID was not changed after the original install
		$moderators_condition = $pbloggers_renamed_to_moderators ? ' OR bloggroup_group_ID = 2' : '';
		$DB->query( "UPDATE T_coll_group_perms SET bloggroup_perm_poststatuses = 'published,community,deprecated,protected,private,review,draft' WHERE bloggroup_group_ID = 1".$moderators_condition );
		// Change groups name
		$DB->query( 'UPDATE T_groups SET grp_name = "Trusted Users" WHERE grp_ID = 3 AND grp_name = "Bloggers"' );
		$DB->query( 'UPDATE T_groups SET grp_name = "Normal Users" WHERE grp_ID = 4 AND grp_name = "Basic Users"' );

		// Get "Misbehaving/Suspect Users" group ID
		$suspect_query = 'SELECT grp_ID
						FROM T_groups
						WHERE grp_name = "Misbehaving/Suspect Users"
						ORDER BY grp_ID DESC
						LIMIT 1';
		$suspect_group_ID = $DB->get_var( $suspect_query );
		if( empty( $suspect_group_ID ) )
		{ // suspect group doesn't exists, check spammers because probably it does not exists either
			$insert_values = '( "Misbehaving/Suspect Users" )';
			// Get "Spammers/Restricted Users" group ID
			$query = 'SELECT grp_ID
					FROM T_groups
					WHERE grp_name = "Spammers/Restricted Users"
					ORDER BY grp_ID DESC
					LIMIT 1';
			$spammers_group_ID = $DB->get_var( $query );
			if( empty( $spammers_group_ID ) )
			{
				$insert_values .= ', ( "Spammers/Restricted Users" )';
			}
			// Insert two new group
			$DB->query( 'INSERT INTO T_groups ( grp_name )
						VALUES '.$insert_values );

			$suspect_group_ID = $DB->get_var( $suspect_query );
			if( $suspect_group_ID )
			{ // Set coll setting permissions for Misbehaving/Suspect Users in Forums
				$query = "
					INSERT INTO T_coll_group_perms( bloggroup_blog_ID, bloggroup_group_ID, bloggroup_ismember,
						bloggroup_perm_poststatuses, bloggroup_perm_delpost, bloggroup_perm_edit_ts,
						bloggroup_perm_own_cmts, bloggroup_perm_vote_spam_cmts, bloggroup_perm_draft_cmts, bloggroup_perm_publ_cmts, bloggroup_perm_depr_cmts,
						bloggroup_perm_cats, bloggroup_perm_properties,
						bloggroup_perm_media_upload, bloggroup_perm_media_browse, bloggroup_perm_media_change )
					SELECT blog_ID, ".$suspect_group_ID.", 1, 'review,draft', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
						FROM T_blogs WHERE blog_ID = 5 AND blog_shortname = 'Forums'";
				$DB->query( $query );
			}
		}
		task_end();

		task_begin( 'Upgrading blogs table...' );
		db_add_col( 'T_blogs', 'blog_type', 'ENUM( "std", "photo", "group", "forum", "manual" ) DEFAULT "std" NOT NULL' );
		task_end();

		task_begin( 'Upgrading comment statuses...' );
		$DB->query( "ALTER TABLE T_comments CHANGE COLUMN comment_status comment_status ENUM('published','community','deprecated','protected','private','review','draft','trash') DEFAULT 'published' NOT NULL" );
		task_end();

		task_begin( 'Updating collection user/group permissions...' );
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_cmtstatuses', "set('review','draft','private','protected','deprecated','community','published') NOT NULL default '' AFTER bloguser_perm_vote_spam_cmts" );
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_edit_cmt', "ENUM('no','own','anon','lt','le','all') NOT NULL default 'no' AFTER bloguser_perm_cmtstatuses" );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_cmtstatuses', "set('review','draft','private','protected','deprecated','community','published') NOT NULL default '' AFTER bloggroup_perm_vote_spam_cmts" );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_edit_cmt', "ENUM('no','own','anon','lt','le','all') NOT NULL default 'no' AFTER bloggroup_perm_cmtstatuses" );

		// Add access to those comment statuses for what user had before
		$DB->query( 'UPDATE T_coll_user_perms
					SET bloguser_perm_cmtstatuses = ( bloguser_perm_publ_cmts * 1 ) | ( bloguser_perm_depr_cmts * 4 ) | ( bloguser_perm_draft_cmts * 64 )' );
		// Add access to all cmt statuses for those users which had edit permission on all comment statuses
		$DB->query( 'UPDATE T_coll_user_perms
					SET bloguser_perm_cmtstatuses = "published,community,deprecated,protected,private,review,draft", bloguser_perm_edit_cmt = "all"
					WHERE bloguser_perm_publ_cmts <> 0 AND bloguser_perm_depr_cmts <> 0 AND bloguser_perm_draft_cmts <> 0' );
		// Add "lower then" edit permission to those users who had permission to edit published or draft comments
		$DB->query( 'UPDATE T_coll_user_perms
					SET bloguser_perm_edit_cmt = "lt"
					WHERE ( bloguser_perm_cmtstatuses & 65 ) != 0 AND bloguser_perm_edit_cmt = "no"' );

		// Add access to those comment statuses for what group had before
		$DB->query( 'UPDATE T_coll_group_perms
					SET bloggroup_perm_cmtstatuses = ( bloggroup_perm_publ_cmts * 1 ) | ( bloggroup_perm_depr_cmts * 4 ) | ( bloggroup_perm_draft_cmts * 64 )' );
		// Add access to all cmt statuses for those groups which had edit permission on all comment statuses
		$DB->query( 'UPDATE T_coll_group_perms
					SET bloggroup_perm_cmtstatuses = "published,community,deprecated,protected,private,review,draft", bloggroup_perm_edit_cmt = "all"
					WHERE bloggroup_perm_publ_cmts <> 0 AND bloggroup_perm_depr_cmts <> 0 AND bloggroup_perm_draft_cmts <> 0' );
		// Add "lower then" edit permission to those groups who had permission to edit published or draft comments
		$DB->query( 'UPDATE T_coll_group_perms
					SET bloggroup_perm_edit_cmt = "lt"
					WHERE ( bloggroup_perm_cmtstatuses & 65 ) != 0 AND bloggroup_perm_edit_cmt = "no"' );

		db_drop_col( 'T_coll_user_perms', 'bloguser_perm_draft_cmts' );
		db_drop_col( 'T_coll_user_perms', 'bloguser_perm_publ_cmts' );
		db_drop_col( 'T_coll_user_perms', 'bloguser_perm_depr_cmts' );
		db_drop_col( 'T_coll_group_perms', 'bloggroup_perm_draft_cmts' );
		db_drop_col( 'T_coll_group_perms', 'bloggroup_perm_publ_cmts' );
		db_drop_col( 'T_coll_group_perms', 'bloggroup_perm_depr_cmts' );

		db_add_col( 'T_coll_user_perms', 'bloguser_perm_delcmts', 'tinyint NOT NULL default 0 AFTER bloguser_perm_edit_ts' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_delcmts', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_ts' );
		// GRANT delete comment perms for moderators
		$DB->query( 'UPDATE T_coll_group_perms
					SET bloggroup_perm_delcmts = 1
					WHERE bloggroup_perm_edit_cmt = "le" OR bloggroup_perm_edit_cmt = "all"' );

		$DB->query( "ALTER TABLE T_coll_user_perms CHANGE COLUMN bloguser_perm_own_cmts bloguser_perm_recycle_owncmts tinyint NOT NULL default 0" );
		$DB->query( "ALTER TABLE T_coll_group_perms CHANGE COLUMN bloggroup_perm_own_cmts bloggroup_perm_recycle_owncmts tinyint NOT NULL default 0" );
		task_end();

		task_begin( 'Updating blogs settings...' );
		$DB->query( 'UPDATE T_coll_settings SET cset_value = "blog" WHERE cset_name = "enable_goto_blog" AND cset_value = "1"' );
		$DB->query( 'UPDATE T_coll_settings SET cset_value = "no" WHERE cset_name = "enable_goto_blog" AND cset_value = "0"' );
		task_end();

		set_upgrade_checkpoint( '11010' );
	}

	if( $old_db_version < 11020 )
	{	// part 10 trunk aka third part of "i4"

		task_begin( 'Upgrading users table...' );
		// Get all users with defined IPs
		$users_SQL = new SQL();
		$users_SQL->SELECT( 'user_ID, user_created_fromIPv4' );
		$users_SQL->FROM( 'T_users' );
		$users_SQL->WHERE( 'user_created_fromIPv4 IS NOT NULL' );
		$users_SQL->WHERE_and( 'user_created_fromIPv4 != '.$DB->quote( ip2int( '0.0.0.0' ) ) );
		$users_SQL->WHERE_and( 'user_created_fromIPv4 != '.$DB->quote( ip2int( '127.0.0.1' ) ) );
		$users = $DB->get_assoc( $users_SQL->get() );
		// Get user's IPs from settings table
		$settings_SQL = new SQL();
		$settings_SQL->SELECT( 'uset_user_ID, uset_value' );
		$settings_SQL->FROM( 'T_users__usersettings' );
		$settings_SQL->WHERE( 'uset_name = "user_ip"' );
		if( count( $users ) > 0 )
		{	// Get IPs only for users which have not IP in T_users table
			$settings_SQL->WHERE_and( 'uset_user_ID NOT IN ('.$DB->quote( array_keys( $users ) ).')' );
		}
		$settings = $DB->get_assoc( $settings_SQL->get() );
		if( count( $users ) > 0 || count( $settings ) > 0 )
		{
			$users_settings_insert_sql = array();
			foreach( $users as $user_ID => $user_IP )
			{
				$users_settings_insert_sql[] = '( '.$DB->quote( $user_ID ).', "created_fromIPv4", '.$DB->quote( $user_IP ).' )';
			}
			foreach( $settings as $user_ID => $user_IP )
			{
				$users_settings_insert_sql[] = '( '.$DB->quote( $user_ID ).', "created_fromIPv4", '.$DB->quote( ip2int( $user_IP ) ).' )';
			}
			// Insert IPs values into settings table
			$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
				VALUES '.implode( ', ', $users_settings_insert_sql ) );
		}
		// Remove old IPs from settings table
		$DB->query( 'DELETE FROM T_users__usersettings
			WHERE uset_name = "user_ip"' );
		db_drop_col( 'T_users', 'user_created_fromIPv4' );
		task_end();

		set_upgrade_checkpoint( '11020' );
	}

	if( $old_db_version < 11025 )
	{	// part 11 trunk aka fourth part of "i4"

		task_begin( 'Upgrading items table...' );
		$DB->query( "UPDATE T_items__item SET post_datecreated = concat( '2000-01-01 ', time( post_datecreated ) )
						WHERE date( post_datecreated ) = '1970-01-01'" );
		$DB->query( "UPDATE T_items__item SET post_datemodified = concat( '2000-01-01 ', time( post_datemodified ) )
						WHERE date( post_datemodified ) = '1970-01-01'" );
		$DB->query( "ALTER TABLE T_items__item CHANGE COLUMN post_datecreated post_datecreated TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'" );
		$DB->query( "ALTER TABLE T_items__item CHANGE COLUMN post_datemodified post_datemodified TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'" );
		db_add_col( 'T_items__item', 'post_last_touched_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' AFTER post_datemodified" );
		$DB->query( 'UPDATE T_items__item SET post_last_touched_ts = post_datemodified' );
		task_end();

		/*
		 * ADD UPGRADES FOR i4 BRANCH __ABOVE__ IN THIS BLOCK.
		 *
		 * This part will be included in trunk and i4 branches
		 */

		set_upgrade_checkpoint( '11025' );
	}

	// In some upgrade versions ( currently only in "i5" ) we would like to create profile pictures links from the user's files in the profile pictures folder
	// To be able to do that we need an up to date database version, so we will create profile pictures after the ugrade script run successfully.
	// Set this $create_profile_picture_links to true only in those upgrade block where it's required.
	$create_profile_picture_links = false;

	if( $old_db_version < 11100 )
	{	// part 12 trunk aka "i5"

		task_begin( 'Update links table...' );
		db_add_col( 'T_links', 'link_usr_ID', 'int(11) unsigned  NULL COMMENT "Used for linking files to users (user profile picture)" AFTER link_cmt_ID' );
		db_add_index( 'T_links', 'link_usr_ID', 'link_usr_ID' );
		task_end();

		task_begin( 'Creating links for users profile pictures...' );
		// Create links for main profile pictures
		$link_create_date = date2mysql( time() );
		$DB->query( 'INSERT INTO T_links( link_datecreated, link_datemodified, link_usr_ID, link_file_ID, link_position, link_order )
						SELECT '.$DB->quote( $link_create_date ).', '.$DB->quote( $link_create_date ).', user_ID, user_avatar_file_ID, "", 1
						FROM T_users
						WHERE user_avatar_file_ID IS NOT NULL' );
		// Set $create_profile_picture_links to true to create links for all files from the users profile_pictures folder
		$create_profile_picture_links = true;
		task_end();

		task_begin( 'Upgrading custom item settings...' );
		$DB->begin(); // Add names for custom fields
		// Select all custom fields from all blogs, to create field names
		$result = $DB->get_results( 'SELECT cset_coll_ID as coll_ID, cset_name as name, cset_value as value
										FROM T_coll_settings
										WHERE cset_name LIKE "custom\_double\_%"
										   OR cset_name LIKE "custom\_varchar\_%"
										ORDER BY cset_coll_ID, cset_name' );
		if( !empty( $result ) )
		{ // There are custom fields in blog settings
			$insert_field_names = '';
			foreach( $result as $row )
			{ // process each custom field
				$field_guid = preg_replace( '/^custom_(double|varchar)_([a-f0-9\-]+)$/', '$2', $row->name );
				// Replace special chars/umlauts, if we can convert charsets:
				load_funcs('locales/_charset.funcs.php');
				$field_name = strtolower( preg_replace( '/[^a-z0-9\-_]+/i', '_', $row->value ) );
				$field_name = replace_special_chars( $field_name );

				$insert_field_names .= '( '.$row->coll_ID.', "custom_fname_'.$field_guid.'", "'.$field_name.'" ), ';
			}
			// Insert names for custom fields in collection settings
			$DB->query( 'INSERT INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
							VALUES '.substr( $insert_field_names, 0, -2 ) );
		}
		$DB->commit(); // End adding of names for custom fields
		task_end();

		task_begin( 'Upgrading comments table...' );
		db_add_index( 'T_comments', 'comment_status', 'comment_status' );
		task_end();

		set_upgrade_checkpoint( '11100' );
	}

	if( $old_db_version < 11110 )
	{ // part 13 trunk aka second part of "i5"

		// Add new settings for antispam groups
		$antispam_group_settings = $DB->get_assoc( 'SELECT set_name, set_value
			 FROM T_settings
			WHERE set_name IN ( '.$DB->quote( array( 'antispam_suspicious_group', 'antispam_trust_groups' ) ).')' );
		if( count( $antispam_group_settings ) < 2 )
		{ // Insert new settings only if don't exist in DB
			task_begin( 'Updating general settings...' );
			// Set antispam suspicious group
			if( !isset( $antispam_group_settings['antispam_suspicious_group'] ) )
			{ // Insert new value, Don't rewrite value if it already defined before
				$suspect_group_SQL = new SQL();
				$suspect_group_SQL->SELECT( 'grp_ID' );
				$suspect_group_SQL->FROM( 'T_groups' );
				$suspect_group_SQL->WHERE( 'grp_name = '.$DB->quote( 'Misbehaving/Suspect Users' ) );
				$suspect_group_ID = $DB->get_var( $suspect_group_SQL->get() );
				if( !empty( $suspect_group_ID ) )
				{ // Save setting value
					$DB->query( 'INSERT INTO T_settings ( set_name, set_value ) VALUES
							( '.$DB->quote( 'antispam_suspicious_group' ).', '.$DB->quote( $suspect_group_ID ).' )' );
				}
			}
			// Set antispam trust groups
			if( !isset( $antispam_group_settings['antispam_trust_groups'] ) )
			{ // Insert new value, Don't rewrite value if it already defined before
				$trust_groups = array( 'Administrators', 'Moderators', 'Trusted Users', 'Spammers/Restricted Users' );
				$trust_groups_SQL = new SQL();
				$trust_groups_SQL->SELECT( 'grp_ID' );
				$trust_groups_SQL->FROM( 'T_groups' );
				$trust_groups_SQL->WHERE( 'grp_name IN ( '.$DB->quote( $trust_groups ).')' );
				$trust_groups_IDs = $DB->get_col( $trust_groups_SQL->get() );
				if( !empty( $trust_groups_IDs ) )
				{ // Save setting value
					$DB->query( 'INSERT INTO T_settings ( set_name, set_value ) VALUES
							( '.$DB->quote( 'antispam_trust_groups' ).', '.$DB->quote( implode( ',', $trust_groups_IDs ) ).' )' );
				}
			}
			task_end();
		}

		set_upgrade_checkpoint( '11110' );
	}

	if( $old_db_version < 11200 )
	{ // part 14 trunk aka "i6"

		task_begin( 'Upgrading comments table...' );
		db_add_col( 'T_comments', 'comment_last_touched_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00' AFTER comment_date" );
		$DB->query( 'UPDATE T_comments
		                SET comment_last_touched_ts = comment_date' );
		task_end();

		task_begin( 'Convert email addresses to lowercase... ' );
		$DB->query( 'UPDATE T_users SET user_email = LOWER( user_email )' );
		$DB->query( 'UPDATE '.$tableprefix.'email__blocked SET emblk_address = LOWER( emblk_address )' );
		$DB->query( 'UPDATE T_email__returns SET emret_address = LOWER( emret_address )' );
		$DB->query( 'UPDATE T_email__log SET emlog_to = LOWER( emlog_to )' );
		$DB->query( 'UPDATE T_comments
			  SET comment_author_email = LOWER( comment_author_email )
			WHERE comment_author_email IS NOT NULL' );
		task_end();

		task_begin( 'Upgrading blogs table...' );
		db_add_col( 'T_blogs', 'blog_order', 'int(11) NULL DEFAULT NULL' );
		$DB->query( 'UPDATE T_blogs
		                SET blog_order = blog_ID' );
		task_end();

		task_begin( 'Updating general settings...' );
		$site_skins_enabled = $DB->get_var( 'SELECT set_value
			 FROM T_settings
			WHERE set_name = '.$DB->quote( 'site_skins_enabled' ) );
		if( is_null( $site_skins_enabled ) )
		{ // Insert new setting to disable site skins
			$DB->query( 'INSERT INTO T_settings ( set_name, set_value )
				VALUES ( '.$DB->quote( 'site_skins_enabled' ).', '.$DB->quote( '0' ).' )' );
		}
		elseif( $site_skins_enabled == '1' )
		{ // Disable site skins if it is enabled
			$DB->query( 'UPDATE T_settings
				  SET set_value = '.$DB->quote( '0' ).'
				WHERE set_name = '.$DB->quote( 'site_skins_enabled' ) );
		}
		task_end();

		task_begin( 'Upgrading blogs table...' );
		db_add_col( 'T_blogs', 'blog_favorite', 'TINYINT(1) NOT NULL DEFAULT 1' );
		task_end();

		task_begin( 'Upgrade table of base domains... ' );
		$DB->query( "ALTER TABLE T_basedomains CHANGE COLUMN dom_status dom_status ENUM('unknown','trusted','suspect','blocked') NOT NULL DEFAULT 'unknown'" );
		task_end();

		task_begin( 'Create table for file links voting... ' );
		db_create_table( $tableprefix.'links__vote', '
			lvot_link_ID       int(11) UNSIGNED NOT NULL,
			lvot_user_ID       int(11) UNSIGNED NOT NULL,
			lvot_like          tinyint(1),
			lvot_inappropriate tinyint(1),
			lvot_spam          tinyint(1),
			primary key (lvot_link_ID, lvot_user_ID)' );

		// Convert all file votes to link votes
		$DB->query( 'INSERT INTO '.$tableprefix.'links__vote ( lvot_link_ID, lvot_user_ID, lvot_like, lvot_inappropriate, lvot_spam )
						SELECT link_ID, fvot_user_ID, fvot_like, fvot_inappropriate, fvot_spam
						FROM '.$tableprefix.'files__vote
						LEFT JOIN T_links ON link_file_ID = fvot_file_ID
						WHERE link_ID IS NOT NULL' );

		// Delete old file voting table
		$DB->query( 'DROP TABLE IF EXISTS '.$tableprefix.'files__vote' );
		task_end();

		task_begin( 'Create table for goal categories... ' );
		db_create_table( 'T_track__goalcat', '
			gcat_ID     int(10) unsigned NOT NULL auto_increment,
			gcat_name   varchar(50) default NULL,
			gcat_color  char(7) default NULL,
			PRIMARY KEY (gcat_ID)',
			'ENGINE = myisam' );
		// Insert default goal category
		$DB->query( 'INSERT INTO T_track__goalcat ( gcat_name, gcat_color )
			VALUES ( '.$DB->quote( 'Default' ).', '.$DB->quote( '#999999' ).' )' );
		$default_goalcat_ID = $DB->insert_id;

		db_add_col( 'T_track__goal', 'goal_gcat_ID', 'int(10) unsigned NOT NULL DEFAULT "'.$default_goalcat_ID.'" AFTER goal_ID' );
		$DB->query( 'ALTER TABLE T_track__goal
			CHANGE goal_gcat_ID goal_gcat_ID int(10) unsigned NOT NULL' );
		task_end();

		// This task was not required, but we would like to make sure that we have future proof link_datecreated and link_datemodified fields.
		// There were previous versions, when these fields were set to '1970-01-01' because the $localtimenow was not initialized during the install script
		task_begin( 'Update links table...' );
		$DB->query( "UPDATE T_links SET link_datecreated = concat( '2000-01-01 ', time( link_datecreated ) )
						WHERE date( link_datecreated ) = '1970-01-01'" );
		$DB->query( "UPDATE T_links SET link_datemodified = concat( '2000-01-01 ', time( link_datemodified ) )
						WHERE date( link_datemodified ) = '1970-01-01'" );
		task_end();

		task_begin( 'Upgrading Blogs table...' );
		$DB->query( 'ALTER TABLE T_blogs CHANGE blog_description blog_shortdesc varchar(250) NULL default ""' );
		task_end();

		task_begin( 'Upgrading Comments table...' );
		$DB->query( 'ALTER TABLE T_comments
			CHANGE comment_post_ID   comment_item_ID        int(11) unsigned NOT NULL default 0,
			CHANGE comment_author_ID comment_author_user_ID int unsigned NULL default NULL');
		$DB->query( 'ALTER TABLE T_comments
			DROP INDEX comment_post_ID');
		$DB->query( 'ALTER TABLE T_comments
			ADD KEY comment_item_ID ( comment_item_ID )' );
		task_end();

		task_begin( 'Upgrading Files table...' );
		$DB->query( 'ALTER TABLE T_files
			ADD COLUMN file_path_hash char(32) default NULL' );
		// Use this query separately from above because MariaDB versions 10+ create an error:
		$DB->query( 'ALTER TABLE T_files
			DROP INDEX file' );
		// Change file path length to the max allowed value
		$DB->query( "ALTER TABLE T_files CHANGE COLUMN file_path file_path VARCHAR(767) NOT NULL DEFAULT ''" );
		$DB->query( 'UPDATE T_files SET file_path_hash = MD5( CONCAT( file_root_type, file_root_ID, file_path ) )');
		$DB->query( 'ALTER TABLE T_files ADD UNIQUE file_path (file_path_hash)' );
		task_end();

		task_begin( 'Create table for email campaigns... ' );
		db_create_table( 'T_email__campaign', '
			ecmp_ID          INT NOT NULL AUTO_INCREMENT,
			ecmp_date_ts     TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			ecmp_name        VARCHAR(255) NOT NULL,
			ecmp_email_title VARCHAR(255) NULL,
			ecmp_email_html  TEXT NULL,
			ecmp_email_text  TEXT NULL,
			ecmp_sent_ts     TIMESTAMP NULL,
			PRIMARY KEY      (ecmp_ID)',
			'ENGINE = myisam' );
		task_end();

		task_begin( 'Create table for email campaign send data... ' );
		db_create_table( 'T_email__campaign_send', '
			csnd_camp_ID  INT(11) UNSIGNED NOT NULL,
			csnd_user_ID  INT(11) UNSIGNED NOT NULL,
			csnd_emlog_ID INT(11) UNSIGNED NULL,
			PRIMARY KEY   csnd_PK ( csnd_camp_ID, csnd_user_ID )',
			'ENGINE = myisam' );
		task_end();

		task_begin( 'Rename table "email blocked" to "email address"... ' );
		$DB->query( 'RENAME TABLE '.$tableprefix.'email__blocked TO T_email__address' );
		$DB->query( "ALTER TABLE T_email__address
			CHANGE emblk_ID                    emadr_ID                    INT(10) UNSIGNED NOT NULL auto_increment,
			CHANGE emblk_address               emadr_address               VARCHAR(255) DEFAULT NULL,
			CHANGE emblk_status                emadr_status                ENUM ( 'unknown', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) NOT NULL DEFAULT 'unknown',
			CHANGE emblk_sent_count            emadr_sent_count            INT(10) UNSIGNED NOT NULL DEFAULT 0,
			CHANGE emblk_sent_last_returnerror emadr_sent_last_returnerror INT(10) UNSIGNED NOT NULL DEFAULT 0,
			CHANGE emblk_prmerror_count        emadr_prmerror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,
			CHANGE emblk_tmperror_count        emadr_tmperror_count        INT(10) UNSIGNED NOT NULL DEFAULT 0,
			CHANGE emblk_spamerror_count       emadr_spamerror_count       INT(10) UNSIGNED NOT NULL DEFAULT 0,
			CHANGE emblk_othererror_count      emadr_othererror_count      INT(10) UNSIGNED NOT NULL DEFAULT 0,
			CHANGE emblk_last_sent_ts          emadr_last_sent_ts          TIMESTAMP NULL,
			CHANGE emblk_last_error_ts         emadr_last_error_ts         TIMESTAMP NULL");
		$DB->query( "ALTER TABLE T_email__address
			ADD UNIQUE emadr_address ( emadr_address )" );
		$DB->query( "ALTER TABLE T_email__address
			DROP INDEX emblk_address");
		task_end();

		// Add new email status 'redemption'
		task_begin( 'Upgrading table of email addresses...' );
		$DB->query( "ALTER TABLE T_email__address
			CHANGE emadr_status   emadr_status ENUM ( 'unknown', 'redemption', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) NOT NULL DEFAULT 'unknown'" );
		task_end();

		task_begin( 'Upgrading blog-group permissions table...' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_can_be_assignee', 'tinyint NOT NULL default 0 AFTER bloggroup_ismember' );
		$DB->query( 'UPDATE T_coll_group_perms
			  SET bloggroup_can_be_assignee = 1
			WHERE bloggroup_group_ID IN ( 1, 2 )' );
		task_end();

		task_begin( 'Upgrading blog-user permissions table...' );
		db_add_col( 'T_coll_user_perms', 'bloguser_can_be_assignee', 'tinyint NOT NULL default 0 AFTER bloguser_ismember' );
		task_end();

		task_begin( 'Dropping obsolete columns from table Links...' );
		$DB->query( 'ALTER TABLE T_links
									DROP COLUMN link_external_url,
									DROP COLUMN link_title,
									DROP COLUMN link_dest_itm_ID' );
		task_end();

		// This task was added later to turn OFF smart view counting on upgrade from v5.0 to v5.1 for better performance
		task_begin( 'Turn off smart view counting...' );
		$DB->query( 'DELETE FROM T_settings WHERE set_name = '.$DB->quote( 'smart_view_count' ) );
		task_end();

		task_begin( 'Upgrading Posts table...' );
		db_drop_col( 'T_items__item', 'post_views' );
		task_end();

		task_begin( 'Upgrading Files table... ' );
		$DB->query( "ALTER TABLE T_files
			CHANGE COLUMN file_root_type file_root_type enum('absolute','user','collection','shared','skins','import') not null default 'absolute'" );
		task_end();

		// Set flag to recreate autogenerated excerpts due to modifications on the excerpt generation
		// Note: We need to generate this in the end of the upgrade script, because the database must be up to date
		$recreate_autogenerated_excerpts = true;

		set_upgrade_checkpoint( '11200' );
	}

	if( $old_db_version < 11208 )
	{ // part 15.a trunk aka second part of "i6"

		// Note create a separate block for the hitlog upgrade because it may require very long time
		task_begin( 'Upgrade hitlog table...' );
		$DB->query( 'ALTER TABLE T_hitlog
			CHANGE COLUMN hit_ID            hit_ID            INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			CHANGE COLUMN hit_datetime      hit_datetime      TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			CHANGE COLUMN hit_serprank      hit_serprank      SMALLINT UNSIGNED DEFAULT NULL,
			CHANGE COLUMN hit_blog_ID       hit_coll_ID       INT(10) UNSIGNED NULL DEFAULT NULL,
			CHANGE COLUMN hit_response_code hit_response_code SMALLINT DEFAULT NULL,
			ADD COLUMN hit_agent_ID SMALLINT UNSIGNED NULL DEFAULT NULL AFTER hit_agent_type' );
		$DB->query( 'ALTER TABLE T_hitlog
			DROP INDEX hit_blog_ID');
		$DB->query( 'ALTER TABLE T_hitlog
			ADD KEY hit_coll_ID ( hit_coll_ID )' );

		task_end();

		set_upgrade_checkpoint( '11208' );
	}

	if( $old_db_version < 11210 )
	{ // part 15.b trunk aka third part of "i6"

		task_begin( 'Updating widgets setting...' );
		// Unset those widgets allow blockcache value which current settings allow blockcache but the caching is always forbidden on runtime;
		$DB->query( 'UPDATE '.$tableprefix.'widget
				SET wi_params = REPLACE( wi_params, \'s:16:"allow_blockcache";i:1\', \'s:16:"allow_blockcache";i:0\' )
				WHERE wi_params LIKE \'%s:16:"allow_blockcache";i:1%\' AND (
					wi_code = "user_tools" OR wi_code = "user_login" OR ( wi_code = "msg_menu_link" AND wi_params LIKE \'%s:9:"link_type";s:8:"messages"%\' )
					OR ( wi_code = "menu_link" AND ( wi_params LIKE \'%s:9:"link_type";s:5:"login"%\' OR wi_params LIKE \'%s:9:"link_type";s:8:"register"%\' ) )
					)' );
		// Unset 'show_badge' setting in case of msg_menu_link widgets where the link_type is contacts
		$DB->query( 'UPDATE '.$tableprefix.'widget
				SET wi_params = REPLACE( wi_params, \'s:10:"show_badge";i:1\', \'s:10:"show_badge";i:0\' )
				WHERE wi_code = "msg_menu_link" AND wi_params LIKE \'%s:9:"link_type";s:8:"contacts"%\' AND wi_params LIKE \'%s:10:"show_badge";i:1%\'' );
		task_end();

		task_begin( 'Updating files hash values...' );
		$DB->query( 'ALTER TABLE T_files MODIFY COLUMN file_hash VARBINARY(32), MODIFY COLUMN file_path_hash VARBINARY(32)' );
		$DB->query( 'UPDATE T_files SET file_hash = UNHEX( file_hash ), file_path_hash = UNHEX( file_path_hash )' );
		$DB->query( 'ALTER TABLE T_files MODIFY COLUMN file_hash BINARY(16) default NULL, MODIFY COLUMN file_path_hash BINARY(16) default NULL' );
		task_end();

		task_begin( 'Upgrading goals table...' );
		$DB->query( 'ALTER TABLE T_track__goal
			ADD COLUMN goal_temp_redir_url varchar(255) default NULL AFTER goal_redir_url,
			ADD COLUMN goal_temp_start_ts  TIMESTAMP NULL            AFTER goal_temp_redir_url,
			ADD COLUMN goal_temp_end_ts    TIMESTAMP NULL            AFTER goal_temp_start_ts,
			ADD COLUMN goal_notes          TEXT DEFAULT NULL' );
		task_end();

		set_upgrade_checkpoint( '11210' );
	}

	if( $old_db_version < 11220 )
	{ // part 16.a trunk aka fourth part of "i6"
		task_begin( 'Upgrading countries table...' );
		$DB->query( 'ALTER TABLE T_regional__country
			ADD COLUMN ctry_status      enum( \'trusted\', \'suspect\', \'blocked\' ) NULL DEFAULT NULL,
			ADD COLUMN ctry_block_count int(10) unsigned DEFAULT 0' );
		task_end();

		set_upgrade_checkpoint( '11220' );
	}

	if( $old_db_version < 11240 )
	{ // part 16.d trunk aka seventh part of "i6"

		task_begin( 'Updating general settings...' );
		$DB->query( 'UPDATE T_settings SET
			set_name = CASE
				WHEN set_name = "user_closing_allow" THEN "account_close_enabled"
				WHEN set_name = "user_closing_intro" THEN "account_close_intro"
				WHEN set_name = "user_closing_reasons" THEN "account_close_reasons"
				WHEN set_name = "user_closing_byemsg" THEN "account_close_byemsg"
				ELSE set_name
			END' );
		task_end();

		set_upgrade_checkpoint( '11240' );
	}

	if( $old_db_version < 11245 )
	{ // part 16.e trunk aka eighth part of "i6"

		task_begin( 'Updating Antispam IP Ranges table...' );
		db_add_col( 'T_antispam__iprange', 'aipr_contact_email_count', 'int(10) unsigned DEFAULT 0 AFTER aipr_user_count' );
		task_end();

		task_begin( 'Updating invalid locale settings...' );
		$current_default_locale = $DB->get_var( 'SELECT set_value FROM T_settings WHERE set_name = "default_locale"' );
		if( empty( $current_default_locale ) )
		{ // The default locale is not set in the database, use the one from the config file
			global $default_locale;
			$current_default_locale = $default_locale;
		}
		if( $DB->get_var( 'SELECT loc_enabled FROM T_locales WHERE loc_locale = '.$DB->quote( $current_default_locale ) ) )
		{ // Update invalid user and collection locales to the default, but only if the default exists and it is enabled
			$DB->query( 'UPDATE T_users
				SET user_locale = '.$DB->quote( $current_default_locale ).'
				WHERE  user_locale NOT IN ( SELECT loc_locale FROM T_locales WHERE loc_enabled = 1 )'
			);
			$DB->query( 'UPDATE T_blogs
				SET blog_locale = '.$DB->quote( $current_default_locale ).'
				WHERE  blog_locale NOT IN ( SELECT loc_locale FROM T_locales WHERE loc_enabled = 1 )'
			);
		}
		task_end();

		set_upgrade_checkpoint( '11245' );
	}

	if( $old_db_version < 11250 )
	{ // part 16.f trunk aka ninth part of "i6"

		// Convert item content separators to new format
		load_funcs('tools/model/_maintenance.funcs.php');
		dbm_convert_item_content_separators();
		set_upgrade_checkpoint( '11250' );
	}

	if( $old_db_version < 11255 )
	{ // part 16.g trunk aka tenth part of "i6"

		task_begin( 'Updating post types...' );
		$DB->query( "INSERT INTO T_items__type ( ptyp_ID, ptyp_name )
			VALUES ( 1400, 'Intro-Front' )" );
		task_end();

		set_upgrade_checkpoint( '11255' );
	}

	if( $old_db_version < 11260 )
	{ // part 16.h trunk aka eleventh part of "i6"

		// This upgrade block updates all field collations from 'ascii_bin' to 'ascii_general_ci' except of slugs table.

		task_begin( 'Clean up comment emails...' );
		$DB->query( "UPDATE T_comments
						SET comment_author_email = CONVERT(comment_author_email USING ascii)" );
		$DB->commit();
		task_end();


		task_begin( 'Convert the field collations from ascii_bin to ascii_general_ci... <br />' );
		// fp> why would we need a transaction here?	$DB->begin();
		task_begin( '- Converting skins table...' );
		$DB->query( "ALTER TABLE T_skins__skin
			MODIFY skin_type enum('normal','feed','sitemap','mobile','tablet') COLLATE ascii_general_ci NOT NULL default 'normal'" );
		task_end();
		task_begin( '- Converting blogs table...' );
		$DB->query( "ALTER TABLE T_blogs
			MODIFY blog_access_type    VARCHAR(10) COLLATE ascii_general_ci NOT NULL DEFAULT 'extrapath',
			MODIFY blog_urlname        VARCHAR(255) COLLATE ascii_general_ci NOT NULL DEFAULT 'urlname',
			MODIFY blog_media_location ENUM( 'default', 'subdir', 'custom', 'none' ) COLLATE ascii_general_ci DEFAULT 'default' NOT NULL,
			MODIFY blog_type           ENUM( 'std', 'photo', 'group', 'forum', 'manual' ) COLLATE ascii_general_ci DEFAULT 'std' NOT NULL" );
		task_end();
		task_begin( '- Converting blog settings table...' );
		$DB->query( 'ALTER TABLE T_coll_settings
			MODIFY cset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL' );
		task_end();
		task_begin( '- Converting widgets table...' );
		$DB->query( "ALTER TABLE {$tableprefix}widget
			MODIFY wi_type ENUM( 'core', 'plugin' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'core',
			MODIFY wi_code VARCHAR(32) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting categories table...' );
		$DB->query( "ALTER TABLE T_categories
			MODIFY cat_urlname varchar(255) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting posts table...' );
		$DB->query( "ALTER TABLE T_items__item
			MODIFY post_status               enum('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NOT NULL default 'published',
			MODIFY post_urltitle             VARCHAR(210) COLLATE ascii_general_ci NOT NULL,
			MODIFY post_notifications_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq',
			MODIFY post_comment_status       ENUM('disabled', 'open', 'closed') COLLATE ascii_general_ci NOT NULL DEFAULT 'open',
			MODIFY post_renderers            TEXT COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting comments table...' );
		$DB->query( "ALTER TABLE T_comments
			MODIFY comment_type         enum('comment','linkback','trackback','pingback') COLLATE ascii_general_ci NOT NULL default 'comment',
			MODIFY comment_status       ENUM('published','community','deprecated','protected','private','review','draft','trash') COLLATE ascii_general_ci DEFAULT 'published' NOT NULL,
			MODIFY comment_author_email varchar(255) COLLATE ascii_general_ci NULL,
			MODIFY comment_author_IP    varchar(23) COLLATE ascii_general_ci NOT NULL default '',
			MODIFY comment_renderers    TEXT COLLATE ascii_general_ci NOT NULL,
			MODIFY comment_secret       CHAR(32) COLLATE ascii_general_ci NULL default NULL,
			MODIFY comment_notif_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq' COMMENT 'Have notifications been sent for this comment? How far are we in the process?'" );
		task_end();
		task_begin( '- Converting post prerendered contents table...' );
		$DB->query( "ALTER TABLE T_items__prerendering
			MODIFY itpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,
			MODIFY itpr_renderers TEXT COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting comment prerendered contents table...' );
		$DB->query( "ALTER TABLE T_comments__prerendering
			MODIFY cmpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,
			MODIFY cmpr_renderers TEXT COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting post versions table...' );
		$DB->query( "ALTER TABLE T_items__version
			MODIFY iver_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NULL" );
		task_end();
		task_begin( '- Converting post settings table...' );
		$DB->query( "ALTER TABLE T_items__item_settings
			MODIFY iset_name varchar( 50 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting user permissions table...' );
		$DB->query( "ALTER TABLE T_coll_user_perms
			MODIFY bloguser_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloguser_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',
			MODIFY bloguser_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloguser_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'" );
		task_end();
		task_begin( '- Converting group permissions table...' );
		$DB->query( "ALTER TABLE T_coll_group_perms
			MODIFY bloggroup_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloggroup_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',
			MODIFY bloggroup_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloggroup_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'" );
		task_end();
		task_begin( '- Converting links table...' );
		$DB->query( "ALTER TABLE T_links
			MODIFY link_position varchar(10) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting files table...' );
		$DB->query( "ALTER TABLE T_files
			MODIFY file_root_type enum('absolute','user','collection','shared','skins','import') COLLATE ascii_general_ci NOT NULL DEFAULT 'absolute'" );
		task_end();
		task_begin( '- Converting file types table...' );
		$DB->query( "ALTER TABLE T_filetypes
			MODIFY ftyp_extensions varchar(30) COLLATE ascii_general_ci NOT NULL,
			MODIFY ftyp_viewtype   varchar(10) COLLATE ascii_general_ci NOT NULL,
			MODIFY ftyp_allowed    enum('any','registered','admin') COLLATE ascii_general_ci NOT NULL default 'admin'" );
		task_end();
		task_begin( '- Converting sessions table...' );
		$DB->query( "ALTER TABLE T_sessions
			MODIFY sess_key       CHAR(32) COLLATE ascii_general_ci NULL,
			MODIFY sess_ipaddress VARCHAR(39) COLLATE ascii_general_ci NOT NULL DEFAULT '',
			MODIFY sess_device    VARCHAR(8) COLLATE ascii_general_ci NOT NULL DEFAULT ''" );
		task_end();
		task_begin( '- Converting domains table...' );
		$DB->query( "ALTER TABLE T_basedomains
			MODIFY dom_status ENUM('unknown','trusted','suspect','blocked') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown',
			MODIFY dom_type   ENUM('unknown','normal','searcheng','aggregator','email') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'" );
		task_end();
		task_begin( '- Converting logs table...' );
		$DB->query( "ALTER TABLE T_hitlog
			MODIFY hit_ctrl         VARCHAR(30) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY hit_type         ENUM('standard','rss','admin','ajax', 'service') COLLATE ascii_general_ci DEFAULT 'standard' NOT NULL,
			MODIFY hit_referer_type ENUM('search','special','spam','referer','direct','self') COLLATE ascii_general_ci NOT NULL,
			MODIFY hit_remote_addr  VARCHAR(40) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY hit_agent_type   ENUM('robot','browser','unknown') COLLATE ascii_general_ci DEFAULT 'unknown' NOT NULL" );
		task_end();
		task_begin( '- Converting goal categories table...' );
		$DB->query( "ALTER TABLE T_track__goalcat
			MODIFY gcat_color  char(7) COLLATE ascii_general_ci default NULL" );
		task_end();
		task_begin( '- Converting groups table...' );
		$DB->query( "ALTER TABLE T_groups
			MODIFY grp_perm_blogs                  enum('user','viewall','editall') COLLATE ascii_general_ci NOT NULL default 'user',
			MODIFY grp_perm_xhtmlvalidation        VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',
			MODIFY grp_perm_xhtmlvalidation_xmlrpc VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',
			MODIFY grp_perm_stats                  enum('none','user','view','edit') COLLATE ascii_general_ci NOT NULL default 'none'" );
		task_end();
		task_begin( '- Converting group settings table...' );
		$DB->query( "ALTER TABLE T_groups__groupsettings
			MODIFY gset_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting settings table...' );
		$DB->query( "ALTER TABLE T_settings
			MODIFY set_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting cache table...' );
		$DB->query( "ALTER TABLE T_global__cache
			MODIFY cach_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting users table...' );
		$DB->query( "ALTER TABLE T_users
			MODIFY user_email           varchar(255) COLLATE ascii_general_ci NOT NULL,
			MODIFY user_status          enum( 'activated', 'autoactivated', 'closed', 'deactivated', 'emailchanged', 'failedactivation', 'new' ) COLLATE ascii_general_ci NOT NULL default 'new',
			MODIFY user_unsubscribe_key CHAR(32) COLLATE ascii_general_ci NOT NULL default '' COMMENT 'A specific key, it is used when a user wants to unsubscribe from a post comments without signing in',
			MODIFY user_gender          char(1) COLLATE ascii_general_ci NULL" );
		task_end();
		task_begin( '- Converting user fields table...' );
		$DB->query( "ALTER TABLE T_users__fielddefs
			MODIFY ufdf_type       char(8) COLLATE ascii_general_ci NOT NULL,
			MODIFY ufdf_required   enum('hidden','optional','recommended','require') COLLATE ascii_general_ci NOT NULL default 'optional',
			MODIFY ufdf_duplicated enum('forbidden','allowed','list') COLLATE ascii_general_ci NOT NULL default 'allowed'" );
		task_end();
		task_begin( '- Converting user reports table...' );
		$DB->query( "ALTER TABLE T_users__reports
			MODIFY urep_status enum( 'fake', 'guidelines', 'harass', 'spam', 'other' ) COLLATE ascii_general_ci" );
		task_end();
		task_begin( '- Converting locales table...' );
		$DB->query( "ALTER TABLE T_locales
			MODIFY loc_charset varchar(15) COLLATE ascii_general_ci NOT NULL default 'iso-8859-1',
			MODIFY loc_datefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'y-m-d',
			MODIFY loc_timefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'H:i:s'" );
		task_end();
		task_begin( '- Converting antispam table...' );
		$DB->query( "ALTER TABLE {$tableprefix}antispam
			MODIFY aspm_source enum( 'local','reported','central' ) COLLATE ascii_general_ci NOT NULL default 'reported'" );
		task_end();
		task_begin( '- Converting IP ranges table...' );
		$DB->query( "ALTER TABLE T_antispam__iprange
			MODIFY aipr_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL" );
		task_end();
		task_begin( '- Converting user settings table...' );
		$DB->query( "ALTER TABLE T_users__usersettings
			MODIFY uset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugins table...' );
		$DB->query( "ALTER TABLE T_plugins
			MODIFY plug_classname VARCHAR(40) COLLATE ascii_general_ci NOT NULL default '',
			MODIFY plug_code      VARCHAR(32) COLLATE ascii_general_ci NULL,
			MODIFY plug_version   VARCHAR(42) COLLATE ascii_general_ci NOT NULL default '0',
			MODIFY plug_status    ENUM( 'enabled', 'disabled', 'needs_config', 'broken' ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugin settings table...' );
		$DB->query( "ALTER TABLE T_pluginsettings
			MODIFY pset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugin user settings table...' );
		$DB->query( "ALTER TABLE T_pluginusersettings
			MODIFY puset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugin events table...' );
		$DB->query( "ALTER TABLE T_pluginevents
			MODIFY pevt_event VARCHAR(40) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting cron logs table...' );
		$DB->query( "ALTER TABLE T_cron__log
			MODIFY clog_status enum('started','finished','error','timeout') COLLATE ascii_general_ci not null default 'started'" );
		task_end();
		task_begin( '- Converting countries table...' );
		$DB->query( "ALTER TABLE T_regional__country
			MODIFY ctry_code   char(2) COLLATE ascii_general_ci NOT NULL,
			MODIFY ctry_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL" );
		task_end();
		task_begin( '- Converting regions table...' );
		$DB->query( "ALTER TABLE T_regional__region
			MODIFY rgn_code char(6) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting subregions table...' );
		$DB->query( "ALTER TABLE T_regional__subregion
			MODIFY subrg_code char(6) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting cities table...' );
		$DB->query( "ALTER TABLE T_regional__city
			MODIFY city_postcode char(12) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting currencies table...' );
		$DB->query( "ALTER TABLE T_regional__currency
			MODIFY curr_code char(3) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting email logs table...' );
		$DB->query( "ALTER TABLE T_email__log
			MODIFY emlog_to     VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY emlog_result ENUM( 'ok', 'error', 'blocked' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'ok'" );
		task_end();
		task_begin( '- Converting email returns table...' );
		$DB->query( "ALTER TABLE T_email__returns
			MODIFY emret_address   VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY emret_errtype   CHAR(1) COLLATE ascii_general_ci NOT NULL DEFAULT 'U'" );
		task_end();
		task_begin( '- Converting email addresses table...' );
		$DB->query( "ALTER TABLE T_email__address
			MODIFY emadr_address VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY emadr_status  ENUM( 'unknown', 'redemption', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'" );
		task_end();
		//	$DB->commit();
		task_end();

		set_upgrade_checkpoint( '11260' );
	}

	if( $old_db_version < 11270 )
	{ // part 16.i trunk aka 12th part of "i6"

		// IPv4 mapped IPv6 addresses maximum length is 45 chars: ex. ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190
		task_begin( 'Upgrading comments table...' );
		$DB->query( "ALTER TABLE T_comments
			MODIFY comment_author_IP varchar(45) COLLATE ascii_general_ci NOT NULL default ''" );
		task_end();
		task_begin( 'Upgrading sessions table...' );
		$DB->query( "ALTER TABLE T_sessions
			MODIFY sess_ipaddress VARCHAR(45) COLLATE ascii_general_ci NOT NULL DEFAULT ''" );
		task_end();

		set_upgrade_checkpoint( '11270' );
	}

	if( $old_db_version < 11280 )
	{ // part 16.j trunk aka 12th part of "i6"

		task_begin( 'Upgrading hit logs table...' );
		$DB->query( "ALTER TABLE T_hitlog
			MODIFY hit_remote_addr VARCHAR(45) COLLATE ascii_general_ci DEFAULT NULL" );
		task_end();

		task_begin( 'Upgrading blogs table...' );
		db_drop_col( 'T_blogs', 'blog_UID' );
		task_end();

		set_upgrade_checkpoint( '11280' );
	}

	if( $old_db_version < 11285 )
	{ // part 16.k trunk aka 13th part of "i6"

		task_begin( 'Updating plugins table...' );
		$DB->query( 'UPDATE T_plugins SET
			plug_code = CASE
				WHEN plug_classname = "generic_ping_plugin"         THEN "b2evGPing"
				WHEN plug_classname = "basic_antispam_plugin"       THEN "b2evBAspm"
				WHEN plug_classname = "flowplayer_plugin"           THEN "b2evFlwP"
				WHEN plug_classname = "html5_mediaelementjs_plugin" THEN "b2evH5MP"
				WHEN plug_classname = "html5_videojs_plugin"        THEN "b2evH5VJSP"
				ELSE plug_code
			END' );
		task_end();

		set_upgrade_checkpoint( '11285' );
	}

	if( $old_db_version < 11286 )
	{	// part 16.l trunk aka 14th part of "i6"

		task_begin( 'Upgrade timestamp fields... ' );
		$DB->query( 'ALTER TABLE T_email__log
			MODIFY emlog_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_email__returns
			MODIFY emret_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_items__prerendering
			MODIFY itpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_comments__prerendering
			MODIFY cmpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_users__reports
			MODIFY urep_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_items__version
			MODIFY iver_edit_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__thread
			MODIFY thrd_datemodified datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__message
			MODIFY msg_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__contact
			MODIFY mct_last_contact_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		task_end();

		set_upgrade_checkpoint( '11286' );
	}

	if( $old_db_version < 11300 )
	{ // part 17 trunk aka "i7"

		task_begin( 'Upgrading locales table...' );
		db_add_col( 'T_locales', 'loc_shorttimefmt', 'varchar(20) COLLATE ascii_general_ci NOT NULL default "H:i" AFTER loc_timefmt' );
		task_end();
		task_begin( 'Creating message prerendering cache table... ' );
		db_create_table( 'T_messaging__prerendering', '
			mspr_msg_ID              INT(11) UNSIGNED NOT NULL,
			mspr_format              ENUM("htmlbody","entityencoded","xml","text") COLLATE ascii_general_ci NOT NULL,
			mspr_renderers           TEXT NOT NULL,
			mspr_content_prerendered MEDIUMTEXT NULL,
			mspr_datemodified        TIMESTAMP NOT NULL,
			PRIMARY KEY (mspr_msg_ID, mspr_format)' );
		db_add_col( 'T_messaging__message', 'msg_renderers', 'TEXT NOT NULL' );
		$DB->query( 'UPDATE T_messaging__message SET msg_renderers = "default"' );
		task_end();

		task_begin( 'Upgrading categories table...' );
		db_add_col( 'T_categories', 'cat_last_touched_ts', "TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'" );
		$DB->query( 'UPDATE T_categories SET cat_last_touched_ts = (
			SELECT post_last_touched_ts
			  FROM T_items__item
			       INNER JOIN T_postcats ON postcat_post_ID = post_ID
			 WHERE postcat_cat_ID = cat_ID
			 ORDER BY post_last_touched_ts DESC
			 LIMIT 1 )' );
		task_end();

		task_begin( 'Create table for User post read status... ' );
		db_create_table( $tableprefix.'users__postreadstatus', '
			uprs_user_ID int(11) unsigned NOT NULL,
			uprs_post_ID int(11) unsigned NOT NULL,
			uprs_read_post_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			uprs_read_comment_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			PRIMARY KEY ( uprs_user_ID, uprs_post_ID )' );
		task_end();

		task_begin( 'Create table for System log... ' );
		db_create_table( 'T_syslog', "
			slg_ID        INT NOT NULL AUTO_INCREMENT,
			slg_timestamp TIMESTAMP NOT NULL,
			slg_origin    ENUM('core', 'plugin') COLLATE ascii_general_ci,
			slg_origin_ID INT UNSIGNED NULL,
			slg_object    ENUM('comment', 'item', 'user') COLLATE ascii_general_ci,
			slg_object_ID INT UNSIGNED NOT NULL,
			slg_message   VARCHAR(255) NOT NULL,
			PRIMARY KEY   (slg_ID),
			INDEX         slg_object (slg_object, slg_object_ID)",
			'ENGINE = myisam' );
		task_end();

		set_upgrade_checkpoint( '11300' );
	}

	if( $old_db_version < 11310 )
	{ // part 18 trunk aka second part of "i7"

		task_begin( 'Upgrading cron tasks table...' );
		load_funcs( 'cron/_cron.funcs.php' );
		$DB->begin();
		$DB->query( 'ALTER TABLE T_cron__task
			CHANGE COLUMN ctsk_controller ctsk_key varchar(50) COLLATE ascii_general_ci NOT NULL AFTER ctsk_repeat_after,
			CHANGE COLUMN ctsk_name ctsk_name varchar(255) null COMMENT "Specific name of this task. This value is set only if this job name was modified by an admin user"' );
		// Update keys from controllers
		// Important: Cron job sql query result must be converted to ascii charset since the ctsk_key is already ascii( ascii_bin collation )
		$DB->query( 'UPDATE T_cron__task
			INNER JOIN ( '.cron_job_sql_query( 'key,ctrl' ).' ) AS temp
			       ON ctsk_key = CONVERT( temp.task_ctrl USING ascii )
			SET ctsk_key = temp.task_key' );
		// Reset names to NULL if its are default
		$DB->query( $sql = 'UPDATE T_cron__task
			INNER JOIN ( '.cron_job_sql_query().' ) AS temp
			        ON ctsk_key = CONVERT( temp.task_key USING ascii ) AND ctsk_name = CONVERT( temp.task_name USING '.$DB->get_connection_charset().' )
			SET ctsk_name = NULL' );
		$DB->commit();
		task_end();

		task_begin( 'Upgrade table system log... ' );
		$DB->query( 'ALTER TABLE T_syslog
			CHANGE COLUMN slg_object slg_object ENUM(\'comment\', \'item\', \'user\', \'file\') COLLATE ascii_general_ci,
			CHANGE COLUMN slg_object_ID slg_object_ID INT UNSIGNED NULL,
			ADD    COLUMN slg_user_ID INT UNSIGNED NULL AFTER slg_timestamp,
			ADD    COLUMN slg_type ENUM(\'info\', \'warning\', \'error\', \'critical_error\') COLLATE ascii_general_ci NOT NULL DEFAULT \'info\' AFTER slg_user_ID' );
		task_end();

		task_begin( 'Upgrade groups table... ' );
		db_add_col( 'T_groups', 'grp_level', 'int unsigned DEFAULT 0 NOT NULL AFTER grp_name' );
		$default_groups_levels = array(
				'Administrators' => 10,
				'Moderators' => 8,
				'Trusted Users' => 6,
				'Normal Users' => 4,
				'Misbehaving/Suspect Users' => 2,
				'Spammers/Restricted Users' => 1
			);
		// Build sql query to update group level depending on name
		$group_level_query = 'SELECT group_name, group_level FROM (';
		$first_task = true;
		foreach( $default_groups_levels as $def_group_name => $def_group_level )
		{
			if( $first_task )
			{
				$group_level_query .= 'SELECT '.$DB->quote( $def_group_name ).' AS group_name, '.$DB->quote( $def_group_level ).' AS group_level';
				$first_task = false;
			}
			else
			{
				$group_level_query .= ' UNION SELECT '.$DB->quote( $def_group_name ).', '.$DB->quote( $def_group_level );
			}
		}
		$group_level_query .= ') AS inner_temp';
		// Set default levels depending on name
		$DB->query( 'UPDATE T_groups
			INNER JOIN ( '.$group_level_query.' ) AS temp
			       ON grp_name = CONVERT( temp.group_name USING '.$DB->get_connection_charset().' )
			  SET grp_level = temp.group_level' );
		// Set default '4' level for all other groups
		$DB->query( 'UPDATE T_groups
			  SET grp_level = 4
			WHERE grp_level = 0' );
		// Set default user permissions for Moderators group
		$DB->query( 'UPDATE T_groups__groupsettings
			  SET gset_value = "moderate"
			WHERE gset_name = "perm_users"
			  AND gset_grp_ID = (SELECT grp_ID FROM T_groups WHERE grp_name = "Moderators")' );
		task_end();

		task_begin( 'Updating general settings...' );
		$DB->query( 'UPDATE T_settings
				SET set_value = '.$DB->quote( 'yes' ).'
			WHERE set_name = '.$DB->quote( 'newusers_canregister' ).'
				AND set_value = '.$DB->quote( '1' ) );
		task_end();

		task_begin( 'Creating table for User invitation codes... ' );
		db_create_table( 'T_users__invitation_code', '
			ivc_ID        int(11) unsigned NOT NULL auto_increment,
			ivc_code      varchar(32) COLLATE ascii_general_ci NOT NULL,
			ivc_expire_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			ivc_source    varchar(30) NULL,
			ivc_grp_ID    int(4) NOT NULL,
			PRIMARY KEY ( ivc_ID ),
			UNIQUE ivc_code ( ivc_code )' );
		task_end();

		task_begin( 'Creating table for User organizations... ' );
		db_create_table( 'T_users__organization', '
			org_ID   INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			org_name VARCHAR(255) NOT NULL,
			org_url  VARCHAR(2000) NULL,
			PRIMARY KEY ( org_ID ),
			UNIQUE org_name ( org_name )' );
		task_end();

		task_begin( 'Creating table for relations users with organizations... ' );
		db_create_table( 'T_users__user_org', '
			uorg_user_ID  INT(11) UNSIGNED NOT NULL,
			uorg_org_ID   INT(11) UNSIGNED NOT NULL,
			uorg_accepted TINYINT(1) DEFAULT 0,
			PRIMARY KEY ( uorg_user_ID, uorg_org_ID )' );
		task_end();

		// Rename item settings:
		//   "post_custom_headers" to "metakeywords"
		//   "post_metadesc" to "metadesc"
		//   "post_expiry_delay" to "comment_expiry_delay"
		task_begin( 'Upgrading Item Settings...' );
		$DB->query( 'UPDATE T_items__item_settings
				  SET iset_name = "metakeywords"
				WHERE iset_name = "post_custom_headers"' );
		$DB->query( 'UPDATE T_items__item_settings
				  SET iset_name = "metadesc"
				WHERE iset_name = "post_metadesc"' );
		$DB->query( 'UPDATE T_items__item_settings
				  SET iset_name = "comment_expiry_delay"
				WHERE iset_name = "post_expiry_delay"' );
		task_end();

		task_begin( 'Upgrade table files... ' );
		db_add_col( 'T_files', 'file_type', "enum('image', 'audio', 'other') COLLATE ascii_general_ci NULL DEFAULT NULL AFTER file_ID" );
		task_end();

		task_begin( 'Upgrade table posts... ' );
		$DB->query( 'ALTER TABLE T_items__item
			CHANGE post_title     post_title     VARCHAR(255) NOT NULL,
			CHANGE post_renderers post_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL' );
		task_end();

		task_begin( 'Upgrade table post prerendering cache... ' );
		$DB->query( 'ALTER TABLE T_items__prerendering
			CHANGE itpr_renderers itpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL' );
		task_end();

		task_begin( 'Upgrade table post versions... ' );
		$DB->query( 'ALTER TABLE T_items__version
			CHANGE iver_title iver_title VARCHAR(255) NULL' );
		task_end();

		task_begin( 'Upgrade table comments... ' );
		$DB->query( 'ALTER TABLE T_comments
			CHANGE comment_renderers comment_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL' );
		task_end();

		task_begin( 'Upgrade table comment prerendering cache... ' );
		$DB->query( 'ALTER TABLE T_comments__prerendering
			CHANGE cmpr_renderers cmpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL' );
		task_end();

		task_begin( 'Upgrade table messages... ' );
		$DB->query( 'ALTER TABLE T_messaging__message
			CHANGE msg_renderers msg_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL' );
		task_end();

		task_begin( 'Upgrade table message prerendering cache... ' );
		$DB->query( 'ALTER TABLE T_messaging__prerendering
			CHANGE mspr_renderers mspr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL' );
		task_end();

		task_begin( 'Upgrade table user field definitions... ' );
		$DB->query( 'ALTER TABLE T_users__fielddefs
			CHANGE ufdf_options ufdf_options VARCHAR(255) NULL DEFAULT NULL' );
		// Change emtpy ufdf_options to NULL, since it must/may be defined only in case of the list ufdf_type
		$DB->query( 'UPDATE T_users__fielddefs
			SET ufdf_options = NULL
			WHERE ufdf_options = "" AND ufdf_type != "list"');
		task_end();

		task_begin( 'Upgrade table cron tasks... ' );
		$DB->query( 'ALTER TABLE T_cron__task
			CHANGE ctsk_params ctsk_params varchar(255)' );
		task_end();

		task_begin( 'Upgrading users table...' );
		db_add_col( 'T_users', 'user_salt', 'CHAR(8) NOT NULL default "" AFTER user_pass' );
		task_end();

		task_begin( 'Updating users pass storage...' );
		$DB->query( 'ALTER TABLE T_users MODIFY COLUMN user_pass VARBINARY(32)' );
		$DB->query( 'UPDATE T_users SET user_pass = UNHEX( user_pass )' );
		$DB->query( 'ALTER TABLE T_users MODIFY COLUMN user_pass BINARY(16) NOT NULL' );
		task_end();

		set_upgrade_checkpoint( '11310' );
	}

	if( $old_db_version < 11320 )
	{ // part 18.a trunk aka third part of "i7"

		task_begin( 'Update locales to utf-8 charset...' );
		db_drop_col( 'T_locales', 'loc_charset' );
		$DB->query( 'UPDATE T_locales
			SET loc_name = REPLACE( loc_name, "latin1", "utf8" )
			WHERE loc_locale IN ( "en-US", "en-AU", "en-CA", "en-GB", "en-IL", "en-NZ", "en-SG" )' );
		$DB->query( 'UPDATE T_users SET user_locale = "en-US" WHERE user_locale = "en-US-utf8"' );
		$DB->query( 'UPDATE T_blogs SET blog_locale = "en-US" WHERE blog_locale = "en-US-utf8"' );
		$DB->query( 'UPDATE T_items__item SET post_locale = "en-US" WHERE post_locale = "en-US-utf8"' );
		$DB->query( 'UPDATE T_settings SET set_value = "en-US" WHERE set_name = "default_locale" AND set_value = "en-US-utf8"' );
		// Check if the 'en-US-utf8' locale is enabled
		$en_us_utf8_enabled = $DB->get_var( 'SELECT loc_enabled FROM T_locales WHERE loc_locale = "en-US-utf8"' );
		if( $en_us_utf8_enabled !== NULL )
		{ // The 'en-US-utf8' was enabled we must enable the 'en-US' even if it was not enabled before because we merged the two locales into one
			$en_us_enabled = $DB->get_var( 'SELECT loc_enabled FROM T_locales WHERE loc_locale = "en-US"' );
			if( $en_us_enabled === NULL )
			{ // Update "en-US-utf8" to "en-US"
				$DB->query( 'UPDATE T_locales SET loc_locale = "en-US" WHERE loc_locale = "en-US-utf8"' );
			}
			elseif( $en_us_utf8_enabled && ( ! $en_us_enabled ) )
			{ // Enable the "en-US" locale because it was not enabled but the "en-US-utf8" was
				$DB->query( 'UPDATE T_locales SET loc_enabled = 1 WHERE loc_locale = "en-US"' );
			}

			if( $en_us_enabled !== NULL )
			{ // Remove the "en-US-utf8" locale if the "en_US" locale is already in the database
				$DB->query( 'DELETE FROM T_locales WHERE loc_locale = "en-US-utf8"' );
			}
		}
		task_end();

		task_begin( 'Upgrade table files... ' );
		db_add_col( 'T_files', 'file_can_be_main_profile', 'TINYINT(1) NOT NULL DEFAULT 1' );
		task_end();

		task_begin( 'Add new video file types... ' );
		$video_types = array(
				'webm' => "( 'webm', 'WebM video file', 'video/webm', 'file_video', 'browser', 'registered' )",
				'ogv'  => "( 'ogv', 'Ogg video file', 'video/ogg', 'file_video', 'browser', 'registered' )",
				'm3u8' => "( 'm3u8', 'M3U8 video file', 'application/x-mpegurl', 'file_video', 'browser', 'registered' )"
			);
		$SQL = new SQL();
		$SQL->SELECT( 'ftyp_extensions' );
		$SQL->FROM( 'T_filetypes' );
		$SQL->WHERE( 'ftyp_extensions LIKE "%'.implode( '%" OR ftyp_extensions LIKE "%', array_keys( $video_types ) ).'%"' );
		$existing_video_types = $DB->get_col( $SQL->get() );
		if( ! empty( $existing_video_types ) )
		{ // Some video types arleady exist in DB, Exclude them from inserting
			foreach( $existing_video_types as $vtype )
			{
				unset( $video_types[ $vtype ] );
			}
		}
		if( count( $video_types ) )
		{ // Insert new video file types
			$DB->query( "INSERT INTO T_filetypes
				( ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed )
				VALUES ".implode( ', ', $video_types ) );
		}
		task_end();

		set_upgrade_checkpoint( '11320' );
	}

	if( $old_db_version < 11330 )
	{ // part 18.b trunk aka 4th part of "i7"

		task_begin( 'Upgrade table blogs... ' );
		$DB->query( 'UPDATE T_blogs
			  SET blog_in_bloglist = "1"
			WHERE blog_in_bloglist > 0' );
		$DB->query( 'ALTER TABLE T_blogs
			CHANGE blog_in_bloglist blog_in_bloglist ENUM( "public", "logged", "member", "never" ) COLLATE ascii_general_ci DEFAULT "public" NOT NULL' );
		$DB->query( 'UPDATE T_blogs
			  SET blog_in_bloglist = "never"
			WHERE blog_in_bloglist = ""' );
		task_end();

		set_upgrade_checkpoint( '11330' );
	}

	if( $old_db_version < 11340 )
	{ // part 18.c trunk aka 5th part of "i7"

		task_begin( 'Upgrading blogs table...' );
		$DB->query( "ALTER TABLE T_blogs
			MODIFY blog_type ENUM( 'main', 'std', 'photo', 'group', 'forum', 'manual' ) COLLATE ascii_general_ci DEFAULT 'std' NOT NULL" );
		task_end();

		set_upgrade_checkpoint( '11340' );
	}

	if( $old_db_version < 11350 )
	{ // part 18.d trunk aka 6th part of "i7"

		task_begin( 'Update category ordering...' );
		$DB->query( 'REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
				SELECT blog_ID, "category_ordering", IFNULL( set_value, "alpha" )
				FROM T_blogs LEFT JOIN T_settings ON set_name = "chapter_ordering"' );
		$DB->query( 'DELETE FROM T_settings WHERE set_name = "chapter_ordering"');
		db_add_col( 'T_categories', 'cat_subcat_ordering', "enum('parent', 'alpha', 'manual') COLLATE ascii_general_ci NULL DEFAULT NULL AFTER cat_order" );
		task_end();

		set_upgrade_checkpoint( '11350' );
	}

	if( $old_db_version < 11360 )
	{ // part 18.e trunk aka 7th part of "i7"

		task_begin( 'Upgrade table posts... ' );
		$DB->query( 'ALTER TABLE T_items__item
            CHANGE post_ptyp_ID post_ityp_ID int(10) unsigned NOT NULL DEFAULT 1');
        $DB->query( 'ALTER TABLE T_items__item
            DROP INDEX post_ptyp_ID');
		$DB->query( 'ALTER TABLE T_items__item
            ADD INDEX post_ityp_ID ( post_ityp_ID )');
		task_end();

		task_begin( 'Upgrade table post types... ' );
		$DB->query( "ALTER TABLE T_items__type
			CHANGE ptyp_ID   ityp_ID   INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			CHANGE ptyp_name ityp_name VARCHAR(30) NOT NULL,
			ADD ityp_description       TEXT NULL DEFAULT NULL,
			ADD ityp_backoffice_tab    VARCHAR(30) NULL DEFAULT NULL,
			ADD ityp_template_name     VARCHAR(40) NULL DEFAULT NULL,
			ADD ityp_use_title         ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'required',
			ADD ityp_use_url           ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_use_text          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_allow_html        TINYINT DEFAULT 1,
			ADD ityp_allow_attachments TINYINT DEFAULT 1,
			ADD ityp_use_excerpt       ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_use_title_tag     ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_use_meta_desc     ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_use_meta_keywds   ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_use_tags          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			ADD ityp_allow_featured    TINYINT DEFAULT 1,
			ADD ityp_use_country       ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			ADD ityp_use_region        ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			ADD ityp_use_sub_region    ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			ADD ityp_use_city          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			ADD ityp_use_coordinates   ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			ADD ityp_use_custom_fields TINYINT DEFAULT 1,
			ADD ityp_use_comments      TINYINT DEFAULT 1,
			ADD ityp_allow_closing_comments   TINYINT DEFAULT 1,
			ADD ityp_allow_disabling_comments TINYINT DEFAULT 0,
			ADD ityp_use_comment_expiration   ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional'" );
		$DB->query( 'UPDATE T_items__type SET
			ityp_backoffice_tab = CASE
				WHEN ityp_ID = 1    THEN "Posts"
				WHEN ityp_ID = 1000 THEN "Pages"
				WHEN ityp_ID >= 1400 AND ityp_ID <= 1600 THEN "Intros"
				WHEN ityp_ID = 2000 THEN "Podcasts"
				WHEN ityp_ID = 3000 THEN "Sidebar links"
				WHEN ityp_ID = 4000 THEN "Advertisement"
				WHEN ityp_ID = 5000 THEN NULL
				ELSE "Posts"
			END,
			ityp_template_name = CASE
				WHEN ityp_ID = 1 OR ityp_ID = 2000 THEN "single"
				WHEN ityp_ID = 1000 THEN "page"
				ELSE NULL
			END' );
		task_end();

		task_begin( 'Adding new post types...' );
		$DB->begin();
		$new_item_types = array(
				/* 'blog type' => array( 'min post type ID', 'title for new type' ) */
				'manual' => array( 'type_ID' => 100, 'title' => 'Manual Page' ),
				'forum'  => array( 'type_ID' => 200, 'title' => 'Forum Topic' ),
			);
		$item_types_insert_data = array();
		foreach( $new_item_types as $blog_type => $item_type_data )
		{
			$item_type_ID = $new_item_types[ $blog_type ]['type_ID'];
			while( $item_type_ID !== NULL )
			{ // Find first free post type ID starting with 100
				$free_item_type_ID = $item_type_ID;
				$item_type_ID = $DB->get_var( 'SELECT ityp_ID FROM T_items__type WHERE ityp_ID = '.$DB->quote( $item_type_ID ) );
				if( $item_type_ID === NULL )
				{ // Use this free ID for new type
					$item_types_insert_data[] = '( '.$free_item_type_ID.', '.$DB->quote( $new_item_types[ $blog_type ]['title'] ).', "Posts", "single", 0 )';
					$new_item_types[ $blog_type ]['new_type_ID'] = $free_item_type_ID;
					break;
				}
				$item_type_ID++;
			}
		}
		if( count( $item_types_insert_data ) )
		{
			// Insert new post types
			$DB->query( 'INSERT INTO T_items__type ( ityp_ID, ityp_name, ityp_backoffice_tab, ityp_template_name, ityp_allow_html )
						VALUES '.implode( ', ', $item_types_insert_data ) );
			// Update types of all post with "Post" type to new created (only for blogs with type 'forum' and 'manual')
			foreach( $new_item_types as $blog_type => $item_type_data )
			{
				$DB->query( 'UPDATE T_items__item
					INNER JOIN T_categories
					   ON post_main_cat_ID = cat_ID
					  AND post_ityp_ID = 1
					INNER JOIN T_blogs
					   ON cat_blog_ID = blog_ID
					  AND blog_type = '.$DB->quote( $blog_type ).'
					  SET post_ityp_ID = '.$DB->quote( $item_type_data['new_type_ID'] ) );
			}
		}
		$DB->commit();
		task_end();

		task_begin( 'Upgrade table comments... ' );
		$DB->query( "ALTER TABLE T_comments
			CHANGE comment_type comment_type enum('comment','linkback','trackback','pingback','meta') COLLATE ascii_general_ci NOT NULL default 'comment'" );
		task_end();

		task_begin( 'Creating table for custom fields of Post Types... ' );
		db_create_table( 'T_items__type_custom_field', '
			itcf_ID      INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			itcf_ityp_ID INT(11) UNSIGNED NOT NULL,
			itcf_label   VARCHAR(255) NOT NULL,
			itcf_name    VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			itcf_type    ENUM( \'double\', \'varchar\' ) COLLATE ascii_general_ci NOT NULL,
			itcf_order   INT NULL,
			PRIMARY KEY ( itcf_ID ),
			UNIQUE itcf_ityp_ID_name( itcf_ityp_ID, itcf_name )' );

		// Create post types for each blog that has at aleast one custom field
		$SQL = new SQL();
		$SQL->SELECT( '*' );
		$SQL->FROM( 'T_coll_settings' );
		$SQL->WHERE( 'cset_name LIKE '.$DB->quote( 'custom_%' ) );
		$SQL->ORDER_BY( 'cset_coll_ID' );
		$setting_rows = $DB->get_results( $SQL->get() );
		$custom_fields = array();
		$blog_setting_delete_data = array();
		$blog_setting_item_types = array();
		if( count( $setting_rows ) )
		{ // Initialize an array of custom fields from blog settings
			foreach( $setting_rows as $setting_row )
			{
				if( preg_match( '/custom_(double|varchar)\d+/', $setting_row->cset_name, $matches ) )
				{ // It is a custom field
					if( ! isset( $custom_fields[ $setting_row->cset_coll_ID ] ) )
					{
						$custom_fields[ $setting_row->cset_coll_ID ] = array();
					}
					// Delete this blog setting
					$blog_setting_delete_data[] = 'cset_coll_ID = '.$DB->quote( $setting_row->cset_coll_ID ).' AND cset_name = '.$DB->quote( $setting_row->cset_name );

					$cf_type = $matches[1];
					$cf_key = $setting_row->cset_value;
					$cf_label = '';
					$cf_name = '';
					foreach( $setting_rows as $s_row )
					{
						if( $s_row->cset_name == 'custom_'.$cf_type.'_'.$cf_key )
						{ // Label
							$cf_label = $s_row->cset_value;
							// Delete this blog setting
							$blog_setting_delete_data[] = 'cset_coll_ID = '.$DB->quote( $s_row->cset_coll_ID ).' AND cset_name = '.$DB->quote( $s_row->cset_name );
						}
						if( $s_row->cset_name == 'custom_fname_'.$cf_key )
						{ // Name
							$cf_name = $s_row->cset_value;
							// Delete this blog setting
							$blog_setting_delete_data[] = 'cset_coll_ID = '.$DB->quote( $s_row->cset_coll_ID ).' AND cset_name = '.$DB->quote( $s_row->cset_name );
						}
					}
					$custom_fields[ $setting_row->cset_coll_ID ][] = array(
							'type'  => $cf_type,
							'key'   => $cf_key,
							'label' => $cf_label,
							'name'  => $cf_name
						);
				}
			}
			if( count( $custom_fields ) )
			{ // Create post type for each blog with custom fields
				$BlogCache = & get_BlogCache();
				$itypes_insert_data = array();
				$item_type_max_ID = $DB->get_var( 'SELECT MAX( ityp_ID ) FROM T_items__type' ) + 1;
				foreach( $custom_fields as $blog_ID => $c_fields )
				{
					if( ! ( $cf_Blog = $BlogCache->get_by_ID( $blog_ID, false, false ) ) )
					{ // Skip incorrect blog ID
						continue;
					}
					$itypes_insert_data[] = '( '.$item_type_max_ID.', '
						.$DB->quote( 'custom_'.$cf_Blog->get( 'shortname' ) ).', '
						.'"Posts", '
						.'"single", '
						.$DB->quote( $cf_Blog->get_setting( 'require_title' ) == 'none' ? 'never' : $cf_Blog->get_setting( 'require_title' ) ).', '
						.$DB->quote( intval( $cf_Blog->get_setting( 'allow_html_post' ) ) ).', '
						.$DB->quote( $cf_Blog->get_setting( 'location_country' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_country' ) ).', '
						.$DB->quote( $cf_Blog->get_setting( 'location_region' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_region' ) ).', '
						.$DB->quote( $cf_Blog->get_setting( 'location_subregion' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_subregion' ) ).', '
						.$DB->quote( $cf_Blog->get_setting( 'location_city' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_city' ) ).', '
						.$DB->quote( $cf_Blog->get_setting( 'show_location_coordinates' ) ? 'optional' : 'never' ).', '
						.$DB->quote( intval( $cf_Blog->get_setting( 'disable_comments_bypost' ) ) ).' )';
					// Update default post type
					$blog_setting_item_types[ $cf_Blog->ID ] = $item_type_max_ID;
					$blog_categories = $DB->get_col( 'SELECT cat_ID FROM T_categories WHERE cat_blog_ID = '.$cf_Blog->ID );
					if( count( $blog_categories ) )
					{ // Set new post type for each post
						$DB->query( 'UPDATE T_items__item SET post_ityp_ID = '.$item_type_max_ID.'
							WHERE post_ityp_ID = 1
							  AND post_main_cat_ID IN ( '.implode( ', ', $blog_categories ).' )' );

						// Find the Pages that have at least one defined custom field:
						$pages_SQL = new SQL();
						$pages_SQL->SELECT( 'post_ID' );
						$pages_SQL->FROM( 'T_items__item' );
						$pages_SQL->FROM_add( 'INNER JOIN T_items__item_settings ON post_ID = iset_item_ID' );
						$pages_SQL->WHERE( 'post_main_cat_ID IN ( '.implode( ', ', $blog_categories ).' )' );
						$pages_SQL->WHERE_and( 'post_ityp_ID = 1000' );
						$pages_SQL->WHERE_and( 'iset_name LIKE '.$DB->quote( 'custom_double_%' )
															.' OR iset_name LIKE '.$DB->quote( 'custom_varchar_%' ) );
						$pages_SQL->WHERE_and( 'iset_value != ""' );
						$pages_SQL->GROUP_BY( 'post_ID' );
						$pages_IDs = $DB->get_col( $pages_SQL->get() );
						$page_type_max_ID = 0;
						if( count( $pages_IDs ) > 0 )
						{ // We have the Pages that have the defined custom fields
							// Increase post type ID for new special post type for pages
							$page_type_max_ID = $item_type_max_ID + 1;
							$itypes_insert_data[] = '( '.$page_type_max_ID.', '
								.$DB->quote( 'page_'.$cf_Blog->get( 'shortname' ) ).', '
								.'"Pages", '
								.'"page", '
								.$DB->quote( $cf_Blog->get_setting( 'require_title' ) == 'none' ? 'never' : $cf_Blog->get_setting( 'require_title' ) ).', '
								.$DB->quote( intval( $cf_Blog->get_setting( 'allow_html_post' ) ) ).', '
								.$DB->quote( $cf_Blog->get_setting( 'location_country' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_country' ) ).', '
								.$DB->quote( $cf_Blog->get_setting( 'location_region' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_region' ) ).', '
								.$DB->quote( $cf_Blog->get_setting( 'location_subregion' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_subregion' ) ).', '
								.$DB->quote( $cf_Blog->get_setting( 'location_city' ) == 'hidden' ? 'never' : $cf_Blog->get_setting( 'location_city' ) ).', '
								.$DB->quote( $cf_Blog->get_setting( 'show_location_coordinates' ) ? 'optional' : 'never' ).', '
								.$DB->quote( intval( $cf_Blog->get_setting( 'disable_comments_bypost' ) ) ).' )';
							foreach( $c_fields as $c_field )
							{
								// Insert custom field to get new ID
								$DB->query( 'INSERT INTO T_items__type_custom_field ( itcf_ityp_ID, itcf_label, itcf_name, itcf_type )
									VALUES ( '.$page_type_max_ID.', '
									.$DB->quote( $c_field['label'] ).', '
									.$DB->quote( $c_field['name'] ).', '
									.$DB->quote( $c_field['type'] ).' )' );
								$itcf_ID = $DB->insert_id;
								// Change the UID of the item settings to the new inserted itcf_ID (ID of the custom field)
								$DB->query( 'UPDATE T_items__item_settings
										SET iset_name = '.$DB->quote( 'custom_'.$c_field['type'].'_'.$itcf_ID ).'
									WHERE iset_item_ID IN ( '.implode( ', ', $pages_IDs ).' )
										AND iset_name = '.$DB->quote( 'custom_'.$c_field['type'].'_'.$c_field['key'] ) );
							}
							// Set new post type for each page
							$DB->query( 'UPDATE T_items__item SET post_ityp_ID = '.$page_type_max_ID.'
								WHERE post_ID IN ( '.implode( ', ', $pages_IDs ).' )' );
						}
					}
					// Insert custom fields for standard posts (not pages)
					foreach( $c_fields as $c_field )
					{
						// Insert custom field to get new ID
						$DB->query( 'INSERT INTO T_items__type_custom_field ( itcf_ityp_ID, itcf_label, itcf_name, itcf_type )
							VALUES ( '.$item_type_max_ID.', '
							.$DB->quote( $c_field['label'] ).', '
							.$DB->quote( $c_field['name'] ).', '
							.$DB->quote( $c_field['type'] ).' )' );
						$itcf_ID = $DB->insert_id;
						// Change the UID of the item settings to the new inserted itcf_ID (ID of the custom field)
						$DB->query( 'UPDATE T_items__item_settings
								SET iset_name = '.$DB->quote( 'custom_'.$c_field['type'].'_'.$itcf_ID ).'
							WHERE iset_name = '.$DB->quote( 'custom_'.$c_field['type'].'_'.$c_field['key'] ) );
					}
					// Increase post type ID for next
					$item_type_max_ID += $page_type_max_ID > 0 ? 2 : 1;
				}
				// Insert post types
				$DB->query( 'INSERT INTO T_items__type ( ityp_ID, ityp_name, ityp_backoffice_tab, ityp_template_name, ityp_use_title, ityp_allow_html, ityp_use_country, ityp_use_region, ityp_use_sub_region, ityp_use_city, ityp_use_coordinates, ityp_allow_disabling_comments )
					VALUES '.implode( ', ', $itypes_insert_data ) );
				// Delete old blog settings from DB (custom fields)
				$blog_setting_delete_data[] = 'cset_name LIKE "count_custom_%"';
				$DB->query( 'DELETE FROM T_coll_settings
					WHERE ( '.implode( ') OR (', $blog_setting_delete_data ).' )' );
			}
		}

		// Update default post types
		$blogs = $DB->get_col( 'SELECT blog_ID FROM T_blogs' );
		$sql_update_blog_settings = array();
		foreach( $blogs as $blog_ID )
		{
			if( isset( $blog_setting_item_types[ $blog_ID ] ) )
			{ // Set it from custom post type
				$current_item_type = $blog_setting_item_types[ $blog_ID ];
			}
			else
			{ // Set it from first non reserved post type
				if( ! isset( $first_item_type ) )
				{
					$SQL = new SQL();
					$SQL->SELECT( 'ityp_ID' );
					$SQL->FROM( 'T_items__type' );
					$SQL->WHERE( 'ityp_ID NOT IN (1000,1400,1500,1520,1530,1570,1600,2000,3000,4000,5000)' );
					$SQL->ORDER_BY( 'ityp_ID' );
					$SQL->LIMIT( '1' );
					$first_item_type = $DB->get_var( $SQL->get() );;
				}
				$current_item_type = $first_item_type;
			}
			$sql_update_blog_settings[] = '( '.$DB->quote( $blog_ID ).', "default_post_type", '.$DB->quote( $current_item_type ).' )';
		}
		if( ! empty( $sql_update_blog_settings ) )
		{ // Execute a query to update the blog settings
			$DB->query( 'REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
				VALUES '.implode( ', ', $sql_update_blog_settings ) );
		}
		task_end();

		task_begin( 'Updating site settings... ' );
		if( $DB->get_var( 'SELECT set_value FROM T_settings WHERE set_name = "site_color"' ) === NULL )
		{ // Set default site color only when it is not defined yet
			$DB->query( 'INSERT INTO T_settings ( set_name, set_value )'
								.' VALUES ( "site_color", "#ff8c0f" )' );
		}
		task_end();

		set_upgrade_checkpoint( '11360' );
	}

	if( $old_db_version < 11370 )
	{ // part 18.f trunk aka 8th part of "i7"

		task_begin( 'Updating user settings... ' );
		$DB->query( 'DELETE FROM T_users__usersettings WHERE uset_name = "admin_skin"' );
		task_end();

		set_upgrade_checkpoint( '11370' );
	}

	if( $old_db_version < 11375 )
	{ // part 18.g trunk aka 9th part of "i7"

		task_begin( 'Upgrade table user field definitions... ' );
		$DB->query( 'ALTER TABLE T_users__fielddefs
			ADD ufdf_icon_name varchar(100) COLLATE ascii_general_ci NULL' );
		$DB->query( 'UPDATE T_users__fielddefs SET
			ufdf_icon_name = CASE
				WHEN ufdf_name = "Yahoo IM"      THEN "fa fa-yahoo"
				WHEN ufdf_name = "Skype"         THEN "fa fa-skype"
				WHEN ufdf_name = "Main phone"    THEN "fa fa-phone"
				WHEN ufdf_name = "Cell phone"    THEN "fa fa-mobile-phone"
				WHEN ufdf_name = "Office phone"  THEN "fa fa-phone"
				WHEN ufdf_name = "Home phone"    THEN "fa fa-phone"
				WHEN ufdf_name = "Office FAX"    THEN "fa fa-fax"
				WHEN ufdf_name = "Home FAX"      THEN "fa fa-fax"
				WHEN ufdf_name = "Linkedin"      THEN "fa fa-linkedin fa-x-linkedin--nudge"
				WHEN ufdf_name = "Twitter"       THEN "fa fa-twitter"
				WHEN ufdf_name = "Facebook"      THEN "fa fa-facebook"
				WHEN ufdf_name = "Flickr"        THEN "fa fa-flickr"
				WHEN ufdf_name = "YouTube"       THEN "fa fa-youtube"
				WHEN ufdf_name = "Digg"          THEN "fa fa-digg"
				WHEN ufdf_name = "StumbleUpon"   THEN "fa fa-stumbleupon"
				WHEN ufdf_name = "GitHub"        THEN "fa fa-github-alt"
				WHEN ufdf_name = "Google Plus"   THEN "fa fa-google-plus fa-x-google-plus--nudge"
				WHEN ufdf_name = "Pinterest"     THEN "fa fa-pinterest-p"
				WHEN ufdf_name = "Main address"  THEN "fa fa-building"
				WHEN ufdf_name = "Home address"  THEN "fa fa-home"
				WHEN ufdf_name = "About me"      THEN "fa fa-info-circle"
				WHEN ufdf_name = "I like"        THEN "fa fa-thumbs-o-up"
				WHEN ufdf_name = "I don\'t like" THEN "fa fa-thumbs-o-down"
				ELSE ufdf_icon_name
			END' );
		task_end();

		set_upgrade_checkpoint( '11375' );
	}

	if( $old_db_version < 11380 )
	{ // part 18.h trunk aka 10th part of "i7"

		task_begin( 'Update links table... ' );
		$DB->query( 'UPDATE T_links
			  SET link_position = "cover"
			WHERE link_position = "albumart"' );
		task_end();

		set_upgrade_checkpoint( '11380' );
	}

	if( $old_db_version < 11390 )
	{ // part 18.i trunk aka 11th part of "i7"

		task_begin( 'Upgrading table of relations users with organizations... ' );
		$DB->query( 'ALTER TABLE T_users__user_org
			ADD COLUMN uorg_role VARCHAR(255) NULL' );
		task_end();

		set_upgrade_checkpoint( '11390' );
	}

	if( $old_db_version < 11400 )
	{ // part 18.j trunk aka 12th part of "i7"

		task_begin( 'Upgrade table user field definitions... ' );
		$DB->query( 'ALTER TABLE T_users__fielddefs
			ADD ufdf_code varchar(20) COLLATE ascii_general_ci NULL' );
		$update_user_fields = array(
				'Micro bio'     => 'microbio',
				'I like'        => 'ilike',
				'I don\'t like' => 'idontlike',
				'MSN/Live IM'   => 'msnliveim',
				'Yahoo IM'      => 'yahooim',
				'AOL AIM'       => 'aolaim',
				'ICQ ID'        => 'icqid',
				'Skype'         => 'skype',
				'Main phone'    => 'mainphone',
				'Cell phone'    => 'cellphone',
				'Office phone'  => 'officephone',
				'Home phone'    => 'homephone',
				'Office FAX'    => 'officefax',
				'Home FAX'      => 'homefax',
				'Twitter'       => 'twitter',
				'Facebook'      => 'facebook',
				'Google Plus'   => 'googleplus',
				'Linkedin'      => 'linkedin',
				'GitHub'        => 'github',
				'Website'       => 'website',
				'Blog'          => 'blog',
				'Myspace'       => 'myspace',
				'Flickr'        => 'flickr',
				'YouTube'       => 'youtube',
				'Digg'          => 'digg',
				'StumbleUpon'   => 'stumbleupon',
				'Pinterest'     => 'pinterest',
				'Role'          => 'role',
				'Organization'  => 'organization',
				'Division'      => 'division',
				'VAT ID'        => 'vatid',
				'Main address'  => 'mainaddress',
				'Home address'  => 'homeaddress',
			);
		foreach( $update_user_fields as $update_user_field_name => $update_user_field_code )
		{
			$DB->query( 'UPDATE T_users__fielddefs
				  SET ufdf_code = '.$DB->quote( $update_user_field_code ).'
				WHERE ufdf_name = '.$DB->quote( $update_user_field_name ).'
				LIMIT 1' ); // limit by 1 in order to update only first record to avoid the duplicate codes
		}
		// Update codes for all other unknown fields
		$DB->query( 'UPDATE T_users__fielddefs
				SET ufdf_code = CONCAT( "code_", ufdf_ID )
			WHERE ufdf_code IS NULL' );
		// Make code field unique
		$DB->query( 'ALTER TABLE T_users__fielddefs
			MODIFY ufdf_code varchar(20) COLLATE ascii_general_ci UNIQUE NOT NULL' );
		task_end();

		/*
		 * ADD UPGRADES FOR i7 BRANCH __ABOVE__ IN THIS BLOCK.
		 *
		 * This part will be included in trunk and i7 branches
		 */

		set_upgrade_checkpoint( '11400' );
	}

	if( $old_db_version < 11410 )
	{ // part 18.k trunk aka 13th part of "i7"

		task_begin( 'Upgrading skin names... ' );
		$DB->query( 'UPDATE T_skins__skin
							 SET skin_folder = CASE
									WHEN skin_folder = "bootstrap"        THEN "bootstrap_blog_skin"
									WHEN skin_folder = "bootstrap_main"   THEN "bootstrap_main_skin"
									WHEN skin_folder = "bootstrap_manual" THEN "bootstrap_manual_skin"
									ELSE skin_folder
			END' );
		task_end();

		/*
		 * ADD UPGRADES FOR i7 BRANCH __ABOVE__ IN THIS BLOCK.
		 *
		 * This part will be included in trunk and i7 branches
		 */

		set_upgrade_checkpoint( '11410' );
	}

	if( $old_db_version < 11420 )
	{ // part 18.l trunk aka 14th part of "i7"

		// This upgrade block restores all field collations that may have been broken by the back-office DB convert tool
		// to 'ascii_bin' and 'ascii_general_ci'

		task_begin( 'Updating hit log keyphrases table...' );
		$DB->query( 'ALTER TABLE T_track__keyphrase
			MODIFY keyp_phrase  VARCHAR( 255 ) COLLATE utf8_bin NOT NULL' );
		task_end();

		task_begin( 'Check and normalize the ASCII charsets/collations... <br />' );
		task_begin( '- Converting skins table...' );
		$DB->query( "ALTER TABLE T_skins__skin
			MODIFY skin_type enum('normal','feed','sitemap','mobile','tablet') COLLATE ascii_general_ci NOT NULL default 'normal'" );
		task_end();
		task_begin( '- Converting blogs table...' );
		$DB->query( "ALTER TABLE T_blogs
			MODIFY blog_access_type    VARCHAR(10) COLLATE ascii_general_ci NOT NULL DEFAULT 'extrapath',
			MODIFY blog_urlname        VARCHAR(255) COLLATE ascii_general_ci NOT NULL DEFAULT 'urlname',
			MODIFY blog_in_bloglist    ENUM( 'public', 'logged', 'member', 'never' ) COLLATE ascii_general_ci DEFAULT 'public' NOT NULL,
			MODIFY blog_media_location ENUM( 'default', 'subdir', 'custom', 'none' ) COLLATE ascii_general_ci DEFAULT 'default' NOT NULL,
			MODIFY blog_type           ENUM( 'main', 'std', 'photo', 'group', 'forum', 'manual' ) COLLATE ascii_general_ci DEFAULT 'std' NOT NULL" );
		task_end();
		task_begin( '- Converting blog settings table...' );
		$DB->query( 'ALTER TABLE T_coll_settings
			MODIFY cset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL' );
		task_end();
		task_begin( '- Converting widgets table...' );
		$DB->query( "ALTER TABLE {$tableprefix}widget
			MODIFY wi_type ENUM( 'core', 'plugin' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'core',
			MODIFY wi_code VARCHAR(32) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting categories table...' );
		$DB->query( "ALTER TABLE T_categories
			MODIFY cat_urlname varchar(255) COLLATE ascii_general_ci NOT NULL,
			MODIFY cat_subcat_ordering enum('parent', 'alpha', 'manual') COLLATE ascii_general_ci NULL DEFAULT NULL" );
		task_end();
		task_begin( '- Converting posts table...' );
		$DB->query( "ALTER TABLE T_items__item
			MODIFY post_status               enum('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NOT NULL default 'published',
			MODIFY post_urltitle             VARCHAR(210) COLLATE ascii_general_ci NOT NULL,
			MODIFY post_notifications_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq',
			MODIFY post_comment_status       ENUM('disabled', 'open', 'closed') COLLATE ascii_general_ci NOT NULL DEFAULT 'open',
			MODIFY post_renderers            VARCHAR(255) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting comments table...' );
		$DB->query( "ALTER TABLE T_comments
			MODIFY comment_type         enum('comment','linkback','trackback','pingback','meta') COLLATE ascii_general_ci NOT NULL default 'comment',
			MODIFY comment_status       ENUM('published','community','deprecated','protected','private','review','draft','trash') COLLATE ascii_general_ci DEFAULT 'published' NOT NULL,
			MODIFY comment_author_email varchar(255) COLLATE ascii_general_ci NULL,
			MODIFY comment_author_IP    varchar(45) COLLATE ascii_general_ci NOT NULL default '',
			MODIFY comment_renderers    VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			MODIFY comment_secret       CHAR(32) COLLATE ascii_general_ci NULL default NULL,
			MODIFY comment_notif_status ENUM('noreq','todo','started','finished') COLLATE ascii_general_ci NOT NULL DEFAULT 'noreq' COMMENT 'Have notifications been sent for this comment? How far are we in the process?'" );
		task_end();
		task_begin( '- Converting post prerendered contents table...' );
		$DB->query( "ALTER TABLE T_items__prerendering
			MODIFY itpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,
			MODIFY itpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting comment prerendered contents table...' );
		$DB->query( "ALTER TABLE T_comments__prerendering
			MODIFY cmpr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,
			MODIFY cmpr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting post versions table...' );
		$DB->query( "ALTER TABLE T_items__version
			MODIFY iver_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NULL" );
		task_end();
		task_begin( '- Converting post types table...' );
		$DB->query( "ALTER TABLE T_items__type
			MODIFY ityp_use_title              ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'required',
			MODIFY ityp_use_url                ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_text               ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_excerpt            ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_title_tag          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_meta_desc          ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_meta_keywds        ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_tags               ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional',
			MODIFY ityp_use_country            ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			MODIFY ityp_use_region             ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			MODIFY ityp_use_sub_region         ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			MODIFY ityp_use_city               ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			MODIFY ityp_use_coordinates        ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never',
			MODIFY ityp_use_comment_expiration ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'optional'" );
		task_end();
		task_begin( '- Converting post types custom fields table...' );
		$DB->query( "ALTER TABLE T_items__type_custom_field
			MODIFY itcf_name VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			MODIFY itcf_type ENUM( 'double', 'varchar' ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting post settings table...' );
		$DB->query( "ALTER TABLE T_items__item_settings
			MODIFY iset_name varchar( 50 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting user permissions table...' );
		$DB->query( "ALTER TABLE T_coll_user_perms
			MODIFY bloguser_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloguser_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',
			MODIFY bloguser_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloguser_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'" );
		task_end();
		task_begin( '- Converting group permissions table...' );
		$DB->query( "ALTER TABLE T_coll_group_perms
			MODIFY bloggroup_perm_poststatuses set('review','draft','private','protected','deprecated','community','published','redirected') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloggroup_perm_edit         ENUM('no','own','lt','le','all','redirected') COLLATE ascii_general_ci NOT NULL default 'no',
			MODIFY bloggroup_perm_cmtstatuses  set('review','draft','private','protected','deprecated','community','published') COLLATE ascii_general_ci NOT NULL default '',
			MODIFY bloggroup_perm_edit_cmt     ENUM('no','own','anon','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'" );
		task_end();
		task_begin( '- Converting links table...' );
		$DB->query( "ALTER TABLE T_links
			MODIFY link_position varchar(10) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting files table...' );
		$DB->query( "ALTER TABLE T_files
			MODIFY file_type      enum('image', 'audio', 'other') COLLATE ascii_general_ci NULL DEFAULT NULL,
			MODIFY file_root_type enum('absolute','user','collection','shared','skins','import') COLLATE ascii_general_ci NOT NULL DEFAULT 'absolute'" );
		task_end();
		task_begin( '- Converting file types table...' );
		$DB->query( "ALTER TABLE T_filetypes
			MODIFY ftyp_extensions varchar(30) COLLATE ascii_general_ci NOT NULL,
			MODIFY ftyp_viewtype   varchar(10) COLLATE ascii_general_ci NOT NULL,
			MODIFY ftyp_allowed    enum('any','registered','admin') COLLATE ascii_general_ci NOT NULL default 'admin'" );
		task_end();
		task_begin( '- Converting messages table...' );
		$DB->query( "ALTER TABLE T_messaging__message
			MODIFY msg_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting message prerendering contents table...' );
		$DB->query( "ALTER TABLE T_messaging__prerendering
			MODIFY mspr_format    ENUM('htmlbody','entityencoded','xml','text') COLLATE ascii_general_ci NOT NULL,
			MODIFY mspr_renderers VARCHAR(255) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting sessions table...' );
		$DB->query( "ALTER TABLE T_sessions
			MODIFY sess_key       CHAR(32) COLLATE ascii_general_ci NULL,
			MODIFY sess_ipaddress VARCHAR(45) COLLATE ascii_general_ci NOT NULL DEFAULT '',
			MODIFY sess_device    VARCHAR(8) COLLATE ascii_general_ci NOT NULL DEFAULT ''" );
		task_end();
		task_begin( '- Converting domains table...' );
		$DB->query( "ALTER TABLE T_basedomains
			MODIFY dom_status ENUM('unknown','trusted','suspect','blocked') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown',
			MODIFY dom_type   ENUM('unknown','normal','searcheng','aggregator','email') COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'" );
		task_end();
		task_begin( '- Converting logs table...' );
		$DB->query( "ALTER TABLE T_hitlog
			MODIFY hit_ctrl         VARCHAR(30) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY hit_type         ENUM('standard','rss','admin','ajax', 'service') COLLATE ascii_general_ci DEFAULT 'standard' NOT NULL,
			MODIFY hit_referer_type ENUM('search','special','spam','referer','direct','self') COLLATE ascii_general_ci NOT NULL,
			MODIFY hit_remote_addr  VARCHAR(45) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY hit_agent_type   ENUM('robot','browser','unknown') COLLATE ascii_general_ci DEFAULT 'unknown' NOT NULL" );
		task_end();
		task_begin( '- Converting goal categories table...' );
		$DB->query( "ALTER TABLE T_track__goalcat
			MODIFY gcat_color  char(7) COLLATE ascii_general_ci default NULL" );
		task_end();
		task_begin( '- Converting groups table...' );
		$DB->query( "ALTER TABLE T_groups
			MODIFY grp_perm_blogs                  enum('user','viewall','editall') COLLATE ascii_general_ci NOT NULL default 'user',
			MODIFY grp_perm_xhtmlvalidation        VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',
			MODIFY grp_perm_xhtmlvalidation_xmlrpc VARCHAR(10) COLLATE ascii_general_ci NOT NULL default 'always',
			MODIFY grp_perm_stats                  enum('none','user','view','edit') COLLATE ascii_general_ci NOT NULL default 'none'" );
		task_end();
		task_begin( '- Converting group settings table...' );
		$DB->query( "ALTER TABLE T_groups__groupsettings
			MODIFY gset_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting settings table...' );
		$DB->query( "ALTER TABLE T_settings
			MODIFY set_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting cache table...' );
		$DB->query( "ALTER TABLE T_global__cache
			MODIFY cach_name VARCHAR(30) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting users table...' );
		$DB->query( "ALTER TABLE T_users
			MODIFY user_email           varchar(255) COLLATE ascii_general_ci NOT NULL,
			MODIFY user_status          enum( 'activated', 'autoactivated', 'closed', 'deactivated', 'emailchanged', 'failedactivation', 'new' ) COLLATE ascii_general_ci NOT NULL default 'new',
			MODIFY user_unsubscribe_key CHAR(32) COLLATE ascii_general_ci NOT NULL default '' COMMENT 'A specific key, it is used when a user wants to unsubscribe from a post comments without signing in',
			MODIFY user_gender          char(1) COLLATE ascii_general_ci NULL" );
		task_end();
		task_begin( '- Converting user fields table...' );
		$DB->query( "ALTER TABLE T_users__fielddefs
			MODIFY ufdf_type       char(8) COLLATE ascii_general_ci NOT NULL,
			MODIFY ufdf_required   enum('hidden','optional','recommended','require') COLLATE ascii_general_ci NOT NULL default 'optional',
			MODIFY ufdf_duplicated enum('forbidden','allowed','list') COLLATE ascii_general_ci NOT NULL default 'allowed',
			MODIFY ufdf_icon_name  varchar(100) COLLATE ascii_general_ci NULL,
			MODIFY ufdf_code       varchar(20) COLLATE ascii_general_ci UNIQUE NOT NULL" );
		task_end();
		task_begin( '- Converting user reports table...' );
		$DB->query( "ALTER TABLE T_users__reports
			MODIFY urep_status enum( 'fake', 'guidelines', 'harass', 'spam', 'other' ) COLLATE ascii_general_ci" );
		task_end();
		task_begin( '- Converting user invitation codes table...' );
		$DB->query( "ALTER TABLE T_users__invitation_code
			MODIFY ivc_code varchar(32) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting locales table...' );
		$DB->query( "ALTER TABLE T_locales
			MODIFY loc_datefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'y-m-d',
			MODIFY loc_timefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'H:i:s',
			MODIFY loc_shorttimefmt varchar(20) COLLATE ascii_general_ci NOT NULL default 'H:i'" );
		task_end();
		task_begin( '- Converting antispam table...' );
		$DB->query( "ALTER TABLE {$tableprefix}antispam
			MODIFY aspm_source enum( 'local','reported','central' ) COLLATE ascii_general_ci NOT NULL default 'reported'" );
		task_end();
		task_begin( '- Converting IP ranges table...' );
		$DB->query( "ALTER TABLE T_antispam__iprange
			MODIFY aipr_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL" );
		task_end();
		task_begin( '- Converting user settings table...' );
		$DB->query( "ALTER TABLE T_users__usersettings
			MODIFY uset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugins table...' );
		$DB->query( "ALTER TABLE T_plugins
			MODIFY plug_classname VARCHAR(40) COLLATE ascii_general_ci NOT NULL default '',
			MODIFY plug_code      VARCHAR(32) COLLATE ascii_general_ci NULL,
			MODIFY plug_version   VARCHAR(42) COLLATE ascii_general_ci NOT NULL default '0',
			MODIFY plug_status    ENUM( 'enabled', 'disabled', 'needs_config', 'broken' ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugin settings table...' );
		$DB->query( "ALTER TABLE T_pluginsettings
			MODIFY pset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugin user settings table...' );
		$DB->query( "ALTER TABLE T_pluginusersettings
			MODIFY puset_name VARCHAR( 30 ) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting plugin events table...' );
		$DB->query( "ALTER TABLE T_pluginevents
			MODIFY pevt_event VARCHAR(40) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting cron tasks table...' );
		$DB->query( "ALTER TABLE T_cron__task
			MODIFY ctsk_key varchar(50) COLLATE ascii_general_ci not null" );
		task_end();
		task_begin( '- Converting cron logs table...' );
		$DB->query( "ALTER TABLE T_cron__log
			MODIFY clog_status enum('started','finished','error','timeout') COLLATE ascii_general_ci not null default 'started'" );
		task_end();
		task_begin( '- Converting countries table...' );
		$DB->query( "ALTER TABLE T_regional__country
			MODIFY ctry_code   char(2) COLLATE ascii_general_ci NOT NULL,
			MODIFY ctry_status enum( 'trusted', 'suspect', 'blocked' ) COLLATE ascii_general_ci NULL DEFAULT NULL" );
		task_end();
		task_begin( '- Converting regions table...' );
		$DB->query( "ALTER TABLE T_regional__region
			MODIFY rgn_code char(6) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting subregions table...' );
		$DB->query( "ALTER TABLE T_regional__subregion
			MODIFY subrg_code char(6) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting cities table...' );
		$DB->query( "ALTER TABLE T_regional__city
			MODIFY city_postcode char(12) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting currencies table...' );
		$DB->query( "ALTER TABLE T_regional__currency
			MODIFY curr_code char(3) COLLATE ascii_general_ci NOT NULL" );
		task_end();
		task_begin( '- Converting slugs table...' );
		$DB->query( "ALTER TABLE T_slug
			MODIFY slug_title varchar(255) COLLATE ascii_bin NOT NULL,
			MODIFY slug_type	char(6) COLLATE ascii_bin NOT NULL DEFAULT 'item'" );
		task_end();
		task_begin( '- Converting email logs table...' );
		$DB->query( "ALTER TABLE T_email__log
			MODIFY emlog_to     VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY emlog_result ENUM( 'ok', 'error', 'blocked' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'ok'" );
		task_end();
		task_begin( '- Converting email returns table...' );
		$DB->query( "ALTER TABLE T_email__returns
			MODIFY emret_address   VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY emret_errtype   CHAR(1) COLLATE ascii_general_ci NOT NULL DEFAULT 'U'" );
		task_end();
		task_begin( '- Converting email addresses table...' );
		$DB->query( "ALTER TABLE T_email__address
			MODIFY emadr_address VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL,
			MODIFY emadr_status  ENUM( 'unknown', 'redemption', 'warning', 'suspicious1', 'suspicious2', 'suspicious3', 'prmerror', 'spammer' ) COLLATE ascii_general_ci NOT NULL DEFAULT 'unknown'" );
		task_end();
		task_begin( '- Converting system log table...' );
		$DB->query( "ALTER TABLE T_syslog
			MODIFY slg_type   ENUM('info', 'warning', 'error', 'critical_error') COLLATE ascii_general_ci NOT NULL DEFAULT 'info',
			MODIFY slg_origin ENUM('core', 'plugin') COLLATE ascii_general_ci,
			MODIFY slg_object ENUM('comment', 'item', 'user', 'file') COLLATE ascii_general_ci" );
		task_end();
		task_end();

		set_upgrade_checkpoint( '11420' );
	}

	if( $old_db_version < 11430 )
	{ // part 18.m trunk aka 15th part of "i7"

		task_begin( 'Upgrading tags table...' );
		// Get all tags that contain not ascii chars, because some mysql versions cannot convert them correctly to utf8_bin
		$not_ascii_tags = $DB->get_results( 'SELECT *
			 FROM T_items__tag
			WHERE tag_name NOT REGEXP "^[A-Za-z0-9_\-\s]+$"' );
		foreach( $not_ascii_tags as $not_ascii_tag )
		{ // Replace each not ascii char with "_" in tag name in order to avoid error on below table upgrading
			$ascii_tag_name = preg_replace( '/[^A-Za-z0-9_\-\s]/', '_', $not_ascii_tag->tag_name );
			$ascii_tag_name = str_replace( '__', '_', $ascii_tag_name );

			if( $ascii_tag_name == $not_ascii_tag->tag_name )
			{ // Skip this tag name because it doesn't contain not ascii chars really
				continue;
			}

			// Check tag name for uniqueness
			$c = 1;
			$new_tag_name = $ascii_tag_name;
			while( $DB->get_var( 'SELECT tag_ID
				 FROM T_items__tag
				WHERE tag_name = '.$DB->quote( $new_tag_name ) ) )
			{
				$new_tag_name = $ascii_tag_name.$c;
				$c++;
			}

			// Update tag name to new value without not ascii chars
			$DB->query( 'UPDATE T_items__tag
				  SET tag_name = '.$DB->quote( $new_tag_name ).'
				WHERE tag_ID = '.$not_ascii_tag->tag_ID );
		}
		// Remove the empty tags
		$empty_tag_IDs = $DB->get_col( 'SELECT tag_ID FROM T_items__tag
			WHERE tag_name = ""' );
		if( ! empty( $empty_tag_IDs ) )
		{
			$DB->query( 'DELETE FROM T_items__tag
				WHERE tag_ID IN ( '.$DB->quote( $empty_tag_IDs ).' ) ' );
			$DB->query( 'DELETE FROM T_items__itemtag
				WHERE itag_tag_ID IN ( '.$DB->quote( $empty_tag_IDs ).' ) ' );
		}
		// Upgrade field "tag_name" from varbinary to varchar utf8_bin
		$DB->query( 'ALTER TABLE T_items__tag
			MODIFY tag_name VARCHAR(50) COLLATE utf8_bin NOT NULL' ); // Allow multiple special char variations for each tag
		task_end();

		task_begin( 'Upgrading collection user/group permissions tables...' );
		$DB->query( "ALTER TABLE T_coll_user_perms
			MODIFY bloguser_perm_edit ENUM('no','own','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'" );
		$DB->query( "ALTER TABLE T_coll_group_perms
			MODIFY bloggroup_perm_edit ENUM('no','own','lt','le','all') COLLATE ascii_general_ci NOT NULL default 'no'" );
		task_end();

		// fp> Note: do NOT put back and "add upgrades" comment here. The comment is OUTSIDE of the block now!

		set_upgrade_checkpoint( '11430' );
	}

	if( upg_task_start( 11440, 'Upgrading base domains table...' ) )
	{	// part of 6.5.0
		$DB->query( "ALTER TABLE T_basedomains
			MODIFY dom_name VARCHAR(250) COLLATE utf8_bin NOT NULL DEFAULT ''" );
		upg_task_end();
	}

	if( upg_task_start( 11450, 'Upgrading blog-group permissions table...' ) )
	{	// part of 6.6.0
		$DB->query( "ALTER TABLE T_coll_group_perms
			ADD COLUMN bloggroup_perm_item_type ENUM('standard','restricted','admin') COLLATE ascii_general_ci NOT NULL default 'standard' AFTER bloggroup_perm_poststatuses,
			DROP COLUMN bloggroup_perm_page,
			DROP COLUMN bloggroup_perm_intro,
			DROP COLUMN bloggroup_perm_podcast,
			DROP COLUMN bloggroup_perm_sidebar" );
		upg_task_end();
	}

	if( upg_task_start( 11453, 'Upgrading blog-user permissions table...' ) )
	{	// part of 6.6.0
		$DB->query( "ALTER TABLE T_coll_user_perms
			ADD COLUMN bloguser_perm_item_type ENUM('standard','restricted','admin') COLLATE ascii_general_ci NOT NULL default 'standard' AFTER bloguser_perm_poststatuses,
			DROP COLUMN bloguser_perm_page,
			DROP COLUMN bloguser_perm_intro,
			DROP COLUMN bloguser_perm_podcast,
			DROP COLUMN bloguser_perm_sidebar" );
		upg_task_end();
	}

	if( upg_task_start( 11456, 'Upgrade post types table...' ) )
	{	// part of 6.6.0
		$DB->query( "ALTER TABLE T_items__type
			ADD COLUMN ityp_perm_level ENUM( 'standard', 'restricted', 'admin' ) COLLATE ascii_general_ci NOT NULL default 'standard'" );
		upg_task_end();
	}

	if( upg_task_start( 11460, 'Creating table for PostType-to-Collection relationships...' ) )
	{	// part of 6.6.0
		db_create_table( 'T_items__type_coll', '
			itc_ityp_ID int(11) unsigned NOT NULL,
			itc_coll_ID int(11) unsigned NOT NULL,
			PRIMARY KEY (itc_ityp_ID, itc_coll_ID),
			UNIQUE itemtypecoll ( itc_ityp_ID, itc_coll_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 11463, 'Updating collection permissions...' ) )
	{	// part of 6.6.0
		$DB->query( 'UPDATE T_coll_group_perms
			  SET bloggroup_perm_item_type = "restricted"
			WHERE bloggroup_perm_item_type = "standard"' );
		$DB->query( 'UPDATE T_coll_user_perms
			  SET bloguser_perm_item_type = "restricted"
			WHERE bloguser_perm_item_type = "standard"' );
		upg_task_end();
	}

	if( upg_task_start( 11466, 'Updating post types table...' ) )
	{	// part of 6.6.0
		$DB->query( 'UPDATE T_items__type SET
			ityp_perm_level = CASE
				WHEN ityp_ID = "1"    THEN "standard"
				WHEN ityp_ID = "100"  THEN "standard"
				WHEN ityp_ID = "200"  THEN "standard"
				WHEN ityp_ID = "1000" THEN "restricted"
				WHEN ityp_ID = "1400" THEN "restricted"
				WHEN ityp_ID = "1500" THEN "restricted"
				WHEN ityp_ID = "1520" THEN "restricted"
				WHEN ityp_ID = "1530" THEN "restricted"
				WHEN ityp_ID = "1570" THEN "restricted"
				WHEN ityp_ID = "1600" THEN "restricted"
				WHEN ityp_ID = "2000" THEN "standard"
				WHEN ityp_ID = "3000" THEN "admin"
				WHEN ityp_ID = "4000" THEN "admin"
				ELSE ityp_perm_level
			END' );
		upg_task_end();
	}

	if( upg_task_start( 11470, 'Updating widgets table...' ) )
	{	// part of 6.6.0
		// Disable all widgets of Menu container for all "Main" collections
		$DB->query( 'UPDATE '.$tableprefix.'widget
			INNER JOIN T_blogs ON blog_ID = wi_coll_ID AND blog_type = "main"
			  SET wi_enabled = 0
			WHERE wi_sco_name = "Menu"' );
		upg_task_end();
	}

	if( upg_task_start( 11480, 'Updating table for PostType-to-Collection relationships...' ) )
	{	// part of 6.6.1
		// Get all collections:
		$collections_SQL = new SQL();
		$collections_SQL->SELECT( 'blog_ID, blog_type' );
		$collections_SQL->FROM( 'T_blogs' );
		$collections = $DB->get_assoc( $collections_SQL->get() );
		// Get all post types:
		$posttypes_SQL = new SQL();
		$posttypes_SQL->SELECT( 'ityp_ID' );
		$posttypes_SQL->FROM( 'T_items__type' );
		$posttypes = $DB->get_col( $posttypes_SQL->get() );
		// Enable post types for the collections:
		$posttypes_collections = array();
		foreach( $collections as $collection_ID => $collection_type )
		{
			switch( $collection_type )
			{ // Set what post types should not be enabled depending on the collection type:
				case 'main':
				case 'photo':
					$skip_posttypes = array( 100, 200, 2000, 5000 );
					break;
				case 'forum':
					$skip_posttypes = array( 1, 100, 2000, 5000 );
					break;
				case 'manual':
					$skip_posttypes = array( 1, 200, 2000, 5000 );
					break;
				default: // 'std'
					$skip_posttypes = array( 100, 200, 5000 );
					break;
			}
			foreach( $posttypes as $posttype_ID )
			{
				if( in_array( $posttype_ID, $skip_posttypes ) )
				{ // Skip(Don't enable) this post type for the collection:
					continue;
				}
				$posttypes_collections[] = '( '.$posttype_ID.', '.$collection_ID.' )';
			}
		}
		if( count( $posttypes_collections ) )
		{ // Update the relationships only when at least one is required:
			$DB->query( 'REPLACE INTO T_items__type_coll
				( itc_ityp_ID, itc_coll_ID )
				VALUES '.implode( ', ', $posttypes_collections ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 11482, 'Updating default post types for forums and manual collections...' ) )
	{	// part of 6.6.3
		$item_types = array(
				'manual' => array( 'ID' => 100, 'name' => 'Manual Page' ),
				'forum'  => array( 'ID' => 200, 'name' => 'Forum Topic' ),
			);
		$update_default_type_sql = array();
		foreach( $item_types as $collection_type => $item_type )
		{
			// Try to find an item type by ID or name:
			$item_type_ID = $DB->get_var( 'SELECT ityp_ID
				 FROM T_items__type
				WHERE ityp_ID = '.$item_type['ID'].'
				   OR ityp_name = '.$DB->quote( $item_type['name'] ) );
			if( empty( $item_type_ID ) )
			{ // Item type is not found in DB, Skip it:
				continue;
			}
			// Get all collections with type:
			$type_collection_IDs = $DB->get_col( 'SELECT blog_ID
				 FROM T_blogs
				WHERE blog_type = '.$DB->quote( $collection_type ) );
			foreach( $type_collection_IDs as $type_collection_ID )
			{
				$update_default_type_sql[] = '( '.$type_collection_ID.', "default_post_type", '.$DB->quote( $item_type_ID ).' )';
			}
		}
		if( count( $update_default_type_sql ) > 0 )
		{ // Update default post types of collections:
			$DB->query( 'REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
				VALUES '.implode( ',', $update_default_type_sql ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 11483, 'Updating general settings...' ) )
	{	// part of 6.6.4
		$DB->query( 'UPDATE T_settings
				SET set_value = '.$DB->quote( 'no' ).'
			WHERE set_name = '.$DB->quote( 'newusers_canregister' ).'
				AND set_value = '.$DB->quote( '0' ) );
		task_end();

		task_begin( 'Updating user settings...' );
		$DB->query( 'ALTER TABLE T_users__usersettings CHANGE COLUMN uset_name uset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL' );
		$DB->query( 'ALTER TABLE T_pluginusersettings CHANGE COLUMN puset_name puset_name VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 11484, 'Upgrade table item types...' ) )
	{	// part of 6.6.4
		$DB->query( "ALTER TABLE T_items__type
			ADD ityp_use_parent ENUM( 'required', 'optional', 'never' ) COLLATE ascii_general_ci DEFAULT 'never' AFTER ityp_use_url" );
		upg_task_end();
	}

	if( upg_task_start( 11485, 'Upgrade table item types...' ) )
	{	// part of 6.6.6
		$DB->query( 'ALTER TABLE T_items__type
			ADD ityp_allow_breaks TINYINT DEFAULT 1 AFTER ityp_allow_html' );
		$DB->query( 'UPDATE T_items__type
			SET ityp_allow_breaks = 0,
			    ityp_allow_featured = 0
			WHERE ityp_ID >= 1400
			  AND ityp_ID <= 1600' );
		upg_task_end();
	}

	if( upg_task_start( 11486, 'Upgrade timestamp fields...' ) )
	{	// part of 6.6.6
		$DB->query( 'ALTER TABLE T_email__log
			MODIFY emlog_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_email__returns
			MODIFY emret_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_syslog
			MODIFY slg_timestamp TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_items__prerendering
			MODIFY itpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_comments__prerendering
			MODIFY cmpr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__prerendering
			MODIFY mspr_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_users__reports
			MODIFY urep_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_items__version
			MODIFY iver_edit_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__thread
			MODIFY thrd_datemodified datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__message
			MODIFY msg_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		$DB->query( 'ALTER TABLE T_messaging__contact
			MODIFY mct_last_contact_datetime datetime NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 11600, 'Updating blogs settings...' ) )
	{	// part of 6.7.0

		// Update the assets urls to 'relative' type of the blogs that have absolute base url:
		// (All other blogs will have the 'basic' url type by default)
		$blogs_abs_url_SQL = new SQL();
		$blogs_abs_url_SQL->SELECT( 'blog_ID' );
		$blogs_abs_url_SQL->FROM( 'T_blogs' );
		$blogs_abs_url_SQL->WHERE( 'blog_access_type = "absolute"' );
		$blogs_abs_url = $DB->get_col( $blogs_abs_url_SQL->get() );
		if( count( $blogs_abs_url ) )
		{ // Update only when at least one blog has an absolute base url
			$blogs_abs_url_values = '';
			foreach( $blogs_abs_url as $b => $blog_abs_url_ID )
			{
				if( $b != 0 )
				{
					$blogs_abs_url_values .= ', ';
				}
				$blogs_abs_url_values .= '( '.$blog_abs_url_ID.', "rsc_assets_url_type", "relative" ), '
					.'( '.$blog_abs_url_ID.', "media_assets_url_type", "relative" ), '
					.'( '.$blog_abs_url_ID.', "skins_assets_url_type", "relative" )';
			}
			$DB->query( 'REPLACE INTO T_coll_settings( cset_coll_ID, cset_name, cset_value )
				VALUES '.$blogs_abs_url_values );
		}

		upg_task_end();
	}

	if( upg_task_start( 11605, 'Upgrading cron logs table...' ) )
	{	// part of 6.7.0
		$DB->query( "ALTER TABLE T_cron__log
			CHANGE clog_status clog_status enum('started','finished','error','timeout','warning') COLLATE ascii_general_ci not null default 'started'" );
		upg_task_end();
	}

	if( upg_task_start( 11610, 'Upgrading cron tasks table...' ) )
	{	// part of 6.7.0
		$DB->query( 'ALTER TABLE T_cron__task
			ADD COLUMN ctsk_repeat_variation int(10) unsigned DEFAULT 0 AFTER ctsk_repeat_after' );
		upg_task_end();
	}

	if( upg_task_start( 11615, 'Upgrading email log table...' ) )
	{	// part of 6.7.0
		$DB->query( 'ALTER TABLE T_email__log
			MODIFY emlog_result ENUM( "ok", "error", "blocked", "simulated" ) COLLATE ascii_general_ci NOT NULL DEFAULT "ok"' );
		upg_task_end();
	}

	if( upg_task_start( 11620, 'Upgrading hitlog table...' ) )
	{	// part of 6.7.0
		$DB->query( "ALTER TABLE T_hitlog
			MODIFY COLUMN hit_type ENUM('standard','rss','admin','ajax', 'service', 'api') COLLATE ascii_general_ci DEFAULT 'standard' NOT NULL" );
		upg_task_end();
	}

	if( upg_task_start( 11625, 'Update plugins table...' ) )
	{	// part of 6.7.0
		$DB->query( 'UPDATE T_plugins
			  SET plug_classname = "shortlinks_plugin"
			WHERE plug_classname = "wikilinks_plugin"' );
		upg_task_end();
	}

	if( upg_task_start( 11630, 'Upgrading plugin settings table...' ) )
	{	// part of 6.7.0
		$DB->query( 'ALTER TABLE T_pluginsettings
			MODIFY pset_name VARCHAR( 60 ) COLLATE ascii_general_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 11635, 'Upgrading email campaigns table...' ) )
	{	// part of 6.7.0
		$DB->query( 'ALTER TABLE T_email__campaign
			ADD COLUMN ecmp_email_plaintext TEXT NULL AFTER ecmp_email_text,
			ADD COLUMN ecmp_renderers       VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			ADD COLUMN ecmp_use_wysiwyg     TINYINT(1) NOT NULL DEFAULT 0' );
		upg_task_end();
	}

	if( upg_task_start( 11640, 'Upgrading hitlog table...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_hitlog', 'hit_method', "ENUM('unknown','GET','POST','PUT','PATCH','DELETE','COPY','HEAD','OPTIONS','LINK','UNLINK','PURGE','LOCK','UNLOCK','PROPFIND','VIEW') COLLATE ascii_general_ci DEFAULT 'unknown' NOT NULL" );
		upg_task_end();
	}

	if( upg_task_start( 11645 ) )
	{	// part of 6.7.0

		/* ---- Install basic widgets for container "Item Single": ---- START */
		global $basic_widgets_insert_sql_rows;
		$basic_widgets_insert_sql_rows = array();

		/**
		 * Add a widget to global array in order to insert it in DB by single SQL query later
		 *
		 * @param integer Blog ID
		 * @param string Container name
		 * @param string Type
		 * @param string Code
		 * @param integer Order
		 * @param array|string|NULL Widget params
		 * @param integer 1 - enabled, 0 - disabled
		 */
		function add_basic_widget_11670( $blog_ID, $container_name, $code, $type, $order, $params = NULL, $enabled = 1 )
		{
			global $basic_widgets_insert_sql_rows, $DB;

			if( is_null( $params ) )
			{ // NULL
				$params = 'NULL';
			}
			elseif( is_array( $params ) )
			{ // array
				$params = $DB->quote( serialize( $params ) );
			}
			else
			{ // string
				$params = $DB->quote( $params );
			}

			$basic_widgets_insert_sql_rows[] = '( '
				.$blog_ID.', '
				.$DB->quote( $container_name ).', '
				.$order.', '
				.$enabled.', '
				.$DB->quote( $type ).', '
				.$DB->quote( $code ).', '
				.$params.' )';
		}

		$collections = $DB->get_assoc( 'SELECT blog_ID, blog_type FROM T_blogs ORDER BY blog_ID' );
		foreach( $collections as $coll_ID => $coll_type )
		{
			task_begin( 'Installing default "Item Single" widgets for collection #'.$coll_ID.'... ' );
			add_basic_widget_11670( $coll_ID, 'Item Single', 'item_content', 'core', 20 );
			if( $coll_type != 'forum' )
			{	// Item Tags:
				add_basic_widget_11670( $coll_ID, 'Item Single', 'item_tags', 'core', 30 );
			}
			if( $coll_type == 'std' )
			{	// About Author:
				add_basic_widget_11670( $coll_ID, 'Item Single', 'item_about_author', 'core', 40 );
			}
			if( $coll_type == 'std' || $coll_type == 'manual' )
			{	// Small Print:
				add_basic_widget_11670( $coll_ID, 'Item Single', 'item_small_print', 'core', 50, array( 'format' => ( $coll_type == 'std' ? 'standard' : 'revision' ) ) );
			}
			// Seen by:
			add_basic_widget_11670( $coll_ID, 'Item Single', 'item_seen_by', 'core', 60, NULL,
				// Disable this widget for "forum" collections by default:
				$coll_type == 'forum' ? 0 : 1 );
			task_end();
		}

		if( ! empty( $basic_widgets_insert_sql_rows ) )
		{	// Insert the widget records by single SQL query:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_enabled, wi_type, wi_code, wi_params ) '
								 .'VALUES '.implode( ', ', $basic_widgets_insert_sql_rows ) );
		}
		/* ---- Install basic widgets for container "Item Single": ---- END */

		upg_task_end( false );
	}

	if( upg_task_start( 11650, 'Upgrading user organizations table...' ) )
	{	// part of 6.7.0
		$DB->query( 'ALTER TABLE T_users__organization
			ADD COLUMN org_owner_user_ID INT(11) UNSIGNED NOT NULL AFTER org_ID,
			ADD COLUMN org_accept        ENUM( "yes", "owner", "no" ) COLLATE ascii_general_ci NOT NULL DEFAULT "owner"' );
		$DB->query( 'UPDATE T_users__organization SET org_owner_user_ID = 1' );
		upg_task_end();
	}

	if( upg_task_start( 11655, 'Creating table for Poll questions...' ) )
	{	// part of 6.7.0
		db_create_table( 'T_polls__question', '
			pqst_ID            INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			pqst_owner_user_ID INT(11) UNSIGNED NOT NULL,
			pqst_question_text VARCHAR(2000) NULL,
			PRIMARY KEY (pqst_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 11660, 'Creating table for Poll options...' ) )
	{	// part of 6.7.0
		db_create_table( 'T_polls__option', '
			popt_ID          INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			popt_pqst_ID     INT(11) UNSIGNED NOT NULL,
			popt_option_text VARCHAR(2000) NULL,
			popt_order       INT(11) NOT NULL,
			PRIMARY KEY (popt_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 11665, 'Creating table for Poll answers...' ) )
	{	// part of 6.7.0
		db_create_table( 'T_polls__answer', '
			pans_ID      INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			pans_pqst_ID INT(11) UNSIGNED NOT NULL,
			pans_user_ID INT(11) UNSIGNED NOT NULL,
			pans_popt_ID INT(11) UNSIGNED NOT NULL,
			PRIMARY KEY (pans_ID),
			UNIQUE pans_pqst_user_ID ( pans_pqst_ID, pans_user_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 11670, 'Creating default polls...' ) )
	{	// part of 6.7.0
		$DB->query( 'INSERT INTO T_polls__question ( pqst_owner_user_ID, pqst_question_text )
			VALUES ( 1, "What is your favorite b2evolution feature?" )' );
		$DB->query( 'INSERT INTO T_polls__option ( popt_pqst_ID, popt_option_text, popt_order )
			VALUES ( 1, "Multiple blogs",          1 ),
						 ( 1, "Photo Galleries",         2 ),
						 ( 1, "Forums",                  3 ),
						 ( 1, "Online Manuals",          4 ),
						 ( 1, "Newsletters / E-mailing", 5 ),
						 ( 1, "Easy Maintenance",        6 )' );
		$DB->query( 'INSERT INTO T_polls__answer ( pans_pqst_ID, pans_user_ID, pans_popt_ID )
			VALUES ( 1, 5, 1 ),
						 ( 1, 6, 2 ),
						 ( 1, 7, 2 ),
						 ( 1, 2, 2 ),
						 ( 1, 3, 3 ),
						 ( 1, 4, 3 ),
						 ( 1, 1, 6 )' );
		upg_task_end();
	}

	if( upg_task_start( 11675, 'Creating table for secondary user groups...' ) )
	{	// part of 6.7.0
		db_create_table( 'T_users__secondary_user_groups', '
				sug_user_ID INT(11) UNSIGNED NOT NULL,
				sug_grp_ID  INT(11) UNSIGNED NOT NULL,
				PRIMARY KEY ( sug_user_ID, sug_grp_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 11680, 'Upgrading groups table...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_groups', 'grp_usage', "ENUM('primary','secondary') COLLATE ascii_general_ci NOT NULL DEFAULT 'primary' AFTER grp_name" );
		upg_task_end();
	}

	if( upg_task_start( 11685, 'Upgrading files table...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_files', 'file_download_count', 'INT(10) UNSIGNED NOT NULL DEFAULT 0 AFTER file_can_be_main_profile' );
		upg_task_end();
	}

	if( upg_task_start( 11690, 'Updating collection user/group permissions...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_meta_comment', 'tinyint NOT NULL default 0 AFTER bloguser_perm_edit_cmt' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_meta_comment', 'tinyint NOT NULL default 0 AFTER bloggroup_perm_edit_cmt' );
		upg_task_end();
	}

	if( upg_task_start( 11695, 'Upgrade table item types...' ) )
	{	// part of 6.7.0
		// Add item type usage field and new setting "Treat as Podcast Media" to use it specially for "Podcast" item type:
		$DB->query( 'ALTER TABLE T_items__type
			ADD COLUMN ityp_usage   VARCHAR(20) COLLATE ascii_general_ci NOT NULL DEFAULT "post" AFTER ityp_backoffice_tab,
			ADD COLUMN ityp_podcast TINYINT(1) DEFAULT 0 AFTER ityp_use_url' );
		// Replace old field "ityp_backoffice_tab" with new "ityp_usage":
		$DB->query( 'UPDATE T_items__type SET
			ityp_usage = CASE
				WHEN ( ityp_backoffice_tab = "Pages" OR ityp_name = "Page" ) THEN "page"
				WHEN ityp_name = "Intro-Front"   THEN "intro-front"
				WHEN ityp_name = "Intro-Main"    THEN "intro-main"
				WHEN ityp_name = "Intro-Cat"     THEN "intro-cat"
				WHEN ityp_name = "Intro-Tag"     THEN "intro-tag"
				WHEN ityp_name = "Intro-Sub"     THEN "intro-sub"
				WHEN ityp_name = "Intro-All"     THEN "intro-all"
				WHEN ityp_name = "Sidebar link"  THEN "special"
				WHEN ityp_name = "Advertisement" THEN "special"
				ELSE "post"
			END' );
		db_drop_col( 'T_items__type', 'ityp_backoffice_tab' );
		upg_task_end();
	}

	if( upg_task_start( 11700, 'Update item types for new created fields...' ) )
	{	// part of 6.7.0
		// Update name of podcast item type:
		$DB->query( 'UPDATE T_items__type
			  SET ityp_name = "Podcast Episode"
			WHERE ityp_name = "Podcast"' );
		// Enable new podcast setting for item type "Podcast"
		$DB->query( 'UPDATE T_items__type
			  SET ityp_podcast = "1"
			WHERE ityp_ID = "2000"' );
		// Delete the reserved item type:
		$DB->query( 'DELETE FROM T_items__type
			WHERE ityp_ID = "5000"' );
		// Update name of page item type:
		$DB->query( 'UPDATE T_items__type
			  SET ityp_name = "Standalone Page"
			WHERE ityp_usage = "page"
			  AND ityp_name = "Page"' );
		upg_task_end();
	}

	if( upg_task_start( 11705, 'Upgrading users organization table...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_users__organization', 'org_perm_role', "ENUM('owner and member', 'owner') COLLATE ascii_general_ci NOT NULL DEFAULT 'owner and member' AFTER org_accept" );
		upg_task_end();
	}

	if( upg_task_start( 11710, 'Deleting back-office skin "chicago"...' ) )
	{	// part of 6.7.0
		// Update the back-office skin of all users to default "bootstrap":
		$DB->query( 'DELETE FROM T_users__usersettings WHERE uset_name = "admin_skin"' );
		// Try to delete skin folder:
		global $adminskins_path;
		$skin_chicago_path = $adminskins_path.'chicago/';
		if( file_exists( $skin_chicago_path ) && ! rmdir_r( $skin_chicago_path ) )
		{	// Display a warning if no permissions to delete the skin folder:
			echo get_install_format_text_and_log( '<span class="text-warning"><evo:warning>'
					.'WARNING: the Chicago admin skin is no longer supported. Please delete the folder <code>'.$skin_chicago_path.'</code>'
				.'</evo:warning></span>' );
		}
		upg_task_end();
	}

	if( upg_task_start( 11715, 'Replace widgets "Simple Sidebar Links list" and "Simple Linkblog Links list" with "Universal Item list"...' ) )
	{	// part of 6.7.0
		$old_widgets = $DB->get_results( 'SELECT wi_ID, wi_code, wi_params
			 FROM '.$tableprefix.'widget
			WHERE wi_type = "core"
			  AND wi_code IN ( "linkblog", "coll_link_list" )', OBJECT,
			'Get widgets "linkblog" and "coll_link_list" to replace them with "coll_item_list"' );
		foreach( $old_widgets as $old_widget )
		{
			// Get current params of each widget to don't miss default settings:
			$widget_params = empty( $old_widget->wi_params ) ? array() : unserialize( $old_widget->wi_params );
			// Rewrite default params with existing widget params from DB:
			switch( $old_widget->wi_code )
			{
				case 'linkblog':
					// Keep default params for old widget "Simple Linkblog Links list":
					$widget_params = array_merge( array(
							'title'                => T_('Linkblog'),
							'item_group_by'        => 'chapter',
							'item_title_link_type' => 'auto',
							'item_type'            => '',
							'item_type_usage'      => 'special',
						), $widget_params );
					break;

				case 'coll_link_list':
					// Keep default params for old widget "Simple Sidebar Links list":
					$widget_params = array_merge( array(
							'title'                => T_('Links'),
							'item_title_link_type' => 'auto',
							'item_type'            => '',
							'item_type_usage'      => 'special',
						), $widget_params );
					break;
			}
			$DB->query( 'UPDATE '.$tableprefix.'widget
					SET wi_code = "coll_item_list", wi_params = '.$DB->quote( serialize( $widget_params ) ).'
				WHERE wi_ID = '.$old_widget->wi_ID );
		}
		upg_task_end();
	}

	if( upg_task_start( 11720, 'Replace renamed widgets...' ) )
	{	// part of 6.7.0
		// It's ok to run several queries in a single block because they don't change the DB structure, so they practically can't fail:
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "item_seen_by"
			WHERE wi_type = "core"
			  AND wi_code = "coll_seen_by"' );
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "item_small_print"
			WHERE wi_type = "core"
			  AND wi_code = "coll_small_print"' );
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "item_tags"
			WHERE wi_type = "core"
			  AND wi_code = "coll_item_tags"' );
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "item_content"
			WHERE wi_type = "core"
			  AND wi_code = "coll_item_content"' );
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "item_about_author"
			WHERE wi_type = "core"
			  AND wi_code = "coll_about_author"' );
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "coll_member_count"
			WHERE wi_type = "core"
			  AND wi_code = "member_count"' );
		upg_task_end();
	}

	if( upg_task_start( 11725, 'Upgrade table post type...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_items__type', 'ityp_front_instruction', 'tinyint default 0 AFTER ityp_template_name' );
		db_add_col( 'T_items__type', 'ityp_back_instruction', 'tinyint default 0 AFTER ityp_front_instruction' );
		db_add_col( 'T_items__type', 'ityp_instruction', 'text NULL default NULL AFTER ityp_back_instruction' );
		upg_task_end();
	}

	if( upg_task_start( 11730, 'Upgrade table invitation codes...' ) )
	{	// part of 6.7.0
		db_add_col( 'T_users__invitation_code', 'ivc_level', 'int unsigned NULL' );
		$DB->query( 'ALTER TABLE T_users__invitation_code
			MODIFY COLUMN ivc_grp_ID int(4) NULL' );
		upg_task_end();
	}

	if( upg_task_start( 11735, 'Upgrade table files...' ) )
	{	// part of 6.7.0
		$DB->query( 'ALTER TABLE T_files
			MODIFY file_type ENUM( "image", "audio", "video", "other" ) COLLATE ascii_general_ci NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 11740, 'Update table user settings for new post/comment moderation settings...' ) )
	{	// part of 6.7.0
		$DB->query( 'INSERT INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
			SELECT uset_user_ID, IF( uset_name = "notify_comment_moderation", "notify_edit_cmt_moderation", "notify_edit_pst_moderation" ), uset_value
			  FROM T_users__usersettings
			 WHERE uset_name IN ( "notify_comment_moderation", "notify_post_moderation" )' );
		upg_task_end();
	}

	if( upg_task_start( 11745, 'Upgrading items table...' ) )
	{	// part of 6.7.1
		db_add_col( 'T_items__item', 'post_notifications_flags', "SET('moderators_notified','members_notified','community_notified','pings_sent') NOT NULL DEFAULT '' AFTER post_notifications_ctsk_ID" );
		$DB->query( 'UPDATE T_items__item
			  SET post_notifications_flags = "moderators_notified,members_notified,community_notified,pings_sent"
			WHERE post_notifications_status = "finished"' );
		upg_task_end();
	}

	if( upg_task_start( 11750, 'Upgrading comments table...' ) )
	{	// part of 6.7.1
		db_add_col( 'T_comments', 'comment_notif_flags', "SET('moderators_notified','members_notified','community_notified') NOT NULL DEFAULT ''" );
		$DB->query( 'UPDATE T_comments
			  SET comment_notif_flags = "moderators_notified,members_notified,community_notified"
			WHERE comment_notif_status = "finished"' );
		upg_task_end();
	}

	if( upg_task_start( 11755, 'Creating collection user favorites table...' ) )
	{	// part of 6.7.1-beta
		db_create_table( 'T_coll_user_favs', '
				cufv_user_ID INT(10) UNSIGNED NOT NULL,
				cufv_blog_ID INT(11) UNSIGNED NOT NULL,
				PRIMARY KEY cufv_pk ( cufv_user_ID, cufv_blog_ID )' );

		// If system user count is less than or equal to 10, Add favorites based on previous blog_favorite settings
		load_funcs( 'tools/model/_system.funcs.php' );
		$user_IDs = system_get_user_IDs();

		$colls_SQL = new SQL( 'Get ALL collections' );
		$colls_SQL->SELECT( 'blog_ID, blog_owner_user_ID, blog_favorite' );
		$colls_SQL->FROM( 'T_blogs' );
		$colls_SQL->ORDER_BY( 'blog_ID' );
		$colls = $DB->get_results( $colls_SQL->get() );

		$user_colls_count = array();
		$insert_values = array();
		foreach( $colls as $coll )
		{	// Collection owners will automatically favorite their collections:
			if( ! isset( $user_colls_count[ $coll->blog_owner_user_ID ] ) )
			{	// Initialize a count of favorite collections for each user:
				$user_colls_count[ $coll->blog_owner_user_ID ] = 1;
			}
			if( $user_colls_count[ $coll->blog_owner_user_ID ] <= 7 )
			{	// Make favorite only first 7 collections for each user:
				$insert_values[] = '( '.$coll->blog_ID.', '.$coll->blog_owner_user_ID.' )';
				$user_colls_count[ $coll->blog_owner_user_ID ]++;
			}
		}

		if( count( $user_IDs ) <= 10 )
		{	// Make collections favorite for other users only if system has <= 10 users:
			foreach( $user_IDs as $user_ID )
			{
				if( ! isset( $user_colls_count[ $user_ID ] ) )
				{	// Initialize a count of favorite collections for each user:
					$user_colls_count[ $user_ID ] = 1;
				}
				foreach( $colls as $coll )
				{
					if( $user_colls_count[ $user_ID ] > 7 )
					{	// Make favorite only first 7 collections for each user:
						break;
					}
					if( $coll->blog_favorite && $user_ID != $coll->blog_owner_user_ID )
					{	// Skip collection owner, because it has this collection as favorite automatically above:
						$insert_values[] = '( '.$coll->blog_ID.', '.$user_ID.' )';
						$user_colls_count[ $user_ID ]++;
					}
				}
			}
		}

		if( count( $insert_values ) )
		{	// Insert rows of favorite collections per users in DB:
			$DB->query( 'INSERT INTO T_coll_user_favs ( cufv_blog_ID, cufv_user_ID ) VALUES '.implode( ', ', $insert_values ) );
		}

		// Drop blog_favorite column:
		db_drop_col( 'T_blogs', 'blog_favorite' );
		upg_task_end();
	}

	if( upg_task_start( 11760, 'Upgrading email campaigns table...' ) )
	{	// part of 6.7.1-beta
		db_add_col( 'T_email__campaign', 'ecmp_send_ctsk_ID', 'INT(10) UNSIGNED NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 11765, 'Upgrading files table...' ) )
	{ // part of 6.7.1-beta
		db_add_col( 'T_files', 'file_creator_user_ID', 'int(10) unsigned NULL default NULL AFTER file_ID' );

		// Update file_creator_user_ID with the owner of the first link to a comment/post/message
		$SQL = 'UPDATE T_files AS t1,
				(
					SELECT a.link_file_ID, a.link_creator_user_ID
					FROM T_links AS a
					INNER JOIN
					(
						SELECT link_file_ID, MIN( link_ID ) AS min_ID
						FROM T_links
						GROUP BY link_file_ID
					) AS b
						ON a.link_file_ID = b.link_file_ID AND a.link_ID = b.min_ID
				) AS t2
				SET
					t1.file_creator_user_ID = t2.link_creator_user_ID
				WHERE
					t1.file_ID = t2.link_file_ID';
		$DB->query( $SQL );

		upg_task_end();
	}

	if( upg_task_start( 11770, 'Upgrading files table...' ) )
	{ // part of 6.7.3-beta
		db_add_index( 'T_files', 'file_creator_user_id', 'file_creator_user_id' );
		upg_task_end();
	}

	if( upg_task_start( 11775, 'Upgrading posts and comments statuses depeding on max allowed status by their collections...' ) )
	{	// part of 6.7.4-stable
		$BlogCache = & get_BlogCache();
		$BlogCache->load_all( 'ID', 'ASC' );
		foreach( $BlogCache->cache as $Blog )
		{
			$Blog->update_reduced_status_data();
		}
		upg_task_end();
	}

	if( upg_task_start( 11780, 'Upgrading subscription settings of collections...' ) )
	{	// part of 6.7.4-stable
		$DB->query( 'REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
				SELECT cset_coll_ID, "allow_comment_subscriptions", 1
				  FROM T_coll_settings
				 WHERE cset_name = "allow_subscriptions"
				   AND cset_value = 1' );
		upg_task_end();
	}

	if( upg_task_start( 11785, 'Upgrading email log table...' ) )
	{	// part of 6.7.7-stable
		$DB->query( 'ALTER TABLE T_email__log
			MODIFY emlog_message MEDIUMTEXT DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 11790, 'Fix number of favorite collections per each user...' ) )
	{	// part of 6.7.7-stable
		// Get users which have more than 20 favorite collections:
		$more_fav_coll_users_SQL = new SQL();
		$more_fav_coll_users_SQL->SELECT( 'cufv_user_ID' );
		$more_fav_coll_users_SQL->FROM( 'T_coll_user_favs' );
		$more_fav_coll_users_SQL->GROUP_BY( 'cufv_user_ID' );
		$more_fav_coll_users_SQL->HAVING( 'COUNT( cufv_blog_ID ) > 20' );
		$more_fav_coll_user_IDs = $DB->get_col( $more_fav_coll_users_SQL->get() );

		foreach( $more_fav_coll_user_IDs as $more_fav_coll_user_ID )
		{
			// Get first 7 collections which should be kept as favorite after upgrade:
			$first_colls_SQL = new SQL();
			$first_colls_SQL->SELECT( 'cufv_blog_ID' );
			$first_colls_SQL->FROM( 'T_coll_user_favs' );
			$first_colls_SQL->WHERE( 'cufv_user_ID = '.$more_fav_coll_user_ID );
			$first_colls_SQL->ORDER_BY( 'cufv_blog_ID' );
			$first_colls_SQL->LIMIT( '7' );
			$first_coll_IDs = $DB->get_col( $first_colls_SQL->get() );

			if( count( $first_coll_IDs ) )
			{	// Delete collections from favorite list:
				$DB->query( 'DELETE FROM T_coll_user_favs
					WHERE cufv_user_ID = '.$more_fav_coll_user_ID.'
					  AND cufv_blog_ID NOT IN ( '.$DB->quote( $first_coll_IDs ).' )' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 11795, 'Upgrading posts table...' ) )
	{	// part of 6.7.7-stable
		$DB->query( 'ALTER TABLE T_items__item
			MODIFY post_excerpt_autogenerated  TINYINT(1) NOT NULL DEFAULT 1' );
		upg_task_end();
	}

	if( upg_task_start( 11800, 'Upgrading collection-user permissions table...' ) )
	{	// part of 6.7.7-stable
		$DB->query( 'ALTER TABLE T_coll_user_perms
			ADD bloguser_perm_analytics tinyint NOT NULL default 0' );
		$DB->query( 'UPDATE T_coll_user_perms
			  SET bloguser_perm_analytics = 1
			WHERE bloguser_perm_properties = 1' );
		upg_task_end();
	}

	if( upg_task_start( 11805, 'Upgrading collection-group permissions table...' ) )
	{	// part of 6.7.7-stable
		$DB->query( 'ALTER TABLE T_coll_group_perms
			ADD bloggroup_perm_analytics tinyint NOT NULL default 0' );
		$DB->query( 'UPDATE T_coll_group_perms
			  SET bloggroup_perm_analytics = 1
			WHERE bloggroup_perm_properties = 1' );
		upg_task_end();
	}

	if( upg_task_start( 11810, 'Upgrading plugins table...' ) )
	{	// part of 6.7.7-stable
		$DB->query( 'ALTER TABLE T_plugins
			MODIFY plug_priority TINYINT UNSIGNED NOT NULL default 50' );
		upg_task_end();
	}

	if( upg_task_start( 12000, 'Add new types "Text" and "HTML" for custom fields of item types...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_items__item_settings
			MODIFY COLUMN iset_value varchar( 10000 ) NULL' );
		$DB->query( 'ALTER TABLE T_items__type_custom_field
			MODIFY COLUMN itcf_type ENUM( "double", "varchar", "text", "html" ) COLLATE ascii_general_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12005, 'Update widget container "Item Single"...' ) )
	{	// part of 6.8.0-alpha
		$SQL = new SQL( 'Get all collections that have a widget container "Item Single"' );
		$SQL->SELECT( 'wi_ID, wi_coll_ID, wi_code, wi_order' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->WHERE( 'wi_sco_name = "Item Single"' );
		$SQL->ORDER_BY( 'wi_coll_ID, wi_order' );
		$coll_item_single_widgets = $DB->get_results( $SQL->get(), ARRAY_A, $SQL->title );
		$coll_widgets = array();
		foreach( $coll_item_single_widgets as $coll_item_single_widget )
		{
			if( ! isset( $coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] ) )
			{	// If the "Item Single" has no widget "Item Content":
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = 1;
			}
			if( $coll_item_single_widget['wi_code'] == 'item_content' )
			{	// If the "Item Single" contains widget "Item Content" then keep an order of this widget:
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = $coll_item_single_widget['wi_order'] + 1;
			}
		}
		$item_attachments_widget_rows = array();
		foreach( $coll_widgets as $coll_ID => $widget_order )
		{	// Insert new widget "Item Attachments" to each colleaction that has a container "Item Single":
			$item_attachments_widget_rows[] = '( '.$coll_ID.', "Item Single", '.$widget_order.', "item_attachments" )';
			// Check and update not unique widget orders:
			$not_unique_widget_ID = $DB->get_var( 'SELECT wi_ID
				 FROM '.$tableprefix.'widget
				WHERE wi_coll_ID = '.$coll_ID.'
					AND wi_sco_name = "Item Single"
					AND wi_order = '.$widget_order );
			if( $not_unique_widget_ID > 0 )
			{	// The collection has not unique widget order:
				$update_order_widgets = array();
				foreach( $coll_item_single_widgets as $coll_item_single_widget )
				{
					if( $coll_item_single_widget['wi_coll_ID'] == $coll_ID && $coll_item_single_widget['wi_order'] >= $widget_order )
					{	// Increase a widget order to avoid mysql errors of duplicate entry:
						$update_order_widgets[] = $coll_item_single_widget['wi_ID'];
					}
				}
				for( $w = count( $update_order_widgets ) - 1; $w >= 0 ; $w-- )
				{	// Update not unique widget orders:
					$DB->query( 'UPDATE '.$tableprefix.'widget
							SET   wi_order = wi_order + 1
							WHERE wi_ID = '.$update_order_widgets[ $w ] );
				}
			}
		}
		if( count( $item_attachments_widget_rows ) )
		{	// Insert new widgets "Item Attachments" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $item_attachments_widget_rows ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12010, 'Create new widget container "404 Page"...' ) )
	{	// part of 6.8.0-alpha
		$coll_IDs = $DB->get_col( 'SELECT blog_ID FROM T_blogs' );
		if( $coll_IDs )
		{
			$page_404_widget_rows = array();
			foreach( $coll_IDs as $coll_ID )
			{
				$page_404_widget_rows[] = '( '.$coll_ID.', "404 Page", 10, "page_404_not_found" )';
				$page_404_widget_rows[] = '( '.$coll_ID.', "404 Page", 20, "coll_search_form" )';
				$page_404_widget_rows[] = '( '.$coll_ID.', "404 Page", 30, "coll_tag_cloud" )';
			}
			// Insert new widgets for container "404 Page" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $page_404_widget_rows ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12015, 'Rename table "T_antispam" to "T_antispam__keyword"...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'RENAME TABLE '.$tableprefix.'antispam TO T_antispam__keyword' );
		$DB->query( "ALTER TABLE T_antispam__keyword
			CHANGE aspm_ID     askw_ID     bigint(11) NOT NULL auto_increment,
			CHANGE aspm_string askw_string varchar(80) NOT NULL,
			CHANGE aspm_source askw_source enum( 'local','reported','central' ) COLLATE ascii_general_ci NOT NULL default 'reported'" );
		// Use this query separately from above because MariaDB versions 10+ create an error:
		$DB->query( "ALTER TABLE T_antispam__keyword
			DROP INDEX aspm_string,
			ADD UNIQUE askw_string ( askw_string )" );
		upg_task_end();
	}

	if( upg_task_start( 12020, 'Upgrade table user post data...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'RENAME TABLE '.$tableprefix.'users__postreadstatus TO T_items__user_data' );
		$DB->query( "ALTER TABLE T_items__user_data
			CHANGE uprs_user_ID         itud_user_ID          INT(11) UNSIGNED NOT NULL,
			CHANGE uprs_post_ID         itud_item_ID          INT(11) UNSIGNED NOT NULL,
			CHANGE uprs_read_post_ts    itud_read_item_ts     TIMESTAMP NULL DEFAULT NULL,
			CHANGE uprs_read_comment_ts itud_read_comments_ts TIMESTAMP NULL DEFAULT NULL,
			ADD                         itud_flagged_item     TINYINT(1) NOT NULL DEFAULT 0" );
		upg_task_end();
	}

	if( upg_task_start( 12025, 'Creating table for user profile visits...' ) )
	{	// part of 6.8.0-alpha
		db_create_table( 'T_users__profile_visits', '
				upv_visited_user_ID INT(11) UNSIGNED NOT NULL,
				upv_visitor_user_ID INT(11) UNSIGNED NOT NULL,
				upv_last_visit_ts   TIMESTAMP NOT NULL DEFAULT "2000-01-01 00:00:00",
				PRIMARY KEY ( upv_visited_user_ID, upv_visitor_user_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 12030, 'Upgrade base domains table...') )
	{ // part of 6.8.0-alpha
		db_add_col( 'T_basedomains', 'dom_comment', 'VARCHAR(255) DEFAULT NULL' );
		upg_task_end();
	}

// fp> TMP NOTE: This was current status of antispam

	if( upg_task_start( 12035, 'Create table for items votes...' ) )
	{	// part of 6.8.0-alpha
		db_create_table( 'T_items__votes', '
			itvt_item_ID INT UNSIGNED NOT NULL,
			itvt_user_ID INT UNSIGNED NOT NULL,
			itvt_updown  TINYINT(1) NULL DEFAULT NULL,
			itvt_report  ENUM( "clean", "rated", "adult", "inappropriate", "spam" ) COLLATE ascii_general_ci NULL DEFAULT NULL,
			itvt_ts      TIMESTAMP NOT NULL DEFAULT "2000-01-01 00:00:00",
			PRIMARY KEY (itvt_item_ID, itvt_user_ID),
			KEY itvt_item_ID (itvt_item_ID),
			KEY itvt_user_ID (itvt_user_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 12040, 'Upgrade table posts for voting...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_items__item
			ADD post_addvotes   INT NOT NULL DEFAULT 0,
			ADD post_countvotes INT UNSIGNED NOT NULL DEFAULT 0' );
		upg_task_end();
	}

	if( upg_task_start( 12045, 'Update table post types...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'UPDATE T_items__type
			  SET ityp_allow_disabling_comments = 1
			WHERE ityp_usage LIKE "intro%"' );
		upg_task_end();
	}

	if( upg_task_start( 12050, 'Upgrade table post types...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_items__type
			ADD ityp_comment_form_msg       TEXT NULL DEFAULT NULL AFTER ityp_use_comments,
			ADD ityp_allow_comment_form_msg TINYINT DEFAULT 0      AFTER ityp_comment_form_msg' );
		upg_task_end();
	}

	if( upg_task_start( 12055, 'Upgrade links table...' ) )
	{	// part of 6.8.0-alpha
		db_add_col( 'T_links', 'link_ecmp_ID', 'int(11) unsigned  NULL COMMENT \'Used for linking files to email campaign\' AFTER link_usr_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12060, 'Upgrade files table...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_files
			MODIFY file_root_type ENUM("absolute","user","collection","shared","skins","import","emailcampaign") COLLATE ascii_general_ci NOT NULL DEFAULT "absolute"' );
		upg_task_end();
	}

	if( upg_task_start( 12065, 'Upgrade blogs table...') )
	{ // part of 6.8.0-alpha
		db_add_col( 'T_blogs', 'blog_http_protocol', 'ENUM("always_redirect", "allow_both") DEFAULT "always_redirect" AFTER blog_access_type' );
		upg_task_end();
	}

	if( upg_task_start( 12070, 'Create table for temporary IDs...' ) )
	{	// part of 6.8.0-alpha
		db_create_table( 'T_temporary_ID', '
			tmp_ID   INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			tmp_type VARCHAR(32) COLLATE ascii_general_ci NOT NULL,
			PRIMARY KEY (tmp_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 12075, 'Upgrade links table...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_links
			ADD link_msg_ID int(11) unsigned  NULL COMMENT \'Used for linking files to private message\' AFTER link_ecmp_ID,
			ADD link_tmp_ID int(11) unsigned  NULL COMMENT \'Used for linking files to new creating object\' AFTER link_msg_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12080, 'Create table for post type status...' ) )
	{ // part of 6.8.0-alpha
		db_create_table( 'T_items__status_type', '
			its_pst_ID INT(11) UNSIGNED NOT NULL,
			its_ityp_ID INT(11) UNSIGNED NOT NULL,
			PRIMARY KEY (its_ityp_ID, its_pst_ID)' );

			// Enable all post statuses for all post types
			$DB->query( 'INSERT INTO T_items__status_type (its_pst_ID, its_ityp_ID)
					( SELECT pst_ID, ityp_ID FROM T_items__type INNER JOIN T_items__status )' );

		upg_task_end();
	}

	if( upg_task_start( 12085, 'Update widget container "Item Single"...' ) )
	{	// part of 6.8.0-alpha
		$SQL = new SQL( 'Get all collections that have a widget container "Item Single"' );
		$SQL->SELECT( 'wi_ID, wi_coll_ID, wi_code, wi_order' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->WHERE( 'wi_sco_name = "Item Single"' );
		$SQL->ORDER_BY( 'wi_coll_ID, wi_order' );
		$coll_item_single_widgets = $DB->get_results( $SQL->get(), ARRAY_A, $SQL->title );
		$coll_widgets = array();
		foreach( $coll_item_single_widgets as $coll_item_single_widget )
		{
			if( ! isset( $coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] ) )
			{	// If the "Item Single" has no widget "Item Content":
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = 1;
			}
			if( $coll_item_single_widget['wi_code'] == 'item_tags' )
			{ // If the "Item Single" contains widget "Item Tags" then make order of this widget a negative
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = -1;
			}
			if( $coll_item_single_widget['wi_code'] == 'item_attachments' && $coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] > 0 )
			{	// If the "Item Single" contains widget "Item Content" and the widget order is positive then keep an order of this widget:
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = $coll_item_single_widget['wi_order'] + 1;
			}
		}

		$item_tags_widget_rows = array();
		foreach( $coll_widgets as $coll_ID => $widget_order )
		{	// Insert new widget "Item Tags" to each collection that has a container "Item Single" with no existing "Item Tags" widget :
			if( $widget_order > 0 )
			{
				$item_tags_widget_rows[] = '( '.$coll_ID.', "Item Single", '.$widget_order.', "item_tags" )';
				// Check and update not unique widget orders:
				$not_unique_widget_ID = $DB->get_var( 'SELECT wi_ID
					FROM '.$tableprefix.'widget
					WHERE wi_coll_ID = '.$coll_ID.'
						AND wi_sco_name = "Item Single"
						AND wi_order = '.$widget_order );
				if( $not_unique_widget_ID > 0 )
				{	// The collection has not unique widget order:
					$update_order_widgets = array();
					foreach( $coll_item_single_widgets as $coll_item_single_widget )
					{
						if( $coll_item_single_widget['wi_coll_ID'] == $coll_ID && $coll_item_single_widget['wi_order'] >= $widget_order )
						{	// Increase a widget order to avoid mysql errors of duplicate entry:
							$update_order_widgets[] = $coll_item_single_widget['wi_ID'];
						}
					}
					for( $w = count( $update_order_widgets ) - 1; $w >= 0 ; $w-- )
					{	// Update not unique widget orders:
						$DB->query( 'UPDATE '.$tableprefix.'widget
								SET   wi_order = wi_order + 1
								WHERE wi_ID = '.$update_order_widgets[ $w ] );
					}
				}
			}
		}
		if( count( $item_tags_widget_rows ) )
		{	// Insert new widgets "Item Tags" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $item_tags_widget_rows ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12090, 'Creating table for Hits aggregations...' ) )
	{	// part of 6.8.0-alpha
		db_create_table( 'T_hits__aggregate', "
			hagg_ID           INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			hagg_date         DATE NOT NULL DEFAULT '2000-01-01',
			hagg_coll_ID      INT(11) UNSIGNED NULL DEFAULT NULL,
			hagg_type         ENUM('standard','rss','admin','ajax', 'service', 'api') COLLATE ascii_general_ci DEFAULT 'standard' NOT NULL,
			hagg_referer_type ENUM('search','special','spam','referer','direct','self') COLLATE ascii_general_ci NOT NULL,
			hagg_agent_type   ENUM('robot','browser','unknown') COLLATE ascii_general_ci DEFAULT 'unknown' NOT NULL,
			hagg_count        INT(11) UNSIGNED NOT NULL,
			PRIMARY KEY       (hagg_ID),
			UNIQUE            hagg_date_coll_ID_types (hagg_date, hagg_coll_ID, hagg_type, hagg_referer_type, hagg_agent_type)",
			'ENGINE = myisam');
		upg_task_end();
	}

	if( upg_task_start( 12095, 'Creating table for aggregations of hit sessions...' ) )
	{	// part of 6.8.0-alpha
		db_create_table( 'T_hits__aggregate_sessions', "
			hags_ID            INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			hags_date          DATE NOT NULL DEFAULT '2000-01-01',
			hags_coll_ID       INT(11) UNSIGNED NULL DEFAULT NULL,
			hags_count_browser INT(11) UNSIGNED NOT NULL DEFAULT 0,
			hags_count_api     INT(11) UNSIGNED NOT NULL DEFAULT 0,
			PRIMARY KEY        (hags_ID),
			UNIQUE             hags_date_coll_ID (hags_date, hags_coll_ID)",
			'ENGINE = myisam' );
		upg_task_end();
	}

	if( upg_task_start( 12100, 'Update widget container "Item Single" by adding "Item Location" widget...' ) )
	{	// part of 6.8.0-alpha
		$SQL = new SQL( 'Get all collections that have a widget container "Item Single"' );
		$SQL->SELECT( 'wi_ID, wi_coll_ID, wi_code, wi_order' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->WHERE( 'wi_sco_name = "Item Single"' );
		$SQL->ORDER_BY( 'wi_coll_ID, wi_order' );
		$coll_item_single_widgets = $DB->get_results( $SQL->get(), ARRAY_A, $SQL->title );
		$coll_widgets = array();
		$coll_attachments_widget = array();
		foreach( $coll_item_single_widgets as $coll_item_single_widget )
		{
			if( ! isset( $coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] ) )
			{	// If the "Item Single" has no widget "Item Content":
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = 1;
			}
			if( $coll_item_single_widget['wi_code'] == 'item_content' && ! in_array( $coll_item_single_widget['wi_coll_ID'], $coll_attachments_widget ) )
			{ // If the "Item Single" contains widget "Item Content" then take order of this widget
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = $coll_item_single_widget['wi_order'] + 1;
			}
			if( $coll_item_single_widget['wi_code'] == 'item_attachments' )
			{ // If the "Item Single" contains widget "Item Attachments" then take order of this widget
				$coll_attachments_widget[] = $coll_item_single_widget['wi_coll_ID'];
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = $coll_item_single_widget['wi_order'] + 1;
			}
		}

		$item_locations_widget_rows = array();
		foreach( $coll_widgets as $coll_ID => $widget_order )
		{	// Insert new widget "Item Location" to each collection that has a container "Item Single":
			$item_locations_widget_rows[] = '( '.$coll_ID.', "Item Single", '.$widget_order.', "item_location" )';
			// Check and update not unique widget orders:
			$not_unique_widget_ID = $DB->get_var( 'SELECT wi_ID
				 FROM '.$tableprefix.'widget
				WHERE wi_coll_ID = '.$coll_ID.'
					AND wi_sco_name = "Item Single"
					AND wi_order = '.$widget_order );
			if( $not_unique_widget_ID > 0 )
			{	// The collection has not unique widget order:
				$update_order_widgets = array();
				foreach( $coll_item_single_widgets as $coll_item_single_widget )
				{
					if( $coll_item_single_widget['wi_coll_ID'] == $coll_ID && $coll_item_single_widget['wi_order'] >= $widget_order )
					{	// Increase a widget order to avoid mysql errors of duplicate entry:
						$update_order_widgets[] = $coll_item_single_widget['wi_ID'];
					}
				}
				for( $w = count( $update_order_widgets ) - 1; $w >= 0 ; $w-- )
				{	// Update not unique widget orders:
					$DB->query( 'UPDATE '.$tableprefix.'widget
							SET   wi_order = wi_order + 1
							WHERE wi_ID = '.$update_order_widgets[ $w ] );
				}
			}
		}
		if( count( $item_locations_widget_rows ) )
		{	// Insert new widgets "Item Locations" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $item_locations_widget_rows ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12105, 'Upgrade items table...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( "ALTER TABLE T_items__item
			MODIFY post_status ENUM('published','community','deprecated','protected','private','review','draft','redirected') COLLATE ascii_general_ci NOT NULL DEFAULT 'draft'" );
		upg_task_end();
	}

	if( upg_task_start( 12110, 'Upgrade comments table...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( "ALTER TABLE T_comments
			MODIFY comment_status ENUM('published','community','deprecated','protected','private','review','draft','trash') COLLATE ascii_general_ci DEFAULT 'draft' NOT NULL" );
		upg_task_end();
	}

	if( upg_task_start( 12115, 'Upgrading collections table...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_blogs
			MODIFY blog_type VARCHAR( 16 ) COLLATE ascii_general_ci DEFAULT "std" NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12120, 'Upgrade locales table...' ) )
	{ // part of 6.8.0-alpha
		db_add_col( 'T_locales', 'loc_longdatefmt', 'varchar(20) COLLATE ascii_general_ci NOT NULL default "Y-m-d" AFTER loc_datefmt' );
		db_add_col( 'T_locales', 'loc_extdatefmt', 'varchar(20) COLLATE ascii_general_ci NOT NULL default "Y M d" AFTER loc_longdatefmt' );

		// Update existing locales
		$DB->query( 'UPDATE T_locales	SET loc_longdatefmt = REPLACE( loc_datefmt, "y", "Y")' );
		$DB->query( 'UPDATE T_locales	SET loc_extdatefmt = REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( loc_longdatefmt, "m", "M"), ".", " " ), "-", " " ), "/", " "), "\\\\", " ")' );
		upg_task_end();
	}

	if( upg_task_start( 12125, 'Upgrade locales table...' ) )
	{	// part of 6.8.0-alpha
		db_add_col( 'T_locales', 'loc_input_datefmt', 'varchar(20) COLLATE ascii_general_ci NOT NULL default "Y-m-d" AFTER loc_extdatefmt' );
		db_add_col( 'T_locales', 'loc_input_timefmt', 'varchar(20) COLLATE ascii_general_ci NOT NULL default "H:i:s" AFTER loc_shorttimefmt' );

		// Allow only numeric date formats:
		$SQL = new SQL( 'Get all short date formats"' );
		$SQL->SELECT( 'loc_locale, loc_datefmt, loc_timefmt' );
		$SQL->FROM( 'T_locales' );
		$db_locale_rows = $DB->get_results( $SQL->get(), ARRAY_A, $SQL->title );

		foreach( $db_locale_rows as $loc_data )
		{
			$loc_data_datefmt = $loc_data['loc_datefmt'];

			if( preg_match( '/[^dDjmnYy:\.,\-_\/\\\\ ]/', $loc_data_datefmt ) )
			{	// If locale date format contains at least one invalid character then use default date format:
				$loc_data_datefmt = 'Y-m-d';
			}

			$DB->query( 'UPDATE T_locales
				  SET loc_input_datefmt = '.$DB->quote( $loc_data_datefmt ).',
				      loc_input_timefmt = "H:i:s"
				WHERE loc_locale = '.$DB->quote( $loc_data['loc_locale'] ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12130, 'Create new widget container "Item Single Header"...' ) )
	{	// part of 6.8.0-alpha
		$SQL = new SQL( 'Get all collections that have a widget container "Item Single"' );
		$SQL->SELECT( 'wi_ID, wi_coll_ID, wi_order, wi_enabled, wi_code, wi_params, blog_type' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->FROM_add( 'LEFT JOIN T_blogs ON blog_id = wi_coll_ID' );
		$SQL->WHERE( 'wi_sco_name = "Item Single"' );
		$SQL->ORDER_BY( 'wi_coll_ID, wi_order' );
		$coll_item_single_widgets = $DB->get_results( $SQL->get(), ARRAY_A, $SQL->title );
		$coll_widgets = array();
		foreach( $coll_item_single_widgets as $coll_item_single_widget )
		{
			if( ! isset( $coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] ) )
			{	// If the "Item Single" has no widget "Item Content":
				$coll_widgets[ $coll_item_single_widget['wi_coll_ID'] ] = $coll_item_single_widget['blog_type'];
			}
		}

		$item_info_line_widget_rows = array();
		foreach( $coll_widgets as $coll_ID => $blog_type )
		{	// Insert new widget "Item Info Line" to each collection that has a container "Item Single":
			if( in_array( $blog_type, array( 'forum', 'group' ) ) )
			{
				$item_info_line_widget_rows[] = '( '.$coll_ID.', "Item Single Header", 10, "item_info_line", "a:14:{s:5:\"title\";s:0:\"\";s:9:\"flag_icon\";i:1;s:14:\"permalink_icon\";i:0;s:13:\"before_author\";s:10:\"started_by\";s:11:\"date_format\";s:8:\"extended\";s:9:\"post_time\";i:1;s:12:\"last_touched\";i:1;s:8:\"category\";i:0;s:9:\"edit_link\";i:0;s:16:\"widget_css_class\";s:0:\"\";s:9:\"widget_ID\";s:0:\"\";s:16:\"allow_blockcache\";i:0;s:11:\"time_format\";s:4:\"none\";s:12:\"display_date\";s:12:\"date_created\";}" )';
			}
			else
			{
				$item_info_line_widget_rows[] = '( '.$coll_ID.', "Item Single Header", 10, "item_info_line", NULL )';
			}
		}
		if( count( $item_info_line_widget_rows ) )
		{	// Insert new widget "Item Info Line" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code, wi_params )
			  VALUES '.implode( ', ', $item_info_line_widget_rows ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12135, 'Upgrade table of user field definitions...' ) )
	{	// part of 6.8.0-alpha
		$DB->query( 'ALTER TABLE T_users__fielddefs
			MODIFY ufdf_code varchar(20) COLLATE ascii_bin UNIQUE NOT NULL COMMENT "Code MUST be lowercase ASCII only"' );
		upg_task_end();
	}

	if( upg_task_start( 12140, 'Updating file types table...' ) )
	{	// part of 6.7.10-stable moved here so it also applies to 6.8.3 -> 6.8.4 upgrades
		$DB->query( 'UPDATE T_filetypes
				SET ftyp_allowed = "admin"
			WHERE ftyp_extensions REGEXP "[[:<:]]swf[[:>:]]"' );
		upg_task_end();
	}

	if( upg_task_start( 12145, 'Upgrade Temporary IDs table...' ) )
	{	// part of 6.8.4-stable
		$DB->query( 'ALTER TABLE T_temporary_ID
			ADD tmp_coll_ID INT(11) UNSIGNED NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12150, 'Upgrade categories table...' ) )
	{	// part of 6.8.4-alpha
		db_add_col( 'T_categories', 'cat_image_file_ID', 'int(10) unsigned  NULL AFTER cat_blog_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12155, 'Renaming notification logo setting...' ) )
	{ // part of 6.8.5-stable
		$notification_logo = $DB->get_var( 'SELECT set_value FROM T_settings WHERE set_name = "notification_logo"' );
		if( !empty( $notification_logo ) )
		{
			if( is_numeric( $notification_logo ) )
			{ // We have a numeric value, it's possible that this is already a file_ID.
			  // Make sure that the integer is a valid file ID and an image file before setting it as the notification_logo_file_ID.
				$notification_logo = intval( $notification_logo );
				$file_type = $DB->get_var( 'SELECT file_type FROM T_files WHERE file_ID = '.$notification_logo );
				if( $file_type && $file_type == 'image' )
				{
					$DB->query( 'INSERT INTO T_settings ( set_name, set_value ) VALUES ( "notification_logo_file_ID", '.$notification_logo.' )' );
				}
			}

			// Remove previous notification logo setting
			$DB->query( 'DELETE FROM T_settings WHERE set_name = "notification_logo"' );
		}
		upg_task_end();
	}

	if( upg_task_start( 12160, 'Renaming user setting...' ) )
	{	// part of 6.8.6-stable
		$DB->query( 'UPDATE T_users__usersettings
			  SET uset_name = "user_registered_from_domain"
			WHERE uset_name = "user_domain"' );
		upg_task_end();
	}

	if( upg_task_start( 12161, 'Updating attachment positions...' ) )
	{	// part of 6.8.7-stable
		$DB->query( 'UPDATE T_links
			INNER JOIN T_files ON file_ID = link_file_ID
			       AND file_type NOT IN ( "image", "audio", "video" )
			  SET link_position = "attachment"
			WHERE link_position = "aftermore"' );
		upg_task_end();
	}

	if( upg_task_start( 12165, 'Upgrade table of users...' ) )
	{	// part of 6.9.0-beta
		db_add_col( 'T_users', 'user_pass_driver', 'VARCHAR(16) NOT NULL default "evo$md5" AFTER user_salt' );
		$DB->query( 'UPDATE T_users
			  SET user_pass_driver = "evo$salted"
			WHERE user_salt != ""' );
		upg_task_end();
	}

	if( upg_task_start( 12170, 'Updating users pass storage...' ) )
	{	// part of 6.9.0-beta
		$DB->query( 'ALTER TABLE T_users MODIFY COLUMN user_pass VARBINARY(32)' );
		$DB->query( 'UPDATE T_users SET user_pass = LOWER( HEX( user_pass ) )' );
		$DB->query( 'ALTER TABLE T_users MODIFY COLUMN user_pass VARCHAR(64) NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12175, 'Upgrade table of users...' ) )
	{	// part of 6.9.0-beta
		$DB->query( 'ALTER TABLE T_users
			MODIFY user_salt VARCHAR(32) NOT NULL default ""' );
		upg_task_end();
	}

	if( upg_task_start( 12180, 'Updating base domains table...' ) )
	{	// part of 6.9.0-beta
		db_drop_index( 'T_basedomains', 'dom_type_name' );

		$SQL = new SQL( 'Get all domains with duplicated names' );
		$SQL->SELECT( 'dom_name AS name, GROUP_CONCAT( dom_ID ) AS ids, GROUP_CONCAT( dom_status ) AS statuses' );
		$SQL->FROM( 'T_basedomains' );
		$SQL->GROUP_BY( 'dom_name' );
		$SQL->HAVING( 'COUNT( dom_ID ) > 1' );
		$SQL->ORDER_BY( 'dom_ID' );
		$domains = $DB->get_results( $SQL->get(), OBJECT, $SQL->title );

		if( count( $domains ) )
		{	// If at least one duplicated domain is detected,
			// Find what domains should be kept and what deleted depending on their status:
			$status_orders = array( 'blocked', 'suspect', 'unknown', 'trusted' );
			$duplicated_domains = array();
			foreach( $domains as $domain )
			{
				$domain_IDs = explode( ',', $domain->ids );
				$domain_statuses = explode( ',', $domain->statuses );
				foreach( $status_orders as $status_order )
				{
					$s_index = array_search( $status_order, $domain_statuses );
					if( $s_index !== false )
					{	// If the highest status is detected:
						$prefered_domain_ID = $domain_IDs[ $s_index ];
						unset( $domain_IDs[ $s_index ] );
						// key is ID of domain which must be used,
						// values are IDs of domains which must be replaced and deleted completely:
						$duplicated_domains[ $prefered_domain_ID ] = $domain_IDs;
						break;
					}
				}
			}

			$update_users_sql = array();
			$update_hits_sql = array();
			$delete_duplicated_domains = array();
			foreach( $duplicated_domains as $keep_domain_ID => $delete_domain_IDs )
			{
				$update_users_sql[] = 'WHEN user_email_dom_ID IN ( '.implode( ',', $delete_domain_IDs ).' ) THEN '.$keep_domain_ID;
				$update_hits_sql[] = 'WHEN hit_referer_dom_ID IN ( '.implode( ',', $delete_domain_IDs ).' ) THEN '.$keep_domain_ID;
				$delete_duplicated_domains = array_merge( $delete_duplicated_domains, $delete_domain_IDs );
			}

			// Update user email domains IDs that will deleted to use related domain IDs that will be retained:
			$DB->query( 'UPDATE T_users
				SET user_email_dom_ID = CASE
					'.implode( ' ', $update_users_sql ).'
					ELSE user_email_dom_ID
				END' );

			// Update hitlist log referer domains IDs:
			$DB->query( 'UPDATE T_hitlog
				SET hit_referer_dom_ID = CASE
					'.implode( ' ', $update_hits_sql ).'
					ELSE hit_referer_dom_ID
				END' );

			// Delete the duplicate domains, order by status: blocked > suspect > unknown > trusted, keep the first one:
			$DB->query( 'DELETE
				 FROM T_basedomains
				WHERE dom_ID IN ( '.implode( ', ', $delete_duplicated_domains ).' )' );
		}

		// Add an unique index for domain name:
		db_add_index( 'T_basedomains', 'dom_name', 'dom_name', 'UNIQUE INDEX' );

		// Add a comment to user_email_dom_ID:
		$DB->query( 'ALTER TABLE T_users MODIFY user_email_dom_ID int(10) unsigned NULL COMMENT "Used for email statistics"' );
		upg_task_end();
	}

	if( upg_task_start( 12185, 'Upgrading posts table...' ) )
	{	// part of 6.9.0-beta
		db_add_col( 'T_items__item', 'post_contents_last_updated_ts', 'TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\' AFTER post_last_touched_ts' );
		$DB->query( 'UPDATE T_items__item
			SET post_contents_last_updated_ts = post_last_touched_ts' );
		upg_task_end();
	}

	if( upg_task_start( 12186, 'Updating attachment positions...' ) )
	{	// part of 6.9.0-stable (This is a duplicated 12161 block from 6.8.7-stable)
		$DB->query( 'UPDATE T_links
			INNER JOIN T_files ON file_ID = link_file_ID
			       AND file_type NOT IN ( "image", "audio", "video" )
			  SET link_position = "attachment"
			WHERE link_position = "aftermore"' );
		upg_task_end();
	}

	if( upg_task_start( 12190, 'Upgrade skins table...' ) )
	{	// part of 6.9.0-beta
		$DB->query( 'ALTER TABLE T_skins__skin
			MODIFY skin_type enum("normal","feed","sitemap","mobile","tablet","rwd") COLLATE ascii_general_ci NOT NULL default "normal"' );
		upg_task_end();
	}

	if( upg_task_start( 12200, 'Updating group permissions...' ) )
	{	// part of 6.9.0-beta
		$DB->query( 'UPDATE T_groups__groupsettings
			SET gset_name = "perm_skins_root",
				gset_value = CASE gset_value WHEN "allowed" THEN "edit" ELSE "none" END
			WHERE gset_name = "perm_templates"' );
		upg_task_end();
	}

	if( upg_task_start( 12210, 'Create new widget container "Forum Front Secondary Area" for forums...' ) )
	{	// part of 6.9.1-beta
		$DB->begin();
		$SQL = new SQL( 'Get all "forum" collections' );
		$SQL->SELECT( 'blog_ID' );
		$SQL->FROM( 'T_blogs' );
		$SQL->WHERE( 'blog_type = "forum"' );
		$forum_collections = $DB->get_col( $SQL->get() );

		$item_tags_widget_rows = array();
		foreach( $forum_collections as $coll_ID )
		{	// Insert new widget "Collection Activity Stats" to each forum collection
			$widget_order = 10;
			$item_tags_widget_rows[] = '( '.$coll_ID.', "Forum Front Secondary Area", '.$widget_order.', "coll_activity_stats" )';
			// Check and update not unique widget orders just to make sure:
			$not_unique_widget_ID = $DB->get_var( 'SELECT wi_ID
				FROM '.$tableprefix.'widget
				WHERE wi_coll_ID = '.$coll_ID.'
					AND wi_sco_name = "Forum Front Secondary Area"
					AND wi_order = '.$widget_order );
			if( $not_unique_widget_ID > 0 )
			{	// The collection has no unique widget order, move all widgets with wi_order >= 10:
				$DB->query( 'UPDATE '.$tableprefix.'widget
						SET wi_order = wi_order + 1
						WHERE wi_coll_ID ='.$coll_ID.'
						AND wi_sco_name = "Forum Front Secondary Area"
						AND wi_order >= '.$widget_order );
			}
		}
		if( count( $item_tags_widget_rows ) )
		{	// Insert new widgets "Item Tags" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $item_tags_widget_rows ) );
		}
		$DB->commit();
		upg_task_end();
	}

	if( upg_task_start( 12220, 'Create new widget container "Item Page"...' ) )
	{ // part of 6.9.1-beta
		// Get all collections
		$collections = $DB->get_col( 'SELECT blog_ID FROM T_blogs ORDER BY blog_ID ASC' );
		$coll_widgets = array();

		// Default widget for Item Page
		$item_page_widgets = array(
				'item_content' => 10,
				'item_attachments' => 15,
				'item_seen_by' => 50,
				'item_vote' => 60
			);

		foreach( $collections as $collection_ID )
		{
			foreach( $item_page_widgets as $page_widget => $widget_order )
			{
				$coll_widgets[] = '( '.$collection_ID.', "Item Page", '.$widget_order.', "'.$page_widget.'" )';
			}
		}

		if( count( $coll_widgets ) )
		{	// Insert new widgets into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $coll_widgets ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 12230, 'Update menu link widget...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "basic_menu_link"
			WHERE wi_code = "menu_link"' );
		upg_task_end();
	}

	if( upg_task_start( 12240, 'Create new widget "Item Link"...' ) )
	{	// part of 6.9.1-beta
		$SQL = new SQL( 'Get all collections that have a widget container "Item Single"' );
		$SQL->SELECT( 'wi_ID, wi_coll_ID, wi_order, wi_enabled, wi_code, wi_params, blog_type' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->FROM_add( 'LEFT JOIN T_blogs ON blog_id = wi_coll_ID' );
		$SQL->WHERE( 'wi_sco_name = "Item Single"' );
		$SQL->ORDER_BY( 'wi_coll_ID, wi_order' );
		$collections = $DB->get_results( $SQL->get(), ARRAY_A, $SQL->title );

		$item_single_rows = array();
		foreach( $collections as $collection )
		{	// Insert new widget "Collection Activity Stats" to each forum collection
			if( ! isset( $item_single_rows[$collection['wi_coll_ID']] ) )
			{
				$item_single_rows[$collection['wi_coll_ID']] = 15; // default item_attachments widget order
			}

			if( in_array( $collection['wi_code'], array( 'item_content', 'item_attachments' ) ) )
			{
				$item_single_rows[$collection['wi_coll_ID']] = $collection['wi_order'] + 1;
			}
		}

		$item_link_widget_rows = array();
		foreach( $item_single_rows as $coll_ID => $wi_order )
		{
			$item_link_widget_rows[] = '( '.$coll_ID.', "Item Single", '.$wi_order.', "item_link" )';
			// Check and update not unique widget orders just to make sure:
			$not_unique_widget_ID = $DB->get_var( 'SELECT wi_ID
				FROM '.$tableprefix.'widget
				WHERE wi_coll_ID = '.$coll_ID.'
					AND wi_sco_name = "Item Single"
					AND wi_order = '.$wi_order );

			if( $not_unique_widget_ID > 0 )
			{	// The collection has no unique widget order, move all widget order >= to current order:
				$DB->query( 'UPDATE '.$tableprefix.'widget
						SET wi_order = wi_order + 1
						WHERE wi_coll_ID = '.$coll_ID.'
						AND wi_sco_name = "Item Single"
						AND wi_order >= '.$wi_order.'
						ORDER BY wi_order DESC');
			}
		}

		if( count( $item_link_widget_rows ) )
		{	// Insert new widgets "Item Link" into DB:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code )
			  VALUES '.implode( ', ', $item_link_widget_rows ) );
		}

		upg_task_end();
	}

	if( upg_task_start( 12250, 'Upgrading table of post type custom fields...' ) )
	{	// part of 6.9.1-beta
		db_add_col( 'T_items__type_custom_field', 'itcf_note', 'VARCHAR(255) NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12260, 'Upgrading table for a latest versions of the PO files...' ) )
	{	// part of 6.9.1-beta
		db_add_index( 'T_i18n_translated_string', 'itst_iost_ID_locale', 'itst_iost_ID, itst_locale' );
		upg_task_end();
	}

	if( upg_task_start( 12262, 'Upgrade datetime fields to timestamp type in users table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_users
			MODIFY user_created_datetime   TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			MODIFY user_profileupdate_date TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12263, 'Upgrade datetime fields to timestamp type in cron tasks table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_cron__task
			MODIFY ctsk_start_datetime TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12264, 'Upgrade datetime fields to timestamp type in cron logs table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_cron__log
			MODIFY clog_realstart_datetime TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			MODIFY clog_realstop_datetime  TIMESTAMP NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12265, 'Upgrade datetime fields to timestamp type in posts table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_items__item
			MODIFY post_datestart    TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			MODIFY post_datedeadline TIMESTAMP NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12266, 'Upgrade datetime fields to timestamp type in comments table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_comments
			MODIFY comment_date TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12267, 'Upgrade datetime fields to timestamp type in post versions table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_items__version
			MODIFY iver_edit_datetime TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12268, 'Upgrade datetime fields to timestamp type in links table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_links
			MODIFY link_datecreated  TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\',
			MODIFY link_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12269, 'Upgrade datetime fields to timestamp type in message threads table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_messaging__thread
			MODIFY thrd_datemodified TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12270, 'Upgrade datetime fields to timestamp type in messages table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_messaging__message
			MODIFY msg_datetime TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12279, 'Upgrade datetime fields to timestamp type in user reports table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_users__reports
			MODIFY urep_datetime TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12280, 'Upgrade datetime fields to timestamp type in message contacts table...' ) )
	{	// part of 6.9.1-beta
		$DB->query( 'ALTER TABLE T_messaging__contact
			MODIFY mct_last_contact_datetime TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 12290, 'Add new type "URL" for custom fields of item types...' ) )
	{	// part of 6.9.2-beta
		$DB->query( 'ALTER TABLE T_items__type_custom_field
			MODIFY COLUMN itcf_type ENUM( "double", "varchar", "text", "html", "url" ) COLLATE ascii_general_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12300, 'Clear invalid values of item type custom fields...' ) )
	{	// part of 6.9.2-beta
		$SQL = new SQL( 'Get all item types with custom fields' );
		$SQL->SELECT( 'GROUP_CONCAT( DISTINCT "\"custom_", itcf_type, "_", itcf_ID, "\"" ) AS valid_setting_names, ' );
		$SQL->SELECT_add( 'GROUP_CONCAT( DISTINCT post_ID ) AS post_IDs' );
		$SQL->FROM( 'T_items__type_custom_field' );
		$SQL->FROM_add( 'INNER JOIN T_items__item ON itcf_ityp_ID = post_ityp_ID' );
		$SQL->GROUP_BY( 'itcf_ityp_ID' );
		$custom_fields = $DB->get_results( $SQL->get(), OBJECT, $SQL->title );

		foreach( $custom_fields as $custom_field )
		{	// Delete all invalid/obsolete values of each item type with custom fields:
			$DB->query( 'DELETE FROM T_items__item_settings
				WHERE iset_item_ID IN ( '.$custom_field->post_IDs.' )
					AND iset_name LIKE "custom\_%"
					AND iset_name NOT IN ( '.$custom_field->valid_setting_names.' )',
				'Clear invalid/obsolete values of item type custom fields' );
		}
		upg_task_end();
	}

	if( upg_task_start( 12310, 'Upgrading goals table...' ) )
	{	// part of 6.9.3-beta
		db_add_index( 'T_track__goal', 'goal_gcat_ID', 'goal_gcat_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12320, 'Updating plugin "Short Links"...' ) )
	{	// part of 6.9.3-beta
		$SQL = new SQL( 'Get old collection setting "Links without brackets" of the plugin "Short Links"' );
		$SQL->SELECT( 'cset_coll_ID, plug_ID, cset_name, cset_value' );
		$SQL->FROM( 'T_plugins' );
		$SQL->FROM_add( 'INNER JOIN T_coll_settings ON cset_name = CONCAT( "plugin", plug_ID, "_link_without_brackets" )' );
		$SQL->WHERE( 'plug_code = "b2evWiLi"' );
		$SQL->WHERE_and( 'cset_value = 1' );
		$coll_settings = $DB->get_results( $SQL->get(), OBJECT, $SQL->title );

		// Default values for new setting:
		$new_short_links_setting = array(
				'absolute_urls'   => 1,
				'relative_urls'   => 0,
				'slugs'           => 1,
				'item_id'         => 1,
				'without_backets' => 0,
			);
		foreach( $coll_settings as $coll_setting )
		{	// Update old plugin setting to new format:
			$new_short_links_setting['without_backets'] = $coll_setting->cset_value;
			$DB->query( 'UPDATE T_coll_settings
				  SET cset_name = '.$DB->quote( 'plugin'.$coll_setting->plug_ID.'_link_types' ).',
				      cset_value = '.$DB->quote( serialize( $new_short_links_setting ) ).'
				WHERE cset_coll_ID = '.$coll_setting->cset_coll_ID.'
				  AND cset_name = '.$DB->quote( $coll_setting->cset_name ) );
		}

		upg_task_end();
	}

	if( upg_task_start( 12330, 'Upgrade categories table...' ) )
	{	// part of 6.9.4
		db_add_col( 'T_categories', 'cat_social_media_image_file_ID', 'int(10) unsigned  NULL AFTER cat_image_file_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12340, 'Upgrade collections table...' ) )
	{	// part of 6.9.4
		$DB->begin();

		// Add new fields to collections table
		db_add_col( 'T_blogs', 'blog_tablet_skin_ID', 'int(10) unsigned NULL AFTER blog_order' );
		db_add_col( 'T_blogs', 'blog_mobile_skin_ID', 'int(10) unsigned NULL AFTER blog_order' );
		db_add_col( 'T_blogs', 'blog_normal_skin_ID', 'int(10) unsigned NULL AFTER blog_order' );

		// Populate new fields from existing collection skin settings
		$DB->query( 'UPDATE T_blogs a
				LEFT JOIN (
					SELECT
						cset_coll_ID,
						GROUP_CONCAT( IF( cset_name = "normal_skin_ID", cset_value, NULL ) ) AS normal_skin_ID,
						GROUP_CONCAT( IF( cset_name = "mobile_skin_ID", cset_value, NULL ) ) AS mobile_skin_ID,
						GROUP_CONCAT( IF( cset_name = "tablet_skin_ID", cset_value, NULL ) ) AS tablet_skin_ID
					FROM T_coll_settings a
					WHERE cset_name LIKE "%_skin_ID"
					GROUP BY cset_coll_ID
				) b ON b.cset_coll_ID = a.blog_ID
				SET a.blog_normal_skin_ID = SUBSTRING_INDEX( b.normal_skin_ID, " ", -1 ),
					a.blog_mobile_skin_ID = SUBSTRING_INDEX( b.mobile_skin_ID, " ", -1 ),
					a.blog_tablet_skin_ID = SUBSTRING_INDEX( b.tablet_skin_ID, " ", -1 )' );

		// Delete old collection skin settings
		$DB->query( 'DELETE FROM T_coll_settings WHERE cset_name LIKE "%_skin_ID"' );

		$DB->commit();
		upg_task_end();
	}

	if( upg_task_start( 12350, 'Adding item versions index...' ) )
	{ // part of 6.9.4
		db_add_index( 'T_items__version', 'iver_edit_user_ID', 'iver_edit_user_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12358, 'Remove skins with duplicating class names...' ) )
	{	// part of 6.9.4
		// Get skins with duplicating class names which will have a conflict in 12360:
		$skins_SQL = new SQL( 'Get skins with duplicating class names' );
		$skins_SQL->SELECT( 's2.skin_ID, s1.skin_ID' );
		$skins_SQL->FROM( 'T_skins__skin AS s1' );
		$skins_SQL->FROM_add( 'INNER JOIN T_skins__skin AS s2 ON s1.skin_folder = CONCAT( s2.skin_folder, "_skin" )' );
		// Array key is ID of old skin, Array value is ID of new skin with folder suffix "_skin":
		$duplicating_skins = $DB->get_assoc( $skins_SQL );

		if( count( $duplicating_skins ) > 0 )
		{
			// Get collections with old skin format folder(wihtout suffix "_skin"):
			$old_skins = array_keys( $duplicating_skins );
			$skin_fields = array( 'blog_normal_skin_ID', 'blog_mobile_skin_ID', 'blog_tablet_skin_ID' );
			$blog_SQL = new SQL( 'Get collection with dupplicating skin class names' );
			$blog_SQL->SELECT( 'blog_ID, blog_normal_skin_ID, blog_mobile_skin_ID, blog_tablet_skin_ID' );
			$blog_SQL->FROM( 'T_blogs' );
			foreach( $skin_fields as $skin_field )
			{
				$blog_SQL->WHERE_or( $skin_field.' IN ( '.$DB->quote( $old_skins ).' )' );
			}
			$old_skin_colls = $DB->get_results( $blog_SQL );

			// Update collections:
			foreach( $old_skin_colls as $old_skin_coll )
			{
				$coll_update_fields = array();
				$coll_settings_update_fields = array();
				foreach( $skin_fields as $skin_field )
				{
					if( isset( $duplicating_skins[ $old_skin_coll->$skin_field ] ) )
					{	// If the skin is old folder format then use skin ID of new format skin folder:
						$coll_update_fields[] = $skin_field.' = '.$duplicating_skins[ $old_skin_coll->$skin_field ];
						$coll_settings_update_fields[] = $skin_field.' = '.$duplicating_skins[ $old_skin_coll->$skin_field ];
					}
				}
				// Update collection skin IDs:
				$DB->query( 'UPDATE T_blogs
					  SET '.implode( ', ', $coll_update_fields ).'
					WHERE blog_ID = '.$old_skin_coll->blog_ID );
			}

			foreach( $duplicating_skins as $old_skin_ID => $new_skin_ID )
			{
				// Update custom skin settings of collections:
				$DB->query( 'UPDATE T_coll_settings
					  SET cset_name = CONCAT( '.$DB->quote( 'skin'.$new_skin_ID.'_' ).', SUBSTRING( cset_name, '.( strlen( 'skin'.$old_skin_ID.'_' ) + 1 ).' ) )
					WHERE cset_name LIKE "skin'.$old_skin_ID.'_%" ' );
				// Update default skins:
				$DB->query( 'UPDATE T_settings
					  SET set_value = '.$new_skin_ID.'
					WHERE set_name LIKE "%_skin_ID"
					  AND set_value LIKE '.$old_skin_ID );
			}

			// Remove duplicating skins with old format folders:
			$DB->query( 'DELETE FROM T_skins__skin
				WHERE skin_ID IN ( '.$DB->quote( $old_skins ).' )' );
			$DB->query( 'DELETE FROM T_skins__container
				WHERE sco_skin_ID IN ( '.$DB->quote( $old_skins ).' )' );
		}

		upg_task_end();
	}

	if( upg_task_start( 12360, 'Upgrading skin table...' ) )
	{ // part of 6.9.4
		db_add_col( 'T_skins__skin', 'skin_class', 'varchar(32) NOT NULL AFTER skin_ID' );

		$DB->query( 'UPDATE T_skins__skin
				SET skin_class = IF(SUBSTRING(skin_folder, -5) = "_skin",
						CONCAT( LEFT( skin_folder, CHAR_LENGTH( skin_folder ) - 5 ), "_Skin" ),
						CONCAT( skin_folder, "_Skin" ) )' );

		db_add_index( 'T_skins__skin', 'skin_class', 'skin_class', 'UNIQUE' );

		upg_task_end();
	}

	if( upg_task_start( 12365, 'Upgrading settings tables...' ) )
	{	// part of 6.9.4
		db_modify_col( 'T_settings',              'set_value',  'VARCHAR(10000) NULL' );
		db_modify_col( 'T_groups__groupsettings', 'gset_value', 'VARCHAR(10000) NULL' );
		db_modify_col( 'T_users__usersettings',   'uset_value', 'VARCHAR(10000) NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12370, 'Creating email newsletters table...' ) )
	{	// part of 6.10.0-beta
		db_create_table( 'T_email__newsletter', "
			enlt_ID     INT UNSIGNED NOT NULL AUTO_INCREMENT,
			enlt_name   VARCHAR(255) NOT NULL,
			enlt_label  VARCHAR(255) NULL,
			enlt_active TINYINT(1) UNSIGNED DEFAULT 1,
			PRIMARY KEY (enlt_ID)",
			'ENGINE = myisam' );
		upg_task_end();
	}

	if( upg_task_start( 12380, 'Creating default newsletters...' ) )
	{	// part of 6.10.0-beta
		$DB->query( 'INSERT INTO T_email__newsletter ( enlt_name, enlt_label )
			VALUES ( "News", "Send me news about this site." ),
			       ( "Promotions", "I want to receive ADs that may be relevant to my interests." )' );
		upg_task_end();
	}

	if( upg_task_start( 12390, 'Creating email newsletter subscriptions table...' ) )
	{	// part of 6.10.0-beta
		db_create_table( 'T_email__newsletter_subscription', "
			enls_user_ID INT UNSIGNED NOT NULL,
			enls_enlt_ID INT UNSIGNED NOT NULL,
			PRIMARY KEY (enls_user_ID, enls_enlt_ID)",
			'ENGINE = myisam' );
		upg_task_end();
	}

	if( upg_task_start( 12400, 'Updating user newsletter subscriptions...' ) )
	{	// part of 6.10.0-beta
		$news_SQL = new SQL( 'Get all users which are subscribed on news about this site' );
		$news_SQL->SELECT( 'user_ID' );
		$news_SQL->FROM( 'T_users' );
		$news_SQL->FROM_add( 'LEFT OUTER JOIN T_users__usersettings ON user_ID = uset_user_ID' );
		$news_SQL->FROM_add( 'AND uset_name = "newsletter_news"' );
		$news_SQL->WHERE( 'uset_value = 1' );
		// If General setting "newsletter_news" = 1 we also should include all users without defined user's setting "newsletter_news":
		$news_SQL->WHERE_or( 'uset_value IS NULL' );
		$news_user_IDs = $DB->get_col( $news_SQL->get(), 0, $news_SQL->title );

		$ads_SQL = new SQL( 'Get all users which are subscribed to receive ADs' );
		$ads_SQL->SELECT( 'user_ID' );
		$ads_SQL->FROM( 'T_users' );
		$ads_SQL->FROM_add( 'LEFT OUTER JOIN T_users__usersettings ON user_ID = uset_user_ID' );
		$ads_SQL->FROM_add( 'AND uset_name = "newsletter_ads"' );
		$ads_SQL->WHERE( 'uset_value = 1' );
		$ads_user_IDs = $DB->get_col( $ads_SQL->get(), 0, $ads_SQL->title );

		$newsletter_subscription_rows = array();
		foreach( $news_user_IDs as $news_user_ID )
		{
			$newsletter_subscription_rows[] = '( '.$news_user_ID.', 1 )';
		}
		foreach( $ads_user_IDs as $ads_user_ID )
		{
			$newsletter_subscription_rows[] = '( '.$ads_user_ID.', 2 )';
		}

		if( count( $newsletter_subscription_rows ) )
		{	// Insert user newsletter subscriptions:
			$DB->query( 'INSERT INTO T_email__newsletter_subscription ( enls_user_ID, enls_enlt_ID )
				VALUES '.implode( ',', $newsletter_subscription_rows ) );

			// Clear old user settings:
			$DB->query( 'DELETE FROM T_users__usersettings
				WHERE uset_name IN ( "newsletter_news", "newsletter_ads" )' );
		}

		upg_task_end();
	}

	if( upg_task_start( 12410, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.0-beta
		$DB->query( 'ALTER TABLE T_email__campaign
			MODIFY ecmp_email_title VARCHAR(255) NOT NULL' );
		$DB->query( 'UPDATE T_email__campaign
			  SET ecmp_email_title = ecmp_name
			WHERE ecmp_email_title = ""' );
		upg_task_end();
	}

	if( upg_task_start( 12420, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.0-beta
		$DB->query( 'ALTER TABLE T_email__campaign
			MODIFY ecmp_ID      INT UNSIGNED NOT NULL AUTO_INCREMENT,
			DROP   ecmp_name,
			ADD    ecmp_enlt_ID INT UNSIGNED NOT NULL AFTER ecmp_date_ts' );
		// Set first newsletter by default:
		$DB->query( 'UPDATE T_email__campaign
			SET ecmp_enlt_ID = 1' );
		upg_task_end();
	}

	if( upg_task_start( 12430, 'Updating general default newsletter settings...' ) )
	{	// part of 6.10.0-beta
		$old_settings_SQL = new SQL( 'Get all default newsletter settings' );
		$old_settings_SQL->SELECT( 'set_name, set_value' );
		$old_settings_SQL->FROM( 'T_settings' );
		$old_settings_SQL->WHERE( 'set_name IN ( "def_newsletter_news", "def_newsletter_ads" )' );
		$old_settings = $DB->get_assoc( $old_settings_SQL->get(), 0, $old_settings_SQL->title );

		$new_settings = array();
		if( ! isset( $old_settings['def_newsletter_news'] ) || $old_settings['def_newsletter_news'] )
		{	// First newsletter setting(news) is enabled by default or saved in DB:
			$new_settings[] = '1';
		}
		if( ! empty( $old_settings['def_newsletter_ads'] ) )
		{	// Second newsletter setting(ads) is saved in DB:
			$new_settings[] = '2';
		}
		// Insert new newsletter setting instead of old:
		$DB->query( 'INSERT INTO T_settings ( set_name, set_value )
			VALUES ( "def_newsletters", "'.implode( ',', $new_settings ).'" )' );
		// Delete old newsletter settings:
		$DB->query( 'DELETE FROM T_settings
			WHERE set_name IN ( "def_newsletter_news", "def_newsletter_ads" )' );

		upg_task_end();
	}

	if( upg_task_start( 12440, 'Upgrading email newsletters table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_email__newsletter', 'enlt_order', 'INT NULL DEFAULT NULL' );
		$DB->query( 'UPDATE T_email__newsletter
			SET enlt_order = enlt_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12450, 'Upgrading email newsletter subscriptions table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_email__newsletter_subscription', 'enls_last_sent_manual_ts', 'TIMESTAMP NULL' );
		db_add_col( 'T_email__newsletter_subscription', 'enls_send_count', 'INT UNSIGNED NOT NULL DEFAULT 0' );
		$DB->query( 'UPDATE T_email__newsletter_subscription
			SET enls_send_count = (
					SELECT COUNT( csnd_camp_ID )
					  FROM T_email__campaign_send
					 WHERE csnd_user_ID = enls_user_ID
					   AND csnd_emlog_ID IS NOT NULL
				),
				enls_last_sent_manual_ts = (
					SELECT MAX( emlog_timestamp )
					  FROM T_email__campaign_send
					 INNER JOIN T_email__log ON emlog_ID = csnd_emlog_ID
					 WHERE csnd_user_ID = enls_user_ID
				)' );
		upg_task_end();
	}

	if( upg_task_start( 12460, 'Upgrading email newsletter subscriptions table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_email__newsletter_subscription', 'enls_subscribed', 'TINYINT(1) UNSIGNED DEFAULT 1' );
		db_add_col( 'T_email__newsletter_subscription', 'enls_subscribed_ts', 'TIMESTAMP NULL' );
		db_add_col( 'T_email__newsletter_subscription', 'enls_unsubscribed_ts', 'TIMESTAMP NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12470, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_email__campaign', 'ecmp_auto_sent_ts', 'TIMESTAMP NULL AFTER ecmp_sent_ts' );
		db_add_col( 'T_email__campaign', 'ecmp_auto_send', 'ENUM("no", "subscription", "sequence") COLLATE ascii_general_ci NOT NULL DEFAULT "no"' );
		db_add_col( 'T_email__campaign', 'ecmp_sequence', 'INT UNSIGNED NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12480, 'Upgrading email campaign send data table...' ) )
	{ // part of 6.10.0-beta
		$DB->query( 'ALTER TABLE T_email__campaign_send
				ADD csnd_status ENUM("ready_to_send", "ready_to_resend", "sent", "send_error", "skipped" ) COLLATE ascii_general_ci NOT NULL DEFAULT "ready_to_send" AFTER csnd_user_ID' );

		$DB->query( 'UPDATE T_email__campaign_send
				SET csnd_status = IF( csnd_emlog_ID IS NULL, "ready_to_send", "sent" )' );
		upg_task_end();
	}

	if( upg_task_start( 12490, 'Creating user tags and user-to-tag tables...' ) )
	{	// part of 6.10.0-beta
		db_create_table( 'T_users__tag', "
			utag_ID INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
			utag_name VARCHAR(200) NOT NULL,
			PRIMARY KEY (utag_ID),
			UNIQUE utag_name(utag_name)",
			'ENGINE = innodb' );

		db_create_table( 'T_users__usertag', "
			uutg_user_ID INT(11) UNSIGNED NOT NULL,
			uutg_emtag_ID INT(11) UNSIGNED NOT NULL,
			PRIMARY KEY (uutg_user_ID, uutg_emtag_ID),
			UNIQUE taguser(uutg_emtag_ID, uutg_user_ID)",
			'ENGINE = innodb' );
		upg_task_end();
	}

	if( upg_task_start( 12500, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.0-beta
		db_modify_col( 'T_email__campaign', 'ecmp_auto_send', 'ENUM("no", "subscription") COLLATE ascii_general_ci NOT NULL DEFAULT "no"' );
		db_drop_col( 'T_email__campaign', 'ecmp_sequence' );
		upg_task_end();
	}

	if( upg_task_start( 12510, 'Upgrading email log table...' ) )
	{ // part of 6.10.0-beta
		db_modify_col( 'T_email__log', 'emlog_result', 'ENUM( "ok", "error", "blocked", "simulated", "ready_to_send" ) COLLATE ascii_general_ci NOT NULL DEFAULT "ok"' );
		db_add_col( 'T_email__log', 'emlog_key', 'CHAR(32) NULL DEFAULT NULL AFTER emlog_ID' );
		db_add_col( 'T_email__log', 'emlog_last_open_ts', 'TIMESTAMP NULL AFTER emlog_message' );
		db_add_col( 'T_email__log', 'emlog_last_click_ts', 'TIMESTAMP NULL AFTER emlog_last_open_ts' );

		// Populate emlog_key of existing records
		$DB->query( 'UPDATE T_email__log
				SET emlog_key = MD5( CONCAT(emlog_ID, emlog_subject) )
				WHERE emlog_key IS NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12520, 'Creating automation tables...' ) )
	{	// part of 6.10.0-beta
		db_create_table( 'T_automation__automation', '
			autm_ID            INT UNSIGNED NOT NULL AUTO_INCREMENT,
			autm_name          VARCHAR(255) NOT NULL,
			autm_status        ENUM("paused", "active") DEFAULT "paused",
			autm_enlt_ID       INT UNSIGNED NOT NULL,
			autm_owner_user_ID INT UNSIGNED NOT NULL,
			autm_autostart     TINYINT(1) UNSIGNED DEFAULT 1,
			PRIMARY KEY        (autm_ID)' );

		db_create_table( 'T_automation__step', '
			step_ID                    INT UNSIGNED NOT NULL AUTO_INCREMENT,
			step_autm_ID               INT UNSIGNED NOT NULL,
			step_order                 INT NOT NULL DEFAULT 1,
			step_label                 VARCHAR(500) NULL,
			step_type                  ENUM("if_condition", "send_campaign", "notify_owner", "add_usertag", "remove_usertag", "subscribe", "unsubscribe") COLLATE ascii_general_ci NOT NULL DEFAULT "if_condition",
			step_info                  TEXT NULL,
			step_yes_next_step_ID      INT NULL,
			step_yes_next_step_delay   INT UNSIGNED NULL,
			step_no_next_step_ID       INT NULL,
			step_no_next_step_delay    INT UNSIGNED NULL,
			step_error_next_step_ID    INT NULL,
			step_error_next_step_delay INT UNSIGNED NULL,
			PRIMARY KEY                (step_ID),
			UNIQUE                     step_autm_ID_order (step_autm_ID, step_order)' );
		upg_task_end();
	}

	if( upg_task_start( 12530, 'Creating automation user state table...' ) )
	{	// part of 6.10.0-beta
		db_create_table( 'T_automation__user_state', '
			aust_autm_ID      INT UNSIGNED NOT NULL,
			aust_user_ID      INT UNSIGNED NOT NULL,
			aust_next_step_ID INT UNSIGNED NULL,
			aust_next_exec_ts TIMESTAMP NULL,
			PRIMARY KEY       (aust_autm_ID, aust_user_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 12540, 'Upgrading email campaigns table...' ) )
	{ // part of 6.10.0-beta
		db_add_col( 'T_email__campaign', 'ecmp_user_tag', 'VARCHAR(255) NULL AFTER ecmp_auto_send' );
		upg_task_end();
	}

	if( upg_task_start( 12550, 'Upgrading email campaign send data table...' ) )
	{ // part of 6.10.0-beta
		db_add_col( 'T_email__campaign_send', 'csnd_clicked_unsubscribe', 'TINYINT(1) UNSIGNED DEFAULT 0 AFTER csnd_emlog_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12560, 'Upgrading automation step table...' ) )
	{	// part of 6.10.0-beta
		db_modify_col( 'T_automation__step', 'step_type', 'ENUM("if_condition", "send_campaign", "notify_owner", "add_usertag", "remove_usertag", "subscribe", "unsubscribe", "start_automation") COLLATE ascii_general_ci NOT NULL DEFAULT "if_condition"' );
		upg_task_end();
	}

	if( upg_task_start( 12570, 'Creating automation newsletter table...' ) )
	{	// part of 6.10.0-beta
		db_create_table( 'T_automation__newsletter', '
			aunl_autm_ID   INT UNSIGNED NOT NULL,
			aunl_enlt_ID   INT UNSIGNED NOT NULL,
			aunl_autostart TINYINT(1) UNSIGNED DEFAULT 1,
			aunl_autoexit  TINYINT(1) UNSIGNED DEFAULT 1,
			PRIMARY KEY    (aunl_autm_ID, aunl_enlt_ID)' );
		// Copy single tied newsletter links from automations table to new created table:
		$DB->query( 'INSERT INTO T_automation__newsletter
			( aunl_autm_ID, aunl_enlt_ID, aunl_autostart )
			SELECT autm_ID, autm_enlt_ID, autm_autostart
			  FROM T_automation__automation' );
		// Remove old columns:
		db_upgrade_cols( 'T_automation__automation', array(
			'DROP' => array( 'autm_enlt_ID', 'autm_autostart' ),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12580, 'Upgrading email campaign send data table...' ) )
	{	// part of 6.10.0-beta
		db_upgrade_cols( 'T_email__campaign_send', array(
			'ADD' => array(
				'csnd_last_sent_ts'  => 'TIMESTAMP NULL',
				'csnd_last_open_ts'  => 'TIMESTAMP NULL',
				'csnd_last_click_ts' => 'TIMESTAMP NULL',
			),
		) );
		// Update new added tables from email log table:
		$DB->query( 'UPDATE T_email__campaign_send
			INNER JOIN T_email__log ON csnd_emlog_ID = emlog_ID
			  SET csnd_last_sent_ts = emlog_timestamp,
			      csnd_last_open_ts = emlog_last_open_ts,
			      csnd_last_click_ts = emlog_last_click_ts' );
		upg_task_end();
	}

	if( upg_task_start( 12590, 'Upgrading email log table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_email__log', 'emlog_camp_ID', 'INT UNSIGNED NULL DEFAULT NULL AFTER emlog_last_click_ts' );
		$DB->query( 'UPDATE T_email__log
				INNER JOIN T_email__campaign_send ON csnd_emlog_ID = emlog_ID
				SET emlog_camp_ID = csnd_camp_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12600, 'Upgrading email log table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_email__log', 'emlog_autm_ID', 'INT UNSIGNED DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12610, 'Upgrading email newsletter subscriptions table...' ) )
	{	// part of 6.10.0-beta
		db_upgrade_cols( 'T_email__newsletter_subscription', array(
			'ADD' => array(
				'enls_last_open_ts'  => 'TIMESTAMP NULL AFTER enls_last_sent_manual_ts',
				'enls_last_click_ts' => 'TIMESTAMP NULL AFTER enls_last_open_ts',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12620, 'Upgrading automation newsletter table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_automation__newsletter', 'aunl_order', 'INT NOT NULL DEFAULT 1' );
		$DB->query( 'UPDATE T_automation__newsletter
			SET aunl_order = aunl_enlt_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12630, 'Upgrading email campaign send data table...' ) )
	{	// part of 6.10.0-beta
		db_upgrade_cols( 'T_email__campaign', array(
			'ADD' => array(
				'ecmp_user_tag_like' => 'VARCHAR(255) NULL AFTER ecmp_user_tag',
				'ecmp_user_tag_dislike' => 'VARCHAR(255) NULL AFTER ecmp_user_tag_like',
			),
		) );

		db_upgrade_cols( 'T_email__campaign_send', array(
			'ADD' => array(
				'csnd_like' => 'TINYINT(1) NULL DEFAULT NULL AFTER csnd_last_click_ts'
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12640, 'Upgrading user organizations tables...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_users__organization', 'org_perm_priority', 'ENUM( "owner and member", "owner" ) COLLATE ascii_general_ci NOT NULL DEFAULT "owner and member"' );
		db_add_col( 'T_users__user_org', 'uorg_priority', 'INT(11) NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12650, 'Upgrading email campaign table...' ) )
	{ // part of 6.10.0-beta
		db_upgrade_cols( 'T_email__campaign', array(
			'ADD' => array(
				'ecmp_user_tag_cta1' => 'VARCHAR(255) NULL AFTER ecmp_user_tag',
				'ecmp_user_tag_cta2' => 'VARCHAR(255) NULL AFTER ecmp_user_tag_cta1',
				'ecmp_user_tag_cta3' => 'VARCHAR(255) NULL AFTER ecmp_user_tag_cta2',
			),
		) );

		db_upgrade_cols( 'T_email__campaign_send', array(
			'ADD' => array(
				'csnd_cta1' => 'TINYINT(1) NULL DEFAULT NULL AFTER csnd_like',
				'csnd_cta2' => 'TINYINT(1) NULL DEFAULT NULL AFTER csnd_cta1',
				'csnd_cta3' => 'TINYINT(1) NULL DEFAULT NULL AFTER csnd_cta2',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12660, 'Updating user settings table...' ) )
	{	// part of 6.10.0-beta
		$DB->query( 'REPLACE INTO T_users__usersettings ( uset_user_ID, uset_name, uset_value )
			SELECT user_ID, "welcome_message_sent", 1
			  FROM T_users
			 WHERE user_status IN ( "activated", "autoactivated" ) ' );
		upg_task_end();
	}

	if( upg_task_start( 12670, 'Upgrading cron logs table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_cron__log', 'clog_actions_num', 'INT UNSIGNED NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12680, 'Upgrading email campaign table...' ) )
	{	// part of 6.10.0-beta
		db_upgrade_cols( 'T_email__campaign', array(
			'ADD' => array(
				'ecmp_user_tag_sendskip' => 'VARCHAR(255) NULL AFTER ecmp_auto_send',
				'ecmp_user_tag_sendsuccess' => 'VARCHAR(255) NULL AFTER ecmp_user_tag_sendskip',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12690, 'Upgrading polls table...' ) )
	{ // part of 6.10.0-beta
		db_add_col( 'T_polls__question', 'pqst_max_answers', 'INT(11) UNSIGNED NOT NULL DEFAULT 1 AFTER pqst_question_text' );

		// Remove autoincrement first
		$DB->query( 'ALTER TABLE T_polls__answer MODIFY pans_ID INT(11) UNSIGNED NOT NULL' );

		// Drop indexes
		$DB->query( 'ALTER TABLE T_polls__answer DROP INDEX `PRIMARY`, DROP INDEX pans_pqst_user_ID' );

		// Drop previous primary column
		db_drop_col( 'T_polls__answer', 'pans_ID' );

		// Add new primary key
		$DB->query( 'ALTER TABLE T_polls__answer ADD PRIMARY KEY (pans_pqst_ID, pans_user_ID, pans_popt_ID)' );

		upg_task_end();
	}

	if( upg_task_start( 12700, 'Upgrading cron tasks table...' ) )
	{	// part of 6.10.1-stable
		db_add_col( 'T_cron__task', 'ctsk_max_exec_time', 'INT UNSIGNED DEFAULT 600 AFTER ctsk_repeat_variation' );
		upg_task_end();
	}

	if( upg_task_start( 12710, 'Upgrading email campaign table...' ) )
	{ // part of 6.10.1-stable
		db_add_col( 'T_email__campaign', 'ecmp_name', 'VARCHAR(255) NOT NULL AFTER ecmp_enlt_ID' );
		$DB->query( 'UPDATE T_email__campaign SET ecmp_name = ecmp_email_title' );
		upg_task_end();
	}

	if( upg_task_start( 12720, 'Upgrading cron tasks table...' ) )
	{	// part of 6.10.1-stable
		db_drop_col( 'T_cron__task', 'ctsk_max_exec_time' );
		// Settings per cron job type like "cjob_timeout_send-non-activated-account-reminders" requires more length:
		db_modify_col( 'T_settings', 'set_name', 'VARCHAR(64) COLLATE ascii_general_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12730, 'Upgrading email campaign table...' ) )
	{ // part of 6.10.1-stable
		db_add_col( 'T_email__campaign', 'ecmp_email_defaultdest', 'VARCHAR(255) NULL AFTER ecmp_email_title' );
		$DB->query( 'UPDATE T_email__campaign SET ecmp_email_defaultdest = '.$DB->quote( $baseurl ) );
		upg_task_end();
	}

	if( upg_task_start( 12735, 'Creating default item type "Content Block"...' ) )
	{	// part of 6.10.1-stable
		$SQL = new SQL( 'Check at least one item type with usage "content-block" for existence' );
		$SQL->SELECT( 'ityp_ID' );
		$SQL->FROM( 'T_items__type' );
		$SQL->WHERE( 'ityp_usage = "content-block"' );
		$SQL->LIMIT( 1 );
		if( ! $DB->get_var( $SQL ) )
		{	// Create one default content block item type:
			$r = $DB->query( 'INSERT INTO T_items__type ( ityp_name, ityp_usage, ityp_allow_breaks, ityp_allow_featured, ityp_use_comments )
					VALUES ( '.$DB->quote( 'Content Block' ).', '.$DB->quote( 'content-block' ).', 0, 0, 0 )' );
			if( $r && $DB->insert_id > 0 )
			{	// Enable new created item type for all collections:
				$DB->query( 'INSERT INTO T_items__type_coll ( itc_ityp_ID, itc_coll_ID )
					SELECT '.$DB->insert_id.', blog_ID
					  FROM T_blogs' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 12740 ) )
	{	// part of 6.10.1-stable

		/* ---- Install basic widgets for containers "Login Required" and "Access Denied": ---- START */
		global $basic_widgets_insert_sql_rows;
		$basic_widgets_insert_sql_rows = array();

		/**
		 * Add a widget to global array in order to insert it in DB by single SQL query later
		 *
		 * @param integer Blog ID
		 * @param string Container name
		 * @param string Type
		 * @param string Code
		 * @param integer Order
		 * @param array|string|NULL Widget params
		 * @param integer 1 - enabled, 0 - disabled
		 */
		function add_basic_widget_12740( $blog_ID, $container_name, $code, $type, $order, $params = NULL, $enabled = 1 )
		{
			global $basic_widgets_insert_sql_rows, $DB;

			if( is_null( $params ) )
			{ // NULL
				$params = 'NULL';
			}
			elseif( is_array( $params ) )
			{ // array
				$params = $DB->quote( serialize( $params ) );
			}
			else
			{ // string
				$params = $DB->quote( $params );
			}

			$basic_widgets_insert_sql_rows[] = '( '
				.$blog_ID.', '
				.$DB->quote( $container_name ).', '
				.$order.', '
				.$enabled.', '
				.$DB->quote( $type ).', '
				.$DB->quote( $code ).', '
				.$params.' )';
		}

		$SQL = new SQL();
		$SQL->SELECT( 'blog_ID, cat_ID' );
		$SQL->FROM( 'T_blogs' );
		$SQL->FROM_add( 'LEFT JOIN T_categories ON cat_blog_ID = blog_ID AND cat_meta = 0' );
		$SQL->WHERE( '( SELECT COUNT( wi_coll_ID ) FROM '.$tableprefix.'widget WHERE wi_coll_ID = blog_ID AND wi_sco_name IN ( "Login Required", "Access Denied" ) AND wi_code = "content_block" ) = 0' );
		$SQL->ORDER_BY( 'blog_ID, cat_ID DESC' );
		$collections = $DB->get_assoc( $SQL );
		if( count( $collections ) > 0 )
		{	// If at least one collection exists:
			$SQL = new SQL( 'Get first item type with usage "content-block"' );
			$SQL->SELECT( 'ityp_ID' );
			$SQL->FROM( 'T_items__type' );
			$SQL->WHERE( 'ityp_usage = "content-block"' );
			$SQL->ORDER_BY( 'ityp_ID' );
			$SQL->LIMIT( 1 );
			$content_block_ityp_ID = intval( $DB->get_var( $SQL ) );

			// We're going to need some environment in order to init item type cache and create item:
			load_class( 'items/model/_item.class.php', 'Item' );
			upg_init_environment( 'Settings,Plugins' );

			// Get collection for info pages(shared content blocks) in order to create a help and a register content block items below:
			$info_Blog = & get_setting_Blog( 'info_blog_ID' );

			foreach( $collections as $coll_ID => $cat_ID )
			{
				if( ! $info_Blog || ! isset( $login_required_Item ) || ! isset( $access_denied_Item ) )
				{	// Create a help and a register content block items once for info/shared collection if it is defined
					// otherwise create them for each current collection:
					if( $info_Blog )
					{	// Use info pages collection if it is defined:
						$content_block_Blog = $info_Blog;
					}
					else
					{	// Otherwise use current collection:
						$BlogCache = & get_BlogCache();
						$content_block_Blog = & $BlogCache->get_by_ID( $coll_ID, false, false );
					}
					if( $content_block_Blog )
					{	// The collection must be always defined but we need this additional check to avoid unexpected die error during upgrade process:
						$cat_ID = $collections[ $content_block_Blog->ID ];
						if( $cat_ID === NULL )
						{	// Create new category if collection has no categories:
							load_class( 'chapters/model/_chapter.class.php', 'Chapter' );
							$new_Chapter = new Chapter( NULL, $content_block_Blog->ID );
							$new_Chapter->set( 'name', T_('Uncategorized') );
							$new_Chapter->set( 'urlname', $content_block_Blog->get( 'urlname' ).'-main' );
							$new_Chapter->dbinsert();
							$cat_ID = $new_Chapter->ID;
							$ChapterCache = & get_ChapterCache();
							$ChapterCache->add( $new_Chapter );
						}
						task_begin( 'Creating default content blocks "Login Required" and "Access Denied" for'
							.( $info_Blog && $info_Blog->ID == $content_block_Blog->ID ? ' info pages' : '' ).' collection #'.$content_block_Blog->ID.'... ' );
						$login_required_Item = new Item();
						$login_required_Item->set_tags_from_string( 'demo' );
						$login_required_Item->insert( 1, T_('Login Required'), '<p class="center">'.T_( 'You need to log in before you can access this section.' ).'</p>',
							date( 'Y-m-d H:i:s' ), $cat_ID, array(), '!published', '#', 'login-required', '', 'open', array( 'default' ), $content_block_ityp_ID );
						// Create a register content block item for info/shared collection:
						$access_denied_Item = new Item();
						$access_denied_Item->set_tags_from_string( 'demo' );
						$access_denied_Item->insert( 1, T_('Access Denied'), '<p class="center">'.T_( 'You are not a member of this collection, therefore you are not allowed to access it.' ).'</p>',
							date( 'Y-m-d H:i:s' ), $cat_ID, array(), '!published', '#', 'access-denied', '', 'open', array( 'default' ), $content_block_ityp_ID );
						task_end();
					}
				}

				task_begin( 'Installing default "Login Required" and "Access Denied" widgets for collection #'.$coll_ID.'... ' );
				/* Login Required */
				add_basic_widget_12740( $coll_ID, 'Login Required', 'content_block', 'core', 10, array( 'item_slug' => $login_required_Item->get( 'urltitle' ) ) );
				add_basic_widget_12740( $coll_ID, 'Login Required', 'user_login', 'core', 20, array( 'title' => T_( 'Log in to your account' ) ) );
				/* Access Denied */
				add_basic_widget_12740( $coll_ID, 'Access Denied', 'content_block', 'core', 10, array( 'item_slug' => $access_denied_Item->get( 'urltitle' ) ) );
				task_end();
			}
		}

		if( ! empty( $basic_widgets_insert_sql_rows ) )
		{	// Insert the widget records by single SQL query:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget( wi_coll_ID, wi_sco_name, wi_order, wi_enabled, wi_type, wi_code, wi_params ) '
								 .'VALUES '.implode( ', ', $basic_widgets_insert_sql_rows ) );
		}
		/* ---- Install basic widgets for containers "Login Required" and "Access Denied": ---- END */

		upg_task_end( false );
	}

	if( upg_task_start( 12750, 'Upgrading users table...' ) )
	{	// part of 6.10.1-stable
		db_modify_col( 'T_users', 'user_status', "enum( 'activated', 'manualactivated', 'autoactivated', 'closed', 'deactivated', 'emailchanged', 'failedactivation', 'new' ) COLLATE ascii_general_ci NOT NULL default 'new'" );
		upg_task_end();
	}

	if( upg_task_start( 12760, 'Upgrading users table...' ) )
	{	// part of 6.10.1-stable
		db_add_col( 'T_subscriptions', 'sub_items_mod', 'TINYINT(1) NOT NULL AFTER sub_items' );
		upg_task_end();
	}

	if( upg_task_start( 12770, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.1-stable
		db_add_col( 'T_email__campaign', 'ecmp_welcome', 'TINYINT(1) NOT NULL DEFAULT 0 AFTER ecmp_auto_send' );
		$SQL = new SQL( 'Find only single of welcome email campaign per list/newsletter' );
		$SQL->SELECT( 'ecmp_ID' );
		$SQL->FROM( 'T_email__campaign' );
		$SQL->WHERE( 'ecmp_auto_send = "subscription"' );
		$SQL->GROUP_BY( 'ecmp_enlt_ID' );
		$SQL->ORDER_BY( 'ecmp_ID' );
		$welcome_campaigns = $DB->get_col( $SQL );
		if( count( $welcome_campaigns ) > 0 )
		{	// Convert "At subscription" email campaigns to "Welcome":
			$DB->query( 'UPDATE T_email__campaign
				  SET ecmp_welcome = 1
				WHERE ecmp_ID IN ( '.$DB->quote( $welcome_campaigns ).' )' );
		}
		db_drop_col( 'T_email__campaign', 'ecmp_auto_send' );
		upg_task_end();
	}

	if( upg_task_start( 12780, 'Upgrading cron logs table...' ) )
	{	// part of 6.10.1-stable
		db_modify_col( 'T_cron__log', 'clog_messages', 'MEDIUMTEXT' );
		upg_task_end();
	}

	if( upg_task_start( 12790, 'Upgrading for widgets "User log in"...' ) )
	{	// part of 6.10.1-stable
		$SQL = new SQL( 'Get widgets "User log in" to upgrade' );
		$SQL->SELECT( 'wi_ID, wi_coll_ID, wi_sco_name, wi_order, wi_params' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->WHERE( 'wi_code = "user_login"' );
		$login_widgets = $DB->get_results( $SQL );
		foreach( $login_widgets as $login_widget )
		{
			$login_widget_params = @unserialize( $login_widget->wi_params );
			if( ! $login_widget_params )
			{
				$login_widget_params = array();
			}

			if( $login_widget->wi_sco_name == 'Login Required' )
			{	// Make form buttons larger only for login widgets of the container "Login Required":
				$login_widget_params['login_button_class'] = 'btn btn-success btn-lg';
				$login_widget_params['register_link_class'] = 'btn btn-primary btn-lg pull-right';
				$DB->query( 'UPDATE '.$tableprefix.'widget
					  SET wi_params = '.$DB->quote( serialize( $login_widget_params ) ).'
					WHERE wi_ID = '.$DB->quote( $login_widget->wi_ID ) );
			}
			else
			{	// Add greetings widget after each login widget from any other container:
				// Firstly we should increase an order of next widgets to avoid error of unique order column:
				$DB->query( 'UPDATE '.$tableprefix.'widget
					  SET wi_order = wi_order + 1
					WHERE wi_coll_ID = '.$DB->quote( $login_widget->wi_coll_ID ).'
					  AND wi_sco_name = '.$DB->quote( $login_widget->wi_sco_name ).'
					  AND wi_order > '.$DB->quote( $login_widget->wi_order ).'
					ORDER BY wi_order DESC' );
				// Insert the widget:
				$login_widget_params['title'] = '';
				$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_code, wi_params )
					VALUES ( '.$DB->quote( $login_widget->wi_coll_ID ).', '
					.$DB->quote( $login_widget->wi_sco_name ).', '
					.$DB->quote( $login_widget->wi_order + 1 ).', '
					.'"user_greetings", '
					.$DB->quote( serialize( $login_widget_params ) ).' )' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 12800, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.1-stable
		db_add_col( 'T_email__campaign', 'ecmp_sync_plaintext', 'TINYINT(1) NOT NULL DEFAULT 1 AFTER ecmp_email_plaintext' );
		upg_task_end();
	}

	if( upg_task_start( 12810, 'Upgrading comments table...' ) )
	{	// part of 6.10.1-stable
		db_add_col( 'T_comments', 'comment_anon_notify', 'TINYINT(1) NOT NULL DEFAULT 0 AFTER comment_allow_msgform' );
		upg_task_end();
	}

	if( upg_task_start( 12820, 'Upgrading email campaign table...' ) )
	{ // part of 6.10.1-stable
		db_upgrade_cols( 'T_email__campaign', array(
			'ADD' => array(
				'ecmp_send_count'    => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_user_tag_dislike',
				'ecmp_open_count'    => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_send_count',
				'ecmp_img_loads'     => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_open_count',
				'ecmp_link_clicks'   => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_img_loads',
				'ecmp_cta1_clicks'   => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_link_clicks',
				'ecmp_cta2_clicks'   => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_cta1_clicks',
				'ecmp_cta3_clicks'   => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_cta2_clicks',
				'ecmp_like_count'    => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_cta3_clicks',
				'ecmp_dislike_count' => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_like_count',
				'ecmp_unsub_clicks'  => 'INT UNSIGNED NOT NULL DEFAULT 0 AFTER ecmp_dislike_count',
			),
		) );

		// Populate the new columns
		$DB->query( 'UPDATE T_email__campaign
				LEFT JOIN (
					SELECT
						csnd_camp_ID,
						SUM( IF( csnd_last_sent_ts IS NULL, 0, 1 ) ) AS send_count,
						SUM( IF( csnd_cta1 = 1, 1, 0 ) ) AS cta1_clicks,
						SUM( IF( csnd_cta2 = 1, 1, 0 ) ) AS cta2_clicks,
						SUM( IF( csnd_cta3 = 1, 1, 0 ) ) AS cta3_clicks,
						SUM( IF( csnd_like = 1, 1, 0 ) ) AS like_count,
						SUM( IF( csnd_like = -1, 1, 0 ) ) AS dislike_count,
						SUM( COALESCE( csnd_clicked_unsubscribe, 0 ) ) AS unsub_clicks,
						SUM( IF( csnd_last_open_ts IS NULL, 0, 1 ) ) AS img_loads,
						SUM( IF( csnd_last_click_ts IS NULL, 0, 1 ) ) AS link_clicks,
						SUM( IF( csnd_last_open_ts IS NOT NULL OR csnd_last_click_ts IS NOT NULL OR
							csnd_like IS NOT NULL OR csnd_cta1 IS NOT NULL OR csnd_cta2 IS NOT NULL OR csnd_cta3 IS NOT NULL, 1, 0 ) ) AS open_count
					FROM T_email__campaign_send
					WHERE csnd_emlog_ID IS NOT NULL
					GROUP BY csnd_camp_ID
				) AS a ON a.csnd_camp_ID = ecmp_ID
				SET
					ecmp_send_count = COALESCE( a.send_count, 0 ),
					ecmp_open_count = COALESCE( a.open_count, 0 ),
					ecmp_img_loads = COALESCE( a.img_loads, 0 ),
					ecmp_link_clicks = COALESCE( a.link_clicks, 0 ),
					ecmp_cta1_clicks = COALESCE( a.cta1_clicks, 0 ),
					ecmp_cta2_clicks = COALESCE( a.cta2_clicks, 0 ),
					ecmp_cta3_clicks = COALESCE( a.cta3_clicks, 0 ),
					ecmp_like_count = COALESCE( a.like_count, 0 ),
					ecmp_dislike_count = COALESCE( a.dislike_count, 0 ),
					ecmp_unsub_clicks = COALESCE( a.unsub_clicks, 0 )' );
		upg_task_end();
	}

	if( upg_task_start( 12830, 'Upgrading comments table...' ) )
	{	// part of 6.10.1-stable
		db_add_col( 'T_comments', 'comment_anon_notify_last', 'VARCHAR(16) COLLATE ascii_general_ci NULL default NULL AFTER comment_anon_notify' );
		upg_task_end();
	}

	if( upg_task_start( 12840, 'Upgrading automation step table...' ) )
	{	// part of 6.10.0-beta
		db_add_col( 'T_automation__step', 'step_diagram', 'VARCHAR(64) NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12850, 'Creating user profile visit counter table...' ) )
	{ // part of 6.10.1-stable
		db_create_table( 'T_users__profile_visit_counters', '
				upvc_user_ID  INT(11) UNSIGNED NOT NULL,
				upvc_total_unique_visitors INT(10) UNSIGNED NOT NULL DEFAULT 0,
				upvc_last_view_ts TIMESTAMP NOT NULL DEFAULT "2000-01-01 00:00:00",
				upvc_new_unique_visitors INT(10) UNSIGNED NOT NULL DEFAULT 0,
				PRIMARY KEY (upvc_user_ID)' );

		// Populate profile visit counters table
		$DB->query( 'INSERT INTO T_users__profile_visit_counters (upvc_user_ID, upvc_total_unique_visitors, upvc_new_unique_visitors)
				SELECT user_ID, COALESCE( upv.total_unique, 0 ), COALESCE( upv.total_unique, 0 )
				FROM T_users
				LEFT JOIN
				(
					SELECT upv_visited_user_ID, COUNT(*) AS total_unique
					FROM T_users__profile_visits
					GROUP BY upv_visited_user_ID
				) AS upv
				ON upv.upv_visited_user_ID = user_ID' );

		upg_task_end();
	}

	if( upg_task_start( 12860 ) )
	{	// part of 6.10.1-stable

		/* ---- Install basic widgets for containers "Help" and "Register": ---- START */
		global $basic_widgets_insert_sql_rows;
		$basic_widgets_insert_sql_rows = array();

		/**
		 * Add a widget to global array in order to insert it in DB by single SQL query later
		 *
		 * @param integer Blog ID
		 * @param string Container name
		 * @param string Type
		 * @param string Code
		 * @param integer Order
		 * @param array|string|NULL Widget params
		 * @param integer 1 - enabled, 0 - disabled
		 */
		function add_basic_widget_12860( $blog_ID, $container_name, $code, $type, $order, $params = NULL, $enabled = 1 )
		{
			global $basic_widgets_insert_sql_rows, $DB;

			if( is_null( $params ) )
			{ // NULL
				$params = 'NULL';
			}
			elseif( is_array( $params ) )
			{ // array
				$params = $DB->quote( serialize( $params ) );
			}
			else
			{ // string
				$params = $DB->quote( $params );
			}

			$basic_widgets_insert_sql_rows[] = '( '
				.$blog_ID.', '
				.$DB->quote( $container_name ).', '
				.$order.', '
				.$enabled.', '
				.$DB->quote( $type ).', '
				.$DB->quote( $code ).', '
				.$params.' )';
		}

		$SQL = new SQL();
		$SQL->SELECT( 'blog_ID, cat_ID' );
		$SQL->FROM( 'T_blogs' );
		$SQL->FROM_add( 'LEFT JOIN T_categories ON cat_blog_ID = blog_ID AND cat_meta = 0' );
		$SQL->WHERE( '( SELECT COUNT( wi_coll_ID ) FROM '.$tableprefix.'widget WHERE wi_coll_ID = blog_ID AND wi_sco_name IN ( "Help", "Register" ) AND wi_code = "content_block" ) = 0' );
		$SQL->ORDER_BY( 'blog_ID, cat_ID DESC' );
		$collections = $DB->get_assoc( $SQL );
		if( count( $collections ) > 0 )
		{	// If at least one collection exists:

			$SQL = new SQL( 'Get first item type with usage "content-block"' );
			$SQL->SELECT( 'ityp_ID' );
			$SQL->FROM( 'T_items__type' );
			$SQL->WHERE( 'ityp_usage = "content-block"' );
			$SQL->ORDER_BY( 'ityp_ID' );
			$SQL->LIMIT( 1 );
			$content_block_ityp_ID = intval( $DB->get_var( $SQL ) );

			// We're going to need some environment in order to init item type cache and create item:
			load_class( 'items/model/_item.class.php', 'Item' );
			upg_init_environment( 'Settings,Plugins' );

			// Get collection for info pages(shared content blocks) in order to create a help and a register content block items below:
			$info_Blog = & get_setting_Blog( 'info_blog_ID' );

			foreach( $collections as $coll_ID => $cat_ID )
			{
				if( ! $info_Blog || ! isset( $help_Item ) || ! isset( $register_Item ) )
				{	// Create a help and a register content block items once for info/shared collection if it is defined
					// otherwise create them for each current collection:
					if( $info_Blog )
					{	// Use info pages collection if it is defined:
						$content_block_Blog = $info_Blog;
					}
					else
					{	// Otherwise use current collection:
						$BlogCache = & get_BlogCache();
						$content_block_Blog = & $BlogCache->get_by_ID( $coll_ID, false, false );
					}
					if( $content_block_Blog )
					{	// The collection must be always defined but we need this additional check to avoid unexpected die error during upgrade process:
						$cat_ID = $collections[ $content_block_Blog->ID ];
						if( $cat_ID === NULL )
						{	// Create new category if collection has no categories:
							load_class( 'chapters/model/_chapter.class.php', 'Chapter' );
							$new_Chapter = new Chapter( NULL, $content_block_Blog->ID );
							$new_Chapter->set( 'name', T_('Uncategorized') );
							$new_Chapter->set( 'urlname', $content_block_Blog->get( 'urlname' ).'-main' );
							$new_Chapter->dbinsert();
							$cat_ID = $new_Chapter->ID;
							$ChapterCache = & get_ChapterCache();
							$ChapterCache->add( $new_Chapter );
						}
						task_begin( 'Creating default content blocks "Help content" and "Register content" for'
							.( $info_Blog && $info_Blog->ID == $content_block_Blog->ID ? ' info pages' : '' ).' collection #'.$content_block_Blog->ID.'... ' );
						$help_Item = new Item();
						$help_Item->set_tags_from_string( 'demo' );
						$help_Item->insert( 1, T_('Help content'), '### '.T_('Email preferences')
							."\n\n"
							.sprintf( T_('You can see and change all your email subscriptions and notifications coming from this site by clicking <a %s>here</a>.'), 'href="'.$content_block_Blog->get( 'subsurl' ).'"' )
							."\n\n"
							.'### '.T_('Managing your personal information')
							."\n\n"
							.sprintf( T_('You can see and correct the personal details we know about you by clicking <a %s>here</a>.'), 'href="'.$content_block_Blog->get( 'profileurl' ).'"' )
							."\n\n"
							.'### '.T_('Closing your account')
							."\n\n"
							.sprintf( T_('You can close your account yourself by clicking <a %s>here</a>.'), 'href="'.$content_block_Blog->get( 'closeaccounturl' ).'"' ),
								date( 'Y-m-d H:i:s' ), $cat_ID, array(), '!published', '#', 'help-content', '', 'open', array( 'b2evMark' ), $content_block_ityp_ID );
						// Create a register content block item for info/shared collection:
						$register_Item = new Item();
						$register_Item->set_tags_from_string( 'demo' );
						$register_Item->insert( 1, T_('Register content'), T_('The information you provide in this form will be recorded in your user account.')
							."\n\n"
							.T_('You will be able to modify it (or even close your account) at any time after logging in with your username and password.')
							."\n\n"
							.T_('Should you forget your password, you will be able to reset it by receiving a link on your email address.')
							."\n\n"
							.T_('All other info is used to personalize your experience with this website.')
							."\n\n"
							.T_('This site may allow conversation between users.')
							.' '.T_('Your email address and password will not be shared with other users.')
							.' '.T_('All other information may be shared with other users.')
							.' '.T_('Do not provide information you are not willing to share.'),
								date( 'Y-m-d H:i:s' ), $cat_ID, array(), '!published', '#', 'register-content', '', 'open', array( 'b2WPAutP' ), $content_block_ityp_ID );
						task_end();
					}
				}

				task_begin( 'Installing default "Help" and "Register" widgets for collection #'.$coll_ID.'... ' );
				/* Help */
				add_basic_widget_12860( $coll_ID, 'Help', 'content_block', 'core', 10, array(
						'item_slug' => ( isset( $help_Item ) ? $help_Item->get( 'urltitle' ) : 'help-content' ),
						'title'     => T_('Personal Data & Privacy'),
					) );
				/* Register */
				add_basic_widget_12860( $coll_ID, 'Register', 'user_normal_register', 'core', 10 );
				add_basic_widget_12860( $coll_ID, 'Register', 'content_block', 'core', 20, array(
						'item_slug' => ( isset( $register_Item ) ? $register_Item->get( 'urltitle' ) : 'register-content' )
					) );
				task_end();
			}
		}

		if( ! empty( $basic_widgets_insert_sql_rows ) )
		{	// Insert the widget records by single SQL query:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget( wi_coll_ID, wi_sco_name, wi_order, wi_enabled, wi_type, wi_code, wi_params ) '
								 .'VALUES '.implode( ', ', $basic_widgets_insert_sql_rows ) );
		}
		/* ---- Install basic widgets for containers "Help" and "Register": ---- END */

		upg_task_end( false );
	}

	if( upg_task_start( 12870, 'Renaming registration widgets...' ) )
	{	// part of 6.10.1-stable
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "user_register_quick"
			WHERE wi_code = "user_register"' );
		$DB->query( 'UPDATE '.$tableprefix.'widget
			  SET wi_code = "user_register_standard"
			WHERE wi_code = "user_normal_register"' );
		upg_task_end();
	}

	if( upg_task_start( 12880, 'Adding Send reminders about inactive accounts threshold setting...' ) )
	{ // part of 6.10.1-stable
		$DB->query( "REPLACE INTO T_settings( set_name, set_value ) VALUES ( 'inactive_account_reminder_threshold', 0 )" );
		upg_task_end();
	}

	if( upg_task_start( 12890, 'Upgrading user fields table...' ) )
	{	// part of 6.10.1-stable
		db_add_index( 'T_users__fields', 'uf_user_ID', 'uf_user_ID' );
		upg_task_end();
	}

	if( upg_task_start( 12900, 'Upgrading system log table...' ) )
	{	// part of 6.10.1-stable
		db_modify_col( 'T_syslog', 'slg_object', 'ENUM("comment", "item", "user", "file", "email_log") COLLATE ascii_general_ci' );
		upg_task_end();
	}

	if( upg_task_start( 12910, 'Upgrading email campaign table...' ) )
	{ // part of 6.10.2-stable
		db_modify_col( 'T_email__campaign', 'ecmp_email_title', 'VARCHAR(255) NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12920, 'Upgrading post type custom fields table...' ) )
	{	// part of 6.10.3-stable
		db_upgrade_cols( 'T_items__type_custom_field', array(
			'ADD' => array(
				'itcf_public'          => 'TINYINT DEFAULT 1',
				'itcf_format'          => 'VARCHAR(2000) NULL',
				'itcf_formula'         => 'VARCHAR(2000) COLLATE ascii_general_ci NULL',
				'itcf_header_class'    => 'VARCHAR(255) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'itcf_cell_class'      => 'VARCHAR(255) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'itcf_link'            => 'ENUM( "nolink", "linkto", "permalink", "zoom", "linkpermzoom", "permzoom", "linkperm", "fieldurl" ) COLLATE ascii_general_ci NOT NULL default "nolink"',
				'itcf_link_nofollow'   => 'TINYINT DEFAULT 0',
				'itcf_link_class'      => 'VARCHAR(255) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'itcf_line_highlight'  => 'ENUM( "never", "differences", "always" ) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'itcf_green_highlight' => 'ENUM( "never", "lowest", "highest" ) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'itcf_red_highlight'   => 'ENUM( "never", "lowest", "highest" ) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'itcf_description'     => 'TEXT NULL',
			),
			'MODIFY' => array(
				'itcf_type' => 'ENUM( "double", "varchar", "text", "html", "url", "image", "computed", "separator" ) COLLATE ascii_general_ci NOT NULL',
			),
		) );
		$DB->query( 'UPDATE T_items__type_custom_field SET
			itcf_line_highlight = "differences",
			itcf_green_highlight = "never",
			itcf_red_highlight = "never",
			itcf_header_class = "right nowrap",
			itcf_cell_class = CASE
				WHEN itcf_type IN( "double", "computed" ) THEN "right"
				ELSE "center"
			END,
			itcf_link = CASE
				WHEN itcf_type = "image" THEN "linkpermzoom"
				WHEN itcf_type = "url"   THEN "fieldurl"
				ELSE "nolink"
			END' );
		db_drop_col( 'T_items__type', 'ityp_use_custom_fields' );
		upg_task_end();
	}

	if( upg_task_start( 12930, 'Update setting names of item custom fields...' ) )
	{	// part of 6.10.3-stable
		$SQL = new SQL( 'Get all item custom field settings' );
		$SQL->SELECT( 'iset_item_ID, iset_name' );
		$SQL->FROM( 'T_items__item_settings' );
		$SQL->WHERE( 'iset_name LIKE "custom\_%"' );
		$custom_field_settings = $DB->get_results( $SQL->get(), OBJECT, $SQL->title );

		if( count( $custom_field_settings ) )
		{	// If at least one item has a filled custom field:
			$SQL = new SQL( 'Get all custom fields of all item types' );
			$SQL->SELECT( 'itcf_ID, itcf_name' );
			$SQL->FROM( 'T_items__type_custom_field' );
			$custom_fields = $DB->get_assoc( $SQL->get(), $SQL->title );

			foreach( $custom_field_settings as $custom_field_setting )
			{	// Update each old custom field setting name like 'custom_double_1' to new 'custom:field_code'
				$custom_field_ID = preg_replace( '#^custom_[a-z]+_(\d+)$#', '$1', $custom_field_setting->iset_name );
				if( isset( $custom_fields[ $custom_field_ID ] ) )
				{	// If custom field is detected
					$DB->query( 'UPDATE T_items__item_settings
						  SET iset_name = '.$DB->quote( 'custom:'.$custom_fields[ $custom_field_ID ] ).'
						WHERE iset_item_ID = '.$custom_field_setting->iset_item_ID.'
						  AND iset_name = '.$DB->quote( $custom_field_setting->iset_name ),
						'Update setting name of item type custom field' );
				}
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 12940 ) )
	{	// part of 6.10.3-stable

		/* ---- Install basic widgets for containers "Compare Main Area": ---- START */
		global $basic_widgets_insert_sql_rows;
		$basic_widgets_insert_sql_rows = array();

		/**
		 * Add a widget to global array in order to insert it in DB by single SQL query later
		 *
		 * @param integer Blog ID
		 * @param string Container name
		 * @param string Type
		 * @param string Code
		 * @param integer Order
		 * @param array|string|NULL Widget params
		 * @param integer 1 - enabled, 0 - disabled
		 */
		function add_basic_widget_12940( $blog_ID, $container_name, $code, $type, $order, $params = NULL, $enabled = 1 )
		{
			global $basic_widgets_insert_sql_rows, $DB;

			if( is_null( $params ) )
			{ // NULL
				$params = 'NULL';
			}
			elseif( is_array( $params ) )
			{ // array
				$params = $DB->quote( serialize( $params ) );
			}
			else
			{ // string
				$params = $DB->quote( $params );
			}

			$basic_widgets_insert_sql_rows[] = '( '
				.$blog_ID.', '
				.$DB->quote( $container_name ).', '
				.$order.', '
				.$enabled.', '
				.$DB->quote( $type ).', '
				.$DB->quote( $code ).', '
				.$params.' )';
		}

		$SQL = new SQL();
		$SQL->SELECT( 'blog_ID, cat_ID' );
		$SQL->FROM( 'T_blogs' );
		$SQL->FROM_add( 'LEFT JOIN T_categories ON cat_blog_ID = blog_ID AND cat_meta = 0' );
		$SQL->WHERE( '( SELECT COUNT( wi_coll_ID ) FROM '.$tableprefix.'widget WHERE wi_coll_ID = blog_ID AND wi_sco_name = "Compare Main Area" AND wi_code = "item_fields_compare" ) = 0' );
		$SQL->ORDER_BY( 'blog_ID, cat_ID DESC' );
		$collections = $DB->get_assoc( $SQL );
		if( count( $collections ) > 0 )
		{	// If at least one collection exists:
			foreach( $collections as $coll_ID => $cat_ID )
			{
				task_begin( 'Installing default "Compare Main Area" widgets for collection #'.$coll_ID.'... ' );
				/* Compare Main Area */
				add_basic_widget_12940( $coll_ID, 'Compare Main Area', 'item_fields_compare', 'core', 10 );
				task_end();
			}
		}

		if( ! empty( $basic_widgets_insert_sql_rows ) )
		{	// Insert the widget records by single SQL query:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget ( wi_coll_ID, wi_sco_name, wi_order, wi_enabled, wi_type, wi_code, wi_params ) '
								 .'VALUES '.implode( ', ', $basic_widgets_insert_sql_rows ) );
		}
		/* ---- Install basic widgets for containers "Help" and "Register": ---- END */

		upg_task_end( false );
	}

	if( upg_task_start( 12950, 'Upgrade items and item types tables to support short title...' ) )
	{	// part of 6.10.3-stable
		db_add_col( 'T_items__item', 'post_short_title', 'VARCHAR(50) NULL AFTER post_excerpt_autogenerated' );
		db_add_col( 'T_items__type', 'ityp_use_short_title', 'ENUM( "optional", "never" ) COLLATE ascii_general_ci DEFAULT "never"' );
		upg_task_end();
	}

	if( upg_task_start( 12960, 'Upgrade collections table...' ) )
	{	// part of 6.10.3-stable
		$SQL = new SQL( 'Get collections settings to upgrade url protocol' );
		$SQL->SELECT( 'blog_ID, blog_http_protocol, blog_access_type, blog_siteurl' );
		$SQL->FROM( 'T_blogs' );
		$colls = $DB->get_results( $SQL );

		// Remove column "SSL" from collections table and use it as value of the collection settings table instead:
		db_drop_col( 'T_blogs', 'blog_http_protocol' );

		if( ! empty( $colls ) )
		{	// If there are collections to update
			$is_https_baseurl = preg_match( '#^https://#', $baseurl );
			$coll_protocol_insert_values = array();
			foreach( $colls as $coll )
			{	// Check what protocol is used by the collection:
				if( $coll->blog_http_protocol == 'allow_both' )
				{	// Use same value from collections table:
					$http_protocol_value = 'allow_both';
				}
				elseif( ( $is_https_baseurl && $coll->blog_access_type != 'absolute' ) || // If base URL use https protocol then all collection without absolute urls use https too
				        ( $coll->blog_access_type == 'absolute' && preg_match( '#^https://#', $coll->blog_siteurl ) ) ) // If collection absolute url uses https url
				{	// This collection should always use https:
					$http_protocol_value = 'always_https';
				}
				else
				{	// Don't insert collection setting with default values "always_http":
					continue;
				}
				// Set sql data to insert collections settings by single query below:
				$coll_protocol_insert_values[] = '( '.$coll->blog_ID.', "http_protocol", "'.$http_protocol_value.'" )';
			}
			if( ! empty( $coll_protocol_insert_values ) )
			{	// Insert new settings only if at least collection has a not default setting "SSL":
				$DB->query( 'INSERT INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
					VALUES '.implode( ', ', $coll_protocol_insert_values ) );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 12963, 'Upgrade items tables...' ) )
	{	// part of 6.10.3-stable
		db_add_col( 'T_items__item', 'post_single_view', 'ENUM("normal","404","redirected") COLLATE ascii_general_ci NOT NULL DEFAULT "normal" AFTER post_status' );
		// All items with status "Redirected" must have single view as "Redirected" too:
		$DB->query( 'UPDATE T_items__item
			SET post_single_view = "redirected"
			WHERE post_status = "redirected"' );
		upg_task_end();
	}

	if( upg_task_start( 12966, 'Upgrade files table...' ) )
	{	// part of 6.10.3-stable
		db_modify_col( 'T_files', 'file_root_type', 'enum("absolute","user","collection","shared","skins","siteskins","plugins","import","emailcampaign") COLLATE ascii_general_ci NOT NULL DEFAULT "absolute"' );
		upg_task_end();
	}

	if( upg_task_start( 12969, 'Upgrade user organizations table...' ) )
	{	// part of 6.10.3-stable
		db_drop_col( 'T_users__organization', 'org_perm_priority' );
		upg_task_end();
	}

	if( upg_task_start( 12972, 'Move Order from Posts table to Categories-to-Posts relationships table...' ) )
	{	// part of 6.10.3-stable
		db_add_col( 'T_postcats', 'postcat_order', 'DOUBLE NULL' );
		$DB->query( 'UPDATE T_postcats
			INNER JOIN T_items__item ON post_ID = postcat_post_ID
			  SET postcat_order = post_order' );
		db_drop_col( 'T_items__item', 'post_order' );
		upg_task_end();
	}

	if( upg_task_start( 12975, 'Upgrade categories table...' ) )
	{	// part of 6.10.4-stable
		db_add_col( 'T_categories', 'cat_ityp_ID', 'INT UNSIGNED NULL' );
		upg_task_end();
	}

	if( upg_task_start( 12978, 'Upgrade table item types...' ) )
	{	// part of 6.10.4-stable
		db_upgrade_cols( 'T_items__type', array(
			'ADD' => array(
				'ityp_evobar_link_text'  => 'VARCHAR(255) NULL DEFAULT NULL AFTER ityp_perm_level',
				'ityp_skin_btn_text'     => 'VARCHAR(255) NULL DEFAULT NULL AFTER ityp_evobar_link_text',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12981, 'Upgrading post type custom fields table...' ) )
	{	// part of 6.10.4-stable
		db_add_col( 'T_items__type_custom_field', 'itcf_merge', 'TINYINT DEFAULT 0' );
		upg_task_end();
	}

	if( upg_task_start( 12984, 'Upgrading post type custom fields table...' ) )
	{	// part of 6.10.4-stable
		db_modify_col( 'T_items__type_custom_field', 'itcf_link', 'ENUM( "nolink", "linkto", "permalink", "zoom", "linkpermzoom", "permzoom", "linkperm", "fieldurl", "fieldurlblank" ) COLLATE ascii_general_ci NOT NULL default "nolink"' );
		upg_task_end();
	}

	if( upg_task_start( 12987, 'Update collection setting...' ) )
	{	// part of 6.10.4-stable
		$setting_SQL = new SQL();
		$setting_SQL->SELECT( 'set_value' );
		$setting_SQL->FROM( 'T_settings' );
		$setting_SQL->WHERE( 'set_name = "cross_post_nav_in_same_coll"' );
		if( $DB->get_var( $setting_SQL ) === '0' )
		{	// Move only not default value to the collection settings table:
			$DB->query( 'INSERT INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
				SELECT blog_ID, "allow_crosspost_urls", 0 FROM T_blogs' );
		}
		upg_task_end();
	}

	if( upg_task_start( 12990 ) )
	{	// part of 6.10.4-stable

		/* ---- Install basic widgets for containers "Front Page Main Area": ---- START */
		global $basic_widgets_insert_sql_rows;
		$basic_widgets_insert_sql_rows = array();

		/**
		 * Add a widget to global array in order to insert it in DB by single SQL query later
		 *
		 * @param integer Blog ID
		 * @param string Container name
		 * @param string Type
		 * @param string Code
		 * @param integer Order
		 * @param array|string|NULL Widget params
		 * @param integer 1 - enabled, 0 - disabled
		 */
		function add_basic_widget_12990( $blog_ID, $container_name, $code, $type, $order, $params = NULL, $enabled = 1 )
		{
			global $basic_widgets_insert_sql_rows, $DB;

			if( is_null( $params ) )
			{ // NULL
				$params = 'NULL';
			}
			elseif( is_array( $params ) )
			{ // array
				$params = $DB->quote( serialize( $params ) );
			}
			else
			{ // string
				$params = $DB->quote( $params );
			}

			$basic_widgets_insert_sql_rows[] = '( '
				.$blog_ID.', '
				.$DB->quote( $container_name ).', '
				.$order.', '
				.$enabled.', '
				.$DB->quote( $type ).', '
				.$DB->quote( $code ).', '
				.$params.' )';
		}

		// Insert content_hierarchy widget:
		$SQL = new SQL();
		$SQL->SELECT( 'wi_coll_ID, MAX(wi_order)' );
		$SQL->FROM( $tableprefix.'widget' );
		$SQL->FROM_add( 'INNER JOIN T_blogs ON blog_ID = wi_coll_ID' );
		$SQL->WHERE( 'blog_type = "manual"' );
		$SQL->WHERE_and( 'wi_sco_name = "Front Page Main Area"' );
		$SQL->ORDER_BY( 'wi_coll_ID' );
		$SQL->GROUP_BY( 'wi_coll_ID');

		$collections = $DB->get_assoc( $SQL );
		if( count( $collections ) > 0 )
		{	// If at least one collection exists:
			foreach( $collections as $coll_ID => $max_order )
			{
				task_begin( 'Installing default "Content Hierarchy" widget for collection #'.$coll_ID.'... ' );
				add_basic_widget_12990( $coll_ID, 'Front Page Main Area', 'content_hierarchy', 'core', intval( $max_order ) + 10 );
				task_end();
			}
		}

		if( ! empty( $basic_widgets_insert_sql_rows ) )
		{	// Insert the widget records by single SQL query:
			$DB->query( 'INSERT INTO '.$tableprefix.'widget( wi_coll_ID, wi_sco_name, wi_order, wi_enabled, wi_type, wi_code, wi_params ) '
								 .'VALUES '.implode( ', ', $basic_widgets_insert_sql_rows ) );
		}
		/* ---- Install basic widgets for containers "Front Page Main Area": ---- END */
		upg_task_end( false );
	}

	if( upg_task_start( 12993, 'Upgrading email newsletters table...' ) )
	{	// part of 6.10.4-stable
		db_upgrade_cols( 'T_email__newsletter', array(
			'ADD' => array(
				'enlt_perm_subscribe' => 'ENUM( "admin", "anyone", "group" ) COLLATE ascii_general_ci NOT NULL DEFAULT "anyone"',
				'enlt_perm_groups'    => 'VARCHAR(255) COLLATE ascii_general_ci DEFAULT NULL',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 12996, 'Upgrading email newsletter subscriptions table...' ) )
	{	// part of 6.10.4-stable
		db_add_col( 'T_email__newsletter_subscription', 'enls_last_sent_auto_ts', 'TIMESTAMP NULL AFTER enls_last_sent_manual_ts' );
		$DB->query( 'UPDATE T_email__newsletter_subscription
			SET enls_last_sent_auto_ts = enls_last_sent_manual_ts' );
		upg_task_end();
	}

	if( upg_task_start( 12999, 'Upgrading email newsletters table...' ) )
	{	// part of 6.10.4-stable
		db_add_col( 'T_email__newsletter', 'enlt_owner_user_ID', 'INT UNSIGNED NOT NULL AFTER enlt_order' );
		$DB->query( 'UPDATE T_email__newsletter SET enlt_owner_user_ID = 1' );
		upg_task_end();
	}

	if( upg_task_start( 13010, 'Upgrading email addresses table...' ) )
	{	// part of 6.10.4-stable
		db_upgrade_cols( 'T_email__address', array(
			'MODIFY' => array( 'emadr_status' => 'ENUM( "unknown", "working", "unattended", "redemption", "warning", "suspicious1", "suspicious2", "suspicious3", "prmerror", "spammer" ) COLLATE ascii_general_ci NOT NULL DEFAULT "unknown"' ),
			'ADD' => array( 'emadr_last_open_ts' => 'TIMESTAMP NULL' ),
		) );
		upg_task_end();
	}

	if( upg_task_start( 13020 ) )
	{	// part of 6.10.4-stable
		task_begin( 'Updating email log table...' );
		db_modify_col( 'T_email__log', 'emlog_camp_ID', 'INT UNSIGNED NULL DEFAULT NULL COMMENT "Used to reference campaign when there is no associated campaign_send or the previously associated campaign_send updated its csnd_emlog_ID"' );
		task_end();

		task_begin( 'Updating email newsletter subscriptions table...' );
		$localtimenow = date2mysql( $GLOBALS['localtimenow'] );
		$DB->query( 'UPDATE T_email__newsletter_subscription
			INNER JOIN T_users ON user_ID = enls_user_ID AND user_status = "closed" AND enls_subscribed = 1
			SET enls_subscribed = 0, enls_unsubscribed_ts = '.$DB->quote( $localtimenow ) );
		task_end();

		task_begin( 'Upgrading email campaigns table...' );
		db_add_col( 'T_email__campaign', 'ecmp_user_tag_unsubscribe', 'VARCHAR(255) NULL AFTER ecmp_user_tag_dislike' );
		task_end();

		upg_task_end( false );
	}

	if( upg_task_start( 13030, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.4-stable
		db_upgrade_cols( 'T_email__campaign', array(
			'ADD' => array(
				'ecmp_cta1_autm_ID'         => 'INT UNSIGNED NULL',
				'ecmp_cta1_autm_execute'    => 'TINYINT(1) NOT NULL DEFAULT 1',
				'ecmp_cta2_autm_ID'         => 'INT UNSIGNED NULL',
				'ecmp_cta2_autm_execute'    => 'TINYINT(1) NOT NULL DEFAULT 1',
				'ecmp_cta3_autm_ID'         => 'INT UNSIGNED NULL',
				'ecmp_cta3_autm_execute'    => 'TINYINT(1) NOT NULL DEFAULT 1',
				'ecmp_like_autm_ID'         => 'INT UNSIGNED NULL',
				'ecmp_like_autm_execute'    => 'TINYINT(1) NOT NULL DEFAULT 1',
				'ecmp_dislike_autm_ID'      => 'INT UNSIGNED NULL',
				'ecmp_dislike_autm_execute' => 'TINYINT(1) NOT NULL DEFAULT 1',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 13040, 'Upgrading items table...' ) )
	{	// part of 6.10.5-stable
		db_modify_col( 'T_items__item', 'post_title', 'VARCHAR(255) NULL' );
		upg_task_end();
	}

	if( upg_task_start( 13050, 'Upgrading email campaigns table...' ) )
	{	// part of 6.10.5-stable
		db_upgrade_cols( 'T_email__campaign', array(
			'ADD' => array(
				'ecmp_activate'              => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER ecmp_welcome',
				'ecmp_user_tag_activate'     => 'VARCHAR(255) NULL AFTER ecmp_user_tag_dislike',
				'ecmp_activate_autm_ID'      => 'INT UNSIGNED NULL',
				'ecmp_activate_autm_execute' => 'TINYINT(1) NOT NULL DEFAULT 1',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 13060, 'Updating settings for scheduled job "Send reminders about non-activated accounts"...' ) )
	{	// part of 6.10.5-stable
		// Add default value "Don't send" for new setting "Delete warning"
		// and default value "Don't delete" for new setting "Delete account":
		$DB->query( 'UPDATE T_settings
			  SET set_value = CONCAT( set_value, ",0,0" )
			WHERE set_name = "activate_account_reminder_config"' );
		upg_task_end();
	}

	if( upg_task_start( 13070, 'Upgrading automation step table...' ) )
	{	// part of 6.10.6-stable
		db_modify_col( 'T_automation__step', 'step_type', 'ENUM("if_condition", "send_campaign", "notify_owner", "add_usertag", "remove_usertag", "subscribe", "unsubscribe", "start_automation", "user_status") COLLATE ascii_general_ci NOT NULL DEFAULT "if_condition"' );
		upg_task_end();
	}

	if( upg_task_start( 13075, 'Upgrading GeoIP plugin data file...' ) )
	{	// part of 6.10.6-stable
		if( $Plugins_admin = & get_Plugins_admin() &&
		    $geoip_Plugin = & $Plugins_admin->get_by_code( 'evo_GeoIP' ) &&
		    $geoip_Plugin->status == 'enabled' )
		{	// Try to download only when plugin is installed and enabled:
			try
			{	// Download GeoIP data file:
				$geoip_Plugin->download_geoip_data();
				task_end( 'OK.' );
			}
			catch( Exception $ex )
			{	// Unexpected error:
				if( ! is_object( $Plugins ) )
				{	// Initiliaze Plugins object because it is required in the function Plugin->set_status():
					load_class( 'plugins/model/_plugins.class.php', 'Plugins' );
					$Plugins = new Plugins();
				}
				// Disable plugin if new data file cannot be downloaded as expected:
				$status_result = $geoip_Plugin->set_status( 'needs_config' );
				// Display error message:
				echo get_install_format_text_and_log( '<span class="text-danger"><evo:error>'
						.'<b>UNEXPECTED ERROR</b>: '.nl2br( $ex->getMessage() )
						.( $status_result ? ' <b>WARNING:</b> The plugin #'.$geoip_Plugin->ID.'('.$geoip_Plugin->name.') has been disabled!' : '' )
						.'<br />Please check the GeoIP plugin settings right after this upgrade has finished.'
					.'</evo:error></span> ' );
				task_end( '' );
			}
		}
		else
		{
			task_end( 'Not needed - Plugin is not active.' );
		}
		upg_task_end( false );
	}

	if( upg_task_start( 13080, 'Upgrading users table...' ) )
	{	// part of 6.10.6-stable
		db_modify_col( 'T_users', 'user_status', "enum( 'activated', 'manualactivated', 'autoactivated', 'closed', 'deactivated', 'emailchanged', 'failedactivation', 'pendingdelete', 'new' ) COLLATE ascii_general_ci NOT NULL default 'new'" );
		upg_task_end();
	}

	if( upg_task_start( 13090, 'Upgrading messages table...' ) )
	{	// part of 6.10.6-stable
		db_add_index( 'T_messaging__message', 'msg_author_user_ID', 'msg_author_user_ID' );
		upg_task_end();
	}

	if( upg_task_start( 13100, 'Upgrading comments table...' ) )
	{	// part of 6.10.6-stable
		db_modify_col( 'T_comments', 'comment_type', "enum('comment','linkback','trackback','pingback','meta','webmention') COLLATE ascii_general_ci NOT NULL default 'comment'" );
		upg_task_end();
	}

	if( upg_task_start( 13110, 'Updating collection ping plugin settings...' ) )
	{	// part of 6.10.6-stable
		load_class( 'collections/model/_collsettings.class.php', 'CollectionSettings' );
		$CollectionSettings = new CollectionSettings();
		// Remove webmention from default setting in order to don't enable webmentions plugin for collections on upgrade:
		$default_ping_plugins = trim( preg_replace( '/(^|,)webmention(,|$)/', '$2', $CollectionSettings->get_default( 'ping_plugins' ) ), ',' );
		$DB->query( 'INSERT INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
			SELECT blog_ID, "ping_plugins", '.$DB->quote( $default_ping_plugins ).'
			  FROM T_blogs
			 WHERE blog_ID NOT IN ( SELECT cset_coll_ID FROM T_coll_settings WHERE cset_name = "ping_plugins" )' );
		upg_task_end();
	}

	if( upg_task_start( 13120, 'Upgrade Temporary IDs table...' ) )
	{	// part of 6.11.0-beta
		db_add_col( 'T_temporary_ID', 'tmp_item_ID', 'INT(11) UNSIGNED NULL COMMENT \'Link to parent Item of Comment in order to enable permission checks\'' );
		upg_task_end();
	}

	if( upg_task_start( 13130, 'Upgrade links table...' ) )
	{	// part of 6.11.0-beta
		db_drop_col( 'T_links', 'link_ltype_ID' );
		upg_task_end();
	}

	if( upg_task_start( 13140, 'Creating custom fields and link versions tables for item versions...' ) )
	{	// part of 6.11.0-beta
		db_create_table( 'T_items__version_custom_field', '
			ivcf_iver_ID     INT UNSIGNED NOT NULL,
			ivcf_iver_itm_ID INT UNSIGNED NOT NULL,
			ivcf_itcf_ID     INT UNSIGNED NOT NULL,
			ivcf_itcf_label  VARCHAR(255) NOT NULL,
			ivcf_value       VARCHAR( 10000 ) NULL,
			PRIMARY KEY      ( ivcf_iver_ID, ivcf_iver_itm_ID, ivcf_itcf_ID )' );

		db_create_table( 'T_items__version_link', '
			ivl_iver_ID     INT UNSIGNED NOT NULL,
			ivl_iver_itm_ID INT UNSIGNED NOT NULL,
			ivl_link_ID     INT(11) UNSIGNED NOT NULL,
			ivl_file_ID     INT(11) UNSIGNED NULL,
			ivl_position    VARCHAR(10) COLLATE ascii_general_ci NOT NULL,
			ivl_order       INT(11) UNSIGNED NOT NULL,
			PRIMARY KEY     ( ivl_iver_ID, ivl_iver_itm_ID, ivl_link_ID )' );

		$DB->query( 'ALTER TABLE T_items__version
				CHANGE iver_edit_datetime iver_edit_last_touched_ts TIMESTAMP NOT NULL DEFAULT \'2000-01-01 00:00:00\'' );
		upg_task_end();
	}

	if( upg_task_start( 13150, 'Upgrading item versions tables...' ) )
	{	// part of 6.11.0-beta

		// Make column iver_ID unique per Item in order to avoid error on adding PRIMARY(unique) KEY below:
		$DB->query( 'SET @iver_ID = 0' );
		$DB->query( 'SET @iver_itm_ID = 0' );
		$DB->query( 'UPDATE T_items__version
			  SET iver_ID = IF( @iver_itm_ID != iver_itm_ID, @iver_ID := 1 AND @iver_itm_ID := iver_itm_ID, @iver_ID := @iver_ID + 1 )
			ORDER BY iver_itm_ID, iver_edit_last_touched_ts' );

		$DB->query( 'ALTER TABLE T_items__version
			ADD COLUMN iver_type ENUM("archived","proposed") COLLATE ascii_general_ci NOT NULL DEFAULT "archived" AFTER iver_ID,
			DROP INDEX iver_ID_itm_ID,
			ADD PRIMARY KEY ( iver_ID , iver_type, iver_itm_ID )' );

		$DB->query( 'ALTER TABLE T_items__version_custom_field
			ADD COLUMN ivcf_iver_type ENUM("archived","proposed") COLLATE ascii_general_ci NOT NULL DEFAULT "archived" AFTER ivcf_iver_ID,
			DROP PRIMARY KEY,
			ADD PRIMARY KEY ( ivcf_iver_ID, ivcf_iver_type, ivcf_iver_itm_ID, ivcf_itcf_ID )' );

		$DB->query( 'ALTER TABLE T_items__version_link
			ADD COLUMN ivl_iver_type ENUM("archived","proposed") COLLATE ascii_general_ci NOT NULL DEFAULT "archived" AFTER ivl_iver_ID,
			DROP PRIMARY KEY,
			ADD PRIMARY KEY ( ivl_iver_ID, ivl_iver_type, ivl_iver_itm_ID, ivl_link_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 13160, 'Updating collection user/group permissions...' ) )
	{	// part of 6.11.0-beta
		db_add_col( 'T_coll_user_perms', 'bloguser_perm_item_propose', 'tinyint NOT NULL default 0 AFTER bloguser_can_be_assignee' );
		db_add_col( 'T_coll_group_perms', 'bloggroup_perm_item_propose', 'tinyint NOT NULL default 0 AFTER bloggroup_can_be_assignee' );
		upg_task_end();
	}

	if( upg_task_start( 13170, 'Creating Markdown text file type...' ) )
	{	// part of 6.11.0-beta
		$SQL = new SQL( 'Check for file type .md' );
		$SQL->SELECT( 'ftyp_ID' );
		$SQL->FROM( 'T_filetypes' );
		$SQL->WHERE( 'ftyp_extensions REGEXP "(^| )md( |$)"' );
		if( ! $DB->get_var( $SQL ) )
		{	// Insert new file type for Markdown Documentation only if it doesn't exist:
			$DB->query( 'INSERT INTO T_filetypes
				       ( ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed )
				VALUES ( "md", "Markdown text file", "text/plain", "file_document", "text", "registered" )' );
		}
		upg_task_end();
	}

	if( upg_task_start( 13180, 'Upgrading cron logs table...' ) )
	{	// part of 6.11.0-beta
		db_modify_col( 'T_cron__log', 'clog_status', 'enum("started","finished","error","imap_error","timeout","warning") COLLATE ascii_general_ci not null default "started"' );
		upg_task_end();
	}

	if( upg_task_start( 13190, 'Update skin color settings with transparency to new format...' ) )
	{	// part of 6.11.0-beta
		$SQL = new SQL( 'Get skins with transparent colors' );
		$SQL->SELECT( 'skin_ID, skin_folder' );
		$SQL->FROM( 'T_skins__skin' );
		$SQL->WHERE( 'skin_folder IN ( "bootstrap_main_skin", "horizon_main_skin" )' );
		$skins = $DB->get_assoc( $SQL->get(), $SQL->title );
		$color_transparency_settings = array();
		foreach( $skins as $skin_ID => $skin_folder )
		{
			$color_set_name = ( $skin_folder == 'bootstrap_main_skin' ? 'front_bg_cont_color' : 'front_bg_color' );
			$color_transparency_settings[ $color_set_name ] = array( $skin_ID, 'front_bg_opacity' );
		}

		$SQL = new SQL( 'Get all skin color settings with transparency which must be updated from hex to rgba format' );
		$SQL->SELECT( '*' );
		$SQL->FROM( 'T_coll_settings' );
		foreach( $color_transparency_settings as $color_set_name => $color_data )
		{
			$skin_ID = $color_data[0];
			$transparency_set_name = $color_data[1];
			$SQL->WHERE_or( 'cset_name LIKE "skin'.$skin_ID.'\_'.str_replace( '_', '\_', $color_set_name ).'"' );
			$SQL->WHERE_or( 'cset_name LIKE "skin'.$skin_ID.'\_'.str_replace( '_', '\_', $transparency_set_name ).'"' );
		}
		$SQL->ORDER_BY( 'cset_coll_ID, cset_name' );
		$color_settings = $DB->get_results( $SQL->get(), OBJECT, $SQL->title );
		foreach( $color_settings as $color_setting )
		{
			$color_set_name = preg_replace( '/^skin\d+_/', '', $color_setting->cset_name );
			if( ! isset( $color_transparency_settings[ $color_set_name ] ) )
			{	// Skip not color setting:
				continue;
			}
			$transparency_set_name = $color_transparency_settings[ $color_set_name ][1];
			foreach( $color_settings as $transparency_setting )
			{
				if( $color_setting->cset_coll_ID == $transparency_setting->cset_coll_ID &&
				    $transparency_setting->cset_name == str_replace( $color_set_name, '', $color_setting->cset_name ).$transparency_set_name )
				{	// We found transparency value for the same color setting,
					// Convert color from format #FFFFFF to rgba(255,255,255,1):
					$transparency = floatval( $transparency_setting->cset_value / 100 );
					$color = substr( $color_setting->cset_value, 1 );
					if( strlen( $color ) == '6' )
					{	// Color value in format #FFFFFF
						$color = str_split( $color, 2 );
					}
					else
					{	// Color value in format #FFF
						$color = str_split( $color, 1 );
						foreach( $color as $c => $v )
						{
							$color[ $c ] = $v.$v;
						}
					}
					// Update color setting to new format:
					$rgba_color = 'rgba('.implode( ',', array_map( 'hexdec', $color ) ).','.$transparency.')';
					$DB->query( 'UPDATE T_coll_settings
						  SET cset_value = '.$DB->quote( $rgba_color ).'
						WHERE cset_coll_ID = '.$color_setting->cset_coll_ID.'
						  AND cset_name = "'.$color_setting->cset_name.'"' );
					// Remove old setting with transparency value:
					$DB->query( 'DELETE FROM T_coll_settings
						WHERE cset_coll_ID = '.$transparency_setting->cset_coll_ID.'
						  AND cset_name = "'.$transparency_setting->cset_name.'"' );
					break;
				}
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 13200, 'Creating CSV file type...' ) )
	{	// part of 6.11.0-beta
		$SQL = new SQL( 'Check for file type .csv' );
		$SQL->SELECT( 'ftyp_ID' );
		$SQL->FROM( 'T_filetypes' );
		$SQL->WHERE( 'ftyp_extensions REGEXP "(^| )csv( |$)"' );
		if( ! $DB->get_var( $SQL ) )
		{	// Insert new file type for Markdown Documentation only if it doesn't exist:
			$DB->query( 'INSERT INTO T_filetypes
				       ( ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed )
				VALUES ( "csv", "CSV file", "text/plain", "file_document", "text", "registered" )' );
		}
		upg_task_end();
	}

	if( upg_task_start( 13210, 'Inserting new collection settings...' ) )
	{	// part of 6.11.2-stable
		// This upgrade block is NOT critical/NOT required for users already on 7.0dev
		$DB->query( 'REPLACE INTO T_coll_settings ( cset_coll_ID, cset_value, cset_name )
			SELECT cset_coll_ID, cset_value,
			  CASE cset_name
			    WHEN "default_noindex"         THEN "posts_firstpage_noindex"
			    WHEN "canonical_homepage"      THEN "canonical_posts"
			    WHEN "self_canonical_homepage" THEN "self_canonical_posts"
			    WHEN "relcanonical_homepage"   THEN "relcanonical_posts"
			  END AS new_cset_name
			  FROM T_coll_settings
			 WHERE cset_name IN ( "default_noindex", "canonical_homepage", "self_canonical_homepage", "relcanonical_homepage" )' );
		upg_task_end();
	}

	if( upg_task_start( 13220, 'Upgrading cron tasks table...' ) )
	{	// part of 6.11.3-stable
		db_modify_col( 'T_cron__task', 'ctsk_params', 'TEXT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15000, 'Creating sections table...' ) )
	{	// part of 7.0.0-alpha
		db_create_table( 'T_section', '
				sec_ID            INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
				sec_name          VARCHAR(255) NOT NULL,
				sec_order         INT(11) NOT NULL,
				sec_owner_user_ID INT(11) UNSIGNED NOT NULL default 1,
				PRIMARY KEY ( sec_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 15005, 'Upgrading collections table...' ) )
	{	// part of 7.0.0-alpha
		db_add_col( 'T_blogs', 'blog_sec_ID', 'INT(11) UNSIGNED NOT NULL DEFAULT 1' );
		upg_task_end();
	}

	if( upg_task_start( 15010, 'Create default section...' ) )
	{	// part of 7.0.0-alpha
		$DB->query( 'INSERT INTO T_section ( sec_ID, sec_name, sec_order, sec_owner_user_ID )
			VALUES ( 1, "No Section", 1, 1 )' );
		$section_ID = $DB->insert_id;
		if( $section_ID > 0 )
		{
			$DB->query( 'UPDATE T_blogs
				SET blog_sec_ID = '.$section_ID.'
				WHERE blog_sec_ID IS NULL' );
		}
		upg_task_end();
	}

	if( upg_task_start( 15020, 'Install default site skin...' ) )
	{	// part of 7.0.0-alpha
		load_funcs( 'skins/_skin.funcs.php' );
		$SkinCache = & get_SkinCache();
		if( ! ( $default_site_Skin = & $SkinCache->get_by_folder( 'default_site_skin', false ) ) )
		{	// If the skin doesn't exist try to install it:
			$default_site_Skin = skin_install( 'default_site_skin', true );
		}
		if( $default_site_Skin && $default_site_Skin->ID > 0 )
		{	// Use the installed skin as default for site:
			$DB->query( 'REPLACE INTO T_settings ( set_name, set_value )
				VALUES ( "normal_skin_ID", '.$default_site_Skin->ID.' )' );
		}
		upg_task_end();
	}

	if( upg_task_start( 15030, 'Creating plugin group settings table...' ) )
	{	// part of 7.0.0-alpha
		db_create_table( 'T_plugingroupsettings', '
			pgset_plug_ID INT(11) UNSIGNED NOT NULL,
			pgset_grp_ID  INT(11) UNSIGNED NOT NULL,
			pgset_name    VARCHAR( 50 ) COLLATE ascii_general_ci NOT NULL,
			pgset_value   TEXT NULL,
			PRIMARY KEY   ( pgset_plug_ID, pgset_grp_ID, pgset_name )' );
		upg_task_end();
	}


	if( upg_task_start( 15040, 'Creating table for widget container...' ) )
	{	// part of 7.0.0-alpha
		db_create_table( 'T_widget__container', '
			wico_ID       INT(10) UNSIGNED auto_increment,
			wico_code     VARCHAR(32) COLLATE ascii_general_ci NULL DEFAULT NULL,
			wico_name     VARCHAR( 40 ) NOT NULL,
			wico_coll_ID  INT(10) NULL DEFAULT NULL,
			wico_order    INT(10) NOT NULL,
			PRIMARY KEY ( wico_ID )' );
		upg_task_end();
	}

	if( upg_task_start( 15050, 'Inserting widget containers...' ) )
	{	// part of 7.0.0-alpha
		$DB->query( 'INSERT INTO T_widget__container ( wico_name, wico_coll_ID, wico_order )
			SELECT wi_sco_name, wi_coll_ID, @order := @order + 1 AS wico_order
			FROM '.$tableprefix.'widget INNER JOIN ( SELECT @order := 0 ) order_count
			GROUP BY wi_coll_ID, wi_sco_name' );
		$container_codes_byname = array(
			'Header'                    => 'header',
			'Footer'                    => 'footer',
			'Menu'                      => 'menu',
			'Item Single Header'        => 'item_single_header',
			'Item Single'               => 'item_single',
			'Item Page'                 => 'item_page',
			'Menu Top'                  => 'menu_top',
			'Page Top'                  => 'page_top',
			'Sidebar'                   => 'sidebar',
			'Sidebar 2'                 => 'sidebar_2',
			'Sidebar Single'            => 'sidebar_single',
			'Front Page Main Area'      => 'front_page_main_area',
			'Front Page Secondary Area' => 'front_page_secondary_area',
			'Forum Front Secondary Area'=> 'forum_front_secondary_area',
			'404 Page'                  => '404_page',
			'Login Required'            => 'login_required',
			'Access Denied'             => 'access_denied',
			'Help'                      => 'help',
			'Register'                  => 'register',
			'Compare Main Area'         => 'compare_main_area',
			'Mobile: Footer'            => 'mobile_footer',
			'Mobile: Navigation Menu'   => 'mobile_navigation_menu',
			'Mobile: Tools Menu'        => 'mobile_tools_menu'
		);
		$set_wico_codes_query = 'UPDATE T_widget__container SET wico_code = CASE';
		foreach( $container_codes_byname as $wico_name => $wico_code )
		{
			$set_wico_codes_query .= ' WHEN wico_name = "'.$wico_name.'" THEN "'.$wico_code.'"';
		}
		$DB->query( $set_wico_codes_query.' END' );
		// Set unique fields for wdiget containers only after updating code field:
		$DB->query( 'ALTER TABLE T_widget__container
			ADD UNIQUE wico_coll_ID_code ( wico_coll_ID, wico_code )' );
		upg_task_end();
	}

	if( upg_task_start( 15060, 'Upgrading widgets table...' ) )
	{	// part of 7.0.0-alpha
		$DB->query( 'RENAME TABLE '.$tableprefix.'widget TO T_widget__widget' );
		db_add_col( 'T_widget__widget', 'wi_wico_ID', 'INT(10) UNSIGNED NULL DEFAULT NULL AFTER wi_ID' );
		$DB->query( 'UPDATE T_widget__widget
				SET wi_wico_ID = (
					SELECT wico_ID FROM T_widget__container
					WHERE wico_coll_ID = wi_coll_ID AND wico_name = wi_sco_name
				)'
		);
		$DB->query( "ALTER TABLE T_widget__widget
				DROP INDEX wi_order,
				DROP COLUMN wi_coll_ID,
				DROP COLUMN wi_sco_name,
				CHANGE COLUMN wi_wico_ID wi_wico_ID INT(10) UNSIGNED NOT NULL,
				ADD UNIQUE wi_order( wi_wico_ID, wi_order )"
		);
		upg_task_end();
	}

	if( upg_task_start( 15070, 'Updating widget containers content...' ) )
	{	// part of 7.0.0-alpha
		// Create Item Single containers and a content widget to make sure item contents will be displayed in every collection:
		$widget_containers_sql_rows = array();
		$widgets_insert_sql_rows = array();
		// Select those blog ids where Item Single container not exists yet:
		$blog_ids = $DB->get_col( 'SELECT blog_ID FROM T_blogs WHERE blog_ID NOT IN (
				SELECT wico_coll_ID FROM T_widget__container WHERE wico_code = "item_single" )' );
		foreach( $blog_ids as $blog_ID )
		{	// Create Item single container rows:
			$widget_containers_sql_rows[] = '( "item_single", "Item Single", '.$blog_ID.', 4 )';
		}
		if( ! empty( $widget_containers_sql_rows ) )
		{	// Insert Item Single containers:
			$DB->query( 'REPLACE INTO T_widget__container( wico_code, wico_name, wico_coll_ID, wico_order ) VALUES'
					.implode( ', ', $widget_containers_sql_rows ) );
		}
		// Get those Item Single containers where the item content widget doesn't exist:
		$item_single_containers = $DB->get_col( 'SELECT wico_ID FROM T_widget__container
				WHERE wico_code = "item_single" AND wico_ID NOT IN (
					SELECT wi_wico_ID FROM T_widget__widget WHERE wi_code = "item_content" )' );
		foreach( $item_single_containers as $wico_ID )
		{
			$widgets_insert_sql_rows[] = '( '.$wico_ID.', 1, "core", "item_content", NULL )';
		}
		if( ! empty( $widgets_insert_sql_rows ) )
		{	// There are widgets to create, insert previously built widget records:
			$DB->query( 'UPDATE T_widget__widget SET wi_order = wi_order + 1
					WHERE wi_wico_ID IN ( '.implode( ', ', $item_single_containers ).' )
					ORDER BY wi_wico_ID, wi_order DESC' );
			$DB->query( 'INSERT INTO T_widget__widget( wi_wico_ID, wi_order, wi_type, wi_code, wi_params ) VALUES'
					.implode( ', ', $widgets_insert_sql_rows ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 15080, 'Droping skin containers table...' ) )
	{	// part of 7.0.0-alpha
		$DB->query( 'DROP TABLE IF EXISTS '.$tableprefix.'skins__container' );
		upg_task_end();
	}

	if( upg_task_start( 15090, 'Upgrading widget containers table...' ) )
	{	// part of 7.0.0-alpha
		db_add_col( 'T_widget__container', 'wico_main', 'TINYINT(1) NOT NULL DEFAULT 0' );
		// Update new flag to 1 for all main containers of existing collections:
		$BlogCache = & get_BlogCache();
		$BlogCache->load_all( 'ID', 'ASC' );
		foreach( $BlogCache->cache as $Blog )
		{
			$main_containers = $Blog->get_main_containers();
			if( count( $main_containers ) )
			{	// If at least one main container exists:
				$DB->query( 'UPDATE T_widget__container
					  SET wico_main = 1
					WHERE wico_coll_ID = '.$Blog->ID.'
					  AND wico_code IN ( '.$DB->quote( array_keys(  $main_containers ) ).' )' );

				// Insert main containers if still doesn't exist in DB but declared only in skin file:
				$SQL = new SQL( 'Get all existing widget containers of collection #'.$Blog->ID );
				$SQL->SELECT( 'wico_code' );
				$SQL->FROM( 'T_widget__container' );
				$SQL->WHERE( 'wico_coll_ID = '.$Blog->ID );
				$existing_containers = $DB->get_col( $SQL->get() );
				$not_existing_containers = array_diff( array_keys(  $main_containers ), $existing_containers );
				if( ! empty( $not_existing_containers ) )
				{	// If at least we have one missed container:
					$new_main_cnontainers_sql = array();
					foreach( $not_existing_containers as $new_wico_code )
					{
						$new_main_cnontainers_sql[] = '( '.$DB->quote( $new_wico_code ).', '
							.$DB->quote( isset( $main_containers[ $new_wico_code ][0] ) ? $main_containers[ $new_wico_code ][0] : $new_wico_code ).', '
							.$Blog->ID.', '
							.$DB->quote( isset( $main_containers[ $new_wico_code ][1] ) ? $main_containers[ $new_wico_code ][1] : $new_wico_code ).', '
							.'1 )';
					}
					$DB->query( 'INSERT INTO T_widget__container ( wico_code, wico_name, wico_coll_ID, wico_order, wico_main )
						VALUES '.implode( ', ', $new_main_cnontainers_sql ),
						'Insert new main widget containers which are declared in skin file for collection #'.$Blog->ID );
				}
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15100, 'Rename widget "coll_avatar" to "user_profile_pics"...' ) )
	{	// part of 7.0.0-alpha
		$DB->query( 'UPDATE T_widget__widget
			  SET wi_code = "user_profile_pics"
			WHERE wi_code = "coll_avatar"' );
		upg_task_end();
	}

	if( upg_task_start( 15110, 'Upgrading widget containers table...' ) )
	{	// part of 7.0.0-alpha
		db_add_col( 'T_widget__container', 'wico_skin_type', 'ENUM( "normal", "mobile", "tablet" ) COLLATE ascii_general_ci NOT NULL DEFAULT "normal" AFTER wico_code' );
		db_drop_index( 'T_widget__container', 'wico_coll_ID_code' );
		db_add_index( 'T_widget__container', 'wico_coll_ID_code_skin_type', 'wico_coll_ID, wico_code, wico_skin_type', 'UNIQUE' );
		upg_task_end();
	}

	if( upg_task_start( 15120, 'Converting columns to ASCII...' ) )
	{	// part of 7.0.0-alpha
		db_modify_col( 'T_automation__automation', 'autm_status', 'ENUM("paused", "active") COLLATE ascii_general_ci DEFAULT "paused"' );
		db_upgrade_cols( 'T_blogs', array(
			'MODIFY' => array(
				'blog_locale'        => 'VARCHAR(20) COLLATE ascii_general_ci NOT NULL DEFAULT "en-EU"',
				'blog_http_protocol' => 'ENUM( "always_redirect", "allow_both" ) COLLATE ascii_general_ci DEFAULT "always_redirect"',
			),
		) );
		db_modify_col( 'T_comments', 'comment_notif_flags', 'SET("moderators_notified","members_notified","community_notified") COLLATE ascii_general_ci NOT NULL DEFAULT ""' );
		db_modify_col( 'T_email__log', 'emlog_key', 'CHAR(32) COLLATE ascii_general_ci NULL DEFAULT NULL' );
		db_upgrade_cols( 'T_filetypes', array(
			'MODIFY' => array(
				'ftyp_mimetype' => 'varchar(50) COLLATE ascii_general_ci NOT NULL',
				'ftyp_icon'     => 'varchar(20) COLLATE ascii_general_ci default NULL',
			),
		) );
		db_upgrade_cols( 'T_hitlog', array(
			'MODIFY' => array(
				'hit_disp'   => 'VARCHAR(30) COLLATE ascii_general_ci DEFAULT NULL',
				'hit_action' => 'VARCHAR(30) COLLATE ascii_general_ci DEFAULT NULL',
			),
		) );
		db_modify_col( 'T_i18n_translated_string', 'itst_locale', 'varchar(20) COLLATE ascii_general_ci NOT NULL default ""' );
		db_upgrade_cols( 'T_items__item', array(
			'MODIFY' => array(
				'post_locale'              => 'VARCHAR(20) COLLATE ascii_general_ci NOT NULL DEFAULT "en-EU"',
				'post_notifications_flags' => 'SET("moderators_notified","members_notified","community_notified","pings_sent") COLLATE ascii_general_ci NOT NULL DEFAULT ""',
			),
		) );
		db_modify_col( 'T_locales', 'loc_locale', 'varchar(20) COLLATE ascii_general_ci NOT NULL default ""' );
		db_modify_col( 'T_skins__skin', 'skin_class', 'varchar(32) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_users', 'user_locale', 'varchar(20) COLLATE ascii_general_ci DEFAULT "en-EU" NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15130, 'Converting columns to utf8mb4...' ) )
	{	// part of 7.0.0-alpha
		// Modify indexes with max 767 chars(191 * 4 bytes):
		db_add_index( 'T_users__organization', 'org_name', 'org_name(191)', 'UNIQUE' );
		db_add_index( 'T_users__tag', 'utag_name', 'utag_name(191)', 'UNIQUE' );
		db_add_index( 'T_users__fields', 'uf_varchar', 'uf_varchar(191)' );
		db_add_index( 'T_users__organization', 'org_name', 'org_name(191)', 'UNIQUE' );
		db_add_index( 'T_users__tag', 'utag_name', 'utag_name(191)', 'UNIQUE' );

		// Convert the columns from utf8_general_ci to utf8mb4_unicode_ci:
		db_convert_cols_to_utf8mb4( array(
			'T_antispam__keyword'          => array( 'askw_string' ),
			'T_automation__automation'     => array( 'autm_name' ),
			'T_automation__step'           => array( 'step_label', 'step_info' ),
			'T_basedomains'                => array( 'dom_comment' ),
			'T_blogs'                      => array( 'blog_shortname', 'blog_name', 'blog_tagline', 'blog_shortdesc', 'blog_longdesc', 'blog_notes', 'blog_keywords' ),
			'T_categories'                 => array( 'cat_name', 'cat_description' ),
			'T_coll_settings'              => array( 'cset_value' ),
			'T_comments'                   => array( 'comment_author', 'comment_content' ),
			'T_comments__prerendering'     => array( 'cmpr_content_prerendered' ),
			'T_cron__log'                  => array( 'clog_messages' ),
			'T_cron__task'                 => array( 'ctsk_name', 'ctsk_params' ),
			'T_email__campaign'            => array( 'ecmp_email_title', 'ecmp_email_html', 'ecmp_email_text', 'ecmp_email_plaintext', 'ecmp_user_tag', 'ecmp_user_tag_cta1', 'ecmp_user_tag_cta2', 'ecmp_user_tag_cta3', 'ecmp_user_tag_like', 'ecmp_user_tag_dislike', 'ecmp_user_tag_activate', 'ecmp_user_tag_unsubscribe' ),
			'T_email__log'                 => array( 'emlog_subject', 'emlog_headers', 'emlog_message' ),
			'T_email__newsletter'          => array( 'enlt_name', 'enlt_label' ),
			'T_email__returns'             => array( 'emret_errormsg', 'emret_headers', 'emret_message' ),
			'T_files'                      => array( 'file_title', 'file_alt', 'file_desc' ),
			'T_filetypes'                  => array( 'ftyp_name' ),
			'T_groups'                     => array( 'grp_name' ),
			'T_groups__groupsettings'      => array( 'gset_value' ),
			'T_hitlog'                     => array( 'hit_keyphrase' ),
			'T_i18n_original_string'       => array( 'iost_string' ),
			'T_items__item'                => array( 'post_content', 'post_excerpt', 'post_title', 'post_titletag' ),
			'T_items__item_settings'       => array( 'iset_value' ),
			'T_items__prerendering'        => array( 'itpr_content_prerendered' ),
			'T_items__status'              => array( 'pst_name' ),
			'T_items__type'                => array( 'ityp_name', 'ityp_description', 'ityp_instruction', 'ityp_comment_form_msg', 'ityp_evobar_link_text', 'ityp_skin_btn_text' ),
			'T_items__type_custom_field'   => array( 'itcf_label', 'itcf_note' ),
			'T_items__version'             => array( 'iver_title', 'iver_content' ),
			'T_locales'                    => array( 'loc_name', 'loc_messages', 'loc_transliteration_map' ),
			'T_messaging__contact_groups'  => array( 'cgr_name' ),
			'T_messaging__message'         => array( 'msg_text' ),
			'T_messaging__prerendering'    => array( 'mspr_content_prerendered' ),
			'T_messaging__thread'          => array( 'thrd_title' ),
			'T_plugingroupsettings'        => array( 'pgset_value' ),
			'T_plugins'                    => array( 'plug_name', 'plug_shortdesc' ),
			'T_pluginsettings'             => array( 'pset_value' ),
			'T_pluginusersettings'         => array( 'puset_value' ),
			'T_polls__option'              => array( 'popt_option_text' ),
			'T_polls__question'            => array( 'pqst_question_text' ),
			'T_regional__city'             => array( 'city_name' ),
			'T_regional__country'          => array( 'ctry_name' ),
			'T_regional__currency'         => array( 'curr_shortcut', 'curr_name' ),
			'T_regional__region'           => array( 'rgn_name' ),
			'T_regional__subregion'        => array( 'subrg_name' ),
			'T_section'                    => array( 'sec_name' ),
			'T_settings'                   => array( 'set_value' ),
			'T_skins__skin'                => array( 'skin_name' ),
			'T_syslog'                     => array( 'slg_message' ),
			'T_track__goal'                => array( 'goal_name', 'goal_notes' ),
			'T_track__goalcat'             => array( 'gcat_name' ),
			'T_track__goalhit'             => array( 'ghit_params' ),
			'T_users'                      => array( 'user_firstname', 'user_lastname', 'user_nickname' ),
			'T_users__fielddefs'           => array( 'ufdf_name', 'ufdf_options', 'ufdf_bubbletip' ),
			'T_users__fieldgroups'         => array( 'ufgp_name' ),
			'T_users__fields'              => array( 'uf_varchar' ),
			'T_users__organization'        => array( 'org_name' ),
			'T_users__reports'             => array( 'urep_info' ),
			'T_users__tag'                 => array( 'utag_name' ),
			'T_users__usersettings'        => array( 'uset_value' ),
			'T_users__user_org'            => array( 'uorg_role' ),
			'T_widget__container'          => array( 'wico_name' ),
			'T_widget__widget'             => array( 'wi_params' ),
		) );

		upg_task_end();
	}

	if( upg_task_start( 15140, 'Converting columns to utf8mb4...' ) )
	{	// part of 7.0.0-alpha
		db_convert_cols_to_utf8mb4( array(
			'T_email__campaign' => array( 'ecmp_name', 'ecmp_user_tag_sendskip', 'ecmp_user_tag_sendsuccess' ),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15150, 'Converting columns to utf8mb4...' ) )
	{	// part of 7.0.0-alpha
		db_convert_cols_to_utf8mb4( array(
			'T_items__type_custom_field' => array( 'itcf_format' ),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15160, 'Creating table for URL aliases...' ) )
	{	// part of 7.0.0-alpha
		db_create_table( 'T_coll_url_aliases', "
			cua_coll_ID   INT(11) UNSIGNED NOT NULL,
			cua_url_alias VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			PRIMARY KEY   ( cua_url_alias ),
			INDEX         cua_coll_ID ( cua_coll_ID )" );
		upg_task_end();
	}

	if( upg_task_start( 15170, 'Updating Antispam IP Ranges table... ' ) )
	{ // part of 7.0.0-alpha
		db_modify_col( 'T_antispam__iprange', 'aipr_status', 'enum( "trusted", "probably_ok", "suspect", "very_suspect", "blocked" ) COLLATE ascii_general_ci NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15180, 'Upgrade table item types... ') )
	{ // part of 7.0.0-alpha
		db_add_col( 'T_items__type', 'ityp_schema', 'ENUM( "Article", "WebPage", "BlogPosting", "ImageGallery", "DiscussionForumPosting", "TechArticle" ) COLLATE ascii_general_ci NULL DEFAULT NULL AFTER ityp_template_name' );
		upg_task_end();
	}

	if( upg_task_start( 15190, 'Installing new widgets/containers...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'item_list' );
		install_new_default_widgets( 'item_in_list' );
		install_new_default_widgets( 'item_single_header', 'item_visibility_badge,item_title,item_next_previous' );
		install_new_default_widgets( 'item_single', 'item_visibility_badge,item_title' );
		upg_task_end();
	}

	if( upg_task_start( 15210, 'Update free html widgets...' ) )
	{	// part of 7.0.0-alpha
		$SQL = new SQL( 'Get free html widget to update new option "renderers"' );
		$SQL->SELECT( 'wi_ID, wi_params' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->WHERE( 'wi_code = "free_html"' );
		$free_html_widgets = $DB->get_assoc( $SQL );
		foreach( $free_html_widgets as $free_html_widget_ID => $free_html_widget_params )
		{
			$free_html_widget_params = ( $free_html_widget_params === NULL ? array() : unserialize( $free_html_widget_params ) );
			// Turn off all renderer plugins for old widgets:
			$free_html_widget_params['renderers'] = array();
			$DB->query( 'UPDATE T_widget__widget
				  SET wi_params = '.$DB->quote( serialize( $free_html_widget_params ) ).'
				WHERE wi_ID = '.$free_html_widget_ID );
		}
		upg_task_end();
	}

	if( upg_task_start( 15220, 'Updating table item types... ' ) )
	{ // part of 7.0.0-alpha
		db_add_col( 'T_items__type', 'ityp_add_aggregate_rating', 'TINYINT DEFAULT 1 AFTER ityp_schema' );
		db_modify_col( 'T_items__type', 'ityp_schema', 'ENUM( "Article", "WebPage", "BlogPosting", "ImageGallery", "DiscussionForumPosting", "TechArticle", "Product" ) COLLATE ascii_general_ci NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15230, 'Installing new widgets/containers...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'front_page_column_a' );
		install_new_default_widgets( 'front_page_column_b' );
		install_new_default_widgets( 'front_page_area_3' );
		install_new_default_widgets( 'user_profile_left' );
		install_new_default_widgets( 'user_profile_right' );
		install_new_default_widgets( 'user_page_reputation' );
		upg_task_end();
	}

	if( upg_task_start( 15240, 'Updating table item types...' ) )
	{ // part of 7.0.0-alpha
		db_modify_col( 'T_items__type', 'ityp_schema', 'ENUM( "Article", "WebPage", "BlogPosting", "ImageGallery", "DiscussionForumPosting", "TechArticle", "Product", "Review" ) COLLATE ascii_general_ci NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15250, 'Updating table item custom fields...' ) )
	{ // part of 7.0.0-alpha
		db_add_col( 'T_items__type_custom_field', 'itcf_schema_prop', 'VARCHAR(255) COLLATE ascii_general_ci NULL AFTER itcf_name' );
		upg_task_end();
	}

	if( upg_task_start( 15260, 'Installing new shared widgets/containers...' ) )
	{	// part of 7.0.0-alpha
		// Initialize environment variable $Settings in order to work with collection objects:
		upg_init_environment();
		if( $info_Blog = & get_setting_Blog( 'info_blog_ID' ) )
		{	// If site uses collection for info pages(shared content blocks):
			global $installed_collection_info_pages;
			$SQL = new SQL( 'Get all pages from Collection for info pages(shared content blocks)' );
			$SQL->SELECT( 'post_ID' );
			$SQL->FROM( 'T_items__item' );
			$SQL->FROM_add( 'INNER JOIN T_categories ON post_main_cat_ID = cat_ID' );
			$SQL->FROM_add( 'INNER JOIN T_items__type ON post_ityp_ID = ityp_ID' );
			$SQL->WHERE( 'cat_blog_ID = '.$info_Blog->ID );
			$SQL->WHERE_and( 'ityp_usage = "page"' );
			// Get only pages which are allowed to be displayed on front-office:
			$SQL->WHERE_and( 'post_status IN ( '.$DB->quote( get_inskin_statuses( $info_Blog->ID, 'post' ) ).' )' );
			// Set pages from info/shared collection in order to create menu items in shared widget containers "Main Navigation" and "Navigation Hamburger":
			$installed_collection_info_pages = $DB->get_col( $SQL );
		}

		// Install new shared widgets/containers:
		install_new_default_widgets( 'site_header' );
		install_new_default_widgets( 'site_footer' );
		install_new_default_widgets( 'navigation_hamburger' );
		install_new_default_widgets( 'main_navigation' );
		install_new_default_widgets( 'right_navigation' );
		upg_task_end();
	}

	if( upg_task_start( 15270, 'Upgrading widget containers table...' ) )
	{	// part of 7.0.0-alpha
		// Add new column for Page Widget Containers:
		db_add_col( 'T_widget__container', 'wico_item_ID', 'INT(11) UNSIGNED NULL DEFAULT NULL' );
		// Insert default Item Type which items should be used for Page Containers:
		$widget_page_result = $DB->query( 'INSERT INTO T_items__type ( ityp_name, ityp_usage, ityp_template_name, ityp_use_text, ityp_use_coordinates, ityp_use_comments, ityp_perm_level )
			VALUES ( "Widget Page", "widget-page", "widget_page", "never", "optional", 0, "admin")' );
		if( $widget_page_result && $DB->insert_id > 0 )
		{	// Enable new inserted Item Type "Widget Page" for all collections:
			$DB->query( 'INSERT INTO T_items__type_coll ( itc_ityp_ID, itc_coll_ID )
				SELECT '.$DB->insert_id.', blog_ID FROM T_blogs' );
		}
		upg_task_end();
	}

	if( upg_task_start( 15280, 'Creating item custom field values table...' ) )
	{	// part of 7.0.0-alpha
		db_create_table( 'T_items__item_custom_field', '
			icfv_item_ID     INT UNSIGNED NOT NULL,
			icfv_itcf_name   VARCHAR(255) COLLATE ascii_general_ci NOT NULL,
			icfv_value       VARCHAR( 10000 ) COLLATE utf8mb4_unicode_ci NULL,
			icfv_parent_sync TINYINT(1) NOT NULL DEFAULT 1,
			PRIMARY KEY      ( icfv_item_ID, icfv_itcf_name )' );
		// Move custom field values from settings table to new created above:
		$DB->query( 'INSERT INTO T_items__item_custom_field ( icfv_item_ID, icfv_itcf_name, icfv_value )
			SELECT iset_item_ID, SUBSTRING( iset_name, 8 ), iset_value
			  FROM T_items__item_settings
			 WHERE iset_name LIKE "custom:%"' );
		$DB->query( 'DELETE FROM T_items__item_settings
			WHERE iset_name LIKE "custom:%"' );
		upg_task_end();
	}

	if( upg_task_start( 15290, 'Updating item types table...' ) )
	{	// part of 7.0.0-alpha
		db_add_col( 'T_items__type', 'ityp_short_title_maxlen', 'SMALLINT UNSIGNED DEFAULT 30' );
		db_add_col( 'T_items__type', 'ityp_title_maxlen', 'SMALLINT UNSIGNED DEFAULT 100' );

		// Set comment max length for forum collections to NULL:
		$SQL = new SQL( 'Get all pages from Collection for info pages(shared content blocks)' );
		$SQL->SELECT( 'blog_ID' );
		$SQL->FROM( 'T_blogs' );
		$SQL->WHERE( 'blog_type = "forum"' );

		$forum_collections = $DB->get_col( $SQL );
		if( $forum_collections )
		{
			$insert_values = array();
			foreach( $forum_collections as $coll_ID )
			{
				$insert_values[] = '( '.$DB->quote( $coll_ID ).', "comment_maxlen", "" )';
			}
			$DB->query( 'REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value ) VALUES '.implode( ', ', $insert_values ) );
		}

		upg_task_end();
	}

	if( upg_task_start( 15300, 'Installing new widget container "Comment Area"...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'comment_area' );
		upg_task_end();
	}

	if( upg_task_start( 15310, 'Installing new shared widget container "Marketing Popup"...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'marketing_popup' );
		upg_task_end();
	}

	if( upg_task_start( 15320, 'Installing new widget container "Chapter Main Area"...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'chapter_main_area' );
		upg_task_end();
	}

	if( upg_task_start( 15330, 'Updating widget "Email capture / Quick registration"...' ) )
	{	// part of 7.0.0-alpha
		$SQL = new SQL( 'Get email capture widgets to update params from checkbox to checklist' );
		$SQL->SELECT( 'wi_ID, wi_params' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->WHERE( 'wi_code = "user_register_quick"' );
		$SQL->WHERE_and( 'wi_params IS NOT NULL' );
		$widgets = $DB->get_assoc( $SQL );
		foreach( $widgets as $widget_ID => $widget_params )
		{
			$widget_params = @unserialize( $widget_params );
			if( ! $widget_params )
			{	// Skip wrong widget params:
				continue;
			}
			// Set the param values in new format:
			$widget_params['subscribe'] = array(
					'post'    => empty( $widget_params['subscribe_post'] ) ? 0 : 1,
					'comment' => empty( $widget_params['subscribe_comment'] ) ? 0 : 1,
				);
			if( isset( $widget_params['subscribe_post'] ) )
			{	// Remove old param:
				unset( $widget_params['subscribe_post'] );
			}
			if( isset( $widget_params['subscribe_comment'] ) )
			{	// Remove old param:
				unset( $widget_params['subscribe_comment'] );
			}
			// Update widget params:
			$DB->query( 'UPDATE T_widget__widget
				  SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
				WHERE wi_ID = '.$widget_ID );
		}
		upg_task_end();
	}

	if( upg_task_start( 15340, 'Updating checkbox plugins settings...' ) )
	{	// part of 7.0.0-alpha

		/**
		 * Convert general plugin checkbox settings to checklist format
		 *
		 * @param string Plugin class name
		 * @param array Setting replacements
		 */
		function upg_convert_plugin_checkbox_settings( $plugin_classname, $setting_replacements )
		{
			global $DB;

			$new_plugin_setting_sql = array();
			$set_names = array();

			foreach( $setting_replacements as $settings_group => $setting_replacement )
			{
				foreach( $setting_replacement as $setting_replacement_new )
				{
					$set_name = $settings_group.'_'.$setting_replacement_new;
					$setting_replacement[ $set_name ] = $setting_replacement_new;
					$set_names[] = $set_name;
				}
				$SQL = new SQL( 'Get plugins to update params from checkbox to checklist' );
				$SQL->SELECT( 'plug_ID, pset_name, pset_value' );
				$SQL->FROM( 'T_plugins' );
				$SQL->FROM_add( 'INNER JOIN T_pluginsettings ON plug_ID = pset_plug_ID' );
				$SQL->WHERE( 'plug_classname = '.$DB->quote( $plugin_classname ) );
				$SQL->WHERE_and( 'pset_plug_ID IS NOT NULL' );
				$SQL->WHERE_and( 'pset_name IN ( '.$DB->quote( array_keys( $setting_replacement ) ).' )' );
				$plugin_settings = $DB->get_results( $SQL );

				if( empty( $plugin_settings ) )
				{	// Nothing to update because either plugin has default settings or it doesn't exist:
					continue;
				}

				$new_plugin_settings = array();
				foreach( $plugin_settings as $plugin_setting )
				{
					if( ! isset( $new_plugin_settings[ $plugin_setting->plug_ID ] ) )
					{
						$new_plugin_settings[ $plugin_setting->plug_ID ] = array();
					}
					if( ! isset( $new_plugin_settings[ $plugin_setting->plug_ID ][ $settings_group ] ) )
					{
						$new_plugin_settings[ $plugin_setting->plug_ID ][ $settings_group ] = array();
					}
					if( empty( $plugin_setting->pset_value ) )
					{
						continue;
					}
					$new_plugin_settings[ $plugin_setting->plug_ID ][ $settings_group ][ $setting_replacement[ $plugin_setting->pset_name ] ] = $plugin_setting->pset_value;
				}
				foreach( $new_plugin_settings as $new_set_plugin_ID => $new_set_value )
				{
					$new_plugin_setting_sql[] = '( '.$new_set_plugin_ID.', '.$DB->quote( $settings_group ).', '.$DB->quote( serialize( $new_set_value[ $settings_group ] ) ).' )';
				}
			}

			if( ! empty( $new_plugin_setting_sql ) )
			{	// Insert new setting in new format:
				$DB->query( 'INSERT INTO T_pluginsettings ( pset_plug_ID, pset_name, pset_value )
					VALUES '.implode( ', '."\n", $new_plugin_setting_sql ) );
				// Delete old settings:
				$DB->query( 'DELETE ps FROM T_pluginsettings AS ps
					INNER JOIN T_plugins AS p ON plug_ID = pset_plug_ID
					WHERE plug_classname = '.$DB->quote( $plugin_classname ).'
						AND pset_name IN ( '.$DB->quote( $set_names ).' )' );
			}
		}

		/**
		 * Convert collection plugin checkbox settings to checklist format
		 *
		 * @param string Plugin class name
		 * @param array Setting replacements
		 */
		function upg_convert_plugin_coll_checkbox_settings( $plugin_classname, $setting_replacements )
		{
			global $DB;

			$new_plugin_setting_sql = array();
			$sql_join_cond = array();

			foreach( $setting_replacements as $settings_group => $setting_replacement )
			{
				$curr_sql_join_cond = array();
				foreach( $setting_replacement as $setting_replacement_new )
				{
					$setting_replacement[ $settings_group.'_'.$setting_replacement_new ] = $setting_replacement_new;
					$join_cond = 'cset_name = CONCAT( "plugin", plug_ID, "_'.$settings_group.'_'.$setting_replacement_new.'" )';;
					$sql_join_cond[] = $join_cond;
					$curr_sql_join_cond[] = $join_cond;
				}

				$SQL = new SQL( 'Get plugins to update params from checkbox to checklist' );
				$SQL->SELECT( 'plug_ID, cset_coll_ID, cset_name, cset_value' );
				$SQL->FROM( 'T_plugins' );
				$SQL->FROM_add( 'INNER JOIN T_coll_settings ON '.implode( ' OR ', $curr_sql_join_cond ) );
				$SQL->WHERE( 'plug_classname = '.$DB->quote( $plugin_classname ) );
				$plugin_settings = $DB->get_results( $SQL );

				if( empty( $plugin_settings ) )
				{	// Nothing to update because either plugin has default settings or it doesn't exist:
					continue;
				}

				$new_plugin_settings = array();
				foreach( $plugin_settings as $plugin_setting )
				{
					if( ! isset( $new_plugin_settings[ $plugin_setting->cset_coll_ID ][ $plugin_setting->plug_ID ] ) )
					{
						$new_plugin_settings[ $plugin_setting->cset_coll_ID ][ $plugin_setting->plug_ID ] = array();
					}
					if( ! isset( $new_plugin_settings[ $plugin_setting->cset_coll_ID ][ $plugin_setting->plug_ID ][ $settings_group ] ) )
					{
						$new_plugin_settings[ $plugin_setting->cset_coll_ID ][ $plugin_setting->plug_ID ][ $settings_group ] = array();
					}
					if( empty( $plugin_setting->cset_value ) )
					{
						continue;
					}
					$cset_name = substr( $plugin_setting->cset_name, strlen( 'plugin'.$plugin_setting->plug_ID.'_' ) );
					$new_plugin_settings[ $plugin_setting->cset_coll_ID ][ $plugin_setting->plug_ID ][ $settings_group ][ $setting_replacement[ $cset_name ] ] = $plugin_setting->cset_value;
				}
				foreach( $new_plugin_settings as $new_set_coll_ID => $new_set_plugins )
				{
					foreach( $new_set_plugins as $new_set_plugin_ID => $new_set_value )
					{
						$new_plugin_setting_sql[] = '( '.$new_set_coll_ID.', '.$DB->quote( 'plugin'.$new_set_plugin_ID.'_'.$settings_group ).', '.$DB->quote( serialize( $new_set_value[ $settings_group ] ) ).' )';
					}
				}
			}

			if( ! empty( $new_plugin_setting_sql ) )
			{	// Insert new setting in new format:
				$DB->query( 'INSERT INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
					VALUES '.implode( ', ', $new_plugin_setting_sql ) );
				// Delete old settings:
				$DB->query( 'DELETE cs FROM T_coll_settings AS cs
					INNER JOIN T_plugins AS p ON '.implode( ' OR ', $sql_join_cond ).'
					WHERE plug_classname = '.$DB->quote( $plugin_classname ) );
			}
		}

		// Update plugin "Autolinks":
		upg_convert_plugin_checkbox_settings( 'autolinks_plugin', array(
				// - general settings:
				'autolink' => array( 'urls', 'defs_default', 'defs_local' ),
				// - message settings:
				'msg_autolink_nofollow' => array( 'exist', 'explicit', 'auto' ),
				// - email campaign settings:
				'email_autolink_nofollow' => array( 'exist', 'explicit', 'auto' ),
				// - shared widget container settings:
				'shared_autolink_nofollow' => array( 'exist', 'explicit', 'auto' ),
			) );
		// - collection settings:
		upg_convert_plugin_coll_checkbox_settings( 'autolinks_plugin', array(
				'autolink_post_nofollow'    => array( 'exist', 'explicit', 'auto' ),
				'autolink_comment_nofollow' => array( 'exist', 'explicit', 'auto' ),
			) );

		// Update collection settings of the plugin "Flowplayer":
		upg_convert_plugin_coll_checkbox_settings( 'flowplayer_plugin', array(
				'use_for' => array( 'posts', 'comments' ),
			) );

		// Update collection settings of the plugin "HTML 5 MediaElement.js Video and Audio Player":
		upg_convert_plugin_coll_checkbox_settings( 'html5_mediaelementjs_plugin', array(
				'use_for' => array( 'posts', 'comments' ),
			) );

		// Update collection settings of the plugin "HTML 5 VideoJS Player":
		upg_convert_plugin_coll_checkbox_settings( 'html5_videojs_plugin', array(
				'use_for' => array( 'posts', 'comments' ),
			) );

		upg_task_end();
	}

	if( upg_task_start( 15350, 'Installing minisite collection default skin...' ) )
	{	// part of 7.0.0-alpha
		load_funcs( 'skins/_skin.funcs.php' );
		skin_install( 'jared_skin', true );
		upg_task_end();
	}

	if( upg_task_start( 15360, 'Fix integer unsigned ID columns...' ) )
	{	// part of 7.0.0-alpha
		$tables_num = 0;
		$columns_num = 0;
		$tables = $DB->get_col( 'SHOW TABLES' );
		// Ignore these ID columns because they can be be signed:
		$ignore_signed_columns = array(
			'step_yes_next_step_ID',
			'step_no_next_step_ID',
			'step_error_next_step_ID',
		);
		foreach( $tables as $table_name )
		{
			if( ! in_array( $table_name, $db_config['aliases'] ) )
			{	// Skip not core table, e.g. custom plugin tables:
				continue;
			}
			$modify_columns = array();
			// ID field must be unsigned 10 digit size instead of wrong 11:
			$columns = $DB->get_results( 'SHOW FULL COLUMNS FROM '.$table_name
				.' WHERE Field LIKE "%_ID"'
				.' AND Type LIKE "int(11)%"' );
			foreach( $columns as $column )
			{
				if( in_array( $column->Field, $ignore_signed_columns ) )
				{	// Skip signed columns:
					continue;
				}
				$modify_columns[ $column->Field ] = 'MODIFY COLUMN `'.$column->Field.'` '
					.'INT(10) UNSIGNED ' // Change from INT(11) to INT(10)
					.( $column->Null == 'YES' ? 'NULL' : 'NOT NULL' )
					.( $column->Default === NULL ? '' : ' DEFAULT '.$DB->quote( $column->Default ) )
					.( empty( $column->Extra ) ? '' : ' '.$column->Extra )
					.( empty( $column->Comment ) ? '' : ' COMMENT '.$DB->quote( $column->Comment ) );
				$columns_num++;
			}
			if( ! empty( $modify_columns ) )
			{	// Upgrade wrong integer unsigned ID columns:
				echo '<br />- table <code>'.$table_name.'</code>, columns: <code>'.implode( '</code>, <code>', array_keys( $modify_columns ) ).'</code>...';
				evo_flush();
				$DB->query( 'ALTER TABLE '.$table_name.' '.implode( ', ', $modify_columns ) );
				$tables_num++;
			}
		}
		echo '<br />'.$columns_num.' columns have been modified in '.$tables_num.' tables - ';
		upg_task_end();
	}

	if( upg_task_start( 15370, 'Installing new widget container "Photo Index"...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'photo_index' );
		// Move skin setting "Thumbnail size in Media index" to widget "Photo Index" of new created container "Photo Index":
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_params, cset_value' );
		$SQL->FROM( 'T_widget__container' );
		$SQL->FROM_add( 'INNER JOIN T_coll_settings ON cset_coll_ID = wico_coll_ID' );
		$SQL->FROM_add( 'INNER JOIN T_widget__widget ON wi_wico_ID = wico_ID' );
		$SQL->WHERE( 'wico_code = "photo_index"' );
		$SQL->WHERE_and( 'wi_code = "coll_media_index"' );
		$SQL->WHERE_and( 'cset_name LIKE "skin%mediaidx\_thumb\_size"' );
		$skin_settings = $DB->get_results( $SQL );
		foreach( $skin_settings as $skin_setting )
		{
			$wi_params = empty( $skin_setting->wi_params ) ? array() : @unserialize( $skin_setting->wi_params );
			if( ! is_array( $wi_params ) )
			{
				$wi_params = array();
			}
			// Update widget thumb size setting with value what was stored in skin settings:
			$wi_params['thumb_size'] = $skin_setting->cset_value;
			$DB->query( 'UPDATE T_widget__widget
				  SET wi_params = '.$DB->quote( serialize( $wi_params ) ).'
				WHERE wi_ID = '.$DB->quote( $skin_setting->wi_ID ) );
		}
		upg_task_end();
	}

	if( upg_task_start( 15380, 'Upgrading posts table...' ) )
	{	// part of 7.0.1-beta
		db_add_col( 'T_items__item', 'post_locale_visibility', 'ENUM( "always", "follow-nav-locale" ) COLLATE ascii_general_ci NOT NULL DEFAULT "always" AFTER post_locale' );
		upg_task_end();
	}

	if( upg_task_start( 15390, 'Creating table for collection extra locales...' ) )
	{	// part of 7.0.1-beta
		db_create_table( 'T_coll_locales', '
			cl_coll_ID INT(10) UNSIGNED NOT NULL,
			cl_locale  VARCHAR(20) COLLATE ascii_general_ci NOT NULL,
			PRIMARY KEY cl_coll_loc_pk (cl_coll_ID, cl_locale)' );
		upg_task_end();
	}

	if( upg_task_start( 15400, 'Inserting collection extra locales...' ) )
	{	// part of 7.0.1-beta
		$DB->query( 'INSERT INTO T_coll_locales ( cl_coll_ID, cl_locale )
			SELECT blog_ID, blog_locale
			  FROM T_blogs' );
		upg_task_end();
	}

	if( upg_task_start( 15410, 'Creating table for Post Groups...' ) )
	{	// part of 7.0.1-beta
		db_create_table( 'T_items__itemgroup', '
			igrp_ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			PRIMARY KEY (igrp_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 15420, 'Upgrading posts table...' ) )
	{	// part of 7.0.1-beta
		db_add_col( 'T_items__item', 'post_igrp_ID', 'INT(10) UNSIGNED NULL AFTER post_ityp_ID' );
		upg_task_end();
	}

	if( upg_task_start( 15430, 'Updating collection locale setting for new posts...' ) )
	{	// part of 7.0.1-beta
		$DB->query( 'UPDATE T_coll_settings
			  SET cset_value = "select_coll"
			WHERE cset_name = "new_item_locale_source"
			  AND cset_value = "use_coll"' );
		upg_task_end();
	}

	if( upg_task_start( 15440, 'Upgrading table of collection extra locales and linking with other collections...' ) )
	{	// part of 7.0.1-beta
		db_add_col( 'T_coll_locales', 'cl_linked_coll_ID', 'INT(10) UNSIGNED NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15450, 'Installing new default widgets...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'page_top', 'coll_locale_switch' );
		upg_task_end();
	}

	if( upg_task_start( 15460, 'Upgrading files table...' ) )
	{	// part of 7.0.1-beta
		db_upgrade_cols( 'T_files', array(
			'ADD' => array(
				'file_ts'  => 'TIMESTAMP NOT NULL DEFAULT "2000-01-01 00:00:00" AFTER file_path',
				'file_width'  => 'INT(10) UNSIGNED NULL AFTER file_ts',
				'file_height'  => 'INT(10) UNSIGNED NULL AFTER file_width',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15470, 'Creating SVG file type...' ) )
	{	// part of 7.0.1-beta
		$SQL = new SQL( 'Check for file type .svg' );
		$SQL->SELECT( 'ftyp_ID' );
		$SQL->FROM( 'T_filetypes' );
		$SQL->WHERE( 'ftyp_extensions REGEXP "(^| )svg( |$)"' );
		if( ! $DB->get_var( $SQL ) )
		{	// Insert new SVG file type only if it doesn't exist:
			$DB->query( 'INSERT INTO T_filetypes
				       ( ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed )
				VALUES ( "svg", "SVG file", "image/svg+xml", "file_document", "image", "admin" )' );
		}
		upg_task_end();
	}

	if( upg_task_start( 15480, 'Creating ICO file type...' ) )
	{	// part of 7.0.1-beta
		$SQL = new SQL( 'Check for file type .ico' );
		$SQL->SELECT( 'ftyp_ID' );
		$SQL->FROM( 'T_filetypes' );
		$SQL->WHERE( 'ftyp_extensions REGEXP "(^| )ico( |$)"' );
		if( ! $DB->get_var( $SQL ) )
		{	// Insert new ICO file type only if it doesn't exist:
			$DB->query( 'INSERT INTO T_filetypes
				       ( ftyp_extensions, ftyp_name, ftyp_mimetype, ftyp_icon, ftyp_viewtype, ftyp_allowed )
				VALUES ( "ico", "ICO image", "image/x-icon", "file_image", "image", "admin" )' );
		}
		upg_task_end();
	}

	if( upg_task_start( 15490, 'Upgrading collection permission tables...' ) )
	{	// part of 7.0.2-beta
		db_upgrade_cols( 'T_coll_user_perms', array(
			'ADD' => array(
				'bloguser_workflow_status'   => 'tinyint NOT NULL default 0 AFTER bloguser_can_be_assignee',
				'bloguser_workflow_user'     => 'tinyint NOT NULL default 0 AFTER bloguser_workflow_status',
				'bloguser_workflow_priority' => 'tinyint NOT NULL default 0 AFTER bloguser_workflow_user',
			),
		) );
		$DB->query( 'UPDATE T_coll_user_perms
			  SET bloguser_workflow_status = 1,
			      bloguser_workflow_user = 1
			WHERE bloguser_can_be_assignee = 1' );
		db_upgrade_cols( 'T_coll_group_perms', array(
			'ADD' => array(
				'bloggroup_workflow_status'   => 'tinyint NOT NULL default 0 AFTER bloggroup_can_be_assignee',
				'bloggroup_workflow_user'     => 'tinyint NOT NULL default 0 AFTER bloggroup_workflow_status',
				'bloggroup_workflow_priority' => 'tinyint NOT NULL default 0 AFTER bloggroup_workflow_user',
			),
		) );
		$DB->query( 'UPDATE T_coll_group_perms
			  SET bloggroup_workflow_status = 1,
			      bloggroup_workflow_user = 1
			WHERE bloggroup_can_be_assignee = 1' );
		upg_task_end();
	}

	if( upg_task_start( 15500, 'Upgrading item types and custom fields tables...' ) )
	{	// part of 7.0.2-beta
		db_upgrade_cols( 'T_items__type', array(
			'ADD' => array(
				'ityp_text_template'           => 'TEXT COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL AFTER ityp_instruction',
				'ityp_front_order_title'       => 'SMALLINT NULL',
				'ityp_front_order_short_title' => 'SMALLINT NULL',
				'ityp_front_order_instruction' => 'SMALLINT NULL',
				'ityp_front_order_attachments' => 'SMALLINT NULL',
				'ityp_front_order_text'        => 'SMALLINT NULL',
				'ityp_front_order_tags'        => 'SMALLINT NULL',
				'ityp_front_order_excerpt'     => 'SMALLINT NULL',
				'ityp_front_order_url'         => 'SMALLINT NULL',
			),
		) );
		$DB->query( 'UPDATE T_items__type
			SET ityp_front_order_title = 10,
			    ityp_front_order_instruction = CASE WHEN ityp_front_instruction = 1 THEN 20 ELSE NULL END,
			    ityp_front_order_attachments = 30,
			    ityp_front_order_text = 80' );
		db_drop_col( 'T_items__type', 'ityp_front_instruction' );
		db_upgrade_cols( 'T_items__type_custom_field', array(
			'ADD' => array(
				'itcf_required' => 'TINYINT DEFAULT 0 AFTER itcf_note',
				'itcf_meta'     => 'TINYINT DEFAULT 0 AFTER itcf_required',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15510, 'Upgrading item types tables...' ) )
	{	// part of 7.0.2-beta
		db_add_col( 'T_items__type', 'ityp_front_order_location', 'SMALLINT NULL' );
		$DB->query( 'UPDATE T_items__type
			SET ityp_front_order_location = 90' );
		upg_task_end();
	}

	if( upg_task_start( 15520, 'Creating table for aggregations of goal hits...' ) )
	{	// part of 7.0.2-beta
		db_create_table( 'T_track__goalhit_aggregate', '
			ghag_ID      INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			ghag_date    DATE NOT NULL DEFAULT "2000-01-01",
			ghag_goal_ID INT(10) UNSIGNED NOT NULL,
			ghag_count   INT(10) UNSIGNED NOT NULL,
			PRIMARY KEY  (ghag_ID),
			UNIQUE       ghag_date_goal_ID (ghag_date, ghag_goal_ID)',
			'ENGINE = myisam' );
		upg_task_end();
	}

	if( upg_task_start( 15530, 'Upgrading settings of the plugin "Short Links"...' ) )
	{	// part of 7.0.2-beta
		// Get plugin settings per collections:
		$coll_SQL = new SQL();
		$coll_SQL->SELECT( 'cset_coll_ID AS coll_ID_type, cset_name AS name, cset_value AS value' );
		$coll_SQL->FROM( 'T_coll_settings' );
		$coll_SQL->WHERE( 'cset_name LIKE "plugin%_link_types"' );
		$coll_SQL->WHERE_or( 'cset_name LIKE "plugin%_optimize"' );
		// Get plugin settings for Email Campaign and Private Messages:
		$msg_email_SQL = new SQL();
		$msg_email_SQL->SELECT( 'IF( pset_name IN ( "msg_link_types", "msg_optimize" ), "msg", "email" ) AS coll_ID_type, ' );
		$msg_email_SQL->SELECT_add( 'CONCAT( "plugin", pset_plug_ID, "_", REPLACE( REPLACE( pset_name, "email_", "" ), "msg_", "" ) ) AS name, ' );
		$msg_email_SQL->SELECT_add( 'pset_value AS value' );
		$msg_email_SQL->FROM( 'T_pluginsettings' );
		$msg_email_SQL->WHERE( 'pset_name IN ( "msg_link_types", "msg_optimize", "email_link_types", "email_optimize" )' );
		// Union two SQL queries above:
		$plug_SQL = new SQL( 'Get settings of the plugin "Short Links" to upgrade' );
		$plug_SQL->SELECT( 'coll_ID_type, name, value' );
		$plug_SQL->FROM( '( '.$coll_SQL->get().' UNION '.$msg_email_SQL->get().' ) AS plugin_settings' );
		$plug_SQL->ORDER_BY( 'coll_ID_type, name, value' );
		$plugin_rows = $DB->get_results( $plug_SQL );

		$plugin_settings = array();
		foreach( $plugin_rows as $plugin_row )
		{
			if( ! isset( $plugin_settings[ $plugin_row->coll_ID_type ] ) )
			{
				$plugin_settings[ $plugin_row->coll_ID_type ] = array();
			}
			if( ! preg_match( '#^plugin(\d+)_(.+)$#', $plugin_row->name, $set_match ) )
			{
				continue;
			}
			if( ! isset( $plugin_settings[ $plugin_row->coll_ID_type ][ $set_match[1] ] ) )
			{
				$plugin_settings[ $plugin_row->coll_ID_type ][ $set_match[1] ] = array();
			}
			$value = @unserialize( $plugin_row->value );
			$plugin_settings[ $plugin_row->coll_ID_type ][ $set_match[1] ][ $set_match[2] ] = $value ? $value : array();
		}

		foreach( $plugin_settings as $coll_ID_type => $plugin_data )
		{
			foreach( $plugin_data as $plugin_ID => $plugin_settings )
			{
				if( ! isset( $plugin_settings['link_types'] ) )
				{	// Skip if detault values are still used:
					continue;
				}
				if( isset( $plugin_settings['link_types']['abs_target_blank'] ) )
				{	// Rename old setting:
					$plugin_settings['link_types']['abs_url_target_blank'] = $plugin_settings['link_types']['abs_target_blank'];
					unset( $plugin_settings['link_types']['abs_target_blank'] );
				}
				if( isset( $plugin_settings['optimize']['absolute_urls'] ) )
				{	// Add new setting:
					$plugin_settings['link_types']['abs_url_optimize'] = $plugin_settings['optimize']['absolute_urls'];
				}
				if( isset( $plugin_settings['optimize']['relative_urls'] ) )
				{	// Add new setting:
					$plugin_settings['link_types']['rel_url_optimize'] = $plugin_settings['optimize']['relative_urls'];
				}
				switch( $coll_ID_type )
				{
					case 'msg':
					case 'email':
						// Plugin settings for Email Campaign and Private Messages
						// Update to new settings:
						$DB->query( 'UPDATE T_pluginsettings
							  SET pset_value = '.$DB->quote( serialize( $plugin_settings['link_types'] ) ).'
							WHERE pset_plug_ID = '.$DB->quote( $plugin_ID ).'
							  AND pset_name = '.$DB->quote( $coll_ID_type.'_link_types' ) );
						// Delete old setting:
						$DB->query( 'DELETE FROM T_pluginsettings
							WHERE pset_plug_ID = '.$DB->quote( $plugin_ID ).'
							  AND pset_name = '.$DB->quote( $coll_ID_type.'_optimize' ) );
						break;
					default:
						// Plugin settings per collection:
						// Update to new settings:
						$DB->query( 'UPDATE T_coll_settings
							  SET cset_value = '.$DB->quote( serialize( $plugin_settings['link_types'] ) ).'
							WHERE cset_coll_ID = '.$DB->quote( $coll_ID_type ).'
							  AND cset_name = '.$DB->quote( 'plugin'.$plugin_ID.'_link_types' ) );
						// Delete old setting:
						$DB->query( 'DELETE FROM T_coll_settings
							WHERE cset_coll_ID = '.$DB->quote( $coll_ID_type ).'
							  AND cset_name = '.$DB->quote( 'plugin'.$plugin_ID.'_optimize' ) );
						break;
				}
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15540, 'Upgrading comments table...' ) )
	{	// part of 7.0.2-beta
		db_upgrade_cols( 'T_comments', array(
			'CHANGE' => array(
				'comment_nofollow' => 'comment_author_url_nofollow TINYINT(1) NOT NULL DEFAULT 1',
			),
			'ADD' => array(
				'comment_author_url_ugc'       => 'TINYINT(1) NOT NULL DEFAULT 1 AFTER comment_author_url_nofollow',
				'comment_author_url_sponsored' => 'TINYINT(1) NOT NULL DEFAULT 0 AFTER comment_author_url_ugc',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15550, 'Installing new plugin "Nofollow UGC Sponsored"...' ) )
	{	// part of 7.0.2-beta
		upg_init_environment( 'Settings,Plugins,Plugins_admin' );
		install_plugin( 'nofollow_plugin',true, array(), array( 'single_task' => false ) );
		$nofollow_plugin_SQL = new SQL( 'Get nofollow plugin ID by class name' );
		$nofollow_plugin_SQL->SELECT( 'plug_ID' );
		$nofollow_plugin_SQL->FROM( 'T_plugins' );
		$nofollow_plugin_SQL->WHERE( 'plug_classname = "nofollow_plugin"' );
		if( $nofollow_plugin_ID = $DB->get_var( $nofollow_plugin_SQL ) )
		{	// Only if nofollow plugin is detected in DB:
			$coll_plug_settings_SQL = new SQL( 'Get autolinks plugin settings per collections in order to move them into nofollow plugin' );
			$coll_plug_settings_SQL->SELECT( 'cset_coll_ID, cset_value' );
			$coll_plug_settings_SQL->FROM( 'T_coll_settings' );
			$coll_plug_settings_SQL->FROM_add( 'INNER JOIN T_plugins ON cset_name = CONCAT( "plugin", plug_ID, "_autolink_post_nofollow" )' );
			$coll_plug_settings_SQL->WHERE( 'plug_classname = "autolinks_plugin"' );
			$coll_plug_settings = $DB->get_results( $coll_plug_settings_SQL );
			foreach( $coll_plug_settings as $coll_plug_setting )
			{
				$coll_plug_setting_values = @unserialize( $coll_plug_setting->cset_value );
				// If "No follow in posts" was enabled for pre-existings or explicit links in autolinks plugin:
				$nofollow_value = ( ! empty( $coll_plug_setting_values['exist'] ) || ! empty( $coll_plug_setting_values['explicit'] ) ? 1 : 0 );
				$DB->query( 'REPLACE INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
					VALUES ( '.$coll_plug_setting->cset_coll_ID.',
					         "plugin'.$nofollow_plugin_ID.'_abs_links_posts",
					         '.$DB->quote( serialize( array( 'nofollow' => $nofollow_value ) ) ).' )' );
			}
		}
		upg_clear_environment();
		upg_task_end();
	}

	if( upg_task_start( 15560, 'Upgrading settings of the plugin "Auto Links"...' ) )
	{	// part of 7.0.2-beta
		$autolinks_plugin_SQL = new SQL( 'Get autolinks plugin ID by class name' );
		$autolinks_plugin_SQL->SELECT( 'plug_ID, pset_value' );
		$autolinks_plugin_SQL->FROM( 'T_plugins' );
		$autolinks_plugin_SQL->FROM_add( 'LEFT JOIN T_pluginsettings ON plug_ID = pset_plug_ID' );
		$autolinks_plugin_SQL->WHERE( 'plug_classname = "autolinks_plugin"' );
		$autolinks_plugin_SQL->WHERE_and( 'pset_name = "autolink"' );
		if( $autolinks_plugin = $DB->get_row( $autolinks_plugin_SQL ) )
		{	// Only if autolinks plugin is detected in DB:
			$plugin_value = ( empty( $autolinks_plugin->pset_value ) ? false : @unserialize( $autolinks_plugin->pset_value ) );
			if( is_array( $plugin_value ) && empty( $plugin_value['urls'] ) )
			{	// Try to update only not default value (default value is checked):
				$DB->query( 'INSERT INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
					SELECT blog_ID, "plugin'.$autolinks_plugin->plug_ID.'_autolink_urls", 0
					  FROM T_blogs' );
				$DB->query( 'INSERT INTO T_coll_settings ( cset_coll_ID, cset_name, cset_value )
					SELECT blog_ID, "plugin'.$autolinks_plugin->plug_ID.'_autolink_emails", 0
					  FROM T_blogs' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15570, 'Upgrading widget containers table...' ) )
	{	// part of 7.0.2-beta
		db_upgrade_cols( 'T_widget__container', array(
			'MODIFY' => array(
				'wico_code' => 'VARCHAR(128) COLLATE ascii_general_ci NULL DEFAULT NULL',
				'wico_name' => 'VARCHAR(128) COLLATE utf8mb4_unicode_ci NOT NULL',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15580, 'Creating default item type "Homepage Content Tab"...' ) )
	{	// part of 7.0.2-beta
		$SQL = new SQL( 'Check at least one item type with name "Homepage Content Tab" for existence' );
		$SQL->SELECT( 'ityp_ID' );
		$SQL->FROM( 'T_items__type' );
		$SQL->WHERE( 'ityp_name = "Homepage Content Tab"' );
		$SQL->LIMIT( 1 );
		if( ! $DB->get_var( $SQL ) )
		{	// Create one default item type "Homepage Content Tab":
			$r = $DB->query( 'INSERT INTO T_items__type ( ityp_name, ityp_usage, ityp_use_short_title )
					VALUES ( "Homepage Content Tab", "post", "optional" )' );
			if( $r && $DB->insert_id > 0 )
			{	// Enable new created item type for all collections:
				$DB->query( 'INSERT INTO T_items__type_coll ( itc_ityp_ID, itc_coll_ID )
					SELECT '.$DB->insert_id.', blog_ID
					  FROM T_blogs
					 WHERE blog_type IN ( "main", "minisite" )' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15590, 'Installing new default widgets...' ) )
	{	// part of 7.0.2-beta
		install_new_default_widgets( 'item_single', 'breadcrumb_path' );
		upg_task_end();
	}

	if( upg_task_start( 15600, 'Creating table for Menus...' ) )
	{	// part of 7.0.2-beta
		db_create_table( 'T_menus__menu', '
			menu_ID     INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			menu_name   VARCHAR(128) COLLATE utf8mb4_unicode_ci NOT NULL,
			menu_locale VARCHAR(20) COLLATE ascii_general_ci NOT NULL DEFAULT "en-US",
			PRIMARY KEY (menu_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 15610, 'Creating table for Menu entries...' ) )
	{	// part of 7.0.2-beta
		db_create_table( 'T_menus__entry', '
			ment_ID             INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			ment_menu_ID        INT(10) UNSIGNED NOT NULL,
			ment_parent_ID      INT(10) UNSIGNED NULL,
			ment_order          INT(11) NULL,
			ment_text           VARCHAR(128) COLLATE utf8mb4_unicode_ci NULL,
			ment_type           VARCHAR(32) COLLATE ascii_general_ci NULL,
			ment_coll_logo_size VARCHAR(32) COLLATE ascii_general_ci NULL,
			ment_coll_ID        INT(10) UNSIGNED NULL,
			ment_cat_ID         INT(10) UNSIGNED NULL,
			ment_item_ID        INT(10) UNSIGNED NULL,
			ment_url            VARCHAR(2000) COLLATE utf8mb4_unicode_ci NULL,
			ment_visibility     ENUM( "always", "access" ) COLLATE ascii_general_ci NOT NULL DEFAULT "always",
			ment_highlight      TINYINT(1) NOT NULL DEFAULT 1,
			PRIMARY KEY          (ment_ID),
			INDEX ment_menu_ID   (ment_menu_ID),
			INDEX ment_parent_ID (ment_parent_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 15620, 'Creating default item type "Text Ad"...' ) )
	{	// part of 7.0.2-beta
		$SQL = new SQL( 'Check item type "Text Ad" with usage "content-block" for existence' );
		$SQL->SELECT( 'ityp_ID' );
		$SQL->FROM( 'T_items__type' );
		$SQL->WHERE( 'ityp_usage = "content-block"' );
		$SQL->WHERE_and( 'ityp_name = "Text Ad"' );
		$SQL->LIMIT( 1 );
		if( ! $DB->get_var( $SQL ) )
		{	// Create content block item type "Text Ad":
			$r = $DB->query( 'INSERT INTO T_items__type ( ityp_name, ityp_usage, ityp_allow_breaks, ityp_allow_featured, ityp_use_comments )
					VALUES ( '.$DB->quote( 'Text Ad' ).', '.$DB->quote( 'content-block' ).', 0, 0, 0 )' );
			if( $r && $DB->insert_id > 0 )
			{	// Enable new created item type for all collections:
				$DB->query( 'INSERT INTO T_items__type_coll ( itc_ityp_ID, itc_coll_ID )
					SELECT '.$DB->insert_id.', blog_ID
					  FROM T_blogs' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15630, 'Upgrading post type custom fields table...' ) )
	{	// part of 7.0.2-beta
		db_add_col( 'T_items__type_custom_field', 'itcf_disp_condition', 'VARCHAR(2000) COLLATE utf8mb4_unicode_ci NULL AFTER itcf_formula' );
		upg_task_end();
	}

	if( upg_task_start( 15640, 'Upgrading item types table...' ) )
	{	// part of 7.0.2-beta
		db_add_col( 'T_items__type', 'ityp_allow_switchable', 'TINYINT DEFAULT 1 AFTER ityp_allow_featured' );
		upg_task_end();
	}

	if( upg_task_start( 15650, 'Installing new widget container "Comment List"...' ) )
	{	// part of 7.0.2-beta
		install_new_default_widgets( 'comment_list' );
		upg_task_end();
	}

	if( upg_task_start( 15660, 'Upgrading base domains table...') )
	{	// part of 7.0.2-beta
		db_add_col( 'T_basedomains', 'dom_source_tag', 'VARCHAR(32) COLLATE utf8mb4_unicode_ci NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15670, 'Creating tables for Social Networks and User Social Networks...' ) )
	{	// part of 7.0.2-beta
		db_create_table( 'T_social__network', '
			sn_ID int(10) UNSIGNED NOT NULL auto_increment,
			sn_name VARCHAR(32) NOT NULL,
			PRIMARY KEY (sn_ID)' );

		db_create_table( 'T_users__social_network', '
			usn_user_ID INT(10) UNSIGNED NOT NULL,
			usn_sn_ID INT(10) UNSIGNED NOT NULL,
			usn_network_ID VARCHAR(256) COLLATE ascii_general_ci NOT NULL,
			usn_token VARCHAR(1000) NOT NULL,
			usn_token_expiration_ts TIMESTAMP NULL DEFAULT NULL,
			PRIMARY KEY (usn_user_ID, usn_sn_ID ),
			INDEX usn_network_ID (usn_network_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 15680, 'Installing default site skins...' ) )
	{	// part of 7.1.0-beta
		load_funcs( 'skins/_skin.funcs.php' );
		skin_install( 'bootstrap_site_navbar_skin', true );
		skin_install( 'bootstrap_site_tabs_skin', true );
		skin_install( 'bootstrap_site_dropdown_skin', true );
		upg_task_end();
	}

	if( upg_task_start( 15690, 'Upgrading menus table...' ) )
	{	// part of 7.1.0-beta
		db_add_col( 'T_menus__menu', 'menu_parent_ID', 'INT(10) UNSIGNED NULL DEFAULT NULL AFTER menu_ID' );
		upg_task_end();
	}

	if( upg_task_start( 15700, 'Creating tables for Templates...' ) )
	{	// part of 7.1.0-beta
		db_create_table( 'T_templates', '
			tpl_ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			tpl_name VARCHAR(128) COLLATE utf8mb4_unicode_ci NOT NULL,
			tpl_code VARCHAR(128) COLLATE ascii_general_ci NULL DEFAULT NULL,
			tpl_parent_tpl_ID INT(10) UNSIGNED NULL DEFAULT NULL,
			tpl_locale VARCHAR(20) COLLATE ascii_general_ci NOT NULL DEFAULT \'en-US\',
			tpl_template_code MEDIUMTEXT NULL,
			PRIMARY KEY (tpl_ID),
			UNIQUE tpl_code( tpl_code )' );

		/* fp> removed because unnecessary: this would be overwritten later anyways
		// Create default templates:
		$DB->query( 'INSERT INTO T_templates ( tpl_name, tpl_code, tpl_template_code ) VALUES
				( "Item Info: Posted by Author on Date in Categories", "iteminfo_short", "Posted by $author$ on $issue_time$ in $categories$" ),
				( "Item Info: Long info line", "iteminfo_long", "$flag_icon$ $permalink_icon$ Posted by $author$ $issue_time$ $categories$ — Last touched: $last_touched$ — Last Updated: $last_updated$ $edit_link$" )' );
		*/

		upg_task_end();
	}

	if( upg_task_start( 15710, 'Updating plugin "Nofollow UGC Sponsored"...' ) )
	{	// part of 7.1.0-beta
		$DB->query( 'UPDATE T_plugins
			  SET plug_priority = 99
			WHERE plug_classname = "nofollow_plugin"
			  AND plug_priority = 120' );
		upg_task_end();
	}

	if( upg_task_start( 15720, 'Installing new widgets/containers...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'item_in_list', 'item_content' );
		upg_task_end();
	}

	if( upg_task_start( 15730, 'Installing new widgets/containers...' ) )
	{	// part of 7.0.0-alpha
		install_new_default_widgets( 'chapter_main_area', 'cat_content_list' );
		upg_task_end();
	}

	if( upg_task_start( 15740, 'Upgrading renderers columns...' ) )
	{	// part of 7.0.0-alpha
		db_modify_col( 'T_email__campaign', 'ecmp_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_items__item', 'post_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_comments', 'comment_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_items__prerendering', 'itpr_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_comments__prerendering', 'cmpr_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_messaging__message', 'msg_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		db_modify_col( 'T_messaging__prerendering', 'mspr_renderers', 'VARCHAR(4000) COLLATE ascii_general_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15751, 'Creating new default templates...' ) )
	{	// part of 7.0.0-alpha

		// Delete the following existing default templates, they may be recreated at the end of upgrade process:
		$template_codes = array( 'iteminfo_long', 'iteminfo_short' );
		$DB->query( 'DELETE FROM T_templates WHERE tpl_code IN ('.$DB->quote( $template_codes ).')' );
		upg_task_end();
	}

	if( upg_task_start( 15760, 'Updating item footer...' ) )
	{	// part of 7.0.0-alpha
		// Delete widget "Item Footer":
		$DB->query( 'DELETE FROM T_widget__widget
			WHERE wi_code = "item_footer"' );

		// Install widget "Info Line" with Template: "Item Details: Comment Link":
		install_new_default_widgets( 'item_in_list', 'item_info_line' );
		upg_task_end();
	}

	if( upg_task_start( 15770, 'Updating widget "Small Print"...' ) )
	{	// part of 7.0.0-alpha
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_params' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->WHERE( 'wi_code = "item_small_print"' );
		$widgets = $DB->get_assoc( $SQL );

		foreach( $widgets as $widget_ID => $widget_params )
		{
			$widget_params = ( empty( $widget_params ) ? array() : unserialize( $widget_params ) );
			if( isset( $widget_params['format'] ) &&
			    $widget_params['format'] == 'revision' )
			{	// Convert "Format / Revisions" to Template "Item Details: Small Print: Revisions":
				$widget_params['template'] = 'item_details_revisions';
			}
			else
			{	// Convert "Format / Blog standard" to Template "Item Details: Small Print: Standard":
				$widget_params['template'] = 'item_details_smallprint_standard';
			}
			if( isset( $widget_params['format'] ) )
			{	// Remove setting "Format" completely from the widget:
				unset( $widget_params['format'] );
			}
			if( isset( $widget_params['avatar_size'] ) )
			{	// Remove setting "Avatar Size" completely from the widget:
				unset( $widget_params['avatar_size'] );
			}

			$DB->query( 'UPDATE T_widget__widget
				  SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
				WHERE wi_ID = '.$widget_ID );
		}

		upg_task_end();
	}

	if( upg_task_start( 15780, 'Updating widget "Info Line"...' ) )
	{	// part of 7.0.0-alpha
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_params, blog_type' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->FROM_add( 'LEFT JOIN T_widget__container ON wi_wico_ID = wico_ID' );
		$SQL->FROM_add( 'LEFT JOIN T_blogs ON wico_coll_ID = blog_ID' );
		$SQL->WHERE( 'wi_code = "item_info_line"' );
		$widgets = $DB->get_results( $SQL );

		foreach( $widgets as $row )
		{
			$widget_params = ( empty( $row->wi_params ) ? array() : unserialize( $row->wi_params ) );
			if(	empty( $widget_params['template'] ) )
			{	// Convert Template depending on collection type:
				switch( $row->blog_type )
				{
					case 'forum':
					case 'group':
						$widget_params['template'] = 'item_details_infoline_forums';
						break;

					default:
						$widget_params['template'] = 'item_details_infoline_standard'; 
				}
			}
			
			if( isset( $widget_params['flag_icon'] ) )
			{	// Remove setting "Display flag icon" completely from the widget:
				unset( $widget_params['flag_icon'] );
			}
			if( isset( $widget_params['permalink_icon'] ) )
			{	// Remove setting "Display permalink icon" completely from the widget:
				unset( $widget_params['permalink_icon'] );
			}
			if( isset( $widget_params['before_author'] ) )
			{	// Remove setting "Display author information" completely from the widget:
				unset( $widget_params['before_author'] );
			}
			if( isset( $widget_params['display_date'] ) )
			{	// Remove setting "Post date to display" completely from the widget:
				unset( $widget_params['display_date'] );
			}
			if( isset( $widget_params['last_touched'] ) )
			{	// Remove setting "Display date and time when item/post was last touched" completely from the widget:
				unset( $widget_params['last_touched'] );
			}
			if( isset( $widget_params['contents_updated'] ) )
			{	// Remove setting "Display date and time when item/post contents (title, content, URL or attachments) were last updated" completely from the widget:
				unset( $widget_params['contents_updated'] );
			}
			if( isset( $widget_params['date_format'] ) )
			{	// Remove setting "Date format" completely from the widget:
				unset( $widget_params['date_format'] );
			}
			if( isset( $widget_params['time_format'] ) )
			{	// Remove setting "Time format" completely from the widget:
				unset( $widget_params['time_format'] );
			}
			if( isset( $widget_params['category'] ) )
			{	// Remove setting "Display item/post category" completely from the widget:
				unset( $widget_params['category'] );
			}
			if( isset( $widget_params['edit_link'] ) )
			{	// Remove setting "Display link to edit the item/post" completely from the widget:
				unset( $widget_params['edit_link'] );
			}
			if( isset( $widget_params['post_time'] ) )
			{	// Remove setting previous setting "post_time" completely from the widget:
				unset( $widget_params['post_time'] );
			}

			$DB->query( 'UPDATE T_widget__widget
				  SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
				WHERE wi_ID = '.$row->wi_ID );
		}

		upg_task_end();
	}

	if( upg_task_start( 15790, 'Upgrading menu entries table...') )
	{	// part of 7.1.2-beta
		db_add_col( 'T_menus__entry', 'ment_item_slug', 'VARCHAR(255) COLLATE ascii_general_ci NULL AFTER ment_item_ID' );
		upg_task_end();
	}

	if( upg_task_start( 15800, 'Upgrading item types table...') )
	{	// part of 7.1.2-beta
		db_upgrade_cols( 'T_items__type', array(
			'ADD' => array(
				'ityp_template_excerpt' => 'VARCHAR(128) COLLATE ascii_general_ci NULL DEFAULT NULL AFTER ityp_usage',
				'ityp_template_normal'  => 'VARCHAR(128) COLLATE ascii_general_ci NULL DEFAULT NULL AFTER ityp_template_excerpt',
				'ityp_template_full'    => 'VARCHAR(128) COLLATE ascii_general_ci NULL DEFAULT NULL AFTER ityp_template_normal',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15810 ) )
	{	// part of 7.1.2-beta
		global $plugins_path;
		$admin_Plugins = & get_Plugins_admin();

		$plugins_to_remove = array(
				'adsense_plugin',
				'cookie_consent_plugin',
				'flowplayer_plugin',
				'google_maps_plugin',
				'watermark_plugin',
				'facebook_plugin',
				'proof_of_work_captcha_plugin',
				'smilies_plugin',
				'twitter_tweet_renderer_plugin'
			);
		foreach( $plugins_to_remove as $plugin_class )
		{
			if( $loop_Plugin = & $admin_Plugins->get_by_classname( $plugin_class ) )
			{
				echo get_install_format_text_and_log( sprintf( '<span class="text-warning"><evo:warning>'
						.'The plugin %s is no longer updated by b2evolution v7. '
						.'You may obtain new versions from the <a href="%s" target="_blank">plugin repository</a>.'
						.'</evo:warning></span>',
						'<code>'.$loop_Plugin->classname.'</code>', $loop_Plugin->get_help_url() )."<br />\n", 'br' );
			}
			else
			{
				$plugin_deleted = true;
				task_begin( sprintf( 'Trying to delete obsolete and unused plugin: %s...', $plugin_class ) );
				$plugin_dir = $plugins_path.$plugin_class;
				$plugin_filename = $plugins_path.'_'.preg_replace( '/_plugin$/', '.plugin.php', $plugin_class );
				if( file_exists( $plugin_dir ) && is_dir( $plugin_dir ) )
				{
					if( is_writable( $plugin_dir) )
					{
						rmdir_r( $plugin_dir );
					}
					else
					{
						$plugin_deleted = false;
						echo get_install_format_text_and_log( sprintf( '<span class="text-danger"><evo:error>Unable to delete directory: %s</evo:error></span>', $plugin_dir )."<br />\n", 'br' );
					}
				}
				if( file_exists( $plugin_filename ) && is_file( $plugin_filename ) )
				{
					if( is_writable( $plugin_filename) )
					{
						unlink( $plugin_filename );
					}
					else
					{
						$plugin_deleted = false;
						echo get_install_format_text_and_log( sprintf( '<span class="text-danger"><evo:error>Unable to delete file: %s</evo:error></span>', $plugin_filename )."<br />\n", 'br' );
					}
				}
				if( $plugin_deleted )
				{
					task_end();
				}
			}
		}
		upg_task_end( false );
	}

	if( upg_task_start( 15820, 'Upgrading users table...') )
	{	// part of 7.1.2-beta
		db_add_col( 'T_users', 'user_birthday_year', 'smallint unsigned NULL AFTER user_age_max' );
		db_add_col( 'T_users', 'user_birthday_month', 'tinyint unsigned NULL AFTER user_birthday_year' );
		db_add_col( 'T_users', 'user_birthday_day', 'tinyint unsigned NULL AFTER user_birthday_month' );

		// Set self_selected_age_group setting to 'optional':
		$DB->query( 'INSERT INTO T_settings ( set_name, set_value ) VALUES ( "self_selected_age_group", "optional" )
				ON DUPLICATE KEY UPDATE set_value = VALUES( set_value )' );

		upg_task_end();
	}

	if( upg_task_start( 15830, 'Updating widget "Free Social Links"...' ) )
	{	// part of 7.1.2-beta
		// Make to use ufdf_code(user field code) instead of ufdf_ID(user field ID) in widget settings:
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_params' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->WHERE( 'wi_code = "social_links"' );
		$widgets = $DB->get_assoc( $SQL );

		if( ! empty( $widgets ) )
		{	// If at least one widget "Free Social Links" exists in DB:
			$SQL = new SQL();
			$SQL->SELECT( 'ufdf_ID, ufdf_code' );
			$SQL->FROM( 'T_users__fielddefs' );
			$SQL->WHERE( 'ufdf_type = "url"' );
			$SQL->WHERE_and( 'ufdf_icon_name IS NOT NULL' );
			$social_fields = $DB->get_assoc( $SQL );

			foreach( $widgets as $widget_ID => $widget_params )
			{
				if( empty( $widget_params ) )
				{	// Skip widget with default settings:
					continue;
				}

				$widget_params = unserialize( $widget_params );

				for( $i = 1; $i <= 7; $i++ )
				{
					if( isset( $widget_params['link'.$i] ) )
					{
						if( isset( $social_fields[ $widget_params['link'.$i] ] ) )
						{	// Replace old using of ufdf_ID to new using ufdf_code if we find such user field in DB by ID:
							$widget_params['link'.$i] = $social_fields[ $widget_params['link'.$i] ];
						}
						else
						{	// Reset wrong user field to default:
							$widget_params['link'.$i] = '';
						}
					}
				}

				$DB->query( 'UPDATE T_widget__widget
						SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
					WHERE wi_ID = '.$widget_ID );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15840, 'Upgrading automation steps table...' ) )
	{	// part of 7.1.2-beta
		db_upgrade_cols( 'T_automation__step', array(
			'MODIFY' => array(
				'step_yes_next_step_ID'   => 'INT NULL COMMENT "Must be unsigned for special values like -1 = STOP"',
				'step_no_next_step_ID'    => 'INT NULL COMMENT "Must be unsigned for special values like -1 = STOP"',
				'step_error_next_step_ID' => 'INT NULL COMMENT "Must be unsigned for special values like -1 = STOP"',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15850, 'Updating Item Type "Recipe"...' ) )
	{	// part of 7.1.2-beta
		$DB->query( 'UPDATE T_items__type
			  SET ityp_template_full = "recipe_content_full",
			      ityp_template_name = NULL
			WHERE ityp_template_name = "recipe"' );
		upg_task_end();
	}

	if( upg_task_start( 15860, 'Upgrading templates table...' ) )
	{	// part of 7.1.2-beta
		db_upgrade_cols( 'T_templates', array(
			'CHANGE' => array(
				'tpl_parent_tpl_ID' => 'tpl_translates_tpl_ID INT(10) UNSIGNED NULL DEFAULT NULL',
			),
		) );
	}

	if( upg_task_start( 15870, 'Upgrading menus table...' ) )
	{	// part of 7.1.2-beta
		db_upgrade_cols( 'T_menus__menu', array(
			'CHANGE' => array(
				'menu_parent_ID' => 'menu_translates_menu_ID INT(10) UNSIGNED NULL DEFAULT NULL',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15880, 'Upgrading templates table...' ) )
	{	// part of 7.1.2-beta
		db_add_col( 'T_templates', 'tpl_context', 'ENUM( "custom", "custom1", "custom2", "custom3", "content_list_master", "content_list_item",	"content_list_category", "content_block", "item_details", "item_content", "registration" ) COLLATE ascii_general_ci NOT NULL DEFAULT "custom" AFTER tpl_template_code' );
		upg_task_end();
	}

	if( upg_task_start( 15890, 'Upgrading templates table...' ) )
	{	// part of 7.1.2-beta
		db_add_col( 'T_templates', 'tpl_owner_grp_ID', 'INT(4) NULL DEFAULT NULL AFTER tpl_context' );
		upg_task_end();
	}

	if( upg_task_start( 15900, 'Updating widgets "Sub-Container" and "Columns (Sub-Containers)"...' ) )
	{	// part of 7.1.2-beta
		// Allow to use shared containers in collection containers:
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_code, wico_coll_ID, wi_params' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->FROM_add( 'INNER JOIN T_widget__container ON wico_ID = wi_wico_ID' );
		$SQL->WHERE( 'wi_code IN ( "subcontainer", "subcontainer_row" )' );
		$widgets = $DB->get_results( $SQL );

		if( ! empty( $widgets ) )
		{	// If at least one widget exists in DB:
			foreach( $widgets as $widget )
			{
				if( empty( $widget->wi_params ) )
				{	// Skip widget with default settings:
					continue;
				}

				$widget_params = unserialize( $widget->wi_params );

				// Set prefix for collection or shared container:
				$prefix = ( $widget->wico_coll_ID ? 'coll:' : 'shared:' );

				switch( $widget->wi_code )
				{
					case 'subcontainer':
						// Sub-Container
						if( ! empty( $widget_params['container'] ) &&
						    strpos( $widget_params['container'], $prefix ) !== 0 ) // Don't add double prefix
						{
							$widget_params['container'] = $prefix.$widget_params['container'];
						}
						break;
					case 'subcontainer_row':
						// Columns (Sub-Containers)
						for( $i = 1; $i <= 6; $i++ )
						{
							if( ! empty( $widget_params['column'.$i.'_container'] ) &&
							    strpos( $widget_params['column'.$i.'_container'], $prefix ) !== 0 ) // Don't add double prefix
							{
								$widget_params['column'.$i.'_container'] = $prefix.$widget_params['column'.$i.'_container'];
							}
						}
						break;
				}

				$DB->query( 'UPDATE T_widget__widget
						SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
					WHERE wi_ID = '.$widget->wi_ID );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15910, 'Updating templates table...' ) )
	{	// part of 7.1.2-beta

		$DB->query( 'UPDATE T_templates SET tpl_context = "custom1" WHERE tpl_context = "custom"' );

		db_upgrade_cols( 'T_templates', array(
			'MODIFY' => array(
				'tpl_context' => 'ENUM( "custom1", "custom2", "custom3", "content_list_master", "content_list_item", "content_list_category", "content_block", "item_details", "item_content", "registration" ) COLLATE ascii_general_ci NOT NULL DEFAULT "custom1"',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15920, 'Updating templates table...' ) )
	{	// part of 7.1.2-beta

		db_upgrade_cols( 'T_templates', array(
			'MODIFY' => array(
				'tpl_context' => 'ENUM( "custom1", "custom2", "custom3", "content_list_master", "content_list_item", "content_list_category", "content_block", "item_details", "item_content", "registration_master", "registration" ) COLLATE ascii_general_ci NOT NULL DEFAULT "custom1"',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15930, 'Upgrading user field definitions table...' ) )
	{	// part of 7.1.2-beta
		db_add_col( 'T_users__fielddefs', 'ufdf_visibility', 'enum("unrestricted","private","admin") COLLATE ascii_general_ci NOT NULL default "unrestricted" AFTER ufdf_required' );
		upg_task_end();
	}

	if( upg_task_start( 15940, 'Upgrading user field definitions table...' ) )
	{	// part of 7.1.2-beta
		db_add_col( 'T_users__fielddefs', 'ufdf_grp_ID', 'int(10) UNSIGNED NULL' );
		upg_task_end();
	}

	if( upg_task_start( 15950, 'Updating templates table...' ) )
	{	// part of 7.1.2-beta

		db_upgrade_cols( 'T_templates', array(
			'MODIFY' => array(
				'tpl_context' => 'ENUM( "custom1", "custom2", "custom3", "content_list_master", "content_list_item", "content_list_category", "content_block", "item_details", "item_content", "registration_master", "registration", "search_form" ) COLLATE ascii_general_ci NOT NULL DEFAULT "custom1"',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15960, 'Installing widget container "Search Area" and updating "Search Form" widget...' ) )
	{	// part of 7.1.2-beta
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_params, wico_name' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->WHERE( 'wi_code = "coll_search_form"' );
		$SQL->FROM_add( 'LEFT JOIN T_widget__container ON wi_wico_ID = wico_ID' );
		$widgets = $DB->get_results( $SQL );

		if( ! empty( $widgets ) )
		{	// If at least one widget exists in DB:
			foreach( $widgets as $widget )
			{
				$widget_params = unserialize( $widget->wi_params );

				if( $widget->wico_name == 'Sidebar' || $widget->wico_name == 'Sidebar 2' )
				{
					$widget_params['template'] = 'search_form_sidebar';
				}
				else
				{
					$widget_params['template'] = 'search_form_full';
				}

				$DB->query( 'UPDATE T_widget__widget
						SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
					WHERE wi_ID = '.$widget->wi_ID );
			}
		}

		// Install widget "Collection Search Form":
		install_new_default_widgets( 'search_area' );
		
		upg_task_end();
	}

	if( upg_task_start( 15970, 'Updating "Search Form" widget...' ) )
	{	// part of 7.1.2-beta
		$SQL = new SQL();
		$SQL->SELECT( 'wi_ID, wi_params' );
		$SQL->FROM( 'T_widget__widget' );
		$SQL->WHERE( 'wi_code = "coll_search_form"' );
		$widgets = $DB->get_results( $SQL );

		if( ! empty( $widgets ) )
		{	// If at least one widget exists in DB:
			foreach( $widgets as $widget )
			{
				$widget_params = unserialize( $widget->wi_params );

				if( in_array( $widget_params['template'], array( 'search_form_sidebar', 'search_form_header' ) ) )
				{	// Merge previous search forms to new search_form_simple:
					$widget_params['template'] = 'search_form_simple';
				

					$DB->query( 'UPDATE T_widget__widget
							SET wi_params = '.$DB->quote( serialize( $widget_params ) ).'
						WHERE wi_ID = '.$widget->wi_ID );
				}
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 15980, 'Upgrading templates table...' ) )
	{	// part of 7.1.2-beta
		db_upgrade_cols( 'T_templates', array(
			'MODIFY' => array(
				'tpl_context' => 'ENUM( "custom1", "custom2", "custom3", "content_list_master", "content_list_item", "content_list_category", "content_block", "item_details", "item_content", "registration_master", "registration", "search_form", "search_result" ) COLLATE ascii_general_ci NOT NULL DEFAULT "custom1"',
			),
		) );
		upg_task_end();
	}

	if( upg_task_start( 15990, 'Removing obsolete skins...<br>' ) )
	{	// part of 7.1.3-beta
		global $skins_path;

		$obsolete_skin_classes = array( 'asevo_Skin', 'basic_Skin', 'dating_mood_Skin', 'evopress_Skin', 'photoalbums_Skin', 'photoblog_Skin', 'touch_Skin' );

		load_funcs( 'skins/_skin.funcs.php' );
		$SkinCache = & get_SkinCache();

		// Get list of available skins in skins folder:
		$skin_folders = get_filenames( $skins_path, array(
				'inc_files' => false,
				'inc_dirs'  => true,
				'recurse'   => false,
				'basename'  => true )
			);
		$r = array();
		foreach( $skin_folders as $folder )
		{
			list( $base_skin, $skin_version ) = get_skin_folder_base_version( $folder );
			$skin_class_name = preg_replace( '/_skin$/i', '', $base_skin ).'_Skin';
			$r[$skin_class_name][$folder] = false;
		}

		foreach( $obsolete_skin_classes as $skin_class )
		{
			if( $obsolete_Skin = $SkinCache->get_by_class( $skin_class, false, false ) )
			{	// Installed skin, display a warning:
				echo get_install_format_text_and_log( sprintf( '<span class="text-warning"><evo:warning>'
						.'The skin %s is no longer updated by b2evolution v7. You may obtain new versions from the <a href="%s" target="_blank">skin repository</a>'
						.'</evo:warning></span>',
						'<code>'.$obsolete_Skin->get_default_name().'</code>', 'https://skins.b2evolution.net/' )."<br />\n", 'br' );
				if( isset( $r[$skin_class][$obsolete_Skin->folder] ) )
				{	// Indicate this skin - version is installed:
					$r[$skin_class][$obsolete_Skin->folder] = true;
				}
				// We can loop through the $r[$skin_class] here if we want to remove unused versions of an installed obsolete skin.
			}
			else
			{	// Not installed, delete the folders:
				task_begin( sprintf( 'Trying to delete obsolete and unused skin: %s...', $skin_class ) );
				$folders_deleted = true;
				if( isset( $r[$skin_class] ) )
				{	// Obsolete skin found in the skins folder:
					foreach( $r[$skin_class] as $folder => $installed )
					{	// Iterate through all available versions:
						if( ! rmdir_r( $skins_path.$folder ) )
						{
							$folders_deleted = false;
							echo get_install_format_text_and_log( sprintf( '<span class="text-danger"><evo:error>Unable to delete folder %s.</evo:error></span>', $skins_path.$folder ) );
						}
					}
				}
				task_end( $folders_deleted ? 'OK.' : '' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 16000, 'Upgrading skins table...' ) )
	{	// part of 7.1.3-beta
		db_modify_col( 'T_skins__skin', 'skin_name', 'varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 16010, 'Upgrading blogs, skins, widgets tables for new skin type "Alt"...' ) )
	{	// part of 7.1.3-beta
		db_add_col( 'T_blogs', 'blog_alt_skin_ID', 'int(10) unsigned NULL' );
		db_modify_col( 'T_skins__skin', 'skin_type', 'enum("normal","feed","sitemap","mobile","tablet","alt","rwd") COLLATE ascii_general_ci NOT NULL default "normal"' );
		db_modify_col( 'T_widget__container', 'wico_skin_type', 'ENUM( "normal", "mobile", "tablet", "alt" ) COLLATE ascii_general_ci NOT NULL DEFAULT "normal"' );
		upg_task_end();
	}

	if( upg_task_start( 16012, 'Updating site skins...' ) )
	{	// part of 7.1.5-stable
		$SQL = new SQL( 'Get site skins for update "Grouping" setting' );
		$SQL->SELECT( 'skin_id.set_value AS skin_ID, set_grouping.set_value AS setting_grouping, set_menu_type.set_value AS setting_menu_type' );
		$SQL->FROM( 'T_settings AS skin_id' );
		$SQL->FROM_add( 'INNER JOIN T_skins__skin ON skin_ID = skin_id.set_value' );
		$SQL->FROM_add( 'LEFT JOIN T_settings AS set_grouping ON set_grouping.set_name = CONCAT( "skin", skin_ID, "_grouping" )' );
		$SQL->FROM_add( 'LEFT JOIN T_settings AS set_menu_type ON set_menu_type.set_name = CONCAT( "skin", skin_ID, "_menu_type" )' );
		$SQL->WHERE( 'skin_id.set_name LIKE "%_skin_ID"' );
		$SQL->WHERE_and( 'skin_class IN( "bootstrap_site_dropdown_Skin", "bootstrap_site_navbar_Skin", "bootstrap_site_tabs_Skin" )' );
		$site_skins = $DB->get_results( $SQL );
		foreach( $site_skins as $site_skin )
		{
			if( $site_skin->setting_grouping !== NULL )
			{	// Remove old setting "Grouping":
				$DB->query( 'DELETE FROM T_settings
					WHERE set_name = '.$DB->quote( 'skin'.$site_skin->skin_ID.'_grouping' ) );
			}

			if( $site_skin->setting_menu_type !== NULL )
			{	// Don't update if "Menu type" was saved in DB:
				continue;
			}

			if( $site_skin->setting_grouping === NUll || $site_skin->setting_grouping == 1 )
			{	// Set value in DB only for option "Automatic - Grouped collection list",
				// because "Automatic - Collection list" is used by default:
				$DB->query( 'INSERT INTO T_settings ( set_name, set_value )
					VALUES ( '.$DB->quote( 'skin'.$site_skin->skin_ID.'_menu_type' ).', "auto_grouped" )' );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 16013, 'Upgrading columns to utf8mb4_bin...' ) )
	{	// part of 7.1.5-stable
		// Remove keyphrases with length > 250 chars before reducing column size in order to avoid duplicate entry errors:
		$DB->query( 'DELETE FROM T_track__keyphrase
			WHERE LENGTH( keyp_phrase ) > 250' );
		$DB->query( 'UPDATE T_hitlog
			  SET hit_keyphrase = NULL
			WHERE LENGTH( hit_keyphrase ) > 250' );
		// Drop unique key before changing column to utf8mb4(4bytes) from utf8(3bytes),
		// because max size for unique key is 1000 bytes(4bytes * 250chars):
		db_drop_index( 'T_track__keyphrase', 'keyp_phrase' );
		db_modify_col( 'T_track__keyphrase', 'keyp_phrase', 'VARCHAR( 250 ) COLLATE utf8mb4_bin NOT NULL' );
		db_add_index( 'T_track__keyphrase', 'keyp_phrase', 'keyp_phrase', 'UNIQUE' );
		db_modify_col( 'T_hitlog', 'hit_keyphrase', 'VARCHAR(250) COLLATE utf8mb4_bin DEFAULT NULL' );
		// Modify these columns in order to avoid errors when 4bytes char is in search string:
		db_modify_col( 'T_items__tag', 'tag_name', 'VARCHAR(50) COLLATE utf8mb4_bin NOT NULL' );
		db_modify_col( 'T_files', 'file_path', 'varchar(767) COLLATE utf8mb4_bin not null default ""' );
		upg_task_end();
	}

	if( upg_task_start( 16083, 'Upgrading table for Menu entries and Converting menu widgets "Messaging", "Flagged Items" and "My Profile" into "Basic Menu link" widget...' ) )
	{	// part of 7.2
		db_upgrade_cols( 'T_menus__entry', array(
			'ADD' => array(
				'ment_user_pic_size' => 'VARCHAR(32) COLLATE ascii_general_ci NULL AFTER ment_order',
				'ment_access'        => 'ENUM( "any", "loggedin", "perms" ) COLLATE ascii_general_ci NOT NULL DEFAULT "perms" AFTER ment_visibility',
				'ment_show_badge'    => 'TINYINT(1) NOT NULL DEFAULT 1 AFTER ment_access',
				'ment_hide_empty'    => 'TINYINT(1) NOT NULL DEFAULT 0',
			),
		) );
		// Convert menu widgets "Messaging", "Flagged Items" and "My Profile" into "Basic Menu link" widget:
		// (update to proper param 'link_type' because these widgets had no this param before)
		$menu_widgets_SQL = new SQL( 'Get menu widgets before converting' );
		$menu_widgets_SQL->SELECT( 'wi_ID, wi_code, wi_params' );
		$menu_widgets_SQL->FROM( 'T_widget__widget' );
		$menu_widgets_SQL->WHERE( 'wi_code IN ( "msg_menu_link", "flag_menu_link", "profile_menu_link" )' );
		$menu_widgets = $DB->get_results( $menu_widgets_SQL );
		foreach( $menu_widgets as $menu_widget )
		{
			$menu_widget_params = empty( $menu_widget->wi_params ) ? array() : unserialize( $menu_widget->wi_params );
			if( $menu_widget->wi_code == 'msg_menu_link' )
			{
				if( ! isset( $menu_widget_params['link_type'] ) )
				{	// Link type may be not set yet:
					$menu_widget_params['link_type'] = 'messages';
				}
			}
			elseif( $menu_widget->wi_code == 'flag_menu_link' )
			{
				$menu_widget_params['link_type'] = 'flagged';
			}
			else
			{
				$menu_widget_params['link_type'] = 'myprofile';
				if( empty( $menu_widget_params['profile_picture_size'] ) )
				{	// Sset default picture profile size if it was not set yet:
					$menu_widget_params['profile_picture_size'] = 'crop-top-15x15';
				}
			}
			$DB->query( 'UPDATE T_widget__widget
				  SET wi_code = "basic_menu_link",
				      wi_params = '.$DB->quote( serialize( $menu_widget_params ) ).'
				WHERE wi_ID = '.$menu_widget->wi_ID );
		}
		upg_task_end();
	}

	if( upg_task_start( 16084, 'Upgrading items type table...' ) )
	{	// part of 7.2
		db_add_col( 'T_items__type', 'ityp_front_order_workflow', 'SMALLINT(6) NULL DEFAULT NULL AFTER ityp_front_order_attachments' );
		upg_task_end();
	}

	if( upg_task_start( 16085, 'Creating default item type "Task"...' ) )
	{	// part of 7.2
		$SQL = new SQL( 'Check at least one item type with name "Task" for existence' );
		$SQL->SELECT( 'ityp_ID' );
		$SQL->FROM( 'T_items__type' );
		$SQL->WHERE( 'ityp_name = "Task"' );
		$SQL->LIMIT( 1 );
		if( ! $DB->get_var( $SQL ) )
		{	// Create one default item type "Task":
			$r = $DB->query( 'INSERT INTO T_items__type ( ityp_name, ityp_usage, ityp_template_name, ityp_allow_html, ityp_front_order_title, ityp_front_order_attachments, ityp_front_order_workflow, ityp_front_order_text, ityp_front_order_location )
					VALUES ( "Task", "post", "single", 0, 10, 30, 20, 80, 90 )' );
			if( $r && $DB->insert_id > 0 )
			{	// Enable new created item type all forum and tracker:
				$DB->query( 'INSERT INTO T_items__type_coll ( itc_ityp_ID, itc_coll_ID )
					SELECT '.$DB->insert_id.', blog_ID
					  FROM T_blogs
					 WHERE blog_type IN ( "forum", "group" )' );
			}
		}
		upg_task_end();
	}
	
	if( upg_task_start( 16086, 'Upgrading item status table...' ) )
	{	// part of 7.2
		db_add_col( 'T_items__status', 'pst_order', 'INT(11) NULL DEFAULT NULL' );
		upg_task_end();
	}

	if( upg_task_start( 16087, 'Upgrading item status table...' ) )
	{	// part of 7.2
		$DB->query( 'UPDATE T_items__status SET pst_order = 10 WHERE pst_name = "New"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 20 WHERE pst_name = "In Progress"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 30 WHERE pst_name = "Duplicate"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 40 WHERE pst_name = "Not A Bug"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 50 WHERE pst_name = "In Review"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 60 WHERE pst_name = "Fixed"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 70 WHERE pst_name = "Closed"' );
		$DB->query( 'UPDATE T_items__status SET pst_order = 80 WHERE pst_name = "OK"' );
		upg_task_end();
	}

	if( upg_task_start( 16088, 'Converting widget "Common Navigation Links" into "Embed Menu" widget...' ) )
	{	// part of 7.2
		$nav_widgets_SQL = new SQL( 'Get widgets "Common Navigation Links" before converting' );
		$nav_widgets_SQL->SELECT( 'wi_ID, wi_params' );
		$nav_widgets_SQL->FROM( 'T_widget__widget' );
		$nav_widgets_SQL->WHERE( 'wi_code = "coll_common_links"' );
		$nav_widgets = $DB->get_assoc( $nav_widgets_SQL );
		if( ! empty( $nav_widgets ) )
		{	// If at least one widget "Common Navigation Links" is found:
			load_class( 'menus/model/_sitemenu.class.php', 'SiteMenu' );
			load_class( 'menus/model/_sitemenuentry.class.php', 'SiteMenuEntry' );
			// widget_param_key => array( menu_entry_type, menu_entry_text ):
			$nav_menu_entries = array(
				'show_home'           => array( 'home', T_('Home') ),
				'show_recently'       => array( 'recentposts', T_('Recently') ),
				'show_search'         => array( 'search', T_('Search') ),
				'show_postidx'        => array( 'postidx', T_('Post index') ),
				'show_archives'       => array( 'arcdir', T_('Archives') ),
				'show_categories'     => array( 'catdir', T_('Categories') ),
				'show_mediaidx'       => array( 'mediaidx', T_('Photo index') ),
				'show_latestcomments' => array( 'latestcomments', T_('Latest comments') ),
				'show_owneruserinfo'  => array( 'owneruserinfo', T_('Owner details') ),
				'show_ownercontact'   => array( 'ownercontact', T_('Contact') ),
				'show_sitemap'        => array( 'sitemap', T_('Site map') ),
			);
			foreach( $nav_widgets as $nav_widget_ID => $nav_widget_params )
			{
				$nav_widget_params = empty( $nav_widget_params ) ? array() : unserialize( $nav_widget_params );

				if( empty( $nav_widget_params ) )
				{	// Set default params:
					$nav_widget_params = array(
						'show_home' => 1,
						'show_recently' => 1,
						'show_archives' => 1,
						'show_categories' => 1,
						'show_latestcomments' => 1,
					);
				}

				// Create Menu for converting Widget:
				$nav_SiteMenu = new SiteMenu();
				$nav_SiteMenu->set( 'name', 'Common Navigation Links #'.$nav_widget_ID );
				$nav_SiteMenu->dbinsert();
				$menu_entry_order = 10;
				foreach( $nav_menu_entries as $nav_widget_param => $nav_menu_entry_data )
				{
					if( empty( $nav_widget_params[ $nav_widget_param ] ) )
					{	// Skip not enabled menu entry in old widget:
						continue;
					}
					// Create only enabled menu entries:
					$nav_SiteMenuEntry = new SiteMenuEntry();
					$nav_SiteMenuEntry->set( 'menu_ID', $nav_SiteMenu->ID );
					$nav_SiteMenuEntry->set( 'type', $nav_menu_entry_data[0] );
					$nav_SiteMenuEntry->set( 'text', $nav_menu_entry_data[1] );
					$nav_SiteMenuEntry->set( 'order', $menu_entry_order );
					$nav_SiteMenuEntry->dbinsert();
					$menu_entry_order += 10;

					// Remove old widget param:
					unset( $nav_widget_params[ $nav_widget_param ] );
				}

				// Use new created Menu to converting widget:
				$nav_widget_params['menu_ID'] = $nav_SiteMenu->ID;
				// Old widget used only list mode:
				$nav_widget_params['display_mode'] = 'list';

				// Update widget to new params:
				$DB->query( 'UPDATE T_widget__widget
					  SET wi_code = "embed_menu",
					      wi_params = '.$DB->quote( serialize( $nav_widget_params ) ).'
					WHERE wi_ID = '.$nav_widget_ID );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 16089, 'Converting widget "User Tools" into "Embed Menu" widget...' ) )
	{	// part of 7.2
		$nav_widgets_SQL = new SQL( 'Get widgets "User Tools" before converting' );
		$nav_widgets_SQL->SELECT( 'wi_ID, wi_params' );
		$nav_widgets_SQL->FROM( 'T_widget__widget' );
		$nav_widgets_SQL->WHERE( 'wi_code = "user_tools"' );
		$nav_widgets = $DB->get_assoc( $nav_widgets_SQL );
		if( ! empty( $nav_widgets ) )
		{	// If at least one widget "User Tools" is found:
			load_class( 'menus/model/_sitemenu.class.php', 'SiteMenu' );
			load_class( 'menus/model/_sitemenuentry.class.php', 'SiteMenuEntry' );
			// widget_param_key => array( menu_entry_type, widget_param_for_text, {widget_param_for_show_badge} ):
			$nav_menu_entries = array(
				'user_postnew_link_show'     => array( 'postnew', 'user_postnew_link' ),
				'user_messaging_link_show'   => array( 'messages', 'user_messaging_link', 'show_badge' ),
				'user_contacts_link_show'    => array( 'contacts', 'user_contacts_link' ),
				'user_view_link_show'        => array( 'myprofile', 'user_view_link' ),
				'user_profile_link_show'     => array( 'profile', 'user_profile_link' ),
				'user_picture_link_show'     => array( 'avatar', 'user_picture_link' ),
				'user_password_link_show'    => array( 'password', 'user_password_link' ),
				'user_preferences_link_show' => array( 'userprefs', 'user_preferences_link' ),
				'user_subs_link_show'        => array( 'usersubs', 'user_subs_link' ),
				'user_admin_link_show'       => array( 'admin', 'user_admin_link' ),
				'user_logout_link_show'      => array( 'logout', 'user_logout_link' ),
			);
			foreach( $nav_widgets as $nav_widget_ID => $nav_widget_params )
			{
				$nav_widget_params = empty( $nav_widget_params ) ? array() : unserialize( $nav_widget_params );

				if( empty( $nav_widget_params ) )
				{	// Set default params:
					$nav_widget_params = array(
						'title'                      => T_('User tools'),
						'user_postnew_link_show'     => 1,
						'user_postnew_link'          => T_('Write a new post...'),
						'user_messaging_link_show'   => 1,
						'show_badge'                 => 1,
						'user_messaging_link'        => T_('My messages'),
						'user_contacts_link_show'    => 1,
						'user_contacts_link'         => T_('My contacts'),
						'user_view_link_show'        => 1,
						'user_view_link'             => T_('My profile'),
						'user_profile_link_show'     => 1,
						'user_profile_link'          => T_('Edit my profile'),
						'user_picture_link_show'     => 1,
						'user_picture_link'          => T_('Change my picture'),
						'user_admin_link_show'       => 1,
						'user_admin_link'            => T_('Admin area'),
						'user_logout_link_show'      => 1,
						'user_logout_link'           => T_('Log out'),
					);
				}

				// Create Menu for converting Widget:
				$nav_SiteMenu = new SiteMenu();
				$nav_SiteMenu->set( 'name', 'User Tools #'.$nav_widget_ID );
				$nav_SiteMenu->dbinsert();
				$menu_entry_order = 10;
				foreach( $nav_menu_entries as $nav_widget_param => $nav_menu_entry_data )
				{
					if( empty( $nav_widget_params[ $nav_widget_param ] ) )
					{	// Skip not enabled menu entry in old widget:
						continue;
					}
					// Create only enabled menu entries:
					$nav_SiteMenuEntry = new SiteMenuEntry();
					$nav_SiteMenuEntry->set( 'menu_ID', $nav_SiteMenu->ID );
					$nav_SiteMenuEntry->set( 'type', $nav_menu_entry_data[0] );
					if( isset( $nav_widget_params[ $nav_menu_entry_data[1] ] ) )
					{	// Set text for menu entry:
						$nav_SiteMenuEntry->set( 'text', $nav_widget_params[ $nav_menu_entry_data[1] ] );
						// Remove old widget param:
						unset( $nav_widget_params[ $nav_menu_entry_data[1] ] );
					}
					if( isset( $nav_menu_entry_data[2], $nav_widget_params[ $nav_menu_entry_data[2] ] ) )
					{	// Set "Show Badge" for menu entry:
						$nav_SiteMenuEntry->set( 'show_badge', $nav_widget_params[ $nav_menu_entry_data[2] ] );
						// Remove old widget param:
						unset( $nav_widget_params[ $nav_menu_entry_data[2] ] );
					}
					$nav_SiteMenuEntry->set( 'order', $menu_entry_order );
					$nav_SiteMenuEntry->dbinsert();
					$menu_entry_order += 10;

					// Remove old widget param:
					unset( $nav_widget_params[ $nav_widget_param ] );
				}

				// Use new created Menu to converting widget:
				$nav_widget_params['menu_ID'] = $nav_SiteMenu->ID;
				// Old widget used only list mode:
				$nav_widget_params['display_mode'] = 'list';

				// Update widget to new params:
				$DB->query( 'UPDATE T_widget__widget
					  SET wi_code = "embed_menu",
					      wi_params = '.$DB->quote( serialize( $nav_widget_params ) ).'
					WHERE wi_ID = '.$nav_widget_ID );
			}
		}
		upg_task_end();
	}

	if( upg_task_start( 16090, 'Installing new widget container "Site Map"...' ) )
	{	// part of 7.2
		install_new_default_widgets( 'sitemap' );
		upg_task_end();
	}

	if( upg_task_start( 16102, 'Upgrading columns to utf8mb4_bin...' ) )
	{	// part of 7.2
		// NOTE: This is a duplicate block of 16014 because auto-upgrade tool cannot detect differences in COLLATE:
		// Remove keyphrases with length > 250 chars before reducing column size in order to avoid duplicate entry errors:
		$DB->query( 'DELETE FROM T_track__keyphrase
			WHERE LENGTH( keyp_phrase ) > 250' );
		$DB->query( 'UPDATE T_hitlog
			  SET hit_keyphrase = NULL
			WHERE LENGTH( hit_keyphrase ) > 250' );
		// Drop unique key before changing column to utf8mb4(4bytes) from utf8(3bytes),
		// because max size for unique key is 1000 bytes(4bytes * 250chars):
		db_drop_index( 'T_track__keyphrase', 'keyp_phrase' );
		// Remove all duplicated key phrases which may were inserted by miskate when INDEX KEY for keyp_phrase was not UNIQUE:
		$dupl_keyphrases_SQL = new SQL( 'Find all duplicated key phrases' );
		$dupl_keyphrases_SQL->SELECT( 'keyp_phrase, GROUP_CONCAT( keyp_ID ) AS IDs,
			SUM( keyp_count_refered_searches ) AS sum_keyp_count_refered_searches,
			SUM( keyp_count_internal_searches ) AS sum_keyp_count_internal_searches' );
		$dupl_keyphrases_SQL->FROM( 'T_track__keyphrase' );
		$dupl_keyphrases_SQL->GROUP_BY( 'keyp_phrase' );
		$dupl_keyphrases_SQL->HAVING( 'COUNT( keyp_phrase ) > 1' );
		$dupl_keyphrases = $DB->get_results( $dupl_keyphrases_SQL );
		foreach( $dupl_keyphrases as $dupl_keyphrase )
		{
			// Find first/min record because only this is correct and only this can be kept in DB:
			// (All next duplicates must be removed from DB)
			$first_keyp_ID = min( explode( ',', $dupl_keyphrase->IDs ) );
			// Fix counters by moving all what counted in duplicated records by mistake:
			$DB->query( 'UPDATE T_track__keyphrase
				  SET keyp_count_refered_searches = '.$dupl_keyphrase->sum_keyp_count_refered_searches.',
				      keyp_count_internal_searches = '.$dupl_keyphrase->sum_keyp_count_internal_searches.'
				WHERE keyp_ID = '.$first_keyp_ID );
			// Delete all duplicated/wrong records except of only first/correct:
			$DB->query( 'DELETE FROM T_track__keyphrase
				WHERE keyp_ID IN ( '.$dupl_keyphrase->IDs.' )
				  AND keyp_ID != '.$first_keyp_ID );
		}
		// Upgrade key phrase columns:
		db_modify_col( 'T_track__keyphrase', 'keyp_phrase', 'VARCHAR( 250 ) COLLATE utf8mb4_bin NOT NULL' );
		db_add_index( 'T_track__keyphrase', 'keyp_phrase', 'keyp_phrase', 'UNIQUE' );
		db_modify_col( 'T_hitlog', 'hit_keyphrase', 'VARCHAR(250) COLLATE utf8mb4_bin DEFAULT NULL' );
		// Modify these columns in order to avoid errors when 4bytes char is in search string:
		db_modify_col( 'T_items__tag', 'tag_name', 'VARCHAR(50) COLLATE utf8mb4_bin NOT NULL' );
		db_modify_col( 'T_files', 'file_path', 'varchar(767) COLLATE utf8mb4_bin not null default ""' );
		upg_task_end();
	}

	if( upg_task_start( 16110, 'Creating table for checklist lines...' ) )
	{	// part of 7.2
		db_create_table( 'T_items__checklist_lines', '
			check_ID      INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
			check_item_ID INT(10) UNSIGNED NOT NULL,
			check_checked TINYINT(1) NOT NULL DEFAULT 0,
			check_label   VARCHAR( 10000 ) COLLATE utf8mb4_unicode_ci NOT NULL,
			check_order   INT(11) NOT NULL DEFAULT 1,
			PRIMARY KEY (check_ID),
			KEY check_item_ID (check_item_ID)' );
		upg_task_end();
	}

	if( upg_task_start( 16130, 'Installing new widgets/containers...' ) )
	{	// part of 7.2.0-beta
		install_new_default_widgets( 'comment_list', 'request_title' );
		upg_task_end();
	}

	if( upg_task_start( 16140, 'Installing new widget title for search page and updating widget "Search Form"...' ) )
	{	// part of 7.2.0-beta
		// Add widget CSS class for all search form widgets that use full form template:
		$search_widgets_SQL = new SQL( 'Get widgets "Search Form" before updating params' );
		$search_widgets_SQL->SELECT( 'wi_ID, wi_params' );
		$search_widgets_SQL->FROM( 'T_widget__widget' );
		$search_widgets_SQL->WHERE( 'wi_code = "coll_search_form"' );
		$search_widgets_SQL->WHERE_and( 'wi_params IS NOT NULL' );
		$search_widgets = $DB->get_assoc( $search_widgets_SQL );
		foreach( $search_widgets as $search_widget_ID => $search_widget_params )
		{
			$search_widget_params = unserialize( $search_widget_params );
			if( isset(  $search_widget_params['template'] ) &&
			    $search_widget_params['template'] == 'search_form_full' )
			{	// Add class "well" only for full form:
				$search_widget_params['widget_css_class'] = isset( $search_widget_params['widget_css_class'] ) ? trim( $search_widget_params['widget_css_class'].' well' ) : 'well';
				$DB->query( 'UPDATE T_widget__widget
					  SET wi_params = '.$DB->quote( serialize( $search_widget_params ) ).'
					WHERE wi_ID = '.$search_widget_ID );
			}
		}
		// Add new default widget for title on search page:
		install_new_default_widgets( 'search_area', 'request_title' );
		upg_task_end();
	}

	if( upg_task_start( 16150, 'Installing new widgets for container "Item List"...' ) )
	{	// part of 7.2.0-beta
		install_new_default_widgets( 'item_list', 'request_title' );
		upg_task_end();
	}

	if( upg_task_start( 16160, 'Dummy upgrade block, just to force execution of the upgrade procedure to update templates for cross-posted items...' ) )
	{	// part of 7.2.0-beta
		upg_task_end();
	}

	if( upg_task_start( 16170, 'Upgrading menu entries table...') )
	{	// part of 7.2.1-beta
		db_add_col( 'T_menus__entry', 'ment_class', 'VARCHAR(128) COLLATE ascii_general_ci NULL' );
		upg_task_end();
	}

	/*
	 * ADD UPGRADES __ABOVE__ IN A NEW UPGRADE BLOCK.
	 *
	 * YOU MUST USE:
	 * if( upg_task_start( 12160, 'Descriptive text about action...' ) )
	 * {	// part of 6.8.6-stable
	 *  	// Write new upgrade code here.
	 *  	upg_task_end();
	 * }
	 *
	 * ALL DB CHANGES MUST BE EXPLICITLY CARRIED OUT. DO NOT RELY ON SCHEMA UPDATES!
	 * Schema updates do not survive after several incremental changes.
	 *
	 * NOTE: every change that gets done here, should bump {@link $new_db_version} (by 10).
	 */

	// Clear environment global variables like $Settings, $Plugins
	// which probably were initialized for upgrade process temporary
	// in order to work with objects like $Blog, $Item, $itemType and etc.:
	upg_clear_environment();

	// Execute general upgrade tasks.
	// These tasks needs to be called after every upgrade process, except if they were already executed but the upgrade was not finished because of the max execution time check.
	if( param( 'exec_general_tasks', 'boolean', 1 ) )
	{	// We haven't executed these general tasks yet:

		// Update modules own b2evo tables
		echo get_install_format_text_and_log( "Calling modules for individual upgrades...<br>\n", 'br' );
		evo_flush();
		modules_call_method( 'upgrade_b2evo_tables' );

		// We're going to need some environment in order to init caches and create profile picture links...
		if( ! is_object( $Settings ) )
		{ // create Settings object
			load_class( 'settings/model/_generalsettings.class.php', 'GeneralSettings' );
			$Settings = new GeneralSettings();
		}
		if( ! is_object( $Plugins ) )
		{ // create Plugins object
			load_class( 'plugins/model/_plugins.class.php', 'Plugins' );
			$Plugins = new Plugins();
		}

		echo get_install_format_text_and_log( '<h2>'.T_('Clearing caches...').'</h2>', 'h2' );
		evo_flush();

		// Init Caches:
		load_funcs('tools/model/_system.funcs.php');
		system_init_caches( true, ($old_db_version <= 11410) ); // Only force enabling the caches if we upgrade from a version older or equal to 11410 (6.4.2-beta)
		// note: the above outputs messages

		// Check/Repair Caches:
		task_begin( 'Checking &amp; repairing caches...' );
		load_funcs('tools/model/_system.funcs.php');
		// Check all cache folders if exist and work properly. Try to repair cache folders if they aren't ready for operation.
		$check_cache_messages = system_check_caches( true );
		if( is_array( $check_cache_messages ) && count( $check_cache_messages ) )
		{ // Display errors of the cache checking
			foreach( $check_cache_messages as $check_cache_message )
			{
				echo get_install_format_text_and_log( '<br />', 'br' );
				echo get_install_format_text_and_log( '<span class="text-danger"><evo:error>'.$check_cache_message.'</evo:error></span>' );
			}
			echo get_install_format_text_and_log( '<br />', 'br' );
		}
		task_end();

		// Check if profile picture links should be recreated. It won't be executed in each upgrade, but only in those cases when it is required.
		// This requires an up to date database, and also $Plugins and $GeneralSettings objects must be initialized before this.
		// Note: Check $create_profile_picture_links intialization and usage above to get more information.
		if( $create_profile_picture_links )
		{ // Create links for all files from the users profile_pictures folder
			task_begin( 'Creating profile picture links...' );
			create_profile_picture_links();
			task_end();
		}

		// Invalidate all page caches after every upgrade.
		// A new version of b2evolution may not use the same links to access special pages.
		// We want to play it safe here so that people don't think that upgrading broke their blog!
		task_begin( 'Invalidating all page caches to make sure they don\'t contain old action links...' );
		invalidate_pagecaches();
		task_end();

		echo get_install_format_text_and_log( '<h2>'.T_('Letting plugins upgrade themselves...').'</h2>', 'h2' );
		evo_flush();

		// Reload plugins after every upgrade, to detect even those changes on plugins which didn't require db modifications
		task_begin( 'Reloading installed plugins to make sure their config is up to date...<br />' );
		$Plugins_admin = & get_Plugins_admin();
		$Plugins_admin->log_register = true; // Set flag to know what plugin is going to be installed before it is initialized in order to detect error
		$Plugins_admin->reload_plugins();
		task_end();


		// This has to be at the end because plugin install may fail if the DB schema is not current (matching Plugins class).
		// Only new default plugins will be installed, based on $old_db_version.
		// dh> NOTE: if this fails (e.g. fatal error in one of the plugins), it will not get repeated
		task_begin( 'Installing new default plugins (if any)...' );
		install_basic_plugins( $old_db_version );
		task_end();

		echo get_install_format_text_and_log( '<h2>'.T_('Checking defaults...').'</h2>', 'h2' );
		evo_flush();

		// Create default cron jobs (this can be done at each upgrade):
		echo get_install_format_text_and_log( "Checking if some default cron jobs need to be installed...<br/>\n", 'br' );
		evo_flush();
		require_once dirname(__FILE__).'/_functions_create.php';
		create_default_jobs( true );

		// "Time running low" test: Check if the upgrade script elapsed time is close to the max execution time.
		// Note: This should not really happen except the case when many plugins must be installed.
		task_begin( 'Checking timing of upgrade...' );
		$elapsed_time = time() - $script_start_time;
		$max_exe_time = ini_get( 'max_execution_time' );
		if( $max_exe_time && ( $elapsed_time > ( $max_exe_time - 20 ) ) )
		{ // Max exe time not disabled and we're recahing the end
			// URL to continue the upgrade process from install folder
			$recreate_excerpts = $recreate_autogenerated_excerpts ? '&amp;recreate_excerpts=1' : '';
			$upgrade_continue_url = $baseurl.'install/index.php?locale='.$locale.'&amp;action='.$upgrade_action.'&amp;exec_general_tasks=0'.$recreate_excerpts;
			echo get_install_format_text_and_log( 'We are reaching the time limit for this script. Please click <a href="'.$upgrade_continue_url.'">continue</a>...' );
			// Dirty temporary solution:
			exit(0);
		}
		task_end();

		task_begin( 'Checking default locale...' );
		locale_check_default();
		task_end();

		task_begin( 'Creating and updating default templates...' );
		create_default_templates( false );
		task_end();
	}

	if( $recreate_autogenerated_excerpts )
	{
		if( ! is_object( $Settings ) )
		{ // create Settings object
			load_class( 'settings/model/_generalsettings.class.php', 'GeneralSettings' );
			$Settings = new GeneralSettings();
		}
		if( ! is_object( $Plugins ) )
		{ // create Plugins object
			load_class( 'plugins/model/_plugins.class.php', 'Plugins' );
			$Plugins = new Plugins();
		}

		task_begin( 'Recreate autogenerated post excerpts...' );
		$upgrade_continue_url = $baseurl.'install/index.php?locale='.$locale.'&amp;action='.$upgrade_action.'&amp;exec_general_tasks=0&amp;recreate_excerpts=1';
		$all_excerpt = param( 'all_excerpt', 'integer', 0 );
		recreate_autogenerated_excerpts( $upgrade_continue_url, $all_excerpt == 0 );
		task_end();
	}


	// Update the progress bar status
	update_install_progress_bar();

	/*
	 * -----------------------------------------------
	 * Check to make sure the DB schema is up to date:
	 * -----------------------------------------------
	 */
	echo get_install_format_text_and_log( '<h2>'.T_('Double checking DB structure...').'</h2>', 'h2' );
	evo_flush();

	echo get_install_format_text_and_log( "Starting to check DB...<br/>\n", 'br' );
	evo_flush();

	$upgrade_db_deltas = array(); // This holds changes to make, if any (just all queries)

	global $debug;

	foreach( $schema_queries as $table => $query_info )
	{	// For each table in the schema, check diffs...
		if( $debug )
		{
			echo get_install_format_text_and_log( '<br />', 'br' );
			echo get_install_format_text_and_log( 'Checking table: '.$table.': ' );
		}
		$updates = db_delta( $query_info[1], array('drop_column', 'drop_index'), false, true );
		if( empty($updates) )
		{
			if( $debug ) echo 'ok';
		}
		else
		{
			if( $debug ) echo 'NEEDS UPDATE!';
			foreach( $updates as $table => $queries )
			{
				foreach( $queries as $qinfo )
				{
					foreach( $qinfo['queries'] as $query )
					{ // subqueries for this query (usually one, but may include required other queries)
						$upgrade_db_deltas[] = $query;
					}
				}
			}
		}
	}

	if( $debug )
	{
		echo get_install_format_text_and_log( '<br />', 'br' );
	}

	if( empty($upgrade_db_deltas) )
	{	// no upgrades needed:
		echo get_install_format_text_and_log( '<p>'.T_('The database schema is up to date.').'</p>', 'p' );
	}
	else
	{	// Upgrades are needed:

		$confirmed_db_upgrade = param('confirmed', 'integer', 0); // force confirmation
		$upgrade_db_deltas_confirm_md5 = param( 'upgrade_db_deltas_confirm_md5', 'string', '' );

		if( ! $confirmed_db_upgrade )
		{
			if( ! empty($upgrade_db_deltas_confirm_md5) )
			{ // received confirmation from form
				if( $upgrade_db_deltas_confirm_md5 != md5( implode('', $upgrade_db_deltas) ) )
				{ // unlikely to happen
					echo get_install_format_text_and_log( '<p class="text-danger"><evo:error>'
						.T_('The DB schema has been changed since confirmation.')
						.'</evo:error></p>', 'p' );
				}
				else
				{
					$confirmed_db_upgrade = true;
				}
			}
		}

		if( ! $confirmed_db_upgrade )
		{
			global $action, $form_action, $display;
			load_class( '_core/ui/forms/_form.class.php', 'Form' );

			if( empty( $display ) || $display != 'cli' )
			{	// Don't print form on CLI mode:
				if( !empty( $form_action ) )
				{
					$Form = new Form( $form_action, '', 'post' );
				}
				else
				{
					$Form = new Form( NULL, '', 'post' );
				}

				$Form->begin_form( 'fform', T_('Upgrade database') );

				$Form->begin_fieldset();
				$Form->hidden( 'upgrade_db_deltas_confirm_md5', md5(implode( '', $upgrade_db_deltas )) );
				$Form->hidden( 'action', $action );
				$Form->hidden( 'locale', $locale );
			}


			echo get_install_format_text_and_log( '<p>'.T_('The version number is correct, but we have detected changes in the database schema. This can happen if you\'ve been using development versions directly off GitHub...').'</p>', 'p' );

			echo get_install_format_text_and_log( '<p>'.T_('The following database changes will be carried out. If you are not sure what this means, it will probably be alright.').'</p>', 'p' );

			echo get_install_format_text_and_log( '<ul>' );
			foreach( $upgrade_db_deltas as $l_delta )
			{
				#echo '<li><code>'.nl2br($l_delta).'</code></li>';
				echo get_install_format_text_and_log( '<li><pre>'.str_replace( "\t", '  ', $l_delta ).'</pre></li>', 'li' );
			}
			echo get_install_format_text_and_log( '</ul>' );

			if( empty( $display ) || $display != 'cli' )
			{	// Don't print form on CLI mode:
				$Form->submit( array( '', T_('Try to Repair/Upgrade database now!'), 'btn-warning' ) );
				$Form->end_form();
			}

			global $install_progress_bar_status;
			$install_progress_bar_status = 'warning';

			return 'need-fix';
		}

		// Alter DB to match DB schema:
		install_make_db_schema_current( true );
	}

	// Force MySQL strict mode
	$DB->query( 'SET sql_mode = "TRADITIONAL"', 'Force MySQL "strict" mode (and make sure server is not configured with a weird incompatible mode)' );

	track_step( 'upgrade-success' );

	return true;
}

?>
