diff --git a/public/templates/admin/settings.tpl b/public/templates/admin/settings.tpl
index 8e23e945c7..da88d2003e 100644
--- a/public/templates/admin/settings.tpl
+++ b/public/templates/admin/settings.tpl
@@ -73,6 +73,11 @@
 		<strong>Post Delay</strong><br /> <input type="text" class="form-control" value="10000" data-field="postDelay"><br />
 		<strong>Minimum Title Length</strong><br /> <input type="text" class="form-control" value="3" data-field="minimumTitleLength"><br />
 		<strong>Minimum Post Length</strong><br /> <input type="text" class="form-control" value="8" data-field="minimumPostLength"><br />
+		<div class="checkbox">
+			<label>
+				<input type="checkbox" data-field="allowGuestPosting"> <strong>Allow guests to post without logging in</strong>
+			</label>
+		</div>
 		<div class="checkbox">
 			<label>
 				<input type="checkbox" data-field="useOutgoingLinksPage"> <strong>Use Outgoing Links Warning Page</strong>
diff --git a/src/install.js b/src/install.js
index 4410dccfe9..01a3806656 100644
--- a/src/install.js
+++ b/src/install.js
@@ -140,6 +140,9 @@ var async = require('async'),
 						}, {
 							field: 'minimumPostLength',
 							value: 8
+						}, {
+							field: 'allowGuestPosting',
+							value: 0
 						}, {
 							field: 'minimumTitleLength',
 							value: 3
diff --git a/src/postTools.js b/src/postTools.js
index 4876d9c5b0..043714072d 100644
--- a/src/postTools.js
+++ b/src/postTools.js
@@ -37,9 +37,7 @@ var RDB = require('./redis.js'),
 
 		function isOwnPost(next) {
 			posts.getPostField(pid, 'uid', function(author) {
-				if (author && parseInt(author) > 0) {
-					next(null, parseInt(author, 10) === parseInt(uid, 10));
-				}
+				next(null, parseInt(author, 10) === parseInt(uid, 10));
 			});
 		}
 
@@ -60,6 +58,7 @@ var RDB = require('./redis.js'),
 
 
 	PostTools.edit = function(uid, pid, title, content) {
+
 		var	success = function() {
 			async.waterfall([
 				function(next) {
diff --git a/src/posts.js b/src/posts.js
index c0386e480d..c5f97cdb4b 100644
--- a/src/posts.js
+++ b/src/posts.js
@@ -287,41 +287,34 @@ var RDB = require('./redis.js'),
 			return;
 		}
 
-		user.getUserField(uid, 'lastposttime', function(lastposttime) {
-			if (Date.now() - lastposttime < meta.config.postDelay) {
-				callback(new Error('too-many-posts'), null);
-				return;
-			}
-
-			Posts.create(uid, tid, content, function(postData) {
-				if (postData) {
+		Posts.create(uid, tid, content, function(postData) {
+			if (postData) {
 
-					topics.markUnRead(tid);
+				topics.markUnRead(tid);
 
-					Posts.get_cid_by_pid(postData.pid, function(cid) {
-						RDB.del('cid:' + cid + ':read_by_uid', function(err, data) {
-							topics.markAsRead(tid, uid);
-						});
+				Posts.get_cid_by_pid(postData.pid, function(cid) {
+					RDB.del('cid:' + cid + ':read_by_uid', function(err, data) {
+						topics.markAsRead(tid, uid);
 					});
+				});
 
-					threadTools.notify_followers(tid, uid);
+				threadTools.notifyFollowers(tid, uid);
 
-					Posts.addUserInfoToPost(postData, function() {
-						var socketData = {
-							posts: [postData]
-						};
-						io.sockets.in('topic_' + tid).emit('event:new_post', socketData);
-						io.sockets.in('recent_posts').emit('event:new_post', socketData);
-						io.sockets.in('user/' + uid).emit('event:new_post', socketData);
-					});
+				Posts.addUserInfoToPost(postData, function() {
+					var socketData = {
+						posts: [postData]
+					};
+					io.sockets.in('topic_' + tid).emit('event:new_post', socketData);
+					io.sockets.in('recent_posts').emit('event:new_post', socketData);
+					io.sockets.in('user/' + uid).emit('event:new_post', socketData);
+				});
 
-					callback(null, 'Reply successful');
-				} else {
-					callback(new Error('reply-error'), null);
-				}
-			});
+				callback(null, 'Reply successful');
+			} else {
+				callback(new Error('reply-error'), null);
+			}
 		});
-	};
+	}
 
 	Posts.create = function(uid, tid, content, callback) {
 		if (uid === null) {
diff --git a/src/threadTools.js b/src/threadTools.js
index e757bd41e6..c3f5297918 100644
--- a/src/threadTools.js
+++ b/src/threadTools.js
@@ -263,7 +263,7 @@ var RDB = require('./redis.js'),
 		});
 	}
 
-	ThreadTools.get_followers = function(tid, callback) {
+	ThreadTools.getFollowers = function(tid, callback) {
 		RDB.smembers('tid:' + tid + ':followers', function(err, followers) {
 			callback(err, followers.map(function(follower) {
 				return parseInt(follower, 10);
@@ -271,7 +271,7 @@ var RDB = require('./redis.js'),
 		});
 	}
 
-	ThreadTools.notify_followers = function(tid, exceptUid) {
+	ThreadTools.notifyFollowers = function(tid, exceptUid) {
 		async.parallel([
 			function(next) {
 				topics.getTopicField(tid, 'title', function(err, title) {
@@ -285,7 +285,7 @@ var RDB = require('./redis.js'),
 				});
 			},
 			function(next) {
-				ThreadTools.get_followers(tid, function(err, followers) {
+				ThreadTools.getFollowers(tid, function(err, followers) {
 					exceptUid = parseInt(exceptUid, 10);
 					if (followers.indexOf(exceptUid) !== -1) followers.splice(followers.indexOf(exceptUid), 1);
 					next(null, followers);
diff --git a/src/topics.js b/src/topics.js
index 76408b9fb5..c95b3be200 100644
--- a/src/topics.js
+++ b/src/topics.js
@@ -85,7 +85,8 @@ var RDB = require('./redis.js'),
 				for (var i = 0; i < postData.length; ++i) {
 					postData[i].fav_button_class = fav_data[postData[i].pid] ? 'btn-warning' : '';
 					postData[i].fav_star_class = fav_data[postData[i].pid] ? 'icon-star' : 'icon-star-empty';
-					postData[i]['display_moderator_tools'] = (postData[i].uid == current_user || privileges.editable) ? 'show' : 'none';
+					postData[i]['display_moderator_tools'] = ((current_user != 0) && (postData[i].uid == current_user || privileges.editable)) ? 'show' : 'none';
+
 					postData[i].show_banned = postData[i].user_banned === '1' ? 'show' : 'hide';
 				}
 
diff --git a/src/websockets.js b/src/websockets.js
index 559f52a98f..311ac0fb70 100644
--- a/src/websockets.js
+++ b/src/websockets.js
@@ -60,7 +60,7 @@ module.exports.init = function(io) {
 
 	io.sockets.on('connection', function(socket) {
 		var hs = socket.handshake,
-			sessionID, uid;
+			sessionID, uid, lastPostTime = 0;
 
 
 		// Validate the session, if present
@@ -397,7 +397,7 @@ module.exports.init = function(io) {
 		});
 
 		socket.on('api:posts.reply', function(data) {
-			if (uid < 1) {
+			if (uid < 1 && meta.config.allowGuestPosting === '0') {
 				socket.emit('event:alert', {
 					title: 'Reply Unsuccessful',
 					message: 'You don&apos;t seem to be logged in, so you cannot reply.',
@@ -407,8 +407,14 @@ module.exports.init = function(io) {
 				return;
 			}
 
+			if (Date.now() - lastPostTime < meta.config.postDelay) {
+				posts.emitTooManyPostsAlert(socket);
+				return;
+			}
+
 			posts.reply(data.topic_id, uid, data.content, function(err, result) {
 				if(err) {
+
 					if(err.message === 'content-too-short') {
 						posts.emitContentTooShortAlert(socket);
 					} else if (err.message === 'too-many-posts') {
@@ -425,7 +431,7 @@ module.exports.init = function(io) {
 				}
 
 				if (result) {
-
+					lastPostTime = Date.now();
 					posts.getTopicPostStats();
 
 					socket.emit('event:alert', {
@@ -535,6 +541,7 @@ module.exports.init = function(io) {
 		});
 
 		socket.on('api:posts.edit', function(data) {
+
 			if (!data.title || data.title.length < topics.minimumTitleLength) {
 				topics.emitTitleTooShortAlert(socket);
 				return;
@@ -542,6 +549,7 @@ module.exports.init = function(io) {
 				posts.emitContentTooShortAlert(socket);
 				return;
 			}
+
 			postTools.edit(uid, data.pid, data.title, data.content, data.images);
 		});
 
@@ -664,7 +672,7 @@ module.exports.init = function(io) {
 		});
 
 		socket.on('api:composer.push', function(data) {
-			if (uid > 0) {
+			if (uid > 0 || meta.config.allowGuestPosting === '1') {
 				if (parseInt(data.tid) > 0) {
 					topics.getTopicData(data.tid, function(topicData) {
 						if (data.body)