Commits

gde...@USGVL36T22M1.babgsetc.pvt  committed 85dd9dd

Created repository, still need to create JsonValue tests

  • Participants

Comments (0)

Files changed (52)

+syntax: glob
+Json.Serialization/bin/
+Json.Serialization/obj/
+Json.Tests/bin/
+Json.Tests/obj/
+Json/bin/
+Json/obj/
+_ReSharper.Json/

File Json.Serialization/Attributes/JsonIgnoreAttribute.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		JsonIgnoreAttribute.cs
+	Namespace:		Manatee.Json.Serialization.Attributes
+	Class Name:		JsonIgnoreAttribute
+	Purpose:		Applied to properties to indicate that they are not to be
+					serialized.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Manatee.Json.Serialization.Attributes
+{
+	/// <summary>
+	/// Applied to properties to indicate that they are not to be serialized.
+	/// </summary>
+	[AttributeUsage(AttributeTargets.Property)]
+	public class JsonIgnoreAttribute : Attribute
+	{
+	}
+}

File Json.Serialization/Cache/ObjectCasterCache.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		ObjectCasterCache.cs
+	Namespace:		Manatee.Json.Serialization.Cache
+	Class Name:		ObjectCasterCache
+	Purpose:		Maintains a cache of ObjectCaster methods organized by type.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace Manatee.Json.Serialization.Cache
+{
+	class ObjectCasterCache
+	{
+		public readonly static ObjectCasterCache Instance;
+
+		private Dictionary<Type, ObjectCasterMethodPair> _cache;
+
+		static ObjectCasterCache()
+		{
+			Instance = new ObjectCasterCache();
+		}
+		private ObjectCasterCache()
+		{
+			_cache = new Dictionary<Type, ObjectCasterMethodPair>();
+		}
+
+		public MethodInfo GetCaster(Type type)
+		{
+			if (!_cache.ContainsKey(type))
+				_cache.Add(type, new ObjectCasterMethodPair(type));
+			return _cache[type].Caster;
+		}
+
+		public MethodInfo GetTryCaster(Type type)
+		{
+			if (!_cache.ContainsKey(type))
+				_cache.Add(type, new ObjectCasterMethodPair(type));
+			return _cache[type].TryCaster;
+		}
+	}
+}

File Json.Serialization/Cache/ObjectCasterMethodPair.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		ObjectCasterMethodPair.cs
+	Namespace:		Manatee.Json.Serialization.Cache
+	Class Name:		ObjectCasterMethodPair
+	Purpose:		Represents a typed pair of ObjectCaster methods.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Manatee.Json.Serialization.Helpers;
+
+namespace Manatee.Json.Serialization.Cache
+{
+	class ObjectCasterMethodPair
+	{
+		public MethodInfo Caster { get; private set; }
+		public MethodInfo TryCaster { get; private set; }
+
+		public ObjectCasterMethodPair(Type type)
+		{
+			Caster = GetTypedSerializeMethod(type);
+			TryCaster = GetTypedDeserializeMethod(type);
+		}
+
+		private static MethodInfo GetTypedSerializeMethod(Type type)
+		{
+			return typeof(ObjectCaster).GetMethod("Cast").MakeGenericMethod(type);
+		}
+		private static MethodInfo GetTypedDeserializeMethod(Type type)
+		{
+			return typeof(ObjectCaster).GetMethod("TryCast").MakeGenericMethod(type);
+		}
+	}
+}

File Json.Serialization/Cache/SerializerCache.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		SerializerCache.cs
+	Namespace:		Manatee.Json.Serialization.Cache
+	Class Name:		SerializerCache
+	Purpose:		Maintains a cache of JsonSerializers methods organized by type.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace Manatee.Json.Serialization.Cache
+{
+	class SerializerCache
+	{
+		public readonly static SerializerCache Instance;
+
+		private Dictionary<Type, SerializerMethodPair> _cache;
+
+		static SerializerCache()
+		{
+			Instance = new SerializerCache();
+		}
+		private SerializerCache()
+		{
+			_cache = new Dictionary<Type, SerializerMethodPair>();
+		}
+
+		public MethodInfo GetSerializer(Type type)
+		{
+			if (!_cache.ContainsKey(type))
+				_cache.Add(type, new SerializerMethodPair(type));
+			return _cache[type].Serializer;
+		}
+
+		public MethodInfo GetDeserializer(Type type)
+		{
+			if (!_cache.ContainsKey(type))
+				_cache.Add(type, new SerializerMethodPair(type));
+			return _cache[type].Deserializer;
+		}
+	}
+}

File Json.Serialization/Cache/SerializerMethodPair.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		SerializerMethodPair.cs
+	Namespace:		Manatee.Json.Serialization.Cache
+	Class Name:		SerializerMethodPair
+	Purpose:		Represents a typed pair of JsonSerializer methods.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace Manatee.Json.Serialization.Cache
+{
+	class SerializerMethodPair
+	{
+		public MethodInfo Serializer { get; private set; }
+		public MethodInfo Deserializer { get; private set; }
+
+		public SerializerMethodPair(Type type)
+		{
+			Serializer = GetTypedSerializeMethod(type);
+			Deserializer = GetTypedDeserializeMethod(type);
+		}
+
+		private static MethodInfo GetTypedSerializeMethod(Type type)
+		{
+			return typeof(JsonSerializer).GetMethod("Serialize").MakeGenericMethod(type);
+		}
+		private static MethodInfo GetTypedDeserializeMethod(Type type)
+		{
+			return typeof(JsonSerializer).GetMethod("Deserialize").MakeGenericMethod(type);
+		}
+	}
+}

File Json.Serialization/Enumerations/InvalidPropertyKeyBehavior.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		InvalidPropertyKeyBehavior.cs
+	Namespace:		Manatee.Json.Serialization.Enumerations
+	Class Name:		InvalidPropertyKeyBehavior
+	Purpose:		Enumeration of behavior options for the deserializer when a
+					JSON structure is passed which contains invalid property keys.
+
+***************************************************************************************/
+namespace Manatee.Json.Serialization.Enumerations
+{
+	/// <summary>
+	/// Enumeration of behavior options for the deserializer when a JSON structure is passed which
+	/// contains invalid property keys.
+	/// </summary>
+	public enum InvalidPropertyKeyBehavior
+	{
+		/// <summary>
+		/// Deserializer ignores the invalid property keys.
+		/// </summary>
+		DoNothing,
+		/// <summary>
+		/// Deserializer will throw an exception when an invalid property key is found.
+		/// </summary>
+		ThrowException
+	}
+}

