diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js
index 43190850da..5ab08eb0fa 100644
--- a/public/src/ajaxify.js
+++ b/public/src/ajaxify.js
@@ -158,7 +158,7 @@ $(document).ready(function() {
 			$(window).trigger('action:ajaxify.end', {url: url});
 		});
 
-		$(window).trigger('action:ajaxify.contentLoaded', {url: url});
+		$(window).trigger('action:ajaxify.contentLoaded', {url: url, tpl: tpl_url});
 
 		app.processPage();
 	};
diff --git a/public/src/client/account/settings.js b/public/src/client/account/settings.js
index 20b33a613b..848bf8c1ef 100644
--- a/public/src/client/account/settings.js
+++ b/public/src/client/account/settings.js
@@ -41,8 +41,8 @@ define('forum/account/settings', ['forum/account/header'], function(header) {
 					if (newSettings.hasOwnProperty(key)) {
 						if (key === 'userLang' && config.userLang !== newSettings.userLang) {
 							requireReload = true;
-						} 
-						config[key] = newSettings[key];	
+						}
+						config[key] = newSettings[key];
 					}
 				}
 				app.exposeConfigToTemplates();
@@ -61,31 +61,6 @@ define('forum/account/settings', ['forum/account/header'], function(header) {
 
 			return false;
 		});
-
-		socket.emit('user.getSettings', {uid: ajaxify.variables.get('theirid')}, function(err, settings) {
-			var inputs = $('.account').find('input, textarea, select');
-
-			inputs.each(function(index, input) {
-				input = $(input);
-				var setting = input.attr('data-property');
-				if (setting) {
-					if (input.is('select')) {
-						input.val(settings[setting]);
-						return;
-					}
-
-					switch (input.attr('type')) {
-						case 'text' :
-						case 'textarea' :
-							input.val(settings[setting]);
-							break;
-						case 'checkbox' :
-							input.prop('checked', !!settings[setting]);
-							break;
-					}
-				}
-			});
-		});
 	};
 
 	return AccountSettings;
diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js
index a0283f0401..e8071ec8ad 100644
--- a/src/controllers/accounts.js
+++ b/src/controllers/accounts.js
@@ -298,7 +298,7 @@ function getFromUserSet(tpl, set, method, type, req, res, next) {
 			},
 			data: function(next) {
 				var start = (page - 1) * itemsPerPage;
-				var stop = start + itemsPerPage;
+				var stop = start + itemsPerPage - 1;
 				method(setName, req.uid, start, stop, next);
 			}
 		}, function(err, results) {
@@ -375,38 +375,59 @@ accountsController.accountEdit = function(req, res, next) {
 };
 
 accountsController.accountSettings = function(req, res, next) {
-	accountsController.getBaseUser(req.params.userslug, req.uid, function(err, userData) {
+	var userData;
+	async.waterfall([
+		function(next) {
+			accountsController.getBaseUser(req.params.userslug, req.uid, next);
+		},
+		function(_userData, next) {
+			userData = _userData;
+			if (!userData) {
+				return helpers.notFound(req, res);
+			}
+			async.parallel({
+				settings: function(next) {
+					user.getSettings(userData.uid, next);
+				},
+				userGroups: function(next) {
+					groups.getUserGroups([userData.uid], next);
+				},
+				languages: function(next) {
+					languages.list(next);
+				}
+			}, next);
+		},
+		function(results, next) {
+			userData.languages = results.languages;
+			userData.userGroups = results.userGroups[0];
+			plugins.fireHook('filter:user.settings', {settings: results.settings, uid: req.uid}, next);
+		},
+		function(data, next) {
+			userData.settings = data.settings;
+			userData.disableEmailSubscriptions = parseInt(meta.config.disableEmailSubscriptions, 10) === 1;
+			next();
+		}
+	], function(err) {
 		if (err) {
 			return next(err);
 		}
 
-		if (!userData) {
-			return helpers.notFound(req, res);
-		}
+		userData.dailyDigestFreqOptions = [
+			{value: 'off', name: '[[user:digest_off]]', selected: 'off' === userData.settings.dailyDigestFreq},
+			{value: 'day', name: '[[user:digest_daily]]', selected: 'day' === userData.settings.dailyDigestFreq},
+			{value: 'week', name: '[[user:digest_weekly]]', selected: 'week' === userData.settings.dailyDigestFreq},
+			{value: 'month', name: '[[user:digest_monthly]]', selected: 'month' === userData.settings.dailyDigestFreq}
+		];
 
-		async.parallel({
-			settings: function(next) {
-				plugins.fireHook('filter:user.settings', [], next);
-			},
-			userGroups: function(next) {
-				groups.getUserGroups([userData.uid], next);
-			},
-			languages: function(next) {
-				languages.list(next);
-			}
-		}, function(err, results) {
-			if (err) {
-				return next(err);
-			}
-
-			userData.settings = results.settings;
-			userData.languages = results.languages;
-			userData.userGroups = results.userGroups[0];
-
-			userData.disableEmailSubscriptions = parseInt(meta.config.disableEmailSubscriptions, 10) === 1;
+		userData.userGroups.forEach(function(group) {
+			group.selected = group.name === userData.settings.groupTitle;
+		});
 
-			res.render('account/settings', userData);
+		userData.languages.forEach(function(language) {
+			language.selected = language.code === userData.settings.userLang;
 		});
+
+		res.render('account/settings', userData);
 	});
 };
 
diff --git a/src/controllers/admin.js b/src/controllers/admin.js
index 52cf194353..4487167873 100644
--- a/src/controllers/admin.js
+++ b/src/controllers/admin.js
@@ -211,8 +211,29 @@ adminController.flags.get = function(req, res, next) {
 };
 
 adminController.database.get = function(req, res, next) {
-	db.info(function (err, data) {
-		res.render('admin/advanced/database', data);
+	async.parallel({
+		redis: function(next) {
+			if (nconf.get('redis')) {
+				var rdb = require('../database/redis');
+				var cxn = rdb.connect();
+				rdb.info(cxn, next);
+			} else {
+				next();
+			}
+		},
+		mongo: function(next) {
+			if (nconf.get('mongo')) {
+				var mdb = require('../database/mongo');
+				mdb.info(mdb.client, next);
+			} else {
+				next();
+			}
+		}
+	}, function(err, results) {
+		if (err) {
+			return next(err);
+		}
+		res.render('admin/advanced/database', results);
 	});
 };
 
diff --git a/src/database/mongo.js b/src/database/mongo.js
index e031132b99..63fdc8b9c2 100644
--- a/src/database/mongo.js
+++ b/src/database/mongo.js
@@ -158,6 +158,24 @@
 		});
 	};
 
+	module.info = function(db, callback) {
+		db.stats({scale:1024}, function(err, stats) {
+			if(err) {
+				return callback(err);
+			}
+
+			stats.avgObjSize = (stats.avgObjSize / 1024).toFixed(2);
+			stats.dataSize = (stats.dataSize / 1024).toFixed(2);
+			stats.storageSize = (stats.storageSize / 1024).toFixed(2);
+			stats.fileSize = (stats.fileSize / 1024).toFixed(2);
+			stats.indexSize = (stats.indexSize / 1024).toFixed(2);
+			stats.raw = JSON.stringify(stats, null, 4);
+			stats.mongo = true;
+
+			callback(null, stats);
+		});
+	};
+
 	module.close = function() {
 		db.close();
 	};
diff --git a/src/database/mongo/main.js b/src/database/mongo/main.js
index eba0b3b14b..7ba58499d3 100644
--- a/src/database/mongo/main.js
+++ b/src/database/mongo/main.js
@@ -79,24 +79,6 @@ module.exports = function(db, module) {
 		db.dropDatabase(callback);
 	};
 
-	module.info = function(callback) {
-		db.stats({scale:1024}, function(err, stats) {
-			if(err) {
-				return callback(err);
-			}
-
-			stats.avgObjSize = (stats.avgObjSize / 1024).toFixed(2);
-			stats.dataSize = (stats.dataSize / 1024).toFixed(2);
-			stats.storageSize = (stats.storageSize / 1024).toFixed(2);
-			stats.fileSize = (stats.fileSize / 1024).toFixed(2);
-			stats.indexSize = (stats.indexSize / 1024).toFixed(2);
-			stats.raw = JSON.stringify(stats, null, 4);
-			stats.mongo = true;
-
-			callback(null, stats);
-		});
-	};
-
 	module.exists = function(key, callback) {
 		if (!key) {
 			return callback();
diff --git a/src/database/redis.js b/src/database/redis.js
index 8e06ce837a..1c224276cc 100644
--- a/src/database/redis.js
+++ b/src/database/redis.js
@@ -115,6 +115,28 @@
 		redisClient.quit();
 	};
 
+	module.info = function(cxn, callback) {
+		cxn.info(function (err, data) {
+			if (err) {
+				return callback(err);
+			}
+
+			var lines = data.toString().split("\r\n").sort();
+			var redisData = {};
+			lines.forEach(function (line) {
+				var parts = line.split(':');
+				if (parts[1]) {
+					redisData[parts[0]] = parts[1];
+				}
+			});
+
+			redisData.raw = JSON.stringify(redisData, null, 4);
+			redisData.redis = true;
+
+			callback(null, redisData);
+		});
+	};
+
 	module.helpers = module.helpers || {};
 	module.helpers.redis = require('./redis/helpers');
 }(exports));
diff --git a/src/database/redis/main.js b/src/database/redis/main.js
index 84e31eaae4..503d515569 100644
--- a/src/database/redis/main.js
+++ b/src/database/redis/main.js
@@ -35,27 +35,7 @@ module.exports = function(redisClient, module) {
 		});
 	};
 
-	module.info = function(callback) {
-		redisClient.info(function (err, data) {
-			if(err) {
-				return callback(err);
-			}
-
-			var lines = data.toString().split("\r\n").sort();
-			var redisData = {};
-			lines.forEach(function (line) {
-				var parts = line.split(':');
-				if (parts[1]) {
-					redisData[parts[0]] = parts[1];
-				}
-			});
-
-			redisData.raw = JSON.stringify(redisData, null, 4);
-			redisData.redis = true;
 
-			callback(null, redisData);
-		});
-	};
 
 	module.exists = function(key, callback) {
 		redisClient.exists(key, function(err, exists) {
diff --git a/src/groups.js b/src/groups.js
index 632a51f805..4f52d2bc9f 100644
--- a/src/groups.js
+++ b/src/groups.js
@@ -760,17 +760,18 @@ var async = require('async'),
 						tasks.push(async.apply(db.setAdd, 'group:' + groupName + ':owners', uid));
 					}
 					async.parallel(tasks, next);
+				},
+				function(results, next) {
+					user.setGroupTitle(groupName, uid, next);
+				},
+				function(next) {
+					plugins.fireHook('action:group.join', {
+						groupName: groupName,
+						uid: uid
+					});
+					next();
 				}
-			], function(err, results) {
-				if (err) {
-					return callback(err);
-				}
-				plugins.fireHook('action:group.join', {
-					groupName: groupName,
-					uid: uid
-				});
-				callback();
-			});
+			], callback);
 		}
 
 		callback = callback || function() {};
