Index: binary-improvements/7dtd-server-fixes/src/JSON/JSONArray.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/JSON/JSONArray.cs	(revision 162)
+++ binary-improvements/7dtd-server-fixes/src/JSON/JSONArray.cs	(revision 187)
@@ -9,20 +9,67 @@
 		private List<JSONNode> nodes = new List<JSONNode> ();
 
+		public JSONNode this [int index] {
+			get { return nodes [index]; }
+			set { nodes [index] = value; }
+		}
+
+		public int Count {
+			get { return nodes.Count; }
+		}
+
 		public void Add (JSONNode node)
 		{
-			nodes.Add(node);
+			nodes.Add (node);
 		}
 
-		public override string ToString ()
+		public override string ToString (bool prettyPrint = false, int currentLevel = 0)
 		{
 			StringBuilder sb = new StringBuilder ("[");
+			if (prettyPrint)
+				sb.Append ('\n');
 			foreach (JSONNode n in nodes) {
-				sb.Append (n.ToString ());
+				if (prettyPrint)
+					sb.Append (new String ('\t', currentLevel + 1));
+				sb.Append (n.ToString (prettyPrint, currentLevel + 1));
 				sb.Append (",");
+				if (prettyPrint)
+					sb.Append ('\n');
 			}
 			if (sb.Length > 1)
-				sb.Remove (sb.Length - 1, 1);
+				sb.Remove (sb.Length - (prettyPrint ? 2 : 1), 1);
+			if (prettyPrint)
+				sb.Append (new String ('\t', currentLevel));
 			sb.Append ("]");
 			return sb.ToString ();
+		}
+
+		public static JSONArray Parse (string json, ref int offset)
+		{
+			//Log.Out ("ParseArray enter (" + offset + ")");
+			JSONArray arr = new JSONArray ();
+
+			bool nextElemAllowed = true;
+			offset++;
+			while (true) {
+				Parser.SkipWhitespace (json, ref offset);
+
+				switch (json [offset]) {
+					case ',':
+						if (!nextElemAllowed) {
+							nextElemAllowed = true;
+							offset++;
+						} else
+							throw new MalformedJSONException ("Could not parse array, found a comma without a value first");
+						break;
+					case ']':
+						offset++;
+						//Log.Out ("JSON:Parsed Array: " + arr.ToString ());
+						return arr;
+					default:
+						arr.Add (Parser.ParseInternal (json, ref offset));
+						nextElemAllowed = false;
+						break;
+				}
+			}
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/JSON/JSONBoolean.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/JSON/JSONBoolean.cs	(revision 162)
+++ binary-improvements/7dtd-server-fixes/src/JSON/JSONBoolean.cs	(revision 187)
@@ -12,7 +12,29 @@
 		}
 
-		public override string ToString ()
+		public bool GetBool ()
+		{
+			return value;
+		}
+
+		public override string ToString (bool prettyPrint = false, int currentLevel = 0)
 		{
 			return value.ToString (System.Globalization.CultureInfo.InvariantCulture).ToLower ();
+		}
+
+		public static JSONBoolean Parse (string json, ref int offset)
+		{
+			//Log.Out ("ParseBool enter (" + offset + ")");
+
+			if (json.Substring (offset, 4).Equals ("true")) {
+				//Log.Out ("JSON:Parsed Bool: true");
+				offset += 4;
+				return new JSONBoolean (true);
+			} else if (json.Substring (offset, 5).Equals ("false")) {
+				//Log.Out ("JSON:Parsed Bool: false");
+				offset += 5;
+				return new JSONBoolean (false);
+			} else {
+				throw new MalformedJSONException ("No valid boolean found");
+			}
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/JSON/JSONNode.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/JSON/JSONNode.cs	(revision 162)
+++ binary-improvements/7dtd-server-fixes/src/JSON/JSONNode.cs	(revision 187)
@@ -5,5 +5,5 @@
 	public abstract class JSONNode
 	{
-		public abstract override string ToString();
+		public abstract string ToString(bool prettyPrint = false, int currentLevel = 0);
 	}
 }
Index: binary-improvements/7dtd-server-fixes/src/JSON/JSONNumber.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/JSON/JSONNumber.cs	(revision 162)
+++ binary-improvements/7dtd-server-fixes/src/JSON/JSONNumber.cs	(revision 187)
@@ -1,3 +1,4 @@
 using System;