File Json.Serialization/Exceptions/NotPrimitiveTypeException.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		NotPrimitiveTypeException.cs
+	Namespace:		Manatee.Json.Serialization.Exceptions
+	Class Name:		NotPrimitiveTypeException
+	Purpose:		Thrown when a request is send to the PrimitiveMapper to map
+					a non-primitive type.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Manatee.Json.Serialization.Exceptions
+{
+	class NotPrimitiveTypeException : Exception
+	{
+		public Type RequestedType { get; private set; }
+		public NotPrimitiveTypeException(Type type)
+			: base(string.Format("Type {0} is not primitive.", type)) {}
+	}
+}

File Json.Serialization/Exceptions/TypeRegistrationException.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		TypeRegistrationException.cs
+	Namespace:		Manatee.Json.Serialization.Exceptions
+	Class Name:		TypeRegistrationException
+	Purpose:		Thrown when incorrectly attempting to register a type for the
+					serializer.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Manatee.Json.Serialization.Exceptions
+{
+	/// <summary>
+	/// Thrown when JsonSerializationTypeRegistry.RegisterType&lt;T&gt;(ToJsonDelegate&lt;T&gt; toJson, FromJsonDelegate&lt;T&gt; fromJson)
+	/// is passed one method and a null.
+	/// </summary>
+	public class TypeRegistrationException : Exception
+	{
+		/// <summary>
+		/// Gets the type.
+		/// </summary>
+		public Type Type { get; private set; }
+
+		/// <summary>
+		/// Initializes a new instance of the TypeRegistrationException class.
+		/// </summary>
+		/// <param name="type">The type.</param>
+		public TypeRegistrationException(Type type)
+			: base(string.Format("Attempted to register type {0} without supplying both an encoder and decoder.", type)) {}
+	}
+}

File Json.Serialization/Helpers/ObjectCaster.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		ObjectCaster.cs
+	Namespace:		Manatee.Json.Serialization.Helpers
+	Class Name:		ObjectCaster
+	Purpose:		Provides type-safe generic casting with additional functionality.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Manatee.Json.Serialization.Cache;
+
+namespace Manatee.Json.Serialization.Helpers
+{
+	internal static class ObjectCaster
+	{
+		public static bool TryCast<T>(object obj, out T result)
+		{
+			try
+			{
+				result = (T)obj;
+				return true;
+			}
+			catch (InvalidCastException)
+			{
+				result = default(T);
+				var parseMethod = typeof(T).GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public,
+													  null, new[] { typeof(string), typeof(T).MakeByRefType() }, null);
+				if (parseMethod == null) return false;
+				var paramsList = new object[] { obj.ToString(), result };
+				if ((bool)parseMethod.Invoke(null, paramsList))
+				{
+					result = (T)paramsList[1];
+					return true;
+				}
+			}
+			catch
+			{
+				result = default(T);
+			}
+			return false;
+		}
+
+		public static T Cast<T>(object obj)
+		{
+			try
+			{
+				return (T) obj;
+			}
+			catch (InvalidCastException)
+			{
+				return default(T);
+			}
+		}
+
+	}
+}

File Json.Serialization/Helpers/PrimitiveMapper.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		PrimitiveMapper.cs
+	Namespace:		Manatee.Json.Serialization.Helpers
+	Class Name:		PrimitiveMapper
+	Purpose:		Provides type-safe generic casting with additional functionality.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Manatee.Json;
+using Manatee.Json.Serialization.Exceptions;
+
+namespace Manatee.Json.Serialization.Helpers
+{
+	internal static class PrimitiveMapper
+	{
+		public static JsonValue MapToJson<T>(T obj)
+		{
+			if (obj is string)
+				return new JsonValue(ObjectCaster.Cast<string>(obj));
+			if (obj is bool)
+				return new JsonValue(ObjectCaster.Cast<bool>(obj));
+			if (obj is Enum)
+				return new JsonValue(ObjectCaster.Cast<int>(obj));
+			double result;
+			return ObjectCaster.TryCast(obj, out result) ? result : JsonValue.Null;
+		}
+
+		public static T MapFromJson<T>(JsonValue json)
+		{
+			if (!IsPrimitive(typeof(T)))
+			    throw new NotPrimitiveTypeException(typeof(T));
+			var value = json.GetValue();
+			T result;
+			ObjectCaster.TryCast(value, out result);
+			return result;
+		}
+
+		public static bool IsPrimitive(Type type)
+		{
+			return (type == typeof (string)) || type.IsPrimitive;
+		}
+
+		private static object GetValue(this JsonValue json)
+		{
+			switch (json.Type)
+			{
+				case JsonValueType.Number:
+					return json.Number;
+				case JsonValueType.String:
+					return json.String;
+				case JsonValueType.Boolean:
+					return json.Boolean;
+				case JsonValueType.Null:
+					return null;
+				default:
+					throw new ArgumentOutOfRangeException();
+			}
+		}
+	}
+}

File Json.Serialization/IJsonCompatible.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		IJsonCompatible.cs
+	Namespace:		Manatee.Json.Serialization
+	Class Name:		IJsonCompatible
+	Purpose:		Provides implementers the option to set a preferred method
+					for serialization.
+
+***************************************************************************************/
+namespace Manatee.Json.Serialization
+{
+	/// <summary>
+	/// Provides implementers the option to set a preferred method for serialization.
+	/// </summary>
+	public interface IJsonCompatible
+	{
+		/// <summary>
+		/// Builds an object from a JsonValue.
+		/// </summary>
+		/// <param name="json">The JsonValue representation of the object.</param>
+		void FromJson(JsonValue json);
+		/// <summary>
+		/// Converts an object to a JsonValue.
+		/// </summary>
+		/// <returns>The JsonValue representation of the object.</returns>
+		JsonValue ToJson();
+	}
+}

