Commits

Anonymous committed a278612

Added validation error handling and reporting.
Reorganized test project to match reorganization of target.

  • Participants
  • Parent commits 1b2aa14

Comments (0)

Files changed (30)

File Manatee.Json.Tests/DevTest.cs

 		//[Ignore]
 		public void Test1()
 		{
-			var schema = JsonSchema.Draft04;
-			var geoSchemaJson = new JsonObject
-				{
-					{"description", "A geographical coordinate"},
-					{"type", "object"},
-					{
-						"properties", new JsonObject
-							{
-								{"latitude", new JsonObject {{"type", "number"}}},
-								{"longitude", new JsonObject {{"type", "number"}}}
-							}
-					},
-					{"required", new JsonArray {"latitude", "longitude"}}
-				};
-			Console.WriteLine("geo schema valid: {0}", schema.Validate(geoSchemaJson));
-			var geoSchema = JsonSchemaFactory.FromJson(geoSchemaJson);
-			var geoJson = new JsonObject
-				{
-					{"latitude", 95.4},
-					{"longitude", 36.8}
-				};
-			Console.WriteLine("geo json valid: {0}", geoSchema.Validate(geoJson));
-		}
-		[TestMethod]
-		//[Ignore]
-		public void Test2()
-		{
-			var schema = JsonSchema.Draft04;
-			var geoSchemaJson = new JsonObject
-				{
-					{"$ref", "http://json-schema.org/geo"}
-				};
-			Console.WriteLine("geo schema valid: {0}", schema.Validate(geoSchemaJson));
-			var serializer = new JsonSerializer();
-			var geoSchema = serializer.Deserialize<IJsonSchema>(geoSchemaJson);
-			var geoJson = new JsonObject
-				{
-					{"latitude", 95.4},
-					{"longitude", 36.8}
-				};
-			Console.WriteLine("geo json valid: {0}", geoSchema.Validate(geoJson));
-		}
-		[TestMethod]
-		//[Ignore]
-		public void Test3()
-		{
 			var geoSchema = new ObjectSchema
 				{
 					Properties = new JsonSchemaPropertyDefinitionCollection
 							new JsonSchemaPropertyDefinition
 								{
 									Name = "latitude",
-									Type = new NumberSchema(),
+									Type = new NumberSchema {Minimum = -180, Maximum = 180},
 									IsRequired = true
 								},
 							new JsonSchemaPropertyDefinition
 								{
 									Name = "longitude",
-									Type = new NumberSchema(),
+									Type = new NumberSchema {Minimum = -90, Maximum = 90},
 									IsRequired = true
+								},
+							new JsonSchemaPropertyDefinition
+								{
+									Name = "nestedProperty",
+									Type = new ObjectSchema
+										{
+											Properties = new JsonSchemaPropertyDefinitionCollection
+												{
+													new JsonSchemaPropertyDefinition
+														{
+															Name = "test",
+															Type = new StringSchema()
+														}
+												}
+										}
 								}
 						}
 				};
 			var geoJson = new JsonObject
 				{
-					{"latitude", 95.4},
-					{"longitude", 36.8}
+					{"latitude", 95},
+					{"longitude", -36.8},
+					{"nestedProperty", new JsonObject {{"test", false}}}
 				};
-			Console.WriteLine("geo json valid: {0}", geoSchema.Validate(geoJson));
+			var validation = geoSchema.Validate(geoJson);
+			Console.WriteLine("geo json valid: {0}", validation.Valid);
+			foreach (var error in validation.Errors)
+			{
+				Console.WriteLine("    {0}", error);
+			}
 		}
 	}
 }

File Manatee.Json.Tests/Extensions/JsonArrayExtensionsTest.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:		JsonArrayExtensionsTest.cs
-	Namespace:		Manatee.Json.Tests.Extensions
-	Class Name:		JsonArrayExtensionsTest
-	Purpose:		Tests for the JsonArray extension methods for the Json library.
-
-***************************************************************************************/
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Manatee.Json.Tests.Extensions
-{
-	[TestClass]
-	public class JsonArrayExtensionsTest
-	{
-		[TestMethod]
-		public void OfType_ReturnsOnlyRequestType()
-		{
-			var json = new JsonArray {6, "string", false, 42, JsonValue.Null, true};
-			var expected = new JsonArray {6, 42};
-			var values = json.OfType(JsonValueType.Number);
-
-			Assert.AreEqual(expected, values);
-		}
-	}
-}