diff --git a/src/socket.io/user.js b/src/socket.io/user.js
index 0df36121e8..65af901b08 100644
--- a/src/socket.io/user.js
+++ b/src/socket.io/user.js
@@ -340,26 +340,6 @@ function toggleFollow(method, uid, theiruid, callback) {
 	});
 }
 
-SocketUser.getSettings = function(socket, data, callback) {
-	if (socket.uid) {
-		if (socket.uid === parseInt(data.uid, 10)) {
-			return user.getSettings(socket.uid, callback);
-		}
-
-		user.isAdministrator(socket.uid, function(err, isAdmin) {
-			if (err) {
-				return callback(err);
-			}
-
-			if (!isAdmin) {
-				return callback(new Error('[[error:no-privileges]]'));
-			}
-
-			user.getSettings(data.uid, callback);
-		});
-	}
-};
-
 SocketUser.saveSettings = function(socket, data, callback) {
 	if (!socket.uid || !data) {
 		return callback(new Error('[[error:invalid-data]]'));
diff --git a/src/upgrade.js b/src/upgrade.js
index da5edb4a36..1044cde651 100644
--- a/src/upgrade.js
+++ b/src/upgrade.js
@@ -21,7 +21,7 @@ var db = require('./database'),
 	schemaDate, thisSchemaDate,
 
 	// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
-	latestSchema = Date.UTC(2015, 4, 7);
+	latestSchema = Date.UTC(2015, 4, 8);
 
 Upgrade.check = function(callback) {
 	db.get('schemaDate', function(err, value) {
@@ -233,18 +233,17 @@ Upgrade.upgrade = function(callback) {
 							var privs = ['find', 'read', 'topics:reply', 'topics:create'];
 
 							async.each(privs, function(priv, next) {
-
 								categoryHasPrivilegesSet(cid, priv, function(err, privilegesSet) {
 									if (err || privilegesSet) {
 										return next(err);
 									}
 
 									async.eachLimit(groups, 50, function(group, next) {
-										if (group && !group.hidden) {
-											if (group.name === 'guests' && (priv === 'topics:reply' || priv === 'topics:create')) {
+										if (group) {
+											if (group === 'guests' && (priv === 'topics:reply' || priv === 'topics:create')) {
 												return next();
 											}
-											Groups.join('cid:' + cid + ':privileges:groups:' + priv, group.name, next);
+											Groups.join('cid:' + cid + ':privileges:groups:' + priv, group, next);
 										} else {
 											next();
 										}
@@ -989,7 +988,7 @@ Upgrade.upgrade = function(callback) {
 			thisSchemaDate = Date.UTC(2015, 4, 7);
 			if (schemaDate < thisSchemaDate) {
 				updatesMade = true;
-				winston.info('[2015/02/25] Upgrading uid mappings to sorted set');
+				winston.info('[2015/05/07] Upgrading uid mappings to sorted set');
 
 				async.series([
 					async.apply(upgradeHashToSortedSet, 'email:uid'),
@@ -1009,6 +1008,41 @@ Upgrade.upgrade = function(callback) {
 				winston.info('[2015/05/07] Upgrading uid mappings to sorted set skipped');
 				next();
 			}
+		},
+		function(next) {
+			thisSchemaDate = Date.UTC(2015, 4, 8);
+			if (schemaDate < thisSchemaDate) {
+				updatesMade = true;
+				winston.info('[2015/05/08] Fixing emails');
+
+				db.getSortedSetRangeWithScores('email:uid', 0, -1, function(err, users) {
+					if (err) {
+						return next(err);
+					}
+
+					async.eachLimit(users, 100, function(user, next) {
+						var newEmail = user.value.replace(/\uff0E/g, '.');
+						if (newEmail === user.value) {
+							return next();
+						}
+						async.series([
+							async.apply(db.sortedSetRemove, 'email:uid', user.value),
+							async.apply(db.sortedSetAdd, 'email:uid', user.score, newEmail)
+						], next);
+
+					}, function(err) {
+						if (err) {
+							return next(err);
+						}
+						winston.info('[2015/05/08] Fixing emails done');
+						Upgrade.update(thisSchemaDate, next);
+					});
+				});
+
+			} else {
+				winston.info('[2015/05/08] Fixing emails skipped');
+				next();
+			}
 		}
 
 		// Add new schema updates here
diff --git a/src/user/settings.js b/src/user/settings.js
index 7c12cbfd00..ec493457aa 100644
--- a/src/user/settings.js
+++ b/src/user/settings.js
@@ -143,4 +143,17 @@ module.exports = function(User) {
 	User.setSetting = function(uid, key, value, callback) {
 		db.setObjectField('user:' + uid + ':settings', key, value, callback);
 	};
+
+	User.setGroupTitle = function(groupName, uid, callback) {
+		if (groupName === 'registered-users') {
+			return callback();
+		}
+		db.getObjectField('user:' + uid + ':settings', 'groupTitle', function(err, currentTitle) {
+			if (err || (currentTitle || currentTitle === '')) {
+				return callback(err);
+			}
+
+			User.setSetting(uid, 'groupTitle', groupName, callback);
+		});
+	};
 };
diff --git a/src/views/admin/advanced/database.tpl b/src/views/admin/advanced/database.tpl
index e08daac3f7..740418fc35 100644
--- a/src/views/admin/advanced/database.tpl
+++ b/src/views/admin/advanced/database.tpl
@@ -1,5 +1,23 @@
 <div class="database">
 	<div class="col-sm-9">
+		<!-- IF mongo -->
+		<div class="panel panel-default">
+			<div class="panel-heading"><i class="fa fa-hdd-o"></i> Mongo</div>
+			<div class="panel-body">
+				<div class="database-info">
+					<span>Collections</span> <span class="text-right formatted-number">{collections}</span><br/>
+					<span>Objects</span> <span class="text-right formatted-number">{objects}</span><br/>
+					<span>Avg. Object Size</span> <span class="text-right">{avgObjSize} kb</span><br/>
+					<hr/>
+					<span>Data Size</span> <span class="text-right">{dataSize} mb</span><br/>
+					<span>Storage Size</span> <span class="text-right">{storageSize} mb</span><br/>
+					<span>Index Size</span> <span class="text-right">{indexSize} mb</span><br/>
+					<span>File Size</span> <span class="text-right">{fileSize} mb</span><br/>
+				</div>
+			</div>
+		</div>
+		<!-- ENDIF mongo -->
+
 		<!-- IF redis -->
 		<div class="panel panel-default">
 			<div class="panel-heading"><i class="fa fa-hdd-o"></i> Redis</div>
@@ -31,29 +49,30 @@
 
 		<!-- IF mongo -->
 		<div class="panel panel-default">
-			<div class="panel-heading"><i class="fa fa-hdd-o"></i> Mongo</div>
-			<div class="panel-body">
-				<div class="database-info">
-					<span>Collections</span> <span class="text-right formatted-number">{collections}</span><br/>
-					<span>Objects</span> <span class="text-right formatted-number">{objects}</span><br/>
-					<span>Avg. Object Size</span> <span class="text-right">{avgObjSize} kb</span><br/>
-					<hr/>
-					<span>Data Size</span> <span class="text-right">{dataSize} mb</span><br/>
-					<span>Storage Size</span> <span class="text-right">{storageSize} mb</span><br/>
-					<span>Index Size</span> <span class="text-right">{indexSize} mb</span><br/>
-					<span>File Size</span> <span class="text-right">{fileSize} mb</span><br/>
+			<div class="panel-heading" data-toggle="collapse" data-target=".mongodb-raw">
+				<h3 class="panel-title"><i class="fa fa-caret-down"></i> MongoDB Raw Info</h3>
+			</div>
+
+			<div class="panel-body mongodb-raw collapse">
+				<div class="highlight">
+					<pre>{mongo.raw}</pre>
 				</div>
 			</div>
 		</div>
 		<!-- ENDIF mongo -->
 
+		<!-- IF redis -->
 		<div class="panel panel-default">
-			<div class="panel-heading"><i class="fa fa-hdd-o"></i> Raw Info</div>
-			<div class="panel-body">
+			<div class="panel-heading" data-toggle="collapse" data-target=".redis-raw">
+				<h3 class="panel-title"><i class="fa fa-caret-down"></i> Redis Raw Info</h3>
+			</div>
+
+			<div class="panel-body redis-raw collapse">
 				<div class="highlight">
-					<pre>{raw}</pre>
+					<pre>{redis.raw}</pre>
 				</div>
 			</div>
 		</div>
+		<!-- ENDIF redis -->
 	</div>
 </div>
diff --git a/src/views/admin/extend/plugins.tpl b/src/views/admin/extend/plugins.tpl
index 72c7228d0e..90611e6d47 100644
--- a/src/views/admin/extend/plugins.tpl
+++ b/src/views/admin/extend/plugins.tpl
@@ -73,7 +73,7 @@
 						<small>Latest <strong class="latestVersion">{plugins.latest}</strong></small>
 
 						<!-- IF plugins.url -->
-						<p>For more information: <a href="{plugins.url}">{plugins.url}</a></p>
+						<p>For more information: <a target="_blank" href="{plugins.url}">{plugins.url}</a></p>
 						<!-- ENDIF plugins.url -->
 					</li>
 					<!-- ENDIF !plugins.installed -->