File Json.Serialization/JsonSerializationTypeRegistry.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		JsonSerializationTypeRegistry.cs
+	Namespace:		Manatee.Json.Serialization
+	Class Name:		JsonSerializationTypeRegistry
+	Purpose:		Manages methods for serializing object types which do not
+					implement IJsonCompatible and cannot be automatically serialized.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Manatee.Json.Serialization.Exceptions;
+
+namespace Manatee.Json.Serialization
+{
+	/// <summary>
+	/// Manages methods for serializing object types which do not implement IJsonCompatible and
+	/// cannot be automatically serialized.
+	/// </summary>
+	public static class JsonSerializationTypeRegistry
+	{
+		#region Operational Items
+		/// <summary>
+		/// Declares the required signature for a serializer method.
+		/// </summary>
+		/// <typeparam name="T">The type which the method serializes.</typeparam>
+		/// <param name="input">The object to be serialized.</param>
+		/// <returns>The JSON representation of the object.</returns>
+		public delegate JsonValue ToJsonDelegate<T>(T input);
+		/// <summary>
+		/// Declares the required signature for a deserializer method.
+		/// </summary>
+		/// <typeparam name="T">The type which the method deserializes.</typeparam>
+		/// <param name="json">The JSON representation of the object.</param>
+		/// <returns>The deserialized object.</returns>
+		public delegate T FromJsonDelegate<T>(JsonValue json);
+
+		private static readonly Dictionary<Type, Delegate> ToJsonConverters;
+		private static readonly Dictionary<Type, Delegate> FromJsonConverters;
+		private static readonly JsonSerializer _serializer;
+
+		internal static ToJsonDelegate<T> GetToJsonConverter<T>()
+		{
+			var type = typeof (T);
+			return ToJsonConverters.ContainsKey(type) ? (ToJsonDelegate<T>)ToJsonConverters[type] : null;
+		}
+		internal static FromJsonDelegate<T> GetFromJsonConverter<T>()
+		{
+			var type = typeof(T);
+			return FromJsonConverters.ContainsKey(type) ? (FromJsonDelegate<T>)FromJsonConverters[type] : null;
+		}
+
+		static JsonSerializationTypeRegistry()
+		{
+			ToJsonConverters = new Dictionary<Type, Delegate>();
+			FromJsonConverters = new Dictionary<Type, Delegate>();
+			_serializer = new JsonSerializer();
+			RegisterLocalTypes();
+		}
+		private static void RegisterLocalTypes()
+		{
+			RegisterType(EncodeDateTime, DecodeDateTime);
+			RegisterType(EncodeTimeSpan, DecodeTimeSpan);
+		}
+		#endregion
+
+		#region Registration
+		/// <summary>
+		/// Registers an encode/decode method pair for a specific type.
+		/// </summary>
+		/// <typeparam name="T">The type.</typeparam>
+		/// <param name="toJson">The serializer method.</param>
+		/// <param name="fromJson">The deserializer method.</param>
+		public static void RegisterType<T>(ToJsonDelegate<T> toJson, FromJsonDelegate<T> fromJson)
+		{
+			if (((toJson == null) && (fromJson != null)) ||
+				((toJson != null) && (fromJson == null)))
+				throw new TypeRegistrationException(typeof (T));
+			var type = typeof (T);
+			ToJsonConverters[type] = toJson;
+			FromJsonConverters[type] = fromJson;
+		}
+		/// <summary>
+		/// Registers an encode/decode method pair for a nullable type.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the nullable.</typeparam>
+		/// <remarks>To register a nullable int, the call should be RegisterNullableType&lt;int&gt;()</remarks>
+		public static void RegisterNullableType<T>() where T : struct
+		{
+			var type = typeof(T);
+			var nullableType = typeof(T?);
+			var toJson = typeof(JsonSerializationTypeRegistry).GetMethod("EncodeNullable").MakeGenericMethod(type);
+			var fromJson = typeof(JsonSerializationTypeRegistry).GetMethod("DecodeNullable").MakeGenericMethod(type);
+			ToJsonConverters[nullableType] = Delegate.CreateDelegate(typeof(ToJsonDelegate<T?>), toJson);
+			FromJsonConverters[nullableType] = Delegate.CreateDelegate(typeof(FromJsonDelegate<T?>), fromJson);
+		}
+		/// <summary>
+		/// Registers an encode/decode method pair for a typed list.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the list.</typeparam>
+		/// <remarks>To register a list of ints, the call should be RegisterListType&lt;int&gt;()</remarks>
+		public static void RegisterListType<T>()
+		{
+			var type = typeof(T);
+			var listType = typeof (List<T>);
+			var toJson = typeof(JsonSerializationTypeRegistry).GetMethod("EncodeGenericList").MakeGenericMethod(type);
+			var fromJson = typeof(JsonSerializationTypeRegistry).GetMethod("DecodeGenericList").MakeGenericMethod(type);
+			ToJsonConverters[listType] = Delegate.CreateDelegate(typeof (ToJsonDelegate<List<T>>), toJson);
+			FromJsonConverters[listType] = Delegate.CreateDelegate(typeof (FromJsonDelegate<List<T>>), fromJson);
+		}
+		/// <summary>
+		/// Registers an encode/decode method pair for a typed dictionary.
+		/// </summary>
+		/// <typeparam name="TKey">The underlying type used as the key for the dictionary.</typeparam>
+		/// <typeparam name="TValue">The underlying type used as the value for the dictionary.</typeparam>
+		/// <remarks>To register a dictionary of ints keyed by strings, the call should be RegisterDictionaryType&lt;string, int&gt;()</remarks>
+		public static void RegisterDictionaryType<TKey, TValue>()
+		{
+			var keyType = typeof(TKey);
+			var valueType = typeof (TValue);
+			var dictType = typeof(Dictionary<TKey, TValue>);
+			var toJson = typeof(JsonSerializationTypeRegistry).GetMethod("EncodeGenericDictionary").MakeGenericMethod(keyType, valueType);
+			var fromJson = typeof(JsonSerializationTypeRegistry).GetMethod("DecodeGenericDictionary").MakeGenericMethod(keyType, valueType);
+			ToJsonConverters[dictType] = Delegate.CreateDelegate(typeof(ToJsonDelegate<Dictionary<TKey, TValue>>), toJson);
+			FromJsonConverters[dictType] = Delegate.CreateDelegate(typeof(FromJsonDelegate<Dictionary<TKey, TValue>>), fromJson);
+		}
+		/// <summary>
+		/// Registers an encode/decode method pair for a typed queue.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the queue.</typeparam>
+		/// <remarks>To register a queue of ints, the call should be RegisterQueueType&lt;int&gt;()</remarks>
+		public static void RegisterQueueType<T>()
+		{
+			var type = typeof(T);
+			var queueType = typeof(Queue<T>);
+			var toJson = typeof(JsonSerializationTypeRegistry).GetMethod("EncodeGenericQueue").MakeGenericMethod(type);
+			var fromJson = typeof(JsonSerializationTypeRegistry).GetMethod("DecodeGenericQueue").MakeGenericMethod(type);
+			ToJsonConverters[queueType] = Delegate.CreateDelegate(typeof(ToJsonDelegate<Queue<T>>), toJson);
+			FromJsonConverters[queueType] = Delegate.CreateDelegate(typeof(FromJsonDelegate<Queue<T>>), fromJson);
+		}
+		/// <summary>
+		/// Registers an encode/decode method pair for a typed stack.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the stack.</typeparam>
+		/// <remarks>To register a stack of ints, the call should be RegisterStackType&lt;int&gt;()</remarks>
+		public static void RegisterStackType<T>()
+		{
+			var type = typeof(T);
+			var stackType = typeof(Stack<T>);
+			var toJson = typeof(JsonSerializationTypeRegistry).GetMethod("EncodeGenericStack").MakeGenericMethod(type);
+			var fromJson = typeof(JsonSerializationTypeRegistry).GetMethod("DecodeGenericStack").MakeGenericMethod(type);
+			ToJsonConverters[stackType] = Delegate.CreateDelegate(typeof(ToJsonDelegate<Stack<T>>), toJson);
+			FromJsonConverters[stackType] = Delegate.CreateDelegate(typeof(FromJsonDelegate<Stack<T>>), fromJson);
+		}
+		#endregion
+
+		#region Specified Types
+		#region DateTime
+		/// <summary>
+		/// Encodes a DateTime object to its JSON representation.
+		/// </summary>
+		/// <param name="dt">A DateTime object.</param>
+		/// <returns>The JSON representation of the DateTime.</returns>
+		public static JsonValue EncodeDateTime(DateTime dt)
+		{
+			return dt.ToString();
+		}
+		/// <summary>
+		/// Decodes a DateTime object from its JSON representation.
+		/// </summary>
+		/// <param name="json">A JSON representation of a DateTime.</param>
+		/// <returns>The DateTime object.</returns>
+		public static DateTime DecodeDateTime(JsonValue json)
+		{
+			return json.Type == JsonValueType.String ? DateTime.Parse(json.String) : default(DateTime);
+		}
+		#endregion
+		#region TimeSpan
+		/// <summary>
+		/// Encodes a TimeSpan object to its JSON representation.
+		/// </summary>
+		/// <param name="ts">A TimeSpan object.</param>
+		/// <returns>The JSON representation of the TimeSpan.</returns>
+		public static JsonValue EncodeTimeSpan(TimeSpan ts)
+		{
+			return ts.ToString();
+		}
+		/// <summary>
+		/// Decodes a TimeSpan object from its JSON representation.
+		/// </summary>
+		/// <param name="json">A JSON representation of a TimeSpan.</param>
+		/// <returns>The TimeSpan object.</returns>
+		public static TimeSpan DecodeTimeSpan(JsonValue json)
+		{
+			return json.Type == JsonValueType.String ? TimeSpan.Parse(json.String) : default(TimeSpan);
+		}
+		#endregion
+		#endregion
+
+		#region Generic Types
+		#region Nullable<T>
+		/// <summary>
+		/// Encodes a Nullable&lt;T&gt; to its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the nullable value.</typeparam>
+		/// <param name="nullable">The Nullable&lt;T&gt; object.</param>
+		/// <returns>The JSON representation of the Nullable&lt;T&gt;.</returns>
+		public static JsonValue EncodeNullable<T>(T? nullable) where T : struct
+		{
+			return nullable.HasValue ? _serializer.Serialize(nullable.Value) : JsonValue.Null;
+		}
+		/// <summary>
+		/// Decodes a Nullable&lt;T&gt; object from its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the nullable value.</typeparam>
+		/// <param name="json">A JSON representation of a Nullable&lt;T&gt;.</param>
+		/// <returns>The Nullable&lt;T&gt; object.</returns>
+		public static T? DecodeNullable<T>(JsonValue json) where T : struct
+		{
+			if (json == JsonValue.Null) return null;
+			T? nullable = _serializer.Deserialize<T>(json);
+			return nullable;
+		}
+		#endregion
+		#region List<T>
+		/// <summary>
+		/// Encodes a List&lt;T&gt; to its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the list.</typeparam>
+		/// <param name="list">The List&lt;T&gt; object.</param>
+		/// <returns>The JSON representation of the List&lt;T&gt;.</returns>
+		public static JsonValue EncodeGenericList<T>(List<T> list)
+		{
+			var array = new JsonArray();
+			array.AddRange(list.Select(item => _serializer.Serialize(item)));
+			return array;
+		}
+		/// <summary>
+		/// Decodes a List&lt;T&gt; object from its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the list.</typeparam>
+		/// <param name="json">A JSON representation of a List&lt;T&gt;.</param>
+		/// <returns>The List&lt;T&gt; object.</returns>
+		public static List<T> DecodeGenericList<T>(JsonValue json)
+		{
+			var list = new List<T>();
+			list.AddRange(json.Array.Select(jv => _serializer.Deserialize<T>(jv)));
+			return list;
+		}
+		#endregion
+		#region Dictionary<TKey, TValue>
+		/// <summary>
+		/// Encodes a Dictionary&lt;T&gt; to its JSON representation.
+		/// </summary>
+		/// <typeparam name="TKey">The underlying type used as the key for the dictionary.</typeparam>
+		/// <typeparam name="TValue">The underlying type used as the value for the dictionary.</typeparam>
+		/// <param name="dict">The Dictionary&lt;T&gt; object.</param>
+		/// <returns>The JSON representation of the Dictionary&lt;T&gt;.</returns>
+		public static JsonValue EncodeGenericDictionary<TKey, TValue>(Dictionary<TKey, TValue> dict)
+		{
+			var array = new JsonArray();
+			array.AddRange(dict.Select(item => (JsonValue)(new JsonObject
+			                                               	{
+			                                               		{"Key", _serializer.Serialize(item.Key)},
+																{"Value", _serializer.Serialize(item.Value)}
+			                                               	})));
+			return array;
+		}
+		/// <summary>
+		/// Decodes a Dictionary&lt;T&gt; object from its JSON representation.
+		/// </summary>
+		/// <typeparam name="TKey">The underlying type used as the key for the dictionary.</typeparam>
+		/// <typeparam name="TValue">The underlying type used as the value for the dictionary.</typeparam>
+		/// <param name="json">A JSON representation of a Dictionary&lt;T&gt;.</param>
+		/// <returns>The Dictionary&lt;T&gt; object.</returns>
+		public static Dictionary<TKey, TValue> DecodeGenericDictionary<TKey, TValue>(JsonValue json)
+		{
+			var dict = new Dictionary<TKey, TValue>();
+			foreach (var jv in json.Array)
+			{
+				dict.Add(_serializer.Deserialize<TKey>(jv.Object["Key"]),
+						 _serializer.Deserialize<TValue>(jv.Object["Value"]));
+			}
+			return dict;
+		}
+		#endregion
+		#region Queue<T>
+		/// <summary>
+		/// Encodes a Queue&lt;T&gt; to its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the queue.</typeparam>
+		/// <param name="queue">The Queue&lt;T&gt; object.</param>
+		/// <returns>The JSON representation of the Queue&lt;T&gt;.</returns>
+		public static JsonValue EncodeGenericQueue<T>(Queue<T> queue)
+		{
+			var array = new JsonArray();
+			for (int i = 0; i < queue.Count; i++)
+			{
+				array.Add(_serializer.Serialize(queue.ElementAt(i)));
+			}
+			return array;
+		}
+		/// <summary>
+		/// Decodes a Queue&lt;T&gt; object from its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the queue.</typeparam>
+		/// <param name="json">A JSON representation of a Queue&lt;T&gt;.</param>
+		/// <returns>The Queue&lt;T&gt; object.</returns>
+		public static Queue<T> DecodeGenericQueue<T>(JsonValue json)
+		{
+			var queue = new Queue<T>();
+			for (int i = 0; i < json.Array.Count; i++)
+			{
+				queue.Enqueue(_serializer.Deserialize<T>(json.Array[i]));
+			}
+			return queue;
+		}
+		#endregion
+		#region Stack<T>
+		/// <summary>
+		/// Encodes a Stack&lt;T&gt; to its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the stack.</typeparam>
+		/// <param name="stack">The Stack&lt;T&gt; object.</param>
+		/// <returns>The JSON representation of the Stack&lt;T&gt;.</returns>
+		public static JsonValue EncodeGenericStack<T>(Stack<T> stack)
+		{
+			var array = new JsonArray();
+			for (int i = 0; i < stack.Count; i++)
+			{
+				array.Add(_serializer.Serialize(stack.ElementAt(i)));
+			}
+			return array;
+		}
+		/// <summary>
+		/// Decodes a Stack&lt;T&gt; object from its JSON representation.
+		/// </summary>
+		/// <typeparam name="T">The underlying type of the stack.</typeparam>
+		/// <param name="json">A JSON representation of a Stack&lt;T&gt;.</param>
+		/// <returns>The Stack&lt;T&gt; object.</returns>
+		public static Stack<T> DecodeGenericStack<T>(JsonValue json)
+		{
+			var stack = new Stack<T>();
+			for (int i = 0; i < json.Array.Count; i++)
+			{
+				stack.Push(_serializer.Deserialize<T>(json.Array[i]));
+			}
+			return stack;
+		}
+		#endregion
+		#endregion
+	}
+}