File Manatee.Json.Tests/Extensions/JsonObjectExtensionsTest.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:		JsonObjectExtensionsTest.cs
-	Namespace:		Manatee.Json.Tests.Extensions
-	Class Name:		JsonObjectExtensionsTest
-	Purpose:		Tests for the JsonObject extension methods for the Json library.
-
-***************************************************************************************/
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Manatee.Json.Tests.Extensions
-{
-	[TestClass]
-	public class JsonObjectExtensionsTest
-	{
-		[TestMethod]
-		public void TryGetString_ReturnsRequested()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"boolean", true}
-				};
-
-			var value = json.TryGetString("string");
-
-			Assert.AreEqual("test", value);
-		}
-		[TestMethod]
-		public void TryGetString_NullObjectReturnsNull()
-		{
-			JsonObject json = null;
-
-			var value = json.TryGetString("string");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetString_ValueNotFoundReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"number", 6},
-					{"boolean", true}
-				};
-			var value = json.TryGetString("string");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetString_ValueNotStringReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"boolean", true}
-				};
-			var value = json.TryGetString("number");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetNumber_ReturnsRequested()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"boolean", true}
-				};
-
-			var value = json.TryGetNumber("number");
-
-			Assert.AreEqual(6.0, value);
-		}
-		[TestMethod]
-		public void TryGetNumber_NullObjectReturnsNull()
-		{
-			JsonObject json = null;
-
-			var value = json.TryGetNumber("number");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetNumber_ValueNotFoundReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"boolean", true}
-				};
-			var value = json.TryGetNumber("number");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetNumber_ValueNotNumberReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"boolean", true}
-				};
-			var value = json.TryGetNumber("string");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetBoolean_ReturnsRequested()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"boolean", true}
-				};
-
-			var value = json.TryGetBoolean("boolean");
-
-			Assert.AreEqual(true, value);
-		}
-		[TestMethod]
-		public void TryGetBoolean_NullObjectReturnsNull()
-		{
-			JsonObject json = null;
-
-			var value = json.TryGetBoolean("boolean");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetBoolean_ValueNotFoundReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6}
-				};
-			var value = json.TryGetBoolean("boolean");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetBoolean_ValueNotBooleanReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"boolean", true}
-				};
-			var value = json.TryGetBoolean("string");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetArray_ReturnsRequested()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"array", new JsonArray()}
-				};
-
-			var value = json.TryGetArray("array");
-
-			Assert.AreEqual(new JsonArray(), value);
-		}
-		[TestMethod]
-		public void TryGetArray_NullObjectReturnsNull()
-		{
-			JsonObject json = null;
-
-			var value = json.TryGetArray("array");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetArray_ValueNotFoundReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6}
-				};
-			var value = json.TryGetArray("array");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetArray_ValueNotBooleanReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"array", new JsonArray()}
-				};
-			var value = json.TryGetArray("string");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetObject_ReturnsRequested()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"object", new JsonObject()}
-				};
-
-			var value = json.TryGetObject("object");
-
-			Assert.AreEqual(new JsonObject(), value);
-		}
-		[TestMethod]
-		public void TryGetObject_NullObjectReturnsNull()
-		{
-			JsonObject json = null;
-
-			var value = json.TryGetObject("object");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetObject_ValueNotFoundReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6}
-				};
-			var value = json.TryGetObject("object");
-
-			Assert.IsNull(value);
-		}
-		[TestMethod]
-		public void TryGetObject_ValueNotBooleanReturnsNull()
-		{
-			var json = new JsonObject
-				{
-					{"string", "test"},
-					{"number", 6},
-					{"object", new JsonObject()}
-				};
-			var value = json.TryGetObject("string");
-
-			Assert.IsNull(value);
-		}
-	}
-}

