Commits

Jacob Reimers  committed 644c1c2

Refactored deserialization.
Adjusted namespaces.
Added code contracts.

  • Participants
  • Parent commits 1c18348

Comments (0)

Files changed (48)

File Linq2Rest.Mvc/Controllers/HomeController.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-using System.Web.Mvc;
+namespace Linq2Rest.Mvc.Controllers
+{
+	using System.Web.Mvc;
 
-namespace UrlQuery.Mvc.Controllers
-{
-    public class HomeController : Controller
+	public class HomeController : Controller
     {
         //
         // GET: /Home/

File Linq2Rest.Mvc/Controllers/SimpleController.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQuery.Mvc.Controllers
+namespace Linq2Rest.Mvc.Controllers
 {
 	using System.Web.Mvc;
 	using System;
-	using UrlQuery.Mvc.Models;
-	using UrlQuery.Mvc.Support;
-	using UrlQueryParser.Mvc;
-	using UrlQueryParser.Parser;
+
+	using Linq2Rest.Mvc.Models;
+	using Linq2Rest.Mvc.Support;
+	using Linq2Rest.Parser;
 
 	public class SimpleController : Controller
 	{

File Linq2Rest.Mvc/Global.asax.cs

-using System.Web;
-using System.Web.Mvc;
-using System.Web.Routing;
+namespace Linq2Rest.Mvc
+{
+	using System.Web;
+	using System.Web.Mvc;
+	using System.Web.Routing;
 
-namespace UrlQuery.Mvc
-{
-	using UrlQuery.Mvc.Models;
-	using UrlQuery.Mvc.Support;
-	using UrlQueryParser.Mvc;
-	using UrlQueryParser.Parser;
+	using Linq2Rest.Mvc.Models;
+	using Linq2Rest.Mvc.Support;
+	using Linq2Rest.Parser;
 
 	// Note: For instructions on enabling IIS6 or IIS7 classic mode, 
 	// visit http://go.microsoft.com/?LinkId=9394801

File Linq2Rest.Mvc/Linq2Rest.Mvc.csproj

     <ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>UrlQuery.Mvc</RootNamespace>
-    <AssemblyName>UrlQuery.Mvc</AssemblyName>
+    <RootNamespace>Linq2Rest.Mvc</RootNamespace>
+    <AssemblyName>Linq2Rest.Mvc</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <MvcBuildViews>false</MvcBuildViews>
     <UseIISExpress>true</UseIISExpress>
     <Content Include="Views\Simple\Index.cshtml" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\UrlQueryParser\UrlQuery.csproj">
+    <ProjectReference Include="..\Linq2Rest\Linq2Rest.csproj">
       <Project>{FEF6620A-87C8-43B4-92BD-5FAAD183CBC7}</Project>
       <Name>UrlQuery</Name>
     </ProjectReference>

File Linq2Rest.Mvc/Models/SimpleContext.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-using System.Data.Entity;
+namespace Linq2Rest.Mvc.Models
+{
+	using System.Data.Entity;
 
-namespace UrlQuery.Mvc.Models
-{
 	public class SimpleContext : DbContext
 	{
         // You can add custom code to this file. Changes will not be overwritten.

File Linq2Rest.Mvc/Models/SimpleDto.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQuery.Mvc.Models
+namespace Linq2Rest.Mvc.Models
 {
 	using System.ComponentModel.DataAnnotations;
 

File Linq2Rest.Mvc/Support/ResponseFormat.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQuery.Mvc.Support
+namespace Linq2Rest.Mvc.Support
 {
 	/// <summary>
 	/// 	Enumeration of supported response formats.

File Linq2Rest.Mvc/Support/ResponseFormatBinder.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQuery.Mvc.Support
+namespace Linq2Rest.Mvc.Support
 {
 	using System;
 	using System.Collections.Generic;
+	using System.Diagnostics.Contracts;
 	using System.Linq;
 	using System.Web;
 	using System.Web.Mvc;
 			/// <returns>The preferred supported content type.</returns>
 			public string GetPreferredContentType(HttpRequestBase request, IEnumerable<string> supportedContentTypes)
 			{
+				Contract.Requires(supportedContentTypes != null);
+
 				return request == null
 					|| request.AcceptTypes == null
 						? null

File Linq2Rest.Mvc/Support/ResponseFormatExtensions.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQuery.Mvc.Support
+namespace Linq2Rest.Mvc.Support
 {
 	using System.Collections.Generic;
 

File Linq2Rest.Tests/FakeItem.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests
 {
 	using System;
 

File Linq2Rest.Tests/Linq2Rest.Tests.csproj

     <ProjectGuid>{0D3564AF-F8C9-42A4-8A01-A4C95526FA28}</ProjectGuid>
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>UrlQueryParser.Tests</RootNamespace>
-    <AssemblyName>UrlQueryParser.Tests</AssemblyName>
+    <RootNamespace>Linq2Rest.Tests</RootNamespace>
+    <AssemblyName>Linq2Rest.Tests</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
     <Compile Include="Provider\SimpleDto.cs" />
     <Compile Include="Parser\SortExpressionFactoryTests.cs" />
     <Compile Include="Parser\TokenSetTests.cs" />
+    <Compile Include="Provider\TestSerializer.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\UrlQueryParser\UrlQuery.csproj">
+    <ProjectReference Include="..\Linq2Rest\Linq2Rest.csproj">
       <Project>{FEF6620A-87C8-43B4-92BD-5FAAD183CBC7}</Project>
       <Name>UrlQuery</Name>
     </ProjectReference>

File Linq2Rest.Tests/LinqExtensionsTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests
 {
 	using System;
 	using System.Reflection;
 
 	using NUnit.Framework;
 
-	using UrlQueryParser.Parser;
-
 	public class LinqExtensionsTests
 	{
 		[Test]

File Linq2Rest.Tests/Mvc/ModelFilterBinderTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests.Mvc
 {
 	using System.Collections.Specialized;
 	using System.Web;
 	using System.Web.Mvc;
 	using System.Web.Routing;
 
+	using Linq2Rest.Mvc;
+	using Linq2Rest.Parser;
+
 	using Moq;
 
 	using NUnit.Framework;
 
-	using UrlQueryParser.Mvc;
-	using UrlQueryParser.Parser;
-
 	public class ModelFilterBinderTests
 	{
 		[Test]

File Linq2Rest.Tests/Parser/ExpressionTokenizerTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests.Parser
 {
 	using System.Linq;
 
+	using Linq2Rest.Parser;
+
 	using NUnit.Framework;
 
-	using UrlQueryParser.Parser;
-
 	public class ExpressionTokenizerTests
 	{
 		private ExpressionTokenizer _tokenizer;

File Linq2Rest.Tests/Parser/FilterExpressionFactoryTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests.Parser
 {
-	using System;
 	using System.Globalization;
 	using System.Threading;
 
+	using Linq2Rest.Parser;
+
 	using NUnit.Framework;
 
-	using UrlQueryParser.Parser;
-
 	public class FilterExpressionFactoryTests
 	{
 		private FilterExpressionFactory _factory;

File Linq2Rest.Tests/Parser/ParameterParserTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests.Parser
 {
 	using System.Collections.Specialized;
 	using System.Linq;
 
+	using Linq2Rest.Mvc;
+	using Linq2Rest.Parser;
+
 	using NUnit.Framework;
 
-	using UrlQueryParser.Mvc;
-	using UrlQueryParser.Parser;
-
 	public class ParameterParserTests
 	{
 		private ParameterParser<FakeItem> _parser;

File Linq2Rest.Tests/Parser/SortExpressionFactoryTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests.Parser
 {
 	using System.Linq;
 
+	using Linq2Rest.Parser;
+
 	using NUnit.Framework;
 
-	using UrlQueryParser.Parser;
-
 	public class SortExpressionFactoryTests
 	{
 		private FakeItem[] _items;

File Linq2Rest.Tests/Parser/TokenSetTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests
+namespace Linq2Rest.Tests.Parser
 {
+	using Linq2Rest.Parser;
+
 	using NUnit.Framework;
 
-	using UrlQueryParser.Parser;
-
 	public class TokenSetTests
 	{
 		[Test]

File Linq2Rest.Tests/Provider/RestClientTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests.Provider
+namespace Linq2Rest.Tests.Provider
 {
 	using System;
 
+	using Linq2Rest.Provider;
+
 	using NUnit.Framework;
 
-	using UrlQueryParser.Provider;
-
 	public class RestClientTests
 	{
 		[Test]

File Linq2Rest.Tests/Provider/RestContextTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests.Provider
+namespace Linq2Rest.Tests.Provider
 {
 	using System;
 	using System.Dynamic;
 	using System.Linq;
 	using System.Web.Script.Serialization;
 
+	using Linq2Rest.Provider;
+
 	using Moq;
 
 	using NUnit.Framework;
-	using UrlQueryParser.Provider;
 
 	public class RestContextTests
 	{
 		public void TestSetup()
 		{
 			var baseUri = new Uri("http://localhost");
-			var serializer = new JavaScriptSerializer();
+			var serializerFactory = new TestSerializerFactory();
 
 			_mockClient = new Mock<IRestClient>();
 			_mockClient.SetupGet(x => x.ServiceBase).Returns(baseUri);
 			_mockClient.Setup(x => x.Get(It.IsAny<Uri>())).Returns("[{Value : 2, Content : \"blah\" }]");
 
-			_provider = new RestContext<SimpleDto>(_mockClient.Object, serializer);
+			_provider = new RestContext<SimpleDto>(_mockClient.Object, serializerFactory);
 		}
 
 		[Test]
 			var uri = new Uri("http://localhost/?$filter=Value%20le%203&$select=Value,Content&$skip=1&$take=1&$orderby=Value");
 			_mockClient.Verify(x => x.Get(uri), Times.Once());
 		}
-
-		private class SelectionObject : DynamicObject { }
 	}
 }

File Linq2Rest.Tests/Provider/RestQueryProviderTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests.Provider
+namespace Linq2Rest.Tests.Provider
 {
 	using System.Linq.Expressions;
-	using System.Web.Script.Serialization;
-
+	using Linq2Rest.Provider;
 	using Moq;
-
 	using NUnit.Framework;
 
-	using UrlQueryParser.Provider;
-
 	public class RestQueryProviderTests
 	{
 		private RestQueryProvider<FakeItem> _provider;
 		[TestFixtureSetUp]
 		public void FixtureSetup()
 		{
-			_provider = new RestQueryProvider<FakeItem>(new Mock<IRestClient>().Object, new JavaScriptSerializer());
+			_provider = new RestQueryProvider<FakeItem>(new Mock<IRestClient>().Object, new TestSerializerFactory());
 		}
 
 		[Test]

File Linq2Rest.Tests/Provider/RestQueryableTests.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests.Provider
+namespace Linq2Rest.Tests.Provider
 {
-	using System.Web.Script.Serialization;
+	using Linq2Rest.Provider;
 
 	using Moq;
 
 	using NUnit.Framework;
 
-	using UrlQueryParser.Provider;
-
 	public class RestQueryableTests
 	{
 		[Test]
 		public void ElementTypeIsSameAsGenericParameter()
 		{
-			var queryable = new RestQueryable<FakeItem>(new Mock<IRestClient>().Object, new JavaScriptSerializer());
+			var queryable = new RestQueryable<FakeItem>(new Mock<IRestClient>().Object, new TestSerializerFactory());
 
 			Assert.AreEqual(typeof(FakeItem), queryable.ElementType);
 		}

File Linq2Rest.Tests/Provider/SimpleDto.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Tests.Provider
+namespace Linq2Rest.Tests.Provider
 {
 	public class SimpleDto
 	{

File Linq2Rest.Tests/Provider/TestSerializer.cs

+namespace Linq2Rest.Tests.Provider
+{
+	using System.Collections.Generic;
+	using System.Web.Script.Serialization;
+
+	using Linq2Rest.Provider;
+
+	public class TestSerializerFactory : ISerializerFactory
+	{
+		public ISerializer<T> Create<T>()
+		{
+			if (typeof(T).IsAnonymousType())
+			{
+				return new SimpleAnonymousTypeSerializer<T>();
+			}
+
+			return new TestSerializer() as ISerializer<T>;
+		}
+	}
+
+	public class TestSerializer : ISerializer<SimpleDto>
+	{
+		private readonly JavaScriptSerializer _innerSerializer = new JavaScriptSerializer();
+
+		public SimpleDto Deserialize(string input)
+		{
+			return _innerSerializer.Deserialize<SimpleDto>(input);
+		}
+
+		public IList<SimpleDto> DeserializeList(string input)
+		{
+			return _innerSerializer.Deserialize<List<SimpleDto>>(input);
+		}
+	}
+}

File Linq2Rest.sln

 
 Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq2Rest", "UrlQueryParser\Linq2Rest.csproj", "{FEF6620A-87C8-43B4-92BD-5FAAD183CBC7}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq2Rest", "Linq2Rest\Linq2Rest.csproj", "{FEF6620A-87C8-43B4-92BD-5FAAD183CBC7}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq2Rest.Tests", "UrlQueryParser.Tests\Linq2Rest.Tests.csproj", "{0D3564AF-F8C9-42A4-8A01-A4C95526FA28}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq2Rest.Tests", "Linq2Rest.Tests\Linq2Rest.Tests.csproj", "{0D3564AF-F8C9-42A4-8A01-A4C95526FA28}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq2Rest.Mvc", "UrlQuery.Mvc\Linq2Rest.Mvc.csproj", "{E0D84C0C-2286-4370-8635-0FFB673DCEA6}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq2Rest.Mvc", "Linq2Rest.Mvc\Linq2Rest.Mvc.csproj", "{E0D84C0C-2286-4370-8635-0FFB673DCEA6}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

File Linq2Rest/Linq2Rest.csproj

     <ProjectGuid>{FEF6620A-87C8-43B4-92BD-5FAAD183CBC7}</ProjectGuid>
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>UrlQueryParser</RootNamespace>
-    <AssemblyName>UrlQueryParser</AssemblyName>
+    <RootNamespace>Linq2Rest</RootNamespace>
+    <AssemblyName>Linq2Rest</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
     <Compile Include="Mvc\ModelFilterExtensions.cs" />
     <Compile Include="Parser\ParameterParser.cs" />
     <Compile Include="Parser\SelectExpressionFactory.cs" />
+    <Compile Include="Parser\TokenSet.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Parser\SortDescription.cs" />
     <Compile Include="Parser\SortExpressionFactory.cs" />
     <Compile Include="Provider\IRestClient.cs" />
+    <Compile Include="Provider\ISerializer.cs" />
+    <Compile Include="Provider\RestClient.cs" />
     <Compile Include="Provider\RestContext.cs" />
     <Compile Include="Provider\RestQueryable.cs" />
     <Compile Include="Provider\RestQueryProvider.cs" />
+    <Compile Include="Provider\SimpleAnonymousTypeSerializer.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

File Linq2Rest/LinqExtensions.cs

 // Based on code from http://stackoverflow.com/questions/606104/how-to-create-linq-expression-tree-with-anonymous-type-in-it
 
 
-namespace UrlQueryParser
+namespace Linq2Rest
 {
 	using System;
 	using System.Collections.Generic;
 
 		public static bool IsAnonymousType(this Type type)
 		{
-			return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false) 
+			Contract.Requires<ArgumentNullException>(type != null);
+
+			return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
 				&& type.IsGenericType
 				&& type.Name.Contains("AnonymousType") && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
 				&& (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;

File Linq2Rest/Mvc/ModelFilterBinder.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Mvc
+namespace Linq2Rest.Mvc
 {
 	using System.Web.Mvc;
 
-	using UrlQueryParser.Parser;
+	using Linq2Rest.Parser;
 
 	public class ModelFilterBinder<T> : IModelBinder
 	{

File Linq2Rest/Mvc/ModelFilterExtensions.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Mvc
+namespace Linq2Rest.Mvc
 {
+	using System;
 	using System.Collections.Generic;
+	using System.Diagnostics.Contracts;
 
-	using UrlQueryParser.Parser;
+	using Linq2Rest.Parser;
 
 	public static class ModelFilterExtensions
 	{
 		public static IEnumerable<object> Filter<T>(this IEnumerable<T> source, ModelFilter<T> filter)
 		{
+			Contract.Requires<ArgumentNullException>(source != null);
+			Contract.Requires<ArgumentNullException>(filter != null);
+
 			return filter.Filter(source);
 		}
 	}

File Linq2Rest/Parser/ExpressionTokenizer.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Collections.Generic;

File Linq2Rest/Parser/FilterExpressionFactory.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
+	using System.Diagnostics.Contracts;
 	using System.Globalization;
 	using System.Linq;
 	using System.Linq.Expressions;
 
 		private TokenSet GetFunctionTokens(string filter)
 		{
+			Contract.Requires(filter != null);
+
 			var functionMatch = FunctionRx.Match(filter);
 			if (!functionMatch.Success)
 			{
 						if (string.Equals(tokenSet.Operation, "not", StringComparison.OrdinalIgnoreCase))
 						{
 							var right = CreateExpression<T>(tokenSet.Right, parameter, type ?? GetExpressionType<T>(tokenSet, parameter), formatProvider);
+
+							if (right == null)
+							{
+								return null;
+							}
+
 							return GetOperation(tokenSet.Operation, null, right);
 						}
-						
+
 						combiner = tokenSet.Operation;
 					}
 					else
 					{
 						var left = CreateExpression<T>(tokenSet.Left, parameter, type ?? GetExpressionType<T>(tokenSet, parameter), formatProvider);
 						var right = CreateExpression<T>(tokenSet.Right, parameter, left.Type, formatProvider);
+
+						if (right == null)
+						{
+							return null;
+						}
+
 						if (existing != null && !string.IsNullOrWhiteSpace(combiner))
 						{
 							var current = GetOperation(tokenSet.Operation, left, right);
 			}
 			if (expression == null)
 			{
+				Contract.Assume(type != null);
+
 				expression = Expression.Constant(Convert.ChangeType(filter, type, formatProvider), type);
 			}
 
 
 		private Expression GetFunctionExpression<T>(string filter, ParameterExpression parameter, Type type, IFormatProvider formatProvider)
 		{
+			Contract.Requires(filter != null);
+
 			var functionTokens = GetFunctionTokens(filter);
 			if (functionTokens == null)
 			{
 
 		private Type GetFunctionParameterType(string operation)
 		{
+			Contract.Requires(operation != null);
+
 			switch (operation.ToLowerInvariant())
 			{
 				case "substring":
 
 		private Expression GetPropertyExpression<T>(string propertyToken, ParameterExpression parameter)
 		{
+			Contract.Requires(propertyToken != null);
+
 			var tokens = Tokenizer.GetTokens(propertyToken);
 			foreach (var token in tokens)
 			{
 
 			var parentType = typeof(T);
 			Expression propertyExpression = null;
+
 			var propertyChain = propertyToken.Split('/');
 			foreach (var propertyName in propertyChain)
 			{
 
 		private Type GetExpressionType<T>(TokenSet set, ParameterExpression parameter)
 		{
+			Contract.Requires(set != null);
+
 			var property = GetPropertyExpression<T>(set.Left, parameter) ?? GetPropertyExpression<T>(set.Right, parameter);
 
 			return property == null ? null : property.Type;
 
 		private Expression GetOperation(string token, Expression left, Expression right)
 		{
+			Contract.Requires(token != null);
+			Contract.Requires(right != null);
+
+			token = token.ToLowerInvariant();
+
+			if (string.Equals("not", token, StringComparison.OrdinalIgnoreCase))
+			{
+				return GetRightOperation(token, right);
+			}
+
+			Contract.Assume(left != null);
+
+			return GetLeftRightOperation(token, left, right);
+		}
+
+		private Expression GetLeftRightOperation(string token, Expression left, Expression right)
+		{
+			Contract.Requires(token != null);
+			Contract.Requires(left != null);
+			Contract.Requires(right != null);
+
 			switch (token.ToLowerInvariant())
 			{
 				case "eq":
 					return Expression.AndAlso(left, right);
 				case "or":
 					return Expression.OrElse(left, right);
-				case "not":
-					return Expression.Not(right);
 				case "add":
 					return Expression.Add(left, right);
 				case "sub":
 			throw new InvalidOperationException("Unsupported operation");
 		}
 
+		private Expression GetRightOperation(string token, Expression right)
+		{
+			Contract.Requires(token != null);
+			Contract.Requires(right != null);
+
+			switch (token.ToLowerInvariant())
+			{
+				case "not":
+					return Expression.Not(right);
+			}
+
+			throw new InvalidOperationException("Unsupported operation");
+		}
+
 		private Expression GetFunction(string function, Expression left, Expression right)
 		{
+			Contract.Requires(function != null);
+
 			switch (function.ToLowerInvariant())
 			{
 				case "substringof":
 				case "year":
 					return Expression.Property(left, YearProperty);
 				case "round":
+					Contract.Assume(left != null);
+
 					return Expression.Call(left.Type == typeof(double) ? DoubleRoundMethod : DecimalRoundMethod, left);
 				case "floor":
+					Contract.Assume(left != null);
+
 					return Expression.Call(left.Type == typeof(double) ? DoubleFloorMethod : DecimalFloorMethod, left);
 				case "ceiling":
+					Contract.Assume(left != null);
+
 					return Expression.Call(left.Type == typeof(double) ? DoubleCeilingMethod : DecimalCeilingMethod, left);
 				default:
 					return null;
 			return string.Format("{0} {1} {2}", Operation, Left, Right);
 		}
 	}
-
-
-	internal class TokenSet
-	{
-		public string Left { get; set; }
-
-		public string Operation { get; set; }
-
-		public string Right { get; set; }
-
-		public override string ToString()
-		{
-			return string.Format("{0} {1} {2}", Left, Operation, Right);
-		}
-	}
 }

File Linq2Rest/Parser/IFilterExpressionFactory.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Collections.Generic;

File Linq2Rest/Parser/IParameterParser.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System.Collections.Specialized;
 

File Linq2Rest/Parser/ISelectExpressionFactory.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 

File Linq2Rest/Parser/ModelFilter.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Collections.Generic;
+	using System.Diagnostics.Contracts;
 	using System.Linq;
 	using System.Web.UI.WebControls;
 
 	public class ModelFilter<T>
 	{
 		private readonly int _skip;
-
 		private readonly int _top;
-
 		private readonly Func<T, bool> _filterExpression;
-
 		private readonly Func<T, object> _selectExpression;
-
 		private readonly IEnumerable<SortDescription<T>> _sortDescriptions;
 
 		public ModelFilter(Func<T, bool> filterExpression, Func<T, object> selectExpression, IEnumerable<SortDescription<T>> sortDescriptions, int skip, int top)
 
 		public IEnumerable<object> Filter(IEnumerable<T> model)
 		{
-			var result = model.Where(_filterExpression);
+			Contract.Requires<ArgumentNullException>(model != null);
+
+			var result = _filterExpression != null ? model.Where(_filterExpression) : model;
 
 			if (_sortDescriptions != null && _sortDescriptions.Any())
 			{
 					}
 					else
 					{
+						var orderedEnumerable = result as IOrderedEnumerable<T>;
+
+						Contract.Assume(orderedEnumerable != null);
+
 						result = sortDescription.Direction == SortDirection.Ascending
-									? (result as IOrderedEnumerable<T>).ThenBy(sortDescription.KeySelector)
-									: (result as IOrderedEnumerable<T>).ThenByDescending(sortDescription.KeySelector);
+									? orderedEnumerable.ThenBy(sortDescription.KeySelector)
+									: orderedEnumerable.ThenByDescending(sortDescription.KeySelector);
 					}
 				}
 			}

File Linq2Rest/Parser/ParameterParser.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Collections.Specialized;

File Linq2Rest/Parser/SelectExpressionFactory.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Collections.Generic;

File Linq2Rest/Parser/SortDescription.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Web.UI.WebControls;

File Linq2Rest/Parser/SortExpressionFactory.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Parser
+namespace Linq2Rest.Parser
 {
 	using System;
 	using System.Collections.Generic;
+	using System.Diagnostics.Contracts;
 	using System.Globalization;
 	using System.Linq;
 	using System.Linq.Expressions;
 
 		private Expression<Func<T, object>> GetPropertyExpression<T>(string propertyToken, ParameterExpression parameter)
 		{
+			Contract.Requires(propertyToken != null);
+
 			var parentType = typeof(T);
 			Expression propertyExpression = null;
 			var propertyChain = propertyToken.Split('/');

File Linq2Rest/Parser/TokenSet.cs

+namespace Linq2Rest.Parser
+{
+	using System;
+	using System.Diagnostics.Contracts;
+
+	internal class TokenSet
+	{
+		private string _left;
+		private string _right;
+		private string _operation;
+
+		public TokenSet()
+		{
+			_left = string.Empty;
+			_right = string.Empty;
+			_operation = string.Empty;
+		}
+
+		public string Left
+		{
+			get
+			{
+				Contract.Ensures(Contract.Result<string>() != null);
+				return _left;
+			}
+			set
+			{
+				Contract.Requires<ArgumentNullException>(value != null);
+				_left = value;
+			}
+		}
+
+		public string Operation
+		{
+			get
+			{
+				Contract.Ensures(Contract.Result<string>() != null);
+				return _operation;
+			}
+			set
+			{
+				Contract.Requires<ArgumentNullException>(value != null);
+				_operation = value;
+			}
+		}
+
+		public string Right
+		{
+			get
+			{
+				Contract.Ensures(Contract.Result<string>() != null);
+				return _right;
+			}
+			set
+			{
+				Contract.Requires<ArgumentNullException>(value != null);
+				_right = value;
+			}
+		}
+
+		public override string ToString()
+		{
+			return string.Format("{0} {1} {2}", Left, Operation, Right);
+		}
+
+		[ContractInvariantMethod]
+		private void Invariants()
+		{
+			Contract.Invariant(_left != null);
+			Contract.Invariant(_right != null);
+			Contract.Invariant(_operation != null);
+		}
+	}
+}

File Linq2Rest/Properties/AssemblyInfo.cs

 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("0.1.0.0")]
 [assembly: AssemblyFileVersion("0.1.0.0")]
-[assembly: InternalsVisibleTo("UrlQueryParser.Tests")]
+[assembly: InternalsVisibleTo("Linq2Rest.Tests")]

File Linq2Rest/Provider/IRestClient.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Provider
+namespace Linq2Rest.Provider
 {
 	using System;
-	using System.Net;
+	using System.Diagnostics.Contracts;
 
+	[ContractClass(typeof(RestClientContracts))]
 	public interface IRestClient
 	{
 		Uri ServiceBase { get; }
 		string Get(Uri uri);
 	}
 
-	public class RestClient : IRestClient
+	[ContractClassFor(typeof(IRestClient))]
+	public abstract class RestClientContracts : IRestClient
 	{
-		private readonly WebClient _client;
-
-		public RestClient(Uri uri)
+		public Uri ServiceBase
 		{
-			_client = new WebClient();
-			_client.Headers["Accept"] = "text/javascript";
-
-			ServiceBase = uri;
+			get
+			{
+				Contract.Ensures(Contract.Result<Uri>() != null);
+				throw new NotImplementedException();
+			}
 		}
 
-		public Uri ServiceBase { get; private set; }
-
 		public string Get(Uri uri)
 		{
-			return _client.DownloadString(uri);
+			Contract.Requires<ArgumentNullException>(uri != null);
+
+			throw new NotImplementedException();
 		}
 	}
 }

File Linq2Rest/Provider/ISerializer.cs

+// (c) Copyright Reimers.dk.
+// This source is subject to the Microsoft Public License (Ms-PL).
+// Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
+// All other rights reserved.
+
+namespace Linq2Rest.Provider
+{
+	using System.Collections.Generic;
+
+	public interface ISerializer<T>
+	{
+		T Deserialize(string input);
+
+		IList<T> DeserializeList(string input);
+	}
+
+	public interface ISerializerFactory
+	{
+		ISerializer<T> Create<T>();
+	}
+}

File Linq2Rest/Provider/RestClient.cs

+namespace Linq2Rest.Provider
+{
+	using System;
+	using System.Net;
+
+	public class RestClient : IRestClient
+	{
+		private readonly WebClient _client;
+
+		public RestClient(Uri uri)
+		{
+			_client = new WebClient();
+			_client.Headers["Accept"] = "text/javascript";
+
+			ServiceBase = uri;
+		}
+
+		public Uri ServiceBase { get; private set; }
+
+		public string Get(Uri uri)
+		{
+			return _client.DownloadString(uri);
+		}
+	}
+}

File Linq2Rest/Provider/RestContext.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Provider
+namespace Linq2Rest.Provider
 {
 	using System;
 	using System.Diagnostics.Contracts;
 	using System.Linq;
-	using System.Web.Script.Serialization;
 
 	public class RestContext<T>
 	{
 		private readonly RestQueryable<T> _queryable;
 
-		public RestContext(IRestClient client, JavaScriptSerializer serializer)
+		public RestContext(IRestClient client, ISerializerFactory serializerFactory)
 		{
 			Contract.Requires<ArgumentNullException>(client != null);
-			Contract.Requires<ArgumentNullException>(serializer != null);
+			Contract.Requires<ArgumentNullException>(serializerFactory != null);
 
-			_queryable = new RestQueryable<T>(client, serializer);
+			_queryable = new RestQueryable<T>(client, serializerFactory);
 		}
 
 		public IQueryable<T> Query
 		{
-			get { return _queryable; }
+			get
+			{
+				Contract.Ensures(Contract.Result<IQueryable<T>>() != null);
+
+				return _queryable;
+			}
 		}
 
 		[ContractInvariantMethod]

File Linq2Rest/Provider/RestQueryProvider.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Provider
+namespace Linq2Rest.Provider
 {
 	using System;
-	using System.Collections;
 	using System.Collections.Generic;
 	using System.Diagnostics.Contracts;
 	using System.Linq;
 	using System.Linq.Expressions;
-	using System.Reflection;
 	using System.Threading;
-	using System.Web.Script.Serialization;
 
 	internal class RestQueryProvider<T> : IQueryProvider
 	{
-		private static readonly MethodInfo ChangeTypeMethod = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
 		private readonly IRestClient _client;
-		private readonly JavaScriptSerializer _serializer;
+		private readonly ISerializerFactory _serializerFactory;
+		private readonly List<string> _orderByParameter = new List<string>();
 
 		private string _selectParameter;
 		private string _filterParameter;
-		private readonly List<string> _orderByParameter = new List<string>();
 		private string _skipParameter;
 		private string _takeParameter;
 
-		public RestQueryProvider(IRestClient client, JavaScriptSerializer serializer)
+		public RestQueryProvider(IRestClient client, ISerializerFactory serializerFactory)
 		{
+			Contract.Requires<ArgumentNullException>(client != null);
+			Contract.Requires<ArgumentNullException>(serializerFactory != null);
+
 			_client = client;
-			_serializer = serializer;
+			_serializerFactory = serializerFactory;
 		}
 
 		public IQueryable CreateQuery(Expression expression)
 		{
-			return new RestQueryable<T>(_client, _serializer, expression);
+			if (expression == null)
+			{
+				throw new ArgumentNullException("expression");
+			}
+
+			return new RestQueryable<T>(_client, _serializerFactory, expression);
 		}
 
 		public IQueryable<TResult> CreateQuery<TResult>(Expression expression)
 		{
-			return new RestQueryable<TResult>(_client, _serializer, expression);
+			if (expression == null)
+			{
+				throw new ArgumentNullException("expression");
+			}
+
+			return new RestQueryable<TResult>(_client, _serializerFactory, expression);
 		}
 
 		public object Execute(Expression expression)
 			return null;
 		}
 
-		private List<T> GetResults()
+		private IList<T> GetResults()
 		{
-			Contract.Ensures(Contract.Result<List<T>>() != null);
+			Contract.Ensures(Contract.Result<IList<T>>() != null);
 
 			var parameters = string.Format(
 				"$filter={0}&$select={1}&$skip={2}&$take={3}&$orderby={4}",
 
 			var builder = new UriBuilder(_client.ServiceBase);
 			builder.Query = (string.IsNullOrEmpty(builder.Query) ? string.Empty : "&") + parameters;
-
+			var t = typeof(T);
 			var response = _client.Get(builder.Uri);
 
-			var elementType = typeof(T);
+			var serializer = _serializerFactory.Create<T>();
 
-			List<T> resultSet = elementType.IsAnonymousType()
-			                 	? ReadToAnonymousType(response, elementType)
-			                 	: _serializer.Deserialize<List<T>>(response);
+			var resultSet = serializer.DeserializeList(response);
+
+			Contract.Assume(resultSet != null);
 
 			return resultSet;
 		}
 
-		private List<T> ReadToAnonymousType(string response, Type elementType)
-		{
-			var deserializeObject = _serializer.DeserializeObject(response);
-			var enumerable = deserializeObject as IEnumerable;
-
-			if (enumerable == null || !enumerable.OfType<object>().Any())
-			{
-				return new List<T>();
-			}
-
-			var first = enumerable.OfType<object>().First();
-			var deserializedType = first.GetType();
-			var objectParameter = Expression.Parameter(typeof(object), "x");
-			var fields = elementType.GetProperties();
-
-			var bindings =
-				fields.Select(
-					p =>
-					Expression.Convert(
-						Expression.Call(
-							ChangeTypeMethod,
-							Expression.MakeIndex(
-								Expression.Convert(objectParameter, deserializedType),
-								deserializedType.GetProperty("Item"),
-								new[] { Expression.Constant(p.Name) }),
-							Expression.Constant(p.PropertyType)),
-						p.PropertyType)).ToArray();
-
-			var constructorInfo = elementType.GetConstructors().First();
-
-			var selector =
-				Expression.Lambda<Func<object, T>>(
-					Expression.New(constructorInfo, bindings), objectParameter);
-			var selectorFunction = selector.Compile();
-
-			return enumerable.OfType<object>().Select<object, T>(selectorFunction).ToList();
-		}
-
 		private string ProcessExpression(Expression expression)
 		{
 			if (expression is LambdaExpression)
 
 		private string GetOperation(Expression expression)
 		{
+			Contract.Requires(expression != null);
+
 			switch (expression.NodeType)
 			{
 				case ExpressionType.Add:
 
 			return string.Empty;
 		}
+
+		[ContractInvariantMethod]
+		private void Invariants()
+		{
+			Contract.Invariant(_client != null);
+			Contract.Invariant(_serializerFactory != null);
+			Contract.Invariant(_orderByParameter != null);
+		}
 	}
 }

File Linq2Rest/Provider/RestQueryable.cs

 // Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
 // All other rights reserved.
 
-namespace UrlQueryParser.Provider
+namespace Linq2Rest.Provider
 {
 	using System;
 	using System.Collections;
 	using System.Diagnostics.Contracts;
 	using System.Linq;
 	using System.Linq.Expressions;
-	using System.Web.Script.Serialization;
 
 	internal class RestQueryable<T> : IOrderedQueryable<T>
 	{
 		private readonly IRestClient _client;
 
-		public RestQueryable(IRestClient client, JavaScriptSerializer serializer)
+		public RestQueryable(IRestClient client, ISerializerFactory serializerFactory)
 		{
 			Contract.Requires<ArgumentNullException>(client != null);
-			Contract.Requires<ArgumentNullException>(serializer != null);
+			Contract.Requires<ArgumentNullException>(serializerFactory != null);
 
 			_client = client;
-			Provider = new RestQueryProvider<T>(_client, serializer);
+			Provider = new RestQueryProvider<T>(_client, serializerFactory);
 			Expression = Expression.Constant(this);
 		}
 
-		public RestQueryable(IRestClient client, JavaScriptSerializer serializer, Expression expression)
-			: this(client, serializer)
+		public RestQueryable(IRestClient client, ISerializerFactory serializerFactory, Expression expression)
+			: this(client, serializerFactory)
 		{
+			Contract.Requires<ArgumentNullException>(client != null);
+			Contract.Requires<ArgumentNullException>(serializerFactory != null);
+			Contract.Requires<ArgumentNullException>(expression != null);
+
 			Expression = expression;
 		}
 
 		{
 			return (Provider.Execute<IEnumerable>(Expression)).GetEnumerator();
 		}
+
+		[ContractInvariantMethod]
+		private void Invariants()
+		{
+			Contract.Invariant(_client != null);
+			Contract.Invariant(Expression != null);
+		}
 	}
 }

File Linq2Rest/Provider/SimpleAnonymousTypeSerializer.cs

+namespace Linq2Rest.Provider
+{
+	using System;
+	using System.Collections;
+	using System.Collections.Generic;
+	using System.Diagnostics.Contracts;
+	using System.Linq;
+	using System.Linq.Expressions;
+	using System.Reflection;
+	using System.Web.Script.Serialization;
+
+	public class SimpleAnonymousTypeSerializer<T> : ISerializer<T>
+	{
+		private static readonly MethodInfo ChangeTypeMethod = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
+		private readonly JavaScriptSerializer _innerSerializer = new JavaScriptSerializer();
+		private readonly Type _elementType = typeof(T);
+
+		public T Deserialize(string input)
+		{
+			var selectorFunction = CreateSelector(typeof(IDictionary<string, object>));
+			var dictionary = _innerSerializer.DeserializeObject(input);
+
+			return selectorFunction(dictionary);
+		}
+
+		public IList<T> DeserializeList(string input)
+		{
+			return ReadToAnonymousType(input);
+		}
+
+		private IList<T> ReadToAnonymousType(string response)
+		{
+			var deserializeObject = _innerSerializer.DeserializeObject(response);
+			var enumerable = deserializeObject as IEnumerable;
+
+			if (enumerable == null || !enumerable.OfType<object>().Any())
+			{
+				return new List<T>();
+			}
+
+			var first = enumerable.OfType<object>().First();
+			var deserializedType = first.GetType();
+			var selectorFunction = CreateSelector(deserializedType);
+
+			Contract.Assume(selectorFunction != null, "Compiled above.");
+
+			return enumerable.OfType<object>().Select<object, T>(selectorFunction).ToList();
+		}
+
+		private Func<object, T> CreateSelector(Type deserializedType)
+		{
+			var objectParameter = Expression.Parameter(typeof(object), "x");
+			var fields = _elementType.GetProperties();
+
+			var bindings =
+				fields.Select(
+					p =>
+					Expression.Convert(
+						Expression.Call(
+							ChangeTypeMethod,
+							Expression.MakeIndex(
+								Expression.Convert(objectParameter, deserializedType),
+								deserializedType.GetProperty("Item"),
+								new[] { Expression.Constant(p.Name) }),
+							Expression.Constant(p.PropertyType)),
+						p.PropertyType)).ToArray();
+
+			var constructorInfos = _elementType.GetConstructors().ToArray();
+			var constructorInfo = constructorInfos.First();
+
+			if (constructorInfo == null)
+			{
+				throw new NullReferenceException("No public constructor found.");
+			}
+
+			var selector =
+				Expression.Lambda<Func<object, T>>(
+					Expression.New(constructorInfo, bindings), objectParameter);
+			var selectorFunction = selector.Compile();
+
+			return selectorFunction;
+		}
+
+		[ContractInvariantMethod]
+		private void Invariants()
+		{
+			Contract.Invariant(_innerSerializer != null);
+			Contract.Invariant(_elementType != null);
+		}
+	}
+}