File Json.Serialization/JsonSerializer.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		JsonSerializer.cs
+	Namespace:		Manatee.Json.Serialization
+	Class Name:		JsonSerializer
+	Purpose:		Serializes and deserializes objects and types to and from
+					JSON structures.
+
+***************************************************************************************/
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Manatee.Json.Serialization.Attributes;
+using Manatee.Json.Serialization.Cache;
+using Manatee.Json.Serialization.Helpers;
+
+namespace Manatee.Json.Serialization
+{
+	/// <summary>
+	/// Serializes and deserializes objects and types to and from JSON structures.
+	/// </summary>
+	public class JsonSerializer
+	{
+		private const string TypeKey = "#Type";
+		private const string ValueKey = "#Value";
+
+		private JsonSerializerOptions Options { get; set; }
+
+		#region Public Methods
+		/// <summary>
+		/// Serializes an object to a JSON structure.
+		/// </summary>
+		/// <typeparam name="T">The type of the object to serialize.</typeparam>
+		/// <param name="obj">The object to serialize.</param>
+		/// <returns>The JSON representation of the object.</returns>
+		public JsonValue Serialize<T>(T obj)
+		{
+			if (typeof(IJsonCompatible).IsAssignableFrom(typeof(T)))
+				return ((IJsonCompatible) obj).ToJson();
+			if (EqualsDefaultValue(obj)) return JsonValue.Null;
+			var tryPrimitive = PrimitiveMapper.MapToJson(obj);
+			if (tryPrimitive != JsonValue.Null)
+				return tryPrimitive;
+			var converter = JsonSerializationTypeRegistry.GetToJsonConverter<T>();
+			return converter == null ? AutoSerializeObject(obj) : converter(obj);
+		}
+		/// <summary>
+		/// Serializes the public static properties of a type to a JSON structure.
+		/// </summary>
+		/// <typeparam name="T">The type to serialize.</typeparam>
+		/// <returns>The JSON representation of the type.</returns>
+		public JsonValue SerializeType<T>()
+		{
+			var json = new JsonObject();
+			var propertyInfoList = typeof(T).GetProperties(BindingFlags.Static | BindingFlags.Public)
+											 .Where(p => p.GetSetMethod() != null)
+											 .Where(p => p.GetGetMethod() != null)
+											 .Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Count() == 0);
+			foreach (var propertyInfo in propertyInfoList)
+			{
+				var value = propertyInfo.GetValue(null, null);
+				if (value == null)
+				{
+					json.Add(propertyInfo.Name, JsonValue.Null);
+				}
+				else
+				{
+					var type = propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface
+								? value.GetType()
+								: propertyInfo.PropertyType;
+					var serialize = SerializerCache.Instance.GetSerializer(type);
+					json.Add(propertyInfo.Name, (JsonValue)serialize.Invoke(this, new[] { value }));
+				}
+			}
+			return json.Count == 0 ? JsonValue.Null : json;
+		}
+		/// <summary>
+		/// Deserializes a JSON structure to an object of the appropriate type.
+		/// </summary>
+		/// <typeparam name="T">The type of the object that the JSON structure represents.</typeparam>
+		/// <param name="json">The JSON representation of the object.</param>
+		/// <returns>The deserialized object.</returns>
+		public T Deserialize<T>(JsonValue json)
+		{
+			if (typeof(IJsonCompatible).IsAssignableFrom(typeof(T)))
+			{
+				var obj = (T)Activator.CreateInstance(typeof (T));
+				((IJsonCompatible)obj).FromJson(json);
+				return obj;
+			}
+			if (json == JsonValue.Null)
+				return default(T);
+			if (PrimitiveMapper.IsPrimitive(typeof(T)))
+				return PrimitiveMapper.MapFromJson<T>(json);
+			var converter = JsonSerializationTypeRegistry.GetFromJsonConverter<T>();
+			return converter == null ? AutoDeserializeObject<T>(json) : converter(json);
+		}
+		/// <summary>
+		/// Deserializes a JSON structure to the public static properties of a type.
+		/// </summary>
+		/// <typeparam name="T">The type to deserialize.</typeparam>
+		/// <param name="json">The JSON representation of the type.</param>
+		public void DeserializeType<T>(JsonValue json)
+		{
+			if (json == JsonValue.Null)
+				return;
+			var propertyInfoList = typeof(T).GetProperties(BindingFlags.Static | BindingFlags.Public)
+											 .Where(p => p.GetSetMethod() != null)
+											 .Where(p => p.GetGetMethod() != null)
+											 .Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Count() == 0);
+			foreach (var propertyInfo in propertyInfoList)
+			{
+				if (json.Object.ContainsKey(propertyInfo.Name))
+				{
+					var deserialize = SerializerCache.Instance.GetDeserializer(propertyInfo.PropertyType);
+					propertyInfo.SetValue(null, deserialize.Invoke(this, new[] { json.Object[propertyInfo.Name] }), null);
+				}
+			}
+		}
+		#endregion
+
+		#region Support Methods
+		private static bool EqualsDefaultValue<T>(T value)
+		{
+			return EqualityComparer<T>.Default.Equals(value, default(T));
+		}
+		private JsonValue AutoSerializeObject<T>(T obj)
+		{
+			var json = new JsonObject();
+			var propertyInfoList = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
+											.Where(p => p.GetSetMethod() != null)
+											.Where(p => p.GetGetMethod() != null)
+											.Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Count() == 0);
+			foreach (var propertyInfo in propertyInfoList)
+			{
+				var value = propertyInfo.GetValue(obj, null);
+				if (value == null) continue;
+				var type = propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface
+					        ? value.GetType()
+					        : propertyInfo.PropertyType;
+				var serialize = SerializerCache.Instance.GetSerializer(type);
+				var jsonProp = (JsonValue) serialize.Invoke(this, new[] {value});
+				if (jsonProp == JsonValue.Null) continue;
+				json.Add(propertyInfo.Name,
+				         type == propertyInfo.PropertyType
+				         	? jsonProp
+				         	: new JsonObject {{TypeKey, type.AssemblyQualifiedName}, {ValueKey, jsonProp}});
+			}
+			return json.Count == 0 ? JsonValue.Null : json;
+		}
+		private T AutoDeserializeObject<T>(JsonValue json)
+		{
+			var propertyInfoList = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
+											.Where(p => p.GetSetMethod() != null)
+											.Where(p => p.GetGetMethod() != null)
+											.Where(p => p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Count() == 0);
+			var obj = (T)Activator.CreateInstance(typeof(T));
+			foreach (var propertyInfo in propertyInfoList)
+			{
+				if (json.Object.ContainsKey(propertyInfo.Name))
+				{
+					var value = json.Object[propertyInfo.Name];
+					if (value.Type == JsonValueType.Object)
+					{
+						var instanceType = Type.GetType(value.Object[TypeKey].String);
+						var instanceJson = value.Object[ValueKey];
+						var deserialize = SerializerCache.Instance.GetDeserializer(instanceType);
+						propertyInfo.SetValue(obj, deserialize.Invoke(this, new[] { instanceJson }), null);
+					}
+					else
+					{
+						var deserialize = SerializerCache.Instance.GetDeserializer(propertyInfo.PropertyType);
+						propertyInfo.SetValue(obj, deserialize.Invoke(this, new[] { json.Object[propertyInfo.Name] }), null);
+					}
+				}
+			}
+			return obj;
+		}
+		#endregion
+	}
+}

