Index: /binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj
===================================================================
--- /binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 305)
+++ /binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 306)
@@ -83,5 +83,4 @@
     <Compile Include="src\JSON\JSONNull.cs" />
     <Compile Include="src\JSON\MalformedJSONException.cs" />
-    <Compile Include="src\ItemList.cs" />
     <Compile Include="src\FileCache\AbstractCache.cs" />
     <Compile Include="src\FileCache\DirectAccess.cs" />
Index: /binary-improvements/7dtd-server-fixes/ModInfo.xml
===================================================================
--- /binary-improvements/7dtd-server-fixes/ModInfo.xml	(revision 305)
+++ /binary-improvements/7dtd-server-fixes/ModInfo.xml	(revision 306)
@@ -5,5 +5,5 @@
 		<Description value="Common functions" />
 		<Author value="Christian 'Alloc' Illy" />
-		<Version value="14" />
+		<Version value="15" />
 		<Website value="http://7dtd.illy.bz" />
 	</ModInfo>
Index: nary-improvements/7dtd-server-fixes/src/ItemList.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/ItemList.cs	(revision 305)
+++ 	(revision )
@@ -1,72 +1,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace AllocsFixes
-{
-	public class ItemList
-	{
-		private static ItemList instance;
-
-		public static ItemList Instance {
-			get {
-				if (instance == null) {
-					instance = new ItemList ();
-				}
-				return instance;
-			}
-		}
-
-		private ItemList ()
-		{
-		}
-
-		private SortedDictionary<string, ItemValue> items = new SortedDictionary<string, ItemValue> ();
-
-		public List<string> ItemNames {
-			get { return new List<string> (items.Keys); }
-		}
-
-		public ItemValue GetItemValue (string itemName)
-		{
-			if (items.ContainsKey (itemName)) {
-				return items [itemName].Clone ();
-			} else {
-				itemName = itemName.ToLower ();
-				foreach (KeyValuePair<string, ItemValue> kvp in items) {
-					if (kvp.Key.ToLower ().Equals (itemName)) {
-						return kvp.Value.Clone ();
-					}
-				}
-				return null;
-			}
-		}
-
-		public void Init ()
-		{
-			NGuiInvGridCreativeMenu cm = new NGuiInvGridCreativeMenu ();
-			foreach (ItemStack invF in cm.GetAllItems()) {
-				ItemClass ib = ItemClass.list [invF.itemValue.type];
-				string name = ib.GetItemName ();
-				if (name != null && name.Length > 0) {
-					if (!items.ContainsKey (name)) {
-						items.Add (name, invF.itemValue);
-					} else {
-						//Log.Out ("Item \"" + name + "\" already in list!");
-					}
-				}
-			}
-			foreach (ItemStack invF in cm.GetAllBlocks()) {
-				ItemClass ib = ItemClass.list [invF.itemValue.type];
-				string name = ib.GetItemName ();
-				if (name != null && name.Length > 0) {
-					if (!items.ContainsKey (name)) {
-						items.Add (name, invF.itemValue);
-					} else {
-						//Log.Out ("Item \"" + name + "\" already in list!");
-					}
-				}
-			}
-		}
-	}
-}
-
Index: /binary-improvements/7dtd-server-fixes/src/JSON/JSONString.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/JSON/JSONString.cs	(revision 305)
+++ /binary-improvements/7dtd-server-fixes/src/JSON/JSONString.cs	(revision 306)
@@ -33,5 +33,5 @@
 					case '\\':
 					case '"':
-					case '/':
+//					case '/':
 						sb.Append ('\\');
 						sb.Append (c);