File Manatee.Json.Tests/Extensions/LinqExtensionsTest.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:		LinqExtensionsTest.cs
-	Namespace:		Manatee.Json.Tests.Extensions
-	Class Name:		LinqExtensionsTest
-	Purpose:		Tests for the LINQ extension methods for the Json library.
-
-***************************************************************************************/
-
-using System.Linq;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Manatee.Json.Tests.Extensions
-{
-	[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 Manatee.Json.Tests/Extensions/XmlExtensionsTest.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:		XmlExtensionsTest.cs
-	Namespace:		Manatee.Json.Tests.Extensions
-	Class Name:		XmlExtensionsTest
-	Purpose:		Tests for the XML extension methods for the Json library.
-
-***************************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Xml.Linq;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Manatee.Json.Tests.Extensions
-{
-	[TestClass]
-	public class XmlExtensionsTest
-	{
-		#region Number
-		[TestMethod]
-		[ExpectedException(typeof(ArgumentException))]
-		public void ToXElement_NumberNullKey_ThrowsArgumentException()
-		{
-			JsonValue json = 42;
-			var actual = json.ToXElement(null);
-		}
-		[TestMethod]
-		public void ToXElement_NumberWithKey_MapsCorrectly()
-		{
-			var value = 42;
-			var key = "aKey";
-			JsonValue json = value;
-			var expected = new XElement(key, value);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToJson_ElementWithNumberValue_MapsCorrectly()
-		{
-			var value = 42;
-			var key = "aKey";
-			var xml = new XElement(key, value);
-			JsonValue expected = new JsonObject {{key, value}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		#endregion
-		#region String
-		[TestMethod]
-		[ExpectedException(typeof(ArgumentException))]
-		public void ToXElement_StringNullKey_ThrowsArgumentException()
-		{
-			JsonValue json = "a string";
-			var actual = json.ToXElement(null);
-		}
-		[TestMethod]
-		public void ToXElement_StringWithKey_MapsCorrectly()
-		{
-			var value = "a string";
-			var key = "aKey";
-			JsonValue json = value;
-			var expected = new XElement(key, value);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToXElement_NumericStringWithKey_MapsCorrectly()
-		{
-			var value = "42";
-			var key = "aKey";
-			JsonValue json = value;
-			var expected = new XElement(key, value);
-			expected.SetAttributeValue("type", "String");
-
-			var actual = json.ToXElement(key);
-
-			Assert.AreEqual(expected.ToString(), actual.ToString());
-		}
-		[TestMethod]
-		public void ToXElement_BooleanStringWithKey_MapsCorrectly()
-		{
-			var value = "true";
-			var key = "aKey";
-			JsonValue json = value;
-			var expected = new XElement(key, value);
-			expected.SetAttributeValue("type", "String");
-
-			var actual = json.ToXElement(key);
-
-			Assert.AreEqual(expected.ToString(), actual.ToString());
-		}
-		[TestMethod]
-		public void ToJson_ElementWithStringValue_MapsCorrectly()
-		{
-			var value = "a string";
-			var key = "aKey";
-			var xml = new XElement(key, value);
-			JsonValue expected = new JsonObject {{key, value}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		[TestMethod]
-		public void ToJson_ElementWithNumericStringValue_MapsCorrectly()
-		{
-			var value = "42";
-			var key = "aKey";
-			var xml = new XElement(key, value);
-			xml.SetAttributeValue("type", "String");
-			JsonValue expected = new JsonObject {{key, value}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		[TestMethod]
-		public void ToJson_ElementWithBooleanStringValue_MapsCorrectly()
-		{
-			var value = "true";
-			var key = "aKey";
-			var xml = new XElement(key, value);
-			xml.SetAttributeValue("type", "String");
-			JsonValue expected = new JsonObject {{key, value}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		#endregion
-		#region Boolean
-		[TestMethod]
-		[ExpectedException(typeof(ArgumentException))]
-		public void ToXElement_BooleanNullKey_ThrowsArgumentException()
-		{
-			JsonValue json = true;
-			var actual = json.ToXElement(null);
-		}
-		[TestMethod]
-		public void ToXElement_BooleanWithKey_MapsCorrectly()
-		{
-			var value = true;
-			var key = "aKey";
-			JsonValue json = value;
-			var expected = new XElement(key, value);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToJson_ElementWithBooleanValue_MapsCorrectly()
-		{
-			var value = true;
-			var key = "aKey";
-			var xml = new XElement(key, value);
-			JsonValue expected = new JsonObject {{key, value}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		#endregion
-		#region Object
-		[TestMethod]
-		[ExpectedException(typeof(ArgumentException))]
-		public void ToXElement_ObjectNullKeyMultiplePairs_ThrowsArgumentException()
-		{
-			JsonValue json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
-			var actual = json.ToXElement(null);
-		}
-		[TestMethod]
-		public void ToXElement_ObjectNullKeySinglePair_MapsCorrectly()
-		{
-			JsonValue json = new JsonObject {{"root", new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}}}};
-			var key = "root";
-			var expected = new XElement(key);
-			var xml = new XElement("bool", false);
-			expected.Add(xml);
-			xml = new XElement("int", 42);
-			expected.Add(xml);
-			xml = new XElement("string", "a string");
-			expected.Add(xml);
-
-			var actual = json.ToXElement(null);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToXElement_ObjectWithKey_MapsCorrectly()
-		{
-			JsonValue json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
-			var key = "aKey";
-			var expected = new XElement(key);
-			var xml = new XElement("bool", false);
-			expected.Add(xml);
-			xml = new XElement("int", 42);
-			expected.Add(xml);
-			xml = new XElement("string", "a string");
-			expected.Add(xml);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToJson_SingleRootElementSimpleContents_MapsCorrectly()
-		{
-			var key = "aKey";
-			var xml = new XElement(key);
-			var element = new XElement("bool", false);
-			xml.Add(element);
-			element = new XElement("int", 42);
-			xml.Add(element);
-			element = new XElement("string", "a string");
-			xml.Add(element);
-			JsonValue expected = new JsonObject {{"aKey", new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}}}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		[TestMethod]
-		public void ToJson_MultipleRootElementsSimpleContents_MapsCorrectly()
-		{
-			var list = new List<XElement>();
-			var element = new XElement("bool", false);
-			list.Add(element);
-			element = new XElement("int", 42);
-			list.Add(element);
-			element = new XElement("string", "a string");
-			list.Add(element);
-			JsonValue expected = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
-
-			var actual = list.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		[TestMethod]
-		public void ToJson_SingleRootElementComplexContents_MapsCorrectly()
-		{
-			var key = "aKey";
-			var xml = new XElement(key);
-			var element = new XElement("bool", false);
-			xml.Add(element);
-			element = new XElement("int", 42);
-			xml.Add(element);
-			element = new XElement("object");
-			var inner = new XElement("string", "a string");
-			element.Add(inner);
-			xml.Add(element);
-			JsonValue expected = new JsonObject
-			                     	{
-			                     		{
-			                     			"aKey",
-			                     			new JsonObject
-			                     				{
-			                     					{"bool", false},
-			                     					{"int", 42},
-			                     					{"object", new JsonObject {{"string", "a string"}}}
-			                     				}
-			                     			}
-			                     	};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		#endregion
-		#region Array
-		[TestMethod]
-		[ExpectedException(typeof(ArgumentException))]
-		public void ToXElement_ArrayNullKey_ThrowsArgumentException()
-		{
-			JsonValue json = new JsonArray {false, 42, "a string"};
-			var actual = json.ToXElement(null);
-		}
-		[TestMethod]
-		public void ToXElement_ArrayWithKey_MapsCorrectly()
-		{
-			var key = "aKey";
-			JsonValue json = new JsonArray {false, 42, "a string"};
-			var expected = new XElement(key);
-			var xml = new XElement(key, false);
-			expected.Add(xml);
-			xml = new XElement(key, 42);
-			expected.Add(xml);
-			xml = new XElement(key, "a string");
-			expected.Add(xml);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToXElement_ArrayWithNestedArray_MapsCorrectly()
-		{
-			var key = "aKey";
-			JsonValue json = new JsonArray {false, 42, new JsonArray {"a string"}};
-			var expected = new XElement(key);
-			var xml = new XElement(key, false);
-			expected.Add(xml);
-			xml = new XElement(key, 42);
-			expected.Add(xml);
-			xml = new XElement(key);
-			var inner = new XElement(key, "a string");
-			xml.Add(inner);
-			xml.SetAttributeValue("nest", true);
-			expected.Add(xml);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToXElement_ArrayWithNestedArrayWithNestedObjectContainingSameKey_MapsCorrectly()
-		{
-			var key = "aKey";
-			JsonValue json = new JsonArray {false, 42, new JsonArray {"a string", new JsonObject {{key, 6}}}};
-			var expected = new XElement(key);
-			var xml = new XElement(key, false);
-			expected.Add(xml);
-			xml = new XElement(key, 42);
-			expected.Add(xml);
-			xml = new XElement(key);
-			var inner = new XElement(key, "a string");
-			xml.Add(inner);
-			inner = new XElement(key);
-			var obj = new XElement(key, 6);
-			inner.Add(obj);
-			xml.Add(inner);
-			xml.SetAttributeValue("nest", true);
-			expected.Add(xml);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		#endregion
-		#region Null
-		[TestMethod]
-		[ExpectedException(typeof(ArgumentException))]
-		public void ToXElement_NullNullKey_ThrowsArgumentException()
-		{
-			JsonValue json = true;
-			var actual = json.ToXElement(null);
-		}
-		[TestMethod]
-		public void ToXElement_NullWithKey_MapsCorrectly()
-		{
-			var key = "aKey";
-			JsonValue json = JsonValue.Null;
-			var expected = new XElement(key);
-
-			var actual = json.ToXElement(key);
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToJson_ElementWithNullValue_MapsCorrectly()
-		{
-			var key = "aKey";
-			var xml = new XElement(key);
-			JsonValue expected = new JsonObject {{key, JsonValue.Null}};
-
-			var actual = xml.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		#endregion
-		#region Complex
-		[TestMethod]
-		public void ToXElement_ComplexObject_MapsCorrectly()
-		{
-			JsonValue json = new JsonObject
-			           			{
-			           				{"string","a string"},
-									{"number", 42},
-									{"array", new JsonArray{-6, JsonValue.Null, true, new JsonArray{Math.PI, false, "another string"}}},
-									{"object", new JsonObject
-							           			{
-							           				{"string", "yet another string"},
-													{"object", new JsonObject{{"number", 263.5},{"array",new JsonArray{1,2,new JsonObject{{"single",1}}}}}}
-							           			}}
-			           			};
-			var expected = new XElement("root");
-			var element1 = new XElement("string", "a string");
-			expected.Add(element1);
-			element1 = new XElement("number", 42);
-			expected.Add(element1);
-			element1 = new XElement("array", -6);
-			expected.Add(element1);
-			element1 = new XElement("array");
-			expected.Add(element1);
-			element1 = new XElement("array", true);
-			expected.Add(element1);
-			element1 = new XElement("array");
-			element1.SetAttributeValue("nest", true);
-			var element2 = new XElement("array", Math.PI);
-			element1.Add(element2);
-			element2 = new XElement("array", false);
-			element1.Add(element2);
-			element2 = new XElement("array", "another string");
-			element1.Add(element2);
-			expected.Add(element1);
-			element1 = new XElement("object");
-			element2 = new XElement("string", "yet another string");
-			element1.Add(element2);
-			element2 = new XElement("object");
-			var element3 = new XElement("number", 263.5);
-			element2.Add(element3);
-			element3 = new XElement("array", 1);
-			element2.Add(element3);
-			element3 = new XElement("array", 2);
-			element2.Add(element3);
-			element3 = new XElement("array");
-			var element4 = new XElement("single", 1);
-			element3.Add(element4);
-			element2.Add(element3);
-			element1.Add(element2);
-			expected.Add(element1);
-
-			var actual = json.ToXElement("root");
-
-			Assert.IsTrue(XNode.DeepEquals(expected, actual));
-		}
-		[TestMethod]
-		public void ToJson_ComplexElement_MapsCorrectly()
-		{
-			var list = new List<XElement>();
-			var element1 = new XElement("string", "a string");
-			list.Add(element1);
-			element1 = new XElement("number", 42);
-			list.Add(element1);
-			element1 = new XElement("array", -6);
-			list.Add(element1);
-			element1 = new XElement("array");
-			list.Add(element1);
-			element1 = new XElement("array", true);
-			list.Add(element1);
-			element1 = new XElement("array");
-			element1.SetAttributeValue("nest", true);
-			var element2 = new XElement("array", Math.PI);
-			element1.Add(element2);
-			element2 = new XElement("array", false);
-			element1.Add(element2);
-			element2 = new XElement("array", "another string");
-			element1.Add(element2);
-			list.Add(element1);
-			element1 = new XElement("object");
-			element2 = new XElement("string", "yet another string");
-			element1.Add(element2);
-			element2 = new XElement("object");
-			var element3 = new XElement("number", 263.5);
-			element2.Add(element3);
-			element3 = new XElement("array", 1);
-			element2.Add(element3);
-			element3 = new XElement("array", 2);
-			element2.Add(element3);
-			element3 = new XElement("array");
-			var element4 = new XElement("single", 1);
-			element3.Add(element4);
-			element2.Add(element3);
-			element1.Add(element2);
-			list.Add(element1);
-			JsonValue expected = new JsonObject
-			           				{
-			           					{"string","a string"},
-										{"number", 42},
-										{"array", new JsonArray{-6, JsonValue.Null, true, new JsonArray{Math.PI, false, "another string"}}},
-										{"object", new JsonObject
-							           				{
-							           					{"string", "yet another string"},
-														{"object", new JsonObject{{"number", 263.5},{"array",new JsonArray{1,2,new JsonObject{{"single",1}}}}}}
-							           				}}
-			           				};
-
-			var actual = list.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		[TestMethod]
-		public void RoundTrip_StartingWithJson()
-		{
-			JsonValue json = new JsonObject
-			           			{
-			           				{"string","a string"},
-									{"number", 42},
-									{"array", new JsonArray{-6, JsonValue.Null, true, new JsonArray{Math.PI, false, "another string"}}},
-									{"object", new JsonObject
-							           			{
-							           				{"string", "yet another string"},
-													{"object", new JsonObject{{"number", 263.5},{"array",new JsonArray{1,2,new JsonObject{{"single",1}}}}}}
-							           			}}
-			           			};
-			var expected = new JsonObject {{"root", json}};
-
-			var toXElement = json.ToXElement("root");
-			var actual = toXElement.ToJson();
-
-			Assert.AreEqual(expected, actual);
-		}
-		[TestMethod]
-		public void RoundTrip_StartingWithXml()
-		{
-			var expected = XElement.Parse(@"<Requests><Request><SearchCustomerRequest xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://www.manatee.com/services/""><MachineName xmlns=""http://www.manatee.com/services/sub/"">USA02415-2</MachineName><SearchContext xmlns:d2p1=""http://www.manatee.com/services/""><d2p1:CustomerId i:nil=""true"" /><d2p1:EdgeId /><d2p1:EmailAddress /><d2p1:LastName /><d2p1:LoyaltyCardNumber>1234567890123</d2p1:LoyaltyCardNumber><d2p1:MaxRows i:nil=""true"" /><d2p1:PhoneNumber /><d2p1:ZipCode /></SearchContext></SearchCustomerRequest></Request></Requests>");
-			var expectedJson = JsonValue.Parse(@"{""Requests"":{""Request"":{""SearchCustomerRequest"":[{""-xmlns:i"":""http:\/\/www.w3.org\/2001\/XMLSchema-instance"",""-xmlns"":""http:\/\/www.manatee.com\/services\/""},{""MachineName"":[{""-xmlns"":""http:\/\/www.manatee.com\/services\/sub\/""},""USA02415-2""],""d2p1:SearchContext"":[{""-xmlns:d2p1"":""http:\/\/www.manatee.com\/services\/""},{""d2p1:CustomerId"":[{""-i:nil"":true},null],""d2p1:EdgeId"":null,""d2p1:EmailAddress"":null,""d2p1:LastName"":null,""d2p1:LoyaltyCardNumber"":1234567890123,""d2p1:MaxRows"":[{""-i:nil"":true},null],""d2p1:PhoneNumber"":null,""d2p1:ZipCode"":null}]}]}}}");
-
-			var toJson = expected.ToJson();
-			Assert.AreEqual(expectedJson, toJson);
-
-			var actual = toJson.ToXElement(null);
-
-			Assert.AreEqual(expected.ToString(), actual.ToString());
-		}
-		#endregion
-	}
-}

File Manatee.Json.Tests/JsonArrayExtensionsTest.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:		JsonArrayExtensionsTest.cs
+	Namespace:		Manatee.Json.Tests
+	Class Name:		JsonArrayExtensionsTest
+	Purpose:		Tests for the JsonArray extension methods for the Json library.
+
+***************************************************************************************/
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests
+{
+	[TestClass]
+	public class JsonArrayExtensionsTest
+	{
+		[TestMethod]
+		public void OfType_ReturnsOnlyRequestType()
+		{
+			var json = new JsonArray {6, "string", false, 42, JsonValue.Null, true};
+			var expected = new JsonArray {6, 42};
+			var values = json.OfType(JsonValueType.Number);
+
+			Assert.AreEqual(expected, values);
+		}
+	}
+}

File Manatee.Json.Tests/JsonObjectExtensionsTest.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:		JsonObjectExtensionsTest.cs
+	Namespace:		Manatee.Json.Tests
+	Class Name:		JsonObjectExtensionsTest
+	Purpose:		Tests for the JsonObject extension methods for the Json library.
+
+***************************************************************************************/
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests
+{
+	[TestClass]
+	public class JsonObjectExtensionsTest
+	{
+		[TestMethod]
+		public void TryGetString_ReturnsRequested()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"boolean", true}
+				};
+
+			var value = json.TryGetString("string");
+
+			Assert.AreEqual("test", value);
+		}
+		[TestMethod]
+		public void TryGetString_NullObjectReturnsNull()
+		{
+			JsonObject json = null;
+
+			var value = json.TryGetString("string");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetString_ValueNotFoundReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"number", 6},
+					{"boolean", true}
+				};
+			var value = json.TryGetString("string");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetString_ValueNotStringReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"boolean", true}
+				};
+			var value = json.TryGetString("number");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetNumber_ReturnsRequested()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"boolean", true}
+				};
+
+			var value = json.TryGetNumber("number");
+
+			Assert.AreEqual(6.0, value);
+		}
+		[TestMethod]
+		public void TryGetNumber_NullObjectReturnsNull()
+		{
+			JsonObject json = null;
+
+			var value = json.TryGetNumber("number");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetNumber_ValueNotFoundReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"boolean", true}
+				};
+			var value = json.TryGetNumber("number");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetNumber_ValueNotNumberReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"boolean", true}
+				};
+			var value = json.TryGetNumber("string");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetBoolean_ReturnsRequested()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"boolean", true}
+				};
+
+			var value = json.TryGetBoolean("boolean");
+
+			Assert.AreEqual(true, value);
+		}
+		[TestMethod]
+		public void TryGetBoolean_NullObjectReturnsNull()
+		{
+			JsonObject json = null;
+
+			var value = json.TryGetBoolean("boolean");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetBoolean_ValueNotFoundReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6}
+				};
+			var value = json.TryGetBoolean("boolean");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetBoolean_ValueNotBooleanReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"boolean", true}
+				};
+			var value = json.TryGetBoolean("string");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetArray_ReturnsRequested()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"array", new JsonArray()}
+				};
+
+			var value = json.TryGetArray("array");
+
+			Assert.AreEqual(new JsonArray(), value);
+		}
+		[TestMethod]
+		public void TryGetArray_NullObjectReturnsNull()
+		{
+			JsonObject json = null;
+
+			var value = json.TryGetArray("array");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetArray_ValueNotFoundReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6}
+				};
+			var value = json.TryGetArray("array");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetArray_ValueNotBooleanReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"array", new JsonArray()}
+				};
+			var value = json.TryGetArray("string");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetObject_ReturnsRequested()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"object", new JsonObject()}
+				};
+
+			var value = json.TryGetObject("object");
+
+			Assert.AreEqual(new JsonObject(), value);
+		}
+		[TestMethod]
+		public void TryGetObject_NullObjectReturnsNull()
+		{
+			JsonObject json = null;
+
+			var value = json.TryGetObject("object");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetObject_ValueNotFoundReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6}
+				};
+			var value = json.TryGetObject("object");
+
+			Assert.IsNull(value);
+		}
+		[TestMethod]
+		public void TryGetObject_ValueNotBooleanReturnsNull()
+		{
+			var json = new JsonObject
+				{
+					{"string", "test"},
+					{"number", 6},
+					{"object", new JsonObject()}
+				};
+			var value = json.TryGetObject("string");
+
+			Assert.IsNull(value);
+		}
+	}
+}