File Json.Serialization/JsonSerializerOptions.cs

+/***************************************************************************************
+
+	Copyright 2012 Greg Dennis
+
+	   Licensed under the Apache License, Version 2.0 (the "License");
+	   you may not use this file except in compliance with the License.
+	   You may obtain a copy of the License at
+
+		 http://www.apache.org/licenses/LICENSE-2.0
+
+	   Unless required by applicable law or agreed to in writing, software
+	   distributed under the License is distributed on an "AS IS" BASIS,
+	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	   See the License for the specific language governing permissions and
+	   limitations under the License.
+ 
+	File Name:		JsonSerializerOptions.cs
+	Namespace:		Manatee.Json.Serialization
+	Class Name:		JsonSerializerOptions
+	Purpose:		Default options used by the serializer.
+
+***************************************************************************************/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Manatee.Json.Serialization.Enumerations;
+
+namespace Manatee.Json.Serialization
+{
+	class JsonSerializerOptions
+	{
+		/// <summary>
+		/// Default options used by the serializer.
+		/// </summary>
+		public JsonSerializerOptions Default = new JsonSerializerOptions
+		                                       	{
+		                                       		EncodeDefaultValues = false,
+													InvalidPropertyKeyBehavior = InvalidPropertyKeyBehavior.DoNothing
+		                                       	};
+		/// <summary>
+		/// Gets and sets whether the serializer encodes default values for properties.
+		/// </summary>
+		/// <remarks>
+		/// Setting to 'true' may significantly increase the size of the JSON structure.
+		/// </remarks>
+		public bool EncodeDefaultValues { get; set; }
+		/// <summary>
+		/// Gets and sets the behavior of the deserializer when a JSON structure is passed which
+		/// contains invalid property keys.
+		/// </summary>
+		public InvalidPropertyKeyBehavior InvalidPropertyKeyBehavior { get; set; }
+	}
+}