Index: /binary-improvements/7dtd-server-fixes/src/LiveData/Animals.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/LiveData/Animals.cs	(revision 305)
+++ /binary-improvements/7dtd-server-fixes/src/LiveData/Animals.cs	(revision 306)
@@ -6,34 +6,47 @@
     public class Animals
     {
-        public static List<EntityAnimal> List {
-            get {
-                List<EntityAnimal> lst = new List<EntityAnimal> ();
+		public static void Get (List<EntityAnimal> _list) {
+			_list.Clear ();
+			try {
+				List<Entity> entities = GameManager.Instance.World.Entities.list;
+				for (int i = 0; i < entities.Count; i++) {
+					Entity entity = entities [i];
 
-                try {
-                    foreach (object base_entity in GameManager.Instance.World.Entities.list) {
-                        try {
-                            Entity entity = (Entity)base_entity;
+					// Kind of hack-ish, but the game is legitimately setting the base type of animals ('entityType') to enum 0 ('EntityType.Unknown').
+					if ((entity.entityType == EntityType.Animal) || (entity is EntityAnimal)) {
+						EntityAnimal ea = (EntityAnimal)entity;
 
-                            // Kind of hack-ish, but the game is legitimately setting the base type of animals ('entityType') to enum 0 ('EntityType.Unknown').
-                            if ((entity.entityType == EntityType.Animal) || (base_entity.GetType ().ToString ().ToLower ().Contains ("animal"))) {
-                                EntityAnimal ea = (EntityAnimal)entity;
+						if (ea.IsAlive ())
+							_list.Add (ea);
+					}
+				}
+			}
+			catch (Exception e) {
+				Log.Exception (e);
+			}
+		}
 
-                                if (ea.IsAlive ())
-                                    lst.Add (ea);
-                            }
-                        }
-                        catch { }
-                    }
-                }
-                catch { }
+		public static int GetCount () {
+			int count = 0;
+			try {
+				List<Entity> entities = GameManager.Instance.World.Entities.list;
+				for (int i = 0; i < entities.Count; i++) {
+					Entity entity = entities [i];
 
-                return lst;
-            }
-        }
+					// Kind of hack-ish, but the game is legitimately setting the base type of animals ('entityType') to enum 0 ('EntityType.Unknown').
+					if ((entity.entityType == EntityType.Animal) || (entity is EntityAnimal)) {
+						EntityAnimal ea = (EntityAnimal)entity;
 
+						if (ea.IsAlive ())
+							count++;
+					}
+				}
+			}
+			catch (Exception e) {
+				Log.Exception (e);
+			}
+			return count;
+		}
 
-        public static int Count {
-            get { return List.Count; }
-        }
     }
 }
Index: /binary-improvements/7dtd-server-fixes/src/LiveData/Hostiles.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/LiveData/Hostiles.cs	(revision 305)
+++ /binary-improvements/7dtd-server-fixes/src/LiveData/Hostiles.cs	(revision 306)
@@ -4,35 +4,45 @@
 namespace AllocsFixes.LiveData
 {
-    public class Hostiles
-    {
-        public static List<EntityEnemy> List {
-            get {
-                List<EntityEnemy> lst = new List<EntityEnemy> ();
+	public class Hostiles
+	{
+		public static void Get (List<EntityEnemy> _list) {
+			_list.Clear ();
+			try {
+				List<Entity> entities = GameManager.Instance.World.Entities.list;
+				for (int i = 0; i < entities.Count; i++) {
+					Entity entity = entities [i];
 
-                try {
-                    foreach (int ent_id in GameManager.Instance.World.Entities.dict.Keys) {
-                        try {
-                            Entity entity = GameManager.Instance.World.Entities.dict [ent_id];
+					if (entity is EntityEnemy) {
+						if (entity.IsAlive ())
+							_list.Add (entity as EntityEnemy);
+					}
+				}
+			}
+			catch (Exception e) {
+				Log.Exception (e);
+			}
+		}
 
-                            if (entity.entityType == EntityType.Zombie) {
-                                EntityEnemy ee = (EntityEnemy)entity;
+		public static int GetCount () {
+			int count = 0;
+			try {
+				List<Entity> entities = GameManager.Instance.World.Entities.list;
+				for (int i = 0; i < entities.Count; i++) {
+					Entity entity = entities [i];
 
-                                if (ee.IsAlive ())
-                                    lst.Add (ee);
-                            }
-                        }
-                        catch { }
-                    }
-                }
-                catch { }
+					if (entity.entityType == EntityType.Zombie) {
+						EntityEnemy ee = (EntityEnemy)entity;
 
-                return lst;
-            }
-        }
-
-        public static int Count {
-            get { return List.Count; }
-        }
-    }
+						if (ee.IsAlive ())
+							count++;
+					}
+				}
+			}
+			catch (Exception e) {
+				Log.Exception (e);
+			}
+			return count;
+		}
+	}
 }
 