File Manatee.Json.Tests/LinqExtensionsTest.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:		LinqExtensionsTest.cs
+	Namespace:		Manatee.Json.Tests
+	Class Name:		LinqExtensionsTest
+	Purpose:		Tests for the LINQ extension methods for the Json library.
+
+***************************************************************************************/
+
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests
+{
+	[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 Manatee.Json.Tests/Manatee.Tests.csproj

   </ItemGroup>
   <ItemGroup>
     <Compile Include="DevTest.cs" />
-    <Compile Include="Extensions\JsonArrayExtensionsTest.cs" />
-    <Compile Include="Extensions\JsonObjectExtensionsTest.cs" />
-    <Compile Include="Extensions\XmlExtensionsTest.cs" />
+    <Compile Include="JsonArrayExtensionsTest.cs" />
+    <Compile Include="JsonObjectExtensionsTest.cs" />
+    <Compile Include="XmlExtensionsTest.cs" />
     <Compile Include="JsonObjectTest.cs" />
     <Compile Include="JsonArrayTest.cs" />
     <Compile Include="JsonValueTest.cs" />
-    <Compile Include="Extensions\LinqExtensionsTest.cs" />
+    <Compile Include="LinqExtensionsTest.cs" />
     <Compile Include="Serialization\Internal\TypeGeneratorTest.cs" />
     <Compile Include="Serialization\JsonSerializerTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
       <Name>Manatee.Json</Name>
     </ProjectReference>
   </ItemGroup>
+  <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.

File Manatee.Json.Tests/XmlExtensionsTest.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:		XmlExtensionsTest.cs
+	Namespace:		Manatee.Json.Tests
+	Class Name:		XmlExtensionsTest
+	Purpose:		Tests for the XML extension methods for the Json library.
+
+***************************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Xml.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Manatee.Json.Tests
+{
+	[TestClass]
+	public class XmlExtensionsTest
+	{
+		#region Number
+		[TestMethod]
+		[ExpectedException(typeof(ArgumentException))]
+		public void ToXElement_NumberNullKey_ThrowsArgumentException()
+		{
+			JsonValue json = 42;
+			var actual = json.ToXElement(null);
+		}
+		[TestMethod]
+		public void ToXElement_NumberWithKey_MapsCorrectly()
+		{
+			var value = 42;
+			var key = "aKey";
+			JsonValue json = value;
+			var expected = new XElement(key, value);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToJson_ElementWithNumberValue_MapsCorrectly()
+		{
+			var value = 42;
+			var key = "aKey";
+			var xml = new XElement(key, value);
+			JsonValue expected = new JsonObject {{key, value}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		#endregion
+		#region String
+		[TestMethod]
+		[ExpectedException(typeof(ArgumentException))]
+		public void ToXElement_StringNullKey_ThrowsArgumentException()
+		{
+			JsonValue json = "a string";
+			var actual = json.ToXElement(null);
+		}
+		[TestMethod]
+		public void ToXElement_StringWithKey_MapsCorrectly()
+		{
+			var value = "a string";
+			var key = "aKey";
+			JsonValue json = value;
+			var expected = new XElement(key, value);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToXElement_NumericStringWithKey_MapsCorrectly()
+		{
+			var value = "42";
+			var key = "aKey";
+			JsonValue json = value;
+			var expected = new XElement(key, value);
+			expected.SetAttributeValue("type", "String");
+
+			var actual = json.ToXElement(key);
+
+			Assert.AreEqual(expected.ToString(), actual.ToString());
+		}
+		[TestMethod]
+		public void ToXElement_BooleanStringWithKey_MapsCorrectly()
+		{
+			var value = "true";
+			var key = "aKey";
+			JsonValue json = value;
+			var expected = new XElement(key, value);
+			expected.SetAttributeValue("type", "String");
+
+			var actual = json.ToXElement(key);
+
+			Assert.AreEqual(expected.ToString(), actual.ToString());
+		}
+		[TestMethod]
+		public void ToJson_ElementWithStringValue_MapsCorrectly()
+		{
+			var value = "a string";
+			var key = "aKey";
+			var xml = new XElement(key, value);
+			JsonValue expected = new JsonObject {{key, value}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void ToJson_ElementWithNumericStringValue_MapsCorrectly()
+		{
+			var value = "42";
+			var key = "aKey";
+			var xml = new XElement(key, value);
+			xml.SetAttributeValue("type", "String");
+			JsonValue expected = new JsonObject {{key, value}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void ToJson_ElementWithBooleanStringValue_MapsCorrectly()
+		{
+			var value = "true";
+			var key = "aKey";
+			var xml = new XElement(key, value);
+			xml.SetAttributeValue("type", "String");
+			JsonValue expected = new JsonObject {{key, value}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		#endregion
+		#region Boolean
+		[TestMethod]
+		[ExpectedException(typeof(ArgumentException))]
+		public void ToXElement_BooleanNullKey_ThrowsArgumentException()
+		{
+			JsonValue json = true;
+			var actual = json.ToXElement(null);
+		}
+		[TestMethod]
+		public void ToXElement_BooleanWithKey_MapsCorrectly()
+		{
+			var value = true;
+			var key = "aKey";
+			JsonValue json = value;
+			var expected = new XElement(key, value);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToJson_ElementWithBooleanValue_MapsCorrectly()
+		{
+			var value = true;
+			var key = "aKey";
+			var xml = new XElement(key, value);
+			JsonValue expected = new JsonObject {{key, value}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		#endregion
+		#region Object
+		[TestMethod]
+		[ExpectedException(typeof(ArgumentException))]
+		public void ToXElement_ObjectNullKeyMultiplePairs_ThrowsArgumentException()
+		{
+			JsonValue json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			var actual = json.ToXElement(null);
+		}
+		[TestMethod]
+		public void ToXElement_ObjectNullKeySinglePair_MapsCorrectly()
+		{
+			JsonValue json = new JsonObject {{"root", new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}}}};
+			var key = "root";
+			var expected = new XElement(key);
+			var xml = new XElement("bool", false);
+			expected.Add(xml);
+			xml = new XElement("int", 42);
+			expected.Add(xml);
+			xml = new XElement("string", "a string");
+			expected.Add(xml);
+
+			var actual = json.ToXElement(null);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToXElement_ObjectWithKey_MapsCorrectly()
+		{
+			JsonValue json = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+			var key = "aKey";
+			var expected = new XElement(key);
+			var xml = new XElement("bool", false);
+			expected.Add(xml);
+			xml = new XElement("int", 42);
+			expected.Add(xml);
+			xml = new XElement("string", "a string");
+			expected.Add(xml);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToJson_SingleRootElementSimpleContents_MapsCorrectly()
+		{
+			var key = "aKey";
+			var xml = new XElement(key);
+			var element = new XElement("bool", false);
+			xml.Add(element);
+			element = new XElement("int", 42);
+			xml.Add(element);
+			element = new XElement("string", "a string");
+			xml.Add(element);
+			JsonValue expected = new JsonObject {{"aKey", new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}}}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void ToJson_MultipleRootElementsSimpleContents_MapsCorrectly()
+		{
+			var list = new List<XElement>();
+			var element = new XElement("bool", false);
+			list.Add(element);
+			element = new XElement("int", 42);
+			list.Add(element);
+			element = new XElement("string", "a string");
+			list.Add(element);
+			JsonValue expected = new JsonObject {{"bool", false}, {"int", 42}, {"string", "a string"}};
+
+			var actual = list.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void ToJson_SingleRootElementComplexContents_MapsCorrectly()
+		{
+			var key = "aKey";
+			var xml = new XElement(key);
+			var element = new XElement("bool", false);
+			xml.Add(element);
+			element = new XElement("int", 42);
+			xml.Add(element);
+			element = new XElement("object");
+			var inner = new XElement("string", "a string");
+			element.Add(inner);
+			xml.Add(element);
+			JsonValue expected = new JsonObject
+			                     	{
+			                     		{
+			                     			"aKey",
+			                     			new JsonObject
+			                     				{
+			                     					{"bool", false},
+			                     					{"int", 42},
+			                     					{"object", new JsonObject {{"string", "a string"}}}
+			                     				}
+			                     			}
+			                     	};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		#endregion
+		#region Array
+		[TestMethod]
+		[ExpectedException(typeof(ArgumentException))]
+		public void ToXElement_ArrayNullKey_ThrowsArgumentException()
+		{
+			JsonValue json = new JsonArray {false, 42, "a string"};
+			var actual = json.ToXElement(null);
+		}
+		[TestMethod]
+		public void ToXElement_ArrayWithKey_MapsCorrectly()
+		{
+			var key = "aKey";
+			JsonValue json = new JsonArray {false, 42, "a string"};
+			var expected = new XElement(key);
+			var xml = new XElement(key, false);
+			expected.Add(xml);
+			xml = new XElement(key, 42);
+			expected.Add(xml);
+			xml = new XElement(key, "a string");
+			expected.Add(xml);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToXElement_ArrayWithNestedArray_MapsCorrectly()
+		{
+			var key = "aKey";
+			JsonValue json = new JsonArray {false, 42, new JsonArray {"a string"}};
+			var expected = new XElement(key);
+			var xml = new XElement(key, false);
+			expected.Add(xml);
+			xml = new XElement(key, 42);
+			expected.Add(xml);
+			xml = new XElement(key);
+			var inner = new XElement(key, "a string");
+			xml.Add(inner);
+			xml.SetAttributeValue("nest", true);
+			expected.Add(xml);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToXElement_ArrayWithNestedArrayWithNestedObjectContainingSameKey_MapsCorrectly()
+		{
+			var key = "aKey";
+			JsonValue json = new JsonArray {false, 42, new JsonArray {"a string", new JsonObject {{key, 6}}}};
+			var expected = new XElement(key);
+			var xml = new XElement(key, false);
+			expected.Add(xml);
+			xml = new XElement(key, 42);
+			expected.Add(xml);
+			xml = new XElement(key);
+			var inner = new XElement(key, "a string");
+			xml.Add(inner);
+			inner = new XElement(key);
+			var obj = new XElement(key, 6);
+			inner.Add(obj);
+			xml.Add(inner);
+			xml.SetAttributeValue("nest", true);
+			expected.Add(xml);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		#endregion
+		#region Null
+		[TestMethod]
+		[ExpectedException(typeof(ArgumentException))]
+		public void ToXElement_NullNullKey_ThrowsArgumentException()
+		{
+			JsonValue json = true;
+			var actual = json.ToXElement(null);
+		}
+		[TestMethod]
+		public void ToXElement_NullWithKey_MapsCorrectly()
+		{
+			var key = "aKey";
+			JsonValue json = JsonValue.Null;
+			var expected = new XElement(key);
+
+			var actual = json.ToXElement(key);
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToJson_ElementWithNullValue_MapsCorrectly()
+		{
+			var key = "aKey";
+			var xml = new XElement(key);
+			JsonValue expected = new JsonObject {{key, JsonValue.Null}};
+
+			var actual = xml.ToJson();
+
+			Assert.AreEqual(expected, actual);
+		}
+		#endregion
+		#region Complex
+		[TestMethod]
+		public void ToXElement_ComplexObject_MapsCorrectly()
+		{
+			JsonValue json = new JsonObject
+			           			{
+			           				{"string","a string"},
+									{"number", 42},
+									{"array", new JsonArray{-6, JsonValue.Null, true, new JsonArray{Math.PI, false, "another string"}}},
+									{"object", new JsonObject
+							           			{
+							           				{"string", "yet another string"},
+													{"object", new JsonObject{{"number", 263.5},{"array",new JsonArray{1,2,new JsonObject{{"single",1}}}}}}
+							           			}}
+			           			};
+			var expected = new XElement("root");
+			var element1 = new XElement("string", "a string");
+			expected.Add(element1);
+			element1 = new XElement("number", 42);
+			expected.Add(element1);
+			element1 = new XElement("array", -6);
+			expected.Add(element1);
+			element1 = new XElement("array");
+			expected.Add(element1);
+			element1 = new XElement("array", true);
+			expected.Add(element1);
+			element1 = new XElement("array");
+			element1.SetAttributeValue("nest", true);
+			var element2 = new XElement("array", Math.PI);
+			element1.Add(element2);
+			element2 = new XElement("array", false);
+			element1.Add(element2);
+			element2 = new XElement("array", "another string");
+			element1.Add(element2);
+			expected.Add(element1);
+			element1 = new XElement("object");
+			element2 = new XElement("string", "yet another string");
+			element1.Add(element2);
+			element2 = new XElement("object");
+			var element3 = new XElement("number", 263.5);
+			element2.Add(element3);
+			element3 = new XElement("array", 1);
+			element2.Add(element3);
+			element3 = new XElement("array", 2);
+			element2.Add(element3);
+			element3 = new XElement("array");
+			var element4 = new XElement("single", 1);
+			element3.Add(element4);
+			element2.Add(element3);
+			element1.Add(element2);
+			expected.Add(element1);
+
+			var actual = json.ToXElement("root");
+
+			Assert.IsTrue(XNode.DeepEquals(expected, actual));
+		}
+		[TestMethod]
+		public void ToJson_ComplexElement_MapsCorrectly()
+		{
+			var list = new List<XElement>();
+			var element1 = new XElement("string", "a string");
+			list.Add(element1);
+			element1 = new XElement("number", 42);
+			list.Add(element1);
+			element1 = new XElement("array", -6);
+			list.Add(element1);
+			element1 = new XElement("array");
+			list.Add(element1);
+			element1 = new XElement("array", true);
+			list.Add(element1);
+			element1 = new XElement("array");
+			element1.SetAttributeValue("nest", true);
+			var element2 = new XElement("array", Math.PI);
+			element1.Add(element2);
+			element2 = new XElement("array", false);
+			element1.Add(element2);
+			element2 = new XElement("array", "another string");
+			element1.Add(element2);
+			list.Add(element1);
+			element1 = new XElement("object");
+			element2 = new XElement("string", "yet another string");
+			element1.Add(element2);
+			element2 = new XElement("object");
+			var element3 = new XElement("number", 263.5);
+			element2.Add(element3);
+			element3 = new XElement("array", 1);
+			element2.Add(element3);
+			element3 = new XElement("array", 2);
+			element2.Add(element3);
+			element3 = new XElement("array");