File Json.Serialization/Manatee.Json.Serialization.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A6066DBF-1B69-4A20-B60B-4AAC28CA35D7}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Manatee.Json.Serialization</RootNamespace>
+    <AssemblyName>Manatee.Json.Serialization</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Manatee.Json.Serialization.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Publish|AnyCPU'">
+    <OutputPath>..\..\Releases\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>..\..\Releases\Manatee.Json.Serialization.XML</DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <CodeAnalysisLogFile>..\..\Releases\Manatee.Json.Serialization.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Attributes\JsonIgnoreAttribute.cs" />
+    <Compile Include="Cache\ObjectCasterCache.cs" />
+    <Compile Include="Cache\ObjectCasterMethodPair.cs" />
+    <Compile Include="Cache\SerializerCache.cs" />
+    <Compile Include="Cache\SerializerMethodPair.cs" />
+    <Compile Include="Enumerations\InvalidPropertyKeyBehavior.cs" />
+    <Compile Include="Exceptions\NotPrimitiveTypeException.cs" />
+    <Compile Include="Exceptions\TypeRegistrationException.cs" />
+    <Compile Include="Helpers\ObjectCaster.cs" />
+    <Compile Include="Helpers\PrimitiveMapper.cs" />
+    <Compile Include="IJsonCompatible.cs" />
+    <Compile Include="JsonSerializationTypeRegistry.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="JsonSerializerOptions.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Json\Manatee.Json.csproj">
+      <Project>{6ADF0BCF-4E46-4605-A784-51EA6DAC81C7}</Project>
+      <Name>Manatee.Json</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