Index: /binary-improvements/7dtd-server-fixes/src/StateManager.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/StateManager.cs	(revision 305)
+++ /binary-improvements/7dtd-server-fixes/src/StateManager.cs	(revision 306)
@@ -9,6 +9,4 @@
 		{
 			try {
-				ItemList.Instance.Init ();
-
 				PersistentData.PersistentContainer.Load ();
 			} catch (Exception e) {
Index: /binary-improvements/AllocsCommands/Commands/Give.cs
===================================================================
--- /binary-improvements/AllocsCommands/Commands/Give.cs	(revision 305)
+++ /binary-improvements/AllocsCommands/Commands/Give.cs	(revision 306)
@@ -39,9 +39,11 @@
 				}
 
-				ItemValue iv = ItemList.Instance.GetItemValue (_params [1]);
-				if (iv == null) {
+				ItemValue iv = ItemClass.GetItem (_params [1], true);
+				if (iv.type == ItemValue.None.type) {
 					SdtdConsole.Instance.Output ("Item not found.");
 					return;
 				}
+
+				iv = new ItemValue (iv.type, true);
 
 				int n = int.MinValue;
@@ -88,5 +90,5 @@
 				ItemStack invField = new ItemStack (iv, n);
 
-				GameManager.Instance.ItemDropServer (invField, p.GetPosition (), Vector3.zero, -1, 50);
+				GameManager.Instance.ItemDropServer (invField, p.GetPosition (), Vector3.zero);
 
 				SdtdConsole.Instance.Output ("Dropped item");
Index: /binary-improvements/AllocsCommands/Commands/ListItems.cs
===================================================================
--- /binary-improvements/AllocsCommands/Commands/ListItems.cs	(revision 305)
+++ /binary-improvements/AllocsCommands/Commands/ListItems.cs	(revision 306)
@@ -16,4 +16,13 @@
 		}
 
+		public override string GetHelp () {
+			return "List all available item names\n" +
+				"Usage:\n" +
+				"   1. listitems <searchString>\n" +
+				"   2. listitems *\n" +
+				"1. List only names that contain the given string.\n" +
+				"2. List all names.";
+		}
+
 		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
@@ -24,13 +33,17 @@
 				}
 