+using System.Text;
 
 namespace AllocsFixes.JSON
@@ -5,14 +6,103 @@
 	public class JSONNumber : JSONNode
 	{
-		private float value;
+		private double value;
 
-		public JSONNumber (float value)
+		public JSONNumber (double value)
 		{
 			this.value = value;
 		}
 
-		public override string ToString ()
+		public double GetDouble ()
+		{
+			return value;
+		}
+
+		public int GetInt ()
+		{
+			return (int)Math.Round(value);
+		}
+
+		public override string ToString (bool prettyPrint = false, int currentLevel = 0)
 		{
 			return value.ToString (System.Globalization.CultureInfo.InvariantCulture);
+		}
+
+		public static JSONNumber Parse (string json, ref int offset)
+		{
+			//Log.Out ("ParseNumber enter (" + offset + ")");
+			StringBuilder sbNum = new StringBuilder ();
+			StringBuilder sbExp = null;
+			bool hasDec = false;
+			bool hasExp = false;
+			while (offset < json.Length) {
+				if (json [offset] >= '0' && json [offset] <= '9') {
+					if (hasExp)
+						sbExp.Append (json [offset]);
+					else
+						sbNum.Append (json [offset]);
+				} else if (json [offset] == '.') {
+					if (hasExp) {
+						throw new MalformedJSONException ("Decimal separator in exponent");
+					} else {
+						if (hasDec)
+							throw new MalformedJSONException ("Multiple decimal separators in number found");
+						else if (sbNum.Length == 0) {
+							throw new MalformedJSONException ("No leading digits before decimal separator found");
+						} else {
+							sbNum.Append ('.');
+							hasDec = true;
+						}
+					}
+				} else	if (json [offset] == '-') {
+					if (hasExp) {
+						if (sbExp.Length > 0)
+							throw new MalformedJSONException ("Negative sign in exponent after digits");
+						else
+							sbExp.Append (json [offset]);
+					} else {
+						if (sbNum.Length > 0)
+							throw new MalformedJSONException ("Negative sign in mantissa after digits");
+						else
+							sbNum.Append (json [offset]);
+					}
+				} else if (json [offset] == 'e' || json [offset] == 'E') {
+					if (hasExp)
+						throw new MalformedJSONException ("Multiple exponential markers in number found");
+					else if (sbNum.Length == 0) {
+						throw new MalformedJSONException ("No leading digits before exponential marker found");
+					} else {
+						sbExp = new StringBuilder ();
+						hasExp = true;
+					}
+				} else if (json [offset] == '+') {
+					if (hasExp) {
+						if (sbExp.Length > 0)
+							throw new MalformedJSONException ("Positive sign in exponent after digits");
+						else
+							sbExp.Append (json [offset]);
+					} else {
+						throw new MalformedJSONException ("Positive sign in mantissa found");
+					}
+				} else {
+					double number;
+					if (!double.TryParse (sbNum.ToString (), out number)) {
+						throw new MalformedJSONException ("Mantissa is not a valid decimal (\"" + sbNum.ToString () + "\")");
+					}
+
+					if (hasExp) {
+						int exp;
+						if (!int.TryParse (sbExp.ToString (), out exp)) {
+							throw new MalformedJSONException ("Exponent is not a valid integer (\"" + sbExp.ToString () + "\")");
+						}
+
+						number = number * Math.Pow (10, exp);
+					}
+
+					//Log.Out ("JSON:Parsed Number: " + number.ToString ());
+					return new JSONNumber (number);
+				}
+				offset++;
+			}
+			throw new MalformedJSONException ("End of JSON reached before parsing number finished");
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/JSON/JSONObject.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/JSON/JSONObject.cs	(revision 162)
+++ binary-improvements/7dtd-server-fixes/src/JSON/JSONObject.cs	(revision 187)
@@ -9,4 +9,22 @@
 		private Dictionary<string, JSONNode> nodes = new Dictionary<string, JSONNode> ();
 
+		public JSONNode this [string name] {
+			get { return nodes [name]; }
+			set { nodes [name] = value; }
+		}
+
+		public int Count {
+			get { return nodes.Count; }
+		}
+
+		public List<string> Keys {
+			get { return new List<string> (nodes.Keys); }
+		}
+
+		public bool ContainsKey (string name)
+		{
+			return nodes.ContainsKey (name);
+		}
+
 		public void Add (string name, JSONNode node)
 		{
@@ -14,16 +32,66 @@
 		}
 
-		public override string ToString ()
+		public override string ToString (bool prettyPrint = false, int currentLevel = 0)
 		{
 			StringBuilder sb = new StringBuilder ("{");
+			if (prettyPrint)
+				sb.Append ('\n');
 			foreach (KeyValuePair<string, JSONNode> kvp in nodes) {
+				if (prettyPrint)
+					sb.Append (new String ('\t', currentLevel + 1));
 				sb.Append (String.Format ("\"{0}\":", kvp.Key));
-				sb.Append (kvp.Value.ToString ());
+				if (prettyPrint)
+					sb.Append (" ");
+				sb.Append (kvp.Value.ToString (prettyPrint, currentLevel + 1));
 				sb.Append (",");
+				if (prettyPrint)
+					sb.Append ('\n');
 			}
 			if (sb.Length > 1)
-				sb.Remove (sb.Length - 1, 1);
+				sb.Remove (sb.Length - (prettyPrint ? 2 : 1), 1);
+			if (prettyPrint)
+				sb.Append (new String ('\t', currentLevel));
 			sb.Append ("}");
 			return sb.ToString ();
+		}
+
+		public static JSONObject Parse (string json, ref int offset)
+		{
+			//Log.Out ("ParseObject enter (" + offset + ")");
+			JSONObject obj = new JSONObject ();
+
+			bool nextElemAllowed = true;
+			offset++;
+			while (true) {
+				Parser.SkipWhitespace (json, ref offset);
+				switch (json [offset]) {
+					case '"':
+						if (nextElemAllowed) {
+							JSONString key = JSONString.Parse (json, ref offset);
+							Parser.SkipWhitespace (json, ref offset);
+							if (json [offset] != ':') {
+								throw new MalformedJSONException ("Could not parse object, missing colon (\":\") after key");
+							}
+							offset++;
+							JSONNode val = Parser.ParseInternal (json, ref offset);
+							obj.Add (key.GetString (), val);
+							nextElemAllowed = false;
+						} else {
+							throw new MalformedJSONException ("Could not parse object, found new key without a separating comma");
+						}
+						break;
+					case ',':
+						if (!nextElemAllowed) {
+							nextElemAllowed = true;
+							offset++;
+						} else
+							throw new MalformedJSONException ("Could not parse object, found a comma without a key/value pair first");
+						break;
+					case '}':
+						offset++;
+						//Log.Out ("JSON:Parsed Object: " + obj.ToString ());
+						return obj;
+				}
+			}
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/JSON/JSONString.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/JSON/JSONString.cs	(revision 162)
+++ binary-improvements/7dtd-server-fixes/src/JSON/JSONString.cs	(revision 187)
@@ -13,5 +13,10 @@
 		}
 
-		public override string ToString ()
+		public string GetString ()
+		{
+			return value;
+		}
+
+		public override string ToString (bool prettyPrint = false, int currentLevel = 0)
 		{
 			if (value == null || value.Length == 0) {
@@ -61,4 +66,53 @@
 		}
 
+		public static JSONString Parse (string json, ref int offset)
+		{
+			//Log.Out ("ParseString enter (" + offset + ")");
+			StringBuilder sb = new StringBuilder ();
+			offset++;
+			while (offset < json.Length) {
+				switch (json [offset]) {
+					case '\\':
+						offset++;
+						switch (json [offset]) {
+							case '\\':
+							case '"':
+							case '/':
+								sb.Append (json [offset]);
+								break;
+							case 'b':
+								sb.Append ('\b');
+								break;
+							case 't':
+								sb.Append ('\t');
+								break;
+							case 'n':
+								sb.Append ('\n');
+								break;
+							case 'f':
+								sb.Append ('\f');
+								break;
+							case 'r':
+								sb.Append ('\r');
+								break;
+							default:
+								sb.Append (json [offset]);
+								break;
+						}
+						offset++;
+						break;
+					case '"':
+						offset++;
+						//Log.Out ("JSON:Parsed String: " + sb.ToString ());
+						return new JSONString (sb.ToString ());
+					default:
+						sb.Append (json [offset]);
+						offset++;
+						break;
+				}
+			}
+			throw new MalformedJSONException ("End of JSON reached before parsing string finished");
+		}
+
 	}
 }