File Json.Serialization/Properties/AssemblyInfo.cs

+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Json.Serialization")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("GameStop, Inc.")]
+[assembly: AssemblyProduct("Json.Serialization")]
+[assembly: AssemblyCopyright("Copyright © GameStop, Inc. 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6a8eea8b-01bc-4225-a365-a429002f96b2")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Json.Tests")]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Manatee.Json.Tests")]

File Json.Tests/Json/JsonArrayTest.cs

+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Linq;
+using Manatee.Json.Exceptions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests.Json
+{
+	[TestClass]
+	public class JsonArrayTest
+	{
+		[TestMethod]
+		public void ToString_ReturnsCorrectString()
+		{
+			var json = new JsonArray {false, 42, "a string"};
+			var expected = "[False,42,\"a string\"]";
+			var actual = json.ToString();
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void Equals_SameValuesSameOrder_ReturnsTrue()
+		{
+			var json1 = new JsonArray { false, 42, "a string" };
+			var json2 = new JsonArray { false, 42, "a string" };
+			Assert.IsTrue(json1.Equals(json2));
+		}
+		[TestMethod]
+		public void Equals_SameValuesDifferentOrder_ReturnsTrue()
+		{
+			var json1 = new JsonArray { false, 42, "a string" };
+			var json2 = new JsonArray { 42, false, "a string" };
+			Assert.IsTrue(json1.Equals(json2));
+		}
+		[TestMethod]
+		public void Equals_DifferentValues_ReturnsFalse()
+		{
+			var json1 = new JsonArray { false, 42, "a string" };
+			var json2 = new JsonArray { false, "42", "a string" };
+			Assert.IsFalse(json1.Equals(json2));
+		}
+		[TestMethod]
+		public void Parse_ValidString_ReturnsCorrectArray()
+		{
+			var s = "[False,42,\"a string\"]";
+			var expected = new JsonArray { false, 42, "a string" };
+			var i = 0;
+			var actual = new JsonArray(s, ref i);
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingValue_ThrowsJsonSyntaxException()
+		{
+			var s = "[False,,\"a string\"]";
+			var i = 0;
+			var actual = new JsonArray(s, ref i);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingOpenBracket_ThrowsJsonSyntaxException()
+		{
+			var s = "False,42,\"a string\"]";
+			var i = 0;
+			var actual = new JsonArray(s, ref i);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingCloseBracket_ThrowsJsonSyntaxException()
+		{
+			var s = "[False,42,\"a string\"";
+			var i = 0;
+			var actual = new JsonArray(s, ref i);
+		}
+	}
+}

File Json.Tests/Json/JsonObjectTest.cs

+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Linq;
+using Manatee.Json.Exceptions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests.Json
+{
+	[TestClass]
+	public class JsonObjectTest
+	{
+		[TestMethod]
+		public void ToString_ReturnsCorrectString()
+		{
+			var json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			var expected = "{\"bool\":False,\"int\":42,\"string\":\"a string\"}";
+			var actual = json.ToString();
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void Equals_SameValuesSameOrder_ReturnsTrue()
+		{
+			var json1 = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			var json2 = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			Assert.IsTrue(json1.Equals(json2));
+		}
+		[TestMethod]
+		public void Equals_SameValuesDifferentOrder_ReturnsTrue()
+		{
+			var json1 = new JsonObject {{"int", 42}, {"bool", false}, {"string", "a string"}};
+			var json2 = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			Assert.IsTrue(json1.Equals(json2));
+		}
+		[TestMethod]
+		public void Equals_DifferentValues_ReturnsFalse()
+		{
+			var json1 = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			var json2 = new JsonObject {{"bool", false}, {"int", "42"}, {"string", "a string"}};
+			Assert.IsFalse(json1.Equals(json2));
+		}
+		[TestMethod]
+		public void Parse_ValidString_ReturnsCorrectObject()
+		{
+			var s = "{\"bool\":False,\"int\":42,\"string\":\"a string\"}";
+			var expected = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			var actual = new JsonObject(s);
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingValue_ThrowsJsonSyntaxException()
+		{
+			var s = "{\"bool\":False,\"int\":,\"string\":\"a string\"}";
+			var actual = new JsonObject(s);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingKey_ThrowsJsonSyntaxException()
+		{
+			var s = "{\"bool\":False,:42,\"string\":\"a string\"}";
+			var actual = new JsonObject(s);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingKeyValue_ThrowsJsonSyntaxException()
+		{
+			var s = "{\"bool\":False,,\"string\":\"a string\"}";
+			var actual = new JsonObject(s);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingKeyValueDelimiter_ThrowsJsonSyntaxException()
+		{
+			var s = "{\"bool\":False,\"int\"42,\"string\":\"a string\"}";
+			var actual = new JsonObject(s);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonValueParseException))]
+		public void Parse_StringMissingDelimiter_ThrowsJsonValueParseException()
+		{
+			var s = "{\"bool\":False,\"int\":42\"string\":\"a string\"}";
+			var actual = new JsonObject(s);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingOpenBrace_ThrowsJsonSyntaxException()
+		{
+			var s = "\"bool\":False,\"int\":42,\"string\":\"a string\"}";
+			var actual = new JsonObject(s);
+		}
+		[TestMethod]
+		[ExpectedException(typeof(JsonSyntaxException))]
+		public void Parse_StringMissingCloseBrace_ThrowsJsonSyntaxException()
+		{
+			var s = "{\"bool\":False,\"int\":42,\"string\":\"a string\"";
+			var actual = new JsonObject(s);
+		}
+	}
+}

File Json.Tests/Json/LinqExtensionsTest.cs

+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests.Json
+{
+	[TestClass]
+	public class LinqExtensionsTest
+	{
+		[TestMethod]
+		public void ToJson_FilteringArray_ReturnsArray()
+		{
+			var json = new JsonArray { false, 42, "a string", "another string" };
+			var expected = new JsonArray { "a string", "another string" };
+			var actual = json.Where(jv => jv.Type == JsonValueType.String).ToJson();
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void ToJson_FilteringObject_ReturnsObject()
+		{
+			var json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}, {"string2", "another string"}};
+			var expected = new JsonObject {{"string", "a string"}, {"string2", "another string"}};
+			var actual = json.Where(jv => jv.Value.Type == JsonValueType.String).ToJson();
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void ToJson_FilteringObjectExtractValues_ReturnsArray()
+		{
+			var json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}, {"string2", "another string"}};
+			var expected = new JsonArray {"a string", "another string"};
+			var actual = json.Where(jv => jv.Value.Type == JsonValueType.String)
+							 .Select(jv => jv.Value).ToJson();
+			Assert.AreEqual(expected, actual);
+		}
+	}
+}

File Json.Tests/Manatee.Json.Tests.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>
+    </ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E74B7538-5E17-43C7-925B-33784945312E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Manatee.Json.Tests</RootNamespace>
+    <AssemblyName>Manatee.Json.Tests</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
+  </ItemGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Json\JsonObjectTest.cs" />
+    <Compile Include="Json\JsonArrayTest.cs" />
+    <Compile Include="Json\LinqExtensionsTest.cs" />
+    <Compile Include="Serialization\JsonSerializerTest.cs" />
+    <Compile Include="Serialization\Helpers\PrimitiveMapperTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Test References\AbstractClass.cs" />
+    <Compile Include="Test References\DerivedClass.cs" />
+    <Compile Include="Test References\JsonCompatibleClass.cs" />
+    <Compile Include="Test References\ObjectWithAbstractAndInterfaceProps.cs" />
+    <Compile Include="Test References\ObjectWithBasicProps.cs" />
+  </ItemGroup>
+  <ItemGroup />
+  <ItemGroup>
+    <ProjectReference Include="..\Json.Serialization\Manatee.Json.Serialization.csproj">
+      <Project>{A6066DBF-1B69-4A20-B60B-4AAC28CA35D7}</Project>
+      <Name>Manatee.Json.Serialization</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Json\Manatee.Json.csproj">
+      <Project>{6ADF0BCF-4E46-4605-A784-51EA6DAC81C7}</Project>
+      <Name>Manatee.Json</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

File Json.Tests/Manatee.Json.Tests.csproj.user

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectView>ProjectFiles</ProjectView>
+  </PropertyGroup>
+</Project>

File Json.Tests/Properties/AssemblyInfo.cs

+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Json.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("GameStop, Inc.")]
+[assembly: AssemblyProduct("Json.Tests")]
+[assembly: AssemblyCopyright("Copyright © GameStop, Inc. 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f1d37ce8-25c2-4a1f-aaf2-813c1bad0af8")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

File Json.Tests/Serialization/Helpers/PrimitiveMapperTest.cs

+using Manatee.Json.Serialization.Exceptions;
+using Manatee.Json.Serialization.Helpers;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Reflection;
+using Manatee.Json;
+
+namespace Json.Tests.Serialization.Helpers
+{
+	
+	
+	/// <summary>
+	///This is a test class for PrimitiveMapperTest and is intended
+	///to contain all PrimitiveMapperTest Unit Tests
+	///</summary>
+	[TestClass()]
+	public class PrimitiveMapperTest
+	{
+
+
+		private TestContext testContextInstance;
+
+		/// <summary>
+		///Gets or sets the test context which provides
+		///information about and functionality for the current test run.
+		///</summary>
+		public TestContext TestContext
+		{
+			get
+			{
+				return testContextInstance;
+			}
+			set
+			{
+				testContextInstance = value;
+			}
+		}
+
+		#region Additional test attributes
+		// 
+		//You can use the following additional attributes as you write your tests:
+		//
+		//Use ClassInitialize to run code before running the first test in the class
+		//[ClassInitialize()]
+		//public static void MyClassInitialize(TestContext testContext)
+		//{
+		//}
+		//
+		//Use ClassCleanup to run code after all tests in a class have run
+		//[ClassCleanup()]
+		//public static void MyClassCleanup()
+		//{
+		//}
+		//
+		//Use TestInitialize to run code before running each test
+		//[TestInitialize()]
+		//public void MyTestInitialize()
+		//{
+		//}
+		//
+		//Use TestCleanup to run code after each test has run
+		//[TestCleanup()]
+		//public void MyTestCleanup()
+		//{
+		//}
+		//
+		#endregion
+
+		#region MapFromJson Tests
+		[TestMethod]
+		public void MapFromJson_ParameterIsNotPrimitive_ThrowsNotPrimitiveTypeException()
+		{
+			JsonValue json = new JsonObject();
+			try
+			{
+				PrimitiveMapper.MapFromJson<Uri>(json);
+				Assert.Fail("Expected NotPrimitiveTypeException");
+			}
+			catch (NotPrimitiveTypeException e) { }
+			catch (Exception e)
+			{
+				Assert.Fail(string.Format("Incorrect exception thrown: {0}", e));
+			}
+		}
+		[TestMethod]
+		public void MapFromJson_ParameterIsString_ReturnsCorrectString()
+		{
+			var json = new JsonValue("test");
+			var expected = "test";
+			var actual = PrimitiveMapper.MapFromJson<string>(json);
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void MapFromJson_ParameterIsInt_ReturnsCorrectInt()
+		{
+			var json = new JsonValue(42);
+			var expected = 42;