-				int n = 0;
-				foreach (string s in ItemList.Instance.ItemNames) {
-					if (s.ToLower ().Contains (_params [0].ToLower ()) || _params[0].Trim().Equals("*")) {
+				int count = ItemClass.ItemNames.Count;
+				bool showAll = _params[0].Trim().Equals("*");
+
+				int listed = 0;
+				for (int i = 0; i < count; i++) {
+					string s = ItemClass.ItemNames [i];
+					if (showAll || s.IndexOf (_params [0], StringComparison.OrdinalIgnoreCase) >= 0) {
 						SdtdConsole.Instance.Output ("    " + s);
-						n++;
+						listed++;
 					}
 				}
 
-				SdtdConsole.Instance.Output ("Listed " + n + " matching items.");
+				SdtdConsole.Instance.Output ("Listed " + listed + " matching items.");
 			} catch (Exception e) {
 				Log.Out ("Error in ListItems.Run: " + e);
Index: /binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs
===================================================================
--- /binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs	(revision 305)
+++ /binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs	(revision 306)
@@ -15,6 +15,8 @@
 				   "  1. removelandprotection <steamid>\n" +
 				   "  2. removelandprotection <x> <y> <z>\n" +
+				   "  3. removelandprotection nearby [length]\n" +
 				   "1. Remove all land claims owned by the user with the given SteamID\n" +
-				   "2. Remove only the claim block on the exactly given block position";
+				   "2. Remove only the claim block on the exactly given block position\n" +
+				   "3. Remove all claims in a square with edge length of 64 (or the optionally specified size) around the executing player";
 		}
 
@@ -95,10 +97,51 @@
 		{
 			try {
-				if (_params.Count == 1) {
+				if (_senderInfo.RemoteClientInfo != null) {
+					if (_params.Count >= 1 && _params [0].EqualsCaseInsensitive ("nearby")) {
+						_params.Add (_senderInfo.RemoteClientInfo.playerId);
+					}
+				}
+
+				if (_params.Count > 0 && _params [0].EqualsCaseInsensitive ("nearby")) {
+					try {
+						int closeToDistance = 32;
+						if (_params.Count == 3) {
+							if (!int.TryParse (_params[1], out closeToDistance)) {
+								SdtdConsole.Instance.Output ("Given length is not an integer!");
+								return;
+							}
+							closeToDistance /= 2;
+						}
+						ClientInfo ci = ConsoleHelper.ParseParamSteamIdOnline (_params [_params.Count - 1]);
+						EntityPlayer ep = GameManager.Instance.World.Players.dict [ci.entityId];
+						Vector3i closeTo = new Vector3i (ep.GetPosition ());
+						LandClaimList.PositionFilter[] posFilters = new LandClaimList.PositionFilter[] { LandClaimList.CloseToFilter2dRect (closeTo, closeToDistance) };
+						Dictionary<PersistentData.Player, List<Vector3i>> claims = LandClaimList.GetLandClaims (null, posFilters);
+
+						try {
+							List<BlockChangeInfo> changes = new List<BlockChangeInfo> ();
+							foreach (KeyValuePair<PersistentData.Player, List<Vector3i>> kvp in claims) {
+								foreach (Vector3i v in kvp.Value) {
+									BlockChangeInfo bci = new BlockChangeInfo (v, new BlockValue (0), true, false);
+									changes.Add (bci);
+								}
+							}
+							GameManager.Instance.SetBlocksRPC (changes);
+						} catch (Exception e) {
+							SdtdConsole.Instance.Output ("Error removing claims");
+							Log.Out ("Error in RemoveLandProtection.Run: " + e);
+							return;
+						}
+					} catch (Exception e) {
+						SdtdConsole.Instance.Output ("Error getting current player's position");
+						Log.Out ("Error in RemoveLandProtection.Run: " + e);
+						return;
+					}
+				} else if (_params.Count == 1) {
 					removeById (_params [0]);
 				} else if (_params.Count == 3) {
 					removeByPosition (_params);
 				} else {
-					SdtdConsole.Instance.Output ("Usage: removelandprotection <x> <y> <z>  OR  removelandprotection <steamid>");
+					SdtdConsole.Instance.Output ("Illegal parameters");
 				}
 			} catch (Exception e) {
Index: /binary-improvements/AllocsCommands/ModInfo.xml
===================================================================
--- /binary-improvements/AllocsCommands/ModInfo.xml	(revision 305)
+++ /binary-improvements/AllocsCommands/ModInfo.xml	(revision 306)
@@ -5,5 +5,5 @@
 		<Description value="Additional commands for server operation" />
 		<Author value="Christian 'Alloc' Illy" />
-		<Version value="12" />
+		<Version value="13" />
 		<Website value="http://7dtd.illy.bz" />
 	</ModInfo>
Index: /binary-improvements/MapRendering/ModInfo.xml
===================================================================
--- /binary-improvements/MapRendering/ModInfo.xml	(revision 305)
+++ /binary-improvements/MapRendering/ModInfo.xml	(revision 306)
@@ -5,5 +5,5 @@
 		<Description value="Render the game map to image map tiles as it is uncovered" />
 		<Author value="Christian 'Alloc' Illy" />
-		<Version value="19" />
+		<Version value="20" />
 		<Website value="http://7dtd.illy.bz" />
 	</ModInfo>
Index: /binary-improvements/MapRendering/Web/API/ExecuteConsoleCommand.cs
===================================================================
--- /binary-improvements/MapRendering/Web/API/ExecuteConsoleCommand.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/API/ExecuteConsoleCommand.cs	(revision 306)
@@ -15,4 +15,9 @@
 				return;
 			}
+
+			WebCommandResult.ResultType responseType =
+				req.QueryString ["raw"] != null ? WebCommandResult.ResultType.Raw :
+				(req.QueryString ["simple"] != null ? WebCommandResult.ResultType.ResultOnly :
+					WebCommandResult.ResultType.Full);
 
 			string commandline = req.QueryString ["command"];
@@ -36,8 +41,6 @@
 			}
 
-			// TODO: Execute command (store resp as IConsoleConnection instance to deliver response to the single client?)
-
 			resp.SendChunked = true;
-			WebCommandResult wcr = new WebCommandResult (commandPart, argumentsPart, resp);
+			WebCommandResult wcr = new WebCommandResult (commandPart, argumentsPart, responseType, resp);
 			SdtdConsole.Instance.ExecuteAsync (commandline, wcr);
 		}
Index: /binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs
===================================================================
--- /binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs	(revision 306)
@@ -9,10 +9,14 @@
     class GetAnimalsLocation : WebAPI
     {
+		private List<EntityAnimal> animals = new List<EntityAnimal> ();
+
         public override void HandleRequest(HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
         {
             JSONArray animalsJsResult = new JSONArray();
 
-            foreach (EntityAnimal entity in Animals.List)
-            {
+			Animals.Get (animals);
+			for (int i = 0; i < animals.Count; i++)
+			{
+				EntityAnimal entity = animals [i];
                 Vector3i position = new Vector3i(entity.GetPosition());
 
Index: /binary-improvements/MapRendering/Web/API/GetHostileLocation.cs
===================================================================
--- /binary-improvements/MapRendering/Web/API/GetHostileLocation.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/API/GetHostileLocation.cs	(revision 306)
@@ -9,10 +9,14 @@
     class GetHostileLocation : WebAPI
     {
+		private List<EntityEnemy> enemies = new List<EntityEnemy> ();
+
         public override void HandleRequest(HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
         {
             JSONArray hostilesJsResult = new JSONArray();
 
-            foreach (EntityEnemy entity in Hostiles.List)
+			Hostiles.Get (enemies);
+			for (int i = 0; i < enemies.Count; i++)
             {
+				EntityEnemy entity = enemies [i];
                 Vector3i position = new Vector3i(entity.GetPosition());
 
Index: /binary-improvements/MapRendering/Web/API/GetStats.cs
===================================================================
--- /binary-improvements/MapRendering/Web/API/GetStats.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/API/GetStats.cs	(revision 306)
@@ -21,6 +21,6 @@
 
 			result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
-            result.Add ("hostiles", new JSONNumber (Hostiles.Count));
-            result.Add ("animals", new JSONNumber (Animals.Count));
+			result.Add ("hostiles", new JSONNumber (Hostiles.GetCount ()));
+			result.Add ("animals", new JSONNumber (Animals.GetCount ()));
 
 			WriteJSON (resp, result);
Index: /binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs
===================================================================
--- /binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs	(revision 306)
@@ -24,6 +24,6 @@
 
 			result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
-            result.Add ("hostiles", new JSONNumber (Hostiles.Count));
-            result.Add ("animals", new JSONNumber (Animals.Count));
+			result.Add ("hostiles", new JSONNumber (Hostiles.GetCount ()));
+			result.Add ("animals", new JSONNumber (Animals.GetCount ()));
 
 			result.Add ("newlogs", new JSONNumber (LogBuffer.Instance.LatestLine - latestLine));
Index: /binary-improvements/MapRendering/Web/API/WebAPI.cs
===================================================================
--- /binary-improvements/MapRendering/Web/API/WebAPI.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/API/WebAPI.cs	(revision 306)
@@ -7,5 +7,5 @@
 	public abstract class WebAPI
 	{
-		public void WriteJSON (HttpListenerResponse resp, JSON.JSONNode root)
+		public static void WriteJSON (HttpListenerResponse resp, JSON.JSONNode root)
 		{
 			byte[] buf = Encoding.UTF8.GetBytes (root.ToString());
@@ -14,4 +14,13 @@
 			resp.ContentEncoding = Encoding.UTF8;
 			resp.OutputStream.Write (buf, 0, buf.Length);
+		}
+
+		public static void WriteText (HttpListenerResponse _resp, string _text)
+		{
+			byte[] buf = Encoding.UTF8.GetBytes (_text);
+			_resp.ContentLength64 = buf.Length;
+			_resp.ContentType = "text/plain";
+			_resp.ContentEncoding = Encoding.UTF8;
+			_resp.OutputStream.Write (buf, 0, buf.Length);
 		}
 
Index: /binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs
===================================================================
--- /binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs	(revision 306)
@@ -152,5 +152,5 @@
 
 		private void AddIcon (string _name, Texture2D _tex, Dictionary<string, List<Color>> _tintedIcons) {
-			icons.Add (_name + "__FFFFFF", _tex.EncodeToPNG ());
+			icons [_name + "__FFFFFF"] = _tex.EncodeToPNG ();
 
 			if (_tintedIcons.ContainsKey (_name)) {
@@ -166,5 +166,5 @@
 						}
 
-						icons.Add (tintedName, tintedTex.EncodeToPNG ());
+						icons [tintedName] = tintedTex.EncodeToPNG ();
 
 						UnityEngine.Object.Destroy (tintedTex);
Index: /binary-improvements/MapRendering/Web/WebCommandResult.cs
===================================================================
--- /binary-improvements/MapRendering/Web/WebCommandResult.cs	(revision 305)
+++ /binary-improvements/MapRendering/Web/WebCommandResult.cs	(revision 306)
@@ -8,4 +8,5 @@
 using System.Net.Sockets;
 using System.Threading;
+using AllocsFixes.NetConnections.Servers.Web.API;
 
 namespace AllocsFixes.NetConnections.Servers.Web
@@ -13,4 +14,10 @@
 	public class WebCommandResult : IConsoleConnection
 	{
+		public enum ResultType {
+			Full,
+			ResultOnly,
+			Raw
+		}
+
 		public static int handlingCount = 0;
 		public static int currentHandlers = 0;
@@ -20,6 +27,7 @@
 		private string command;
 		private string parameters;
+		private ResultType responseType;
 
-		public WebCommandResult (string _command, string _parameters, HttpListenerResponse _response) {
+		public WebCommandResult (string _command, string _parameters, ResultType _responseType, HttpListenerResponse _response) {
 			Interlocked.Increment (ref handlingCount);
 			Interlocked.Increment (ref currentHandlers);
@@ -28,4 +36,5 @@
 			command = _command;
 			parameters = _parameters;
+			responseType = _responseType;
 		}
 
@@ -38,14 +47,24 @@
 			}
 
-			JSONObject result = new JSONObject ();
-
-			result.Add ("command", new JSONString (command));
-			result.Add ("parameters", new JSONString (parameters));
-			result.Add ("result", new JSONString (sb.ToString ()));
-
 			response.SendChunked = false;
 
 			try {
-				WriteJSON (response, result);
+				if (responseType == ResultType.Raw) {
+					WebAPI.WriteText (response, sb.ToString ());
+				} else {
+					JSONNode result;
+					if (responseType == ResultType.ResultOnly) {
+						result = new JSONString (sb.ToString ());
+					} else {
+						JSONObject resultObj = new JSONObject ();
+
+						resultObj.Add ("command", new JSONString (command));
+						resultObj.Add ("parameters", new JSONString (parameters));
+						resultObj.Add ("result", new JSONString (sb.ToString ()));
+
+						result = resultObj;
+					}
+					WebAPI.WriteJSON (response, result);
+				}
 			} catch (IOException e) {
 				if (e.InnerException is SocketException) {
@@ -62,17 +81,10 @@
 
 				msw.Stop ();
-				totalHandlingTime += msw.ElapsedMicroseconds;
-				Log.Out ("WebCommandResult.SendLines(): Took {0} µs", msw.ElapsedMicroseconds);
+				if (GamePrefs.GetInt (EnumGamePrefs.HideCommandExecutionLog) < 1) {
+					totalHandlingTime += msw.ElapsedMicroseconds;
+					Log.Out ("WebCommandResult.SendLines(): Took {0} µs", msw.ElapsedMicroseconds);
+				}
 				Interlocked.Decrement (ref currentHandlers);
 			}
-		}
-
-		public void WriteJSON (HttpListenerResponse resp, JSON.JSONNode root)
-		{
-			byte[] buf = Encoding.UTF8.GetBytes (root.ToString());
-			resp.ContentLength64 = buf.Length;
-			resp.ContentType = "application/json";
-			resp.ContentEncoding = Encoding.UTF8;
-			resp.OutputStream.Write (buf, 0, buf.Length);
 		}
 
Index: /binary-improvements/server-fixes.userprefs
===================================================================
--- /binary-improvements/server-fixes.userprefs	(revision 305)
+++ /binary-improvements/server-fixes.userprefs	(revision 306)
@@ -1,25 +1,32 @@
 ﻿<Properties>
   <MonoDevelop.Ide.Workspace ActiveConfiguration="Release_Version" />
-  <MonoDevelop.Ide.Workbench ActiveDocument="7dtd-server-fixes/src/ItemList.cs">
+  <MonoDevelop.Ide.Workbench ActiveDocument="MapRendering/Web/API/WebAPI.cs">
     <Files>
       <File FileName="7dtd-server-fixes/ModInfo.xml" Line="1" Column="1" />
-      <File FileName="AllocsCommands/ModInfo.xml" Line="21" Column="21" />
-      <File FileName="MapRendering/ModInfo.xml" Line="7" Column="7" />
-      <File FileName="MapRendering/Web/Web.cs" Line="1" Column="1" />
-      <File FileName="MapRendering/Web/API/ExecuteConsoleCommand.cs" Line="1" Column="1" />
+      <File FileName="AllocsCommands/ModInfo.xml" Line="1" Column="1" />
+      <File FileName="MapRendering/ModInfo.xml" Line="1" Column="1" />
+      <File FileName="MapRendering/Web/Web.cs" Line="10" Column="10" />
+      <File FileName="MapRendering/Web/API/ExecuteConsoleCommand.cs" Line="41" Column="41" />
       <File FileName="MapRendering/Commands/WebTokens.cs" Line="1" Column="1" />
-      <File FileName="MapRendering/API.cs" Line="1" Column="1" />
+      <File FileName="MapRendering/API.cs" Line="48" Column="48" />
       <File FileName="MapRendering/Web/API/GetAllowedCommands.cs" Line="1" Column="1" />
       <File FileName="MapRendering/Web/API/GetPlayerList.cs" Line="1" Column="1" />
-      <File FileName="AllocsCommands/Commands/ListKnownPlayers.cs" Line="1" Column="1" />
-      <File FileName="MapRendering/Web/API/GetHostileLocation.cs" Line="1" Column="1" />
-      <File FileName="7dtd-server-fixes/src/LiveData/Hostiles.cs" Line="1" Column="1" />
+      <File FileName="MapRendering/Web/API/GetHostileLocation.cs" Line="54" Column="54" />
       <File FileName="7dtd-server-fixes/src/PersistentData/Player.cs" Line="1" Column="1" />
-      <File FileName="MapRendering/Web/API/GetPlayersOnline.cs" Line="1" Column="1" />
+      <File FileName="MapRendering/Web/API/GetPlayersOnline.cs" Line="57" Column="57" />
       <File FileName="AllocsCommands/Commands/Give.cs" Line="1" Column="1" />
-      <File FileName="MapRendering/Web/Handlers/ItemIconHandler.cs" Line="1" Column="1" />
-      <File FileName="AllocsCommands/Commands/ShowInventory.cs" Line="107" Column="107" />
-      <File FileName="7dtd-server-fixes/src/ItemList.cs" Line="17" Column="17" />
-      <File FileName="7dtd-server-fixes/src/API.cs" Line="17" Column="17" />
+      <File FileName="MapRendering/Web/Handlers/ItemIconHandler.cs" Line="4" Column="4" />
+      <File FileName="AllocsCommands/Commands/ShowInventory.cs" Line="1" Column="1" />
+      <File FileName="7dtd-server-fixes/src/ItemList.cs" Line="25" Column="25" />
+      <File FileName="7dtd-server-fixes/src/PersistentData/Inventory.cs" Line="1" Column="1" />
+      <File FileName="7dtd-server-fixes/src/AllocsLogFunctions.cs" Line="1" Column="1" />
+      <File FileName="7dtd-server-fixes/src/PersistentData/PersistentContainer.cs" Line="1" Column="1" />
+      <File FileName="7dtd-server-fixes/src/ChatHookExample.cs" Line="1" Column="1" />
+      <File FileName="MapRendering/Commands/WebPermissionsCmd.cs" Line="1" Column="1" />
+      <File FileName="MapRendering/Web/WebPermissions.cs" Line="1" Column="1" />
+      <File FileName="MapRendering/Web/Handlers/ApiHandler.cs" Line="28" Column="28" />
+      <File FileName="MapRendering/Web/WebCommandResult.cs" Line="18" Column="18" />
+      <File FileName="7dtd-server-fixes/src/LiveData/Hostiles.cs" Line="51" Column="51" />
+      <File FileName="MapRendering/Web/API/WebAPI.cs" Line="34" Column="34" />
     </Files>
   </MonoDevelop.Ide.Workbench>
Index: /binary-improvements/webserver/js/map.js
===================================================================
--- /binary-improvements/webserver/js/map.js	(revision 305)
+++ /binary-improvements/webserver/js/map.js	(revision 306)
@@ -93,4 +93,14 @@
 	});
 
+	var densityMismatchMarkerGroupAir = L.markerClusterGroup({
+		maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
+	});
+	var densityMismatchMarkerGroupTerrain = L.markerClusterGroup({
+		maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
+	});
+	var densityMismatchMarkerGroupNonTerrain = L.markerClusterGroup({
+		maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
+	});
+
 
 	var layerControl = L.control.layers({
@@ -117,4 +127,5 @@
 	
 	layerControl.addOverlay (GetRegionLayer (mapinfo), "Region files");
+	layerCount++;
 	
 	var miniMap = new L.Control.MiniMap(tileLayerMiniMap, {
@@ -166,5 +177,5 @@
 		layerCount++;
 	}
-
+	
 	if (layerCount > 0) {
 		layerControl.addTo(map);
@@ -430,4 +441,119 @@
 	}
 
+	
+	
+	
+	
+	
+	
+	
+	
+	// ===============================================================================================
+	// Density markers
+
+	var setDensityMarkers = function(data) {
+		var densityCountAir = 0;
+		var densityCountTerrain = 0;
+		var densityCountNonTerrain = 0;
+
+		densityMismatchMarkerGroupAir.clearLayers();
+		densityMismatchMarkerGroupTerrain.clearLayers();
+		densityMismatchMarkerGroupNonTerrain.clearLayers();
+		
+		
+		var downloadCsv = true;
+		var downloadJson = false;
+		
+		if (downloadJson) {
+			var jsonAir = [];
+			var jsonTerrain = [];
+			var jsonNonTerrain = [];
+		}
+		if (downloadCsv) {
+			var csvAir = "x;y;z;Density;IsTerrain;BvType\r\n";
+			var csvTerrain = "x;y;z;Density;IsTerrain;BvType\r\n";
+			var csvNonTerrain = "x;y;z;Density;IsTerrain;BvType\r\n";
+		}
+		
+		$.each( data, function( key, val ) {
+			if (val.bvtype == 0) {
+				marker = L.marker([val.x, val.z]).bindPopup(
+					"Density Mismatch: <br>Position: " + val.x + " " + val.y + " " + val.z + "<br>Density: " + val.density + "<br>isTerrain: " + val.terrain + "<br>bv.type: " + val.bvtype
+				);
+				densityMismatchMarkerGroupAir.addLayer(marker);
+				densityCountAir++;
+				if (downloadJson) {
+					jsonAir.push (val);
+				}
+				if (downloadCsv) {
+					csvAir += val.x + ";" + val.y + ";" + val.z + ";" + val.density + ";" + val.terrain + ";" + val.bvtype + "\r\n";
+				}
+			} else if (val.terrain) {
+				marker = L.marker([val.x, val.z]).bindPopup(
+					"Density Mismatch: <br>Position: " + val.x + " " + val.y + " " + val.z + "<br>Density: " + val.density + "<br>isTerrain: " + val.terrain + "<br>bv.type: " + val.bvtype
+				);
+				densityMismatchMarkerGroupTerrain.addLayer(marker);
+				densityCountTerrain++;
+				if (downloadJson) {
+					jsonTerrain.push (val);
+				}
+				if (downloadCsv) {
+					csvTerrain += val.x + ";" + val.y + ";" + val.z + ";" + val.density + ";" + val.terrain + ";" + val.bvtype + "\r\n";
+				}
+			} else {
+				marker = L.marker([val.x, val.z]).bindPopup(
+					"Density Mismatch: <br>Position: " + val.x + " " + val.y + " " + val.z + "<br>Density: " + val.density + "<br>isTerrain: " + val.terrain + "<br>bv.type: " + val.bvtype
+				);
+				densityMismatchMarkerGroupNonTerrain.addLayer(marker);
+				densityCountNonTerrain++;
+				if (downloadJson) {
+					jsonNonTerrain.push (val);
+				}
+				if (downloadCsv) {
+					csvNonTerrain += val.x + ";" + val.y + ";" + val.z + ";" + val.density + ";" + val.terrain + ";" + val.bvtype + "\r\n";
+				}
+			}
+		});
+
+		layerControl.addOverlay (densityMismatchMarkerGroupAir, "Density Mismatches Air (<span id='mapControlDensityCountAir'>0</span>)");
+		layerControl.addOverlay (densityMismatchMarkerGroupTerrain, "Density Mismatches Terrain (<span id='mapControlDensityCountTerrain'>0</span>)");
+		layerControl.addOverlay (densityMismatchMarkerGroupNonTerrain, "Density Mismatches NonTerrain (<span id='mapControlDensityCountNonTerrain'>0</span>)");
+
+		$( "#mapControlDensityCountAir" ).text( densityCountAir );
+		$( "#mapControlDensityCountTerrain" ).text( densityCountTerrain );
+		$( "#mapControlDensityCountNonTerrain" ).text( densityCountNonTerrain );
+		
+		if (downloadJson) {
+			download ("air-negative-density.json", JSON.stringify(jsonAir, null, '\t'));
+			download ("terrain-positive-density.json", JSON.stringify(jsonTerrain, null, '\t'));
+			download ("nonterrain-negative-density.json", JSON.stringify(jsonNonTerrain, null, '\t'));
+		}
+		if (downloadCsv) {
+			download ("air-negative-density.csv", csvAir);
+			download ("terrain-positive-density.csv", csvTerrain);
+			download ("nonterrain-negative-density.csv", csvNonTerrain);
+		}
+		
+		function download(filename, text) {
+			var element = document.createElement('a');
+			var file = new Blob([text], {type: 'text/plain'});
+			element.href = URL.createObjectURL(file);
+			element.download = filename;
+
+			element.style.display = 'none';
+			document.body.appendChild(element);
+
+			element.click();
+
+			document.body.removeChild(element);
+		}
+	}
+
+	$.getJSON("densitymismatch.json")
+	.done(setDensityMarkers)
+	.fail(function(jqxhr, textStatus, error) {
+		console.log("Error fetching density mismatch list");
+	});
+
 }
 
