Index: binary-improvements/MapRendering/API.cs
===================================================================
--- binary-improvements/MapRendering/API.cs	(revision 325)
+++ binary-improvements/MapRendering/API.cs	(revision 326)
@@ -14,5 +14,5 @@
 			// ReSharper disable once ObjectCreationAsStatement
 			new Web ();
-			LogBuffer.Instance.GetType ();
+			LogBuffer.Init ();
 		}
 
Index: binary-improvements/MapRendering/Commands/WebPermissionsCmd.cs
===================================================================
--- binary-improvements/MapRendering/Commands/WebPermissionsCmd.cs	(revision 325)
+++ binary-improvements/MapRendering/Commands/WebPermissionsCmd.cs	(revision 326)
@@ -23,17 +23,12 @@
 		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) {
 			if (_params.Count >= 1) {
-				switch (_params [0].ToLower ()) {
-					case "add":
-						ExecuteAdd (_params);
-						break;
-					case "remove":
-						ExecuteRemove (_params);
-						break;
-					case "list":
-						ExecuteList ();
-						break;
-					default:
-						SdtdConsole.Instance.Output ("Invalid sub command \"" + _params [0] + "\".");
-						return;
+				if (_params [0].EqualsCaseInsensitive ("add")) {
+					ExecuteAdd (_params);
+				} else if (_params [0].EqualsCaseInsensitive ("remove")) {
+					ExecuteRemove (_params);
+				} else if (_params [0].EqualsCaseInsensitive ("list")) {
+					ExecuteList ();
+				} else {
+					SdtdConsole.Instance.Output ("Invalid sub command \"" + _params [0] + "\".");
 				}
 			} else {
Index: binary-improvements/MapRendering/Commands/WebTokens.cs
===================================================================
--- binary-improvements/MapRendering/Commands/WebTokens.cs	(revision 325)
+++ binary-improvements/MapRendering/Commands/WebTokens.cs	(revision 326)
@@ -25,17 +25,12 @@
 		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) {
 			if (_params.Count >= 1) {
-				switch (_params [0].ToLower ()) {
-					case "add":
-						ExecuteAdd (_params);
-						break;
-					case "remove":
-						ExecuteRemove (_params);
-						break;
-					case "list":
-						ExecuteList ();
-						break;
-					default:
-						SdtdConsole.Instance.Output ("Invalid sub command \"" + _params [0] + "\".");
-						return;
+				if (_params [0].EqualsCaseInsensitive ("add")) {
+					ExecuteAdd (_params);
+				} else if (_params [0].EqualsCaseInsensitive ("remove")) {
+					ExecuteRemove (_params);
+				} else if (_params [0].EqualsCaseInsensitive ("list")) {
+					ExecuteList ();
+				} else {
+					SdtdConsole.Instance.Output ("Invalid sub command \"" + _params [0] + "\".");
 				}
 			} else {
Index: binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs	(revision 325)
+++ binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs	(revision 326)
@@ -71,18 +71,20 @@
 		private void loadTextureFromFile (string _fileName) {
 			byte[] array = cache.LoadTile (zoomLevel, _fileName);
-			if (array == null || !blockMap.LoadImage (array) || blockMap.height != Constants.MAP_BLOCK_SIZE ||
-			    blockMap.width != Constants.MAP_BLOCK_SIZE) {
-				if (array != null) {
-					Log.Error ("Map image tile " + _fileName + " has been corrupted, recreating tile");
-				}
+			if (array != null && blockMap.LoadImage (array) && blockMap.height == Constants.MAP_BLOCK_SIZE &&
+			    blockMap.width == Constants.MAP_BLOCK_SIZE) {
+				return;
+			}
 
-				if (blockMap.height != Constants.MAP_BLOCK_SIZE || blockMap.width != Constants.MAP_BLOCK_SIZE) {
-					blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
-				}
+			if (array != null) {
+				Log.Error ("Map image tile " + _fileName + " has been corrupted, recreating tile");
+			}
 
-				for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
-					for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
-						blockMap.SetPixel (x, y, nullColor);
-					}
+			if (blockMap.height != Constants.MAP_BLOCK_SIZE || blockMap.width != Constants.MAP_BLOCK_SIZE) {
+				blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
+			}
+
+			for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
+				for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
+					blockMap.SetPixel (x, y, nullColor);
 				}
 			}
Index: binary-improvements/MapRendering/MapRendering/MapRendering.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/MapRendering.cs	(revision 325)
+++ binary-improvements/MapRendering/MapRendering/MapRendering.cs	(revision 326)
@@ -104,6 +104,6 @@
 			Texture2D fullMapTexture = null;
 
-			Vector2i minChunk = default (Vector2i), maxChunk = default (Vector2i);
-			Vector2i minPos = default (Vector2i), maxPos = default (Vector2i);
+			Vector2i minChunk, maxChunk;
+			Vector2i minPos, maxPos;
 			int widthChunks, heightChunks, widthPix, heightPix;
 			getWorldExtent (rfm, out minChunk, out maxChunk, out minPos, out maxPos, out widthChunks, out heightChunks,
@@ -181,5 +181,4 @@
 				File.WriteAllBytes (Constants.MAP_DIRECTORY + "/map.png", array);
 				Object.Destroy (fullMapTexture);
-				fullMapTexture = null;
 			}
 
@@ -190,5 +189,5 @@
 		}
 
-		private void SaveAllBlockMaps (object source, ElapsedEventArgs e) {
+		private void SaveAllBlockMaps () {
 			for (int i = 0; i < Constants.ZOOMLEVELS; i++) {
 				zoomLevelBuffers [i].SaveBlock ();
@@ -215,56 +214,59 @@
 			msw.ResetAndRestart ();
 
-			if (dirtyChunks.Count > 0) {
-				List<Vector2i> keys = new List<Vector2i> (dirtyChunks.Keys);
-				List<Vector2i> chunksDone = new List<Vector2i> ();
-
-				Vector2i chunkPos = keys [0];
-				chunksDone.Add (chunkPos);
-
-				//Log.Out ("Start Dirty: " + chunkPos);
-
-				Vector2i block = default (Vector2i), blockOffset = default (Vector2i);
-				getBlockNumber (chunkPos, out block, out blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV,
+			if (dirtyChunks.Count <= 0) {
+				return;
+			}
+
+			List<Vector2i> keys = new List<Vector2i> (dirtyChunks.Keys);
+			List<Vector2i> chunksDone = new List<Vector2i> ();
+
+			Vector2i chunkPos = keys [0];
+			chunksDone.Add (chunkPos);
+
+			//Log.Out ("Start Dirty: " + chunkPos);
+
+			Vector2i block, blockOffset;
+			getBlockNumber (chunkPos, out block, out blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV,
+				Constants.MAP_CHUNK_SIZE);
+
+			zoomLevelBuffers [Constants.ZOOMLEVELS - 1].LoadBlock (block);
+
+			Vector2i v_block, v_blockOffset;
+			foreach (Vector2i v in keys) {
+				getBlockNumber (v, out v_block, out v_blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV,
 					Constants.MAP_CHUNK_SIZE);
-
-				zoomLevelBuffers [Constants.ZOOMLEVELS - 1].LoadBlock (block);
-
-				Vector2i v_block = default (Vector2i), v_blockOffset = default (Vector2i);
-				foreach (Vector2i v in keys) {
-					getBlockNumber (v, out v_block, out v_blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV,
-						Constants.MAP_CHUNK_SIZE);
-					if (v_block.Equals (block)) {
-						//Log.Out ("Dirty: " + v + " render: true");
-						chunksDone.Add (v);
-						if (dirtyChunks [v].Length != Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE) {
-							Log.Error (string.Format ("Rendering chunk has incorrect data size of {0} instead of {1}",
-								dirtyChunks [v].Length, Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE));
-						}
-
-						zoomLevelBuffers [Constants.ZOOMLEVELS - 1]
-							.SetPart (v_blockOffset, Constants.MAP_CHUNK_SIZE, dirtyChunks [v]);
-					}
-				}
-
-				foreach (Vector2i v in chunksDone) {
-					dirtyChunks.Remove (v);
-				}
-
-				RenderZoomLevel (Constants.ZOOMLEVELS - 1, block);
-
-				SaveAllBlockMaps (null, null);
-			}
-		}
-
-		private void RenderZoomLevel (int level, Vector2i innerBlock) {
-			if (level > 0) {
-				Vector2i block = default (Vector2i), blockOffset = default (Vector2i);
+				if (v_block.Equals (block)) {
+					//Log.Out ("Dirty: " + v + " render: true");
+					chunksDone.Add (v);
+					if (dirtyChunks [v].Length != Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE) {
+						Log.Error (string.Format ("Rendering chunk has incorrect data size of {0} instead of {1}",
+							dirtyChunks [v].Length, Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE));
+					}
+
+					zoomLevelBuffers [Constants.ZOOMLEVELS - 1]
+						.SetPart (v_blockOffset, Constants.MAP_CHUNK_SIZE, dirtyChunks [v]);
+				}
+			}
+
+			foreach (Vector2i v in chunksDone) {
+				dirtyChunks.Remove (v);
+			}
+
+			RenderZoomLevel (block);
+
+			SaveAllBlockMaps ();
+		}
+
+		private void RenderZoomLevel (Vector2i innerBlock) {
+			int level = Constants.ZOOMLEVELS - 1;
+			while (level > 0) {
+				Vector2i block, blockOffset;
 				getBlockNumber (innerBlock, out block, out blockOffset, 2, Constants.MAP_BLOCK_SIZE / 2);
 
 				zoomLevelBuffers [level - 1].LoadBlock (block);
-				zoomLevelBuffers [level - 1].SetPart (blockOffset, Constants.MAP_BLOCK_SIZE / 2,
-					zoomLevelBuffers [level].GetHalfScaled ());
-
-				RenderZoomLevel (level - 1, block);
+				zoomLevelBuffers [level - 1].SetPart (blockOffset, Constants.MAP_BLOCK_SIZE / 2, zoomLevelBuffers [level].GetHalfScaled ());
+
+				level = level - 1;
+				innerBlock = block;
 			}
 		}
@@ -290,25 +292,27 @@
 
 		private bool LoadMapInfo () {
-			if (File.Exists (Constants.MAP_DIRECTORY + "/mapinfo.json")) {
-				string json = File.ReadAllText (Constants.MAP_DIRECTORY + "/mapinfo.json", Encoding.UTF8);
-				try {
-					JSONNode node = Parser.Parse (json);
-					if (node is JSONObject) {
-						JSONObject jo = (JSONObject) node;
-						if (jo.ContainsKey ("blockSize")) {
-							Constants.MAP_BLOCK_SIZE = ((JSONNumber) jo ["blockSize"]).GetInt ();
-						}
-
-						if (jo.ContainsKey ("maxZoom")) {
-							Constants.ZOOMLEVELS = ((JSONNumber) jo ["maxZoom"]).GetInt () + 1;
-						}
-
-						return true;
-					}
-				} catch (MalformedJSONException e) {
-					Log.Out ("Exception in LoadMapInfo: " + e);
-				} catch (InvalidCastException e) {
-					Log.Out ("Exception in LoadMapInfo: " + e);
-				}
+			if (!File.Exists (Constants.MAP_DIRECTORY + "/mapinfo.json")) {
+				return false;
+			}
+
+			string json = File.ReadAllText (Constants.MAP_DIRECTORY + "/mapinfo.json", Encoding.UTF8);
+			try {
+				JSONNode node = Parser.Parse (json);
+				if (node is JSONObject) {
+					JSONObject jo = (JSONObject) node;
+					if (jo.ContainsKey ("blockSize")) {
+						Constants.MAP_BLOCK_SIZE = ((JSONNumber) jo ["blockSize"]).GetInt ();
+					}
+
+					if (jo.ContainsKey ("maxZoom")) {
+						Constants.ZOOMLEVELS = ((JSONNumber) jo ["maxZoom"]).GetInt () + 1;
+					}
+
+					return true;
+				}
+			} catch (MalformedJSONException e) {
+				Log.Out ("Exception in LoadMapInfo: " + e);
+			} catch (InvalidCastException e) {
+				Log.Out ("Exception in LoadMapInfo: " + e);
 			}
 
Index: binary-improvements/MapRendering/Web/API/GetLandClaims.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetLandClaims.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/API/GetLandClaims.cs	(revision 326)
@@ -50,5 +50,5 @@
 
 			foreach (KeyValuePair<Player, List<Vector3i>> kvp in claims) {
-				try {
+//				try {
 					JSONObject owner = new JSONObject ();
 					claimOwners.Add (owner);
@@ -74,6 +74,6 @@
 						claimsJson.Add (claim);
 					}
-				} catch {
-				}
+//				} catch {
+//				}
 			}
 
Index: binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs	(revision 326)
@@ -75,19 +75,20 @@
 
 		internal static JSONNode GetJsonForItem (InvItem _item) {
-			if (_item != null) {
-				JSONObject jsonItem = new JSONObject ();
-				jsonItem.Add ("count", new JSONNumber (_item.count));
-				jsonItem.Add ("name", new JSONString (_item.itemName));
-				jsonItem.Add ("icon", new JSONString (_item.icon));
-				jsonItem.Add ("iconcolor", new JSONString (_item.iconcolor));
-				jsonItem.Add ("quality", new JSONNumber (_item.quality));
-				if (_item.quality >= 0) {
-					jsonItem.Add ("qualitycolor", new JSONString (QualityInfo.GetQualityColorHex (_item.quality)));
-				}
-
-				return jsonItem;
+			if (_item == null) {
+				return new JSONNull ();
 			}
 
-			return new JSONNull ();
+			JSONObject jsonItem = new JSONObject ();
+			jsonItem.Add ("count", new JSONNumber (_item.count));
+			jsonItem.Add ("name", new JSONString (_item.itemName));
+			jsonItem.Add ("icon", new JSONString (_item.icon));
+			jsonItem.Add ("iconcolor", new JSONString (_item.iconcolor));
+			jsonItem.Add ("quality", new JSONNumber (_item.quality));
+			if (_item.quality >= 0) {
+				jsonItem.Add ("qualitycolor", new JSONString (QualityInfo.GetQualityColorHex (_item.quality)));
+			}
+
+			return jsonItem;
+
 		}
 	}
Index: binary-improvements/MapRendering/Web/API/GetPlayerList.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayerList.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/API/GetPlayerList.cs	(revision 326)
@@ -40,5 +40,5 @@
 				Player p = playersList [sid, false];
 
-				ulong player_steam_ID = 0L;
+				ulong player_steam_ID;
 				if (!ulong.TryParse (sid, out player_steam_ID)) {
 					player_steam_ID = 0L;
@@ -64,5 +64,5 @@
 					pJson.Add ("ping", new JSONNumber (p.IsOnline ? p.ClientInfo.ping : -1));
 
-					JSONBoolean banned = null;
+					JSONBoolean banned;
 					if (admTools != null) {
 						banned = new JSONBoolean (admTools.IsBanned (sid));
@@ -132,6 +132,6 @@
 
 				if (colType == typeof (JSONBoolean)) {
-					bool value = _filterVal.Trim ().ToLower () == "true";
-					return _list.Where (line => (line [_filterCol] as JSONBoolean).GetBool () == value);
+					bool value = StringParsers.ParseBool (_filterVal);
+					return _list.Where (line => ((JSONBoolean) line [_filterCol]).GetBool () == value);
 				}
 
@@ -143,5 +143,5 @@
 					//Log.Out ("GetPlayerList: Filter on String with Regex '" + _filterVal + "'");
 					Regex matcher = new Regex (_filterVal, RegexOptions.IgnoreCase);
-					return _list.Where (line => matcher.IsMatch ((line [_filterCol] as JSONString).GetString ()));
+					return _list.Where (line => matcher.IsMatch (((JSONString) line [_filterCol]).GetString ()));
 				}
 			}
@@ -185,5 +185,5 @@
 
 				return _list.Where (delegate (JSONObject line) {
-					double objVal = (line [_filterCol] as JSONNumber).GetDouble ();
+					double objVal = ((JSONNumber) line [_filterCol]).GetDouble ();
 					switch (matchType) {
 						case NumberMatchType.Greater:
@@ -216,16 +216,16 @@
 				if (colType == typeof (JSONNumber)) {
 					if (_ascending) {
-						return _list.OrderBy (line => (line [_sortCol] as JSONNumber).GetDouble ());
-					}
-
-					return _list.OrderByDescending (line => (line [_sortCol] as JSONNumber).GetDouble ());
+						return _list.OrderBy (line => ((JSONNumber) line [_sortCol]).GetDouble ());
+					}
+
+					return _list.OrderByDescending (line => ((JSONNumber) line [_sortCol]).GetDouble ());
 				}
 
 				if (colType == typeof (JSONBoolean)) {
 					if (_ascending) {
-						return _list.OrderBy (line => (line [_sortCol] as JSONBoolean).GetBool ());
-					}
-
-					return _list.OrderByDescending (line => (line [_sortCol] as JSONBoolean).GetBool ());
+						return _list.OrderBy (line => ((JSONBoolean) line [_sortCol]).GetBool ());
+					}
+
+					return _list.OrderByDescending (line => ((JSONBoolean) line [_sortCol]).GetBool ());
 				}
 
Index: binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs	(revision 326)
@@ -31,5 +31,5 @@
 
 				if (listOffline || p.IsOnline) {
-					ulong player_steam_ID = 0L;
+					ulong player_steam_ID;
 					if (!ulong.TryParse (sid, out player_steam_ID)) {
 						player_steam_ID = 0L;
Index: binary-improvements/MapRendering/Web/API/GetPlayersOnline.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayersOnline.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/API/GetPlayersOnline.cs	(revision 326)
@@ -41,5 +41,5 @@
 				p.Add ("totalplaytime", new JSONNumber (player != null ? player.TotalPlayTime : -1));
 				p.Add ("lastonline", new JSONString (player != null ? player.LastOnline.ToString ("s") : string.Empty));
-				p.Add ("ping", new JSONNumber (ci != null ? ci.ping : -1));
+				p.Add ("ping", new JSONNumber (ci.ping));
 
 				players.Add (p);
Index: binary-improvements/MapRendering/Web/API/WebAPI.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/WebAPI.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/API/WebAPI.cs	(revision 326)
@@ -5,4 +5,10 @@
 namespace AllocsFixes.NetConnections.Servers.Web.API {
 	public abstract class WebAPI {
+		public readonly string Name;
+
+		protected WebAPI () {
+			Name = GetType ().Name;
+		}
+
 		public static void WriteJSON (HttpListenerResponse resp, JSONNode root) {
 			StringBuilder sb = new StringBuilder ();
Index: binary-improvements/MapRendering/Web/ConnectionHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/ConnectionHandler.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/ConnectionHandler.cs	(revision 326)
@@ -5,9 +5,4 @@
 	public class ConnectionHandler {
 		private readonly Dictionary<string, WebConnection> connections = new Dictionary<string, WebConnection> ();
-		private Web parent;
-
-		public ConnectionHandler (Web _parent) {
-			parent = _parent;
-		}
 
 		public WebConnection IsLoggedIn (string _sessionId, string _endpoint) {
Index: binary-improvements/MapRendering/Web/Handlers/ApiHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/Handlers/ApiHandler.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/Handlers/ApiHandler.cs	(revision 326)
@@ -7,5 +7,5 @@
 namespace AllocsFixes.NetConnections.Servers.Web.Handlers {
 	public class ApiHandler : PathHandler {
-		private readonly Dictionary<string, WebAPI> apis = new Dictionary<string, WebAPI> ();
+		private readonly Dictionary<string, WebAPI> apis = new CaseInsensitiveStringDictionary<WebAPI> ();
 		private readonly string staticPart;
 
@@ -18,5 +18,5 @@
 					if (ctor != null) {
 						WebAPI apiInstance = (WebAPI) ctor.Invoke (new object [0]);
-						addApi (t.Name.ToLower (), apiInstance);
+						addApi (apiInstance.Name, apiInstance);
 					}
 				}
@@ -52,18 +52,17 @@
 			}
 
-			foreach (KeyValuePair<string, WebAPI> kvp in apis) {
-				if (apiName.StartsWith (kvp.Key)) {
-					try {
-						kvp.Value.HandleRequest (req, resp, user, permissionLevel);
-						return;
-					} catch (Exception e) {
-						Log.Error ("Error in ApiHandler.HandleRequest(): Handler {0} threw an exception:", kvp.Key);
-						Log.Exception (e);
-						resp.StatusCode = (int) HttpStatusCode.InternalServerError;
-						return;
-					}
+			WebAPI api;
+			if (apis.TryGetValue (apiName, out api)) {
+				try {
+					api.HandleRequest (req, resp, user, permissionLevel);
+					return;
+				} catch (Exception e) {
+					Log.Error ("Error in ApiHandler.HandleRequest(): Handler {0} threw an exception:", api.Name);
+					Log.Exception (e);
+					resp.StatusCode = (int) HttpStatusCode.InternalServerError;
+					return;
 				}
 			}
-
+			
 			Log.Out ("Error in ApiHandler.HandleRequest(): No handler found for API \"" + apiName + "\"");
 			resp.StatusCode = (int) HttpStatusCode.NotFound;
Index: binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs	(revision 326)
@@ -37,5 +37,5 @@
 			requestFileName = requestFileName.Remove (requestFileName.LastIndexOf ('.'));
 
-			if (icons.ContainsKey (requestFileName) && req.Url.AbsolutePath.ToLower ().EndsWith (".png")) {
+			if (icons.ContainsKey (requestFileName) && req.Url.AbsolutePath.EndsWith (".png", StringComparison.OrdinalIgnoreCase)) {
 				resp.ContentType = MimeType.GetMimeType (".png");
 
@@ -128,5 +128,5 @@
 							foreach (string file in Directory.GetFiles (modIconsPath)) {
 								try {
-									if (file.ToLower ().EndsWith (".png")) {
+									if (file.EndsWith (".png", StringComparison.OrdinalIgnoreCase)) {
 										string name = Path.GetFileNameWithoutExtension (file);
 										Texture2D tex = new Texture2D (1, 1, TextureFormat.ARGB32, false);
Index: binary-improvements/MapRendering/Web/LogBuffer.cs
===================================================================
--- binary-improvements/MapRendering/Web/LogBuffer.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/LogBuffer.cs	(revision 326)
@@ -15,4 +15,10 @@
 
 		private int listOffset;
+
+		public static void Init () {
+			if (instance == null) {
+				instance = new LogBuffer ();
+			};
+		}
 
 		private LogBuffer () {
Index: binary-improvements/MapRendering/Web/OpenID.cs
===================================================================
--- binary-improvements/MapRendering/Web/OpenID.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/OpenID.cs	(revision 326)
@@ -87,5 +87,5 @@
 						}
 
-						if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot && chainEl.Certificate == caCert) {
+						if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot && chainEl.Certificate.Equals (caCert)) {
 							// This status is about the cert being an untrusted root certificate but the certificate is one of those we added, ignore
 							continue;
@@ -149,5 +149,5 @@
 
 			string steamIdString = getValue (_req, "openid.claimed_id");
-			ulong steamId = 0;
+			ulong steamId;
 			Match steamIdMatch = steamIdUrlMatcher.Match (steamIdString);
 			if (steamIdMatch.Success) {
@@ -190,5 +190,5 @@
 
 			HttpWebResponse response = (HttpWebResponse) request.GetResponse ();
-			string responseString = null;
+			string responseString;
 			using (Stream st = response.GetResponseStream ()) {
 				using (StreamReader str = new StreamReader (st)) {
@@ -197,5 +197,5 @@
 			}
 
-			if (responseString.ToLower ().Contains ("is_valid:true")) {
+			if (responseString.ContainsCaseInsensitive ("is_valid:true")) {
 				return steamId;
 			}
Index: binary-improvements/MapRendering/Web/Web.cs
===================================================================
--- binary-improvements/MapRendering/Web/Web.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/Web.cs	(revision 326)
@@ -107,5 +107,5 @@
 				);
 
-				connectionHandler = new ConnectionHandler (this);
+				connectionHandler = new ConnectionHandler ();
 
 				_listener.Prefixes.Add (string.Format ("http://*:{0}/", webPort + 2));
@@ -149,82 +149,84 @@
 
 		private void HandleRequest (IAsyncResult result) {
-			if (_listener.IsListening) {
-				Interlocked.Increment (ref handlingCount);
-				Interlocked.Increment (ref currentHandlers);
+			if (!_listener.IsListening) {
+				return;
+			}
+
+			Interlocked.Increment (ref handlingCount);
+			Interlocked.Increment (ref currentHandlers);
 
 //				MicroStopwatch msw = new MicroStopwatch ();
-				HttpListenerContext ctx = _listener.EndGetContext (result);
-				_listener.BeginGetContext (HandleRequest, _listener);
-				try {
-					HttpListenerRequest request = ctx.Request;
-					HttpListenerResponse response = ctx.Response;
-					response.SendChunked = false;
-
-					response.ProtocolVersion = new Version ("1.1");
-
-					WebConnection conn;
-					int permissionLevel = DoAuthentication (request, out conn);
-
-
-					//Log.Out ("Login status: conn!=null: {0}, permissionlevel: {1}", conn != null, permissionLevel);
-
-
-					if (conn != null) {
-						Cookie cookie = new Cookie ("sid", conn.SessionID, "/");
-						cookie.Expired = false;
-						cookie.Expires = new DateTime (2020, 1, 1);
-						cookie.HttpOnly = true;
-						cookie.Secure = false;
-						response.AppendCookie (cookie);
-					}
-
-					// No game yet -> fail request
-					if (GameManager.Instance.World == null) {
-						response.StatusCode = (int) HttpStatusCode.ServiceUnavailable;
-						return;
-					}
-
-					if (request.Url.AbsolutePath.Length < 2) {
-						handlers ["/index.htm"].HandleRequest (request, response, conn, permissionLevel);
-						return;
-					} else {
-						foreach (KeyValuePair<string, PathHandler> kvp in handlers) {
-							if (request.Url.AbsolutePath.StartsWith (kvp.Key)) {
-								if (!kvp.Value.IsAuthorizedForHandler (conn, permissionLevel)) {
-									response.StatusCode = (int) HttpStatusCode.Forbidden;
-									if (conn != null) {
-										//Log.Out ("Web.HandleRequest: user '{0}' not allowed to access '{1}'", conn.SteamID, kvp.Value.ModuleName);
-									}
-								} else {
-									kvp.Value.HandleRequest (request, response, conn, permissionLevel);
+			HttpListenerContext ctx = _listener.EndGetContext (result);
+			_listener.BeginGetContext (HandleRequest, _listener);
+			try {
+				HttpListenerRequest request = ctx.Request;
+				HttpListenerResponse response = ctx.Response;
+				response.SendChunked = false;
+
+				response.ProtocolVersion = new Version ("1.1");
+
+				WebConnection conn;
+				int permissionLevel = DoAuthentication (request, out conn);
+
+
+				//Log.Out ("Login status: conn!=null: {0}, permissionlevel: {1}", conn != null, permissionLevel);
+
+
+				if (conn != null) {
+					Cookie cookie = new Cookie ("sid", conn.SessionID, "/");
+					cookie.Expired = false;
+					cookie.Expires = new DateTime (2020, 1, 1);
+					cookie.HttpOnly = true;
+					cookie.Secure = false;
+					response.AppendCookie (cookie);
+				}
+
+				// No game yet -> fail request
+				if (GameManager.Instance.World == null) {
+					response.StatusCode = (int) HttpStatusCode.ServiceUnavailable;
+					return;
+				}
+
+				if (request.Url.AbsolutePath.Length < 2) {
+					handlers ["/index.htm"].HandleRequest (request, response, conn, permissionLevel);
+					return;
+				} else {
+					foreach (KeyValuePair<string, PathHandler> kvp in handlers) {
+						if (request.Url.AbsolutePath.StartsWith (kvp.Key)) {
+							if (!kvp.Value.IsAuthorizedForHandler (conn, permissionLevel)) {
+								response.StatusCode = (int) HttpStatusCode.Forbidden;
+								if (conn != null) {
+									//Log.Out ("Web.HandleRequest: user '{0}' not allowed to access '{1}'", conn.SteamID, kvp.Value.ModuleName);
 								}
-
-								return;
+							} else {
+								kvp.Value.HandleRequest (request, response, conn, permissionLevel);
 							}
+
+							return;
 						}
 					}
-
-					// Not really relevant for non-debugging purposes:
-					//Log.Out ("Error in Web.HandleRequest(): No handler found for path \"" + request.Url.AbsolutePath + "\"");
-					response.StatusCode = (int) HttpStatusCode.NotFound;
-				} catch (IOException e) {
-					if (e.InnerException is SocketException) {
-						Log.Out ("Error in Web.HandleRequest(): Remote host closed connection: " +
-						         e.InnerException.Message);
-					} else {
-						Log.Out ("Error (IO) in Web.HandleRequest(): " + e);
-					}
-				} catch (Exception e) {
-					Log.Out ("Error in Web.HandleRequest(): " + e);
-				} finally {
-					if (ctx != null && !ctx.Response.SendChunked) {
-						ctx.Response.Close ();
-					}
+				}
+
+				// Not really relevant for non-debugging purposes:
+				//Log.Out ("Error in Web.HandleRequest(): No handler found for path \"" + request.Url.AbsolutePath + "\"");
+				response.StatusCode = (int) HttpStatusCode.NotFound;
+			} catch (IOException e) {
+				if (e.InnerException is SocketException) {
+					Log.Out ("Error in Web.HandleRequest(): Remote host closed connection: " +
+					         e.InnerException.Message);
+				} else {
+					Log.Out ("Error (IO) in Web.HandleRequest(): " + e);
+				}
+			} catch (Exception e) {
+				Log.Out ("Error in Web.HandleRequest(): " + e);
+			} finally {
+				if (ctx != null && !ctx.Response.SendChunked) {
+					ctx.Response.Close ();
+				}
 
 //					msw.Stop ();
 //					totalHandlingTime += msw.ElapsedMicroseconds;
 //					Log.Out ("Web.HandleRequest(): Took {0} µs", msw.ElapsedMicroseconds);
-					Interlocked.Decrement (ref currentHandlers);
-				}
+				Interlocked.Decrement (ref currentHandlers);
 			}
 		}
Index: binary-improvements/MapRendering/Web/WebConnection.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebConnection.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/WebConnection.cs	(revision 326)
@@ -6,5 +6,5 @@
 	public class WebConnection : ConsoleConnectionAbstract {
 		private readonly DateTime login;
-		private readonly List<string> outputLines = new List<string> ();
+//		private readonly List<string> outputLines = new List<string> ();
 		private DateTime lastAction;
 		private readonly string conDescription;
@@ -30,17 +30,12 @@
 
 		public static bool CanViewAllPlayers (int _permissionLevel) {
-			bool val = false;
+			const int defaultPermissionLevel = 0;
 
-			try {
-				const int defaultPermissionLevel = 0;
+			bool val = _permissionLevel <= defaultPermissionLevel;
 
-				val = _permissionLevel <= defaultPermissionLevel;
-
-				foreach (WebPermissions.WebModulePermission wap in WebPermissions.Instance.GetModules ()) {
-					if (wap.module.Trim ().ToLower () == "webapi.viewallplayers") {
-						val = _permissionLevel <= wap.permissionLevel;
-					}
+			foreach (WebPermissions.WebModulePermission wap in WebPermissions.Instance.GetModules ()) {
+				if (wap.module.EqualsCaseInsensitive ("webapi.viewallplayers")) {
+					val = _permissionLevel <= wap.permissionLevel;
 				}
-			} catch {
 			}
 
@@ -49,17 +44,12 @@
 
 		public static bool CanViewAllClaims (int _permissionLevel) {
-			bool val = false;
+			const int defaultPermissionLevel = 0;
 
-			try {
-				const int defaultPermissionLevel = 0;
+			bool val = _permissionLevel <= defaultPermissionLevel;
 
-				val = _permissionLevel <= defaultPermissionLevel;
-
-				foreach (WebPermissions.WebModulePermission wap in WebPermissions.Instance.GetModules ()) {
-					if (wap.module.Trim ().ToLower () == "webapi.viewallclaims") {
-						val = _permissionLevel <= wap.permissionLevel;
-					}
+			foreach (WebPermissions.WebModulePermission wap in WebPermissions.Instance.GetModules ()) {
+				if (wap.module.EqualsCaseInsensitive ("webapi.viewallclaims")) {
+					val = _permissionLevel <= wap.permissionLevel;
 				}
-			} catch {
 			}
 
@@ -76,9 +66,9 @@
 
 		public override void SendLine (string _text) {
-			outputLines.Add (_text);
+//			outputLines.Add (_text);
 		}
 
 		public override void SendLines (List<string> _output) {
-			outputLines.AddRange (_output);
+//			outputLines.AddRange (_output);
 		}
 
Index: binary-improvements/MapRendering/Web/WebPermissions.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebPermissions.cs	(revision 325)
+++ binary-improvements/MapRendering/Web/WebPermissions.cs	(revision 326)
@@ -12,8 +12,8 @@
 			new Dictionary<string, WebModulePermission> ();
 
-		private Dictionary<string, AdminToken> admintokens;
+		private readonly Dictionary<string, AdminToken> admintokens = new CaseInsensitiveStringDictionary<AdminToken> ();
 		private FileSystemWatcher fileWatcher;
 
-		private Dictionary<string, WebModulePermission> modules;
+		private readonly Dictionary<string, WebModulePermission> modules = new CaseInsensitiveStringDictionary<WebModulePermission> ();
 
 		public WebPermissions () {
@@ -49,6 +49,7 @@
 
 		public WebModulePermission GetModulePermission (string _module) {
-			if (modules.ContainsKey (_module.ToLower ())) {
-				return modules [_module.ToLower ()];
+			WebModulePermission result;
+			if (modules.TryGetValue (_module, out result)) {
+				return result;
 			}
 
@@ -83,5 +84,5 @@
 		public AdminToken[] GetAdmins () {
 			AdminToken[] result = new AdminToken[admintokens.Count];
-			admintokens.Values.CopyTo (result, 0);
+			admintokens.CopyValuesTo (result);
 			return result;
 		}
@@ -90,5 +91,5 @@
 		// Commands
 		public void AddModulePermission (string _module, int _permissionLevel, bool _save = true) {
-			WebModulePermission p = new WebModulePermission (_module.ToLower (), _permissionLevel);
+			WebModulePermission p = new WebModulePermission (_module, _permissionLevel);
 			lock (this) {
 				modules [_module] = p;
@@ -100,13 +101,15 @@
 
 		public void AddKnownModule (string _module, int _defaultPermission) {
-			if (!string.IsNullOrEmpty (_module)) {
-				lock (this) {
-					if (!IsKnownModule (_module)) {
-						knownModules.Add (_module, new WebModulePermission (_module, _defaultPermission));
-					}
-
-					if (_defaultPermission > 0 && !modules.ContainsKey (_module.ToLower ())) {
-						AddModulePermission (_module, _defaultPermission);
-					}
+			if (string.IsNullOrEmpty (_module)) {
+				return;
+			}
+
+			lock (this) {
+				if (!IsKnownModule (_module)) {
+					knownModules.Add (_module, new WebModulePermission (_module, _defaultPermission));
+				}
+
+				if (_defaultPermission > 0 && !modules.ContainsKey (_module)) {
+					AddModulePermission (_module, _defaultPermission);
 				}
 			}
@@ -114,16 +117,17 @@
 
 		public bool IsKnownModule (string _module) {
-			if (!string.IsNullOrEmpty (_module)) {
-				lock (this) {
-					return knownModules.ContainsKey (_module);
-				}
-			}
-
-			return false;
+			if (string.IsNullOrEmpty (_module)) {
+				return false;
+			}
+
+			lock (this) {
+				return knownModules.ContainsKey (_module);
+			}
+
 		}
 
 		public void RemoveModulePermission (string _module, bool _save = true) {
 			lock (this) {
-				modules.Remove (_module.ToLower ());
+				modules.Remove (_module);
 				if (_save) {
 					Save ();
@@ -174,6 +178,6 @@
 
 		public void Load () {
-			admintokens = new Dictionary<string, AdminToken> ();
-			modules = new Dictionary<string, WebModulePermission> ();
+			admintokens.Clear ();
+			modules.Clear ();
 
 			if (!Utils.FileExists (GetFullPath ())) {
@@ -190,5 +194,5 @@
 				xmlDoc.Load (GetFullPath ());
 			} catch (XmlException e) {
-				Log.Error (string.Format ("Failed loading permissions file: {0}", e.Message));
+				Log.Error ("Failed loading permissions file: " + e.Message);
 				return;
 			}
@@ -196,4 +200,9 @@
 			XmlNode adminToolsNode = xmlDoc.DocumentElement;
 
+			if (adminToolsNode == null) {
+				Log.Error ("Failed loading permissions file: No DocumentElement found");
+				return;
+			}
+			
 			foreach (XmlNode childNode in adminToolsNode.ChildNodes) {
 				if (childNode.Name == "admintokens") {
@@ -230,5 +239,5 @@
 						string name = lineItem.GetAttribute ("name");
 						string token = lineItem.GetAttribute ("token");
-						int permissionLevel = 2000;
+						int permissionLevel;
 						if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
 							Log.Warning (
@@ -267,5 +276,5 @@
 						}
 
-						int permissionLevel = 0;
+						int permissionLevel;
 						if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
 							Log.Warning (
@@ -275,5 +284,5 @@
 						}
 
-						AddModulePermission (lineItem.GetAttribute ("module").ToLower (), permissionLevel, false);
+						AddModulePermission (lineItem.GetAttribute ("module"), permissionLevel, false);
 					}
 				}
